Flutter Engine
 
Loading...
Searching...
No Matches
image_encoding_skia.cc
Go to the documentation of this file.
1// Copyright 2013 The Flutter Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#if !SLIMPELLER
6
9
11
12namespace flutter {
13
15 const sk_sp<DlImage>& dl_image,
16 std::function<void(sk_sp<SkImage>)> encode_task,
17 const fml::RefPtr<fml::TaskRunner>& raster_task_runner,
18 const fml::RefPtr<fml::TaskRunner>& io_task_runner,
19 const fml::WeakPtr<GrDirectContext>& resource_context,
21 const std::shared_ptr<const fml::SyncSwitch>& is_gpu_disabled_sync_switch) {
22 // If the owning_context is kRaster, we can't access it on this task runner.
23 if (dl_image->owning_context() != DlImage::OwningContext::kRaster) {
24 auto image = dl_image->skia_image();
25
26 // Check validity of the image.
27 if (image == nullptr) {
28 FML_LOG(ERROR) << "Image was null.";
29 encode_task(nullptr);
30 return;
31 }
32
33 auto dimensions = image->dimensions();
34
35 if (dimensions.isEmpty()) {
36 FML_LOG(ERROR) << "Image dimensions were empty.";
37 encode_task(nullptr);
38 return;
39 }
40
41 SkPixmap pixmap;
42 if (image->peekPixels(&pixmap)) {
43 // This is already a raster image.
44 encode_task(image);
45 return;
46 }
47
48 if (sk_sp<SkImage> raster_image =
49 image->makeRasterImage(resource_context.get())) {
50 // The image can be converted to a raster image.
51 encode_task(raster_image);
52 return;
53 }
54 }
55
56 if (!raster_task_runner) {
57 FML_LOG(ERROR) << "Raster task runner was null.";
58 encode_task(nullptr);
59 return;
60 }
61
62 if (!io_task_runner) {
63 FML_LOG(ERROR) << "IO task runner was null.";
64 encode_task(nullptr);
65 return;
66 }
67
68 // Cross-context images do not support makeRasterImage. Convert these images
69 // by drawing them into a surface. This must be done on the raster thread
70 // to prevent concurrent usage of the image on both the IO and raster threads.
71 raster_task_runner->PostTask([dl_image, encode_task = std::move(encode_task),
72 resource_context, snapshot_delegate,
73 io_task_runner, is_gpu_disabled_sync_switch,
74 raster_task_runner]() {
75 auto image = dl_image->skia_image();
76 if (!image || !snapshot_delegate) {
77 io_task_runner->PostTask(
78 [encode_task = encode_task]() mutable { encode_task(nullptr); });
79 return;
80 }
81
82 sk_sp<SkImage> raster_image =
83 snapshot_delegate->ConvertToRasterImage(image);
84
85 io_task_runner->PostTask([image, encode_task = encode_task,
86 raster_image = std::move(raster_image),
87 resource_context, is_gpu_disabled_sync_switch,
88 owning_context = dl_image->owning_context(),
89 raster_task_runner]() mutable {
90 if (!raster_image) {
91 // The rasterizer was unable to render the cross-context image
92 // (presumably because it does not have a GrContext). In that case,
93 // convert the image on the IO thread using the resource context.
95 image, resource_context, is_gpu_disabled_sync_switch);
96 }
97 encode_task(raster_image);
98 if (owning_context == DlImage::OwningContext::kRaster) {
99 raster_task_runner->PostTask([image = std::move(image)]() {});
100 }
101 });
102 });
103}
104
105} // namespace flutter
106
107#endif // !SLIMPELLER
T * get() const
Definition weak_ptr.h:87
FlutterVulkanImage * image
#define FML_LOG(severity)
Definition logging.h:101
sk_sp< SkImage > ConvertToRasterUsingResourceContext(const sk_sp< SkImage > &image, const fml::WeakPtr< GrDirectContext > &resource_context, const std::shared_ptr< const SyncSwitch > &is_gpu_disabled_sync_switch)
void ConvertImageToRasterSkia(const sk_sp< DlImage > &dl_image, std::function< void(sk_sp< SkImage >)> encode_task, const fml::RefPtr< fml::TaskRunner > &raster_task_runner, const fml::RefPtr< fml::TaskRunner > &io_task_runner, const fml::WeakPtr< GrDirectContext > &resource_context, const fml::TaskRunnerAffineWeakPtr< SnapshotDelegate > &snapshot_delegate, const std::shared_ptr< const fml::SyncSwitch > &is_gpu_disabled_sync_switch)