Flutter Engine Uber Docs
Docs for the entire Flutter Engine repo.
 
Loading...
Searching...
No Matches
flutter::ImageDecoderSkia Class Referencefinal

#include <image_decoder_skia.h>

Inheritance diagram for flutter::ImageDecoderSkia:
flutter::ImageDecoder

Public Member Functions

 ImageDecoderSkia (const TaskRunners &runners, std::shared_ptr< fml::ConcurrentTaskRunner > concurrent_task_runner, fml::WeakPtr< IOManager > io_manager)
 
 ~ImageDecoderSkia () override
 
void Decode (fml::RefPtr< ImageDescriptor > descriptor, const Options &options, const ImageResult &result) override
 
- Public Member Functions inherited from flutter::ImageDecoder
virtual ~ImageDecoder ()
 
fml::TaskRunnerAffineWeakPtr< ImageDecoderGetWeakPtr () const
 

Static Public Member Functions

static sk_sp< SkImage > ImageFromCompressedData (ImageDescriptor *descriptor, uint32_t target_width, uint32_t target_height, const fml::tracing::TraceFlow &flow)
 
- Static Public Member Functions inherited from flutter::ImageDecoder
static std::unique_ptr< ImageDecoderMake (const Settings &settings, const TaskRunners &runners, std::shared_ptr< fml::ConcurrentTaskRunner > concurrent_task_runner, const fml::WeakPtr< IOManager > &io_manager, const std::shared_ptr< fml::SyncSwitch > &gpu_disabled_switch)
 

Additional Inherited Members

- Public Types inherited from flutter::ImageDecoder
enum  TargetPixelFormat {
  kUnknown ,
  kDontCare ,
  kR32G32B32A32Float ,
  kR32Float
}
 
using ImageResult = std::function< void(sk_sp< DlImage >, std::string)>
 
- Protected Member Functions inherited from flutter::ImageDecoder
 ImageDecoder (const TaskRunners &runners, std::shared_ptr< fml::ConcurrentTaskRunner > concurrent_task_runner, fml::WeakPtr< IOManager > io_manager)
 
- Protected Attributes inherited from flutter::ImageDecoder
TaskRunners runners_
 
std::shared_ptr< fml::ConcurrentTaskRunnerconcurrent_task_runner_
 
fml::WeakPtr< IOManagerio_manager_
 

Detailed Description

Definition at line 15 of file image_decoder_skia.h.

Constructor & Destructor Documentation

◆ ImageDecoderSkia()

flutter::ImageDecoderSkia::ImageDecoderSkia ( const TaskRunners runners,
std::shared_ptr< fml::ConcurrentTaskRunner concurrent_task_runner,
fml::WeakPtr< IOManager io_manager 
)

Definition at line 20 of file image_decoder_skia.cc.

24 : ImageDecoder(runners,
25 std::move(concurrent_task_runner),
26 std::move(io_manager)) {}
ImageDecoder(const TaskRunners &runners, std::shared_ptr< fml::ConcurrentTaskRunner > concurrent_task_runner, fml::WeakPtr< IOManager > io_manager)

◆ ~ImageDecoderSkia()

flutter::ImageDecoderSkia::~ImageDecoderSkia ( )
overridedefault

Member Function Documentation

◆ Decode()

void flutter::ImageDecoderSkia::Decode ( fml::RefPtr< ImageDescriptor descriptor,
const Options options,
const ImageResult result 
)
overridevirtual

Implements flutter::ImageDecoder.

Definition at line 224 of file image_decoder_skia.cc.

226 {
227 TRACE_EVENT0("flutter", __FUNCTION__);
228 fml::tracing::TraceFlow flow(__FUNCTION__);
229
230 // ImageDescriptors have Dart peers that must be collected on the UI thread.
231 // However, closures in MakeCopyable below capture the descriptor. The
232 // captures of copyable closures may be collected on any of the thread
233 // participating in task execution.
234 //
235 // To avoid this issue, we resort to manually reference counting the
236 // descriptor. Since all task flows invoke the `result` callback, the raw
237 // descriptor is retained in the beginning and released in the `result`
238 // callback.
239 //
240 // `ImageDecoder::Decode` itself is invoked on the UI thread, so the
241 // collection of the smart pointer from which we obtained the raw descriptor
242 // is fine in this scope.
243 auto raw_descriptor = descriptor_ref_ptr.get();
244 raw_descriptor->AddRef();
245
248
249 // Always service the callback (and cleanup the descriptor) on the UI thread.
250 auto result =
251 [callback, raw_descriptor, ui_runner = runners_.GetUITaskRunner()](
252 SkiaGPUObject<SkImage> image, fml::tracing::TraceFlow flow) {
253 ui_runner->PostTask(fml::MakeCopyable(
254 [callback, raw_descriptor, image = std::move(image),
255 flow = std::move(flow)]() mutable {
256 // We are going to terminate the trace flow here. Flows cannot
257 // terminate without a base trace. Add one explicitly.
258 TRACE_EVENT0("flutter", "ImageDecodeCallback");
259 flow.End();
260 callback(DlImageGPU::Make(std::move(image)), {});
261 raw_descriptor->Release();
262 }));
263 };
264
265 if (!raw_descriptor->data() || raw_descriptor->data()->size() == 0) {
266 result({}, std::move(flow));
267 return;
268 }
269
270 concurrent_task_runner_->PostTask(
271 fml::MakeCopyable([raw_descriptor, //
272 io_manager = io_manager_, //
273 io_runner = runners_.GetIOTaskRunner(), //
274 result, //
275 target_width = options.target_width, //
276 target_height = options.target_height, //
277 flow = std::move(flow) //
278 ]() mutable {
279 // Step 1: Decompress the image.
280 // On Worker.
281
282 auto decompressed = raw_descriptor->is_compressed()
283 ? ImageFromCompressedData(raw_descriptor, //
284 target_width, //
285 target_height, //
286 flow)
287 : ImageFromDecompressedData(raw_descriptor, //
288 target_width, //
289 target_height, //
290 flow);
291
292 if (!decompressed) {
293 FML_DLOG(ERROR) << "Could not decompress image.";
294 result({}, std::move(flow));
295 return;
296 }
297
298 // Step 2: Update the image to the GPU.
299 // On IO Thread.
300
301 io_runner->PostTask(fml::MakeCopyable([io_manager, decompressed, result,
302 flow =
303 std::move(flow)]() mutable {
304 if (!io_manager) {
305 FML_DLOG(ERROR) << "Could not acquire IO manager.";
306 result({}, std::move(flow));
307 return;
308 }
309
310 // If the IO manager does not have a resource context, the caller
311 // might not have set one or a software backend could be in use.
312 // Either way, just return the image as-is.
313 if (!io_manager->GetResourceContext()) {
314 result({std::move(decompressed), io_manager->GetSkiaUnrefQueue()},
315 std::move(flow));
316 return;
317 }
318
319 auto uploaded =
320 UploadRasterImage(std::move(decompressed), io_manager, flow);
321
322 if (!uploaded.skia_object()) {
323 FML_DLOG(ERROR) << "Could not upload image to the GPU.";
324 result({}, std::move(flow));
325 return;
326 }
327
328 // Finally, all done.
329 result(std::move(uploaded), std::move(flow));
330 }));
331 }));
332}
static sk_sp< DlImageGPU > Make(SkiaGPUObject< SkImage > image)
std::shared_ptr< fml::ConcurrentTaskRunner > concurrent_task_runner_
fml::WeakPtr< IOManager > io_manager_
fml::RefPtr< fml::TaskRunner > GetUITaskRunner() const
fml::RefPtr< fml::TaskRunner > GetIOTaskRunner() const
virtual bool RunsTasksOnCurrentThread()
FlutterVulkanImage * image
if(end==-1)
FlutterDesktopBinaryReply callback
#define FML_DLOG(severity)
Definition logging.h:121
#define FML_DCHECK(condition)
Definition logging.h:122
static SkiaGPUObject< SkImage > UploadRasterImage(sk_sp< SkImage > image, const fml::WeakPtr< IOManager > &io_manager, const fml::tracing::TraceFlow &flow)
internal::CopyableLambda< T > MakeCopyable(T lambda)
#define TRACE_EVENT0(category_group, name)

References callback, flutter::ImageDecoder::concurrent_task_runner_, fml::tracing::TraceFlow::End(), FML_DCHECK, fml::RefPtr< T >::get(), flutter::TaskRunners::GetIOTaskRunner(), flutter::TaskRunners::GetUITaskRunner(), if(), image, flutter::ImageDecoder::io_manager_, flutter::DlImageGPU::Make(), fml::MakeCopyable(), flutter::ImageDecoder::runners_, fml::TaskRunner::RunsTasksOnCurrentThread(), flutter::ImageDecoder::Options::target_height, flutter::ImageDecoder::Options::target_width, and TRACE_EVENT0.

◆ ImageFromCompressedData()

sk_sp< SkImage > flutter::ImageDecoderSkia::ImageFromCompressedData ( ImageDescriptor descriptor,
uint32_t  target_width,
uint32_t  target_height,
const fml::tracing::TraceFlow flow 
)
static

Definition at line 103 of file image_decoder_skia.cc.

107 {
108 TRACE_EVENT0("flutter", __FUNCTION__);
109 flow.Step(__FUNCTION__);
110
111 if (!descriptor->should_resize(target_width, target_height)) {
112 // No resizing requested. Just decode & rasterize the image.
113 sk_sp<SkImage> image = descriptor->image();
114 return image ? image->makeRasterImage(nullptr) : nullptr;
115 }
116
117 const SkImageInfo image_info =
118 ImageDescriptor::ToSkImageInfo(descriptor->image_info());
119 const SkISize source_dimensions = image_info.dimensions();
120 const SkISize resized_dimensions = {static_cast<int32_t>(target_width),
121 static_cast<int32_t>(target_height)};
122
123 auto decode_dimensions = descriptor->get_scaled_dimensions(
124 std::max(static_cast<float>(resized_dimensions.width()) /
125 source_dimensions.width(),
126 static_cast<float>(resized_dimensions.height()) /
127 source_dimensions.height()));
128
129 // If the codec supports efficient sub-pixel decoding, decoded at a resolution
130 // close to the target resolution before resizing.
131 if (decode_dimensions != source_dimensions) {
132 auto scaled_image_info = image_info.makeDimensions(decode_dimensions);
133
134 SkBitmap scaled_bitmap;
135 if (!scaled_bitmap.tryAllocPixels(scaled_image_info)) {
136 FML_LOG(ERROR) << "Failed to allocate memory for bitmap of size "
137 << scaled_image_info.computeMinByteSize() << "B";
138 return nullptr;
139 }
140
141 const auto& pixmap = scaled_bitmap.pixmap();
142 if (descriptor->get_pixels(pixmap)) {
143 // Marking this as immutable makes the MakeFromBitmap call share
144 // the pixels instead of copying.
145 scaled_bitmap.setImmutable();
146
147 auto decoded_image = SkImages::RasterFromBitmap(scaled_bitmap);
148 FML_DCHECK(decoded_image);
149 if (!decoded_image) {
150 FML_LOG(ERROR)
151 << "Could not create a scaled image from a scaled bitmap.";
152 return nullptr;
153 }
154 return ResizeRasterImage(decoded_image, resized_dimensions, flow);
155 }
156 }
157
158 auto image = descriptor->image();
159 if (!image) {
160 return nullptr;
161 }
162
163 return ResizeRasterImage(image, resized_dimensions, flow);
164}
static SkImageInfo ToSkImageInfo(const ImageInfo &image_info)
void Step(const char *label=nullptr) const
#define FML_LOG(severity)
Definition logging.h:101
static sk_sp< SkImage > ResizeRasterImage(const sk_sp< SkImage > &image, const SkISize &resized_dimensions, const fml::tracing::TraceFlow &flow)
FlutterVulkanImageHandle image
Definition embedder.h:931

References FML_DCHECK, FML_LOG, flutter::ImageDescriptor::get_pixels(), flutter::ImageDescriptor::get_scaled_dimensions(), flutter::ImageDescriptor::image(), image, flutter::ImageDescriptor::image_info(), flutter::ResizeRasterImage(), flutter::ImageDescriptor::should_resize(), fml::tracing::TraceFlow::Step(), flutter::ImageDescriptor::ToSkImageInfo(), and TRACE_EVENT0.

Referenced by flutter::testing::TEST(), flutter::testing::TEST(), and flutter::testing::TEST().


The documentation for this class was generated from the following files: