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#ifndef FLUTTER_DISPLAY_LIST_TESTING_DL_TEST_SNIPPETS_H_
6#define FLUTTER_DISPLAY_LIST_TESTING_DL_TEST_SNIPPETS_H_
7
8#include "flutter/display_list/display_list.h"
9#include "flutter/display_list/dl_builder.h"
10
11#include "third_party/skia/include/core/SkCanvas.h"
12#include "third_party/skia/include/core/SkSurface.h"
13#include "third_party/skia/include/effects/SkDashPathEffect.h"
14#include "third_party/skia/include/effects/SkGradientShader.h"
15#include "third_party/skia/include/effects/SkImageFilters.h"
16
17namespace flutter {
18namespace testing {
19
20sk_sp<DisplayList> GetSampleDisplayList();
21sk_sp<DisplayList> GetSampleDisplayList(int ops);
22sk_sp<DisplayList> GetSampleNestedDisplayList();
23
24typedef const std::function<void(DlOpReceiver&)> DlInvoker;
25
26constexpr SkPoint kEndPoints[] = {
27 {.fX: 0, .fY: 0},
28 {.fX: 100, .fY: 100},
29};
30const DlColor kColors[] = {
31 DlColor::kGreen(),
32 DlColor::kYellow(),
33 DlColor::kBlue(),
34};
35constexpr float kStops[] = {
36 0.0,
37 0.5,
38 1.0,
39};
40static std::vector<uint32_t> color_vector(kColors, kColors + 3);
41static std::vector<float> stops_vector(kStops, kStops + 3);
42
43// clang-format off
44constexpr float kRotateColorMatrix[20] = {
45 0, 1, 0, 0, 0,
46 0, 0, 1, 0, 0,
47 1, 0, 0, 0, 0,
48 0, 0, 0, 1, 0,
49};
50constexpr float kInvertColorMatrix[20] = {
51 -1.0, 0, 0, 1.0, 0,
52 0, -1.0, 0, 1.0, 0,
53 0, 0, -1.0, 1.0, 0,
54 1.0, 1.0, 1.0, 1.0, 0,
55};
56// clang-format on
57
58const SkScalar kTestDashes1[] = {4.0, 2.0};
59const SkScalar kTestDashes2[] = {1.0, 1.5};
60
61constexpr SkPoint TestPoints[] = {
62 {.fX: 10, .fY: 10},
63 {.fX: 20, .fY: 20},
64 {.fX: 10, .fY: 20},
65 {.fX: 20, .fY: 10},
66};
67#define TestPointCount sizeof(TestPoints) / (sizeof(TestPoints[0]))
68
69static DlImageSampling kNearestSampling = DlImageSampling::kNearestNeighbor;
70static DlImageSampling kLinearSampling = DlImageSampling::kLinear;
71
72static sk_sp<DlImage> MakeTestImage(int w, int h, int checker_size) {
73 sk_sp<SkSurface> surface =
74 SkSurfaces::Raster(imageInfo: SkImageInfo::MakeN32Premul(width: w, height: h));
75 SkCanvas* canvas = surface->getCanvas();
76 SkPaint p0, p1;
77 p0.setStyle(SkPaint::kFill_Style);
78 p0.setColor(SK_ColorGREEN);
79 p1.setStyle(SkPaint::kFill_Style);
80 p1.setColor(SK_ColorBLUE);
81 p1.setAlpha(128);
82 for (int y = 0; y < w; y += checker_size) {
83 for (int x = 0; x < h; x += checker_size) {
84 SkPaint& cellp = ((x + y) & 1) == 0 ? p0 : p1;
85 canvas->drawRect(rect: SkRect::MakeXYWH(x, y, w: checker_size, h: checker_size),
86 paint: cellp);
87 }
88 }
89 return DlImage::Make(image: surface->makeImageSnapshot());
90}
91
92static auto TestImage1 = MakeTestImage(w: 40, h: 40, checker_size: 5);
93static auto TestImage2 = MakeTestImage(w: 50, h: 50, checker_size: 5);
94static auto TestSkImage = MakeTestImage(w: 30, h: 30, checker_size: 5)->skia_image();
95
96static const DlImageColorSource kTestSource1(TestImage1,
97 DlTileMode::kClamp,
98 DlTileMode::kMirror,
99 kLinearSampling);
100static const std::shared_ptr<DlColorSource> kTestSource2 =
101 DlColorSource::MakeLinear(start_point: kEndPoints[0],
102 end_point: kEndPoints[1],
103 stop_count: 3,
104 colors: kColors,
105 stops: kStops,
106 tile_mode: DlTileMode::kMirror);
107static const std::shared_ptr<DlColorSource> kTestSource3 =
108 DlColorSource::MakeRadial(center: kEndPoints[0],
109 radius: 10.0,
110 stop_count: 3,
111 colors: kColors,
112 stops: kStops,
113 tile_mode: DlTileMode::kMirror);
114static const std::shared_ptr<DlColorSource> kTestSource4 =
115 DlColorSource::MakeConical(start_center: kEndPoints[0],
116 start_radius: 10.0,
117 end_center: kEndPoints[1],
118 end_radius: 200.0,
119 stop_count: 3,
120 colors: kColors,
121 stops: kStops,
122 tile_mode: DlTileMode::kDecal);
123static const std::shared_ptr<DlColorSource> kTestSource5 =
124 DlColorSource::MakeSweep(center: kEndPoints[0],
125 start: 0.0,
126 end: 360.0,
127 stop_count: 3,
128 colors: kColors,
129 stops: kStops,
130 tile_mode: DlTileMode::kDecal);
131static const DlBlendColorFilter kTestBlendColorFilter1(DlColor::kRed(),
132 DlBlendMode::kDstATop);
133static const DlBlendColorFilter kTestBlendColorFilter2(DlColor::kBlue(),
134 DlBlendMode::kDstATop);
135static const DlBlendColorFilter kTestBlendColorFilter3(DlColor::kRed(),
136 DlBlendMode::kDstIn);
137static const DlMatrixColorFilter kTestMatrixColorFilter1(kRotateColorMatrix);
138static const DlMatrixColorFilter kTestMatrixColorFilter2(kInvertColorMatrix);
139static const DlBlurImageFilter kTestBlurImageFilter1(5.0,
140 5.0,
141 DlTileMode::kClamp);
142static const DlBlurImageFilter kTestBlurImageFilter2(6.0,
143 5.0,
144 DlTileMode::kClamp);
145static const DlBlurImageFilter kTestBlurImageFilter3(5.0,
146 6.0,
147 DlTileMode::kClamp);
148static const DlBlurImageFilter kTestBlurImageFilter4(5.0,
149 5.0,
150 DlTileMode::kDecal);
151static const DlDilateImageFilter kTestDilateImageFilter1(5.0, 5.0);
152static const DlDilateImageFilter kTestDilateImageFilter2(6.0, 5.0);
153static const DlDilateImageFilter kTestDilateImageFilter3(5.0, 6.0);
154static const DlErodeImageFilter kTestErodeImageFilter1(4.0, 4.0);
155static const DlErodeImageFilter kTestErodeImageFilter2(4.0, 3.0);
156static const DlErodeImageFilter kTestErodeImageFilter3(3.0, 4.0);
157static const DlMatrixImageFilter kTestMatrixImageFilter1(
158 SkMatrix::RotateDeg(deg: 45),
159 kNearestSampling);
160static const DlMatrixImageFilter kTestMatrixImageFilter2(
161 SkMatrix::RotateDeg(deg: 85),
162 kNearestSampling);
163static const DlMatrixImageFilter kTestMatrixImageFilter3(
164 SkMatrix::RotateDeg(deg: 45),
165 kLinearSampling);
166static const DlComposeImageFilter kTestComposeImageFilter1(
167 kTestBlurImageFilter1,
168 kTestMatrixImageFilter1);
169static const DlComposeImageFilter kTestComposeImageFilter2(
170 kTestBlurImageFilter2,
171 kTestMatrixImageFilter1);
172static const DlComposeImageFilter kTestComposeImageFilter3(
173 kTestBlurImageFilter1,
174 kTestMatrixImageFilter2);
175static const DlColorFilterImageFilter kTestCFImageFilter1(
176 kTestBlendColorFilter1);
177static const DlColorFilterImageFilter kTestCFImageFilter2(
178 kTestBlendColorFilter2);
179static const std::shared_ptr<DlPathEffect> kTestPathEffect1 =
180 DlDashPathEffect::Make(intervals: kTestDashes1, count: 2, phase: 0.0f);
181static const std::shared_ptr<DlPathEffect> kTestPathEffect2 =
182 DlDashPathEffect::Make(intervals: kTestDashes2, count: 2, phase: 0.0f);
183static const DlBlurMaskFilter kTestMaskFilter1(DlBlurStyle::kNormal, 3.0);
184static const DlBlurMaskFilter kTestMaskFilter2(DlBlurStyle::kNormal, 5.0);
185static const DlBlurMaskFilter kTestMaskFilter3(DlBlurStyle::kSolid, 3.0);
186static const DlBlurMaskFilter kTestMaskFilter4(DlBlurStyle::kInner, 3.0);
187static const DlBlurMaskFilter kTestMaskFilter5(DlBlurStyle::kOuter, 3.0);
188constexpr SkRect kTestBounds = SkRect::MakeLTRB(l: 10, t: 10, r: 50, b: 60);
189static const SkRRect kTestRRect = SkRRect::MakeRectXY(rect: kTestBounds, xRad: 5, yRad: 5);
190static const SkRRect kTestRRectRect = SkRRect::MakeRect(r: kTestBounds);
191static const SkRRect kTestInnerRRect =
192 SkRRect::MakeRectXY(rect: kTestBounds.makeInset(dx: 5, dy: 5), xRad: 2, yRad: 2);
193static const SkPath kTestPathRect = SkPath::Rect(kTestBounds);
194static const SkPath kTestPathOval = SkPath::Oval(kTestBounds);
195static const SkPath kTestPath1 =
196 SkPath::Polygon(list: {{.fX: 0, .fY: 0}, {.fX: 10, .fY: 10}, {.fX: 10, .fY: 0}, {.fX: 0, .fY: 10}}, isClosed: true);
197static const SkPath kTestPath2 =
198 SkPath::Polygon(list: {{.fX: 0, .fY: 0}, {.fX: 10, .fY: 10}, {.fX: 0, .fY: 10}, {.fX: 10, .fY: 0}}, isClosed: true);
199static const SkPath kTestPath3 =
200 SkPath::Polygon(list: {{.fX: 0, .fY: 0}, {.fX: 10, .fY: 10}, {.fX: 10, .fY: 0}, {.fX: 0, .fY: 10}}, isClosed: false);
201static const SkMatrix kTestMatrix1 = SkMatrix::Scale(sx: 2, sy: 2);
202static const SkMatrix kTestMatrix2 = SkMatrix::RotateDeg(deg: 45);
203
204static std::shared_ptr<const DlVertices> TestVertices1 =
205 DlVertices::Make(mode: DlVertexMode::kTriangles, //
206 vertex_count: 3,
207 vertices: TestPoints,
208 texture_coordinates: nullptr,
209 colors: kColors);
210static std::shared_ptr<const DlVertices> TestVertices2 =
211 DlVertices::Make(mode: DlVertexMode::kTriangleFan, //
212 vertex_count: 3,
213 vertices: TestPoints,
214 texture_coordinates: nullptr,
215 colors: kColors);
216
217static sk_sp<DisplayList> MakeTestDisplayList(int w, int h, SkColor color) {
218 DisplayListBuilder builder;
219 builder.DrawRect(rect: SkRect::MakeWH(w, h), paint: DlPaint(color));
220 return builder.Build();
221}
222static sk_sp<DisplayList> TestDisplayList1 =
223 MakeTestDisplayList(w: 20, h: 20, color: SK_ColorGREEN);
224static sk_sp<DisplayList> TestDisplayList2 =
225 MakeTestDisplayList(w: 25, h: 25, color: SK_ColorBLUE);
226
227static sk_sp<SkTextBlob> MakeTextBlob(std::string string) {
228 return SkTextBlob::MakeFromText(text: string.c_str(), byteLength: string.size(), font: SkFont(),
229 encoding: SkTextEncoding::kUTF8);
230}
231static sk_sp<SkTextBlob> TestBlob1 = MakeTextBlob(string: "TestBlob1");
232static sk_sp<SkTextBlob> TestBlob2 = MakeTextBlob(string: "TestBlob2");
233
234struct DisplayListInvocation {
235 unsigned int op_count_;
236 size_t byte_count_;
237
238 // in some cases, running the sequence through an SkCanvas will result
239 // in fewer ops/bytes. Attribute invocations are recorded in an SkPaint
240 // and not forwarded on, and SkCanvas culls unused save/restore/transforms.
241 int sk_op_count_;
242 size_t sk_byte_count_;
243
244 DlInvoker invoker;
245 bool supports_group_opacity_ = false;
246
247 bool is_empty() { return byte_count_ == 0; }
248
249 bool supports_group_opacity() { return supports_group_opacity_; }
250
251 unsigned int op_count() { return op_count_; }
252 // byte count for the individual ops, no DisplayList overhead
253 size_t raw_byte_count() { return byte_count_; }
254 // byte count for the ops with DisplayList overhead, comparable
255 // to |DisplayList.byte_count().
256 size_t byte_count() { return sizeof(DisplayList) + byte_count_; }
257
258 void Invoke(DlOpReceiver& builder) { invoker(builder); }
259
260 // sk_sp<DisplayList> Build() {
261 // DisplayListBuilder builder;
262 // invoker(builder.asReceiver());
263 // return builder.Build();
264 // }
265};
266
267struct DisplayListInvocationGroup {
268 std::string op_name;
269 std::vector<DisplayListInvocation> variants;
270};
271
272std::vector<DisplayListInvocationGroup> CreateAllRenderingOps();
273std::vector<DisplayListInvocationGroup> CreateAllGroups();
274
275} // namespace testing
276} // namespace flutter
277
278#endif // FLUTTER_DISPLAY_LIST_TESTING_DL_TEST_SNIPPETS_H_
279

source code of flutter_engine/flutter/display_list/testing/dl_test_snippets.h