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