Flutter Engine
 
Loading...
Searching...
No Matches
layer_tree_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 <stddef.h>
7
12#include "flutter/fml/macros.h"
15#include "gtest/gtest.h"
16
17namespace flutter {
18namespace testing {
19
20class LayerTreeTest : public CanvasTest {
21 public:
23 : root_transform_(DlMatrix::MakeTranslation({1.0f, 1.0f})),
25 scoped_frame_(compositor_context_.AcquireFrame(nullptr,
26 &builder_,
27 nullptr,
28 root_transform_,
29 false,
30 true,
31 nullptr,
32 nullptr)) {}
33
34 CompositorContext::ScopedFrame& frame() { return *scoped_frame_.get(); }
35 const DlMatrix& root_transform() { return root_transform_; }
36 sk_sp<DisplayList> display_list() { return builder_.Build(); }
37
38 std::unique_ptr<LayerTree> BuildLayerTree(
39 const std::shared_ptr<Layer>& root_layer) {
40 return std::make_unique<LayerTree>(root_layer, DlISize(64, 64));
41 }
42
43 private:
44 CompositorContext compositor_context_;
45 DlMatrix root_transform_;
46 DisplayListBuilder builder_;
47 std::unique_ptr<CompositorContext::ScopedFrame> scoped_frame_;
48};
49
50TEST_F(LayerTreeTest, PaintingEmptyLayerDies) {
51 auto layer = std::make_shared<ContainerLayer>();
52 auto layer_tree = BuildLayerTree(layer);
53 layer_tree->Preroll(frame());
54 EXPECT_EQ(layer->paint_bounds(), DlRect());
55 EXPECT_TRUE(layer->is_empty());
56
57 layer_tree->Paint(frame());
58}
59
60TEST_F(LayerTreeTest, PaintBeforePrerollDies) {
61 const DlRect child_bounds = DlRect::MakeLTRB(5.0f, 6.0f, 20.5f, 21.5f);
62 DlPath child_path = DlPath::MakeRect(child_bounds);
63 auto mock_layer = std::make_shared<MockLayer>(child_path);
64 auto layer = std::make_shared<ContainerLayer>();
65 layer->Add(mock_layer);
66
67 auto layer_tree = BuildLayerTree(layer);
68 EXPECT_EQ(mock_layer->paint_bounds(), DlRect());
69 EXPECT_EQ(layer->paint_bounds(), DlRect());
70 EXPECT_TRUE(mock_layer->is_empty());
71 EXPECT_TRUE(layer->is_empty());
72
73 layer_tree->Paint(frame());
74
75 DisplayListBuilder expected_builder;
76 auto expected_dl = expected_builder.Build();
77
78 EXPECT_TRUE(DisplayListsEQ_Verbose(display_list(), expected_dl));
79}
80
82 const DlRect child_bounds = DlRect::MakeLTRB(5.0f, 6.0f, 20.5f, 21.5f);
83 const DlPath child_path = DlPath::MakeRect(child_bounds);
84 const DlPaint child_paint = DlPaint(DlColor::kCyan());
85 auto mock_layer = std::make_shared<MockLayer>(child_path, child_paint);
86 auto layer = std::make_shared<ContainerLayer>();
87 layer->Add(mock_layer);
88
89 auto layer_tree = BuildLayerTree(layer);
90 layer_tree->Preroll(frame());
91 EXPECT_EQ(mock_layer->paint_bounds(), child_bounds);
92 EXPECT_EQ(layer->paint_bounds(), mock_layer->paint_bounds());
93 EXPECT_FALSE(mock_layer->is_empty());
94 EXPECT_FALSE(layer->is_empty());
95 EXPECT_EQ(mock_layer->parent_matrix(), root_transform());
96
97 layer_tree->Paint(frame());
98
99 DisplayListBuilder expected_builder;
100 expected_builder.DrawPath(child_path, child_paint);
101 auto expected_dl = expected_builder.Build();
102
103 EXPECT_TRUE(DisplayListsEQ_Verbose(display_list(), expected_dl));
104}
105
107 const DlPath child_path1 = DlPath::MakeRectLTRB(5.0f, 6.0f, 20.5f, 21.5f);
108 const DlPath child_path2 = DlPath::MakeRectLTRB(8.0f, 2.0f, 16.5f, 14.5f);
109 const DlPaint child_paint1 = DlPaint(DlColor::kMidGrey());
110 const DlPaint child_paint2 = DlPaint(DlColor::kGreen());
111 auto mock_layer1 = std::make_shared<MockLayer>(child_path1, child_paint1);
112 mock_layer1->set_fake_has_platform_view(true);
113 auto mock_layer2 = std::make_shared<MockLayer>(child_path2, child_paint2);
114 auto layer = std::make_shared<ContainerLayer>();
115 layer->Add(mock_layer1);
116 layer->Add(mock_layer2);
117
118 const DlRect expected_total_bounds =
119 child_path1.GetBounds().Union(child_path2.GetBounds());
120 auto layer_tree = BuildLayerTree(layer);
121 layer_tree->Preroll(frame());
122 EXPECT_EQ(mock_layer1->paint_bounds(), child_path1.GetBounds());
123 EXPECT_EQ(mock_layer2->paint_bounds(), child_path2.GetBounds());
124 EXPECT_EQ(layer->paint_bounds(), expected_total_bounds);
125 EXPECT_FALSE(mock_layer1->is_empty());
126 EXPECT_FALSE(mock_layer2->is_empty());
127 EXPECT_FALSE(layer->is_empty());
128 EXPECT_EQ(mock_layer1->parent_matrix(), root_transform());
129 EXPECT_EQ(mock_layer2->parent_matrix(), root_transform());
130 EXPECT_EQ(mock_layer1->parent_cull_rect(), kGiantRect);
131 EXPECT_EQ(mock_layer2->parent_cull_rect(),
132 kGiantRect); // Siblings are independent
133
134 layer_tree->Paint(frame());
135
136 DisplayListBuilder expected_builder;
137 expected_builder.DrawPath(child_path1, child_paint1);
138 expected_builder.DrawPath(child_path2, child_paint2);
139 auto expected_dl = expected_builder.Build();
140
141 EXPECT_TRUE(DisplayListsEQ_Verbose(display_list(), expected_dl));
142}
143
144TEST_F(LayerTreeTest, MultipleWithEmpty) {
145 const DlPath child_path1 = DlPath::MakeRectLTRB(5.0f, 6.0f, 20.5f, 21.5f);
146 const DlPaint child_paint1 = DlPaint(DlColor::kMidGrey());
147 const DlPaint child_paint2 = DlPaint(DlColor::kGreen());
148 auto mock_layer1 = std::make_shared<MockLayer>(child_path1, child_paint1);
149 auto mock_layer2 = std::make_shared<MockLayer>(DlPath(), child_paint2);
150 auto layer = std::make_shared<ContainerLayer>();
151 layer->Add(mock_layer1);
152 layer->Add(mock_layer2);
153
154 auto layer_tree = BuildLayerTree(layer);
155 layer_tree->Preroll(frame());
156 EXPECT_EQ(mock_layer1->paint_bounds(), child_path1.GetBounds());
157 EXPECT_EQ(mock_layer2->paint_bounds(), DlPath().GetBounds());
158 EXPECT_EQ(layer->paint_bounds(), child_path1.GetBounds());
159 EXPECT_FALSE(mock_layer1->is_empty());
160 EXPECT_TRUE(mock_layer2->is_empty());
161 EXPECT_FALSE(layer->is_empty());
162 EXPECT_EQ(mock_layer1->parent_matrix(), root_transform());
163 EXPECT_EQ(mock_layer2->parent_matrix(), root_transform());
164 EXPECT_EQ(mock_layer1->parent_cull_rect(), kGiantRect);
165 EXPECT_EQ(mock_layer2->parent_cull_rect(), kGiantRect);
166
167 layer_tree->Paint(frame());
168
169 DisplayListBuilder expected_builder;
170 expected_builder.DrawPath(child_path1, child_paint1);
171 auto expected_dl = expected_builder.Build();
172
173 EXPECT_TRUE(DisplayListsEQ_Verbose(display_list(), expected_dl));
174}
175
176TEST_F(LayerTreeTest, NeedsSystemComposite) {
177 const DlPath child_path1 = DlPath::MakeRectLTRB(5.0f, 6.0f, 20.5f, 21.5f);
178 const DlPath child_path2 = DlPath::MakeRectLTRB(8.0f, 2.0f, 16.5f, 14.5f);
179 const DlPaint child_paint1 = DlPaint(DlColor::kMidGrey());
180 const DlPaint child_paint2 = DlPaint(DlColor::kGreen());
181 auto mock_layer1 = std::make_shared<MockLayer>(child_path1, child_paint1);
182 auto mock_layer2 = std::make_shared<MockLayer>(child_path2, child_paint2);
183 auto layer = std::make_shared<ContainerLayer>();
184 layer->Add(mock_layer1);
185 layer->Add(mock_layer2);
186
187 DlRect expected_total_bounds =
188 child_path1.GetBounds().Union(child_path2.GetBounds());
189 auto layer_tree = BuildLayerTree(layer);
190 layer_tree->Preroll(frame());
191 EXPECT_EQ(mock_layer1->paint_bounds(), child_path1.GetBounds());
192 EXPECT_EQ(mock_layer2->paint_bounds(), child_path2.GetBounds());
193 EXPECT_EQ(layer->paint_bounds(), expected_total_bounds);
194 EXPECT_FALSE(mock_layer1->is_empty());
195 EXPECT_FALSE(mock_layer2->is_empty());
196 EXPECT_FALSE(layer->is_empty());
197 EXPECT_EQ(mock_layer1->parent_matrix(), root_transform());
198 EXPECT_EQ(mock_layer2->parent_matrix(), root_transform());
199 EXPECT_EQ(mock_layer1->parent_cull_rect(), kGiantRect);
200 EXPECT_EQ(mock_layer2->parent_cull_rect(), kGiantRect);
201
202 layer_tree->Paint(frame());
203
204 DisplayListBuilder expected_builder;
205 expected_builder.DrawPath(child_path1, child_paint1);
206 expected_builder.DrawPath(child_path2, child_paint2);
207 auto expected_dl = expected_builder.Build();
208
209 EXPECT_TRUE(DisplayListsEQ_Verbose(display_list(), expected_dl));
210}
211
212TEST_F(LayerTreeTest, PrerollContextInitialization) {
213 LayerStateStack state_stack;
215 FixedRefreshRateStopwatch mock_raster_time;
216 FixedRefreshRateStopwatch mock_ui_time;
217 std::shared_ptr<TextureRegistry> mock_registry;
218
219 auto expect_defaults = [&state_stack, &mock_raster_time, &mock_ui_time,
220 &mock_registry](const PrerollContext& context) {
221 EXPECT_EQ(context.raster_cache, nullptr);
222 EXPECT_EQ(context.gr_context, nullptr);
223 EXPECT_EQ(context.view_embedder, nullptr);
224 EXPECT_EQ(&context.state_stack, &state_stack);
225 EXPECT_EQ(context.dst_color_space, nullptr);
226 EXPECT_EQ(context.state_stack.device_cull_rect(), kGiantRect);
227 EXPECT_EQ(context.state_stack.matrix(), DlMatrix());
228 EXPECT_TRUE(context.state_stack.matrix().IsIdentity());
229 EXPECT_EQ(context.surface_needs_readback, false);
230
231 EXPECT_EQ(&context.raster_time, &mock_raster_time);
232 EXPECT_EQ(&context.ui_time, &mock_ui_time);
233 EXPECT_EQ(context.texture_registry.get(), mock_registry.get());
234
235 EXPECT_EQ(context.has_platform_view, false);
236 EXPECT_EQ(context.has_texture_layer, false);
237
238 EXPECT_EQ(context.renderable_state_flags, 0);
239 EXPECT_EQ(context.raster_cached_entries, nullptr);
240 };
241
242 // These 4 initializers are required because they are handled by reference
243 PrerollContext context{
244 .state_stack = state_stack,
245 .raster_time = mock_raster_time,
246 .ui_time = mock_ui_time,
247 .texture_registry = mock_registry,
248 };
249 expect_defaults(context);
250}
251
252TEST_F(LayerTreeTest, PaintContextInitialization) {
253 LayerStateStack state_stack;
254 FixedRefreshRateStopwatch mock_raster_time;
255 FixedRefreshRateStopwatch mock_ui_time;
256 std::shared_ptr<TextureRegistry> mock_registry;
257
258 auto expect_defaults = [&state_stack, &mock_raster_time, &mock_ui_time,
259 &mock_registry](const PaintContext& context) {
260 EXPECT_EQ(&context.state_stack, &state_stack);
261 EXPECT_EQ(context.canvas, nullptr);
262 EXPECT_EQ(context.gr_context, nullptr);
263 EXPECT_EQ(context.view_embedder, nullptr);
264 EXPECT_EQ(&context.raster_time, &mock_raster_time);
265 EXPECT_EQ(&context.ui_time, &mock_ui_time);
266 EXPECT_EQ(context.texture_registry.get(), mock_registry.get());
267 EXPECT_EQ(context.raster_cache, nullptr);
268 };
269
270 // These 4 initializers are required because they are handled by reference
271 PaintContext context{
272 .state_stack = state_stack,
273 .raster_time = mock_raster_time,
274 .ui_time = mock_ui_time,
275 .texture_registry = mock_registry,
276 };
277 expect_defaults(context);
278}
279
280} // namespace testing
281} // namespace flutter
static constexpr DlRect kMaxCullRect
Definition dl_builder.h:32
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
static DlPath MakeRect(const DlRect &rect)
Definition dl_path.cc:39
DlRect GetBounds() const override
Definition dl_path.cc:245
Used for fixed refresh rate cases.
Definition stopwatch.h:80
void set_preroll_delegate(const DlRect &cull_rect, const DlMatrix &matrix)
CompositorContext::ScopedFrame & frame()
std::unique_ptr< LayerTree > BuildLayerTree(const std::shared_ptr< Layer > &root_layer)
TEST_F(DisplayListTest, Defaults)
bool DisplayListsEQ_Verbose(const DisplayList *a, const DisplayList *b)
impeller::Matrix DlMatrix
impeller::ISize32 DlISize
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
static constexpr DlColor kCyan()
Definition dl_color.h:74
LayerStateStack & state_stack
Definition layer.h:91
LayerStateStack & state_stack
Definition layer.h:49
A 4x4 matrix using column-major storage.
Definition matrix.h:37
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