Flutter Engine
The Flutter Engine
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
5#include "flutter/flow/layers/clip_rect_layer.h"
6
7#include "flutter/flow/layers/layer_tree.h"
8#include "flutter/flow/layers/opacity_layer.h"
9#include "flutter/flow/layers/platform_view_layer.h"
10#include "flutter/flow/testing/layer_test.h"
11#include "flutter/flow/testing/mock_embedder.h"
12#include "flutter/flow/testing/mock_layer.h"
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
24
25#ifndef NDEBUG
26TEST_F(ClipRectLayerTest, ClipNoneBehaviorDies) {
27 EXPECT_DEATH_IF_SUPPORTED(
28 auto clip = std::make_shared<ClipRectLayer>(kEmptyRect, Clip::kNone),
29 "clip_behavior != Clip::kNone");
30}
31
32TEST_F(ClipRectLayerTest, PaintingEmptyLayerDies) {
33 auto layer = std::make_shared<ClipRectLayer>(kEmptyRect, Clip::kHardEdge);
34
35 layer->Preroll(preroll_context());
36
37 // Untouched
38 EXPECT_EQ(preroll_context()->state_stack.device_cull_rect(), kGiantRect);
39 EXPECT_TRUE(preroll_context()->state_stack.is_empty());
40
41 EXPECT_EQ(layer->paint_bounds(), kEmptyRect);
42 EXPECT_EQ(layer->child_paint_bounds(), kEmptyRect);
43 EXPECT_FALSE(layer->needs_painting(paint_context()));
44
45 EXPECT_DEATH_IF_SUPPORTED(layer->Paint(paint_context()),
46 "needs_painting\\(context\\)");
47}
48
49TEST_F(ClipRectLayerTest, PaintBeforePrerollDies) {
50 const SkRect layer_bounds = SkRect::MakeXYWH(0.5, 1.0, 5.0, 6.0);
51 auto layer = std::make_shared<ClipRectLayer>(layer_bounds, Clip::kHardEdge);
52 EXPECT_EQ(layer->paint_bounds(), kEmptyRect);
53 EXPECT_EQ(layer->child_paint_bounds(), kEmptyRect);
54 EXPECT_FALSE(layer->needs_painting(paint_context()));
55
56 EXPECT_DEATH_IF_SUPPORTED(layer->Paint(paint_context()),
57 "needs_painting\\(context\\)");
58}
59
60TEST_F(ClipRectLayerTest, PaintingCulledLayerDies) {
61 const SkMatrix initial_matrix = SkMatrix::Translate(0.5f, 1.0f);
62 const SkRect child_bounds = SkRect::MakeXYWH(1.0, 2.0, 2.0, 2.0);
63 const SkRect layer_bounds = SkRect::MakeXYWH(0.5, 1.0, 5.0, 6.0);
64 const SkRect distant_bounds = SkRect::MakeXYWH(100.0, 100.0, 10.0, 10.0);
65 const SkPath child_path = SkPath().addRect(child_bounds);
66 auto mock_layer = std::make_shared<MockLayer>(child_path);
67 auto layer = std::make_shared<ClipRectLayer>(layer_bounds, Clip::kHardEdge);
68 layer->Add(mock_layer);
69
70 // Cull these children
71 preroll_context()->state_stack.set_preroll_delegate(distant_bounds,
72 initial_matrix);
73 layer->Preroll(preroll_context());
74
75 // Untouched
76 EXPECT_EQ(preroll_context()->state_stack.device_cull_rect(), distant_bounds);
77 EXPECT_TRUE(preroll_context()->state_stack.is_empty());
78
79 EXPECT_EQ(mock_layer->paint_bounds(), child_bounds);
80 EXPECT_EQ(layer->paint_bounds(), child_bounds);
81 EXPECT_EQ(layer->child_paint_bounds(), child_bounds);
82 EXPECT_TRUE(mock_layer->needs_painting(paint_context()));
83 EXPECT_TRUE(layer->needs_painting(paint_context()));
84 EXPECT_EQ(mock_layer->parent_cull_rect(), kEmptyRect);
85 EXPECT_EQ(mock_layer->parent_matrix(), initial_matrix);
86 EXPECT_EQ(mock_layer->parent_mutators(),
87 std::vector({Mutator(layer_bounds)}));
88
89 auto mutator = paint_context().state_stack.save();
90 mutator.clipRect(distant_bounds, false);
91 EXPECT_FALSE(mock_layer->needs_painting(paint_context()));
92 EXPECT_FALSE(layer->needs_painting(paint_context()));
93 EXPECT_DEATH_IF_SUPPORTED(layer->Paint(paint_context()),
94 "needs_painting\\(context\\)");
95}
96#endif
97
98TEST_F(ClipRectLayerTest, ChildOutsideBounds) {
99 const SkMatrix initial_matrix = SkMatrix::Translate(0.5f, 1.0f);
100 const SkRect local_cull_bounds = SkRect::MakeXYWH(0.0, 0.0, 2.0, 4.0);
101 const SkRect device_cull_bounds = initial_matrix.mapRect(local_cull_bounds);
102 const SkRect child_bounds = SkRect::MakeXYWH(2.5, 5.0, 4.5, 4.0);
103 const SkRect clip_rect = SkRect::MakeXYWH(0.5, 1.0, 5.0, 6.0);
104 const SkPath child_path = SkPath().addRect(child_bounds);
105 const DlPaint child_paint = DlPaint(DlColor::kYellow());
106 auto mock_layer = std::make_shared<MockLayer>(child_path, child_paint);
107 auto layer = std::make_shared<ClipRectLayer>(clip_rect, Clip::kHardEdge);
108 layer->Add(mock_layer);
109
110 SkRect clip_cull_rect = local_cull_bounds;
111 ASSERT_TRUE(clip_cull_rect.intersect(clip_rect));
112 SkRect clip_layer_bounds = child_bounds;
113 ASSERT_TRUE(clip_layer_bounds.intersect(clip_rect));
114
115 // Set up both contexts to cull clipped child
116 preroll_context()->state_stack.set_preroll_delegate(device_cull_bounds,
117 initial_matrix);
118 paint_context().canvas->ClipRect(device_cull_bounds);
119 paint_context().canvas->Transform(initial_matrix);
120
121 layer->Preroll(preroll_context());
122 // Untouched
123 EXPECT_EQ(preroll_context()->state_stack.device_cull_rect(),
124 device_cull_bounds);
125 EXPECT_EQ(preroll_context()->state_stack.local_cull_rect(),
126 local_cull_bounds);
127 EXPECT_TRUE(preroll_context()->state_stack.is_empty());
128
129 EXPECT_EQ(mock_layer->paint_bounds(), child_bounds);
130 EXPECT_EQ(layer->paint_bounds(), clip_layer_bounds);
131 EXPECT_EQ(layer->child_paint_bounds(), child_bounds);
132 EXPECT_EQ(mock_layer->parent_cull_rect(), clip_cull_rect);
133 EXPECT_EQ(mock_layer->parent_matrix(), initial_matrix);
134 EXPECT_EQ(mock_layer->parent_mutators(), std::vector({Mutator(clip_rect)}));
135
136 EXPECT_FALSE(layer->needs_painting(paint_context()));
137 EXPECT_FALSE(mock_layer->needs_painting(paint_context()));
138 // Top level layer not visible so calling layer->Paint()
139 // would trip an FML_DCHECK
140}
141
142TEST_F(ClipRectLayerTest, FullyContainedChild) {
143 const SkMatrix initial_matrix = SkMatrix::Translate(0.5f, 1.0f);
144 const SkRect child_bounds = SkRect::MakeXYWH(1.0, 2.0, 2.0, 2.0);
145 const SkRect layer_bounds = SkRect::MakeXYWH(0.5, 1.0, 5.0, 6.0);
146 const SkPath child_path = SkPath().addRect(child_bounds);
147 const DlPaint child_paint = DlPaint(DlColor::kYellow());
148 auto mock_layer = std::make_shared<MockLayer>(child_path, child_paint);
149 auto layer = std::make_shared<ClipRectLayer>(layer_bounds, Clip::kHardEdge);
150 layer->Add(mock_layer);
151
152 preroll_context()->state_stack.set_preroll_delegate(initial_matrix);
153 layer->Preroll(preroll_context());
154
155 // Untouched
156 EXPECT_EQ(preroll_context()->state_stack.device_cull_rect(), kGiantRect);
157 EXPECT_TRUE(preroll_context()->state_stack.is_empty());
158
159 EXPECT_EQ(mock_layer->paint_bounds(), child_bounds);
160 EXPECT_EQ(layer->paint_bounds(), mock_layer->paint_bounds());
161 EXPECT_EQ(layer->child_paint_bounds(), child_bounds);
162 EXPECT_TRUE(mock_layer->needs_painting(paint_context()));
163 EXPECT_TRUE(layer->needs_painting(paint_context()));
164 EXPECT_EQ(mock_layer->parent_cull_rect(), layer_bounds);
165 EXPECT_EQ(mock_layer->parent_matrix(), initial_matrix);
166 EXPECT_EQ(mock_layer->parent_mutators(),
167 std::vector({Mutator(layer_bounds)}));
168
169 layer->Paint(display_list_paint_context());
170 DisplayListBuilder expected_builder;
171 /* (ClipRect)layer::Paint */ {
172 expected_builder.Save();
173 {
174 expected_builder.ClipRect(layer_bounds);
175 /* mock_layer::Paint */ {
176 expected_builder.DrawPath(child_path, child_paint);
177 }
178 }
179 expected_builder.Restore();
180 }
181 EXPECT_TRUE(DisplayListsEQ_Verbose(display_list(), expected_builder.Build()));
182}
183
184TEST_F(ClipRectLayerTest, PartiallyContainedChild) {
185 const SkMatrix initial_matrix = SkMatrix::Translate(0.5f, 1.0f);
186 const SkRect local_cull_bounds = SkRect::MakeXYWH(0.0, 0.0, 4.0, 5.5);
187 const SkRect device_cull_bounds = initial_matrix.mapRect(local_cull_bounds);
188 const SkRect child_bounds = SkRect::MakeXYWH(2.5, 5.0, 4.5, 4.0);
189 const SkRect clip_rect = SkRect::MakeXYWH(0.5, 1.0, 5.0, 6.0);
190 const SkPath child_path = SkPath().addRect(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 SkRect clip_cull_rect = clip_rect;
197 ASSERT_TRUE(clip_cull_rect.intersect(local_cull_bounds));
198 SkRect clip_layer_bounds = clip_rect;
199 ASSERT_TRUE(clip_layer_bounds.intersect(child_bounds));
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);
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);
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 SkRect layer_bounds = SkRect::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 SkPath path;
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 = SkPath().addRect({10, 10, 30, 30});
297 SkRect clip_rect = SkRect::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 = SkPath().addRect({40, 40, 50, 50});
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 = SkPath().addRect({20, 20, 40, 40});
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 = SkPath().addRect({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 = SkPath().addRect({10, 10, 30, 30});
389 auto path2 = SkPath().addRect({40, 40, 50, 50});
391 SkRect clip_rect = SkRect::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 SkPoint offset = SkPoint::Make(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.fX, offset.fY);
416 /* ClipRectLayer::Paint() */ {
417 expected_builder.Save();
418 expected_builder.ClipRect(clip_rect, ClipOp::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 = SkPath().addRect({10, 10, 30, 30});
438 auto path2 = SkPath().addRect({20, 20, 40, 40});
440 auto children_bounds = path1.getBounds();
441 children_bounds.join(path2.getBounds());
442 SkRect clip_rect = SkRect::MakeWH(500, 500);
443 auto clip_rect_layer =
444 std::make_shared<ClipRectLayer>(clip_rect, Clip::kAntiAliasWithSaveLayer);
445 clip_rect_layer->Add(mock1);
446 clip_rect_layer->Add(mock2);
447
448 // ClipRectLayer will pass through compatibility from multiple
449 // non-overlapping compatible children
450 PrerollContext* context = preroll_context();
451 clip_rect_layer->Preroll(context);
452 EXPECT_EQ(context->renderable_state_flags, Layer::kSaveLayerRenderFlags);
453
454 int opacity_alpha = 0x7F;
455 SkPoint offset = SkPoint::Make(10, 10);
456 auto opacity_layer = std::make_shared<OpacityLayer>(opacity_alpha, offset);
457 opacity_layer->Add(clip_rect_layer);
458 opacity_layer->Preroll(context);
459 EXPECT_TRUE(opacity_layer->children_can_accept_opacity());
460
461 DisplayListBuilder expected_builder;
462 /* OpacityLayer::Paint() */ {
463 expected_builder.Save();
464 {
465 expected_builder.Translate(offset.fX, offset.fY);
466 /* ClipRectLayer::Paint() */ {
467 expected_builder.Save();
468 expected_builder.ClipRect(clip_rect, ClipOp::kIntersect, true);
469 expected_builder.SaveLayer(&children_bounds,
470 &DlPaint().setAlpha(opacity_alpha));
471 /* child layer1 paint */ {
472 expected_builder.DrawPath(path1, DlPaint());
473 }
474 /* child layer2 paint */ { //
475 expected_builder.DrawPath(path2, DlPaint());
476 }
477 expected_builder.Restore();
478 }
479 }
480 expected_builder.Restore();
481 }
482
483 opacity_layer->Paint(display_list_paint_context());
484 EXPECT_TRUE(DisplayListsEQ_Verbose(expected_builder.Build(), display_list()));
485}
486
487TEST_F(ClipRectLayerTest, LayerCached) {
488 auto path1 = SkPath().addRect({10, 10, 30, 30});
490 SkRect clip_rect = SkRect::MakeWH(500, 500);
491 auto layer =
492 std::make_shared<ClipRectLayer>(clip_rect, Clip::kAntiAliasWithSaveLayer);
493 layer->Add(mock1);
494
495 auto initial_transform = SkMatrix::Translate(50.0, 25.5);
496 SkMatrix cache_ctm = initial_transform;
497 DisplayListBuilder cache_canvas;
498 cache_canvas.Transform(cache_ctm);
499
500 use_mock_raster_cache();
501 preroll_context()->state_stack.set_preroll_delegate(initial_transform);
502
503 const auto* clip_cache_item = layer->raster_cache_item();
504
505 layer->Preroll(preroll_context());
506 LayerTree::TryToRasterCache(cacheable_items(), &paint_context());
507
508 EXPECT_EQ(raster_cache()->GetLayerCachedEntriesCount(), (size_t)0);
509 EXPECT_EQ(clip_cache_item->cache_state(), RasterCacheItem::CacheState::kNone);
510
511 layer->Preroll(preroll_context());
512 LayerTree::TryToRasterCache(cacheable_items(), &paint_context());
513 EXPECT_EQ(raster_cache()->GetLayerCachedEntriesCount(), (size_t)0);
514 EXPECT_EQ(clip_cache_item->cache_state(), RasterCacheItem::CacheState::kNone);
515
516 layer->Preroll(preroll_context());
517 LayerTree::TryToRasterCache(cacheable_items(), &paint_context());
518 EXPECT_EQ(raster_cache()->GetLayerCachedEntriesCount(), (size_t)1);
519 EXPECT_EQ(clip_cache_item->cache_state(),
520 RasterCacheItem::CacheState::kCurrent);
522 EXPECT_TRUE(raster_cache()->Draw(clip_cache_item->GetId().value(),
523 cache_canvas, &paint));
524}
525
526TEST_F(ClipRectLayerTest, EmptyClipDoesNotCullPlatformView) {
527 const SkPoint view_offset = SkPoint::Make(0.0f, 0.0f);
528 const SkSize view_size = SkSize::Make(8.0f, 8.0f);
529 const int64_t view_id = 42;
530 auto platform_view =
531 std::make_shared<PlatformViewLayer>(view_offset, view_size, view_id);
532
533 auto clip = std::make_shared<ClipRectLayer>(kEmptyRect, Clip::kHardEdge);
534 clip->Add(platform_view);
535
536 auto embedder = MockViewEmbedder();
537 DisplayListBuilder fake_overlay_builder;
538 embedder.AddCanvas(&fake_overlay_builder);
539 preroll_context()->view_embedder = &embedder;
540 paint_context().view_embedder = &embedder;
541
542 clip->Preroll(preroll_context());
543 EXPECT_EQ(embedder.prerolled_views(), std::vector<int64_t>({view_id}));
544
545 clip->Paint(paint_context());
546 EXPECT_EQ(embedder.painted_views(), std::vector<int64_t>({view_id}));
547}
548
549} // namespace testing
550} // namespace flutter
551
552// NOLINTEND(bugprone-unchecked-optional-access)
std::unique_ptr< flutter::PlatformViewIOS > platform_view
static SkPath path1()
static SkPath path4()
static SkPath path3()
static SkPath path2()
static SkPath clip(const SkPath &path, const SkHalfPlane &plane)
Definition: SkPath.cpp:3892
static SkMatrix Translate(SkScalar dx, SkScalar dy)
Definition: SkMatrix.h:91
bool mapRect(SkRect *dst, const SkRect &src, SkApplyPerspectiveClip pc=SkApplyPerspectiveClip::kYes) const
Definition: SkMatrix.cpp:1141
Definition: SkPath.h:59
const SkRect & getBounds() const
Definition: SkPath.cpp:430
SkPath & addRect(const SkRect &rect, SkPathDirection dir, unsigned start)
Definition: SkPath.cpp:864
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:68
static constexpr int kSaveLayerRenderFlags
Definition: layer.h:132
static std::shared_ptr< MockLayer > MakeOpacityCompatible(const SkPath &path)
Definition: mock_layer.h:35
static std::shared_ptr< MockLayer > Make(const SkPath &path, DlPaint paint=DlPaint())
Definition: mock_layer.h:30
static void Draw(SkCanvas *canvas, const SkRect &rect)
const Paint & paint
Definition: color_source.cc:38
TEST_F(DisplayListTest, Defaults)
LayerTestBase<::testing::Test > LayerTest
Definition: layer_test.h:210
bool DisplayListsEQ_Verbose(const DisplayList *a, const DisplayList *b)
static constexpr SkRect kEmptyRect
Definition: mock_canvas.h:30
static bool ReadbackResult(PrerollContext *context, Clip clip_behavior, const std::shared_ptr< Layer > &child, bool before)
Clip
Definition: layer.h:53
@ kAntiAlias
Definition: layer.h:53
@ kAntiAliasWithSaveLayer
Definition: layer.h:53
@ kNone
Definition: layer.h:53
@ kHardEdge
Definition: layer.h:53
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: switches.h:57
static constexpr SkRect kGiantRect
Definition: layer.h:50
flutter::DlPaint DlPaint
SeparatedVector2 offset
static constexpr SkPoint Make(float x, float y)
Definition: SkPoint_impl.h:173
bool intersect(const SkRect &r)
Definition: SkRect.cpp:114
static constexpr SkRect MakeXYWH(float x, float y, float w, float h)
Definition: SkRect.h:659
void join(const SkRect &r)
Definition: SkRect.cpp:126
static constexpr SkRect MakeWH(float w, float h)
Definition: SkRect.h:609
Definition: SkSize.h:52
static constexpr SkSize Make(SkScalar w, SkScalar h)
Definition: SkSize.h:56
static constexpr DlColor kYellow()
Definition: dl_color.h:29
bool surface_needs_readback
Definition: layer.h:61
#define EXPECT_TRUE(handle)
Definition: unit_test.h:678