Flutter Engine
 
Loading...
Searching...
No Matches
clip_rect_layer_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
6
13#include "flutter/fml/macros.h"
14
15// TODO(zanderso): https://github.com/flutter/flutter/issues/127701
16// NOLINTBEGIN(bugprone-unchecked-optional-access)
17
18namespace flutter {
19namespace testing {
20
22
23#ifndef NDEBUG
24TEST_F(ClipRectLayerTest, ClipNoneBehaviorDies) {
25 EXPECT_DEATH_IF_SUPPORTED(
26 auto clip = std::make_shared<ClipRectLayer>(DlRect(), Clip::kNone),
27 "clip_behavior != Clip::kNone");
28}
29
30TEST_F(ClipRectLayerTest, PaintingEmptyLayerDies) {
31 auto layer = std::make_shared<ClipRectLayer>(DlRect(), Clip::kHardEdge);
32
33 layer->Preroll(preroll_context());
34
35 // Untouched
36 EXPECT_EQ(preroll_context()->state_stack.device_cull_rect(), kGiantRect);
37 EXPECT_TRUE(preroll_context()->state_stack.is_empty());
38
39 EXPECT_EQ(layer->paint_bounds(), DlRect());
40 EXPECT_EQ(layer->child_paint_bounds(), DlRect());
41 EXPECT_FALSE(layer->needs_painting(paint_context()));
42
43 EXPECT_DEATH_IF_SUPPORTED(layer->Paint(paint_context()),
44 "needs_painting\\(context\\)");
45}
46
47TEST_F(ClipRectLayerTest, PaintBeforePrerollDies) {
48 const DlRect layer_bounds = DlRect::MakeXYWH(0.5, 1.0, 5.0, 6.0);
49 auto layer = std::make_shared<ClipRectLayer>(layer_bounds, Clip::kHardEdge);
50 EXPECT_EQ(layer->paint_bounds(), DlRect());
51 EXPECT_EQ(layer->child_paint_bounds(), DlRect());
52 EXPECT_FALSE(layer->needs_painting(paint_context()));
53
54 EXPECT_DEATH_IF_SUPPORTED(layer->Paint(paint_context()),
55 "needs_painting\\(context\\)");
56}
57
58TEST_F(ClipRectLayerTest, PaintingCulledLayerDies) {
59 const DlMatrix initial_matrix = DlMatrix::MakeTranslation({0.5f, 1.0f});
60 const DlRect child_bounds = DlRect::MakeXYWH(1.0, 2.0, 2.0, 2.0);
61 const DlRect layer_bounds = DlRect::MakeXYWH(0.5, 1.0, 5.0, 6.0);
62 const DlRect distant_bounds = DlRect::MakeXYWH(100.0, 100.0, 10.0, 10.0);
63 const DlPath child_path = DlPath::MakeRect(child_bounds);
64 auto mock_layer = std::make_shared<MockLayer>(child_path);
65 auto layer = std::make_shared<ClipRectLayer>(layer_bounds, Clip::kHardEdge);
66 layer->Add(mock_layer);
67
68 // Cull these children
69 preroll_context()->state_stack.set_preroll_delegate(distant_bounds,
70 initial_matrix);
71 layer->Preroll(preroll_context());
72
73 // Untouched
74 EXPECT_EQ(preroll_context()->state_stack.device_cull_rect(), distant_bounds);
75 EXPECT_TRUE(preroll_context()->state_stack.is_empty());
76
77 EXPECT_EQ(mock_layer->paint_bounds(), child_bounds);
78 EXPECT_EQ(layer->paint_bounds(), child_bounds);
79 EXPECT_EQ(layer->child_paint_bounds(), child_bounds);
80 EXPECT_TRUE(mock_layer->needs_painting(paint_context()));
81 EXPECT_TRUE(layer->needs_painting(paint_context()));
82 EXPECT_EQ(mock_layer->parent_cull_rect(), DlRect());
83 EXPECT_EQ(mock_layer->parent_matrix(), initial_matrix);
84 EXPECT_EQ(mock_layer->parent_mutators(),
85 std::vector({Mutator(layer_bounds)}));
86
87 auto mutator = paint_context().state_stack.save();
88 mutator.clipRect(distant_bounds, false);
89 EXPECT_FALSE(mock_layer->needs_painting(paint_context()));
90 EXPECT_FALSE(layer->needs_painting(paint_context()));
91 EXPECT_DEATH_IF_SUPPORTED(layer->Paint(paint_context()),
92 "needs_painting\\(context\\)");
93}
94#endif
95
96TEST_F(ClipRectLayerTest, ChildOutsideBounds) {
97 const DlMatrix initial_matrix = DlMatrix::MakeTranslation({0.5f, 1.0f});
98 const DlRect local_cull_bounds = DlRect::MakeXYWH(0.0, 0.0, 2.0, 4.0);
99 const DlRect device_cull_bounds =
100 local_cull_bounds.TransformAndClipBounds(initial_matrix);
101 const DlRect child_bounds = DlRect::MakeXYWH(2.5, 5.0, 4.5, 4.0);
102 const DlRect clip_rect = DlRect::MakeXYWH(0.5, 1.0, 5.0, 6.0);
103 const DlPath child_path = DlPath::MakeRect(child_bounds);
104 const DlPaint child_paint = DlPaint(DlColor::kYellow());
105 auto mock_layer = std::make_shared<MockLayer>(child_path, child_paint);
106 auto layer = std::make_shared<ClipRectLayer>(clip_rect, Clip::kHardEdge);
107 layer->Add(mock_layer);
108
109 auto clip_cull_rect = local_cull_bounds.Intersection(clip_rect);
110 ASSERT_TRUE(clip_cull_rect.has_value());
111 auto clip_layer_bounds = child_bounds.Intersection(clip_rect);
112 ASSERT_TRUE(clip_layer_bounds.has_value());
113
114 // Set up both contexts to cull clipped child
115 preroll_context()->state_stack.set_preroll_delegate(device_cull_bounds,
116 initial_matrix);
117 paint_context().canvas->ClipRect(device_cull_bounds);
118 paint_context().canvas->Transform(initial_matrix);
119
120 layer->Preroll(preroll_context());
121 // Untouched
122 EXPECT_EQ(preroll_context()->state_stack.device_cull_rect(),
123 device_cull_bounds);
124 EXPECT_EQ(preroll_context()->state_stack.local_cull_rect(),
125 local_cull_bounds);
126 EXPECT_TRUE(preroll_context()->state_stack.is_empty());
127
128 EXPECT_EQ(mock_layer->paint_bounds(), child_bounds);
129 EXPECT_EQ(layer->paint_bounds(), clip_layer_bounds.value());
130 EXPECT_EQ(layer->child_paint_bounds(), child_bounds);
131 EXPECT_EQ(mock_layer->parent_cull_rect(), clip_cull_rect.value());
132 EXPECT_EQ(mock_layer->parent_matrix(), initial_matrix);
133 EXPECT_EQ(mock_layer->parent_mutators(), std::vector({Mutator(clip_rect)}));
134
135 EXPECT_FALSE(layer->needs_painting(paint_context()));
136 EXPECT_FALSE(mock_layer->needs_painting(paint_context()));
137 // Top level layer not visible so calling layer->Paint()
138 // would trip an FML_DCHECK
139}
140
141TEST_F(ClipRectLayerTest, FullyContainedChild) {
142 const DlMatrix initial_matrix = DlMatrix::MakeTranslation({0.5f, 1.0f});
143 const DlRect child_bounds = DlRect::MakeXYWH(1.0, 2.0, 2.0, 2.0);
144 const DlRect layer_bounds = DlRect::MakeXYWH(0.5, 1.0, 5.0, 6.0);
145 const DlPath child_path = DlPath::MakeRect(child_bounds);
146 const DlPaint child_paint = DlPaint(DlColor::kYellow());
147 auto mock_layer = std::make_shared<MockLayer>(child_path, child_paint);
148 auto layer = std::make_shared<ClipRectLayer>(layer_bounds, Clip::kHardEdge);
149 layer->Add(mock_layer);
150
151 preroll_context()->state_stack.set_preroll_delegate(initial_matrix);
152 layer->Preroll(preroll_context());
153
154 // Untouched
155 EXPECT_EQ(preroll_context()->state_stack.device_cull_rect(), kGiantRect);
156 EXPECT_TRUE(preroll_context()->state_stack.is_empty());
157
158 EXPECT_EQ(mock_layer->paint_bounds(), child_bounds);
159 EXPECT_EQ(layer->paint_bounds(), mock_layer->paint_bounds());
160 EXPECT_EQ(layer->child_paint_bounds(), child_bounds);
161 EXPECT_TRUE(mock_layer->needs_painting(paint_context()));
162 EXPECT_TRUE(layer->needs_painting(paint_context()));
163 EXPECT_EQ(mock_layer->parent_cull_rect(), layer_bounds);
164 EXPECT_EQ(mock_layer->parent_matrix(), initial_matrix);
165 EXPECT_EQ(mock_layer->parent_mutators(),
166 std::vector({Mutator(layer_bounds)}));
167
168 layer->Paint(display_list_paint_context());
169 DisplayListBuilder expected_builder;
170 /* (ClipRect)layer::Paint */ {
171 expected_builder.Save();
172 {
173 expected_builder.ClipRect(layer_bounds);
174 /* mock_layer::Paint */ {
175 expected_builder.DrawPath(child_path, child_paint);
176 }
177 }
178 expected_builder.Restore();
179 }
180 EXPECT_TRUE(DisplayListsEQ_Verbose(display_list(), expected_builder.Build()));
181}
182
183TEST_F(ClipRectLayerTest, PartiallyContainedChild) {
184 const DlMatrix initial_matrix = DlMatrix::MakeTranslation({0.5f, 1.0f});
185 const DlRect local_cull_bounds = DlRect::MakeXYWH(0.0, 0.0, 4.0, 5.5);
186 const DlRect device_cull_bounds =
187 local_cull_bounds.TransformAndClipBounds(initial_matrix);
188 const DlRect child_bounds = DlRect::MakeXYWH(2.5, 5.0, 4.5, 4.0);
189 const DlRect clip_rect = DlRect::MakeXYWH(0.5, 1.0, 5.0, 6.0);
190 const DlPath child_path = DlPath::MakeRect(child_bounds);
191 const DlPaint child_paint = DlPaint(DlColor::kYellow());
192 auto mock_layer = std::make_shared<MockLayer>(child_path, child_paint);
193 auto layer = std::make_shared<ClipRectLayer>(clip_rect, Clip::kHardEdge);
194 layer->Add(mock_layer);
195
196 auto clip_cull_rect = clip_rect.Intersection(local_cull_bounds);
197 ASSERT_TRUE(clip_cull_rect.has_value());
198 auto clip_layer_bounds = clip_rect.Intersection(child_bounds);
199 ASSERT_TRUE(clip_layer_bounds.has_value());
200
201 // Cull child
202 preroll_context()->state_stack.set_preroll_delegate(device_cull_bounds,
203 initial_matrix);
204 layer->Preroll(preroll_context());
205
206 // Untouched
207 EXPECT_EQ(preroll_context()->state_stack.device_cull_rect(),
208 device_cull_bounds);
209 EXPECT_TRUE(preroll_context()->state_stack.is_empty());
210
211 EXPECT_EQ(mock_layer->paint_bounds(), child_bounds);
212 EXPECT_EQ(layer->paint_bounds(), clip_layer_bounds.value());
213 EXPECT_EQ(layer->child_paint_bounds(), child_bounds);
214 EXPECT_TRUE(mock_layer->needs_painting(paint_context()));
215 EXPECT_TRUE(layer->needs_painting(paint_context()));
216 EXPECT_EQ(mock_layer->parent_cull_rect(), clip_cull_rect.value());
217 EXPECT_EQ(mock_layer->parent_matrix(), initial_matrix);
218 EXPECT_EQ(mock_layer->parent_mutators(), std::vector({Mutator(clip_rect)}));
219
220 layer->Paint(display_list_paint_context());
221 DisplayListBuilder expected_builder;
222 /* (ClipRect)layer::Paint */ {
223 expected_builder.Save();
224 {
225 expected_builder.ClipRect(clip_rect);
226 /* mock_layer::Paint */ {
227 expected_builder.DrawPath(child_path, child_paint);
228 }
229 }
230 expected_builder.Restore();
231 }
232 EXPECT_TRUE(DisplayListsEQ_Verbose(display_list(), expected_builder.Build()));
233}
234
235static bool ReadbackResult(PrerollContext* context,
236 Clip clip_behavior,
237 const std::shared_ptr<Layer>& child,
238 bool before) {
239 const DlRect layer_bounds = DlRect::MakeXYWH(0.5, 1.0, 5.0, 6.0);
240 auto layer = std::make_shared<ClipRectLayer>(layer_bounds, clip_behavior);
241 if (child != nullptr) {
242 layer->Add(child);
243 }
244 context->surface_needs_readback = before;
245 layer->Preroll(context);
246 return context->surface_needs_readback;
247}
248
249TEST_F(ClipRectLayerTest, Readback) {
250 PrerollContext* context = preroll_context();
251 DlPath path;
252 DlPaint paint;
253
254 const Clip hard = Clip::kHardEdge;
255 const Clip soft = Clip::kAntiAlias;
256 const Clip save_layer = Clip::kAntiAliasWithSaveLayer;
257
258 std::shared_ptr<MockLayer> nochild;
259 auto reader = std::make_shared<MockLayer>(path, paint);
260 reader->set_fake_reads_surface(true);
261 auto nonreader = std::make_shared<MockLayer>(path, paint);
262
263 // No children, no prior readback -> no readback after
264 EXPECT_FALSE(ReadbackResult(context, hard, nochild, false));
265 EXPECT_FALSE(ReadbackResult(context, soft, nochild, false));
266 EXPECT_FALSE(ReadbackResult(context, save_layer, nochild, false));
267
268 // No children, prior readback -> readback after
269 EXPECT_TRUE(ReadbackResult(context, hard, nochild, true));
270 EXPECT_TRUE(ReadbackResult(context, soft, nochild, true));
271 EXPECT_TRUE(ReadbackResult(context, save_layer, nochild, true));
272
273 // Non readback child, no prior readback -> no readback after
274 EXPECT_FALSE(ReadbackResult(context, hard, nonreader, false));
275 EXPECT_FALSE(ReadbackResult(context, soft, nonreader, false));
276 EXPECT_FALSE(ReadbackResult(context, save_layer, nonreader, false));
277
278 // Non readback child, prior readback -> readback after
279 EXPECT_TRUE(ReadbackResult(context, hard, nonreader, true));
280 EXPECT_TRUE(ReadbackResult(context, soft, nonreader, true));
281 EXPECT_TRUE(ReadbackResult(context, save_layer, nonreader, true));
282
283 // Readback child, no prior readback -> readback after unless SaveLayer
284 EXPECT_TRUE(ReadbackResult(context, hard, reader, false));
285 EXPECT_TRUE(ReadbackResult(context, soft, reader, false));
286 EXPECT_FALSE(ReadbackResult(context, save_layer, reader, false));
287
288 // Readback child, prior readback -> readback after
289 EXPECT_TRUE(ReadbackResult(context, hard, reader, true));
290 EXPECT_TRUE(ReadbackResult(context, soft, reader, true));
291 EXPECT_TRUE(ReadbackResult(context, save_layer, reader, true));
292}
293
294TEST_F(ClipRectLayerTest, OpacityInheritance) {
295 auto path1 = DlPath::MakeRectLTRB(10, 10, 30, 30);
296 auto mock1 = MockLayer::MakeOpacityCompatible(path1);
297 DlRect clip_rect = DlRect::MakeWH(500, 500);
298 auto clip_rect_layer =
299 std::make_shared<ClipRectLayer>(clip_rect, Clip::kHardEdge);
300 clip_rect_layer->Add(mock1);
301
302 // ClipRectLayer will pass through compatibility from a compatible child
303 PrerollContext* context = preroll_context();
304 clip_rect_layer->Preroll(context);
305 EXPECT_EQ(context->renderable_state_flags,
307
308 auto path2 = DlPath::MakeRectLTRB(40, 40, 50, 50);
309 auto mock2 = MockLayer::MakeOpacityCompatible(path2);
310 clip_rect_layer->Add(mock2);
311
312 // ClipRectLayer will pass through compatibility from multiple
313 // non-overlapping compatible children
314 clip_rect_layer->Preroll(context);
315 EXPECT_EQ(context->renderable_state_flags,
317
318 auto path3 = DlPath::MakeRectLTRB(20, 20, 40, 40);
319 auto mock3 = MockLayer::MakeOpacityCompatible(path3);
320 clip_rect_layer->Add(mock3);
321
322 // ClipRectLayer will not pass through compatibility from multiple
323 // overlapping children even if they are individually compatible
324 clip_rect_layer->Preroll(context);
325 EXPECT_EQ(context->renderable_state_flags, 0);
326
327 {
328 // ClipRectLayer(aa with saveLayer) will always be compatible
329 auto clip_path_savelayer = std::make_shared<ClipRectLayer>(
331 clip_path_savelayer->Add(mock1);
332 clip_path_savelayer->Add(mock2);
333
334 // Double check first two children are compatible and non-overlapping
335 clip_path_savelayer->Preroll(context);
336 EXPECT_EQ(context->renderable_state_flags, Layer::kSaveLayerRenderFlags);
337
338 // Now add the overlapping child and test again, should still be compatible
339 clip_path_savelayer->Add(mock3);
340 clip_path_savelayer->Preroll(context);
341 EXPECT_EQ(context->renderable_state_flags, Layer::kSaveLayerRenderFlags);
342 }
343
344 // An incompatible, but non-overlapping child for the following tests
345 auto path4 = DlPath::MakeRectLTRB(60, 60, 70, 70);
346 auto mock4 = MockLayer::Make(path4);
347
348 {
349 // ClipRectLayer with incompatible child will not be compatible
350 auto clip_rect_bad_child =
351 std::make_shared<ClipRectLayer>(clip_rect, Clip::kHardEdge);
352 clip_rect_bad_child->Add(mock1);
353 clip_rect_bad_child->Add(mock2);
354
355 // Double check first two children are compatible and non-overlapping
356 clip_rect_bad_child->Preroll(context);
357 EXPECT_EQ(context->renderable_state_flags,
359
360 clip_rect_bad_child->Add(mock4);
361
362 // The third child is non-overlapping, but not compatible so the
363 // TransformLayer should end up incompatible
364 clip_rect_bad_child->Preroll(context);
365 EXPECT_EQ(context->renderable_state_flags, 0);
366 }
367
368 {
369 // ClipRectLayer(aa with saveLayer) will always be compatible
370 auto clip_path_savelayer_bad_child = std::make_shared<ClipRectLayer>(
372 clip_path_savelayer_bad_child->Add(mock1);
373 clip_path_savelayer_bad_child->Add(mock2);
374
375 // Double check first two children are compatible and non-overlapping
376 clip_path_savelayer_bad_child->Preroll(context);
377 EXPECT_EQ(context->renderable_state_flags, Layer::kSaveLayerRenderFlags);
378
379 // Now add the incompatible child and test again, should still be compatible
380 clip_path_savelayer_bad_child->Add(mock4);
381 clip_path_savelayer_bad_child->Preroll(context);
382 EXPECT_EQ(context->renderable_state_flags, Layer::kSaveLayerRenderFlags);
383 }
384}
385
386TEST_F(ClipRectLayerTest, OpacityInheritancePainting) {
387 auto path1 = DlPath::MakeRectLTRB(10, 10, 30, 30);
388 auto mock1 = MockLayer::MakeOpacityCompatible(path1);
389 auto path2 = DlPath::MakeRectLTRB(40, 40, 50, 50);
390 auto mock2 = MockLayer::MakeOpacityCompatible(path2);
391 DlRect clip_rect = DlRect::MakeWH(500, 500);
392 auto clip_rect_layer =
393 std::make_shared<ClipRectLayer>(clip_rect, Clip::kAntiAlias);
394 clip_rect_layer->Add(mock1);
395 clip_rect_layer->Add(mock2);
396
397 // ClipRectLayer will pass through compatibility from multiple
398 // non-overlapping compatible children
399 PrerollContext* context = preroll_context();
400 clip_rect_layer->Preroll(context);
401 EXPECT_EQ(context->renderable_state_flags,
403
404 int opacity_alpha = 0x7F;
405 DlPoint offset = DlPoint(10, 10);
406 auto opacity_layer = std::make_shared<OpacityLayer>(opacity_alpha, offset);
407 opacity_layer->Add(clip_rect_layer);
408 opacity_layer->Preroll(context);
409 EXPECT_TRUE(opacity_layer->children_can_accept_opacity());
410
411 DisplayListBuilder expected_builder;
412 /* OpacityLayer::Paint() */ {
413 expected_builder.Save();
414 {
415 expected_builder.Translate(offset.x, offset.y);
416 /* ClipRectLayer::Paint() */ {
417 expected_builder.Save();
418 expected_builder.ClipRect(clip_rect, DlClipOp::kIntersect, true);
419 /* child layer1 paint */ {
420 expected_builder.DrawPath(path1, DlPaint().setAlpha(opacity_alpha));
421 }
422 /* child layer2 paint */ {
423 expected_builder.DrawPath(path2, DlPaint().setAlpha(opacity_alpha));
424 }
425 expected_builder.Restore();
426 }
427 }
428 expected_builder.Restore();
429 }
430
431 opacity_layer->Paint(display_list_paint_context());
432 EXPECT_TRUE(DisplayListsEQ_Verbose(expected_builder.Build(), display_list()));
433}
434
435TEST_F(ClipRectLayerTest, OpacityInheritanceSaveLayerPainting) {
436 auto path1 = DlPath::MakeRectLTRB(10, 10, 30, 30);
437 auto mock1 = MockLayer::MakeOpacityCompatible(path1);
438 auto path2 = DlPath::MakeRectLTRB(20, 20, 40, 40);
439 auto mock2 = MockLayer::MakeOpacityCompatible(path2);
440 auto children_bounds = path1.GetBounds().Union(path2.GetBounds());
441 DlRect clip_rect = DlRect::MakeWH(500, 500);
442 auto clip_rect_layer =
443 std::make_shared<ClipRectLayer>(clip_rect, Clip::kAntiAliasWithSaveLayer);
444 clip_rect_layer->Add(mock1);
445 clip_rect_layer->Add(mock2);
446
447 // ClipRectLayer will pass through compatibility from multiple
448 // non-overlapping compatible children
449 PrerollContext* context = preroll_context();
450 clip_rect_layer->Preroll(context);
451 EXPECT_EQ(context->renderable_state_flags, Layer::kSaveLayerRenderFlags);
452
453 int opacity_alpha = 0x7F;
454 DlPoint offset = DlPoint(10, 10);
455 auto opacity_layer = std::make_shared<OpacityLayer>(opacity_alpha, offset);
456 opacity_layer->Add(clip_rect_layer);
457 opacity_layer->Preroll(context);
458 EXPECT_TRUE(opacity_layer->children_can_accept_opacity());
459
460 DisplayListBuilder expected_builder;
461 /* OpacityLayer::Paint() */ {
462 expected_builder.Save();
463 {
464 expected_builder.Translate(offset.x, offset.y);
465 /* ClipRectLayer::Paint() */ {
466 expected_builder.Save();
467 expected_builder.ClipRect(clip_rect, DlClipOp::kIntersect, true);
468 expected_builder.SaveLayer(children_bounds,
469 &DlPaint().setAlpha(opacity_alpha));
470 /* child layer1 paint */ {
471 expected_builder.DrawPath(path1, DlPaint());
472 }
473 /* child layer2 paint */ { //
474 expected_builder.DrawPath(path2, DlPaint());
475 }
476 expected_builder.Restore();
477 }
478 }
479 expected_builder.Restore();
480 }
481
482 opacity_layer->Paint(display_list_paint_context());
483 EXPECT_TRUE(DisplayListsEQ_Verbose(expected_builder.Build(), display_list()));
484}
485
486TEST_F(ClipRectLayerTest, LayerCached) {
487 auto path1 = DlPath::MakeRectLTRB(10, 10, 30, 30);
488 auto mock1 = MockLayer::MakeOpacityCompatible(path1);
489 DlRect clip_rect = DlRect::MakeWH(500, 500);
490 auto layer =
491 std::make_shared<ClipRectLayer>(clip_rect, Clip::kAntiAliasWithSaveLayer);
492 layer->Add(mock1);
493
494 auto initial_transform = DlMatrix::MakeTranslation({50.0, 25.5});
495 DlMatrix cache_ctm = initial_transform;
496 DisplayListBuilder cache_canvas;
497 cache_canvas.Transform(cache_ctm);
498
499 use_mock_raster_cache();
500 preroll_context()->state_stack.set_preroll_delegate(initial_transform);
501
502 const auto* clip_cache_item = layer->raster_cache_item();
503
504 layer->Preroll(preroll_context());
505 LayerTree::TryToRasterCache(cacheable_items(), &paint_context());
506
507 EXPECT_EQ(raster_cache()->GetLayerCachedEntriesCount(), (size_t)0);
508 EXPECT_EQ(clip_cache_item->cache_state(), RasterCacheItem::CacheState::kNone);
509
510 layer->Preroll(preroll_context());
511 LayerTree::TryToRasterCache(cacheable_items(), &paint_context());
512 EXPECT_EQ(raster_cache()->GetLayerCachedEntriesCount(), (size_t)0);
513 EXPECT_EQ(clip_cache_item->cache_state(), RasterCacheItem::CacheState::kNone);
514
515 layer->Preroll(preroll_context());
516 LayerTree::TryToRasterCache(cacheable_items(), &paint_context());
517 EXPECT_EQ(raster_cache()->GetLayerCachedEntriesCount(), (size_t)1);
518 EXPECT_EQ(clip_cache_item->cache_state(),
520 DlPaint paint;
521 EXPECT_TRUE(raster_cache()->Draw(clip_cache_item->GetId().value(),
522 cache_canvas, &paint));
523}
524
525TEST_F(ClipRectLayerTest, EmptyClipDoesNotCullPlatformView) {
526 const DlPoint view_offset = DlPoint(0.0f, 0.0f);
527 const DlSize view_size = DlSize(8.0f, 8.0f);
528 const int64_t view_id = 42;
529 auto platform_view =
530 std::make_shared<PlatformViewLayer>(view_offset, view_size, view_id);
531
532 auto clip = std::make_shared<ClipRectLayer>(DlRect(), Clip::kHardEdge);
533 clip->Add(platform_view);
534
535 auto embedder = MockViewEmbedder();
536 DisplayListBuilder fake_overlay_builder;
537 embedder.AddCanvas(&fake_overlay_builder);
538 preroll_context()->view_embedder = &embedder;
539 paint_context().view_embedder = &embedder;
540
541 clip->Preroll(preroll_context());
542 EXPECT_EQ(embedder.prerolled_views(), std::vector<int64_t>({view_id}));
543
544 clip->Paint(paint_context());
545 EXPECT_EQ(embedder.painted_views(), std::vector<int64_t>({view_id}));
546}
547
548} // namespace testing
549} // namespace flutter
550
551// NOLINTEND(bugprone-unchecked-optional-access)
std::unique_ptr< flutter::PlatformViewIOS > platform_view
static DlPath MakeRectLTRB(DlScalar left, DlScalar top, DlScalar right, DlScalar bottom)
Definition dl_path.cc:43
static DlPath MakeRect(const DlRect &rect)
Definition dl_path.cc:39
static constexpr int kSaveLayerRenderFlags
Definition layer.h:118
static constexpr int kCallerCanApplyOpacity
static void TryToRasterCache(const std::vector< RasterCacheItem * > &raster_cached_entries, const PaintContext *paint_context, bool ignore_raster_cache=false)
Definition layer_tree.cc:67
static std::shared_ptr< MockLayer > Make(const DlPath &path, DlPaint paint=DlPaint())
Definition mock_layer.h:30
static std::shared_ptr< MockLayer > MakeOpacityCompatible(const DlPath &path)
Definition mock_layer.h:35
G_BEGIN_DECLS FlutterViewId view_id
TEST_F(DisplayListTest, Defaults)
LayerTestBase<::testing::Test > LayerTest
Definition layer_test.h:177
bool DisplayListsEQ_Verbose(const DisplayList *a, const DisplayList *b)
static bool ReadbackResult(PrerollContext *context, Clip clip_behavior, const std::shared_ptr< Layer > &child, bool before)
@ kAntiAlias
Definition layer.h:43
@ kAntiAliasWithSaveLayer
Definition layer.h:43
@ kNone
Definition layer.h:43
@ kHardEdge
Definition layer.h:43
impeller::Matrix DlMatrix
impeller::Rect DlRect
impeller::Size DlSize
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
Definition switch_defs.h:52
static constexpr DlRect kGiantRect
Definition layer.h:40
impeller::Point DlPoint
flutter::DlPath DlPath
flutter::DlPaint DlPaint
static constexpr DlColor kYellow()
Definition dl_color.h:76
bool surface_needs_readback
Definition layer.h:51
static constexpr Matrix MakeTranslation(const Vector3 &t)
Definition matrix.h:95
constexpr Quad Transform(const Quad &quad) const
Definition matrix.h:623
static constexpr TRect MakeWH(Type width, Type height)
Definition rect.h:140
static constexpr TRect MakeXYWH(Type x, Type y, Type width, Type height)
Definition rect.h:136
constexpr TRect TransformAndClipBounds(const Matrix &transform) const
Creates a new bounding box that contains this transformed rectangle, clipped against the near clippin...
Definition rect.h:438