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/testing/layer_test.h"
8 #include "flutter/flow/testing/mock_layer.h"
9 #include "flutter/fml/macros.h"
10 #include "flutter/testing/mock_canvas.h"
11 
12 namespace flutter {
13 namespace testing {
14 
16 
17 #ifndef NDEBUG
18 TEST_F(ContainerLayerTest, LayerWithParentHasPlatformView) {
19  auto layer = std::make_shared<ContainerLayer>();
20 
21  preroll_context()->has_platform_view = true;
22  EXPECT_DEATH_IF_SUPPORTED(layer->Preroll(preroll_context(), SkMatrix()),
23  "!context->has_platform_view");
24 }
25 
26 TEST_F(ContainerLayerTest, PaintingEmptyLayerDies) {
27  auto layer = std::make_shared<ContainerLayer>();
28 
29  layer->Preroll(preroll_context(), SkMatrix());
30  EXPECT_EQ(layer->paint_bounds(), SkRect::MakeEmpty());
31  EXPECT_FALSE(layer->needs_painting());
32  EXPECT_FALSE(layer->needs_system_composite());
33 
34  EXPECT_DEATH_IF_SUPPORTED(layer->Paint(paint_context()),
35  "needs_painting\\(\\)");
36 }
37 
38 TEST_F(ContainerLayerTest, PaintBeforePreollDies) {
39  SkPath child_path;
40  child_path.addRect(5.0f, 6.0f, 20.5f, 21.5f);
41  auto mock_layer = std::make_shared<MockLayer>(child_path);
42  auto layer = std::make_shared<ContainerLayer>();
43  layer->Add(mock_layer);
44 
45  EXPECT_EQ(layer->paint_bounds(), SkRect::MakeEmpty());
46  EXPECT_DEATH_IF_SUPPORTED(layer->Paint(paint_context()),
47  "needs_painting\\(\\)");
48 }
49 #endif
50 
52  SkPath child_path;
53  child_path.addRect(5.0f, 6.0f, 20.5f, 21.5f);
54  SkPaint child_paint(SkColors::kGreen);
55  SkMatrix initial_transform = SkMatrix::Translate(-0.5f, -0.5f);
56 
57  auto mock_layer = std::make_shared<MockLayer>(child_path, child_paint);
58  auto layer = std::make_shared<ContainerLayer>();
59  layer->Add(mock_layer);
60 
61  layer->Preroll(preroll_context(), initial_transform);
62  EXPECT_FALSE(preroll_context()->has_platform_view);
63  EXPECT_EQ(mock_layer->paint_bounds(), child_path.getBounds());
64  EXPECT_EQ(layer->paint_bounds(), child_path.getBounds());
65  EXPECT_TRUE(mock_layer->needs_painting());
66  EXPECT_TRUE(layer->needs_painting());
67  EXPECT_FALSE(mock_layer->needs_system_composite());
68  EXPECT_FALSE(layer->needs_system_composite());
69  EXPECT_EQ(mock_layer->parent_matrix(), initial_transform);
70  EXPECT_EQ(mock_layer->parent_cull_rect(), kGiantRect);
71 
72  layer->Paint(paint_context());
73  EXPECT_EQ(mock_canvas().draw_calls(),
74  std::vector({MockCanvas::DrawCall{
75  0, MockCanvas::DrawPathData{child_path, child_paint}}}));
76 }
77 
79  SkPath child_path1;
80  child_path1.addRect(5.0f, 6.0f, 20.5f, 21.5f);
81  SkPath child_path2;
82  child_path2.addRect(8.0f, 2.0f, 16.5f, 14.5f);
83  SkPaint child_paint1(SkColors::kGray);
84  SkPaint child_paint2(SkColors::kGreen);
85  SkMatrix initial_transform = SkMatrix::Translate(-0.5f, -0.5f);
86 
87  auto mock_layer1 = std::make_shared<MockLayer>(
88  child_path1, child_paint1, true /* fake_has_platform_view */);
89  auto mock_layer2 = std::make_shared<MockLayer>(child_path2, child_paint2);
90  auto layer = std::make_shared<ContainerLayer>();
91  layer->Add(mock_layer1);
92  layer->Add(mock_layer2);
93 
94  SkRect expected_total_bounds = child_path1.getBounds();
95  expected_total_bounds.join(child_path2.getBounds());
96  layer->Preroll(preroll_context(), initial_transform);
97  EXPECT_TRUE(preroll_context()->has_platform_view);
98  EXPECT_EQ(mock_layer1->paint_bounds(), child_path1.getBounds());
99  EXPECT_EQ(mock_layer2->paint_bounds(), child_path2.getBounds());
100  EXPECT_EQ(layer->paint_bounds(), expected_total_bounds);
101  EXPECT_TRUE(mock_layer1->needs_painting());
102  EXPECT_TRUE(mock_layer2->needs_painting());
103  EXPECT_TRUE(layer->needs_painting());
104  EXPECT_FALSE(mock_layer1->needs_system_composite());
105  EXPECT_FALSE(mock_layer2->needs_system_composite());
106  EXPECT_FALSE(layer->needs_system_composite());
107  EXPECT_EQ(mock_layer1->parent_matrix(), initial_transform);
108  EXPECT_EQ(mock_layer2->parent_matrix(), initial_transform);
109  EXPECT_EQ(mock_layer1->parent_cull_rect(), kGiantRect);
110  EXPECT_EQ(mock_layer2->parent_cull_rect(),
111  kGiantRect); // Siblings are independent
112 
113  layer->Paint(paint_context());
114  EXPECT_EQ(
115  mock_canvas().draw_calls(),
116  std::vector({MockCanvas::DrawCall{
117  0, MockCanvas::DrawPathData{child_path1, child_paint1}},
119  child_path2, child_paint2}}}));
120 }
121 
122 TEST_F(ContainerLayerTest, MultipleWithEmpty) {
123  SkPath child_path1;
124  child_path1.addRect(5.0f, 6.0f, 20.5f, 21.5f);
125  SkPaint child_paint1(SkColors::kGray);
126  SkPaint child_paint2(SkColors::kGreen);
127  SkMatrix initial_transform = SkMatrix::Translate(-0.5f, -0.5f);
128 
129  auto mock_layer1 = std::make_shared<MockLayer>(child_path1, child_paint1);
130  auto mock_layer2 = std::make_shared<MockLayer>(SkPath(), child_paint2);
131  auto layer = std::make_shared<ContainerLayer>();
132  layer->Add(mock_layer1);
133  layer->Add(mock_layer2);
134 
135  layer->Preroll(preroll_context(), initial_transform);
136  EXPECT_FALSE(preroll_context()->has_platform_view);
137  EXPECT_EQ(mock_layer1->paint_bounds(), child_path1.getBounds());
138  EXPECT_EQ(mock_layer2->paint_bounds(), SkPath().getBounds());
139  EXPECT_EQ(layer->paint_bounds(), child_path1.getBounds());
140  EXPECT_TRUE(mock_layer1->needs_painting());
141  EXPECT_FALSE(mock_layer2->needs_painting());
142  EXPECT_TRUE(layer->needs_painting());
143  EXPECT_FALSE(mock_layer1->needs_system_composite());
144  EXPECT_FALSE(mock_layer2->needs_system_composite());
145  EXPECT_FALSE(layer->needs_system_composite());
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(), kGiantRect);
150 
151  layer->Paint(paint_context());
152  EXPECT_EQ(mock_canvas().draw_calls(),
153  std::vector({MockCanvas::DrawCall{
154  0, MockCanvas::DrawPathData{child_path1, child_paint1}}}));
155 }
156 
157 TEST_F(ContainerLayerTest, NeedsSystemComposite) {
158  SkPath child_path1;
159  child_path1.addRect(5.0f, 6.0f, 20.5f, 21.5f);
160  SkPath child_path2;
161  child_path2.addRect(8.0f, 2.0f, 16.5f, 14.5f);
162  SkPaint child_paint1(SkColors::kGray);
163  SkPaint child_paint2(SkColors::kGreen);
164  SkMatrix initial_transform = SkMatrix::Translate(-0.5f, -0.5f);
165 
166  auto mock_layer1 = std::make_shared<MockLayer>(
167  child_path1, child_paint1, false /* fake_has_platform_view */,
168  true /* fake_needs_system_composite */);
169  auto mock_layer2 = std::make_shared<MockLayer>(child_path2, child_paint2);
170  auto layer = std::make_shared<ContainerLayer>();
171  layer->Add(mock_layer1);
172  layer->Add(mock_layer2);
173 
174  SkRect expected_total_bounds = child_path1.getBounds();
175  expected_total_bounds.join(child_path2.getBounds());
176  layer->Preroll(preroll_context(), initial_transform);
177  EXPECT_FALSE(preroll_context()->has_platform_view);
178  EXPECT_EQ(mock_layer1->paint_bounds(), child_path1.getBounds());
179  EXPECT_EQ(mock_layer2->paint_bounds(), child_path2.getBounds());
180  EXPECT_EQ(layer->paint_bounds(), expected_total_bounds);
181  EXPECT_TRUE(mock_layer1->needs_painting());
182  EXPECT_TRUE(mock_layer2->needs_painting());
183  EXPECT_TRUE(layer->needs_painting());
184  EXPECT_TRUE(mock_layer1->needs_system_composite());
185  EXPECT_FALSE(mock_layer2->needs_system_composite());
186  EXPECT_TRUE(layer->needs_system_composite());
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(paint_context());
193  EXPECT_EQ(
194  mock_canvas().draw_calls(),
195  std::vector({MockCanvas::DrawCall{
196  0, MockCanvas::DrawPathData{child_path1, child_paint1}},
198  child_path2, child_paint2}}}));
199 }
200 
201 TEST_F(ContainerLayerTest, MergedOneChild) {
202  SkPath child_path;
203  child_path.addRect(5.0f, 6.0f, 20.5f, 21.5f);
204  SkPaint child_paint(SkColors::kGreen);
205  SkMatrix initial_transform = SkMatrix::Translate(-0.5f, -0.5f);
206 
207  auto mock_layer = std::make_shared<MockLayer>(child_path, child_paint);
208  auto layer = std::make_shared<MergedContainerLayer>();
209  layer->Add(mock_layer);
210 
211  layer->Preroll(preroll_context(), initial_transform);
212  EXPECT_FALSE(preroll_context()->has_platform_view);
213  EXPECT_EQ(mock_layer->paint_bounds(), child_path.getBounds());
214  EXPECT_EQ(layer->paint_bounds(), child_path.getBounds());
215  EXPECT_TRUE(mock_layer->needs_painting());
216  EXPECT_TRUE(layer->needs_painting());
217  EXPECT_FALSE(mock_layer->needs_system_composite());
218  EXPECT_FALSE(layer->needs_system_composite());
219  EXPECT_EQ(mock_layer->parent_matrix(), initial_transform);
220  EXPECT_EQ(mock_layer->parent_cull_rect(), kGiantRect);
221 
222  layer->Paint(paint_context());
223  EXPECT_EQ(mock_canvas().draw_calls(),
224  std::vector({MockCanvas::DrawCall{
225  0, MockCanvas::DrawPathData{child_path, child_paint}}}));
226 }
227 
228 TEST_F(ContainerLayerTest, MergedMultipleChildren) {
229  SkPath child_path1;
230  child_path1.addRect(5.0f, 6.0f, 20.5f, 21.5f);
231  SkPath child_path2;
232  child_path2.addRect(58.0f, 2.0f, 16.5f, 14.5f);
233  SkPaint child_paint1(SkColors::kGray);
234  SkPaint child_paint2(SkColors::kGreen);
235  SkMatrix initial_transform = SkMatrix::Translate(-0.5f, -0.5f);
236 
237  auto mock_layer1 = std::make_shared<MockLayer>(child_path1, child_paint1);
238  auto mock_layer2 = std::make_shared<MockLayer>(child_path2, child_paint2);
239  auto layer = std::make_shared<MergedContainerLayer>();
240  layer->Add(mock_layer1);
241  layer->Add(mock_layer2);
242 
243  SkRect expected_total_bounds = child_path1.getBounds();
244  expected_total_bounds.join(child_path2.getBounds());
245  layer->Preroll(preroll_context(), initial_transform);
246  EXPECT_FALSE(preroll_context()->has_platform_view);
247  EXPECT_EQ(mock_layer1->paint_bounds(), child_path1.getBounds());
248  EXPECT_EQ(mock_layer2->paint_bounds(), child_path2.getBounds());
249  EXPECT_EQ(layer->paint_bounds(), expected_total_bounds);
250  EXPECT_TRUE(mock_layer1->needs_painting());
251  EXPECT_TRUE(mock_layer2->needs_painting());
252  EXPECT_TRUE(layer->needs_painting());
253  EXPECT_FALSE(mock_layer1->needs_system_composite());
254  EXPECT_FALSE(mock_layer2->needs_system_composite());
255  EXPECT_FALSE(layer->needs_system_composite());
256  EXPECT_EQ(mock_layer1->parent_matrix(), initial_transform);
257  EXPECT_EQ(mock_layer2->parent_matrix(), initial_transform);
258  EXPECT_EQ(mock_layer1->parent_cull_rect(), kGiantRect);
259  EXPECT_EQ(mock_layer2->parent_cull_rect(),
260  kGiantRect); // Siblings are independent
261 
262  layer->Paint(paint_context());
263  EXPECT_EQ(
264  mock_canvas().draw_calls(),
265  std::vector({MockCanvas::DrawCall{
266  0, MockCanvas::DrawPathData{child_path1, child_paint1}},
268  child_path2, child_paint2}}}));
269 }
270 
271 } // namespace testing
272 } // namespace flutter
static constexpr SkRect kGiantRect
Definition: layer.h:38
LayerTestBase<::testing::Test > LayerTest
Definition: layer_test.h:151
TEST_F(BackdropFilterLayerTest, PaintingEmptyLayerDies)