Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit c805bfc

Browse files
committed
Add LayerTree tests
1 parent fa39f33 commit c805bfc

File tree

2 files changed

+212
-0
lines changed

2 files changed

+212
-0
lines changed

flow/BUILD.gn

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,7 @@ executable("flow_unittests") {
135135
"layers/clip_rrect_layer_unittests.cc",
136136
"layers/color_filter_layer_unittests.cc",
137137
"layers/container_layer_unittests.cc",
138+
"layers/layer_tree_unittests.cc",
138139
"layers/opacity_layer_unittests.cc",
139140
"layers/performance_overlay_layer_unittests.cc",
140141
"layers/physical_shape_layer_unittests.cc",
Lines changed: 211 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,211 @@
1+
// Copyright 2019 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/layer_tree.h"
6+
7+
#include "flutter/flow/compositor_context.h"
8+
#include "flutter/flow/layers/container_layer.h"
9+
#include "flutter/flow/testing/mock_layer.h"
10+
#include "flutter/fml/macros.h"
11+
#include "flutter/testing/canvas_test.h"
12+
#include "flutter/testing/mock_canvas.h"
13+
#include "gtest/gtest.h"
14+
15+
namespace flutter {
16+
namespace testing {
17+
18+
class LayerTreeTest : public CanvasTest<::testing::Test> {
19+
public:
20+
void SetUp() override {
21+
root_transform_ = SkMatrix::MakeTrans(1.0f, 1.0f);
22+
scoped_frame_ = compositor_context_.AcquireFrame(
23+
nullptr, &mock_canvas(), nullptr, root_transform_, false, nullptr);
24+
}
25+
26+
void TearDown() override { scoped_frame_ = nullptr; }
27+
28+
LayerTree& layer_tree() { return layer_tree_; }
29+
CompositorContext::ScopedFrame& frame() { return *scoped_frame_.get(); }
30+
const SkMatrix& root_transform() { return root_transform_; }
31+
32+
private:
33+
LayerTree layer_tree_;
34+
CompositorContext compositor_context_;
35+
SkMatrix root_transform_;
36+
std::unique_ptr<CompositorContext::ScopedFrame> scoped_frame_;
37+
};
38+
39+
40+
TEST_F(LayerTreeTest, NoRootLayer) {
41+
EXPECT_DEATH_IF_SUPPORTED(layer_tree().Preroll(frame()), ""); // Crashes.
42+
EXPECT_DEATH_IF_SUPPORTED(layer_tree().Paint(frame()), ""); // Crashes.
43+
}
44+
45+
TEST_F(LayerTreeTest, EmptyLayer) {
46+
auto layer = std::make_shared<ContainerLayer>();
47+
48+
layer_tree().set_root_layer(layer);
49+
layer_tree().Preroll(frame());
50+
EXPECT_EQ(layer->paint_bounds(), SkRect::MakeEmpty());
51+
EXPECT_FALSE(layer->needs_painting());
52+
53+
layer_tree().Paint(frame());
54+
}
55+
56+
TEST_F(LayerTreeTest, PaintBeforePreroll) {
57+
const SkRect child_bounds = SkRect::MakeLTRB(5.0f, 6.0f, 20.5f, 21.5f);
58+
SkPath child_path;
59+
child_path.addRect(child_bounds);
60+
auto mock_layer = std::make_shared<MockLayer>(child_path);
61+
auto layer = std::make_shared<ContainerLayer>();
62+
layer->Add(mock_layer);
63+
64+
layer_tree().set_root_layer(layer);
65+
EXPECT_EQ(mock_layer->paint_bounds(), kEmptyRect);
66+
EXPECT_EQ(layer->paint_bounds(),kEmptyRect);
67+
EXPECT_FALSE(mock_layer->needs_painting());
68+
EXPECT_FALSE(layer->needs_painting());
69+
70+
layer_tree().Paint(frame());
71+
EXPECT_EQ(mock_canvas().draw_calls(), std::vector<MockCanvas::DrawCall>());
72+
}
73+
74+
TEST_F(LayerTreeTest, Simple) {
75+
const SkRect child_bounds = SkRect::MakeLTRB(5.0f, 6.0f, 20.5f, 21.5f);
76+
const SkPath child_path = SkPath().addRect(child_bounds);
77+
const SkPaint child_paint = SkPaint(SkColors::kCyan);
78+
auto mock_layer = std::make_shared<MockLayer>(child_path, child_paint);
79+
auto layer = std::make_shared<ContainerLayer>();
80+
layer->Add(mock_layer);
81+
82+
layer_tree().set_root_layer(layer);
83+
layer_tree().Preroll(frame());
84+
EXPECT_EQ(mock_layer->paint_bounds(), child_bounds);
85+
EXPECT_EQ(layer->paint_bounds(), mock_layer->paint_bounds());
86+
EXPECT_TRUE(mock_layer->needs_painting());
87+
EXPECT_TRUE(layer->needs_painting());
88+
EXPECT_EQ(mock_layer->parent_matrix(), root_transform());
89+
90+
layer_tree().Paint(frame());
91+
EXPECT_EQ(mock_canvas().draw_calls(), std::vector({MockCanvas::DrawCall{0, MockCanvas::DrawPathData{child_path, child_paint}}}));
92+
}
93+
94+
TEST_F(LayerTreeTest, Multiple) {
95+
const SkPath child_path1 = SkPath().addRect(5.0f, 6.0f, 20.5f, 21.5f);
96+
const SkPath child_path2 = SkPath().addRect(8.0f, 2.0f, 16.5f, 14.5f);
97+
const SkPaint child_paint1(SkColors::kGray);
98+
const SkPaint child_paint2(SkColors::kGreen);
99+
auto mock_layer1 = std::make_shared<MockLayer>(
100+
child_path1, child_paint1, true /* fake_has_platform_view */);
101+
auto mock_layer2 = std::make_shared<MockLayer>(child_path2, child_paint2);
102+
auto layer = std::make_shared<ContainerLayer>();
103+
layer->Add(mock_layer1);
104+
layer->Add(mock_layer2);
105+
106+
SkRect expected_total_bounds = child_path1.getBounds();
107+
expected_total_bounds.join(child_path2.getBounds());
108+
layer_tree().set_root_layer(layer);
109+
layer_tree().Preroll(frame());
110+
EXPECT_EQ(mock_layer1->paint_bounds(), child_path1.getBounds());
111+
EXPECT_EQ(mock_layer2->paint_bounds(), child_path2.getBounds());
112+
EXPECT_EQ(layer->paint_bounds(), expected_total_bounds);
113+
EXPECT_TRUE(mock_layer1->needs_painting());
114+
EXPECT_TRUE(mock_layer2->needs_painting());
115+
EXPECT_TRUE(layer->needs_painting());
116+
EXPECT_FALSE(mock_layer1->needs_system_composite());
117+
EXPECT_FALSE(mock_layer2->needs_system_composite());
118+
EXPECT_FALSE(layer->needs_system_composite());
119+
EXPECT_EQ(mock_layer1->parent_matrix(), root_transform());
120+
EXPECT_EQ(mock_layer2->parent_matrix(), root_transform());
121+
EXPECT_EQ(mock_layer1->parent_cull_rect(), kGiantRect);
122+
EXPECT_EQ(mock_layer2->parent_cull_rect(),
123+
kGiantRect); // Siblings are independent
124+
125+
layer_tree().Paint(frame());
126+
EXPECT_EQ(
127+
mock_canvas().draw_calls(),
128+
std::vector({MockCanvas::DrawCall{
129+
0, MockCanvas::DrawPathData{child_path1,
130+
child_paint1}},
131+
MockCanvas::DrawCall{0, MockCanvas::DrawPathData{
132+
child_path2,
133+
child_paint2}}}));
134+
}
135+
136+
TEST_F(LayerTreeTest, MultipleWithEmpty) {
137+
const SkPath child_path1 = SkPath().addRect(5.0f, 6.0f, 20.5f, 21.5f);
138+
const SkPaint child_paint1(SkColors::kGray);
139+
const SkPaint child_paint2(SkColors::kGreen);
140+
auto mock_layer1 = std::make_shared<MockLayer>(child_path1, child_paint1);
141+
auto mock_layer2 = std::make_shared<MockLayer>(SkPath(), child_paint2);
142+
auto layer = std::make_shared<ContainerLayer>();
143+
layer->Add(mock_layer1);
144+
layer->Add(mock_layer2);
145+
146+
layer_tree().set_root_layer(layer);
147+
layer_tree().Preroll(frame());
148+
EXPECT_EQ(mock_layer1->paint_bounds(), child_path1.getBounds());
149+
EXPECT_EQ(mock_layer2->paint_bounds(), SkPath().getBounds());
150+
EXPECT_EQ(layer->paint_bounds(), child_path1.getBounds());
151+
EXPECT_TRUE(mock_layer1->needs_painting());
152+
EXPECT_FALSE(mock_layer2->needs_painting());
153+
EXPECT_TRUE(layer->needs_painting());
154+
EXPECT_FALSE(mock_layer1->needs_system_composite());
155+
EXPECT_FALSE(mock_layer2->needs_system_composite());
156+
EXPECT_FALSE(layer->needs_system_composite());
157+
EXPECT_EQ(mock_layer1->parent_matrix(), root_transform());
158+
EXPECT_EQ(mock_layer2->parent_matrix(), root_transform());
159+
EXPECT_EQ(mock_layer1->parent_cull_rect(), kGiantRect);
160+
EXPECT_EQ(mock_layer2->parent_cull_rect(), kGiantRect);
161+
162+
layer_tree().Paint(frame());
163+
EXPECT_EQ(mock_canvas().draw_calls(),
164+
std::vector({MockCanvas::DrawCall{
165+
0, MockCanvas::DrawPathData{child_path1, child_paint1}}}));
166+
}
167+
168+
TEST_F(LayerTreeTest, NeedsSystemComposite) {
169+
const SkPath child_path1 = SkPath().addRect(5.0f, 6.0f, 20.5f, 21.5f);
170+
const SkPath child_path2 = SkPath().addRect(8.0f, 2.0f, 16.5f, 14.5f);
171+
const SkPaint child_paint1(SkColors::kGray);
172+
const SkPaint child_paint2(SkColors::kGreen);
173+
auto mock_layer1 = std::make_shared<MockLayer>(
174+
child_path1, child_paint1, false /* fake_has_platform_view */,
175+
true /* fake_needs_system_composite */);
176+
auto mock_layer2 = std::make_shared<MockLayer>(child_path2, child_paint2);
177+
auto layer = std::make_shared<ContainerLayer>();
178+
layer->Add(mock_layer1);
179+
layer->Add(mock_layer2);
180+
181+
SkRect expected_total_bounds = child_path1.getBounds();
182+
expected_total_bounds.join(child_path2.getBounds());
183+
layer_tree().set_root_layer(layer);
184+
layer_tree().Preroll(frame());
185+
EXPECT_EQ(mock_layer1->paint_bounds(), child_path1.getBounds());
186+
EXPECT_EQ(mock_layer2->paint_bounds(), child_path2.getBounds());
187+
EXPECT_EQ(layer->paint_bounds(), expected_total_bounds);
188+
EXPECT_TRUE(mock_layer1->needs_painting());
189+
EXPECT_TRUE(mock_layer2->needs_painting());
190+
EXPECT_TRUE(layer->needs_painting());
191+
EXPECT_TRUE(mock_layer1->needs_system_composite());
192+
EXPECT_FALSE(mock_layer2->needs_system_composite());
193+
EXPECT_TRUE(layer->needs_system_composite());
194+
EXPECT_EQ(mock_layer1->parent_matrix(), root_transform());
195+
EXPECT_EQ(mock_layer2->parent_matrix(), root_transform());
196+
EXPECT_EQ(mock_layer1->parent_cull_rect(), kGiantRect);
197+
EXPECT_EQ(mock_layer2->parent_cull_rect(), kGiantRect);
198+
199+
layer_tree().Paint(frame());
200+
EXPECT_EQ(
201+
mock_canvas().draw_calls(),
202+
std::vector({MockCanvas::DrawCall{
203+
0, MockCanvas::DrawPathData{child_path1,
204+
child_paint1}},
205+
MockCanvas::DrawCall{0, MockCanvas::DrawPathData{
206+
child_path2,
207+
child_paint2}}}));
208+
}
209+
210+
} // namespace testing
211+
} // namespace flutter

0 commit comments

Comments
 (0)