Flutter Engine
 
Loading...
Searching...
No Matches
transform_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
10#include "flutter/fml/macros.h"
11
12namespace flutter {
13namespace testing {
14
16
17#ifndef NDEBUG
18TEST_F(TransformLayerTest, PaintingEmptyLayerDies) {
19 auto layer = std::make_shared<TransformLayer>(DlMatrix()); // identity
20
21 layer->Preroll(preroll_context());
22 EXPECT_EQ(layer->paint_bounds(), DlRect());
23 EXPECT_EQ(layer->child_paint_bounds(), DlRect());
24 EXPECT_FALSE(layer->needs_painting(paint_context()));
25
26 EXPECT_DEATH_IF_SUPPORTED(layer->Paint(paint_context()),
27 "needs_painting\\(context\\)");
28}
29
30TEST_F(TransformLayerTest, PaintBeforePrerollDies) {
31 const DlPath child_path = DlPath::MakeRectLTRB(5.0f, 6.0f, 20.5f, 21.5f);
32 auto mock_layer = std::make_shared<MockLayer>(child_path, DlPaint());
33 auto layer = std::make_shared<TransformLayer>(DlMatrix()); // identity
34 layer->Add(mock_layer);
35
36 EXPECT_DEATH_IF_SUPPORTED(layer->Paint(paint_context()),
37 "needs_painting\\(context\\)");
38}
39#endif
40
42 const DlPath child_path = DlPath::MakeRectLTRB(5.0f, 6.0f, 20.5f, 21.5f);
43 DlRect cull_rect = DlRect::MakeXYWH(2.0f, 2.0f, 14.0f, 14.0f);
44 auto mock_layer = std::make_shared<MockLayer>(child_path, DlPaint());
45 auto layer = std::make_shared<TransformLayer>(DlMatrix()); // identity
46 layer->Add(mock_layer);
47
48 preroll_context()->state_stack.set_preroll_delegate(cull_rect);
49 layer->Preroll(preroll_context());
50 EXPECT_EQ(mock_layer->paint_bounds(), child_path.GetBounds());
51 EXPECT_EQ(layer->paint_bounds(), mock_layer->paint_bounds());
52 EXPECT_EQ(layer->child_paint_bounds(), mock_layer->paint_bounds());
53 EXPECT_TRUE(mock_layer->needs_painting(paint_context()));
54 EXPECT_TRUE(layer->needs_painting(paint_context()));
55 EXPECT_EQ(mock_layer->parent_matrix(), DlMatrix()); // identity
56 EXPECT_EQ(mock_layer->parent_cull_rect(), cull_rect);
57 EXPECT_EQ(mock_layer->parent_mutators().stack_count(), 0u);
58 EXPECT_EQ(mock_layer->parent_mutators(), MutatorsStack());
59
60 layer->Paint(display_list_paint_context());
61 DisplayListBuilder expected_builder;
62 /* (Transform)layer::Paint */ {
63 expected_builder.Save();
64 {
65 expected_builder.Transform(DlMatrix());
66 /* mock_layer::Paint */ {
67 expected_builder.DrawPath(child_path, DlPaint());
68 }
69 }
70 expected_builder.Restore();
71 }
72 EXPECT_TRUE(DisplayListsEQ_Verbose(display_list(), expected_builder.Build()));
73}
74
76 const DlPath child_path = DlPath::MakeRectLTRB(5.0f, 6.0f, 20.5f, 21.5f);
77 DlMatrix initial_transform = DlMatrix::MakeTranslation({-0.5f, -0.5f});
78 DlRect local_cull_rect = DlRect::MakeXYWH(2.0f, 2.0f, 14.0f, 14.0f);
79 DlRect device_cull_rect =
80 local_cull_rect.TransformAndClipBounds(initial_transform);
81 DlMatrix layer_transform = DlMatrix::MakeTranslation({2.5f, 2.5f});
82 EXPECT_TRUE(layer_transform.IsInvertible());
83 DlMatrix inverse_layer_transform = layer_transform.Invert();
84
85 auto mock_layer = std::make_shared<MockLayer>(child_path, DlPaint());
86 auto layer = std::make_shared<TransformLayer>(layer_transform);
87 layer->Add(mock_layer);
88
89 preroll_context()->state_stack.set_preroll_delegate(device_cull_rect,
90 initial_transform);
91 layer->Preroll(preroll_context());
92 EXPECT_EQ(mock_layer->paint_bounds(), child_path.GetBounds());
93 EXPECT_EQ(layer->paint_bounds(),
94 mock_layer->paint_bounds().TransformAndClipBounds(layer_transform));
95 EXPECT_EQ(layer->child_paint_bounds(), mock_layer->paint_bounds());
96 EXPECT_TRUE(mock_layer->needs_painting(paint_context()));
97 EXPECT_TRUE(layer->needs_painting(paint_context()));
98 EXPECT_EQ(mock_layer->parent_matrix(), initial_transform * layer_transform);
99 EXPECT_EQ(mock_layer->parent_cull_rect(),
100 local_cull_rect.TransformAndClipBounds(inverse_layer_transform));
101 EXPECT_EQ(mock_layer->parent_mutators(),
102 std::vector({Mutator(layer_transform)}));
103
104 layer->Paint(display_list_paint_context());
105 DisplayListBuilder expected_builder;
106 /* (Transform)layer::Paint */ {
107 expected_builder.Save();
108 {
109 expected_builder.Transform(layer_transform);
110 /* mock_layer::Paint */ {
111 expected_builder.DrawPath(child_path, DlPaint());
112 }
113 }
114 expected_builder.Restore();
115 }
116 EXPECT_TRUE(DisplayListsEQ_Verbose(display_list(), expected_builder.Build()));
117}
118
119TEST_F(TransformLayerTest, ComplexMatrix) {
120 const DlPath child_path = DlPath::MakeRectLTRB(5.0f, 6.0f, 20.5f, 21.5f);
121 DlMatrix initial_transform = DlMatrix::MakeTranslation({-2.0f, -2.0f});
122 DlRect local_cull_rect = DlRect::MakeXYWH(4.0f, 4.0f, 16.0f, 16.0f);
123 DlRect device_cull_rect =
124 local_cull_rect.TransformAndClipBounds(initial_transform);
125 DlMatrix layer_transform = (DlMatrix::MakeTranslation({1.0f, 1.0f}) *
128
129 EXPECT_TRUE(layer_transform.IsInvertible());
130 DlMatrix inverse_layer_transform = layer_transform.Invert();
131
132 auto mock_layer = std::make_shared<MockLayer>(child_path, DlPaint());
133 auto layer = std::make_shared<TransformLayer>(layer_transform);
134 layer->Add(mock_layer);
135
136 preroll_context()->state_stack.set_preroll_delegate(device_cull_rect,
137 initial_transform);
138 layer->Preroll(preroll_context());
139 EXPECT_EQ(mock_layer->paint_bounds(), child_path.GetBounds());
140 EXPECT_EQ(layer->paint_bounds(),
141 mock_layer->paint_bounds().TransformAndClipBounds(layer_transform));
142 EXPECT_EQ(layer->child_paint_bounds(), mock_layer->paint_bounds());
143 EXPECT_TRUE(mock_layer->needs_painting(paint_context()));
144 EXPECT_TRUE(layer->needs_painting(paint_context()));
145 EXPECT_EQ(mock_layer->parent_matrix(), initial_transform * layer_transform);
146
147 // Even having switched to binary-ieee friendly numbers for the
148 // initial conditions, these numbers which are based on a matrix
149 // concatenation and inversion still aren't exact, so we are using
150 // fuzzy float comparisons to check them.
151 DlRect parent_cull_rect = mock_layer->parent_cull_rect();
152 DlRect expect_parent_cull_rect =
153 local_cull_rect.TransformAndClipBounds(inverse_layer_transform);
154 EXPECT_FLOAT_EQ(parent_cull_rect.GetLeft(),
155 expect_parent_cull_rect.GetLeft());
156 EXPECT_FLOAT_EQ(parent_cull_rect.GetTop(), //
157 expect_parent_cull_rect.GetTop());
158 EXPECT_FLOAT_EQ(parent_cull_rect.GetRight(),
159 expect_parent_cull_rect.GetRight());
160 EXPECT_FLOAT_EQ(parent_cull_rect.GetBottom(),
161 expect_parent_cull_rect.GetBottom());
162
163 EXPECT_EQ(mock_layer->parent_mutators(),
164 std::vector({Mutator(layer_transform)}));
165
166 layer->Paint(display_list_paint_context());
167 DisplayListBuilder expected_builder;
168 /* (Transform)layer::Paint */ {
169 expected_builder.Save();
170 {
171 expected_builder.Transform(layer_transform);
172 /* mock_layer::Paint */ {
173 expected_builder.DrawPath(child_path, DlPaint());
174 }
175 }
176 expected_builder.Restore();
177 }
178 EXPECT_TRUE(DisplayListsEQ_Verbose(display_list(), expected_builder.Build()));
179}
180
181TEST_F(TransformLayerTest, Nested) {
182 DlPath child_path = DlPath::MakeRectLTRB(5.0f, 6.0f, 20.5f, 21.5f);
183 DlMatrix initial_transform = DlMatrix::MakeTranslation({-0.5f, -0.5f});
184 DlRect local_cull_rect = DlRect::MakeXYWH(2.0f, 2.0f, 14.0f, 14.0f);
185 DlRect device_cull_rect =
186 local_cull_rect.TransformAndClipBounds(initial_transform);
187 DlMatrix layer1_transform = DlMatrix::MakeTranslation({2.5f, 2.5f});
188 DlMatrix layer2_transform = DlMatrix::MakeTranslation({3.5f, 3.5f});
189 EXPECT_TRUE(layer1_transform.IsInvertible());
190 EXPECT_TRUE(layer2_transform.IsInvertible());
191 DlMatrix inverse_layer1_transform = layer1_transform.Invert();
192 DlMatrix inverse_layer2_transform = layer2_transform.Invert();
193
194 auto mock_layer = std::make_shared<MockLayer>(child_path, DlPaint());
195 auto layer1 = std::make_shared<TransformLayer>(layer1_transform);
196 auto layer2 = std::make_shared<TransformLayer>(layer2_transform);
197 layer1->Add(layer2);
198 layer2->Add(mock_layer);
199
200 preroll_context()->state_stack.set_preroll_delegate(device_cull_rect,
201 initial_transform);
202 layer1->Preroll(preroll_context());
203 EXPECT_EQ(mock_layer->paint_bounds(), child_path.GetBounds());
204 EXPECT_EQ(
205 layer2->paint_bounds(),
206 mock_layer->paint_bounds().TransformAndClipBounds(layer2_transform));
207 EXPECT_EQ(layer2->child_paint_bounds(), mock_layer->paint_bounds());
208 EXPECT_EQ(layer1->paint_bounds(),
209 layer2->paint_bounds().TransformAndClipBounds(layer1_transform));
210 EXPECT_EQ(layer1->child_paint_bounds(), layer2->paint_bounds());
211 EXPECT_TRUE(mock_layer->needs_painting(paint_context()));
212 EXPECT_TRUE(layer2->needs_painting(paint_context()));
213 EXPECT_TRUE(layer1->needs_painting(paint_context()));
214 EXPECT_EQ(mock_layer->parent_matrix(),
215 (initial_transform * layer1_transform) * layer2_transform);
216 EXPECT_EQ(mock_layer->parent_cull_rect(),
217 local_cull_rect.TransformAndClipBounds(inverse_layer1_transform)
218 .TransformAndClipBounds(inverse_layer2_transform));
219 EXPECT_EQ(
220 mock_layer->parent_mutators(),
221 std::vector({Mutator(layer1_transform), Mutator(layer2_transform)}));
222
223 layer1->Paint(display_list_paint_context());
224 DisplayListBuilder expected_builder;
225 /* (Transform)layer1::Paint */ {
226 expected_builder.Save();
227 {
228 expected_builder.Transform(layer1_transform);
229 /* (Transform)layer1::Paint */ {
230 expected_builder.Save();
231 {
232 expected_builder.Transform(layer2_transform);
233 /* mock_layer::Paint */ {
234 expected_builder.DrawPath(child_path, DlPaint());
235 }
236 }
237 expected_builder.Restore();
238 }
239 }
240 expected_builder.Restore();
241 }
242 EXPECT_TRUE(DisplayListsEQ_Verbose(display_list(), expected_builder.Build()));
243}
244
245TEST_F(TransformLayerTest, NestedSeparated) {
246 DlPath child_path = DlPath::MakeRectLTRB(5.0f, 6.0f, 20.5f, 21.5f);
247 DlMatrix initial_transform = DlMatrix::MakeTranslation({-0.5f, -0.5f});
248 DlRect local_cull_rect = DlRect::MakeXYWH(2.0f, 2.0f, 14.0f, 14.0f);
249 DlRect device_cull_rect =
250 local_cull_rect.TransformAndClipBounds(initial_transform);
251 DlMatrix layer1_transform = DlMatrix::MakeTranslation({2.5f, 2.5f});
252 DlMatrix layer2_transform = DlMatrix::MakeTranslation({3.5f, 3.5f});
253 EXPECT_TRUE(layer1_transform.IsInvertible());
254 EXPECT_TRUE(layer2_transform.IsInvertible());
255 DlMatrix inverse_layer1_transform = layer1_transform.Invert();
256 DlMatrix inverse_layer2_transform = layer2_transform.Invert();
257 DlPaint child_paint1(DlColor::kBlue());
258 DlPaint child_paint2(DlColor::kGreen());
259
260 auto mock_layer1 = std::make_shared<MockLayer>(child_path, child_paint1);
261 auto mock_layer2 = std::make_shared<MockLayer>(child_path, child_paint2);
262 auto layer1 = std::make_shared<TransformLayer>(layer1_transform);
263 auto layer2 = std::make_shared<TransformLayer>(layer2_transform);
264 layer1->Add(mock_layer1);
265 layer1->Add(layer2);
266 layer2->Add(mock_layer2);
267
268 preroll_context()->state_stack.set_preroll_delegate(device_cull_rect,
269 initial_transform);
270 layer1->Preroll(preroll_context());
271 DlRect layer1_child_bounds =
272 layer2->paint_bounds().Union(mock_layer1->paint_bounds());
273 DlRect expected_layer1_bounds =
274 layer1_child_bounds.TransformAndClipBounds(layer1_transform);
275
276 EXPECT_EQ(mock_layer2->paint_bounds(), child_path.GetBounds());
277 EXPECT_EQ(
278 layer2->paint_bounds(),
279 mock_layer2->paint_bounds().TransformAndClipBounds(layer2_transform));
280 EXPECT_EQ(layer2->child_paint_bounds(), mock_layer2->paint_bounds());
281 EXPECT_EQ(mock_layer1->paint_bounds(), child_path.GetBounds());
282 EXPECT_EQ(layer1->paint_bounds(), expected_layer1_bounds);
283 EXPECT_EQ(layer1->child_paint_bounds(), layer1_child_bounds);
284 EXPECT_TRUE(mock_layer2->needs_painting(paint_context()));
285 EXPECT_TRUE(layer2->needs_painting(paint_context()));
286 EXPECT_TRUE(mock_layer1->needs_painting(paint_context()));
287 EXPECT_TRUE(layer1->needs_painting(paint_context()));
288 EXPECT_EQ(mock_layer1->parent_matrix(), initial_transform * layer1_transform);
289 EXPECT_EQ(mock_layer2->parent_matrix(),
290 (initial_transform * layer1_transform) * layer2_transform);
291 EXPECT_EQ(mock_layer1->parent_cull_rect(),
292 local_cull_rect.TransformAndClipBounds(inverse_layer1_transform));
293 EXPECT_EQ(mock_layer2->parent_cull_rect(),
294 local_cull_rect.TransformAndClipBounds(inverse_layer1_transform)
295 .TransformAndClipBounds(inverse_layer2_transform));
296 EXPECT_EQ(mock_layer1->parent_mutators(),
297 std::vector({Mutator(layer1_transform)}));
298 EXPECT_EQ(
299 mock_layer2->parent_mutators(),
300 std::vector({Mutator(layer1_transform), Mutator(layer2_transform)}));
301
302 layer1->Paint(display_list_paint_context());
303 DisplayListBuilder expected_builder;
304 /* (Transform)layer1::Paint */ {
305 expected_builder.Save();
306 {
307 expected_builder.Transform(layer1_transform);
308 /* mock_layer::Paint */ {
309 expected_builder.DrawPath(child_path, child_paint1);
310 }
311 /* (Transform)layer1::Paint */ {
312 expected_builder.Save();
313 {
314 expected_builder.Transform(layer2_transform);
315 /* mock_layer::Paint */ {
316 expected_builder.DrawPath(child_path, child_paint2);
317 }
318 }
319 expected_builder.Restore();
320 }
321 }
322 expected_builder.Restore();
323 }
324 EXPECT_TRUE(DisplayListsEQ_Verbose(display_list(), expected_builder.Build()));
325}
326
327TEST_F(TransformLayerTest, OpacityInheritance) {
328 auto path1 = DlPath::MakeRectLTRB(10, 10, 30, 30);
329 auto mock1 = MockLayer::MakeOpacityCompatible(path1);
330 auto transform1 =
331 std::make_shared<TransformLayer>(DlMatrix::MakeScale({2.0f, 2.0f, 1.0f}));
332 transform1->Add(mock1);
333
334 // TransformLayer will pass through compatibility from a compatible child
335 PrerollContext* context = preroll_context();
336 transform1->Preroll(context);
337 EXPECT_EQ(context->renderable_state_flags,
339
340 auto path2 = DlPath::MakeRectLTRB(40, 40, 50, 50);
341 auto mock2 = MockLayer::MakeOpacityCompatible(path2);
342 transform1->Add(mock2);
343
344 // TransformLayer will pass through compatibility from multiple
345 // non-overlapping compatible children
346 transform1->Preroll(context);
347 EXPECT_EQ(context->renderable_state_flags,
349
350 auto path3 = DlPath::MakeRectLTRB(20, 20, 40, 40);
351 auto mock3 = MockLayer::MakeOpacityCompatible(path3);
352 transform1->Add(mock3);
353
354 // TransformLayer will not pass through compatibility from multiple
355 // overlapping children even if they are individually compatible
356 transform1->Preroll(context);
357 EXPECT_EQ(context->renderable_state_flags, 0);
358
359 auto transform2 =
360 std::make_shared<TransformLayer>(DlMatrix::MakeScale({2.0f, 2.0f, 1.0f}));
361 transform2->Add(mock1);
362 transform2->Add(mock2);
363
364 // Double check first two children are compatible and non-overlapping
365 transform2->Preroll(context);
366 EXPECT_EQ(context->renderable_state_flags,
368
369 auto path4 = DlPath::MakeRectLTRB(60, 60, 70, 70);
370 auto mock4 = MockLayer::Make(path4);
371 transform2->Add(mock4);
372
373 // The third child is non-overlapping, but not compatible so the
374 // TransformLayer should end up incompatible
375 transform2->Preroll(context);
376 EXPECT_EQ(context->renderable_state_flags, 0);
377}
378
379TEST_F(TransformLayerTest, OpacityInheritancePainting) {
380 auto path1 = DlPath::MakeRectLTRB(10, 10, 30, 30);
381 auto mock1 = MockLayer::MakeOpacityCompatible(path1);
382 auto path2 = DlPath::MakeRectLTRB(40, 40, 50, 50);
383 auto mock2 = MockLayer::MakeOpacityCompatible(path2);
384 auto transform = DlMatrix::MakeScale({2.0f, 2.0f, 1.0f});
385 auto transform_layer = std::make_shared<TransformLayer>(transform);
386 transform_layer->Add(mock1);
387 transform_layer->Add(mock2);
388
389 // TransformLayer will pass through compatibility from multiple
390 // non-overlapping compatible children
391 PrerollContext* context = preroll_context();
392 transform_layer->Preroll(context);
393 EXPECT_EQ(context->renderable_state_flags,
395
396 uint8_t opacity_alpha = 0x7F;
397 DlPoint offset = DlPoint(10, 10);
398 auto opacity_layer = std::make_shared<OpacityLayer>(opacity_alpha, offset);
399 opacity_layer->Add(transform_layer);
400 opacity_layer->Preroll(context);
401 EXPECT_TRUE(opacity_layer->children_can_accept_opacity());
402
403 DisplayListBuilder expected_builder;
404 /* opacity_layer paint */ {
405 expected_builder.Save();
406 {
407 expected_builder.Translate(offset.x, offset.y);
408 /* transform_layer paint */ {
409 expected_builder.Save();
410 expected_builder.Transform(transform);
411 /* child layer1 paint */ {
412 expected_builder.DrawPath(path1, DlPaint().setAlpha(opacity_alpha));
413 }
414 /* child layer2 paint */ {
415 expected_builder.DrawPath(path2, DlPaint().setAlpha(opacity_alpha));
416 }
417 expected_builder.Restore();
418 }
419 }
420 expected_builder.Restore();
421 }
422
423 opacity_layer->Paint(display_list_paint_context());
424 EXPECT_TRUE(DisplayListsEQ_Verbose(display_list(), expected_builder.Build()));
425}
426
428
430 auto path1 = DlPath::MakeRectLTRB(0, 0, 50, 50);
431 auto m1 = std::make_shared<MockLayer>(path1);
432
433 auto transform1 =
434 std::make_shared<TransformLayer>(DlMatrix::MakeTranslation({10, 10}));
435 transform1->Add(m1);
436
437 MockLayerTree t1;
438 t1.root()->Add(transform1);
439
440 auto damage = DiffLayerTree(t1, MockLayerTree());
441 EXPECT_EQ(damage.frame_damage, DlIRect::MakeLTRB(10, 10, 60, 60));
442
443 auto transform2 =
444 std::make_shared<TransformLayer>(DlMatrix::MakeTranslation({20, 20}));
445 transform2->Add(m1);
446 transform2->AssignOldLayer(transform1.get());
447
448 MockLayerTree t2;
449 t2.root()->Add(transform2);
450
451 damage = DiffLayerTree(t2, t1);
452 EXPECT_EQ(damage.frame_damage, DlIRect::MakeLTRB(10, 10, 70, 70));
453
454 auto transform3 =
455 std::make_shared<TransformLayer>(DlMatrix::MakeTranslation({20, 20}));
456 transform3->Add(m1);
457 transform3->AssignOldLayer(transform2.get());
458
459 MockLayerTree t3;
460 t3.root()->Add(transform3);
461
462 damage = DiffLayerTree(t3, t2);
463 EXPECT_EQ(damage.frame_damage, DlIRect());
464}
465
467 auto path1 = DlPath::MakeRectLTRB(0, 0, 50, 50);
468 auto m1 = CreateContainerLayer(std::make_shared<MockLayer>(path1));
469 auto m2 = CreateContainerLayer(std::make_shared<MockLayer>(path1));
470 auto m3 = CreateContainerLayer(std::make_shared<MockLayer>(path1));
471
472 auto transform1 =
473 std::make_shared<TransformLayer>(DlMatrix::MakeScale({2.0f, 2.0f, 1.0f}));
474
475 auto transform1_1 =
476 std::make_shared<TransformLayer>(DlMatrix::MakeTranslation({10, 10}));
477 transform1_1->Add(m1);
478 transform1->Add(transform1_1);
479
480 auto transform1_2 =
481 std::make_shared<TransformLayer>(DlMatrix::MakeTranslation({100, 100}));
482 transform1_2->Add(m2);
483 transform1->Add(transform1_2);
484
485 auto transform1_3 =
486 std::make_shared<TransformLayer>(DlMatrix::MakeTranslation({200, 200}));
487 transform1_3->Add(m3);
488 transform1->Add(transform1_3);
489
490 MockLayerTree l1;
491 l1.root()->Add(transform1);
492
493 auto damage = DiffLayerTree(l1, MockLayerTree());
494 EXPECT_EQ(damage.frame_damage, DlIRect::MakeLTRB(20, 20, 500, 500));
495
496 auto transform2 =
497 std::make_shared<TransformLayer>(DlMatrix::MakeScale({2.0f, 2.0f, 1.0f}));
498
499 auto transform2_1 =
500 std::make_shared<TransformLayer>(DlMatrix::MakeTranslation({10, 10}));
501 transform2_1->Add(m1);
502 transform2_1->AssignOldLayer(transform1_1.get());
503 transform2->Add(transform2_1);
504
505 // Offset 1px from transform1_2 so that they're not the same
506 auto transform2_2 =
507 std::make_shared<TransformLayer>(DlMatrix::MakeTranslation({100, 101}));
508 transform2_2->Add(m2);
509 transform2_2->AssignOldLayer(transform1_2.get());
510 transform2->Add(transform2_2);
511
512 auto transform2_3 =
513 std::make_shared<TransformLayer>(DlMatrix::MakeTranslation({200, 200}));
514 transform2_3->Add(m3);
515 transform2_3->AssignOldLayer(transform1_3.get());
516 transform2->Add(transform2_3);
517
518 MockLayerTree l2;
519 l2.root()->Add(transform2);
520
521 damage = DiffLayerTree(l2, l1);
522
523 // transform2 has not transform1 assigned as old layer, so it should be
524 // invalidated completely
525 EXPECT_EQ(damage.frame_damage, DlIRect::MakeLTRB(20, 20, 500, 500));
526
527 // now diff the tree properly, the only difference being transform2_2 and
528 // transform_2_1
529 transform2->AssignOldLayer(transform1.get());
530 damage = DiffLayerTree(l2, l1);
531
532 EXPECT_EQ(damage.frame_damage, DlIRect::MakeLTRB(200, 200, 300, 302));
533}
534
535} // namespace testing
536} // namespace flutter
virtual void Add(std::shared_ptr< Layer > layer)
sk_sp< DisplayList > Build()
Definition dl_builder.cc:66
void DrawPath(const DlPath &path, const DlPaint &paint) override
void Transform(const DlMatrix &matrix) 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 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::Matrix DlMatrix
impeller::Rect DlRect
impeller::Degrees DlDegrees
impeller::Point DlPoint
flutter::DlPaint DlPaint
static constexpr DlColor kBlue()
Definition dl_color.h:73
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
bool IsInvertible() const
Definition matrix.h:321
Matrix Invert() const
Definition matrix.cc:99
static Matrix MakeRotationY(Radians r)
Definition matrix.h:208
static constexpr Matrix MakeScale(const Vector3 &s)
Definition matrix.h:104
static Matrix MakeRotationX(Radians r)
Definition matrix.h:193
constexpr auto GetBottom() const
Definition rect.h:357
constexpr auto GetTop() const
Definition rect.h:353
constexpr TRect Union(const TRect &o) const
Definition rect.h:513
constexpr auto GetLeft() const
Definition rect.h:351
constexpr auto GetRight() const
Definition rect.h:355
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
static constexpr TRect MakeLTRB(Type left, Type top, Type right, Type bottom)
Definition rect.h:129