Flutter Engine
 
Loading...
Searching...
No Matches
dl_complexity_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
15
16namespace flutter {
17namespace testing {
18
19namespace {
20
21std::vector<DisplayListComplexityCalculator*> Calculators() {
25}
26
27std::vector<DisplayListComplexityCalculator*> AccumulatorCalculators() {
30}
31
32std::vector<DlPoint> GetTestPoints() {
33 std::vector<DlPoint> points;
34 points.emplace_back(0, 0);
35 points.emplace_back(10, 0);
36 points.emplace_back(10, 10);
37 points.emplace_back(20, 10);
38 points.emplace_back(20, 20);
39
40 return points;
41}
42
43} // namespace
44
45TEST(DisplayListComplexity, EmptyDisplayList) {
46 auto display_list = GetSampleDisplayList(0);
47
48 auto calculators = Calculators();
49 for (auto calculator : calculators) {
50 ASSERT_EQ(calculator->Compute(display_list.get()), 0u);
51 }
52}
53
54TEST(DisplayListComplexity, DisplayListCeiling) {
55 auto display_list = GetSampleDisplayList();
56
57 auto calculators = AccumulatorCalculators();
58 for (auto calculator : calculators) {
59 calculator->SetComplexityCeiling(10u);
60 ASSERT_EQ(calculator->Compute(display_list.get()), 10u);
61 calculator->SetComplexityCeiling(std::numeric_limits<unsigned int>::max());
62 }
63}
64
65TEST(DisplayListComplexity, NestedDisplayList) {
66 auto display_list = GetSampleNestedDisplayList();
67
68 auto calculators = Calculators();
69 for (auto calculator : calculators) {
70 // There's only one draw call in the "outer" DisplayList, which calls
71 // drawDisplayList with the "inner" DisplayList. To ensure we are
72 // recursing correctly into the inner DisplayList, check that we aren't
73 // returning 0 (if the function is a no-op) or 1 (as the op_count is 1)
74 ASSERT_GT(calculator->Compute(display_list.get()), 1u);
75 }
76}
77
78TEST(DisplayListComplexity, AntiAliasing) {
79 DisplayListBuilder builder_no_aa;
80 builder_no_aa.DrawLine(DlPoint(0, 0), DlPoint(100, 100), DlPaint());
81 auto display_list_no_aa = builder_no_aa.Build();
82
83 DisplayListBuilder builder_aa;
84 builder_aa.DrawLine(DlPoint(0, 0), DlPoint(100, 100),
85 DlPaint().setAntiAlias(true));
86 auto display_list_aa = builder_aa.Build();
87
88 auto calculators = AccumulatorCalculators();
89 for (auto calculator : calculators) {
90 ASSERT_NE(calculator->Compute(display_list_no_aa.get()),
91 calculator->Compute(display_list_aa.get()));
92 }
93}
94
95TEST(DisplayListComplexity, StrokeWidth) {
96 DisplayListBuilder builder_stroke_0;
97 builder_stroke_0.DrawLine(DlPoint(0, 0), DlPoint(100, 100),
98 DlPaint().setStrokeWidth(0.0f));
99 auto display_list_stroke_0 = builder_stroke_0.Build();
100
101 DisplayListBuilder builder_stroke_1;
102 builder_stroke_1.DrawLine(DlPoint(0, 0), DlPoint(100, 100),
103 DlPaint().setStrokeWidth(1.0f));
104 auto display_list_stroke_1 = builder_stroke_1.Build();
105
106 auto calculators = AccumulatorCalculators();
107 for (auto calculator : calculators) {
108 ASSERT_NE(calculator->Compute(display_list_stroke_0.get()),
109 calculator->Compute(display_list_stroke_1.get()));
110 }
111}
112
113TEST(DisplayListComplexity, Style) {
114 DisplayListBuilder builder_filled;
115 builder_filled.DrawRect(DlRect::MakeXYWH(10, 10, 80, 80),
116 DlPaint().setDrawStyle(DlDrawStyle::kFill));
117 auto display_list_filled = builder_filled.Build();
118
119 DisplayListBuilder builder_stroked;
120 builder_stroked.DrawRect(DlRect::MakeXYWH(10, 10, 80, 80),
121 DlPaint().setDrawStyle(DlDrawStyle::kStroke));
122 auto display_list_stroked = builder_stroked.Build();
123
124 auto calculators = AccumulatorCalculators();
125 for (auto calculator : calculators) {
126 ASSERT_NE(calculator->Compute(display_list_filled.get()),
127 calculator->Compute(display_list_stroked.get()));
128 }
129}
130
131TEST(DisplayListComplexity, SaveLayers) {
132 DisplayListBuilder builder;
133 builder.SaveLayer(std::nullopt, nullptr);
134 auto display_list = builder.Build();
135
136 auto calculators = AccumulatorCalculators();
137 for (auto calculator : calculators) {
138 ASSERT_NE(calculator->Compute(display_list.get()), 0u);
139 }
140}
141
142TEST(DisplayListComplexity, DrawPath) {
143 DisplayListBuilder builder_line;
144 DlPathBuilder line_path_builder;
145 line_path_builder.MoveTo(DlPoint(0, 0));
146 line_path_builder.LineTo(DlPoint(10, 10));
147 line_path_builder.Close();
148 builder_line.DrawPath(line_path_builder.TakePath(), DlPaint());
149 auto display_list_line = builder_line.Build();
150
151 DisplayListBuilder builder_quad;
152 DlPathBuilder quad_path_builder;
153 quad_path_builder.MoveTo(DlPoint(0, 0));
154 quad_path_builder.QuadraticCurveTo(DlPoint(10, 10), DlPoint(10, 20));
155 quad_path_builder.Close();
156 builder_quad.DrawPath(quad_path_builder.TakePath(), DlPaint());
157 auto display_list_quad = builder_quad.Build();
158
159 DisplayListBuilder builder_conic;
160 DlPathBuilder conic_path_builder;
161 conic_path_builder.MoveTo(DlPoint(0, 0));
162 conic_path_builder.ConicCurveTo(DlPoint(10, 10), DlPoint(10, 20), 1.5f);
163 conic_path_builder.Close();
164 builder_conic.DrawPath(conic_path_builder.TakePath(), DlPaint());
165 auto display_list_conic = builder_conic.Build();
166
167 DisplayListBuilder builder_cubic;
168 DlPathBuilder cubic_path_builder;
169 cubic_path_builder.MoveTo(DlPoint(0, 0));
170 cubic_path_builder.CubicCurveTo(DlPoint(10, 10), DlPoint(10, 20),
171 DlPoint(20, 20));
172 builder_cubic.DrawPath(cubic_path_builder.TakePath(), DlPaint());
173 auto display_list_cubic = builder_cubic.Build();
174
175 auto calculators = AccumulatorCalculators();
176 for (auto calculator : calculators) {
177 ASSERT_NE(calculator->Compute(display_list_line.get()), 0u);
178 ASSERT_NE(calculator->Compute(display_list_quad.get()), 0u);
179 ASSERT_NE(calculator->Compute(display_list_conic.get()), 0u);
180 ASSERT_NE(calculator->Compute(display_list_cubic.get()), 0u);
181 }
182}
183
184TEST(DisplayListComplexity, DrawShadow) {
185 DisplayListBuilder builder_line;
186 DlPathBuilder line_path_builder;
187 line_path_builder.MoveTo(DlPoint(0, 0));
188 line_path_builder.LineTo(DlPoint(10, 10));
189 line_path_builder.Close();
190 builder_line.DrawShadow(line_path_builder.TakePath(), DlColor(SK_ColorRED),
191 10.0f, false, 1.0f);
192 auto display_list_line = builder_line.Build();
193
194 DisplayListBuilder builder_quad;
195 DlPathBuilder quad_path_builder;
196 quad_path_builder.MoveTo(DlPoint(0, 0));
197 quad_path_builder.QuadraticCurveTo(DlPoint(10, 10), DlPoint(10, 20));
198 quad_path_builder.Close();
199 builder_quad.DrawShadow(quad_path_builder.TakePath(), DlColor(SK_ColorRED),
200 10.0f, false, 1.0f);
201 auto display_list_quad = builder_quad.Build();
202
203 DisplayListBuilder builder_conic;
204 DlPathBuilder conic_path_builder;
205 conic_path_builder.MoveTo(DlPoint(0, 0));
206 conic_path_builder.ConicCurveTo(DlPoint(10, 10), DlPoint(10, 20), 1.5f);
207 conic_path_builder.Close();
208 builder_conic.DrawShadow(conic_path_builder.TakePath(), DlColor(SK_ColorRED),
209 10.0f, false, 1.0f);
210 auto display_list_conic = builder_conic.Build();
211
212 DisplayListBuilder builder_cubic;
213 DlPathBuilder cubic_path_builder;
214 cubic_path_builder.MoveTo(DlPoint(0, 0));
215 cubic_path_builder.CubicCurveTo(DlPoint(10, 10), DlPoint(10, 20),
216 DlPoint(20, 20));
217 builder_cubic.DrawShadow(cubic_path_builder.TakePath(), DlColor(SK_ColorRED),
218 10.0f, false, 1.0f);
219 auto display_list_cubic = builder_cubic.Build();
220
221 auto calculators = AccumulatorCalculators();
222 for (auto calculator : calculators) {
223 ASSERT_NE(calculator->Compute(display_list_line.get()), 0u);
224 ASSERT_NE(calculator->Compute(display_list_quad.get()), 0u);
225 ASSERT_NE(calculator->Compute(display_list_conic.get()), 0u);
226 ASSERT_NE(calculator->Compute(display_list_cubic.get()), 0u);
227 }
228}
229
230TEST(DisplayListComplexity, DrawOval) {
231 DisplayListBuilder builder;
232 builder.DrawOval(DlRect::MakeXYWH(10, 10, 100, 80), DlPaint());
233 auto display_list = builder.Build();
234
235 auto calculators = AccumulatorCalculators();
236 for (auto calculator : calculators) {
237 ASSERT_NE(calculator->Compute(display_list.get()), 0u);
238 }
239}
240
241TEST(DisplayListComplexity, DrawCircle) {
242 DisplayListBuilder builder;
243 builder.DrawCircle(DlPoint(50, 50), 10.0f, DlPaint());
244 auto display_list = builder.Build();
245
246 auto calculators = AccumulatorCalculators();
247 for (auto calculator : calculators) {
248 ASSERT_NE(calculator->Compute(display_list.get()), 0u);
249 }
250}
251
252TEST(DisplayListComplexity, DrawRoundRect) {
253 DisplayListBuilder builder;
254 builder.DrawRoundRect(
255 DlRoundRect::MakeRectXY(DlRect::MakeXYWH(10, 10, 80, 80), 2.0f, 3.0f),
256 DlPaint());
257 auto display_list = builder.Build();
258
259 auto calculators = AccumulatorCalculators();
260 for (auto calculator : calculators) {
261 ASSERT_NE(calculator->Compute(display_list.get()), 0u);
262 }
263}
264
265TEST(DisplayListComplexity, DrawDiffRoundRect) {
266 DisplayListBuilder builder;
267 DlRoundRect outer =
268 DlRoundRect::MakeRectXY(DlRect::MakeXYWH(10, 10, 80, 80), 2.0f, 3.0f);
269 DlRoundRect inner =
270 DlRoundRect::MakeRectXY(DlRect::MakeXYWH(15, 15, 70, 70), 1.5f, 1.5f);
271 builder.DrawDiffRoundRect(outer, inner, DlPaint());
272 auto display_list = builder.Build();
273
274 auto calculators = AccumulatorCalculators();
275 for (auto calculator : calculators) {
276 ASSERT_NE(calculator->Compute(display_list.get()), 0u);
277 }
278}
279
280TEST(DisplayListComplexity, DrawArc) {
281 DisplayListBuilder builder;
282 builder.DrawArc(DlRect::MakeXYWH(10, 10, 100, 80), 0.0f, 10.0f, true,
283 DlPaint());
284 auto display_list = builder.Build();
285
286 auto calculators = AccumulatorCalculators();
287 for (auto calculator : calculators) {
288 ASSERT_NE(calculator->Compute(display_list.get()), 0u);
289 }
290}
291
292TEST(DisplayListComplexity, DrawVertices) {
293 auto points = GetTestPoints();
294 auto vertices = DlVertices::Make(DlVertexMode::kTriangles, points.size(),
295 points.data(), nullptr, nullptr);
296 DisplayListBuilder builder;
297 builder.DrawVertices(vertices, DlBlendMode::kSrc, DlPaint());
298 auto display_list = builder.Build();
299
300 auto calculators = AccumulatorCalculators();
301 for (auto calculator : calculators) {
302 ASSERT_NE(calculator->Compute(display_list.get()), 0u);
303 }
304}
305
306TEST(DisplayListComplexity, DrawTextBlob) {
307 auto text_blob =
308 GetTestTextBlob("The quick brown fox jumps over the lazy dog.", 20.0f);
309 auto text = DlTextSkia::Make(text_blob);
310 DisplayListBuilder builder;
311 builder.DrawText(text, 0.0f, 0.0f, DlPaint());
312 auto display_list = builder.Build();
313
314 DisplayListBuilder builder_multiple;
315 builder_multiple.DrawText(text, 0.0f, 0.0f, DlPaint());
316 builder_multiple.DrawText(text, 0.0f, 0.0f, DlPaint());
317 auto display_list_multiple = builder_multiple.Build();
318
319 auto calculators = AccumulatorCalculators();
320 for (auto calculator : calculators) {
321 ASSERT_NE(calculator->Compute(display_list.get()), 0u);
322 ASSERT_GT(calculator->Compute(display_list_multiple.get()),
323 calculator->Compute(display_list.get()));
324 }
325}
326
327TEST(DisplayListComplexity, DrawPoints) {
328 auto points = GetTestPoints();
329 DisplayListBuilder builder_lines;
330 builder_lines.DrawPoints(DlPointMode::kLines, points.size(), points.data(),
331 DlPaint());
332 auto display_list_lines = builder_lines.Build();
333
334 DisplayListBuilder builder_points;
335 builder_points.DrawPoints(DlPointMode::kPoints, points.size(), points.data(),
336 DlPaint());
337 auto display_list_points = builder_points.Build();
338
339 DisplayListBuilder builder_polygon;
340 builder_polygon.DrawPoints(DlPointMode::kPolygon, points.size(),
341 points.data(), DlPaint());
342 auto display_list_polygon = builder_polygon.Build();
343
344 auto calculators = AccumulatorCalculators();
345 for (auto calculator : calculators) {
346 ASSERT_NE(calculator->Compute(display_list_lines.get()), 0u);
347 ASSERT_NE(calculator->Compute(display_list_points.get()), 0u);
348 ASSERT_NE(calculator->Compute(display_list_polygon.get()), 0u);
349 }
350}
351
352TEST(DisplayListComplexity, DrawImage) {
353 auto image = MakeTestImage(50, 50, DlColor::kBlue().withAlphaF(0.5));
354
355 DisplayListBuilder builder;
357 nullptr);
358 auto display_list = builder.Build();
359
360 auto calculators = AccumulatorCalculators();
361 for (auto calculator : calculators) {
362 ASSERT_NE(calculator->Compute(display_list.get()), 0u);
363 }
364}
365
366TEST(DisplayListComplexity, DrawImageNine) {
367 auto image = MakeTestImage(50, 50, DlColor::kBlue().withAlphaF(0.5));
368
369 DlIRect center = DlIRect::MakeXYWH(5, 5, 20, 20);
370 DlRect dest = DlRect::MakeXYWH(0, 0, 50, 50);
371
372 DisplayListBuilder builder;
373 builder.DrawImageNine(image, center, dest, DlFilterMode::kNearest, nullptr);
374 auto display_list = builder.Build();
375
376 auto calculators = AccumulatorCalculators();
377 for (auto calculator : calculators) {
378 ASSERT_NE(calculator->Compute(display_list.get()), 0u);
379 }
380}
381
382TEST(DisplayListComplexity, DrawImageRect) {
383 auto image = MakeTestImage(50, 50, DlColor::kBlue().withAlphaF(0.5));
384
385 DlRect src = DlRect::MakeXYWH(0, 0, 50, 50);
386 DlRect dest = DlRect::MakeXYWH(0, 0, 50, 50);
387
388 DisplayListBuilder builder;
390 nullptr);
391 auto display_list = builder.Build();
392
393 auto calculators = AccumulatorCalculators();
394 for (auto calculator : calculators) {
395 ASSERT_NE(calculator->Compute(display_list.get()), 0u);
396 }
397}
398
399TEST(DisplayListComplexity, DrawAtlas) {
400 auto image = MakeTestImage(50, 50, DlColor::kBlue().withAlphaF(0.5));
401
402 std::vector<DlRect> rects;
403 std::vector<DlRSTransform> xforms;
404 for (int i = 0; i < 10; i++) {
405 rects.push_back(DlRect::MakeXYWH(0, 0, 10, 10));
406 xforms.push_back(DlRSTransform(1, 0, 0, 0));
407 }
408
409 DisplayListBuilder builder;
410 builder.DrawAtlas(image, xforms.data(), rects.data(), nullptr, 10,
411 DlBlendMode::kSrc, DlImageSampling::kNearestNeighbor,
412 nullptr, nullptr);
413 auto display_list = builder.Build();
414
415 auto calculators = AccumulatorCalculators();
416 for (auto calculator : calculators) {
417 ASSERT_NE(calculator->Compute(display_list.get()), 0u);
418 }
419}
420
421} // namespace testing
422} // namespace flutter
void DrawOval(const DlRect &bounds, const DlPaint &paint) override
void DrawImageRect(const sk_sp< DlImage > &image, const DlRect &src, const DlRect &dst, DlImageSampling sampling, const DlPaint *paint=nullptr, DlSrcRectConstraint constraint=DlSrcRectConstraint::kFast) override
void DrawVertices(const std::shared_ptr< DlVertices > &vertices, DlBlendMode mode, const DlPaint &paint) override
void DrawImageNine(const sk_sp< DlImage > &image, const DlIRect &center, const DlRect &dst, DlFilterMode filter, const DlPaint *paint=nullptr) override
void DrawAtlas(const sk_sp< DlImage > &atlas, const DlRSTransform xform[], const DlRect tex[], const DlColor colors[], int count, DlBlendMode mode, DlImageSampling sampling, const DlRect *cullRect, const DlPaint *paint=nullptr) override
void DrawRoundRect(const DlRoundRect &rrect, const DlPaint &paint) override
void DrawArc(const DlRect &bounds, DlScalar start, DlScalar sweep, bool useCenter, const DlPaint &paint) override
void DrawShadow(const DlPath &path, const DlColor color, const DlScalar elevation, bool transparent_occluder, DlScalar dpr) override
Draws the shadow of the given |path| rendered in the provided |color| (which is only consulted for it...
void DrawImage(const sk_sp< DlImage > &image, const DlPoint &point, DlImageSampling sampling, const DlPaint *paint=nullptr) override
void DrawCircle(const DlPoint &center, DlScalar radius, const DlPaint &paint) override
void SaveLayer(const std::optional< DlRect > &bounds, const DlPaint *paint=nullptr, const DlImageFilter *backdrop=nullptr, std::optional< int64_t > backdrop_id=std::nullopt) override
void DrawLine(const DlPoint &p0, const DlPoint &p1, const DlPaint &paint) override
void DrawText(const std::shared_ptr< DlText > &text, DlScalar x, DlScalar y, const DlPaint &paint) override
sk_sp< DisplayList > Build()
Definition dl_builder.cc:66
void DrawPath(const DlPath &path, const DlPaint &paint) override
void DrawPoints(DlPointMode mode, uint32_t count, const DlPoint pts[], const DlPaint &paint) override
void DrawDiffRoundRect(const DlRoundRect &outer, const DlRoundRect &inner, const DlPaint &paint) override
void DrawRect(const DlRect &rect, const DlPaint &paint) override
static DisplayListGLComplexityCalculator * GetInstance()
static DisplayListMetalComplexityCalculator * GetInstance()
static DisplayListComplexityCalculator * GetInstance()
DlPathBuilder & LineTo(DlPoint p2)
Draw a line from the current point to the indicated point p2.
DlPathBuilder & MoveTo(DlPoint p2)
Start a new contour that will originate at the indicated point p2.
const DlPath TakePath()
Returns the path constructed by this path builder and resets its internal state to the default state ...
DlPathBuilder & ConicCurveTo(DlPoint cp, DlPoint p2, DlScalar weight)
Draw a conic curve (a rational quadratic bezier curve) from the current point to the indicated point ...
DlPathBuilder & QuadraticCurveTo(DlPoint cp, DlPoint p2)
Draw a quadratic bezier curve from the current point to the indicated point p2, using the indicated p...
DlPathBuilder & Close()
The path is closed back to the location of the most recent MoveTo call. Contours that are filled are ...
DlPathBuilder & CubicCurveTo(DlPoint cp1, DlPoint cp2, DlPoint p2)
Draw a cubic bezier curve from the current point to the indicated point p2, using the indicated point...
static std::shared_ptr< DlTextSkia > Make(const sk_sp< SkTextBlob > &blob)
static std::shared_ptr< DlVertices > Make(DlVertexMode mode, int vertex_count, const DlPoint vertices[], const DlPoint texture_coordinates[], const DlColor colors[], int index_count=0, const uint16_t indices[]=nullptr, const DlRect *bounds=nullptr)
Constructs a DlVector with compact inline storage for all of its required and optional lists of data.
FlutterVulkanImage * image
std::u16string text
sk_sp< DlImage > MakeTestImage(int w, int h, int checker_size)
sk_sp< DisplayList > GetSampleDisplayList()
std::vector< DlPoint > GetTestPoints(size_t count, DlISize canvas_size)
TEST(NativeAssetsManagerTest, NoAvailableAssets)
sk_sp< DisplayList > GetSampleNestedDisplayList()
sk_sp< SkTextBlob > GetTestTextBlob(int index)
impeller::RSTransform DlRSTransform
@ kLines
draw each separate pair of points as a line segment
@ kPolygon
draw each pair of overlapping points as a line segment
@ kPoints
draw each point separately
@ kTriangles
The vertices are taken 3 at a time to form a triangle.
@ kStroke
strokes boundary of shapes
@ kFill
fills interior of shapes
impeller::Point DlPoint
static constexpr DlColor kBlue()
Definition dl_color.h:73
static RoundRect MakeRectXY(const Rect &rect, Scalar x_radius, Scalar y_radius)
Definition round_rect.h:31
static constexpr TRect MakeXYWH(Type x, Type y, Type width, Type height)
Definition rect.h:136
std::vector< Point > points