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_TRUE(layer->is_empty());
50 
51  layer_tree().Paint(frame());
52 }
53 
54 TEST_F(LayerTreeTest, PaintBeforePrerollDies) {
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_TRUE(mock_layer->is_empty());
66  EXPECT_TRUE(layer->is_empty());
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_FALSE(mock_layer->is_empty());
85  EXPECT_FALSE(layer->is_empty());
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_FALSE(mock_layer1->is_empty());
114  EXPECT_FALSE(mock_layer2->is_empty());
115  EXPECT_FALSE(layer->is_empty());
116  EXPECT_EQ(mock_layer1->parent_matrix(), root_transform());
117  EXPECT_EQ(mock_layer2->parent_matrix(), root_transform());
118  EXPECT_EQ(mock_layer1->parent_cull_rect(), kGiantRect);
119  EXPECT_EQ(mock_layer2->parent_cull_rect(),
120  kGiantRect); // Siblings are independent
121 
122  layer_tree().Paint(frame());
123  EXPECT_EQ(
124  mock_canvas().draw_calls(),
125  std::vector({MockCanvas::DrawCall{
126  0, MockCanvas::DrawPathData{child_path1, child_paint1}},
128  child_path2, child_paint2}}}));
129 }
130 
131 TEST_F(LayerTreeTest, MultipleWithEmpty) {
132  const SkPath child_path1 = SkPath().addRect(5.0f, 6.0f, 20.5f, 21.5f);
133  const SkPaint child_paint1(SkColors::kGray);
134  const SkPaint child_paint2(SkColors::kGreen);
135  auto mock_layer1 = std::make_shared<MockLayer>(child_path1, child_paint1);
136  auto mock_layer2 = std::make_shared<MockLayer>(SkPath(), child_paint2);
137  auto layer = std::make_shared<ContainerLayer>();
138  layer->Add(mock_layer1);
139  layer->Add(mock_layer2);
140 
141  layer_tree().set_root_layer(layer);
142  layer_tree().Preroll(frame());
143  EXPECT_EQ(mock_layer1->paint_bounds(), child_path1.getBounds());
144  EXPECT_EQ(mock_layer2->paint_bounds(), SkPath().getBounds());
145  EXPECT_EQ(layer->paint_bounds(), child_path1.getBounds());
146  EXPECT_FALSE(mock_layer1->is_empty());
147  EXPECT_TRUE(mock_layer2->is_empty());
148  EXPECT_FALSE(layer->is_empty());
149  EXPECT_EQ(mock_layer1->parent_matrix(), root_transform());
150  EXPECT_EQ(mock_layer2->parent_matrix(), root_transform());
151  EXPECT_EQ(mock_layer1->parent_cull_rect(), kGiantRect);
152  EXPECT_EQ(mock_layer2->parent_cull_rect(), kGiantRect);
153 
154  layer_tree().Paint(frame());
155  EXPECT_EQ(mock_canvas().draw_calls(),
156  std::vector({MockCanvas::DrawCall{
157  0, MockCanvas::DrawPathData{child_path1, child_paint1}}}));
158 }
159 
160 TEST_F(LayerTreeTest, NeedsSystemComposite) {
161  const SkPath child_path1 = SkPath().addRect(5.0f, 6.0f, 20.5f, 21.5f);
162  const SkPath child_path2 = SkPath().addRect(8.0f, 2.0f, 16.5f, 14.5f);
163  const SkPaint child_paint1(SkColors::kGray);
164  const SkPaint child_paint2(SkColors::kGreen);
165  auto mock_layer1 = std::make_shared<MockLayer>(
166  child_path1, child_paint1, false /* fake_has_platform_view */);
167  auto mock_layer2 = std::make_shared<MockLayer>(child_path2, child_paint2);
168  auto layer = std::make_shared<ContainerLayer>();
169  layer->Add(mock_layer1);
170  layer->Add(mock_layer2);
171 
172  SkRect expected_total_bounds = child_path1.getBounds();
173  expected_total_bounds.join(child_path2.getBounds());
174  layer_tree().set_root_layer(layer);
175  layer_tree().Preroll(frame());
176  EXPECT_EQ(mock_layer1->paint_bounds(), child_path1.getBounds());
177  EXPECT_EQ(mock_layer2->paint_bounds(), child_path2.getBounds());
178  EXPECT_EQ(layer->paint_bounds(), expected_total_bounds);
179  EXPECT_FALSE(mock_layer1->is_empty());
180  EXPECT_FALSE(mock_layer2->is_empty());
181  EXPECT_FALSE(layer->is_empty());
182  EXPECT_EQ(mock_layer1->parent_matrix(), root_transform());
183  EXPECT_EQ(mock_layer2->parent_matrix(), root_transform());
184  EXPECT_EQ(mock_layer1->parent_cull_rect(), kGiantRect);
185  EXPECT_EQ(mock_layer2->parent_cull_rect(), kGiantRect);
186 
187  layer_tree().Paint(frame());
188  EXPECT_EQ(
189  mock_canvas().draw_calls(),
190  std::vector({MockCanvas::DrawCall{
191  0, MockCanvas::DrawPathData{child_path1, child_paint1}},
193  child_path2, child_paint2}}}));
194 }
195 
196 } // namespace testing
197 } // namespace flutter
void set_root_layer(std::shared_ptr< Layer > root_layer)
Definition: layer_tree.h:41
Definition: ascii_trie.cc:9
static constexpr SkRect kGiantRect
Definition: layer.h:37
bool Preroll(CompositorContext::ScopedFrame &frame, bool ignore_raster_cache=false)
Definition: layer_tree.cc:25
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:57
static constexpr SkRect kEmptyRect
Definition: mock_canvas.h:28