Flutter Engine
 
Loading...
Searching...
No Matches
container_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
12#include "flutter/fml/macros.h"
13#include "gtest/gtest.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(ContainerLayerTest, LayerWithParentHasPlatformView) {
25 auto layer = std::make_shared<ContainerLayer>();
26
27 preroll_context()->has_platform_view = true;
28 EXPECT_DEATH_IF_SUPPORTED(layer->Preroll(preroll_context()),
29 "!context->has_platform_view");
30}
31
32TEST_F(ContainerLayerTest, LayerWithParentHasTextureLayer) {
33 auto layer = std::make_shared<ContainerLayer>();
34
35 preroll_context()->has_texture_layer = true;
36 EXPECT_DEATH_IF_SUPPORTED(layer->Preroll(preroll_context()),
37 "!context->has_texture_layer");
38}
39
40TEST_F(ContainerLayerTest, PaintingEmptyLayerDies) {
41 auto layer = std::make_shared<ContainerLayer>();
42
43 layer->Preroll(preroll_context());
44 EXPECT_EQ(layer->paint_bounds(), DlRect());
45 EXPECT_EQ(layer->child_paint_bounds(), DlRect());
46 EXPECT_FALSE(layer->needs_painting(paint_context()));
47
48 EXPECT_DEATH_IF_SUPPORTED(layer->Paint(paint_context()),
49 "needs_painting\\(context\\)");
50}
51
52TEST_F(ContainerLayerTest, PaintBeforePrerollDies) {
53 DlPath child_path = DlPath::MakeRectLTRB(5.0f, 6.0f, 20.5f, 21.5f);
54 auto mock_layer = std::make_shared<MockLayer>(child_path);
55 auto layer = std::make_shared<ContainerLayer>();
56 layer->Add(mock_layer);
57
58 EXPECT_EQ(layer->paint_bounds(), DlRect());
59 EXPECT_EQ(layer->child_paint_bounds(), DlRect());
60 EXPECT_DEATH_IF_SUPPORTED(layer->Paint(paint_context()),
61 "needs_painting\\(context\\)");
62}
63#endif
64
65TEST_F(ContainerLayerTest, LayerWithParentHasTextureLayerNeedsResetFlag) {
66 DlPath child_path1 = DlPath::MakeRectLTRB(5.0f, 6.0f, 20.5f, 21.5f);
67 DlPath child_path2 = DlPath::MakeRectLTRB(8.0f, 2.0f, 16.5f, 14.5f);
68 DlPaint child_paint1 = DlPaint(DlColor::kMidGrey());
69 DlPaint child_paint2 = DlPaint(DlColor::kGreen());
70
71 auto mock_layer1 = std::make_shared<MockLayer>(child_path1, child_paint1);
72 mock_layer1->set_fake_has_texture_layer(true);
73 auto mock_layer2 = std::make_shared<MockLayer>(child_path2, child_paint2);
74
75 auto root = std::make_shared<ContainerLayer>();
76 auto container_layer1 = std::make_shared<ContainerLayer>();
77 auto container_layer2 = std::make_shared<ContainerLayer>();
78 root->Add(container_layer1);
79 root->Add(container_layer2);
80 container_layer1->Add(mock_layer1);
81 container_layer2->Add(mock_layer2);
82
83 EXPECT_EQ(preroll_context()->has_texture_layer, false);
84 root->Preroll(preroll_context());
85 EXPECT_EQ(preroll_context()->has_texture_layer, true);
86 // The flag for holding texture layer from parent needs to be clear
87 EXPECT_EQ(mock_layer2->parent_has_texture_layer(), false);
88}
89
91 DlPath child_path = DlPath::MakeRectLTRB(5.0f, 6.0f, 20.5f, 21.5f);
92 DlPaint child_paint = DlPaint(DlColor::kGreen());
93 DlMatrix initial_transform = DlMatrix::MakeTranslation({-0.5f, -0.5f});
94
95 auto mock_layer = std::make_shared<MockLayer>(child_path, child_paint);
96 auto layer = std::make_shared<ContainerLayer>();
97 layer->Add(mock_layer);
98
99 preroll_context()->state_stack.set_preroll_delegate(initial_transform);
100 layer->Preroll(preroll_context());
101 EXPECT_FALSE(preroll_context()->has_platform_view);
102 EXPECT_EQ(mock_layer->paint_bounds(), child_path.GetBounds());
103 EXPECT_EQ(layer->paint_bounds(), child_path.GetBounds());
104 EXPECT_EQ(layer->child_paint_bounds(), layer->paint_bounds());
105 EXPECT_TRUE(mock_layer->needs_painting(paint_context()));
106 EXPECT_TRUE(layer->needs_painting(paint_context()));
107 EXPECT_EQ(mock_layer->parent_matrix(), initial_transform);
108 EXPECT_EQ(mock_layer->parent_cull_rect(), kGiantRect);
109
110 layer->Paint(display_list_paint_context());
111 DisplayListBuilder expected_builder;
112 /* (Container)layer::Paint */ {
113 /* mock_layer::Paint */ {
114 expected_builder.DrawPath(child_path, child_paint);
115 }
116 }
117 EXPECT_TRUE(DisplayListsEQ_Verbose(display_list(), expected_builder.Build()));
118}
119
121 DlPath child_path1 = DlPath::MakeRectLTRB(5.0f, 6.0f, 20.5f, 21.5f);
122 DlPath child_path2 = DlPath::MakeRectLTRB(8.0f, 2.0f, 16.5f, 14.5f);
123 DlPaint child_paint1 = DlPaint(DlColor::kMidGrey());
124 DlPaint child_paint2 = DlPaint(DlColor::kGreen());
125 DlMatrix initial_transform = DlMatrix::MakeTranslation({-0.5f, -0.5f});
126
127 auto mock_layer1 = std::make_shared<MockLayer>(child_path1, child_paint1);
128 mock_layer1->set_fake_has_platform_view(true);
129 auto mock_layer2 = std::make_shared<MockLayer>(child_path2, child_paint2);
130 auto layer = std::make_shared<ContainerLayer>();
131 layer->Add(mock_layer1);
132 layer->Add(mock_layer2);
133
134 DlRect expected_total_bounds =
135 child_path1.GetBounds().Union(child_path2.GetBounds());
136 preroll_context()->state_stack.set_preroll_delegate(initial_transform);
137 layer->Preroll(preroll_context());
138 EXPECT_TRUE(preroll_context()->has_platform_view);
139 EXPECT_EQ(mock_layer1->paint_bounds(), child_path1.GetBounds());
140 EXPECT_EQ(mock_layer2->paint_bounds(), child_path2.GetBounds());
141 EXPECT_EQ(layer->paint_bounds(), expected_total_bounds);
142 EXPECT_EQ(layer->child_paint_bounds(), layer->paint_bounds());
143 EXPECT_TRUE(mock_layer1->needs_painting(paint_context()));
144 EXPECT_TRUE(mock_layer2->needs_painting(paint_context()));
145 EXPECT_TRUE(layer->needs_painting(paint_context()));
146 EXPECT_EQ(mock_layer1->parent_matrix(), initial_transform);
147 EXPECT_EQ(mock_layer2->parent_matrix(), initial_transform);
148 EXPECT_EQ(mock_layer1->parent_cull_rect(), kGiantRect);
149 EXPECT_EQ(mock_layer2->parent_cull_rect(),
150 kGiantRect); // Siblings are independent
151
152 layer->Paint(display_list_paint_context());
153 DisplayListBuilder expected_builder;
154 /* (Container)layer::Paint */ {
155 /* mock_layer1::Paint */ {
156 expected_builder.DrawPath(child_path1, child_paint1);
157 }
158 /* mock_layer2::Paint */ {
159 expected_builder.DrawPath(child_path2, child_paint2);
160 }
161 }
162 EXPECT_TRUE(DisplayListsEQ_Verbose(display_list(), expected_builder.Build()));
163}
164
165TEST_F(ContainerLayerTest, MultipleWithEmpty) {
166 DlPath child_path1 = DlPath::MakeRectLTRB(5.0f, 6.0f, 20.5f, 21.5f);
167 DlPaint child_paint1 = DlPaint(DlColor::kMidGrey());
168 DlPaint child_paint2 = DlPaint(DlColor::kGreen());
169 DlMatrix initial_transform = DlMatrix::MakeTranslation({-0.5f, -0.5f});
170
171 auto mock_layer1 = std::make_shared<MockLayer>(child_path1, child_paint1);
172 auto mock_layer2 = std::make_shared<MockLayer>(DlPath(), child_paint2);
173 auto layer = std::make_shared<ContainerLayer>();
174 layer->Add(mock_layer1);
175 layer->Add(mock_layer2);
176
177 preroll_context()->state_stack.set_preroll_delegate(initial_transform);
178 layer->Preroll(preroll_context());
179 EXPECT_FALSE(preroll_context()->has_platform_view);
180 EXPECT_EQ(mock_layer1->paint_bounds(), child_path1.GetBounds());
181 EXPECT_EQ(mock_layer2->paint_bounds(), DlPath().GetBounds());
182 EXPECT_EQ(layer->paint_bounds(), child_path1.GetBounds());
183 EXPECT_EQ(layer->child_paint_bounds(), layer->paint_bounds());
184 EXPECT_TRUE(mock_layer1->needs_painting(paint_context()));
185 EXPECT_FALSE(mock_layer2->needs_painting(paint_context()));
186 EXPECT_TRUE(layer->needs_painting(paint_context()));
187 EXPECT_EQ(mock_layer1->parent_matrix(), initial_transform);
188 EXPECT_EQ(mock_layer2->parent_matrix(), initial_transform);
189 EXPECT_EQ(mock_layer1->parent_cull_rect(), kGiantRect);
190 EXPECT_EQ(mock_layer2->parent_cull_rect(), kGiantRect);
191
192 layer->Paint(display_list_paint_context());
193 DisplayListBuilder expected_builder;
194 /* (Container)layer::Paint */ {
195 /* mock_layer1::Paint */ {
196 expected_builder.DrawPath(child_path1, child_paint1);
197 }
198 // mock_layer2 not drawn due to needs_painting() returning false
199 }
200 EXPECT_TRUE(DisplayListsEQ_Verbose(display_list(), expected_builder.Build()));
201}
202
203TEST_F(ContainerLayerTest, NeedsSystemComposite) {
204 DlPath child_path1 = DlPath::MakeRectLTRB(5.0f, 6.0f, 20.5f, 21.5f);
205 DlPath child_path2 = DlPath::MakeRectLTRB(8.0f, 2.0f, 16.5f, 14.5f);
206 DlPaint child_paint1 = DlPaint(DlColor::kMidGrey());
207 DlPaint child_paint2 = DlPaint(DlColor::kGreen());
208 DlMatrix initial_transform = DlMatrix::MakeTranslation({-0.5f, -0.5f});
209
210 auto mock_layer1 = std::make_shared<MockLayer>(child_path1, child_paint1);
211 mock_layer1->set_fake_has_platform_view(false);
212 auto mock_layer2 = std::make_shared<MockLayer>(child_path2, child_paint2);
213 auto layer = std::make_shared<ContainerLayer>();
214 layer->Add(mock_layer1);
215 layer->Add(mock_layer2);
216
217 DlRect expected_total_bounds =
218 child_path1.GetBounds().Union(child_path2.GetBounds());
219 preroll_context()->state_stack.set_preroll_delegate(initial_transform);
220 layer->Preroll(preroll_context());
221 EXPECT_FALSE(preroll_context()->has_platform_view);
222 EXPECT_EQ(mock_layer1->paint_bounds(), child_path1.GetBounds());
223 EXPECT_EQ(mock_layer2->paint_bounds(), child_path2.GetBounds());
224 EXPECT_EQ(layer->paint_bounds(), expected_total_bounds);
225 EXPECT_EQ(layer->child_paint_bounds(), layer->paint_bounds());
226 EXPECT_TRUE(mock_layer1->needs_painting(paint_context()));
227 EXPECT_TRUE(mock_layer2->needs_painting(paint_context()));
228 EXPECT_TRUE(layer->needs_painting(paint_context()));
229 EXPECT_EQ(mock_layer1->parent_matrix(), initial_transform);
230 EXPECT_EQ(mock_layer2->parent_matrix(), initial_transform);
231 EXPECT_EQ(mock_layer1->parent_cull_rect(), kGiantRect);
232 EXPECT_EQ(mock_layer2->parent_cull_rect(), kGiantRect);
233
234 layer->Paint(display_list_paint_context());
235 DisplayListBuilder expected_builder;
236 /* (Container)layer::Paint */ {
237 /* mock_layer1::Paint */ {
238 expected_builder.DrawPath(child_path1, child_paint1);
239 }
240 /* mock_layer2::Paint */ {
241 expected_builder.DrawPath(child_path2, child_paint2);
242 }
243 }
244 EXPECT_TRUE(DisplayListsEQ_Verbose(display_list(), expected_builder.Build()));
245}
246
248 // LTRB
249 const DlPath child_path1 = DlPath::MakeRectLTRB(5.0f, 6.0f, 20.5f, 21.5f);
250 const DlPath child_path2 = DlPath::MakeRectLTRB(21.0f, 6.0f, 25.5f, 21.5f);
251 const DlPath child_path3 = DlPath::MakeRectLTRB(26.0f, 6.0f, 30.5f, 21.5f);
252 const DlPaint child_paint1 = DlPaint(DlColor::kMidGrey());
253 const DlPaint child_paint2 = DlPaint(DlColor::kGreen());
254 const DlPaint paint;
255 auto cacheable_container_layer1 =
257 auto cacheable_container_layer2 =
259 auto cacheable_container_layer11 =
261
262 auto cacheable_layer111 =
263 std::make_shared<MockCacheableLayer>(child_path3, paint);
264 // if the frame had rendered 2 frames, we will cache the cacheable_layer21
265 // layer
266 auto cacheable_layer21 =
267 std::make_shared<MockCacheableLayer>(child_path1, paint, 2);
268
269 // clang-format off
270// layer
271// |
272// ________________________________ ________________________________
273// | | |
274// cacheable_container_layer1 mock_layer2 cacheable_container_layer2
275// | |
276// cacheable_container_layer11 cacheable_layer21
277// |
278// cacheable_layer111
279 // clang-format on
280
281 auto mock_layer1 = std::make_shared<MockLayer>(child_path1, child_paint1);
282 auto mock_layer2 = std::make_shared<MockLayer>(DlPath(), child_paint2);
283 auto mock_layer3 = std::make_shared<MockLayer>(child_path2, paint);
284
285 cacheable_container_layer1->Add(mock_layer1);
286 cacheable_container_layer1->Add(mock_layer3);
287
288 cacheable_container_layer1->Add(cacheable_container_layer11);
289 cacheable_container_layer11->Add(cacheable_layer111);
290
291 cacheable_container_layer2->Add(cacheable_layer21);
292 auto layer = std::make_shared<ContainerLayer>();
293 layer->Add(cacheable_container_layer1);
294 layer->Add(mock_layer2);
295 layer->Add(cacheable_container_layer2);
296
297 DisplayListBuilder cache_canvas;
298 cache_canvas.TransformReset();
299
300 // Initial Preroll for check the layer paint bounds
301 layer->Preroll(preroll_context());
302
303 EXPECT_EQ(mock_layer1->paint_bounds(),
304 DlRect::MakeLTRB(5.f, 6.f, 20.5f, 21.5f));
305 EXPECT_EQ(mock_layer3->paint_bounds(),
306 DlRect::MakeLTRB(21.0f, 6.0f, 25.5f, 21.5f));
307 EXPECT_EQ(cacheable_layer111->paint_bounds(),
308 DlRect::MakeLTRB(26.0f, 6.0f, 30.5f, 21.5f));
309 EXPECT_EQ(cacheable_container_layer1->paint_bounds(),
310 DlRect::MakeLTRB(5.f, 6.f, 30.5f, 21.5f));
311
312 // the preroll context's raster cache is nullptr
313 EXPECT_EQ(preroll_context()->raster_cached_entries->size(),
314 static_cast<unsigned long>(0));
315 {
316 // frame1
317 use_mock_raster_cache();
318 preroll_context()->raster_cache->BeginFrame();
319 layer->Preroll(preroll_context());
320 preroll_context()->raster_cache->EvictUnusedCacheEntries();
321 // Cache the cacheable entries
322 LayerTree::TryToRasterCache(*(preroll_context()->raster_cached_entries),
323 &paint_context());
324
325 EXPECT_EQ(preroll_context()->raster_cached_entries->size(),
326 static_cast<unsigned long>(5));
327
328 // cacheable_container_layer1 will cache his children
329 EXPECT_EQ(cacheable_container_layer1->raster_cache_item()->cache_state(),
331 EXPECT_TRUE(raster_cache()->HasEntry(
332 cacheable_container_layer1->raster_cache_item()->GetId().value(),
333 SkMatrix::I()));
334
335 EXPECT_EQ(cacheable_container_layer11->raster_cache_item()->cache_state(),
337 EXPECT_TRUE(raster_cache()->HasEntry(
338 cacheable_container_layer11->raster_cache_item()->GetId().value(),
339 SkMatrix::I()));
340 EXPECT_FALSE(raster_cache()->Draw(
341 cacheable_container_layer11->raster_cache_item()->GetId().value(),
342 cache_canvas, &paint));
343
344 // The cacheable_layer111 should be cached when rended 3 frames
345 EXPECT_EQ(cacheable_layer111->raster_cache_item()->cache_state(),
347 // render count < 2 don't cache it
348 EXPECT_EQ(cacheable_container_layer2->raster_cache_item()->cache_state(),
350 preroll_context()->raster_cache->EndFrame();
351 }
352
353 {
354 // frame2
355 // new frame the layer tree will create new PrerollContext, so in here we
356 // clear the cached_entries
357 preroll_context()->raster_cached_entries->clear();
358 preroll_context()->raster_cache->BeginFrame();
359 layer->Preroll(preroll_context());
360 preroll_context()->raster_cache->EvictUnusedCacheEntries();
361
362 // Cache the cacheable entries
363 LayerTree::TryToRasterCache(*(preroll_context()->raster_cached_entries),
364 &paint_context());
365 EXPECT_EQ(preroll_context()->raster_cached_entries->size(),
366 static_cast<unsigned long>(5));
367 EXPECT_EQ(cacheable_container_layer1->raster_cache_item()->cache_state(),
369 EXPECT_TRUE(raster_cache()->HasEntry(
370 cacheable_container_layer1->raster_cache_item()->GetId().value(),
371 SkMatrix::I()));
372
373 EXPECT_EQ(cacheable_container_layer11->raster_cache_item()->cache_state(),
375 EXPECT_TRUE(raster_cache()->HasEntry(
376 cacheable_container_layer11->raster_cache_item()->GetId().value(),
377 SkMatrix::I()));
378 EXPECT_FALSE(raster_cache()->Draw(
379 cacheable_container_layer11->raster_cache_item()->GetId().value(),
380 cache_canvas, &paint));
381
382 EXPECT_EQ(cacheable_container_layer2->raster_cache_item()->cache_state(),
384
385 // render count == 2 cache it
386 EXPECT_EQ(cacheable_layer21->raster_cache_item()->cache_state(),
388 EXPECT_TRUE(raster_cache()->HasEntry(
389 cacheable_layer21->raster_cache_item()->GetId().value(),
390 SkMatrix::I()));
391 EXPECT_TRUE(raster_cache()->Draw(
392 cacheable_layer21->raster_cache_item()->GetId().value(), cache_canvas,
393 &paint));
394 preroll_context()->raster_cache->EndFrame();
395 }
396
397 {
398 // frame3
399 // new frame the layer tree will create new PrerollContext, so in here we
400 // clear the cached_entries
401 preroll_context()->raster_cache->BeginFrame();
402 preroll_context()->raster_cached_entries->clear();
403 layer->Preroll(preroll_context());
404 preroll_context()->raster_cache->EvictUnusedCacheEntries();
405 // Cache the cacheable entries
406 LayerTree::TryToRasterCache(*(preroll_context()->raster_cached_entries),
407 &paint_context());
408 EXPECT_EQ(preroll_context()->raster_cached_entries->size(),
409 static_cast<unsigned long>(5));
410 EXPECT_EQ(cacheable_container_layer1->raster_cache_item()->cache_state(),
412 EXPECT_TRUE(raster_cache()->HasEntry(
413 cacheable_container_layer1->raster_cache_item()->GetId().value(),
414 SkMatrix::I()));
415 EXPECT_TRUE(raster_cache()->HasEntry(
416 cacheable_container_layer11->raster_cache_item()->GetId().value(),
417 SkMatrix::I()));
418 EXPECT_FALSE(raster_cache()->Draw(
419 cacheable_container_layer11->raster_cache_item()->GetId().value(),
420 cache_canvas, &paint));
421 // The 3td frame, we will cache the cacheable_layer111, but his ancestor has
422 // been cached, so cacheable_layer111 Draw is false
423 EXPECT_TRUE(raster_cache()->HasEntry(
424 cacheable_layer111->raster_cache_item()->GetId().value(),
425 SkMatrix::I()));
426 EXPECT_FALSE(raster_cache()->Draw(
427 cacheable_layer111->raster_cache_item()->GetId().value(), cache_canvas,
428 &paint));
429
430 // The third frame, we will cache the cacheable_container_layer2
431 EXPECT_EQ(cacheable_container_layer2->raster_cache_item()->cache_state(),
433
434 EXPECT_TRUE(raster_cache()->HasEntry(
435 cacheable_layer21->raster_cache_item()->GetId().value(),
436 SkMatrix::I()));
437 preroll_context()->raster_cache->EndFrame();
438 }
439
440 {
441 preroll_context()->raster_cache->BeginFrame();
442 // frame4
443 preroll_context()->raster_cached_entries->clear();
444 layer->Preroll(preroll_context());
445 preroll_context()->raster_cache->EvictUnusedCacheEntries();
446 LayerTree::TryToRasterCache(*(preroll_context()->raster_cached_entries),
447 &paint_context());
448 preroll_context()->raster_cache->EndFrame();
449
450 // frame5
451 preroll_context()->raster_cache->BeginFrame();
452 preroll_context()->raster_cached_entries->clear();
453 layer->Preroll(preroll_context());
454 LayerTree::TryToRasterCache(*(preroll_context()->raster_cached_entries),
455 &paint_context());
456 preroll_context()->raster_cache->EndFrame();
457
458 // frame6
459 preroll_context()->raster_cache->BeginFrame();
460 preroll_context()->raster_cached_entries->clear();
461 layer->Preroll(preroll_context());
462 LayerTree::TryToRasterCache(*(preroll_context()->raster_cached_entries),
463 &paint_context());
464 preroll_context()->raster_cache->EndFrame();
465 }
466}
467
468TEST_F(ContainerLayerTest, OpacityInheritance) {
469 auto path1 = DlPath::MakeRectLTRB(10, 10, 30, 30);
470 auto mock1 = MockLayer::MakeOpacityCompatible(path1);
471 auto container1 = std::make_shared<ContainerLayer>();
472 container1->Add(mock1);
473
474 // ContainerLayer will pass through compatibility
475 PrerollContext* context = preroll_context();
476 container1->Preroll(context);
477 EXPECT_EQ(context->renderable_state_flags,
479
480 auto path2 = DlPath::MakeRectLTRB(40, 40, 50, 50);
481 auto mock2 = MockLayer::MakeOpacityCompatible(path2);
482 container1->Add(mock2);
483
484 // ContainerLayer will pass through compatibility from multiple
485 // non-overlapping compatible children
486 container1->Preroll(context);
487 EXPECT_EQ(context->renderable_state_flags,
489
490 auto path3 = DlPath::MakeRectLTRB(20, 20, 40, 40);
491 auto mock3 = MockLayer::MakeOpacityCompatible(path3);
492 container1->Add(mock3);
493
494 // ContainerLayer will not pass through compatibility from multiple
495 // overlapping children even if they are individually compatible
496 container1->Preroll(context);
497 EXPECT_EQ(context->renderable_state_flags, 0);
498
499 auto container2 = std::make_shared<ContainerLayer>();
500 container2->Add(mock1);
501 container2->Add(mock2);
502
503 // Double check first two children are compatible and non-overlapping
504 container2->Preroll(context);
505 EXPECT_EQ(context->renderable_state_flags,
507
508 auto path4 = DlPath::MakeRectLTRB(60, 60, 70, 70);
509 auto mock4 = MockLayer::Make(path4);
510 container2->Add(mock4);
511
512 // The third child is non-overlapping, but not compatible so the
513 // ContainerLayer should end up incompatible
514 container2->Preroll(context);
515 EXPECT_EQ(context->renderable_state_flags, 0);
516}
517
518TEST_F(ContainerLayerTest, CollectionCacheableLayer) {
519 DlPath child_path = DlPath::MakeRectLTRB(5.0f, 6.0f, 20.5f, 21.5f);
520 DlPaint child_paint = DlPaint(DlColor::kGreen());
521 DlMatrix initial_transform = DlMatrix::MakeTranslation({-0.5f, -0.5f});
522
523 auto mock_layer1 = std::make_shared<MockLayer>(DlPath(), child_paint);
524 auto mock_cacheable_container_layer1 =
525 std::make_shared<MockCacheableContainerLayer>();
526 auto mock_container_layer = std::make_shared<ContainerLayer>();
527 auto mock_cacheable_layer =
528 std::make_shared<MockCacheableLayer>(child_path, child_paint);
529 mock_cacheable_container_layer1->Add(mock_cacheable_layer);
530
531 // ContainerLayer
532 // |- MockLayer
533 // |- MockCacheableContainerLayer
534 // |- MockCacheableLayer
535 auto layer = std::make_shared<ContainerLayer>();
536 layer->Add(mock_cacheable_container_layer1);
537 layer->Add(mock_layer1);
538
539 preroll_context()->state_stack.set_preroll_delegate(initial_transform);
540 layer->Preroll(preroll_context());
541 // raster cache is null, so no entry
542 ASSERT_EQ(preroll_context()->raster_cached_entries->size(),
543 static_cast<const unsigned long>(0));
544
545 use_mock_raster_cache();
546 // preroll_context()->raster_cache = raster_cache();
547 layer->Preroll(preroll_context());
548 ASSERT_EQ(preroll_context()->raster_cached_entries->size(),
549 static_cast<const unsigned long>(2));
550}
551
553
554// Insert PictureLayer amongst container layers
555TEST_F(ContainerLayerDiffTest, PictureLayerInsertion) {
556 auto pic1 = CreateDisplayList(DlRect::MakeLTRB(0, 0, 50, 50));
557 auto pic2 = CreateDisplayList(DlRect::MakeLTRB(100, 0, 150, 50));
558 auto pic3 = CreateDisplayList(DlRect::MakeLTRB(200, 0, 250, 50));
559
560 MockLayerTree t1;
561
562 auto t1_c1 = CreateContainerLayer(CreateDisplayListLayer(pic1));
563 t1.root()->Add(t1_c1);
564
565 auto t1_c2 = CreateContainerLayer(CreateDisplayListLayer(pic2));
566 t1.root()->Add(t1_c2);
567
568 auto damage = DiffLayerTree(t1, MockLayerTree());
569 EXPECT_EQ(damage.frame_damage, DlIRect::MakeLTRB(0, 0, 150, 50));
570
571 // Add in the middle
572
573 MockLayerTree t2;
574 auto t2_c1 = CreateContainerLayer(CreateDisplayListLayer(pic1));
575 t2_c1->AssignOldLayer(t1_c1.get());
576 t2.root()->Add(t2_c1);
577
578 t2.root()->Add(CreateDisplayListLayer(pic3));
579
580 auto t2_c2 = CreateContainerLayer(CreateDisplayListLayer(pic2));
581 t2_c2->AssignOldLayer(t1_c2.get());
582 t2.root()->Add(t2_c2);
583
584 damage = DiffLayerTree(t2, t1);
585 EXPECT_EQ(damage.frame_damage, DlIRect::MakeLTRB(200, 0, 250, 50));
586
587 // Add in the beginning
588
589 t2 = MockLayerTree();
590 t2.root()->Add(CreateDisplayListLayer(pic3));
591 t2.root()->Add(t2_c1);
592 t2.root()->Add(t2_c2);
593 damage = DiffLayerTree(t2, t1);
594 EXPECT_EQ(damage.frame_damage, DlIRect::MakeLTRB(200, 0, 250, 50));
595
596 // Add at the end
597
598 t2 = MockLayerTree();
599 t2.root()->Add(t2_c1);
600 t2.root()->Add(t2_c2);
601 t2.root()->Add(CreateDisplayListLayer(pic3));
602 damage = DiffLayerTree(t2, t1);
603 EXPECT_EQ(damage.frame_damage, DlIRect::MakeLTRB(200, 0, 250, 50));
604}
605
606// Insert picture layer amongst other picture layers
607TEST_F(ContainerLayerDiffTest, PictureInsertion) {
608 auto pic1 = CreateDisplayList(DlRect::MakeLTRB(0, 0, 50, 50));
609 auto pic2 = CreateDisplayList(DlRect::MakeLTRB(100, 0, 150, 50));
610 auto pic3 = CreateDisplayList(DlRect::MakeLTRB(200, 0, 250, 50));
611
612 MockLayerTree t1;
613 t1.root()->Add(CreateDisplayListLayer(pic1));
614 t1.root()->Add(CreateDisplayListLayer(pic2));
615
616 auto damage = DiffLayerTree(t1, MockLayerTree());
617 EXPECT_EQ(damage.frame_damage, DlIRect::MakeLTRB(0, 0, 150, 50));
618
619 MockLayerTree t2;
620 t2.root()->Add(CreateDisplayListLayer(pic3));
621 t2.root()->Add(CreateDisplayListLayer(pic1));
622 t2.root()->Add(CreateDisplayListLayer(pic2));
623
624 damage = DiffLayerTree(t2, t1);
625 EXPECT_EQ(damage.frame_damage, DlIRect::MakeLTRB(200, 0, 250, 50));
626
627 MockLayerTree t3;
628 t3.root()->Add(CreateDisplayListLayer(pic1));
629 t3.root()->Add(CreateDisplayListLayer(pic3));
630 t3.root()->Add(CreateDisplayListLayer(pic2));
631
632 damage = DiffLayerTree(t3, t1);
633 EXPECT_EQ(damage.frame_damage, DlIRect::MakeLTRB(200, 0, 250, 50));
634
635 MockLayerTree t4;
636 t4.root()->Add(CreateDisplayListLayer(pic1));
637 t4.root()->Add(CreateDisplayListLayer(pic2));
638 t4.root()->Add(CreateDisplayListLayer(pic3));
639
640 damage = DiffLayerTree(t4, t1);
641 EXPECT_EQ(damage.frame_damage, DlIRect::MakeLTRB(200, 0, 250, 50));
642}
643
645 auto path1 = DlPath::MakeRectLTRB(0, 0, 50, 50);
646 auto path2 = DlPath::MakeRectLTRB(100, 0, 150, 50);
647 auto path3 = DlPath::MakeRectLTRB(200, 0, 250, 50);
648
649 auto c1 = CreateContainerLayer(std::make_shared<MockLayer>(path1));
650 auto c2 = CreateContainerLayer(std::make_shared<MockLayer>(path2));
651 auto c3 = CreateContainerLayer(std::make_shared<MockLayer>(path3));
652
653 MockLayerTree t1;
654 t1.root()->Add(c1);
655 t1.root()->Add(c2);
656 t1.root()->Add(c3);
657
658 auto damage = DiffLayerTree(t1, MockLayerTree());
659 EXPECT_EQ(damage.frame_damage, DlIRect::MakeLTRB(0, 0, 250, 50));
660
661 MockLayerTree t2;
662 t2.root()->Add(c2);
663 t2.root()->Add(c3);
664
665 damage = DiffLayerTree(t2, t1);
666 EXPECT_EQ(damage.frame_damage, DlIRect::MakeLTRB(0, 0, 50, 50));
667
668 MockLayerTree t3;
669 t3.root()->Add(c1);
670 t3.root()->Add(c3);
671
672 damage = DiffLayerTree(t3, t1);
673 EXPECT_EQ(damage.frame_damage, DlIRect::MakeLTRB(100, 0, 150, 50));
674
675 MockLayerTree t4;
676 t4.root()->Add(c1);
677 t4.root()->Add(c2);
678
679 damage = DiffLayerTree(t4, t1);
680 EXPECT_EQ(damage.frame_damage, DlIRect::MakeLTRB(200, 0, 250, 50));
681
682 MockLayerTree t5;
683 t5.root()->Add(c1);
684
685 damage = DiffLayerTree(t5, t1);
686 EXPECT_EQ(damage.frame_damage, DlIRect::MakeLTRB(100, 0, 250, 50));
687
688 MockLayerTree t6;
689 t6.root()->Add(c2);
690
691 damage = DiffLayerTree(t6, t1);
692 EXPECT_EQ(damage.frame_damage, DlIRect::MakeLTRB(0, 0, 250, 50));
693
694 MockLayerTree t7;
695 t7.root()->Add(c3);
696
697 damage = DiffLayerTree(t7, t1);
698 EXPECT_EQ(damage.frame_damage, DlIRect::MakeLTRB(0, 0, 150, 50));
699}
700
702 auto path1 = DlPath::MakeRectLTRB(0, 0, 50, 50);
703 auto path2 = DlPath::MakeRectLTRB(100, 0, 150, 50);
704 auto path3 = DlPath::MakeRectLTRB(200, 0, 250, 50);
705
706 auto path1a = DlPath::MakeRectLTRB(0, 100, 50, 150);
707 auto path2a = DlPath::MakeRectLTRB(100, 100, 150, 150);
708 auto path3a = DlPath::MakeRectLTRB(200, 100, 250, 150);
709
710 auto c1 = CreateContainerLayer(std::make_shared<MockLayer>(path1));
711 auto c2 = CreateContainerLayer(std::make_shared<MockLayer>(path2));
712 auto c3 = CreateContainerLayer(std::make_shared<MockLayer>(path3));
713
714 MockLayerTree t1;
715 t1.root()->Add(c1);
716 t1.root()->Add(c2);
717 t1.root()->Add(c3);
718
719 auto damage = DiffLayerTree(t1, MockLayerTree());
720 EXPECT_EQ(damage.frame_damage, DlIRect::MakeLTRB(0, 0, 250, 50));
721
722 MockLayerTree t2;
723 t2.root()->Add(c1);
724 t2.root()->Add(c2);
725 t2.root()->Add(c3);
726
727 damage = DiffLayerTree(t2, t1);
728 EXPECT_TRUE(damage.frame_damage.IsEmpty());
729
730 MockLayerTree t3;
731 t3.root()->Add(CreateContainerLayer({std::make_shared<MockLayer>(path1a)}));
732 t3.root()->Add(c2);
733 t3.root()->Add(c3);
734
735 damage = DiffLayerTree(t3, t1);
736 EXPECT_EQ(damage.frame_damage, DlIRect::MakeLTRB(0, 0, 50, 150));
737
738 MockLayerTree t4;
739 t4.root()->Add(c1);
740 t4.root()->Add(CreateContainerLayer(std::make_shared<MockLayer>(path2a)));
741 t4.root()->Add(c3);
742
743 damage = DiffLayerTree(t4, t1);
744 EXPECT_EQ(damage.frame_damage, DlIRect::MakeLTRB(100, 0, 150, 150));
745
746 MockLayerTree t5;
747 t5.root()->Add(c1);
748 t5.root()->Add(c2);
749 t5.root()->Add(CreateContainerLayer(std::make_shared<MockLayer>(path3a)));
750
751 damage = DiffLayerTree(t5, t1);
752 EXPECT_EQ(damage.frame_damage, DlIRect::MakeLTRB(200, 0, 250, 150));
753}
754
755} // namespace testing
756} // namespace flutter
757
758// NOLINTEND(bugprone-unchecked-optional-access)
virtual void Add(std::shared_ptr< Layer > layer)
void TransformReset() override
sk_sp< DisplayList > Build()
Definition dl_builder.cc:66
void DrawPath(const DlPath &path, const DlPaint &paint) override
static DlPath MakeRectLTRB(DlScalar left, DlScalar top, DlScalar right, DlScalar bottom)
Definition dl_path.cc:43
DlRect GetBounds() const override
Definition dl_path.cc:245
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< MockCacheableContainerLayer > CacheLayerOnly()
Definition mock_layer.h:140
static std::shared_ptr< MockCacheableContainerLayer > CacheLayerOrChildren()
Definition mock_layer.h:134
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
TEST_F(DisplayListTest, Defaults)
LayerTestBase<::testing::Test > LayerTest
Definition layer_test.h:177
bool DisplayListsEQ_Verbose(const DisplayList *a, const DisplayList *b)
impeller::Rect DlRect
static constexpr DlRect kGiantRect
Definition layer.h:40
static constexpr DlColor kMidGrey()
Definition dl_color.h:78
static constexpr DlColor kGreen()
Definition dl_color.h:72
A 4x4 matrix using column-major storage.
Definition matrix.h:37
static constexpr Matrix MakeTranslation(const Vector3 &t)
Definition matrix.h:95
constexpr TRect Union(const TRect &o) const
Definition rect.h:513
static constexpr TRect MakeLTRB(Type left, Type top, Type right, Type bottom)
Definition rect.h:129