Flutter Engine
picture_layer_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 #define FML_USED_ON_EMBEDDER
6 
7 #include "flutter/flow/layers/picture_layer.h"
8 
9 #include "flutter/flow/testing/diff_context_test.h"
10 #include "flutter/flow/testing/skia_gpu_object_layer_test.h"
11 #include "flutter/fml/macros.h"
12 #include "flutter/testing/mock_canvas.h"
13 #include "third_party/skia/include/core/SkPicture.h"
14 
15 #ifndef SUPPORT_FRACTIONAL_TRANSLATION
16 #include "flutter/flow/raster_cache.h"
17 #endif
18 
19 namespace flutter {
20 namespace testing {
21 
23 
24 #ifndef NDEBUG
25 TEST_F(PictureLayerTest, PaintBeforePrerollInvalidPictureDies) {
26  const SkPoint layer_offset = SkPoint::Make(0.0f, 0.0f);
27  auto layer = std::make_shared<PictureLayer>(
28  layer_offset, SkiaGPUObject<SkPicture>(), false, false);
29 
30  EXPECT_DEATH_IF_SUPPORTED(layer->Paint(paint_context()),
31  "picture_\\.skia_object\\(\\)");
32 }
33 
34 TEST_F(PictureLayerTest, PaintBeforePrerollDies) {
35  const SkPoint layer_offset = SkPoint::Make(0.0f, 0.0f);
36  const SkRect picture_bounds = SkRect::MakeLTRB(5.0f, 6.0f, 20.5f, 21.5f);
37  auto mock_picture = SkPicture::MakePlaceholder(picture_bounds);
38  auto layer = std::make_shared<PictureLayer>(
39  layer_offset, SkiaGPUObject(mock_picture, unref_queue()), false, false);
40 
41  EXPECT_EQ(layer->paint_bounds(), SkRect::MakeEmpty());
42  EXPECT_DEATH_IF_SUPPORTED(layer->Paint(paint_context()),
43  "needs_painting\\(context\\)");
44 }
45 
46 TEST_F(PictureLayerTest, PaintingEmptyLayerDies) {
47  const SkPoint layer_offset = SkPoint::Make(0.0f, 0.0f);
48  const SkRect picture_bounds = SkRect::MakeEmpty();
49  auto mock_picture = SkPicture::MakePlaceholder(picture_bounds);
50  auto layer = std::make_shared<PictureLayer>(
51  layer_offset, SkiaGPUObject(mock_picture, unref_queue()), false, false);
52 
53  layer->Preroll(preroll_context(), SkMatrix());
54  EXPECT_EQ(layer->paint_bounds(), SkRect::MakeEmpty());
55  EXPECT_FALSE(layer->needs_painting(paint_context()));
56 
57  EXPECT_DEATH_IF_SUPPORTED(layer->Paint(paint_context()),
58  "needs_painting\\(context\\)");
59 }
60 
61 TEST_F(PictureLayerTest, InvalidPictureDies) {
62  const SkPoint layer_offset = SkPoint::Make(0.0f, 0.0f);
63  auto layer = std::make_shared<PictureLayer>(
64  layer_offset, SkiaGPUObject<SkPicture>(), false, false);
65 
66  // Crashes reading a nullptr.
67  EXPECT_DEATH_IF_SUPPORTED(layer->Preroll(preroll_context(), SkMatrix()), "");
68 }
69 #endif
70 
71 TEST_F(PictureLayerTest, SimplePicture) {
72  const SkPoint layer_offset = SkPoint::Make(1.5f, -0.5f);
73  const SkMatrix layer_offset_matrix =
74  SkMatrix::Translate(layer_offset.fX, layer_offset.fY);
75  const SkRect picture_bounds = SkRect::MakeLTRB(5.0f, 6.0f, 20.5f, 21.5f);
76  auto mock_picture = SkPicture::MakePlaceholder(picture_bounds);
77  auto layer = std::make_shared<PictureLayer>(
78  layer_offset, SkiaGPUObject(mock_picture, unref_queue()), false, false);
79 
80  layer->Preroll(preroll_context(), SkMatrix());
81  EXPECT_EQ(layer->paint_bounds(),
82  picture_bounds.makeOffset(layer_offset.fX, layer_offset.fY));
83  EXPECT_EQ(layer->picture(), mock_picture.get());
84  EXPECT_TRUE(layer->needs_painting(paint_context()));
85 
86  layer->Paint(paint_context());
87  auto expected_draw_calls = std::vector(
90  1, MockCanvas::ConcatMatrixData{SkM44(layer_offset_matrix)}},
91 #ifndef SUPPORT_FRACTIONAL_TRANSLATION
94  RasterCache::GetIntegralTransCTM(layer_offset_matrix))}},
95 #endif
97  EXPECT_EQ(mock_canvas().draw_calls(), expected_draw_calls);
98 }
99 
100 #ifdef FLUTTER_ENABLE_DIFF_CONTEXT
101 
102 using PictureLayerDiffTest = DiffContextTest;
103 
104 TEST_F(PictureLayerDiffTest, SimplePicture) {
105  auto picture = CreatePicture(SkRect::MakeLTRB(10, 10, 60, 60), 1);
106 
107  MockLayerTree tree1;
108  tree1.root()->Add(CreatePictureLayer(picture));
109 
110  auto damage = DiffLayerTree(tree1, MockLayerTree());
111  EXPECT_EQ(damage.frame_damage, SkIRect::MakeLTRB(10, 10, 60, 60));
112 
113  MockLayerTree tree2;
114  tree2.root()->Add(CreatePictureLayer(picture));
115 
116  damage = DiffLayerTree(tree2, tree1);
117  EXPECT_TRUE(damage.frame_damage.isEmpty());
118 
119  MockLayerTree tree3;
120  damage = DiffLayerTree(tree3, tree2);
121  EXPECT_EQ(damage.frame_damage, SkIRect::MakeLTRB(10, 10, 60, 60));
122 }
123 
124 TEST_F(PictureLayerDiffTest, FractionalTranslation) {
125  auto picture = CreatePicture(SkRect::MakeLTRB(10, 10, 60, 60), 1);
126 
127  MockLayerTree tree1;
128  tree1.root()->Add(CreatePictureLayer(picture, SkPoint::Make(0.5, 0.5)));
129 
130  auto damage = DiffLayerTree(tree1, MockLayerTree());
131 #ifndef SUPPORT_FRACTIONAL_TRANSLATION
132  EXPECT_EQ(damage.frame_damage, SkIRect::MakeLTRB(11, 11, 61, 61));
133 #else
134  EXPECT_EQ(damage.frame_damage, SkIRect::MakeLTRB(10, 10, 61, 61));
135 #endif
136 }
137 
138 TEST_F(PictureLayerDiffTest, PictureCompare) {
139  MockLayerTree tree1;
140  auto picture1 = CreatePicture(SkRect::MakeLTRB(10, 10, 60, 60), 1);
141  tree1.root()->Add(CreatePictureLayer(picture1));
142 
143  auto damage = DiffLayerTree(tree1, MockLayerTree());
144  EXPECT_EQ(damage.frame_damage, SkIRect::MakeLTRB(10, 10, 60, 60));
145 
146  MockLayerTree tree2;
147  auto picture2 = CreatePicture(SkRect::MakeLTRB(10, 10, 60, 60), 1);
148  tree2.root()->Add(CreatePictureLayer(picture2));
149 
150  damage = DiffLayerTree(tree2, tree1);
151  EXPECT_TRUE(damage.frame_damage.isEmpty());
152 
153  MockLayerTree tree3;
154  auto picture3 = CreatePicture(SkRect::MakeLTRB(10, 10, 60, 60), 1);
155  // add offset
156  tree3.root()->Add(CreatePictureLayer(picture3, SkPoint::Make(10, 10)));
157 
158  damage = DiffLayerTree(tree3, tree2);
159  EXPECT_EQ(damage.frame_damage, SkIRect::MakeLTRB(10, 10, 70, 70));
160 
161  MockLayerTree tree4;
162  // different color
163  auto picture4 = CreatePicture(SkRect::MakeLTRB(10, 10, 60, 60), 2);
164  tree4.root()->Add(CreatePictureLayer(picture4, SkPoint::Make(10, 10)));
165 
166  damage = DiffLayerTree(tree4, tree3);
167  EXPECT_EQ(damage.frame_damage, SkIRect::MakeLTRB(20, 20, 70, 70));
168 }
169 
170 #endif
171 
172 } // namespace testing
173 } // namespace flutter
TEST_F(BackdropFilterLayerTest, PaintingEmptyLayerDies)
static SkMatrix GetIntegralTransCTM(const SkMatrix &ctm)
Snap the translation components of the matrix to integers.
Definition: raster_cache.h:122