Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
raster_cache_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 "flutter/display_list/benchmarking/dl_complexity.h"
6#include "flutter/display_list/display_list.h"
7#include "flutter/display_list/dl_builder.h"
8#include "flutter/display_list/testing/dl_test_snippets.h"
9#include "flutter/flow/layers/container_layer.h"
10#include "flutter/flow/layers/display_list_layer.h"
11#include "flutter/flow/layers/image_filter_layer.h"
12#include "flutter/flow/layers/layer_tree.h"
13#include "flutter/flow/layers/transform_layer.h"
14#include "flutter/flow/raster_cache.h"
15#include "flutter/flow/raster_cache_item.h"
16#include "flutter/flow/testing/layer_test.h"
17#include "flutter/flow/testing/mock_raster_cache.h"
18#include "flutter/testing/assertions_skia.h"
19#include "gtest/gtest.h"
22
23// TODO(zanderso): https://github.com/flutter/flutter/issues/127701
24// NOLINTBEGIN(bugprone-unchecked-optional-access)
25
26namespace flutter {
27namespace testing {
28
29TEST(RasterCache, SimpleInitialization) {
31 ASSERT_TRUE(true);
32}
33
34TEST(RasterCache, MetricsOmitUnpopulatedEntries) {
35 size_t threshold = 2;
36 flutter::RasterCache cache(threshold);
37
38 SkMatrix matrix = SkMatrix::I();
39
40 auto display_list = GetSampleDisplayList();
41
42 MockCanvas dummy_canvas(1000, 1000);
44
45 LayerStateStack preroll_state_stack;
46 preroll_state_stack.set_preroll_delegate(kGiantRect, matrix);
47 LayerStateStack paint_state_stack;
48 preroll_state_stack.set_delegate(&dummy_canvas);
49
50 FixedRefreshRateStopwatch raster_time;
53 preroll_state_stack, &cache, &raster_time, &ui_time);
55 paint_state_stack, &cache, &raster_time, &ui_time);
56 auto& preroll_context = preroll_context_holder.preroll_context;
57 auto& paint_context = paint_context_holder.paint_context;
58
59 cache.BeginFrame();
60 DisplayListRasterCacheItem display_list_item(display_list, SkPoint(), true,
61 false);
62
63 // 1st access.
65 display_list_item, preroll_context, paint_context, matrix));
66 ASSERT_FALSE(display_list_item.Draw(paint_context, &dummy_canvas, &paint));
67
68 cache.EndFrame();
69 ASSERT_EQ(cache.picture_metrics().total_count(), 0u);
70 ASSERT_EQ(cache.picture_metrics().total_bytes(), 0u);
71 cache.BeginFrame();
72
73 // 2nd access.
75 display_list_item, preroll_context, paint_context, matrix));
76 ASSERT_FALSE(display_list_item.Draw(paint_context, &dummy_canvas, &paint));
77
78 cache.EndFrame();
79 ASSERT_EQ(cache.picture_metrics().total_count(), 0u);
80 ASSERT_EQ(cache.picture_metrics().total_bytes(), 0u);
81 cache.BeginFrame();
82
83 // Now Prepare should cache it.
85 display_list_item, preroll_context, paint_context, matrix));
86 ASSERT_TRUE(display_list_item.Draw(paint_context, &dummy_canvas, &paint));
87
88 cache.EndFrame();
89 ASSERT_EQ(cache.picture_metrics().total_count(), 1u);
90 // 80w * 80h * 4bpp + image object overhead
91 ASSERT_EQ(cache.picture_metrics().total_bytes(), 25624u);
92}
93
94TEST(RasterCache, ThresholdIsRespectedForDisplayList) {
95 size_t threshold = 2;
96 flutter::RasterCache cache(threshold);
97
98 SkMatrix matrix = SkMatrix::I();
99
100 auto display_list = GetSampleDisplayList();
101
102 MockCanvas dummy_canvas(1000, 1000);
104
105 LayerStateStack preroll_state_stack;
106 preroll_state_stack.set_preroll_delegate(kGiantRect, matrix);
107 LayerStateStack paint_state_stack;
108 preroll_state_stack.set_delegate(&dummy_canvas);
109
110 FixedRefreshRateStopwatch raster_time;
113 preroll_state_stack, &cache, &raster_time, &ui_time);
114 PaintContextHolder paint_context_holder = GetSamplePaintContextHolder(
115 paint_state_stack, &cache, &raster_time, &ui_time);
116 auto& preroll_context = preroll_context_holder.preroll_context;
117 auto& paint_context = paint_context_holder.paint_context;
118
119 cache.BeginFrame();
120
121 DisplayListRasterCacheItem display_list_item(display_list, SkPoint(), true,
122 false);
123
124 // 1st access.
126 display_list_item, preroll_context, paint_context, matrix));
127 ASSERT_FALSE(display_list_item.Draw(paint_context, &dummy_canvas, &paint));
128
129 cache.EndFrame();
130 cache.BeginFrame();
131
132 // 2nd access.
134 display_list_item, preroll_context, paint_context, matrix));
135 ASSERT_FALSE(display_list_item.Draw(paint_context, &dummy_canvas, &paint));
136
137 cache.EndFrame();
138 cache.BeginFrame();
139
140 // Now Prepare should cache it.
142 display_list_item, preroll_context, paint_context, matrix));
143 ASSERT_TRUE(display_list_item.Draw(paint_context, &dummy_canvas, &paint));
144}
145
146TEST(RasterCache, SetCheckboardCacheImages) {
147 size_t threshold = 1;
148 flutter::RasterCache cache(threshold);
149
150 SkMatrix matrix = SkMatrix::I();
151 auto display_list = GetSampleDisplayList();
152
153 LayerStateStack preroll_state_stack;
154 preroll_state_stack.set_preroll_delegate(kGiantRect, matrix);
155
156 FixedRefreshRateStopwatch raster_time;
158 PaintContextHolder paint_context_holder = GetSamplePaintContextHolder(
159 preroll_state_stack, &cache, &raster_time, &ui_time);
160 auto& paint_context = paint_context_holder.paint_context;
161 auto dummy_draw_function = [](DlCanvas* canvas) {};
162 bool did_draw_checkerboard = false;
163 auto draw_checkerboard = [&](DlCanvas* canvas, const SkRect&) {
164 did_draw_checkerboard = true;
165 };
166 RasterCache::Context r_context = {
167 // clang-format off
168 .gr_context = paint_context.gr_context,
169 .dst_color_space = paint_context.dst_color_space,
170 .matrix = matrix,
171 .logical_rect = display_list->bounds(),
172 .flow_type = "RasterCacheFlow::DisplayList",
173 // clang-format on
174 };
175
176 cache.SetCheckboardCacheImages(false);
177 cache.Rasterize(r_context, nullptr, dummy_draw_function, draw_checkerboard);
178 ASSERT_FALSE(did_draw_checkerboard);
179
180 cache.SetCheckboardCacheImages(true);
181 cache.Rasterize(r_context, nullptr, dummy_draw_function, draw_checkerboard);
182 ASSERT_TRUE(did_draw_checkerboard);
183}
184
185TEST(RasterCache, AccessThresholdOfZeroDisablesCachingForDisplayList) {
186 size_t threshold = 0;
187 flutter::RasterCache cache(threshold);
188
189 SkMatrix matrix = SkMatrix::I();
190
191 auto display_list = GetSampleDisplayList();
192
193 MockCanvas dummy_canvas(1000, 1000);
195
196 LayerStateStack preroll_state_stack;
197 preroll_state_stack.set_preroll_delegate(kGiantRect, matrix);
198 LayerStateStack paint_state_stack;
199 preroll_state_stack.set_delegate(&dummy_canvas);
200
201 FixedRefreshRateStopwatch raster_time;
204 preroll_state_stack, &cache, &raster_time, &ui_time);
205 PaintContextHolder paint_context_holder = GetSamplePaintContextHolder(
206 paint_state_stack, &cache, &raster_time, &ui_time);
207 auto& preroll_context = preroll_context_holder.preroll_context;
208 auto& paint_context = paint_context_holder.paint_context;
209
210 cache.BeginFrame();
211
212 DisplayListRasterCacheItem display_list_item(display_list, SkPoint(), true,
213 false);
215 display_list_item, preroll_context, paint_context, matrix));
216 ASSERT_FALSE(display_list_item.Draw(paint_context, &dummy_canvas, &paint));
217}
218
219TEST(RasterCache, PictureCacheLimitPerFrameIsRespectedWhenZeroForDisplayList) {
220 size_t picture_cache_limit_per_frame = 0;
221 flutter::RasterCache cache(3, picture_cache_limit_per_frame);
222
223 SkMatrix matrix = SkMatrix::I();
224
225 auto display_list = GetSampleDisplayList();
226
227 MockCanvas dummy_canvas(1000, 1000);
229
230 LayerStateStack preroll_state_stack;
231 preroll_state_stack.set_preroll_delegate(kGiantRect, matrix);
232 LayerStateStack paint_state_stack;
233 preroll_state_stack.set_delegate(&dummy_canvas);
234
235 FixedRefreshRateStopwatch raster_time;
238 preroll_state_stack, &cache, &raster_time, &ui_time);
239 PaintContextHolder paint_context_holder = GetSamplePaintContextHolder(
240 paint_state_stack, &cache, &raster_time, &ui_time);
241 auto& preroll_context = preroll_context_holder.preroll_context;
242 auto& paint_context = paint_context_holder.paint_context;
243
244 cache.BeginFrame();
245
246 DisplayListRasterCacheItem display_list_item(display_list, SkPoint(), true,
247 false);
248 // 1st access.
250 display_list_item, preroll_context, paint_context, matrix));
251 ASSERT_FALSE(display_list_item.Draw(paint_context, &dummy_canvas, &paint));
252 // 2nd access.
254 display_list_item, preroll_context, paint_context, matrix));
255 ASSERT_FALSE(display_list_item.Draw(paint_context, &dummy_canvas, &paint));
256 // the picture_cache_limit_per_frame = 0, so don't cache it
258 display_list_item, preroll_context, paint_context, matrix));
259 ASSERT_FALSE(display_list_item.Draw(paint_context, &dummy_canvas, &paint));
260}
261
262TEST(RasterCache, EvictUnusedCacheEntries) {
263 size_t threshold = 1;
264 flutter::RasterCache cache(threshold);
265
266 SkMatrix matrix = SkMatrix::I();
267
268 auto display_list_1 = GetSampleDisplayList();
269 auto display_list_2 = GetSampleDisplayList();
270
271 MockCanvas dummy_canvas(1000, 1000);
273
274 LayerStateStack preroll_state_stack;
275 preroll_state_stack.set_preroll_delegate(kGiantRect, matrix);
276 LayerStateStack paint_state_stack;
277 preroll_state_stack.set_delegate(&dummy_canvas);
278
279 FixedRefreshRateStopwatch raster_time;
282 preroll_state_stack, &cache, &raster_time, &ui_time);
283 PaintContextHolder paint_context_holder = GetSamplePaintContextHolder(
284 paint_state_stack, &cache, &raster_time, &ui_time);
285 auto& preroll_context = preroll_context_holder.preroll_context;
286 auto& paint_context = paint_context_holder.paint_context;
287
288 DisplayListRasterCacheItem display_list_item_1(display_list_1, SkPoint(),
289 true, false);
290 DisplayListRasterCacheItem display_list_item_2(display_list_2, SkPoint(),
291 true, false);
292
293 cache.BeginFrame();
294 RasterCacheItemPreroll(display_list_item_1, preroll_context, matrix);
295 RasterCacheItemPreroll(display_list_item_2, preroll_context, matrix);
296 cache.EvictUnusedCacheEntries();
297 ASSERT_EQ(cache.EstimatePictureCacheByteSize(), 0u);
298 ASSERT_FALSE(
299 RasterCacheItemTryToRasterCache(display_list_item_1, paint_context));
300 ASSERT_FALSE(
301 RasterCacheItemTryToRasterCache(display_list_item_2, paint_context));
302 ASSERT_EQ(cache.EstimatePictureCacheByteSize(), 0u);
303 ASSERT_FALSE(display_list_item_1.Draw(paint_context, &dummy_canvas, &paint));
304 ASSERT_FALSE(display_list_item_2.Draw(paint_context, &dummy_canvas, &paint));
305 cache.EndFrame();
306
307 ASSERT_EQ(cache.EstimatePictureCacheByteSize(), 0u);
308 ASSERT_EQ(cache.picture_metrics().total_count(), 0u);
309 ASSERT_EQ(cache.picture_metrics().total_bytes(), 0u);
310
311 cache.BeginFrame();
312 RasterCacheItemPreroll(display_list_item_1, preroll_context, matrix);
313 RasterCacheItemPreroll(display_list_item_2, preroll_context, matrix);
314 cache.EvictUnusedCacheEntries();
315 ASSERT_EQ(cache.EstimatePictureCacheByteSize(), 0u);
316 ASSERT_TRUE(
317 RasterCacheItemTryToRasterCache(display_list_item_1, paint_context));
318 ASSERT_TRUE(
319 RasterCacheItemTryToRasterCache(display_list_item_2, paint_context));
320 ASSERT_EQ(cache.EstimatePictureCacheByteSize(), 51248u);
321 ASSERT_TRUE(display_list_item_1.Draw(paint_context, &dummy_canvas, &paint));
322 ASSERT_TRUE(display_list_item_2.Draw(paint_context, &dummy_canvas, &paint));
323 cache.EndFrame();
324
325 ASSERT_EQ(cache.EstimatePictureCacheByteSize(), 51248u);
326 ASSERT_EQ(cache.picture_metrics().total_count(), 2u);
327 ASSERT_EQ(cache.picture_metrics().total_bytes(), 51248u);
328
329 cache.BeginFrame();
330 RasterCacheItemPreroll(display_list_item_1, preroll_context, matrix);
331 cache.EvictUnusedCacheEntries();
332 ASSERT_EQ(cache.EstimatePictureCacheByteSize(), 25624u);
333 ASSERT_TRUE(
334 RasterCacheItemTryToRasterCache(display_list_item_1, paint_context));
335 ASSERT_EQ(cache.EstimatePictureCacheByteSize(), 25624u);
336 ASSERT_TRUE(display_list_item_1.Draw(paint_context, &dummy_canvas, &paint));
337 cache.EndFrame();
338
339 ASSERT_EQ(cache.EstimatePictureCacheByteSize(), 25624u);
340 ASSERT_EQ(cache.picture_metrics().total_count(), 1u);
341 ASSERT_EQ(cache.picture_metrics().total_bytes(), 25624u);
342
343 cache.BeginFrame();
344 cache.EvictUnusedCacheEntries();
345 ASSERT_EQ(cache.EstimatePictureCacheByteSize(), 0u);
346 cache.EndFrame();
347
348 ASSERT_EQ(cache.EstimatePictureCacheByteSize(), 0u);
349 ASSERT_EQ(cache.picture_metrics().total_count(), 0u);
350 ASSERT_EQ(cache.picture_metrics().total_bytes(), 0u);
351
352 cache.BeginFrame();
353 ASSERT_FALSE(
354 cache.Draw(display_list_item_1.GetId().value(), dummy_canvas, &paint));
355 ASSERT_FALSE(display_list_item_1.Draw(paint_context, &dummy_canvas, &paint));
356 ASSERT_FALSE(
357 cache.Draw(display_list_item_2.GetId().value(), dummy_canvas, &paint));
358 ASSERT_FALSE(display_list_item_2.Draw(paint_context, &dummy_canvas, &paint));
359 cache.EndFrame();
360}
361
362TEST(RasterCache, ComputeDeviceRectBasedOnFractionalTranslation) {
363 SkRect logical_rect = SkRect::MakeLTRB(0, 0, 300.2, 300.3);
364 SkMatrix ctm = SkMatrix::MakeAll(2.0, 0, 0, 0, 2.0, 0, 0, 0, 1);
365 auto result = RasterCacheUtil::GetDeviceBounds(logical_rect, ctm);
366 ASSERT_EQ(result, SkRect::MakeLTRB(0.0, 0.0, 600.4, 600.6));
367}
368
369// Construct a cache result whose device target rectangle rounds out to be one
370// pixel wider than the cached image. Verify that it can be drawn without
371// triggering any assertions.
372TEST(RasterCache, DeviceRectRoundOutForDisplayList) {
373 size_t threshold = 1;
374 flutter::RasterCache cache(threshold);
375
376 SkRect logical_rect = SkRect::MakeLTRB(28, 0, 354.56731, 310.288);
377 DisplayListBuilder builder(logical_rect);
378 builder.DrawRect(logical_rect, DlPaint(DlColor::kRed()));
379 sk_sp<DisplayList> display_list = builder.Build();
380
381 SkMatrix ctm = SkMatrix::MakeAll(1.3312, 0, 233, 0, 1.3312, 206, 0, 0, 1);
383
384 MockCanvas canvas(1000, 1000);
385 canvas.SetTransform(ctm);
386
387 LayerStateStack preroll_state_stack;
388 preroll_state_stack.set_preroll_delegate(kGiantRect, ctm);
389 LayerStateStack paint_state_stack;
390 preroll_state_stack.set_delegate(&canvas);
391
392 FixedRefreshRateStopwatch raster_time;
395 preroll_state_stack, &cache, &raster_time, &ui_time);
396 PaintContextHolder paint_context_holder = GetSamplePaintContextHolder(
397 paint_state_stack, &cache, &raster_time, &ui_time);
398 auto& preroll_context = preroll_context_holder.preroll_context;
399 auto& paint_context = paint_context_holder.paint_context;
400
401 cache.BeginFrame();
402 DisplayListRasterCacheItem display_list_item(display_list, SkPoint(), true,
403 false);
404
406 display_list_item, preroll_context, paint_context, ctm));
407 ASSERT_FALSE(display_list_item.Draw(paint_context, &canvas, &paint));
408
409 cache.EndFrame();
410 cache.BeginFrame();
411
413 display_list_item, preroll_context, paint_context, ctm));
414 ASSERT_TRUE(display_list_item.Draw(paint_context, &canvas, &paint));
415
416 canvas.Translate(248, 0);
417 ASSERT_TRUE(cache.Draw(display_list_item.GetId().value(), canvas, &paint));
418 ASSERT_TRUE(display_list_item.Draw(paint_context, &canvas, &paint));
419}
420
421TEST(RasterCache, NestedOpCountMetricUsedForDisplayList) {
422 size_t threshold = 1;
423 flutter::RasterCache cache(threshold);
424
425 SkMatrix matrix = SkMatrix::I();
426
427 auto display_list = GetSampleNestedDisplayList();
428 ASSERT_EQ(display_list->op_count(), 1u);
429 ASSERT_EQ(display_list->op_count(true), 36u);
430
431 MockCanvas dummy_canvas(1000, 1000);
433
434 LayerStateStack preroll_state_stack;
435 preroll_state_stack.set_preroll_delegate(kGiantRect, matrix);
436 LayerStateStack paint_state_stack;
437 preroll_state_stack.set_delegate(&dummy_canvas);
438
439 FixedRefreshRateStopwatch raster_time;
442 preroll_state_stack, &cache, &raster_time, &ui_time);
443 PaintContextHolder paint_context_holder = GetSamplePaintContextHolder(
444 paint_state_stack, &cache, &raster_time, &ui_time);
445 auto& preroll_context = preroll_context_holder.preroll_context;
446 auto& paint_context = paint_context_holder.paint_context;
447
448 cache.BeginFrame();
449
450 DisplayListRasterCacheItem display_list_item(display_list, SkPoint(), false,
451 false);
452
454 display_list_item, preroll_context, paint_context, matrix));
455 ASSERT_FALSE(display_list_item.Draw(paint_context, &dummy_canvas, &paint));
456
457 cache.EndFrame();
458 cache.BeginFrame();
459
461 display_list_item, preroll_context, paint_context, matrix));
462 ASSERT_TRUE(display_list_item.Draw(paint_context, &dummy_canvas, &paint));
463}
464
465TEST(RasterCache, NaiveComplexityScoringDisplayList) {
468
469 size_t threshold = 1;
470 flutter::RasterCache cache(threshold);
471
472 SkMatrix matrix = SkMatrix::I();
473
474 // Five raster ops will not be cached
475 auto display_list = GetSampleDisplayList(5);
476 unsigned int complexity_score = calculator->Compute(display_list.get());
477
478 ASSERT_EQ(complexity_score, 5u);
479 ASSERT_EQ(display_list->op_count(), 5u);
480 ASSERT_FALSE(calculator->ShouldBeCached(complexity_score));
481
482 MockCanvas dummy_canvas(1000, 1000);
484
485 LayerStateStack preroll_state_stack;
486 preroll_state_stack.set_preroll_delegate(kGiantRect, matrix);
487 LayerStateStack paint_state_stack;
488 preroll_state_stack.set_delegate(&dummy_canvas);
489
490 FixedRefreshRateStopwatch raster_time;
493 preroll_state_stack, &cache, &raster_time, &ui_time);
494 PaintContextHolder paint_context_holder = GetSamplePaintContextHolder(
495 paint_state_stack, &cache, &raster_time, &ui_time);
496 auto& preroll_context = preroll_context_holder.preroll_context;
497 auto& paint_context = paint_context_holder.paint_context;
498
499 cache.BeginFrame();
500
501 DisplayListRasterCacheItem display_list_item(display_list, SkPoint(), false,
502 false);
503
505 display_list_item, preroll_context, paint_context, matrix));
506 ASSERT_FALSE(display_list_item.Draw(paint_context, &dummy_canvas, &paint));
507
508 cache.EndFrame();
509 cache.BeginFrame();
510
512 display_list_item, preroll_context, paint_context, matrix));
513 ASSERT_FALSE(display_list_item.Draw(paint_context, &dummy_canvas, &paint));
514
515 // Six raster ops should be cached
516 display_list = GetSampleDisplayList(6);
517 complexity_score = calculator->Compute(display_list.get());
518
519 ASSERT_EQ(complexity_score, 6u);
520 ASSERT_EQ(display_list->op_count(), 6u);
521 ASSERT_TRUE(calculator->ShouldBeCached(complexity_score));
522
523 DisplayListRasterCacheItem display_list_item_2 =
524 DisplayListRasterCacheItem(display_list, SkPoint(), false, false);
525 cache.BeginFrame();
526
528 display_list_item_2, preroll_context, paint_context, matrix));
529 ASSERT_FALSE(display_list_item_2.Draw(paint_context, &dummy_canvas, &paint));
530
531 cache.EndFrame();
532 cache.BeginFrame();
533
535 display_list_item_2, preroll_context, paint_context, matrix));
536 ASSERT_TRUE(display_list_item_2.Draw(paint_context, &dummy_canvas, &paint));
537}
538
539TEST(RasterCache, DisplayListWithSingularMatrixIsNotCached) {
540 size_t threshold = 2;
541 flutter::RasterCache cache(threshold);
542
543 SkMatrix matrices[] = {
544 SkMatrix::Scale(0, 1),
545 SkMatrix::Scale(1, 0),
546 SkMatrix::Skew(1, 1),
547 };
548 int matrix_count = sizeof(matrices) / sizeof(matrices[0]);
549
550 auto display_list = GetSampleDisplayList();
551
552 MockCanvas dummy_canvas(1000, 1000);
554
555 LayerStateStack preroll_state_stack;
556 preroll_state_stack.set_preroll_delegate(kGiantRect, SkMatrix::I());
557 LayerStateStack paint_state_stack;
558 preroll_state_stack.set_delegate(&dummy_canvas);
559
560 FixedRefreshRateStopwatch raster_time;
563 preroll_state_stack, &cache, &raster_time, &ui_time);
564 PaintContextHolder paint_context_holder = GetSamplePaintContextHolder(
565 paint_state_stack, &cache, &raster_time, &ui_time);
566 auto& preroll_context = preroll_context_holder.preroll_context;
567 auto& paint_context = paint_context_holder.paint_context;
568
569 DisplayListRasterCacheItem display_list_item(display_list, SkPoint(), true,
570 false);
571
572 for (int i = 0; i < 10; i++) {
573 cache.BeginFrame();
574
575 for (int j = 0; j < matrix_count; j++) {
576 display_list_item.set_matrix(matrices[j]);
578 display_list_item, preroll_context, paint_context, matrices[j]));
579 }
580
581 for (int j = 0; j < matrix_count; j++) {
582 dummy_canvas.SetTransform(matrices[j]);
583 ASSERT_FALSE(
584 display_list_item.Draw(paint_context, &dummy_canvas, &paint));
585 }
586
587 cache.EndFrame();
588 }
589}
590
591TEST(RasterCache, PrepareLayerTransform) {
592 SkRect child_bounds = SkRect::MakeLTRB(10, 10, 50, 50);
593 SkPath child_path = SkPath().addOval(child_bounds);
594 auto child_layer = MockLayer::Make(child_path);
595 auto blur_filter =
596 std::make_shared<DlBlurImageFilter>(5, 5, DlTileMode::kClamp);
597 auto blur_layer = std::make_shared<ImageFilterLayer>(blur_filter);
598 SkMatrix matrix = SkMatrix::Scale(2, 2);
599 auto transform_layer = std::make_shared<TransformLayer>(matrix);
600 SkMatrix cache_matrix = SkMatrix::Translate(-20, -20);
601 cache_matrix.preConcat(matrix);
602 child_layer->set_expected_paint_matrix(cache_matrix);
603
604 blur_layer->Add(child_layer);
605 transform_layer->Add(blur_layer);
606
607 size_t threshold = 2;
608 MockRasterCache cache(threshold);
609 MockCanvas dummy_canvas(1000, 1000);
610
611 LayerStateStack preroll_state_stack;
612 preroll_state_stack.set_preroll_delegate(kGiantRect, matrix);
613 LayerStateStack paint_state_stack;
614 preroll_state_stack.set_delegate(&dummy_canvas);
615
616 FixedRefreshRateStopwatch raster_time;
618 std::vector<RasterCacheItem*> cache_items;
619
620 cache.BeginFrame();
621
622 auto preroll_holder = GetSamplePrerollContextHolder(
623 preroll_state_stack, &cache, &raster_time, &ui_time);
624 preroll_holder.preroll_context.raster_cached_entries = &cache_items;
625 transform_layer->Preroll(&preroll_holder.preroll_context);
626
627 auto paint_holder = GetSamplePaintContextHolder(paint_state_stack, &cache,
628 &raster_time, &ui_time);
629
630 cache.EvictUnusedCacheEntries();
632 *preroll_holder.preroll_context.raster_cached_entries,
633 &paint_holder.paint_context);
634
635 // Condition tested inside MockLayer::Paint against expected paint matrix.
636}
637
638TEST(RasterCache, RasterCacheKeyHashFunction) {
640 auto hash_function = map.hash_function();
641 SkMatrix matrix = SkMatrix::I();
642 uint64_t id = 5;
643 RasterCacheKey layer_key(id, RasterCacheKeyType::kLayer, matrix);
644 RasterCacheKey display_list_key(id, RasterCacheKeyType::kDisplayList, matrix);
646 matrix);
647
648 auto layer_cache_key_id = RasterCacheKeyID(id, RasterCacheKeyType::kLayer);
649 auto layer_hash_code = hash_function(layer_key);
650 ASSERT_EQ(layer_hash_code, layer_cache_key_id.GetHash());
651
652 auto display_list_cache_key_id =
654 auto display_list_hash_code = hash_function(display_list_key);
655 ASSERT_EQ(display_list_hash_code, display_list_cache_key_id.GetHash());
656
657 auto layer_children_cache_key_id =
659 auto layer_children_hash_code = hash_function(layer_children_key);
660 ASSERT_EQ(layer_children_hash_code, layer_children_cache_key_id.GetHash());
661}
662
663TEST(RasterCache, RasterCacheKeySameID) {
665 SkMatrix matrix = SkMatrix::I();
666 uint64_t id = 5;
667 RasterCacheKey layer_key(id, RasterCacheKeyType::kLayer, matrix);
668 RasterCacheKey display_list_key(id, RasterCacheKeyType::kDisplayList, matrix);
670 matrix);
671 map[layer_key] = 100;
672 map[display_list_key] = 300;
673 map[layer_children_key] = 400;
674
675 ASSERT_EQ(map[layer_key], 100);
676 ASSERT_EQ(map[display_list_key], 300);
677 ASSERT_EQ(map[layer_children_key], 400);
678}
679
680TEST(RasterCache, RasterCacheKeySameType) {
682 SkMatrix matrix = SkMatrix::I();
683
685 RasterCacheKey layer_first_key(5, type, matrix);
686 RasterCacheKey layer_second_key(10, type, matrix);
687 RasterCacheKey layer_third_key(15, type, matrix);
688 map[layer_first_key] = 50;
689 map[layer_second_key] = 100;
690 map[layer_third_key] = 150;
691 ASSERT_EQ(map[layer_first_key], 50);
692 ASSERT_EQ(map[layer_second_key], 100);
693 ASSERT_EQ(map[layer_third_key], 150);
694
696 RasterCacheKey picture_first_key(20, type, matrix);
697 RasterCacheKey picture_second_key(25, type, matrix);
698 RasterCacheKey picture_third_key(30, type, matrix);
699 map[picture_first_key] = 200;
700 map[picture_second_key] = 250;
701 map[picture_third_key] = 300;
702 ASSERT_EQ(map[picture_first_key], 200);
703 ASSERT_EQ(map[picture_second_key], 250);
704 ASSERT_EQ(map[picture_third_key], 300);
705
707 RasterCacheKey display_list_first_key(35, type, matrix);
708 RasterCacheKey display_list_second_key(40, type, matrix);
709 RasterCacheKey display_list_third_key(45, type, matrix);
710 map[display_list_first_key] = 350;
711 map[display_list_second_key] = 400;
712 map[display_list_third_key] = 450;
713 ASSERT_EQ(map[display_list_first_key], 350);
714 ASSERT_EQ(map[display_list_second_key], 400);
715 ASSERT_EQ(map[display_list_third_key], 450);
716
721 RasterCacheKey layer_children_first_key(
722 RasterCacheKeyID({foo, bar, baz}, type), matrix);
723 RasterCacheKey layer_children_second_key(
724 RasterCacheKeyID({foo, baz, bar}, type), matrix);
725 RasterCacheKey layer_children_third_key(
726 RasterCacheKeyID({baz, bar, foo}, type), matrix);
727 map[layer_children_first_key] = 100;
728 map[layer_children_second_key] = 200;
729 map[layer_children_third_key] = 300;
730 ASSERT_EQ(map[layer_children_first_key], 100);
731 ASSERT_EQ(map[layer_children_second_key], 200);
732 ASSERT_EQ(map[layer_children_third_key], 300);
733}
734
735TEST(RasterCache, RasterCacheKeyIDEqual) {
738 RasterCacheKeyID third =
740
741 ASSERT_NE(first, second);
742 ASSERT_NE(first, third);
743 ASSERT_NE(second, third);
744
745 RasterCacheKeyID fourth =
747 RasterCacheKeyID fifth =
749 RasterCacheKeyID sixth =
751 ASSERT_NE(fourth, fifth);
752 ASSERT_NE(fifth, sixth);
753}
754
755TEST(RasterCache, RasterCacheKeyIDHashCode) {
756 uint64_t foo = 1;
757 uint64_t bar = 2;
760 std::size_t first_hash = first.GetHash();
761 std::size_t second_hash = second.GetHash();
762
763 ASSERT_EQ(first_hash, fml::HashCombine(foo, RasterCacheKeyType::kLayer));
764 ASSERT_EQ(second_hash, fml::HashCombine(bar, RasterCacheKeyType::kLayer));
765
766 RasterCacheKeyID third =
768 RasterCacheKeyID fourth =
770 std::size_t third_hash = third.GetHash();
771 std::size_t fourth_hash = fourth.GetHash();
772
775 first.GetHash(), second.GetHash()));
778 second.GetHash(), first.GetHash()));
779
780 // Verify that the cached hash code is correct.
781 ASSERT_EQ(first_hash, first.GetHash());
782 ASSERT_EQ(second_hash, second.GetHash());
783 ASSERT_EQ(third_hash, third.GetHash());
784 ASSERT_EQ(fourth_hash, fourth.GetHash());
785}
786
788
789TEST_F(RasterCacheTest, RasterCacheKeyIDLayerChildrenIds) {
790 auto layer = std::make_shared<ContainerLayer>();
791
792 const SkPath child_path = SkPath().addRect(SkRect::MakeWH(5.0f, 5.0f));
793 auto mock_layer = std::make_shared<MockLayer>(child_path);
794 layer->Add(mock_layer);
795
796 auto display_list = GetSampleDisplayList();
797 auto display_list_layer = std::make_shared<DisplayListLayer>(
798 SkPoint::Make(0.0f, 0.0f), display_list, false, false);
799 layer->Add(display_list_layer);
800
801 auto ids = RasterCacheKeyID::LayerChildrenIds(layer.get()).value();
802 std::vector<RasterCacheKeyID> expected_ids;
803 expected_ids.emplace_back(
804 RasterCacheKeyID(mock_layer->unique_id(), RasterCacheKeyType::kLayer));
805 expected_ids.emplace_back(RasterCacheKeyID(display_list->unique_id(),
807 ASSERT_EQ(expected_ids[0], mock_layer->caching_key_id());
808 ASSERT_EQ(expected_ids[1], display_list_layer->caching_key_id());
809 ASSERT_EQ(ids, expected_ids);
810}
811
812TEST(RasterCacheUtilsTest, SkMatrixIntegralTransCTM) {
813#define EXPECT_EQ_WITH_TRANSLATE(test, expected, expected_tx, expected_ty) \
814 do { \
815 EXPECT_EQ(test[SkMatrix::kMScaleX], expected[SkMatrix::kMScaleX]); \
816 EXPECT_EQ(test[SkMatrix::kMSkewX], expected[SkMatrix::kMSkewX]); \
817 EXPECT_EQ(test[SkMatrix::kMScaleY], expected[SkMatrix::kMScaleY]); \
818 EXPECT_EQ(test[SkMatrix::kMSkewY], expected[SkMatrix::kMSkewY]); \
819 EXPECT_EQ(test[SkMatrix::kMSkewX], expected[SkMatrix::kMSkewX]); \
820 EXPECT_EQ(test[SkMatrix::kMPersp0], expected[SkMatrix::kMPersp0]); \
821 EXPECT_EQ(test[SkMatrix::kMPersp1], expected[SkMatrix::kMPersp1]); \
822 EXPECT_EQ(test[SkMatrix::kMPersp2], expected[SkMatrix::kMPersp2]); \
823 EXPECT_EQ(test[SkMatrix::kMTransX], expected_tx); \
824 EXPECT_EQ(test[SkMatrix::kMTransY], expected_ty); \
825 } while (0)
826
827#define EXPECT_NON_INTEGER_TRANSLATION(matrix) \
828 EXPECT_TRUE(SkScalarFraction(matrix[SkMatrix::kMTransX]) != 0.0f || \
829 SkScalarFraction(matrix[SkMatrix::kMTransY]) != 0.0f)
830
831 {
832 // Identity
833 SkMatrix matrix = SkMatrix::I();
835 SkMatrix compute;
836 EXPECT_FALSE(RasterCacheUtil::ComputeIntegralTransCTM(matrix, &compute));
837 EXPECT_EQ(get, matrix);
838 }
839 {
840 // Integer translate
841 SkMatrix matrix = SkMatrix::Translate(10.0f, 12.0f);
843 SkMatrix compute;
844 EXPECT_FALSE(RasterCacheUtil::ComputeIntegralTransCTM(matrix, &compute));
845 EXPECT_EQ(get, matrix);
846 }
847 {
848 // Fractional x translate
849 SkMatrix matrix = SkMatrix::Translate(10.2f, 12.0f);
852 SkMatrix compute;
854 EXPECT_EQ_WITH_TRANSLATE(get, matrix, 10.0f, 12.0f);
855 EXPECT_EQ(get, compute);
856 }
857 {
858 // Fractional y translate
859 SkMatrix matrix = SkMatrix::Translate(10.0f, 12.3f);
862 SkMatrix compute;
864 EXPECT_EQ_WITH_TRANSLATE(get, matrix, 10.0f, 12.0f);
865 EXPECT_EQ(get, compute);
866 }
867 {
868 // Fractional x & y translate
869 SkMatrix matrix = SkMatrix::Translate(10.7f, 12.3f);
872 SkMatrix compute;
874 EXPECT_EQ_WITH_TRANSLATE(get, matrix, 11.0f, 12.0f);
875 EXPECT_EQ(get, compute);
876 }
877 {
878 // Scale
879 SkMatrix matrix = SkMatrix::Scale(2.0f, 3.0f);
881 SkMatrix compute;
882 EXPECT_FALSE(RasterCacheUtil::ComputeIntegralTransCTM(matrix, &compute));
883 EXPECT_EQ(get, matrix);
884 }
885 {
886 // Scale, Integer translate
887 SkMatrix matrix = SkMatrix::Scale(2.0f, 3.0f);
888 matrix.preTranslate(10.0f, 12.0f);
890 SkMatrix compute;
891 EXPECT_FALSE(RasterCacheUtil::ComputeIntegralTransCTM(matrix, &compute));
892 EXPECT_EQ(get, matrix);
893 }
894 {
895 // Scale, Fractional translate
896 SkMatrix matrix = SkMatrix::Scale(2.0f, 3.0f);
897 matrix.preTranslate(10.7f, 12.1f);
900 SkMatrix compute;
902 EXPECT_EQ_WITH_TRANSLATE(get, matrix, 21.0f, 36.0f);
903 EXPECT_EQ(get, compute);
904 }
905 {
906 // Skew
907 SkMatrix matrix = SkMatrix::Skew(0.5f, 0.1f);
909 SkMatrix compute;
910 EXPECT_FALSE(RasterCacheUtil::ComputeIntegralTransCTM(matrix, &compute));
911 EXPECT_EQ(get, matrix);
912 }
913 {
914 // Skew, Fractional translate - should be NOP
915 SkMatrix matrix = SkMatrix::Skew(0.5f, 0.1f);
916 matrix.preTranslate(10.7f, 12.1f);
919 SkMatrix compute;
920 EXPECT_FALSE(RasterCacheUtil::ComputeIntegralTransCTM(matrix, &compute));
921 EXPECT_EQ(get, matrix);
922 }
923 {
924 // Rotate
925 SkMatrix matrix = SkMatrix::RotateDeg(45);
927 SkMatrix compute;
928 EXPECT_FALSE(RasterCacheUtil::ComputeIntegralTransCTM(matrix, &compute));
929 EXPECT_EQ(get, matrix);
930 }
931 {
932 // Rotate, Fractional Translate - should be NOP
933 SkMatrix matrix = SkMatrix::RotateDeg(45);
934 matrix.preTranslate(10.7f, 12.1f);
937 SkMatrix compute;
938 EXPECT_FALSE(RasterCacheUtil::ComputeIntegralTransCTM(matrix, &compute));
939 EXPECT_EQ(get, matrix);
940 }
941 {
942 // Perspective x
943 SkMatrix matrix = SkMatrix::I();
944 matrix.setPerspX(0.1);
946 SkMatrix compute;
947 EXPECT_FALSE(RasterCacheUtil::ComputeIntegralTransCTM(matrix, &compute));
948 EXPECT_EQ(get, matrix);
949 }
950 {
951 // Perspective x, Fractional Translate - should be NOP
952 SkMatrix matrix = SkMatrix::I();
953 matrix.setPerspX(0.1);
954 matrix.preTranslate(10.7f, 12.1f);
957 SkMatrix compute;
958 EXPECT_FALSE(RasterCacheUtil::ComputeIntegralTransCTM(matrix, &compute));
959 EXPECT_EQ(get, matrix);
960 }
961 {
962 // Perspective y
963 SkMatrix matrix = SkMatrix::I();
964 matrix.setPerspY(0.1);
966 SkMatrix compute;
967 EXPECT_FALSE(RasterCacheUtil::ComputeIntegralTransCTM(matrix, &compute));
968 EXPECT_EQ(get, matrix);
969 }
970 {
971 // Perspective y, Fractional Translate - should be NOP
972 SkMatrix matrix = SkMatrix::I();
973 matrix.setPerspY(0.1);
974 matrix.preTranslate(10.7f, 12.1f);
977 SkMatrix compute;
978 EXPECT_FALSE(RasterCacheUtil::ComputeIntegralTransCTM(matrix, &compute));
979 EXPECT_EQ(get, matrix);
980 }
981 {
982 // Perspective weight
983 // clang-format off
985 1.0f, 0.0f, 0.0f,
986 0.0f, 1.0f, 0.0f,
987 0.0f, 0.0f, 0.9f);
988 // clang-format on
990 SkMatrix compute;
991 EXPECT_FALSE(RasterCacheUtil::ComputeIntegralTransCTM(matrix, &compute));
992 EXPECT_EQ(get, matrix);
993 }
994 {
995 // Perspective weight, Fractional Translate - should be NOP
996 // clang-format off
998 1.0f, 0.0f, 0.0f,
999 0.0f, 1.0f, 0.0f,
1000 0.0f, 0.0f, 0.9f);
1001 // clang-format on
1002 matrix.preTranslate(10.7f, 12.1f);
1005 SkMatrix compute;
1006 EXPECT_FALSE(RasterCacheUtil::ComputeIntegralTransCTM(matrix, &compute));
1007 EXPECT_EQ(get, matrix);
1008 }
1009#undef EXPECT_NON_INTEGER_TRANSLATION
1010#undef EXPECT_EQ_WITH_TRANSLATE
1011}
1012
1013TEST(RasterCacheUtilsTest, SkM44IntegralTransCTM) {
1014#define EXPECT_EQ_WITH_TRANSLATE(test, expected, tx, ty, label) \
1015 do { \
1016 EXPECT_EQ(test.rc(0, 0), expected.rc(0, 0)) << label; \
1017 EXPECT_EQ(test.rc(0, 1), expected.rc(0, 1)) << label; \
1018 EXPECT_EQ(test.rc(0, 2), expected.rc(0, 2)) << label; \
1019 EXPECT_EQ(test.rc(0, 3), tx) << label; \
1020 EXPECT_EQ(test.rc(1, 0), expected.rc(1, 0)) << label; \
1021 EXPECT_EQ(test.rc(1, 1), expected.rc(1, 1)) << label; \
1022 EXPECT_EQ(test.rc(1, 2), expected.rc(1, 2)) << label; \
1023 EXPECT_EQ(test.rc(1, 3), ty) << label; \
1024 EXPECT_EQ(test.rc(2, 0), expected.rc(2, 0)) << label; \
1025 EXPECT_EQ(test.rc(2, 1), expected.rc(2, 1)) << label; \
1026 EXPECT_EQ(test.rc(2, 2), expected.rc(2, 2)) << label; \
1027 EXPECT_EQ(test.rc(2, 3), expected.rc(2, 3)) << label; \
1028 EXPECT_EQ(test.rc(3, 0), expected.rc(3, 0)) << label; \
1029 EXPECT_EQ(test.rc(3, 1), expected.rc(3, 1)) << label; \
1030 EXPECT_EQ(test.rc(3, 2), expected.rc(3, 2)) << label; \
1031 EXPECT_EQ(test.rc(3, 3), expected.rc(3, 3)) << label; \
1032 } while (0)
1033
1034#define EXPECT_NON_INTEGER_TRANSLATION(matrix) \
1035 EXPECT_TRUE(SkScalarFraction(matrix.rc(0, 3)) != 0.0f || \
1036 SkScalarFraction(matrix.rc(1, 3)) != 0.0f)
1037
1038 for (int r = 0; r < 4; r++) {
1039 for (int c = 0; c < 4; c++) {
1040 bool snaps;
1041 switch (r) {
1042 case 0: // X equation
1043 if (c == 3) {
1044 continue; // TranslateX, the value we are testing, skip
1045 }
1046 snaps = (c == 0); // X Scale value yes, Skew by Y or Z no
1047 break;
1048 case 1: // Y equation
1049 if (c == 3) {
1050 continue; // TranslateY, the value we are testing, skip
1051 }
1052 snaps = (c == 1); // Y Scale value yes, Skew by X or Z no
1053 break;
1054 case 2: // Z equation, ignored, will snap
1055 snaps = true;
1056 break;
1057 case 3: // W equation, modifications prevent snapping
1058 snaps = false;
1059 break;
1060 default:
1062 }
1063 auto label = std::to_string(r) + ", " + std::to_string(c);
1064 SkM44 matrix = SkM44::Translate(10.7f, 12.1f);
1065 EXPECT_NON_INTEGER_TRANSLATION(matrix) << label;
1066 matrix.setRC(r, c, 0.5f);
1067 if (snaps) {
1068 SkM44 compute;
1071 << label;
1072 EXPECT_EQ_WITH_TRANSLATE(get, matrix, 11.0f, 12.0f, label);
1073 EXPECT_EQ(get, compute) << label;
1074 } else {
1075 SkM44 compute;
1077 EXPECT_FALSE(RasterCacheUtil::ComputeIntegralTransCTM(matrix, &compute))
1078 << label;
1079 EXPECT_EQ(get, matrix) << label;
1080 }
1081 }
1082 }
1083#undef EXPECT_NON_INTEGER_TRANSLATION
1084#undef EXPECT_EQ_WITH_TRANSLATE
1085}
1086
1087} // namespace testing
1088} // namespace flutter
1089
1090// NOLINTEND(bugprone-unchecked-optional-access)
#define TEST(S, s, D, expected)
Definition SkM44.h:150
static SkM44 Translate(SkScalar x, SkScalar y, SkScalar z=0)
Definition SkM44.h:225
static SkMatrix Scale(SkScalar sx, SkScalar sy)
Definition SkMatrix.h:75
static SkMatrix RotateDeg(SkScalar deg)
Definition SkMatrix.h:104
static SkMatrix Translate(SkScalar dx, SkScalar dy)
Definition SkMatrix.h:91
static SkMatrix MakeAll(SkScalar scaleX, SkScalar skewX, SkScalar transX, SkScalar skewY, SkScalar scaleY, SkScalar transY, SkScalar pers0, SkScalar pers1, SkScalar pers2)
Definition SkMatrix.h:179
static const SkMatrix & I()
SkMatrix & preConcat(const SkMatrix &other)
Definition SkMatrix.cpp:674
static SkMatrix Skew(SkScalar kx, SkScalar ky)
Definition SkMatrix.h:124
SkPath & addOval(const SkRect &oval, SkPathDirection dir=SkPathDirection::kCW)
Definition SkPath.cpp:1101
SkPath & addRect(const SkRect &rect, SkPathDirection dir, unsigned start)
Definition SkPath.cpp:854
virtual bool ShouldBeCached(unsigned int complexity_score)=0
virtual unsigned int Compute(const DisplayList *display_list)=0
static DisplayListComplexityCalculator * GetInstance()
bool Draw(const PaintContext &context, const DlPaint *paint) const override
Developer-facing API for rendering anything within the engine.
Definition dl_canvas.h:37
Used for fixed refresh rate cases.
Definition stopwatch.h:77
void set_preroll_delegate(const SkRect &cull_rect, const SkMatrix &matrix)
void set_delegate(DlCanvas *canvas)
static void TryToRasterCache(const std::vector< RasterCacheItem * > &raster_cached_entries, const PaintContext *paint_context, bool ignore_raster_cache=false)
Definition layer_tree.cc:73
void set_matrix(const SkMatrix &matrix)
virtual std::optional< RasterCacheKeyID > GetId() const
static constexpr uint64_t kDefaultUniqueID
std::size_t GetHash() const
static std::optional< std::vector< RasterCacheKeyID > > LayerChildrenIds(const Layer *layer)
std::unordered_map< RasterCacheKey, Value, Hash, Equal > Map
void Translate(SkScalar tx, SkScalar ty) override
void SetTransform(const SkMatrix *matrix) override
static std::shared_ptr< MockLayer > Make(const SkPath &path, DlPaint paint=DlPaint())
Definition mock_layer.h:30
A RasterCache implementation that simulates the act of rendering a Layer or DisplayList without the o...
const Paint & paint
GAsyncResult * result
#define FML_UNREACHABLE()
Definition logging.h:109
TEST_F(DisplayListTest, Defaults)
bool RasterCacheItemTryToRasterCache(DisplayListRasterCacheItem &display_list_item, PaintContext &paint_context)
LayerTestBase<::testing::Test > LayerTest
Definition layer_test.h:240
PrerollContextHolder GetSamplePrerollContextHolder(LayerStateStack &state_stack, RasterCache *raster_cache, FixedRefreshRateStopwatch *raster_time, FixedRefreshRateStopwatch *ui_time)
void RasterCacheItemPreroll(DisplayListRasterCacheItem &display_list_item, PrerollContext &context, const SkMatrix &matrix)
sk_sp< DisplayList > GetSampleDisplayList()
bool RasterCacheItemPrerollAndTryToRasterCache(DisplayListRasterCacheItem &display_list_item, PrerollContext &context, PaintContext &paint_context, const SkMatrix &matrix)
sk_sp< DisplayList > GetSampleNestedDisplayList()
PaintContextHolder GetSamplePaintContextHolder(LayerStateStack &state_stack, RasterCache *raster_cache, FixedRefreshRateStopwatch *raster_time, FixedRefreshRateStopwatch *ui_time)
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 cache
Definition switches.h:191
static constexpr SkRect kGiantRect
Definition layer.h:49
constexpr std::size_t HashCombine()
#define EXPECT_NON_INTEGER_TRANSLATION(matrix)
#define EXPECT_EQ_WITH_TRANSLATE(test, expected, expected_tx, expected_ty)
static constexpr SkPoint Make(float x, float y)
static constexpr SkRect MakeWH(float w, float h)
Definition SkRect.h:609
static constexpr SkRect MakeLTRB(float l, float t, float r, float b)
Definition SkRect.h:646
static constexpr DlColor kRed()
Definition dl_color.h:24
static bool ComputeIntegralTransCTM(const SkMatrix &in, SkMatrix *out)
Snap the translation components of the |in| matrix to integers and store the snapped matrix in |out|.
static SkMatrix GetIntegralTransCTM(const SkMatrix &ctm)
Snap the translation components of the matrix to integers.
static SkRect GetDeviceBounds(const SkRect &rect, const SkMatrix &ctm)
#define EXPECT_TRUE(handle)
Definition unit_test.h:685