Flutter Engine
The Flutter Engine
image_decoder_impeller.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#include "flutter/lib/ui/painting/image_decoder_impeller.h"
6
7#include <memory>
8
9#include "flutter/fml/closure.h"
10#include "flutter/fml/make_copyable.h"
11#include "flutter/fml/trace_event.h"
12#include "flutter/impeller/core/allocator.h"
13#include "flutter/impeller/display_list/dl_image_impeller.h"
14#include "flutter/impeller/renderer/command_buffer.h"
15#include "flutter/impeller/renderer/context.h"
31
32namespace flutter {
33
34namespace {
35/**
36 * Loads the gamut as a set of three points (triangle).
37 */
38void LoadGamut(SkPoint abc[3], const skcms_Matrix3x3& xyz) {
39 // rx = rX / (rX + rY + rZ)
40 // ry = rY / (rX + rY + rZ)
41 // gx, gy, bx, and gy are calculated similarly.
42 for (int index = 0; index < 3; index++) {
43 float sum = xyz.vals[index][0] + xyz.vals[index][1] + xyz.vals[index][2];
44 abc[index].fX = xyz.vals[index][0] / sum;
45 abc[index].fY = xyz.vals[index][1] / sum;
46 }
47}
48
49/**
50 * Calculates the area of the triangular gamut.
51 */
52float CalculateArea(SkPoint abc[3]) {
53 const SkPoint& a = abc[0];
54 const SkPoint& b = abc[1];
55 const SkPoint& c = abc[2];
56 return 0.5f * fabsf(a.fX * b.fY + b.fX * c.fY - a.fX * c.fY - c.fX * b.fY -
57 b.fX * a.fY);
58}
59
60// Note: This was calculated from SkColorSpace::MakeSRGB().
61static constexpr float kSrgbGamutArea = 0.0982f;
62
63// Source:
64// https://source.chromium.org/chromium/_/skia/skia.git/+/393fb1ec80f41d8ad7d104921b6920e69749fda1:src/codec/SkAndroidCodec.cpp;l=67;drc=46572b4d445f41943059d0e377afc6d6748cd5ca;bpv=1;bpt=0
65bool IsWideGamut(const SkColorSpace* color_space) {
66 if (!color_space) {
67 return false;
68 }
69 skcms_Matrix3x3 xyzd50;
70 color_space->toXYZD50(&xyzd50);
71 SkPoint rgb[3];
72 LoadGamut(rgb, xyzd50);
73 float area = CalculateArea(rgb);
74 return area > kSrgbGamutArea;
75}
76} // namespace
77
79 const TaskRunners& runners,
80 std::shared_ptr<fml::ConcurrentTaskRunner> concurrent_task_runner,
81 const fml::WeakPtr<IOManager>& io_manager,
82 bool supports_wide_gamut,
83 const std::shared_ptr<fml::SyncSwitch>& gpu_disabled_switch)
84 : ImageDecoder(runners, std::move(concurrent_task_runner), io_manager),
85 supports_wide_gamut_(supports_wide_gamut),
86 gpu_disabled_switch_(gpu_disabled_switch) {
87 std::promise<std::shared_ptr<impeller::Context>> context_promise;
88 context_ = context_promise.get_future();
90 [promise = std::move(context_promise), io_manager]() mutable {
91 promise.set_value(io_manager ? io_manager->GetImpellerContext()
92 : nullptr);
93 }));
94}
95
97
99 switch (type) {
102 default:
104 }
105}
106
108 return type;
109}
110
112 ImageDescriptor* descriptor,
113 SkISize target_size,
114 impeller::ISize max_texture_size,
115 bool supports_wide_gamut,
116 const std::shared_ptr<impeller::Allocator>& allocator) {
117 TRACE_EVENT0("impeller", __FUNCTION__);
118 if (!descriptor) {
119 std::string decode_error("Invalid descriptor (should never happen)");
120 FML_DLOG(ERROR) << decode_error;
121 return DecompressResult{.decode_error = decode_error};
122 }
123
124 target_size.set(std::min(static_cast<int32_t>(max_texture_size.width),
125 target_size.width()),
126 std::min(static_cast<int32_t>(max_texture_size.height),
127 target_size.height()));
128
129 const SkISize source_size = descriptor->image_info().dimensions();
130 auto decode_size = source_size;
131 if (descriptor->is_compressed()) {
132 decode_size = descriptor->get_scaled_dimensions(std::max(
133 static_cast<float>(target_size.width()) / source_size.width(),
134 static_cast<float>(target_size.height()) / source_size.height()));
135 }
136
137 //----------------------------------------------------------------------------
138 /// 1. Decode the image.
139 ///
140
141 const auto base_image_info = descriptor->image_info();
142 const bool is_wide_gamut =
143 supports_wide_gamut ? IsWideGamut(base_image_info.colorSpace()) : false;
145 ChooseCompatibleAlphaType(base_image_info.alphaType());
146 SkImageInfo image_info;
147 if (is_wide_gamut) {
151 image_info =
152 base_image_info.makeWH(decode_size.width(), decode_size.height())
156 } else {
157 image_info =
158 base_image_info.makeWH(decode_size.width(), decode_size.height())
160 ChooseCompatibleColorType(base_image_info.colorType()))
162 }
163
164 const auto pixel_format =
166 if (!pixel_format.has_value()) {
167 std::string decode_error(impeller::SPrintF(
168 "Codec pixel format is not supported (SkColorType=%d)",
169 image_info.colorType()));
170 FML_DLOG(ERROR) << decode_error;
171 return DecompressResult{.decode_error = decode_error};
172 }
173
174 auto bitmap = std::make_shared<SkBitmap>();
175 bitmap->setInfo(image_info);
176 auto bitmap_allocator = std::make_shared<ImpellerAllocator>(allocator);
177
178 if (descriptor->is_compressed()) {
179 if (!bitmap->tryAllocPixels(bitmap_allocator.get())) {
180 std::string decode_error(
181 "Could not allocate intermediate for image decompression.");
182 FML_DLOG(ERROR) << decode_error;
183 return DecompressResult{.decode_error = decode_error};
184 }
185 // Decode the image into the image generator's closest supported size.
186 if (!descriptor->get_pixels(bitmap->pixmap())) {
187 std::string decode_error("Could not decompress image.");
188 FML_DLOG(ERROR) << decode_error;
189 return DecompressResult{.decode_error = decode_error};
190 }
191 } else {
192 auto temp_bitmap = std::make_shared<SkBitmap>();
193 temp_bitmap->setInfo(base_image_info);
194 auto pixel_ref = SkMallocPixelRef::MakeWithData(
195 base_image_info, descriptor->row_bytes(), descriptor->data());
196 temp_bitmap->setPixelRef(pixel_ref, 0, 0);
197
198 if (!bitmap->tryAllocPixels(bitmap_allocator.get())) {
199 std::string decode_error(
200 "Could not allocate intermediate for pixel conversion.");
201 FML_DLOG(ERROR) << decode_error;
202 return DecompressResult{.decode_error = decode_error};
203 }
204 temp_bitmap->readPixels(bitmap->pixmap());
205 bitmap->setImmutable();
206 }
207
208 if (bitmap->dimensions() == target_size) {
209 std::shared_ptr<impeller::DeviceBuffer> buffer =
210 bitmap_allocator->GetDeviceBuffer();
211 if (!buffer) {
212 return DecompressResult{.decode_error = "Unable to get device buffer"};
213 }
214 buffer->Flush();
215
216 return DecompressResult{.device_buffer = std::move(buffer),
217 .sk_bitmap = bitmap,
218 .image_info = bitmap->info()};
219 }
220
221 //----------------------------------------------------------------------------
222 /// 2. If the decoded image isn't the requested target size, resize it.
223 ///
224
225 TRACE_EVENT0("impeller", "DecodeScale");
226 const auto scaled_image_info = image_info.makeDimensions(target_size);
227
228 auto scaled_bitmap = std::make_shared<SkBitmap>();
229 auto scaled_allocator = std::make_shared<ImpellerAllocator>(allocator);
230 scaled_bitmap->setInfo(scaled_image_info);
231 if (!scaled_bitmap->tryAllocPixels(scaled_allocator.get())) {
232 std::string decode_error(
233 "Could not allocate scaled bitmap for image decompression.");
234 FML_DLOG(ERROR) << decode_error;
235 return DecompressResult{.decode_error = decode_error};
236 }
237 if (!bitmap->pixmap().scalePixels(
238 scaled_bitmap->pixmap(),
240 FML_LOG(ERROR) << "Could not scale decoded bitmap data.";
241 }
242 scaled_bitmap->setImmutable();
243
244 std::shared_ptr<impeller::DeviceBuffer> buffer =
245 scaled_allocator->GetDeviceBuffer();
246 buffer->Flush();
247
248 if (!buffer) {
249 return DecompressResult{.decode_error = "Unable to get device buffer"};
250 }
251 return DecompressResult{.device_buffer = std::move(buffer),
252 .sk_bitmap = scaled_bitmap,
253 .image_info = scaled_bitmap->info()};
254}
255
256/// Only call this method if the GPU is available.
257static std::pair<sk_sp<DlImage>, std::string> UnsafeUploadTextureToPrivate(
258 const std::shared_ptr<impeller::Context>& context,
259 const std::shared_ptr<impeller::DeviceBuffer>& buffer,
260 const SkImageInfo& image_info) {
261 const auto pixel_format =
263 if (!pixel_format) {
264 std::string decode_error(impeller::SPrintF(
265 "Unsupported pixel format (SkColorType=%d)", image_info.colorType()));
266 FML_DLOG(ERROR) << decode_error;
267 return std::make_pair(nullptr, decode_error);
268 }
269
270 impeller::TextureDescriptor texture_descriptor;
272 texture_descriptor.format = pixel_format.value();
273 texture_descriptor.size = {image_info.width(), image_info.height()};
274 texture_descriptor.mip_count = texture_descriptor.size.MipCount();
276
277 auto dest_texture =
278 context->GetResourceAllocator()->CreateTexture(texture_descriptor);
279 if (!dest_texture) {
280 std::string decode_error("Could not create Impeller texture.");
281 FML_DLOG(ERROR) << decode_error;
282 return std::make_pair(nullptr, decode_error);
283 }
284
285 dest_texture->SetLabel(
286 impeller::SPrintF("ui.Image(%p)", dest_texture.get()).c_str());
287
288 auto command_buffer = context->CreateCommandBuffer();
289 if (!command_buffer) {
290 std::string decode_error(
291 "Could not create command buffer for mipmap generation.");
292 FML_DLOG(ERROR) << decode_error;
293 return std::make_pair(nullptr, decode_error);
294 }
295 command_buffer->SetLabel("Mipmap Command Buffer");
296
297 auto blit_pass = command_buffer->CreateBlitPass();
298 if (!blit_pass) {
299 std::string decode_error(
300 "Could not create blit pass for mipmap generation.");
301 FML_DLOG(ERROR) << decode_error;
302 return std::make_pair(nullptr, decode_error);
303 }
304 blit_pass->SetLabel("Mipmap Blit Pass");
306 dest_texture);
307 if (texture_descriptor.size.MipCount() > 1) {
308 blit_pass->GenerateMipmap(dest_texture);
309 }
310
311 blit_pass->EncodeCommands(context->GetResourceAllocator());
312 if (!context->GetCommandQueue()->Submit({command_buffer}).ok()) {
313 std::string decode_error("Failed to submit blit pass command buffer.");
314 FML_DLOG(ERROR) << decode_error;
315 return std::make_pair(nullptr, decode_error);
316 }
317
318 return std::make_pair(
319 impeller::DlImageImpeller::Make(std::move(dest_texture)), std::string());
320}
321
322std::pair<sk_sp<DlImage>, std::string>
324 const std::shared_ptr<impeller::Context>& context,
325 const std::shared_ptr<impeller::DeviceBuffer>& buffer,
326 const SkImageInfo& image_info,
327 const std::shared_ptr<SkBitmap>& bitmap,
328 const std::shared_ptr<fml::SyncSwitch>& gpu_disabled_switch) {
329 TRACE_EVENT0("impeller", __FUNCTION__);
330 if (!context) {
331 return std::make_pair(nullptr, "No Impeller context is available");
332 }
333 if (!buffer) {
334 return std::make_pair(nullptr, "No Impeller device buffer is available");
335 }
336
337 std::pair<sk_sp<DlImage>, std::string> result;
338 gpu_disabled_switch->Execute(
340 .SetIfFalse([&result, context, buffer, image_info] {
341 result = UnsafeUploadTextureToPrivate(context, buffer, image_info);
342 })
343 .SetIfTrue([&result, context, bitmap, gpu_disabled_switch] {
344 // create_mips is false because we already know the GPU is disabled.
345 result =
346 UploadTextureToStorage(context, bitmap, gpu_disabled_switch,
348 /*create_mips=*/false);
349 }));
350 return result;
351}
352
353std::pair<sk_sp<DlImage>, std::string>
355 const std::shared_ptr<impeller::Context>& context,
356 std::shared_ptr<SkBitmap> bitmap,
357 const std::shared_ptr<fml::SyncSwitch>& gpu_disabled_switch,
358 impeller::StorageMode storage_mode,
359 bool create_mips) {
360 TRACE_EVENT0("impeller", __FUNCTION__);
361 if (!context) {
362 return std::make_pair(nullptr, "No Impeller context is available");
363 }
364 if (!bitmap) {
365 return std::make_pair(nullptr, "No texture bitmap is available");
366 }
367 const auto image_info = bitmap->info();
368 const auto pixel_format =
369 impeller::skia_conversions::ToPixelFormat(image_info.colorType());
370 if (!pixel_format) {
371 std::string decode_error(impeller::SPrintF(
372 "Unsupported pixel format (SkColorType=%d)", image_info.colorType()));
373 FML_DLOG(ERROR) << decode_error;
374 return std::make_pair(nullptr, decode_error);
375 }
376
377 impeller::TextureDescriptor texture_descriptor;
378 texture_descriptor.storage_mode = storage_mode;
379 texture_descriptor.format = pixel_format.value();
380 texture_descriptor.size = {image_info.width(), image_info.height()};
381 texture_descriptor.mip_count =
382 create_mips ? texture_descriptor.size.MipCount() : 1;
383
384 auto texture =
385 context->GetResourceAllocator()->CreateTexture(texture_descriptor);
386 if (!texture) {
387 std::string decode_error("Could not create Impeller texture.");
388 FML_DLOG(ERROR) << decode_error;
389 return std::make_pair(nullptr, decode_error);
390 }
391
392 auto mapping = std::make_shared<fml::NonOwnedMapping>(
393 reinterpret_cast<const uint8_t*>(bitmap->getAddr(0, 0)), // data
394 texture_descriptor.GetByteSizeOfBaseMipLevel(), // size
395 [bitmap](auto, auto) mutable { bitmap.reset(); } // proc
396 );
397
398 if (!texture->SetContents(mapping)) {
399 std::string decode_error("Could not copy contents into Impeller texture.");
400 FML_DLOG(ERROR) << decode_error;
401 return std::make_pair(nullptr, decode_error);
402 }
403
404 texture->SetLabel(impeller::SPrintF("ui.Image(%p)", texture.get()).c_str());
405
406 if (texture_descriptor.mip_count > 1u && create_mips) {
407 std::optional<std::string> decode_error;
408
409 // The only platform that needs mipmapping unconditionally is GL.
410 // GL based platforms never disable GPU access.
411 // This is only really needed for iOS.
412 gpu_disabled_switch->Execute(fml::SyncSwitch::Handlers().SetIfFalse(
413 [context, &texture, &decode_error] {
414 auto command_buffer = context->CreateCommandBuffer();
415 if (!command_buffer) {
416 decode_error =
417 "Could not create command buffer for mipmap generation.";
418 return;
419 }
420 command_buffer->SetLabel("Mipmap Command Buffer");
421
422 auto blit_pass = command_buffer->CreateBlitPass();
423 if (!blit_pass) {
424 decode_error = "Could not create blit pass for mipmap generation.";
425 return;
426 }
427 blit_pass->SetLabel("Mipmap Blit Pass");
428 blit_pass->GenerateMipmap(texture);
429 blit_pass->EncodeCommands(context->GetResourceAllocator());
430 if (!context->GetCommandQueue()->Submit({command_buffer}).ok()) {
431 decode_error = "Failed to submit blit pass command buffer.";
432 return;
433 }
434 command_buffer->WaitUntilScheduled();
435 }));
436 if (decode_error.has_value()) {
437 FML_DLOG(ERROR) << decode_error.value();
438 return std::make_pair(nullptr, decode_error.value());
439 }
440 }
441
442 return std::make_pair(impeller::DlImageImpeller::Make(std::move(texture)),
443 std::string());
444}
445
446// |ImageDecoder|
448 uint32_t target_width,
449 uint32_t target_height,
450 const ImageResult& p_result) {
451 FML_DCHECK(descriptor);
452 FML_DCHECK(p_result);
453
454 // Wrap the result callback so that it can be invoked from any thread.
455 auto raw_descriptor = descriptor.get();
456 raw_descriptor->AddRef();
457 ImageResult result = [p_result, //
458 raw_descriptor, //
459 ui_runner = runners_.GetUITaskRunner() //
460 ](auto image, auto decode_error) {
461 ui_runner->PostTask([raw_descriptor, p_result, image, decode_error]() {
462 raw_descriptor->Release();
463 p_result(std::move(image), decode_error);
464 });
465 };
466
467 concurrent_task_runner_->PostTask(
468 [raw_descriptor, //
469 context = context_.get(), //
470 target_size = SkISize::Make(target_width, target_height), //
471 io_runner = runners_.GetIOTaskRunner(), //
472 result,
473 supports_wide_gamut = supports_wide_gamut_, //
474 gpu_disabled_switch = gpu_disabled_switch_]() {
475 if (!context) {
476 result(nullptr, "No Impeller context is available");
477 return;
478 }
479 auto max_size_supported =
480 context->GetResourceAllocator()->GetMaxTextureSizeSupported();
481
482 // Always decompress on the concurrent runner.
483 auto bitmap_result = DecompressTexture(
484 raw_descriptor, target_size, max_size_supported,
485 supports_wide_gamut, context->GetResourceAllocator());
486 if (!bitmap_result.device_buffer) {
487 result(nullptr, bitmap_result.decode_error);
488 return;
489 }
490
491 auto upload_texture_and_invoke_result = [result, context, bitmap_result,
492 gpu_disabled_switch]() {
494 std::string decode_error;
495 std::tie(image, decode_error) = UploadTextureToPrivate(
496 context, bitmap_result.device_buffer, bitmap_result.image_info,
497 bitmap_result.sk_bitmap, gpu_disabled_switch);
498 result(image, decode_error);
499 };
500 io_runner->PostTask(upload_texture_and_invoke_result);
501 });
502}
503
505 std::shared_ptr<impeller::Allocator> allocator)
506 : allocator_(std::move(allocator)) {}
507
508std::shared_ptr<impeller::DeviceBuffer> ImpellerAllocator::GetDeviceBuffer()
509 const {
510 return buffer_;
511}
512
514 if (!bitmap) {
515 return false;
516 }
517 const SkImageInfo& info = bitmap->info();
518 if (kUnknown_SkColorType == info.colorType() || info.width() < 0 ||
519 info.height() < 0 || !info.validRowBytes(bitmap->rowBytes())) {
520 return false;
521 }
522
525 descriptor.size = ((bitmap->height() - 1) * bitmap->rowBytes()) +
526 (bitmap->width() * bitmap->bytesPerPixel());
527
528 std::shared_ptr<impeller::DeviceBuffer> device_buffer =
529 allocator_->CreateBuffer(descriptor);
530 if (!device_buffer) {
531 return false;
532 }
533
534 struct ImpellerPixelRef final : public SkPixelRef {
535 ImpellerPixelRef(int w, int h, void* s, size_t r)
536 : SkPixelRef(w, h, s, r) {}
537
538 ~ImpellerPixelRef() override {}
539 };
540
541 auto pixel_ref = sk_sp<SkPixelRef>(
542 new ImpellerPixelRef(info.width(), info.height(),
543 device_buffer->OnGetContents(), bitmap->rowBytes()));
544
545 bitmap->setPixelRef(std::move(pixel_ref), 0, 0);
546 buffer_ = std::move(device_buffer);
547 return true;
548}
549
550} // namespace flutter
static void info(const char *fmt,...) SK_PRINTF_LIKE(1
Definition: DM.cpp:213
SkAlphaType
Definition: SkAlphaType.h:26
@ kOpaque_SkAlphaType
pixel is opaque
Definition: SkAlphaType.h:28
SkColorType
Definition: SkColorType.h:19
@ kRGBA_F16_SkColorType
pixel with half floats for red, green, blue, alpha;
Definition: SkColorType.h:38
@ kRGBA_8888_SkColorType
pixel with 8 bits for red, green, blue, alpha; in 32-bit word
Definition: SkColorType.h:24
@ kRGBA_F32_SkColorType
pixel using C float for red, green, blue, alpha; in 128-bit word
Definition: SkColorType.h:40
@ kBGR_101010x_XR_SkColorType
pixel with 10 bits each for blue, green, red; in 32-bit word, extended range
Definition: SkColorType.h:31
@ kUnknown_SkColorType
uninitialized
Definition: SkColorType.h:20
GLenum type
bool toXYZD50(skcms_Matrix3x3 *toXYZD50) const
static sk_sp< SkColorSpace > MakeSRGB()
void Decode(fml::RefPtr< ImageDescriptor > descriptor, uint32_t target_width, uint32_t target_height, const ImageResult &result) override
static std::pair< sk_sp< DlImage >, std::string > UploadTextureToStorage(const std::shared_ptr< impeller::Context > &context, std::shared_ptr< SkBitmap > bitmap, const std::shared_ptr< fml::SyncSwitch > &gpu_disabled_switch, impeller::StorageMode storage_mode, bool create_mips=true)
Create a host visible texture from the provided bitmap.
ImageDecoderImpeller(const TaskRunners &runners, std::shared_ptr< fml::ConcurrentTaskRunner > concurrent_task_runner, const fml::WeakPtr< IOManager > &io_manager, bool supports_wide_gamut, const std::shared_ptr< fml::SyncSwitch > &gpu_disabled_switch)
static std::pair< sk_sp< DlImage >, std::string > UploadTextureToPrivate(const std::shared_ptr< impeller::Context > &context, const std::shared_ptr< impeller::DeviceBuffer > &buffer, const SkImageInfo &image_info, const std::shared_ptr< SkBitmap > &bitmap, const std::shared_ptr< fml::SyncSwitch > &gpu_disabled_switch)
Create a device private texture from the provided host buffer. This method is only suported on the me...
static DecompressResult DecompressTexture(ImageDescriptor *descriptor, SkISize target_size, impeller::ISize max_texture_size, bool supports_wide_gamut, const std::shared_ptr< impeller::Allocator > &allocator)
std::function< void(sk_sp< DlImage >, std::string)> ImageResult
Definition: image_decoder.h:35
std::shared_ptr< fml::ConcurrentTaskRunner > concurrent_task_runner_
Definition: image_decoder.h:51
Creates an image descriptor for encoded or decoded image data, describing the width,...
const SkImageInfo & image_info() const
The orientation corrected image info for this image.
SkISize get_scaled_dimensions(float scale)
Gets the scaled dimensions of this image, if backed by an ImageGenerator that can perform efficient s...
int row_bytes() const
The byte length of the first row of the image. Defaults to width() * 4.
bool get_pixels(const SkPixmap &pixmap) const
Gets pixels for this image transformed based on the EXIF orientation tag, if applicable.
bool is_compressed() const
Whether this descriptor represents compressed (encoded) data or not.
sk_sp< SkData > data() const
The underlying buffer for this image.
bool allocPixelRef(SkBitmap *bitmap) override
ImpellerAllocator(std::shared_ptr< impeller::Allocator > allocator)
std::shared_ptr< impeller::DeviceBuffer > GetDeviceBuffer() const
fml::RefPtr< fml::TaskRunner > GetUITaskRunner() const
Definition: task_runners.cc:34
fml::RefPtr< fml::TaskRunner > GetIOTaskRunner() const
Definition: task_runners.cc:38
T * get() const
Definition: ref_ptr.h:116
virtual void PostTask(const fml::closure &task) override
Definition: task_runner.cc:24
static BufferView AsBufferView(std::shared_ptr< DeviceBuffer > buffer)
Create a buffer view of this entire buffer.
static sk_sp< DlImageImpeller > Make(std::shared_ptr< Texture > texture, OwningContext owning_context=OwningContext::kIO)
static bool b
struct MyStruct s
struct MyStruct a[10]
if(end==-1)
GAsyncResult * result
#define FML_DLOG(severity)
Definition: logging.h:102
#define FML_LOG(severity)
Definition: logging.h:82
#define FML_DCHECK(condition)
Definition: logging.h:103
static float max(float r, float g, float b)
Definition: hsl.cpp:49
static float min(float r, float g, float b)
Definition: hsl.cpp:48
FlTexture * texture
SK_API sk_sp< SkPixelRef > MakeWithData(const SkImageInfo &, size_t rowBytes, sk_sp< SkData > data)
sk_sp< const SkImage > image
Definition: SkRecords.h:269
Definition: bitmap.py:1
static std::pair< sk_sp< DlImage >, std::string > UnsafeUploadTextureToPrivate(const std::shared_ptr< impeller::Context > &context, const std::shared_ptr< impeller::DeviceBuffer > &buffer, const SkImageInfo &image_info)
Only call this method if the GPU is available.
static SkAlphaType ChooseCompatibleAlphaType(SkAlphaType type)
static SkColorType ChooseCompatibleColorType(SkColorType type)
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot The VM snapshot data that will be memory mapped as read only SnapshotAssetPath must be present isolate snapshot The isolate snapshot data that will be memory mapped as read only SnapshotAssetPath must be present cache dir Path to the cache directory This is different from the persistent_cache_path in embedder which is used for Skia shader cache icu native lib Path to the library file that exports the ICU data vm service The hostname IP address on which the Dart VM Service should be served If not defaults to or::depending on whether ipv6 is specified vm service A custom Dart VM Service port The default is to pick a randomly available open port disable vm Disable the Dart VM Service The Dart VM Service is never available in release mode disable vm service Disable mDNS Dart VM Service publication Bind to the IPv6 localhost address for the Dart VM Service Ignored if vm service host is set endless trace buffer
Definition: switches.h:126
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot The VM snapshot data that will be memory mapped as read only SnapshotAssetPath must be present isolate snapshot The isolate snapshot data that will be memory mapped as read only SnapshotAssetPath must be present cache dir Path to the cache directory This is different from the persistent_cache_path in embedder h
Definition: switches.h:59
internal::CopyableLambda< T > MakeCopyable(T lambda)
Definition: make_copyable.h:57
std::optional< impeller::PixelFormat > ToPixelFormat(SkColorType type)
StorageMode
Specified where the allocation resides and how it is used.
Definition: formats.h:32
std::string SPrintF(const char *format,...)
Definition: strings.cc:12
Definition: ref_ptr.h:256
SkScalar w
uint32_t color_type
uint32_t alpha_type
Definition: SkSize.h:16
static constexpr SkISize Make(int32_t w, int32_t h)
Definition: SkSize.h:20
constexpr int32_t width() const
Definition: SkSize.h:36
void set(int32_t w, int32_t h)
Definition: SkSize.h:24
constexpr int32_t height() const
Definition: SkSize.h:37
SkImageInfo makeWH(int newWidth, int newHeight) const
Definition: SkImageInfo.h:444
SkImageInfo makeAlphaType(SkAlphaType newAlphaType) const
Definition: SkImageInfo.h:466
SkImageInfo makeDimensions(SkISize newSize) const
Definition: SkImageInfo.h:454
SkISize dimensions() const
Definition: SkImageInfo.h:421
SkImageInfo makeColorSpace(sk_sp< SkColorSpace > cs) const
int width() const
Definition: SkImageInfo.h:365
SkColorType colorType() const
Definition: SkImageInfo.h:373
int height() const
Definition: SkImageInfo.h:371
SkImageInfo makeColorType(SkColorType newColorType) const
Definition: SkImageInfo.h:475
float fX
x-axis value
Definition: SkPoint_impl.h:164
float fY
y-axis value
Definition: SkPoint_impl.h:165
std::shared_ptr< impeller::DeviceBuffer > device_buffer
Represents the 2 code paths available when calling |SyncSwitch::Execute|.
Definition: sync_switch.h:35
Type height
Definition: size.h:23
Type width
Definition: size.h:22
constexpr size_t MipCount() const
Definition: size.h:115
A lightweight object that describes the attributes of a texture that can then used an allocator to cr...
constexpr size_t GetByteSizeOfBaseMipLevel() const
float vals[3][3]
Definition: skcms_public.h:27
#define ERROR(message)
Definition: elf_loader.cc:260
#define TRACE_EVENT0(category_group, name)
Definition: trace_event.h:131