Flutter Engine
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 "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:
21  : layer_tree_(SkISize::Make(64, 64), 1.0f),
22  compositor_context_(fml::kDefaultFrameBudget),
23  root_transform_(SkMatrix::Translate(1.0f, 1.0f)),
24  scoped_frame_(compositor_context_.AcquireFrame(nullptr,
25  &mock_canvas(),
26  nullptr,
27  root_transform_,
28  false,
29  true,
30  nullptr)) {}
31 
32  LayerTree& layer_tree() { return layer_tree_; }
33  CompositorContext::ScopedFrame& frame() { return *scoped_frame_.get(); }
34  const SkMatrix& root_transform() { return root_transform_; }
35 
36  private:
37  LayerTree layer_tree_;
38  CompositorContext compositor_context_;
39  SkMatrix root_transform_;
40  std::unique_ptr<CompositorContext::ScopedFrame> scoped_frame_;
41 };
42 
43 TEST_F(LayerTreeTest, PaintingEmptyLayerDies) {
44  auto layer = std::make_shared<ContainerLayer>();
45 
46  layer_tree().set_root_layer(layer);
48  EXPECT_EQ(layer->paint_bounds(), SkRect::MakeEmpty());
49  EXPECT_FALSE(layer->needs_painting());
50 
51  layer_tree().Paint(frame());
52 }
53 
54 TEST_F(LayerTreeTest, PaintBeforePreollDies) {
55  const SkRect child_bounds = SkRect::MakeLTRB(5.0f, 6.0f, 20.5f, 21.5f);
56  SkPath child_path;
57  child_path.addRect(child_bounds);
58  auto mock_layer = std::make_shared<MockLayer>(child_path);
59  auto layer = std::make_shared<ContainerLayer>();
60  layer->Add(mock_layer);
61 
62  layer_tree().set_root_layer(layer);
63  EXPECT_EQ(mock_layer->paint_bounds(), kEmptyRect);
64  EXPECT_EQ(layer->paint_bounds(), kEmptyRect);
65  EXPECT_FALSE(mock_layer->needs_painting());
66  EXPECT_FALSE(layer->needs_painting());
67 
68  layer_tree().Paint(frame());
69  EXPECT_EQ(mock_canvas().draw_calls(), std::vector<MockCanvas::DrawCall>());
70 }
71 
73  const SkRect child_bounds = SkRect::MakeLTRB(5.0f, 6.0f, 20.5f, 21.5f);
74  const SkPath child_path = SkPath().addRect(child_bounds);
75  const SkPaint child_paint = SkPaint(SkColors::kCyan);
76  auto mock_layer = std::make_shared<MockLayer>(child_path, child_paint);
77  auto layer = std::make_shared<ContainerLayer>();
78  layer->Add(mock_layer);
79 
80  layer_tree().set_root_layer(layer);
82  EXPECT_EQ(mock_layer->paint_bounds(), child_bounds);
83  EXPECT_EQ(layer->paint_bounds(), mock_layer->paint_bounds());
84  EXPECT_TRUE(mock_layer->needs_painting());
85  EXPECT_TRUE(layer->needs_painting());
86  EXPECT_EQ(mock_layer->parent_matrix(), root_transform());
87 
88  layer_tree().Paint(frame());
89  EXPECT_EQ(mock_canvas().draw_calls(),
90  std::vector({MockCanvas::DrawCall{
91  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, child_paint1}},
131  child_path2, child_paint2}}}));
132 }
133 
134 TEST_F(LayerTreeTest, MultipleWithEmpty) {
135  const SkPath child_path1 = SkPath().addRect(5.0f, 6.0f, 20.5f, 21.5f);
136  const SkPaint child_paint1(SkColors::kGray);
137  const SkPaint child_paint2(SkColors::kGreen);
138  auto mock_layer1 = std::make_shared<MockLayer>(child_path1, child_paint1);
139  auto mock_layer2 = std::make_shared<MockLayer>(SkPath(), child_paint2);
140  auto layer = std::make_shared<ContainerLayer>();
141  layer->Add(mock_layer1);
142  layer->Add(mock_layer2);
143 
144  layer_tree().set_root_layer(layer);
145  layer_tree().Preroll(frame());
146  EXPECT_EQ(mock_layer1->paint_bounds(), child_path1.getBounds());
147  EXPECT_EQ(mock_layer2->paint_bounds(), SkPath().getBounds());
148  EXPECT_EQ(layer->paint_bounds(), child_path1.getBounds());
149  EXPECT_TRUE(mock_layer1->needs_painting());
150  EXPECT_FALSE(mock_layer2->needs_painting());
151  EXPECT_TRUE(layer->needs_painting());
152  EXPECT_FALSE(mock_layer1->needs_system_composite());
153  EXPECT_FALSE(mock_layer2->needs_system_composite());
154  EXPECT_FALSE(layer->needs_system_composite());
155  EXPECT_EQ(mock_layer1->parent_matrix(), root_transform());
156  EXPECT_EQ(mock_layer2->parent_matrix(), root_transform());
157  EXPECT_EQ(mock_layer1->parent_cull_rect(), kGiantRect);
158  EXPECT_EQ(mock_layer2->parent_cull_rect(), kGiantRect);
159 
160  layer_tree().Paint(frame());
161  EXPECT_EQ(mock_canvas().draw_calls(),
162  std::vector({MockCanvas::DrawCall{
163  0, MockCanvas::DrawPathData{child_path1, child_paint1}}}));
164 }
165 
166 TEST_F(LayerTreeTest, NeedsSystemComposite) {
167  const SkPath child_path1 = SkPath().addRect(5.0f, 6.0f, 20.5f, 21.5f);
168  const SkPath child_path2 = SkPath().addRect(8.0f, 2.0f, 16.5f, 14.5f);
169  const SkPaint child_paint1(SkColors::kGray);
170  const SkPaint child_paint2(SkColors::kGreen);
171  auto mock_layer1 = std::make_shared<MockLayer>(
172  child_path1, child_paint1, false /* fake_has_platform_view */,
173  true /* fake_needs_system_composite */);
174  auto mock_layer2 = std::make_shared<MockLayer>(child_path2, child_paint2);
175  auto layer = std::make_shared<ContainerLayer>();
176  layer->Add(mock_layer1);
177  layer->Add(mock_layer2);
178 
179  SkRect expected_total_bounds = child_path1.getBounds();
180  expected_total_bounds.join(child_path2.getBounds());
181  layer_tree().set_root_layer(layer);
182  layer_tree().Preroll(frame());
183  EXPECT_EQ(mock_layer1->paint_bounds(), child_path1.getBounds());
184  EXPECT_EQ(mock_layer2->paint_bounds(), child_path2.getBounds());
185  EXPECT_EQ(layer->paint_bounds(), expected_total_bounds);
186  EXPECT_TRUE(mock_layer1->needs_painting());
187  EXPECT_TRUE(mock_layer2->needs_painting());
188  EXPECT_TRUE(layer->needs_painting());
189  EXPECT_TRUE(mock_layer1->needs_system_composite());
190  EXPECT_FALSE(mock_layer2->needs_system_composite());
191  EXPECT_TRUE(layer->needs_system_composite());
192  EXPECT_EQ(mock_layer1->parent_matrix(), root_transform());
193  EXPECT_EQ(mock_layer2->parent_matrix(), root_transform());
194  EXPECT_EQ(mock_layer1->parent_cull_rect(), kGiantRect);
195  EXPECT_EQ(mock_layer2->parent_cull_rect(), kGiantRect);
196 
197  layer_tree().Paint(frame());
198  EXPECT_EQ(
199  mock_canvas().draw_calls(),
200  std::vector({MockCanvas::DrawCall{
201  0, MockCanvas::DrawPathData{child_path1, child_paint1}},
203  child_path2, child_paint2}}}));
204 }
205 
206 } // namespace testing
207 } // namespace flutter
void set_root_layer(std::shared_ptr< Layer > root_layer)
Definition: layer_tree.h:45
Definition: ascii_trie.cc:9
static constexpr SkRect kGiantRect
Definition: layer.h:38
bool Preroll(CompositorContext::ScopedFrame &frame, bool ignore_raster_cache=false)
Definition: layer_tree.cc:32
TEST_F(BackdropFilterLayerTest, PaintingEmptyLayerDies)
CompositorContext::ScopedFrame & frame()
constexpr Milliseconds kDefaultFrameBudget
Definition: time_delta.h:21
void Paint(CompositorContext::ScopedFrame &frame, bool ignore_raster_cache=false) const
Definition: layer_tree.cc:89
static constexpr SkRect kEmptyRect
Definition: mock_canvas.h:28