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

Commit c19f6cb

Browse files
committed
Add LayerTree tests
1 parent ec9e6b2 commit c19f6cb

File tree

4 files changed

+205
-4
lines changed

4 files changed

+205
-4
lines changed

flow/BUILD.gn

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,8 @@ 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",
139+
"layers/layer_unittests.cc",
138140
"layers/opacity_layer_unittests.cc",
139141
"layers/performance_overlay_layer_unittests.cc",
140142
"layers/physical_shape_layer_unittests.cc",

flow/layers/layer_tree.cc

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,6 @@ LayerTree::LayerTree()
1717
checkerboard_raster_cache_images_(false),
1818
checkerboard_offscreen_layers_(false) {}
1919

20-
LayerTree::~LayerTree() = default;
21-
2220
void LayerTree::RecordBuildTime(fml::TimePoint start) {
2321
build_start_ = start;
2422
build_finish_ = fml::TimePoint::Now();

flow/layers/layer_tree.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,6 @@ class LayerTree {
2222
public:
2323
LayerTree();
2424

25-
~LayerTree();
26-
2725
void Preroll(CompositorContext::ScopedFrame& frame,
2826
bool ignore_raster_cache = false);
2927

Lines changed: 203 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,203 @@
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/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 {
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+
TEST_F(LayerTreeTest, EmptyLayer) {
40+
auto layer = std::make_shared<ContainerLayer>();
41+
42+
layer_tree().set_root_layer(layer);
43+
layer_tree().Preroll(frame());
44+
EXPECT_EQ(layer->paint_bounds(), SkRect::MakeEmpty());
45+
EXPECT_FALSE(layer->needs_painting());
46+
47+
layer_tree().Paint(frame());
48+
}
49+
50+
TEST_F(LayerTreeTest, PaintBeforePreroll) {
51+
const SkRect child_bounds = SkRect::MakeLTRB(5.0f, 6.0f, 20.5f, 21.5f);
52+
SkPath child_path;
53+
child_path.addRect(child_bounds);
54+
auto mock_layer = std::make_shared<MockLayer>(child_path);
55+
auto layer = std::make_shared<ContainerLayer>();
56+
layer->Add(mock_layer);
57+
58+
layer_tree().set_root_layer(layer);
59+
EXPECT_EQ(mock_layer->paint_bounds(), kEmptyRect);
60+
EXPECT_EQ(layer->paint_bounds(), kEmptyRect);
61+
EXPECT_FALSE(mock_layer->needs_painting());
62+
EXPECT_FALSE(layer->needs_painting());
63+
64+
layer_tree().Paint(frame());
65+
EXPECT_EQ(mock_canvas().draw_calls(), std::vector<MockCanvas::DrawCall>());
66+
}
67+
68+
TEST_F(LayerTreeTest, Simple) {
69+
const SkRect child_bounds = SkRect::MakeLTRB(5.0f, 6.0f, 20.5f, 21.5f);
70+
const SkPath child_path = SkPath().addRect(child_bounds);
71+
const SkPaint child_paint = SkPaint(SkColors::kCyan);
72+
auto mock_layer = std::make_shared<MockLayer>(child_path, child_paint);
73+
auto layer = std::make_shared<ContainerLayer>();
74+
layer->Add(mock_layer);
75+
76+
layer_tree().set_root_layer(layer);
77+
layer_tree().Preroll(frame());
78+
EXPECT_EQ(mock_layer->paint_bounds(), child_bounds);
79+
EXPECT_EQ(layer->paint_bounds(), mock_layer->paint_bounds());
80+
EXPECT_TRUE(mock_layer->needs_painting());
81+
EXPECT_TRUE(layer->needs_painting());
82+
EXPECT_EQ(mock_layer->parent_matrix(), root_transform());
83+
84+
layer_tree().Paint(frame());
85+
EXPECT_EQ(mock_canvas().draw_calls(),
86+
std::vector({MockCanvas::DrawCall{
87+
0, MockCanvas::DrawPathData{child_path, child_paint}}}));
88+
}
89+
90+
TEST_F(LayerTreeTest, Multiple) {
91+
const SkPath child_path1 = SkPath().addRect(5.0f, 6.0f, 20.5f, 21.5f);
92+
const SkPath child_path2 = SkPath().addRect(8.0f, 2.0f, 16.5f, 14.5f);
93+
const SkPaint child_paint1(SkColors::kGray);
94+
const SkPaint child_paint2(SkColors::kGreen);
95+
auto mock_layer1 = std::make_shared<MockLayer>(
96+
child_path1, child_paint1, true /* fake_has_platform_view */);
97+
auto mock_layer2 = std::make_shared<MockLayer>(child_path2, child_paint2);
98+
auto layer = std::make_shared<ContainerLayer>();
99+
layer->Add(mock_layer1);
100+
layer->Add(mock_layer2);
101+
102+
SkRect expected_total_bounds = child_path1.getBounds();
103+
expected_total_bounds.join(child_path2.getBounds());
104+
layer_tree().set_root_layer(layer);
105+
layer_tree().Preroll(frame());
106+
EXPECT_EQ(mock_layer1->paint_bounds(), child_path1.getBounds());
107+
EXPECT_EQ(mock_layer2->paint_bounds(), child_path2.getBounds());
108+
EXPECT_EQ(layer->paint_bounds(), expected_total_bounds);
109+
EXPECT_TRUE(mock_layer1->needs_painting());
110+
EXPECT_TRUE(mock_layer2->needs_painting());
111+
EXPECT_TRUE(layer->needs_painting());
112+
EXPECT_FALSE(mock_layer1->needs_system_composite());
113+
EXPECT_FALSE(mock_layer2->needs_system_composite());
114+
EXPECT_FALSE(layer->needs_system_composite());
115+
EXPECT_EQ(mock_layer1->parent_matrix(), root_transform());
116+
EXPECT_EQ(mock_layer2->parent_matrix(), root_transform());
117+
EXPECT_EQ(mock_layer1->parent_cull_rect(), kGiantRect);
118+
EXPECT_EQ(mock_layer2->parent_cull_rect(),
119+
kGiantRect); // Siblings are independent
120+
121+
layer_tree().Paint(frame());
122+
EXPECT_EQ(
123+
mock_canvas().draw_calls(),
124+
std::vector({MockCanvas::DrawCall{
125+
0, MockCanvas::DrawPathData{child_path1, child_paint1}},
126+
MockCanvas::DrawCall{0, MockCanvas::DrawPathData{
127+
child_path2, child_paint2}}}));
128+
}
129+
130+
TEST_F(LayerTreeTest, MultipleWithEmpty) {
131+
const SkPath child_path1 = SkPath().addRect(5.0f, 6.0f, 20.5f, 21.5f);
132+
const SkPaint child_paint1(SkColors::kGray);
133+
const SkPaint child_paint2(SkColors::kGreen);
134+
auto mock_layer1 = std::make_shared<MockLayer>(child_path1, child_paint1);
135+
auto mock_layer2 = std::make_shared<MockLayer>(SkPath(), child_paint2);
136+
auto layer = std::make_shared<ContainerLayer>();
137+
layer->Add(mock_layer1);
138+
layer->Add(mock_layer2);
139+
140+
layer_tree().set_root_layer(layer);
141+
layer_tree().Preroll(frame());
142+
EXPECT_EQ(mock_layer1->paint_bounds(), child_path1.getBounds());
143+
EXPECT_EQ(mock_layer2->paint_bounds(), SkPath().getBounds());
144+
EXPECT_EQ(layer->paint_bounds(), child_path1.getBounds());
145+
EXPECT_TRUE(mock_layer1->needs_painting());
146+
EXPECT_FALSE(mock_layer2->needs_painting());
147+
EXPECT_TRUE(layer->needs_painting());
148+
EXPECT_FALSE(mock_layer1->needs_system_composite());
149+
EXPECT_FALSE(mock_layer2->needs_system_composite());
150+
EXPECT_FALSE(layer->needs_system_composite());
151+
EXPECT_EQ(mock_layer1->parent_matrix(), root_transform());
152+
EXPECT_EQ(mock_layer2->parent_matrix(), root_transform());
153+
EXPECT_EQ(mock_layer1->parent_cull_rect(), kGiantRect);
154+
EXPECT_EQ(mock_layer2->parent_cull_rect(), kGiantRect);
155+
156+
layer_tree().Paint(frame());
157+
EXPECT_EQ(mock_canvas().draw_calls(),
158+
std::vector({MockCanvas::DrawCall{
159+
0, MockCanvas::DrawPathData{child_path1, child_paint1}}}));
160+
}
161+
162+
TEST_F(LayerTreeTest, NeedsSystemComposite) {
163+
const SkPath child_path1 = SkPath().addRect(5.0f, 6.0f, 20.5f, 21.5f);
164+
const SkPath child_path2 = SkPath().addRect(8.0f, 2.0f, 16.5f, 14.5f);
165+
const SkPaint child_paint1(SkColors::kGray);
166+
const SkPaint child_paint2(SkColors::kGreen);
167+
auto mock_layer1 = std::make_shared<MockLayer>(
168+
child_path1, child_paint1, false /* fake_has_platform_view */,
169+
true /* fake_needs_system_composite */);
170+
auto mock_layer2 = std::make_shared<MockLayer>(child_path2, child_paint2);
171+
auto layer = std::make_shared<ContainerLayer>();
172+
layer->Add(mock_layer1);
173+
layer->Add(mock_layer2);
174+
175+
SkRect expected_total_bounds = child_path1.getBounds();
176+
expected_total_bounds.join(child_path2.getBounds());
177+
layer_tree().set_root_layer(layer);
178+
layer_tree().Preroll(frame());
179+
EXPECT_EQ(mock_layer1->paint_bounds(), child_path1.getBounds());
180+
EXPECT_EQ(mock_layer2->paint_bounds(), child_path2.getBounds());
181+
EXPECT_EQ(layer->paint_bounds(), expected_total_bounds);
182+
EXPECT_TRUE(mock_layer1->needs_painting());
183+
EXPECT_TRUE(mock_layer2->needs_painting());
184+
EXPECT_TRUE(layer->needs_painting());
185+
EXPECT_TRUE(mock_layer1->needs_system_composite());
186+
EXPECT_FALSE(mock_layer2->needs_system_composite());
187+
EXPECT_TRUE(layer->needs_system_composite());
188+
EXPECT_EQ(mock_layer1->parent_matrix(), root_transform());
189+
EXPECT_EQ(mock_layer2->parent_matrix(), root_transform());
190+
EXPECT_EQ(mock_layer1->parent_cull_rect(), kGiantRect);
191+
EXPECT_EQ(mock_layer2->parent_cull_rect(), kGiantRect);
192+
193+
layer_tree().Paint(frame());
194+
EXPECT_EQ(
195+
mock_canvas().draw_calls(),
196+
std::vector({MockCanvas::DrawCall{
197+
0, MockCanvas::DrawPathData{child_path1, child_paint1}},
198+
MockCanvas::DrawCall{0, MockCanvas::DrawPathData{
199+
child_path2, child_paint2}}}));
200+
}
201+
202+
} // namespace testing
203+
} // namespace flutter

0 commit comments

Comments
 (0)