Flutter Engine
The Flutter Engine
image_encoding_unittests.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 "png.h"
6
7#include "flutter/lib/ui/painting/image_encoding.h"
8#include "flutter/lib/ui/painting/image_encoding_impl.h"
9
10#include "flutter/common/task_runners.h"
11#include "flutter/fml/synchronization/waitable_event.h"
12#include "flutter/lib/ui/painting/image.h"
13#include "flutter/runtime/dart_vm.h"
14#include "flutter/shell/common/shell_test.h"
15#include "flutter/shell/common/thread_host.h"
16#include "flutter/testing/testing.h"
17#include "gmock/gmock.h"
18#include "gtest/gtest.h"
19
20#if IMPELLER_SUPPORTS_RENDERING
21#include "flutter/lib/ui/painting/image_encoding_impeller.h"
23#endif // IMPELLER_SUPPORTS_RENDERING
24
25// CREATE_NATIVE_ENTRY is leaky by design
26// NOLINTBEGIN(clang-analyzer-core.StackAddressEscape)
27
28#pragma GCC diagnostic ignored "-Wunreachable-code"
29
30namespace flutter {
31namespace testing {
32
33namespace {
34fml::AutoResetWaitableEvent message_latch;
35
36class MockDlImage : public DlImage {
37 public:
38 MOCK_METHOD(sk_sp<SkImage>, skia_image, (), (const, override));
39 MOCK_METHOD(std::shared_ptr<impeller::Texture>,
40 impeller_texture,
41 (),
42 (const, override));
43 MOCK_METHOD(bool, isOpaque, (), (const, override));
44 MOCK_METHOD(bool, isTextureBacked, (), (const, override));
45 MOCK_METHOD(bool, isUIThreadSafe, (), (const, override));
46 MOCK_METHOD(SkISize, dimensions, (), (const, override));
47 MOCK_METHOD(size_t, GetApproximateByteSize, (), (const, override));
48};
49
50} // namespace
51
53 public:
54 struct Handlers {
55 Handlers& SetIfTrue(const std::function<void()>& handler) {
56 true_handler = handler;
57 return *this;
58 }
59 Handlers& SetIfFalse(const std::function<void()>& handler) {
60 false_handler = handler;
61 return *this;
62 }
63 std::function<void()> true_handler = [] {};
65 };
66
67 MOCK_METHOD(void, Execute, (const Handlers& handlers), (const));
68 MOCK_METHOD(void, SetSwitch, (bool value));
69};
70
71TEST_F(ShellTest, EncodeImageGivesExternalTypedData) {
72 auto native_encode_image = [&](Dart_NativeArguments args) {
73 auto image_handle = Dart_GetNativeArgument(args, 0);
74 image_handle =
75 Dart_GetField(image_handle, Dart_NewStringFromCString("_image"));
76 ASSERT_FALSE(Dart_IsError(image_handle)) << Dart_GetError(image_handle);
77 ASSERT_FALSE(Dart_IsNull(image_handle));
78 auto format_handle = Dart_GetNativeArgument(args, 1);
79 auto callback_handle = Dart_GetNativeArgument(args, 2);
80
81 intptr_t peer = 0;
83 image_handle, tonic::DartWrappable::kPeerIndex, &peer);
84 ASSERT_FALSE(Dart_IsError(result));
85 CanvasImage* canvas_image = reinterpret_cast<CanvasImage*>(peer);
86
87 int64_t format = -1;
88 result = Dart_IntegerToInt64(format_handle, &format);
89 ASSERT_FALSE(Dart_IsError(result));
90
91 result = EncodeImage(canvas_image, format, callback_handle);
92 ASSERT_TRUE(Dart_IsNull(result));
93 };
94
95 auto nativeValidateExternal = [&](Dart_NativeArguments args) {
96 auto handle = Dart_GetNativeArgument(args, 0);
97
98 auto typed_data_type = Dart_GetTypeOfExternalTypedData(handle);
99 EXPECT_EQ(typed_data_type, Dart_TypedData_kUint8);
100
101 message_latch.Signal();
102 };
103
104 Settings settings = CreateSettingsForFixture();
105 TaskRunners task_runners("test", // label
106 GetCurrentTaskRunner(), // platform
107 CreateNewThread(), // raster
108 CreateNewThread(), // ui
109 CreateNewThread() // io
110 );
111
112 AddNativeCallback("EncodeImage", CREATE_NATIVE_ENTRY(native_encode_image));
113 AddNativeCallback("ValidateExternal",
114 CREATE_NATIVE_ENTRY(nativeValidateExternal));
115
116 std::unique_ptr<Shell> shell = CreateShell(settings, task_runners);
117
118 ASSERT_TRUE(shell->IsSetup());
119 auto configuration = RunConfiguration::InferFromSettings(settings);
120 configuration.SetEntrypoint("encodeImageProducesExternalUint8List");
121
122 shell->RunEngine(std::move(configuration), [&](auto result) {
124 });
125
126 message_latch.Wait();
127 DestroyShell(std::move(shell), task_runners);
128}
129
130TEST_F(ShellTest, EncodeImageAccessesSyncSwitch) {
131 Settings settings = CreateSettingsForFixture();
132 TaskRunners task_runners("test", // label
133 GetCurrentTaskRunner(), // platform
134 CreateNewThread(), // raster
135 CreateNewThread(), // ui
136 CreateNewThread() // io
137 );
138
139 auto native_encode_image = [&](Dart_NativeArguments args) {
140 auto image_handle = Dart_GetNativeArgument(args, 0);
141 image_handle =
142 Dart_GetField(image_handle, Dart_NewStringFromCString("_image"));
143 ASSERT_FALSE(Dart_IsError(image_handle)) << Dart_GetError(image_handle);
144 ASSERT_FALSE(Dart_IsNull(image_handle));
145 auto format_handle = Dart_GetNativeArgument(args, 1);
146
147 intptr_t peer = 0;
149 image_handle, tonic::DartWrappable::kPeerIndex, &peer);
150 ASSERT_FALSE(Dart_IsError(result));
151 CanvasImage* canvas_image = reinterpret_cast<CanvasImage*>(peer);
152
153 int64_t format = -1;
154 result = Dart_IntegerToInt64(format_handle, &format);
155 ASSERT_FALSE(Dart_IsError(result));
156
157 auto io_manager = UIDartState::Current()->GetIOManager();
159
160 task_runners.GetIOTaskRunner()->PostTask([&]() {
161 auto is_gpu_disabled_sync_switch =
162 std::make_shared<const MockSyncSwitch>();
163 EXPECT_CALL(*is_gpu_disabled_sync_switch, Execute)
164 .WillOnce([](const MockSyncSwitch::Handlers& handlers) {
165 handlers.true_handler();
166 });
167 ConvertToRasterUsingResourceContext(canvas_image->image()->skia_image(),
168 io_manager->GetResourceContext(),
169 is_gpu_disabled_sync_switch);
170 latch.Signal();
171 });
172
173 latch.Wait();
174
175 message_latch.Signal();
176 };
177
178 AddNativeCallback("EncodeImage", CREATE_NATIVE_ENTRY(native_encode_image));
179
180 std::unique_ptr<Shell> shell = CreateShell(settings, task_runners);
181
182 ASSERT_TRUE(shell->IsSetup());
183 auto configuration = RunConfiguration::InferFromSettings(settings);
184 configuration.SetEntrypoint("encodeImageProducesExternalUint8List");
185
186 shell->RunEngine(std::move(configuration), [&](auto result) {
188 });
189
190 message_latch.Wait();
191 DestroyShell(std::move(shell), task_runners);
192}
193
194#if IMPELLER_SUPPORTS_RENDERING
195using ::impeller::testing::MockAllocator;
196using ::impeller::testing::MockBlitPass;
197using ::impeller::testing::MockCommandBuffer;
198using ::impeller::testing::MockCommandQueue;
199using ::impeller::testing::MockDeviceBuffer;
200using ::impeller::testing::MockImpellerContext;
201using ::impeller::testing::MockTexture;
202using ::testing::_;
203using ::testing::DoAll;
205using ::testing::InvokeArgument;
206using ::testing::Return;
207
208namespace {
209std::shared_ptr<impeller::Context> MakeConvertDlImageToSkImageContext(
210 std::vector<uint8_t>& buffer) {
211 auto context = std::make_shared<MockImpellerContext>();
212 auto command_buffer = std::make_shared<MockCommandBuffer>(context);
213 auto allocator = std::make_shared<MockAllocator>();
214 auto blit_pass = std::make_shared<MockBlitPass>();
215 auto command_queue = std::make_shared<MockCommandQueue>();
216 impeller::DeviceBufferDescriptor device_buffer_desc;
217 device_buffer_desc.size = buffer.size();
218 auto device_buffer = std::make_shared<MockDeviceBuffer>(device_buffer_desc);
219 EXPECT_CALL(*allocator, OnCreateBuffer).WillOnce(Return(device_buffer));
220 EXPECT_CALL(*blit_pass, IsValid).WillRepeatedly(Return(true));
221 EXPECT_CALL(*command_buffer, IsValid).WillRepeatedly(Return(true));
222 EXPECT_CALL(*command_buffer, OnCreateBlitPass).WillOnce(Return(blit_pass));
223 EXPECT_CALL(*context, GetResourceAllocator).WillRepeatedly(Return(allocator));
224 EXPECT_CALL(*context, CreateCommandBuffer).WillOnce(Return(command_buffer));
225 EXPECT_CALL(*device_buffer, OnGetContents).WillOnce(Return(buffer.data()));
226 EXPECT_CALL(*command_queue, Submit(_, _))
227 .WillRepeatedly(
228 DoAll(InvokeArgument<1>(impeller::CommandBuffer::Status::kCompleted),
229 Return(fml::Status())));
230 EXPECT_CALL(*context, GetCommandQueue).WillRepeatedly(Return(command_queue));
231 return context;
232}
233} // namespace
234
235TEST_F(ShellTest, EncodeImageRetries) {
236#ifndef FML_OS_MACOSX
237 GTEST_SKIP() << "Only works on macos currently.";
238#endif
239 Settings settings = CreateSettingsForFixture();
240 settings.enable_impeller = true;
241 TaskRunners task_runners("test", // label
242 GetCurrentTaskRunner(), // platform
243 CreateNewThread(), // raster
244 CreateNewThread(), // ui
245 CreateNewThread() // io
246 );
247
248 std::unique_ptr<Shell> shell = CreateShell({
249 .settings = settings,
250 .task_runners = task_runners,
251 });
252
253 auto turn_off_gpu = [&](Dart_NativeArguments args) {
254 auto handle = Dart_GetNativeArgument(args, 0);
255 bool value = true;
256 ASSERT_TRUE(Dart_IsBoolean(handle));
257 Dart_BooleanValue(handle, &value);
258 TurnOffGPU(shell.get(), value);
259 };
260
261 AddNativeCallback("TurnOffGPU", CREATE_NATIVE_ENTRY(turn_off_gpu));
262
263 auto validate_not_null = [&](Dart_NativeArguments args) {
264 auto handle = Dart_GetNativeArgument(args, 0);
265 EXPECT_FALSE(Dart_IsNull(handle));
266 message_latch.Signal();
267 };
268
269 AddNativeCallback("ValidateNotNull", CREATE_NATIVE_ENTRY(validate_not_null));
270
271 ASSERT_TRUE(shell->IsSetup());
272 auto configuration = RunConfiguration::InferFromSettings(settings);
273 configuration.SetEntrypoint("toByteDataRetries");
274
275 shell->RunEngine(std::move(configuration), [&](auto result) {
277 });
278
279 message_latch.Wait();
280 DestroyShell(std::move(shell), task_runners);
281}
282
283TEST_F(ShellTest, ToImageRetries) {
284#ifndef FML_OS_MACOSX
285 GTEST_SKIP() << "Only works on macos currently.";
286#endif
287 Settings settings = CreateSettingsForFixture();
288 settings.enable_impeller = true;
289 TaskRunners task_runners("test", // label
290 GetCurrentTaskRunner(), // platform
291 CreateNewThread(), // raster
292 CreateNewThread(), // ui
293 CreateNewThread() // io
294 );
295
296 std::unique_ptr<Shell> shell = CreateShell({
297 .settings = settings,
298 .task_runners = task_runners,
299 });
300
301 auto turn_off_gpu = [&](Dart_NativeArguments args) {
302 auto handle = Dart_GetNativeArgument(args, 0);
303 bool value = true;
304 ASSERT_TRUE(Dart_IsBoolean(handle));
305 Dart_BooleanValue(handle, &value);
306 TurnOffGPU(shell.get(), value);
307 };
308
309 AddNativeCallback("TurnOffGPU", CREATE_NATIVE_ENTRY(turn_off_gpu));
310
311 auto validate_not_null = [&](Dart_NativeArguments args) {
312 auto handle = Dart_GetNativeArgument(args, 0);
313 EXPECT_FALSE(Dart_IsNull(handle));
314 message_latch.Signal();
315 };
316
317 AddNativeCallback("ValidateNotNull", CREATE_NATIVE_ENTRY(validate_not_null));
318
319 ASSERT_TRUE(shell->IsSetup());
320 auto configuration = RunConfiguration::InferFromSettings(settings);
321 configuration.SetEntrypoint("toImageRetries");
322
323 shell->RunEngine(std::move(configuration), [&](auto result) {
325 });
326
327 message_latch.Wait();
328 DestroyShell(std::move(shell), task_runners);
329}
330
331TEST_F(ShellTest, EncodeImageFailsWithoutGPUImpeller) {
332#ifndef FML_OS_MACOSX
333 // Only works on macos currently.
334 GTEST_SKIP();
335#endif
336 Settings settings = CreateSettingsForFixture();
337 settings.enable_impeller = true;
338 TaskRunners task_runners("test", // label
339 GetCurrentTaskRunner(), // platform
340 CreateNewThread(), // raster
341 CreateNewThread(), // ui
342 CreateNewThread() // io
343 );
344
345 auto native_validate_error = [&](Dart_NativeArguments args) {
346 auto handle = Dart_GetNativeArgument(args, 0);
347
348 EXPECT_FALSE(Dart_IsNull(handle));
349
350 message_latch.Signal();
351 };
352
353 AddNativeCallback("ValidateError",
354 CREATE_NATIVE_ENTRY(native_validate_error));
355
356 std::unique_ptr<Shell> shell = CreateShell({
357 .settings = settings,
358 .task_runners = task_runners,
359 });
360
361 auto turn_off_gpu = [&](Dart_NativeArguments args) {
362 auto handle = Dart_GetNativeArgument(args, 0);
363 bool value = true;
364 ASSERT_TRUE(Dart_IsBoolean(handle));
365 Dart_BooleanValue(handle, &value);
366 TurnOffGPU(shell.get(), true);
367 };
368
369 AddNativeCallback("TurnOffGPU", CREATE_NATIVE_ENTRY(turn_off_gpu));
370
371 auto flush_awaiting_tasks = [&](Dart_NativeArguments args) {
372 task_runners.GetIOTaskRunner()->PostTask([&] {
373 std::shared_ptr<impeller::Context> impeller_context =
374 shell->GetIOManager()->GetImpellerContext();
375 // This will cause the stored tasks to overflow and start throwing them
376 // away.
377 for (int i = 0; i < impeller::Context::kMaxTasksAwaitingGPU; ++i) {
378 impeller_context->StoreTaskForGPU([] {});
379 }
380 });
381 };
382
383 AddNativeCallback("FlushGpuAwaitingTasks",
384 CREATE_NATIVE_ENTRY(flush_awaiting_tasks));
385
386 ASSERT_TRUE(shell->IsSetup());
387 auto configuration = RunConfiguration::InferFromSettings(settings);
388 configuration.SetEntrypoint("toByteDataWithoutGPU");
389
390 shell->RunEngine(std::move(configuration), [&](auto result) {
392 });
393
394 message_latch.Wait();
395 DestroyShell(std::move(shell), task_runners);
396}
397
398TEST(ImageEncodingImpellerTest, ConvertDlImageToSkImage16Float) {
399 sk_sp<MockDlImage> image(new MockDlImage());
400 EXPECT_CALL(*image, dimensions)
401 .WillRepeatedly(Return(SkISize::Make(100, 100)));
404 auto texture = std::make_shared<MockTexture>(desc);
405 EXPECT_CALL(*image, impeller_texture).WillOnce(Return(texture));
406 std::vector<uint8_t> buffer;
407 buffer.reserve(100 * 100 * 8);
408 auto context = MakeConvertDlImageToSkImageContext(buffer);
409 bool did_call = false;
411 image,
412 [&did_call](const fml::StatusOr<sk_sp<SkImage>>& image) {
413 did_call = true;
414 ASSERT_TRUE(image.ok());
415 ASSERT_TRUE(image.value());
416 EXPECT_EQ(100, image.value()->width());
417 EXPECT_EQ(100, image.value()->height());
418 EXPECT_EQ(kRGBA_F16_SkColorType, image.value()->colorType());
419 EXPECT_EQ(nullptr, image.value()->colorSpace());
420 },
421 context);
422 EXPECT_TRUE(did_call);
423}
424
425TEST(ImageEncodingImpellerTest, ConvertDlImageToSkImage10XR) {
426 sk_sp<MockDlImage> image(new MockDlImage());
427 EXPECT_CALL(*image, dimensions)
428 .WillRepeatedly(Return(SkISize::Make(100, 100)));
431 auto texture = std::make_shared<MockTexture>(desc);
432 EXPECT_CALL(*image, impeller_texture).WillOnce(Return(texture));
433 std::vector<uint8_t> buffer;
434 buffer.reserve(100 * 100 * 4);
435 auto context = MakeConvertDlImageToSkImageContext(buffer);
436 bool did_call = false;
438 image,
439 [&did_call](const fml::StatusOr<sk_sp<SkImage>>& image) {
440 did_call = true;
441 ASSERT_TRUE(image.ok());
442 ASSERT_TRUE(image.value());
443 EXPECT_EQ(100, image.value()->width());
444 EXPECT_EQ(100, image.value()->height());
445 EXPECT_EQ(kBGR_101010x_XR_SkColorType, image.value()->colorType());
446 EXPECT_EQ(nullptr, image.value()->colorSpace());
447 },
448 context);
449 EXPECT_TRUE(did_call);
450}
451
452TEST(ImageEncodingImpellerTest, PngEncoding10XR) {
453 int width = 100;
454 int height = 100;
457
459 SkCanvas* canvas = surface->getCanvas();
460
462 paint.setColor(SK_ColorBLUE);
463 paint.setAntiAlias(true);
464
465 canvas->clear(SK_ColorWHITE);
466 canvas->drawCircle(width / 2, height / 2, 100, paint);
467
468 sk_sp<SkImage> image = surface->makeImageSnapshot();
469
470 fml::StatusOr<sk_sp<SkData>> png = EncodeImage(image, ImageByteFormat::kPNG);
471 EXPECT_TRUE(png.ok());
472}
473
474namespace {
475struct PngMemoryReader {
476 const uint8_t* data;
477 size_t offset;
478 size_t size;
479};
480
481void PngMemoryRead(png_structp png_ptr,
482 png_bytep out_bytes,
483 png_size_t byte_count_to_read) {
484 PngMemoryReader* memory_reader =
485 reinterpret_cast<PngMemoryReader*>(png_get_io_ptr(png_ptr));
486 if (memory_reader->offset + byte_count_to_read > memory_reader->size) {
487 png_error(png_ptr, "Read error in PngMemoryRead");
488 }
489 memcpy(out_bytes, memory_reader->data + memory_reader->offset,
490 byte_count_to_read);
491 memory_reader->offset += byte_count_to_read;
492}
493
494fml::StatusOr<std::vector<uint32_t>> ReadPngFromMemory(const uint8_t* png_data,
495 size_t png_size) {
496 png_structp png =
497 png_create_read_struct(PNG_LIBPNG_VER_STRING, nullptr, nullptr, nullptr);
498 if (!png) {
499 return fml::Status(fml::StatusCode::kAborted, "unknown");
500 }
501
502 png_infop info = png_create_info_struct(png);
503 if (!info) {
504 png_destroy_read_struct(&png, nullptr, nullptr);
505 return fml::Status(fml::StatusCode::kAborted, "unknown");
506 }
507
508 fml::ScopedCleanupClosure png_cleanup(
509 [&png, &info]() { png_destroy_read_struct(&png, &info, nullptr); });
510
511 if (setjmp(png_jmpbuf(png))) {
512 return fml::Status(fml::StatusCode::kAborted, "unknown");
513 }
514
515 PngMemoryReader memory_reader = {
516 .data = png_data, .offset = 0, .size = png_size};
517 png_set_read_fn(png, &memory_reader, PngMemoryRead);
518
519 png_read_info(png, info);
520
521 int width = png_get_image_width(png, info);
522 int height = png_get_image_height(png, info);
523 png_byte color_type = png_get_color_type(png, info);
524 png_byte bit_depth = png_get_bit_depth(png, info);
525
526 if (bit_depth == 16) {
527 png_set_strip_16(png);
528 }
529 if (color_type == PNG_COLOR_TYPE_PALETTE) {
530 png_set_palette_to_rgb(png);
531 }
532
533 png_read_update_info(png, info);
534 std::vector<uint32_t> result(width * height);
535 std::vector<png_bytep> row_pointers;
536 row_pointers.reserve(height);
537
538 for (int i = 0; i < height; ++i) {
539 row_pointers.push_back(
540 reinterpret_cast<png_bytep>(result.data() + i * width));
541 }
542
543 png_read_image(png, row_pointers.data());
544
545 return result;
546}
547} // namespace
548
549TEST(ImageEncodingImpellerTest, PngEncodingBGRA10XR) {
550 int width = 100;
551 int height = 100;
554
556 SkCanvas* canvas = surface->getCanvas();
557
559 paint.setColor(SK_ColorBLUE);
560 paint.setAntiAlias(true);
561
562 canvas->clear(SK_ColorRED);
563 canvas->drawCircle(width / 2, height / 2, 25, paint);
564
565 sk_sp<SkImage> image = surface->makeImageSnapshot();
566
567 fml::StatusOr<sk_sp<SkData>> png = EncodeImage(image, ImageByteFormat::kPNG);
568 ASSERT_TRUE(png.ok());
570 ReadPngFromMemory(png.value()->bytes(), png.value()->size());
571 ASSERT_TRUE(pixels.ok());
572 EXPECT_EQ(pixels.value()[0], 0xff0000ff);
573 int middle = 100 * 50 + 50;
574 EXPECT_EQ(pixels.value()[middle], 0xffff0000);
575}
576
577#endif // IMPELLER_SUPPORTS_RENDERING
578
579} // namespace testing
580} // namespace flutter
581
582// NOLINTEND(clang-analyzer-core.StackAddressEscape)
static void info(const char *fmt,...) SK_PRINTF_LIKE(1
Definition: DM.cpp:213
kUnpremul_SkAlphaType
@ kRGBA_F16_SkColorType
pixel with half floats for red, green, blue, alpha;
Definition: SkColorType.h:38
@ kBGRA_10101010_XR_SkColorType
pixel with 10 bits each for blue, green, red, alpha; in 64-bit word, extended range
Definition: SkColorType.h:32
@ kBGR_101010x_XR_SkColorType
pixel with 10 bits each for blue, green, red; in 32-bit word, extended range
Definition: SkColorType.h:31
constexpr SkColor SK_ColorBLUE
Definition: SkColor.h:135
constexpr SkColor SK_ColorRED
Definition: SkColor.h:126
constexpr SkColor SK_ColorWHITE
Definition: SkColor.h:122
void clear(SkColor color)
Definition: SkCanvas.h:1199
void drawCircle(SkScalar cx, SkScalar cy, SkScalar radius, const SkPaint &paint)
Definition: SkCanvas.cpp:2707
SkColorSpace * colorSpace() const
Definition: SkImage.cpp:156
int width() const
Definition: SkImage.h:285
SkColorType colorType() const
Definition: SkImage.cpp:152
int height() const
Definition: SkImage.h:291
sk_sp< DlImage > image() const
Definition: image.h:42
static void ConvertDlImageToSkImage(const sk_sp< DlImage > &dl_image, std::function< void(fml::StatusOr< sk_sp< SkImage > >)> encode_task, const std::shared_ptr< impeller::Context > &impeller_context)
static RunConfiguration InferFromSettings(const Settings &settings, const fml::RefPtr< fml::TaskRunner > &io_worker=nullptr, IsolateLaunchType launch_type=IsolateLaunchType::kNewGroup)
Attempts to infer a run configuration from the settings object. This tries to create a run configurat...
fml::RefPtr< fml::TaskRunner > GetIOTaskRunner() const
Definition: task_runners.cc:38
fml::WeakPtr< IOManager > GetIOManager() const
static UIDartState * Current()
MOCK_METHOD(void, Execute,(const Handlers &handlers),(const))
MOCK_METHOD(void, SetSwitch,(bool value))
Wraps a closure that is invoked in the destructor unless released by the caller.
Definition: closure.h:32
const T & value() const
Definition: status_or.h:77
bool ok() const
Definition: status_or.h:75
virtual void PostTask(const fml::closure &task) override
Definition: task_runner.cc:24
static constexpr int32_t kMaxTasksAwaitingGPU
Definition: context.h:59
const Paint & paint
Definition: color_source.cc:38
DART_EXPORT Dart_TypedData_Type Dart_GetTypeOfExternalTypedData(Dart_Handle object)
DART_EXPORT bool Dart_IsBoolean(Dart_Handle object)
DART_EXPORT Dart_Handle Dart_IntegerToInt64(Dart_Handle integer, int64_t *value)
struct _Dart_Handle * Dart_Handle
Definition: dart_api.h:258
DART_EXPORT Dart_Handle Dart_GetNativeArgument(Dart_NativeArguments args, int index)
DART_EXPORT Dart_Handle Dart_GetNativeInstanceField(Dart_Handle obj, int index, intptr_t *value)
struct _Dart_NativeArguments * Dart_NativeArguments
Definition: dart_api.h:3019
@ Dart_TypedData_kUint8
Definition: dart_api.h:2615
DART_EXPORT bool Dart_IsNull(Dart_Handle object)
DART_EXPORT Dart_Handle Dart_NewStringFromCString(const char *str)
DART_EXPORT DART_WARN_UNUSED_RESULT Dart_Handle Dart_GetField(Dart_Handle container, Dart_Handle name)
DART_EXPORT bool Dart_IsError(Dart_Handle handle)
DART_EXPORT const char * Dart_GetError(Dart_Handle handle)
DART_EXPORT Dart_Handle Dart_BooleanValue(Dart_Handle boolean_obj, bool *value)
VkSurfaceKHR surface
Definition: main.cc:49
G_BEGIN_DECLS G_MODULE_EXPORT FlValue * args
uint8_t value
GAsyncResult * result
Dart_NativeFunction function
Definition: fuchsia.cc:51
FlTexture * texture
fml::RefPtr< fml::TaskRunner > CreateNewThread(const std::string &name)
fml::RefPtr< fml::TaskRunner > GetCurrentTaskRunner()
sk_sp< const SkImage > image
Definition: SkRecords.h:269
SK_API sk_sp< SkSurface > Raster(const SkImageInfo &imageInfo, size_t rowBytes, const SkSurfaceProps *surfaceProps)
ObjectPtr Invoke(const Library &lib, const char *name)
TEST_F(DisplayListTest, Defaults)
TEST(DisplayListComplexity, EmptyDisplayList)
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot data
Definition: switches.h:41
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)
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
it will be possible to load the file into Perfetto s trace viewer disable asset Prevents usage of any non test fonts unless they were explicitly Loaded via prefetched default font Indicates whether the embedding started a prefetch of the default font manager before creating the engine run In non interactive keep the shell running after the Dart script has completed enable serial On low power devices with low core running concurrent GC tasks on threads can cause them to contend with the UI thread which could potentially lead to jank This option turns off all concurrent GC activities domain network JSON encoded network policy per domain This overrides the DisallowInsecureConnections switch Embedder can specify whether to allow or disallow insecure connections at a domain level old gen heap size
Definition: switches.h:259
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 Enable an endless trace buffer The default is a ring buffer This is useful when very old events need to viewed For during application launch Memory usage will continue to grow indefinitely however Start app with an specific route defined on the framework flutter assets Path to the Flutter assets directory enable service port Allow the VM service to fallback to automatic port selection if binding to a specified port fails trace Trace early application lifecycle Automatically switches to an endless trace buffer trace skia Filters out all Skia trace event categories except those that are specified in this comma separated list dump skp on shader Automatically dump the skp that triggers new shader compilations This is useful for writing custom ShaderWarmUp to reduce jank By this is not enabled to reduce the overhead purge persistent Remove all existing persistent cache This is mainly for debugging purposes such as reproducing the shader compilation jank trace to Write the timeline trace to a file at the specified path The file will be in Perfetto s proto format
Definition: switches.h:203
Dart_Handle EncodeImage(CanvasImage *canvas_image, int format, Dart_Handle callback_handle)
static id< MTLCommandBuffer > CreateCommandBuffer(id< MTLCommandQueue > queue)
Task::Status Status
Definition: TaskList.cpp:15
flutter::DlImage DlImage
uint32_t color_type
int32_t height
int32_t width
SeparatedVector2 offset
Definition: SkSize.h:16
static constexpr SkISize Make(int32_t w, int32_t h)
Definition: SkSize.h:20
static SkImageInfo Make(int width, int height, SkColorType ct, SkAlphaType at)
Handlers & SetIfTrue(const std::function< void()> &handler)
Handlers & SetIfFalse(const std::function< void()> &handler)
A lightweight object that describes the attributes of a texture that can then used an allocator to cr...
#define CREATE_NATIVE_ENTRY(native_entry)
#define EXPECT_TRUE(handle)
Definition: unit_test.h:678