| Flutter Impeller |

aiks_dl_gradient_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 "display_list/display_list.h"
6 #include "display_list/dl_blend_mode.h"
7 #include "display_list/dl_tile_mode.h"
8 #include "display_list/effects/dl_color_filter.h"
9 #include "display_list/effects/dl_color_source.h"
10 #include "display_list/effects/dl_mask_filter.h"
11 #include "flutter/impeller/display_list/aiks_unittests.h"
12
13 #include "flutter/display_list/dl_builder.h"
14 #include "flutter/display_list/dl_color.h"
15 #include "flutter/display_list/dl_paint.h"
16 #include "flutter/testing/testing.h"
17 #include "impeller/playground/widgets.h"
18 #include "include/core/SkPath.h"
19 #include "include/core/SkRRect.h"
20 #include "include/core/SkRect.h"
21
22 using namespace flutter;
23 ////////////////////////////////////////////////////////////////////////////////
24 // This is for tests of Canvas that are interested the results of rendering
25 // gradients.
26 ////////////////////////////////////////////////////////////////////////////////
27
28 namespace impeller {
29 namespace testing {
30
31 namespace {
32
33 /// Test body for linear gradient tile mode tests (ex.
34 /// CanRenderLinearGradientClamp).
35 void CanRenderLinearGradient(AiksTest* aiks_test, DlTileMode tile_mode) {
36 DisplayListBuilder builder;
37 Point scale = aiks_test->GetContentScale();
38 builder.Scale(scale.x, scale.y);
39 DlPaint paint;
40 builder.Translate(100.0f, 0);
41
42 std::vector<DlColor> colors = {
43 DlColor(Color{0.9568, 0.2627, 0.2118, 1.0}.ToARGB()),
44 DlColor(Color{0.1294, 0.5882, 0.9529, 0.0}.ToARGB())};
45 std::vector<Scalar> stops = {0.0, 1.0};
46
47 auto gradient = DlColorSource::MakeLinear(
48 {0, 0}, {200, 200}, 2, colors.data(), stops.data(), tile_mode);
49 paint.setColorSource(gradient);
50 paint.setColor(DlColor::kWhite());
51 builder.DrawRect(SkRect::MakeXYWH(0, 0, 600, 600), paint);
52 ASSERT_TRUE(aiks_test->OpenPlaygroundHere(builder.Build()));
53 }
54
55 Matrix ToMatrix(const SkMatrix& m) {
56 return Matrix{
57 // clang-format off
58 m[0], m[3], 0, m[6],
59 m[1], m[4], 0, m[7],
60 0, 0, 1, 0,
61 m[2], m[5], 0, m[8],
62 // clang-format on
63 };
64 }
65 } // namespace
66
67 TEST_P(AiksTest, CanRenderLinearGradientClamp) {
68 CanRenderLinearGradient(this, DlTileMode::kClamp);
69 }
70 TEST_P(AiksTest, CanRenderLinearGradientRepeat) {
71 CanRenderLinearGradient(this, DlTileMode::kRepeat);
72 }
73 TEST_P(AiksTest, CanRenderLinearGradientMirror) {
74 CanRenderLinearGradient(this, DlTileMode::kMirror);
75 }
76 TEST_P(AiksTest, CanRenderLinearGradientDecal) {
77 CanRenderLinearGradient(this, DlTileMode::kDecal);
78 }
79
80 TEST_P(AiksTest, CanRenderLinearGradientDecalWithColorFilter) {
81 DisplayListBuilder builder;
82 Point scale = GetContentScale();
83 builder.Scale(scale.x, scale.y);
84 DlPaint paint;
85 builder.Translate(100.0f, 0);
86
87 std::vector<DlColor> colors = {
88 DlColor(Color{0.9568, 0.2627, 0.2118, 1.0}.ToARGB()),
89 DlColor(Color{0.1294, 0.5882, 0.9529, 0.0}.ToARGB())};
90 std::vector<Scalar> stops = {0.0, 1.0};
91
92 paint.setColorSource(DlColorSource::MakeLinear(
93 {0, 0}, {200, 200}, 2, colors.data(), stops.data(), DlTileMode::kDecal));
94 // Overlay the gradient with 25% green. This should appear as the entire
95 // rectangle being drawn with 25% green, including the border area outside the
96 // decal gradient.
97 paint.setColorFilter(DlColorFilter::MakeBlend(DlColor::kGreen().withAlpha(64),
98 DlBlendMode::kSrcOver));
99 paint.setColor(DlColor::kWhite());
100 builder.DrawRect(SkRect::MakeXYWH(0, 0, 600, 600), paint);
101 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
102 }
103
104 static void CanRenderLinearGradientWithDithering(AiksTest* aiks_test) {
105 DisplayListBuilder builder;
106 DlPaint paint;
107 builder.Translate(100.0, 100.0);
108
109 // 0xffcccccc --> 0xff333333, taken from
110 // https://github.com/flutter/flutter/issues/118073#issue-1521699748
111 std::vector<DlColor> colors = {DlColor(0xFFCCCCCC), DlColor(0xFF333333)};
112 std::vector<Scalar> stops = {0.0, 1.0};
113
114 paint.setColorSource(DlColorSource::MakeLinear(
115 {0, 0}, {800, 500}, 2, colors.data(), stops.data(), DlTileMode::kClamp));
116 builder.DrawRect(SkRect::MakeXYWH(0, 0, 800, 500), paint);
117 ASSERT_TRUE(aiks_test->OpenPlaygroundHere(builder.Build()));
118 }
119
120 TEST_P(AiksTest, CanRenderLinearGradientWithDitheringEnabled) {
121 CanRenderLinearGradientWithDithering(this);
122 }
123
124 static void CanRenderRadialGradientWithDithering(AiksTest* aiks_test) {
125 DisplayListBuilder builder;
126 DlPaint paint;
127 builder.Translate(100.0, 100.0);
128
129 // #FFF -> #000
130 std::vector<DlColor> colors = {DlColor(Color{1.0, 1.0, 1.0, 1.0}.ToARGB()),
131 DlColor(Color{0.0, 0.0, 0.0, 1.0}.ToARGB())};
132 std::vector<Scalar> stops = {0.0, 1.0};
133
134 paint.setColorSource(DlColorSource::MakeRadial(
135 {600, 600}, 600, 2, colors.data(), stops.data(), DlTileMode::kClamp));
136 builder.DrawRect(SkRect::MakeXYWH(0, 0, 1200, 1200), paint);
137 ASSERT_TRUE(aiks_test->OpenPlaygroundHere(builder.Build()));
138 }
139
140 TEST_P(AiksTest, CanRenderRadialGradientWithDitheringEnabled) {
141 CanRenderRadialGradientWithDithering(this);
142 }
143
144 static void CanRenderSweepGradientWithDithering(AiksTest* aiks_test) {
145 DisplayListBuilder builder;
146 builder.Scale(aiks_test->GetContentScale().x, aiks_test->GetContentScale().y);
147 DlPaint paint;
148 builder.Translate(100.0, 100.0);
149
150 // #FFF -> #000
151 std::vector<DlColor> colors = {DlColor(Color{1.0, 1.0, 1.0, 1.0}.ToARGB()),
152 DlColor(Color{0.0, 0.0, 0.0, 1.0}.ToARGB())};
153 std::vector<Scalar> stops = {0.0, 1.0};
154
155 paint.setColorSource(DlColorSource::MakeSweep(
156 {100, 100}, /*start=*/45, /*end=*/135, 2, colors.data(), stops.data(),
157 DlTileMode::kMirror));
158
159 builder.DrawRect(SkRect::MakeXYWH(0, 0, 600, 600), paint);
160 ASSERT_TRUE(aiks_test->OpenPlaygroundHere(builder.Build()));
161 }
162
163 TEST_P(AiksTest, CanRenderSweepGradientWithDitheringEnabled) {
164 CanRenderSweepGradientWithDithering(this);
165 }
166
167 static void CanRenderConicalGradientWithDithering(AiksTest* aiks_test) {
168 DisplayListBuilder builder;
169 builder.Scale(aiks_test->GetContentScale().x, aiks_test->GetContentScale().y);
170 DlPaint paint;
171 builder.Translate(100.0, 100.0);
172
173 // #FFF -> #000
174 std::vector<DlColor> colors = {DlColor(Color{1.0, 1.0, 1.0, 1.0}.ToARGB()),
175 DlColor(Color{0.0, 0.0, 0.0, 1.0}.ToARGB())};
176 std::vector<Scalar> stops = {0.0, 1.0};
177
178 paint.setColorSource(DlColorSource::MakeConical({0, 1}, 0, {100, 100}, 100, 2,
179 colors.data(), stops.data(),
180 DlTileMode::kMirror));
181
182 builder.DrawRect(SkRect::MakeXYWH(0, 0, 600, 600), paint);
183 ASSERT_TRUE(aiks_test->OpenPlaygroundHere(builder.Build()));
184 }
185
186 TEST_P(AiksTest, CanRenderConicalGradientWithDitheringEnabled) {
187 CanRenderConicalGradientWithDithering(this);
188 }
189
190 namespace {
191 void CanRenderLinearGradientWithOverlappingStops(AiksTest* aiks_test,
192 DlTileMode tile_mode) {
193 DisplayListBuilder builder;
194 DlPaint paint;
195 builder.Translate(100.0, 100.0);
196
197 std::vector<DlColor> colors = {
198 DlColor(Color{0.9568, 0.2627, 0.2118, 1.0}.ToARGB()),
199 DlColor(Color{0.9568, 0.2627, 0.2118, 1.0}.ToARGB()),
200 DlColor(Color{0.1294, 0.5882, 0.9529, 1.0}.ToARGB()),
201 DlColor(Color{0.1294, 0.5882, 0.9529, 1.0}.ToARGB())};
202 std::vector<Scalar> stops = {0.0, 0.5, 0.5, 1.0};
203
204 paint.setColorSource(DlColorSource::MakeLinear({0, 0}, {500, 500},
205 stops.size(), colors.data(),
206 stops.data(), tile_mode));
207
208 paint.setColor(DlColor::kWhite());
209 builder.DrawRect(SkRect::MakeXYWH(0, 0, 500, 500), paint);
210 ASSERT_TRUE(aiks_test->OpenPlaygroundHere(builder.Build()));
211 }
212 } // namespace
213
214 // Only clamp is necessary. All tile modes are the same output.
215 TEST_P(AiksTest, CanRenderLinearGradientWithOverlappingStopsClamp) {
216 CanRenderLinearGradientWithOverlappingStops(this, DlTileMode::kClamp);
217 }
218
219 namespace {
220 void CanRenderGradientWithIncompleteStops(AiksTest* aiks_test,
221 DlColorSourceType type) {
222 const DlTileMode tile_modes[4] = {
223 DlTileMode::kClamp,
224 DlTileMode::kRepeat,
225 DlTileMode::kMirror,
226 DlTileMode::kDecal,
227 };
228 const DlScalar test_size = 250;
229 const DlScalar test_border = 25;
230 const DlScalar gradient_size = 50;
231 const DlScalar quadrant_size = test_size + test_border * 2;
232
233 DisplayListBuilder builder;
234 builder.DrawRect(DlRect::MakeWH(quadrant_size * 2, quadrant_size * 2),
235 DlPaint().setColor(DlColor::kDarkGrey()));
236
237 for (int quadrant = 0; quadrant < 4; quadrant++) {
238 builder.Save();
239 builder.Translate((quadrant & 1) * quadrant_size + test_border,
240 (quadrant >> 1) * quadrant_size + test_border);
241
242 if (type == DlColorSourceType::kLinearGradient) {
243 // Alignment lines for the gradient edges/repeats/mirrors/etc.
244 // (rendered under the gradient so as not to obscure it)
245 DlPoint center = DlPoint(test_size, test_size) * 0.5;
246 DlScalar ten_percent = gradient_size * 0.1;
247 for (int i = gradient_size / 2; i <= test_size / 2; i += gradient_size) {
248 auto draw_at = [=](DlCanvas& canvas, DlScalar offset, DlColor color) {
249 DlPaint line_paint;
250 line_paint.setColor(color);
251 // strokewidth of 2 straddles the dividing line
252 line_paint.setStrokeWidth(2.0f);
253 line_paint.setDrawStyle(DlDrawStyle::kStroke);
254
255 DlPoint along(offset, offset);
256 DlScalar across_distance = test_size / 2 + 10 - offset;
257 DlPoint across(across_distance, -across_distance);
258
259 canvas.DrawLine(center - along - across, //
260 center - along + across, //
261 line_paint);
262 canvas.DrawLine(center + along - across, //
263 center + along + across, //
264 line_paint);
265 };
266 // White line is at the edge of the gradient
267 // Grey lines are where the 0.1 and 0.9 color stops land
268 draw_at(builder, i - ten_percent, DlColor::kMidGrey());
269 draw_at(builder, i, DlColor::kWhite());
270 draw_at(builder, i + ten_percent, DlColor::kMidGrey());
271 }
272 }
273
274 std::vector<DlColor> colors = {
275 DlColor::kGreen(),
276 DlColor::kPurple(),
277 DlColor::kOrange(),
278 DlColor::kBlue(),
279 };
280 std::vector<Scalar> stops = {0.1, 0.3, 0.7, 0.9};
281
282 DlPaint paint;
283 switch (type) {
284 case DlColorSourceType::kLinearGradient:
285 paint.setColorSource(DlColorSource::MakeLinear(
286 {test_size / 2 - gradient_size / 2,
287 test_size / 2 - gradient_size / 2},
288 {test_size / 2 + gradient_size / 2,
289 test_size / 2 + gradient_size / 2},
290 stops.size(), colors.data(), stops.data(), tile_modes[quadrant]));
291 break;
292 case DlColorSourceType::kRadialGradient:
293 paint.setColorSource(DlColorSource::MakeRadial(
294 {test_size / 2, test_size / 2}, gradient_size, //
295 stops.size(), colors.data(), stops.data(), tile_modes[quadrant]));
296 break;
297 case DlColorSourceType::kConicalGradient:
298 paint.setColorSource(DlColorSource::MakeConical(
299 {test_size / 2, test_size / 2}, 0,
300 {test_size / 2 + 20, test_size / 2 - 10}, gradient_size,
301 stops.size(), colors.data(), stops.data(), tile_modes[quadrant]));
302 break;
303 case DlColorSourceType::kSweepGradient:
304 paint.setColorSource(DlColorSource::MakeSweep(
305 {test_size / 2, test_size / 2}, 0, 45, //
306 stops.size(), colors.data(), stops.data(), tile_modes[quadrant]));
307 break;
308 default:
309 FML_UNREACHABLE();
310 }
311
312 builder.DrawRect(SkRect::MakeXYWH(0, 0, test_size, test_size), paint);
313 builder.Restore();
314 }
315
316 ASSERT_TRUE(aiks_test->OpenPlaygroundHere(builder.Build()));
317 }
318 } // namespace
319
320 TEST_P(AiksTest, CanRenderLinearGradientWithIncompleteStops) {
321 CanRenderGradientWithIncompleteStops(this,
322 DlColorSourceType::kLinearGradient);
323 }
324 TEST_P(AiksTest, CanRenderRadialGradientWithIncompleteStops) {
325 CanRenderGradientWithIncompleteStops(this,
326 DlColorSourceType::kRadialGradient);
327 }
328 TEST_P(AiksTest, CanRenderConicalGradientWithIncompleteStops) {
329 CanRenderGradientWithIncompleteStops(this,
330 DlColorSourceType::kConicalGradient);
331 }
332 TEST_P(AiksTest, CanRenderSweepGradientWithIncompleteStops) {
333 CanRenderGradientWithIncompleteStops(this, DlColorSourceType::kSweepGradient);
334 }
335
336 namespace {
337 void CanRenderLinearGradientManyColors(AiksTest* aiks_test,
338 DlTileMode tile_mode) {
339 DisplayListBuilder builder;
340 builder.Scale(aiks_test->GetContentScale().x, aiks_test->GetContentScale().y);
341 DlPaint paint;
342 builder.Translate(100, 100);
343
344 std::vector<DlColor> colors = {
345 DlColor(Color{0x1f / 255.0, 0.0, 0x5c / 255.0, 1.0}.ToARGB()),
346 DlColor(Color{0x5b / 255.0, 0.0, 0x60 / 255.0, 1.0}.ToARGB()),
347 DlColor(Color{0x87 / 255.0, 0x01 / 255.0, 0x60 / 255.0, 1.0}.ToARGB()),
348 DlColor(Color{0xac / 255.0, 0x25 / 255.0, 0x53 / 255.0, 1.0}.ToARGB()),
349 DlColor(Color{0xe1 / 255.0, 0x6b / 255.0, 0x5c / 255.0, 1.0}.ToARGB()),
350 DlColor(Color{0xf3 / 255.0, 0x90 / 255.0, 0x60 / 255.0, 1.0}.ToARGB()),
351 DlColor(Color{0xff / 255.0, 0xb5 / 255.0, 0x6b / 250.0, 1.0}.ToARGB())};
352 std::vector<Scalar> stops = {
353 0.0,
354 (1.0 / 6.0) * 1,
355 (1.0 / 6.0) * 2,
356 (1.0 / 6.0) * 3,
357 (1.0 / 6.0) * 4,
358 (1.0 / 6.0) * 5,
359 1.0,
360 };
361
362 paint.setColorSource(DlColorSource::MakeLinear({0, 0}, {200, 200},
363 stops.size(), colors.data(),
364 stops.data(), tile_mode));
365
366 paint.setColor(DlColor::kWhite());
367 builder.DrawRect(SkRect::MakeXYWH(0, 0, 600, 600), paint);
368 builder.Restore();
369 ASSERT_TRUE(aiks_test->OpenPlaygroundHere(builder.Build()));
370 }
371 } // namespace
372
373 TEST_P(AiksTest, CanRenderLinearGradientManyColorsClamp) {
374 CanRenderLinearGradientManyColors(this, DlTileMode::kClamp);
375 }
376 TEST_P(AiksTest, CanRenderLinearGradientManyColorsRepeat) {
377 CanRenderLinearGradientManyColors(this, DlTileMode::kRepeat);
378 }
379 TEST_P(AiksTest, CanRenderLinearGradientManyColorsMirror) {
380 CanRenderLinearGradientManyColors(this, DlTileMode::kMirror);
381 }
382 TEST_P(AiksTest, CanRenderLinearGradientManyColorsDecal) {
383 CanRenderLinearGradientManyColors(this, DlTileMode::kDecal);
384 }
385
386 namespace {
387 void CanRenderLinearGradientWayManyColors(AiksTest* aiks_test,
388 DlTileMode tile_mode) {
389 DisplayListBuilder builder;
390 DlPaint paint;
391 builder.Translate(100.0, 100.0);
392 auto color = DlColor(Color{0x1f / 255.0, 0.0, 0x5c / 255.0, 1.0}.ToARGB());
393 std::vector<DlColor> colors;
394 std::vector<Scalar> stops;
395 auto current_stop = 0.0;
396 for (int i = 0; i < 2000; i++) {
397 colors.push_back(color);
398 stops.push_back(current_stop);
399 current_stop += 1 / 2000.0;
400 }
401 stops[2000 - 1] = 1.0;
402
403 paint.setColorSource(DlColorSource::MakeLinear({0, 0}, {200, 200},
404 stops.size(), colors.data(),
405 stops.data(), tile_mode));
406
407 builder.DrawRect(SkRect::MakeXYWH(0, 0, 600, 600), paint);
408 ASSERT_TRUE(aiks_test->OpenPlaygroundHere(builder.Build()));
409 }
410 } // namespace
411
412 // Only test clamp on purpose since they all look the same.
413 TEST_P(AiksTest, CanRenderLinearGradientWayManyColorsClamp) {
414 CanRenderLinearGradientWayManyColors(this, DlTileMode::kClamp);
415 }
416
417 TEST_P(AiksTest, CanRenderLinearGradientManyColorsUnevenStops) {
418 auto callback = [&]() -> sk_sp<DisplayList> {
419 const char* tile_mode_names[] = {"Clamp", "Repeat", "Mirror", "Decal"};
420 const DlTileMode tile_modes[] = {DlTileMode::kClamp, DlTileMode::kRepeat,
421 DlTileMode::kMirror, DlTileMode::kDecal};
422
423 static int selected_tile_mode = 0;
424 static Matrix matrix;
425 if (AiksTest::ImGuiBegin("Controls", nullptr,
426 ImGuiWindowFlags_AlwaysAutoResize)) {
427 ImGui::Combo("Tile mode", &selected_tile_mode, tile_mode_names,
428 sizeof(tile_mode_names) / sizeof(char*));
429 std::string label = "##1";
430 for (int i = 0; i < 4; i++) {
431 ImGui::InputScalarN(label.c_str(), ImGuiDataType_Float,
432 &(matrix.vec[i]), 4, NULL, NULL, "%.2f", 0);
433 label[2]++;
434 }
435 ImGui::End();
436 }
437
438 DisplayListBuilder builder;
439 DlPaint paint;
440 builder.Translate(100.0, 100.0);
441 auto tile_mode = tile_modes[selected_tile_mode];
442
443 std::vector<DlColor> colors = {
444 DlColor(Color{0x1f / 255.0, 0.0, 0x5c / 255.0, 1.0}.ToARGB()),
445 DlColor(Color{0x5b / 255.0, 0.0, 0x60 / 255.0, 1.0}.ToARGB()),
446 DlColor(Color{0x87 / 255.0, 0x01 / 255.0, 0x60 / 255.0, 1.0}.ToARGB()),
447 DlColor(Color{0xac / 255.0, 0x25 / 255.0, 0x53 / 255.0, 1.0}.ToARGB()),
448 DlColor(Color{0xe1 / 255.0, 0x6b / 255.0, 0x5c / 255.0, 1.0}.ToARGB()),
449 DlColor(Color{0xf3 / 255.0, 0x90 / 255.0, 0x60 / 255.0, 1.0}.ToARGB()),
450 DlColor(Color{0xff / 255.0, 0xb5 / 255.0, 0x6b / 250.0, 1.0}.ToARGB())};
451 std::vector<Scalar> stops = {
452 0.0, 2.0 / 62.0, 4.0 / 62.0, 8.0 / 62.0, 16.0 / 62.0, 32.0 / 62.0, 1.0,
453 };
454
455 paint.setColorSource(DlColorSource::MakeLinear({0, 0}, {200, 200},
456 stops.size(), colors.data(),
457 stops.data(), tile_mode));
458
459 builder.DrawRect(SkRect::MakeXYWH(0, 0, 600, 600), paint);
460 return builder.Build();
461 };
462 ASSERT_TRUE(OpenPlaygroundHere(callback));
463 }
464
465 TEST_P(AiksTest, CanRenderLinearGradientMaskBlur) {
466 DisplayListBuilder builder;
467
468 std::vector<DlColor> colors = {
469 DlColor::kRed(), DlColor::kWhite(), DlColor::kRed(), DlColor::kWhite(),
470 DlColor::kRed(), DlColor::kWhite(), DlColor::kRed(), DlColor::kWhite(),
471 DlColor::kRed(), DlColor::kWhite(), DlColor::kRed()};
472 std::vector<Scalar> stops = {0.0, 0.1, 0.2, 0.3, 0.4, 0.5,
473 0.6, 0.7, 0.8, 0.9, 1.0};
474
475 DlPaint paint;
476 paint.setColor(DlColor::kWhite());
477 paint.setColorSource(DlColorSource::MakeLinear(
478 {200, 200}, {400, 400}, stops.size(), colors.data(), stops.data(),
479 DlTileMode::kClamp));
480 paint.setMaskFilter(DlBlurMaskFilter::Make(DlBlurStyle::kNormal, 20));
481
482 builder.DrawCircle(SkPoint{300, 300}, 200, paint);
483 builder.DrawRect(SkRect::MakeLTRB(100, 300, 500, 600), paint);
484
485 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
486 }
487
488 TEST_P(AiksTest, CanRenderRadialGradient) {
489 auto callback = [&]() -> sk_sp<DisplayList> {
490 const char* tile_mode_names[] = {"Clamp", "Repeat", "Mirror", "Decal"};
491 const DlTileMode tile_modes[] = {DlTileMode::kClamp, DlTileMode::kRepeat,
492 DlTileMode::kMirror, DlTileMode::kDecal};
493
494 static int selected_tile_mode = 0;
495 static Matrix matrix;
496 if (AiksTest::ImGuiBegin("Controls", nullptr,
497 ImGuiWindowFlags_AlwaysAutoResize)) {
498 ImGui::Combo("Tile mode", &selected_tile_mode, tile_mode_names,
499 sizeof(tile_mode_names) / sizeof(char*));
500 std::string label = "##1";
501 for (int i = 0; i < 4; i++) {
502 ImGui::InputScalarN(label.c_str(), ImGuiDataType_Float,
503 &(matrix.vec[i]), 4, NULL, NULL, "%.2f", 0);
504 label[2]++;
505 }
506 ImGui::End();
507 }
508
509 DisplayListBuilder builder;
510 DlPaint paint;
511 builder.Translate(100.0, 100.0);
512 auto tile_mode = tile_modes[selected_tile_mode];
513
514 std::vector<DlColor> colors = {
515 DlColor(Color{0.9568, 0.2627, 0.2118, 1.0}.ToARGB()),
516 DlColor(Color{0.1294, 0.5882, 0.9529, 1.0}.ToARGB())};
517 std::vector<Scalar> stops = {0.0, 1.0};
518
519 paint.setColorSource(DlColorSource::MakeRadial(
520 {100, 100}, 100, 2, colors.data(), stops.data(), tile_mode));
521
522 builder.DrawRect(SkRect::MakeXYWH(0, 0, 600, 600), paint);
523 return builder.Build();
524 };
525 ASSERT_TRUE(OpenPlaygroundHere(callback));
526 }
527
528 TEST_P(AiksTest, CanRenderRadialGradientManyColors) {
529 auto callback = [&]() -> sk_sp<DisplayList> {
530 const char* tile_mode_names[] = {"Clamp", "Repeat", "Mirror", "Decal"};
531 const DlTileMode tile_modes[] = {DlTileMode::kClamp, DlTileMode::kRepeat,
532 DlTileMode::kMirror, DlTileMode::kDecal};
533
534 static int selected_tile_mode = 0;
535 static Matrix matrix = {
536 1, 0, 0, 0, //
537 0, 1, 0, 0, //
538 0, 0, 1, 0, //
539 0, 0, 0, 1 //
540 };
541 if (AiksTest::ImGuiBegin("Controls", nullptr,
542 ImGuiWindowFlags_AlwaysAutoResize)) {
543 ImGui::Combo("Tile mode", &selected_tile_mode, tile_mode_names,
544 sizeof(tile_mode_names) / sizeof(char*));
545 std::string label = "##1";
546 for (int i = 0; i < 4; i++) {
547 ImGui::InputScalarN(label.c_str(), ImGuiDataType_Float,
548 &(matrix.vec[i]), 4, NULL, NULL, "%.2f", 0);
549 label[2]++;
550 }
551 ImGui::End();
552 }
553
554 DisplayListBuilder builder;
555 DlPaint paint;
556 builder.Translate(100.0, 100.0);
557 auto tile_mode = tile_modes[selected_tile_mode];
558
559 std::vector<DlColor> colors = {
560 DlColor(Color{0x1f / 255.0, 0.0, 0x5c / 255.0, 1.0}.ToARGB()),
561 DlColor(Color{0x5b / 255.0, 0.0, 0x60 / 255.0, 1.0}.ToARGB()),
562 DlColor(Color{0x87 / 255.0, 0x01 / 255.0, 0x60 / 255.0, 1.0}.ToARGB()),
563 DlColor(Color{0xac / 255.0, 0x25 / 255.0, 0x53 / 255.0, 1.0}.ToARGB()),
564 DlColor(Color{0xe1 / 255.0, 0x6b / 255.0, 0x5c / 255.0, 1.0}.ToARGB()),
565 DlColor(Color{0xf3 / 255.0, 0x90 / 255.0, 0x60 / 255.0, 1.0}.ToARGB()),
566 DlColor(Color{0xff / 255.0, 0xb5 / 255.0, 0x6b / 250.0, 1.0}.ToARGB())};
567 std::vector<Scalar> stops = {
568 0.0,
569 (1.0 / 6.0) * 1,
570 (1.0 / 6.0) * 2,
571 (1.0 / 6.0) * 3,
572 (1.0 / 6.0) * 4,
573 (1.0 / 6.0) * 5,
574 1.0,
575 };
576
577 paint.setColorSource(DlColorSource::MakeRadial(
578 {100, 100}, 100, stops.size(), colors.data(), stops.data(), tile_mode));
579
580 builder.DrawRect(SkRect::MakeXYWH(0, 0, 600, 600), paint);
581 return builder.Build();
582 };
583 ASSERT_TRUE(OpenPlaygroundHere(callback));
584 }
585
586 namespace {
587 void CanRenderSweepGradient(AiksTest* aiks_test, DlTileMode tile_mode) {
588 DisplayListBuilder builder;
589 builder.Scale(aiks_test->GetContentScale().x, aiks_test->GetContentScale().y);
590 DlPaint paint;
591 builder.Translate(100, 100);
592
593 std::vector<DlColor> colors = {
594 DlColor(Color{0.9568, 0.2627, 0.2118, 1.0}.ToARGB()),
595 DlColor(Color{0.1294, 0.5882, 0.9529, 1.0}.ToARGB())};
596 std::vector<Scalar> stops = {0.0, 1.0};
597
598 paint.setColorSource(DlColorSource::MakeSweep(
599 {100, 100}, /*start=*/45, /*end=*/135, /*stop_count=*/2, colors.data(),
600 stops.data(), tile_mode));
601
602 builder.DrawRect(SkRect::MakeXYWH(0, 0, 600, 600), paint);
603 ASSERT_TRUE(aiks_test->OpenPlaygroundHere(builder.Build()));
604 }
605 } // namespace
606
607 TEST_P(AiksTest, CanRenderSweepGradientClamp) {
608 CanRenderSweepGradient(this, DlTileMode::kClamp);
609 }
610 TEST_P(AiksTest, CanRenderSweepGradientRepeat) {
611 CanRenderSweepGradient(this, DlTileMode::kRepeat);
612 }
613 TEST_P(AiksTest, CanRenderSweepGradientMirror) {
614 CanRenderSweepGradient(this, DlTileMode::kMirror);
615 }
616 TEST_P(AiksTest, CanRenderSweepGradientDecal) {
617 CanRenderSweepGradient(this, DlTileMode::kDecal);
618 }
619
620 namespace {
621 void CanRenderSweepGradientManyColors(AiksTest* aiks_test,
622 DlTileMode tile_mode) {
623 DisplayListBuilder builder;
624 DlPaint paint;
625 builder.Translate(100.0, 100.0);
626
627 std::vector<DlColor> colors = {
628 DlColor(Color{0x1f / 255.0, 0.0, 0x5c / 255.0, 1.0}.ToARGB()),
629 DlColor(Color{0x5b / 255.0, 0.0, 0x60 / 255.0, 1.0}.ToARGB()),
630 DlColor(Color{0x87 / 255.0, 0x01 / 255.0, 0x60 / 255.0, 1.0}.ToARGB()),
631 DlColor(Color{0xac / 255.0, 0x25 / 255.0, 0x53 / 255.0, 1.0}.ToARGB()),
632 DlColor(Color{0xe1 / 255.0, 0x6b / 255.0, 0x5c / 255.0, 1.0}.ToARGB()),
633 DlColor(Color{0xf3 / 255.0, 0x90 / 255.0, 0x60 / 255.0, 1.0}.ToARGB()),
634 DlColor(Color{0xff / 255.0, 0xb5 / 255.0, 0x6b / 250.0, 1.0}.ToARGB())};
635 std::vector<Scalar> stops = {
636 0.0,
637 (1.0 / 6.0) * 1,
638 (1.0 / 6.0) * 2,
639 (1.0 / 6.0) * 3,
640 (1.0 / 6.0) * 4,
641 (1.0 / 6.0) * 5,
642 1.0,
643 };
644
645 paint.setColorSource(DlColorSource::MakeSweep({100, 100}, 45, 135,
646 stops.size(), colors.data(),
647 stops.data(), tile_mode));
648
649 builder.DrawRect(SkRect::MakeXYWH(0, 0, 600, 600), paint);
650 ASSERT_TRUE(aiks_test->OpenPlaygroundHere(builder.Build()));
651 }
652 } // namespace
653
654 TEST_P(AiksTest, CanRenderSweepGradientManyColorsClamp) {
655 CanRenderSweepGradientManyColors(this, DlTileMode::kClamp);
656 }
657 TEST_P(AiksTest, CanRenderSweepGradientManyColorsRepeat) {
658 CanRenderSweepGradientManyColors(this, DlTileMode::kRepeat);
659 }
660 TEST_P(AiksTest, CanRenderSweepGradientManyColorsMirror) {
661 CanRenderSweepGradientManyColors(this, DlTileMode::kMirror);
662 }
663 TEST_P(AiksTest, CanRenderSweepGradientManyColorsDecal) {
664 CanRenderSweepGradientManyColors(this, DlTileMode::kDecal);
665 }
666
667 TEST_P(AiksTest, CanRenderConicalGradient) {
668 Scalar size = 256;
669 DisplayListBuilder builder;
670 DlPaint paint;
671 paint.setColor(DlColor::kWhite());
672 builder.DrawRect(SkRect::MakeXYWH(0, 0, size * 3, size * 3), paint);
673 std::vector<DlColor> colors = {
674 DlColor(Color::MakeRGBA8(0xF4, 0x43, 0x36, 0xFF).ToARGB()),
675 DlColor(Color::MakeRGBA8(0xFF, 0xEB, 0x3B, 0xFF).ToARGB()),
676 DlColor(Color::MakeRGBA8(0x4c, 0xAF, 0x50, 0xFF).ToARGB()),
677 DlColor(Color::MakeRGBA8(0x21, 0x96, 0xF3, 0xFF).ToARGB())};
678 std::vector<Scalar> stops = {0.0, 1.f / 3.f, 2.f / 3.f, 1.0};
679 std::array<std::tuple<DlPoint, float, DlPoint, float>, 8> array{
680 std::make_tuple(DlPoint(size / 2.f, size / 2.f), 0.f,
681 DlPoint(size / 2.f, size / 2.f), size / 2.f),
682 std::make_tuple(DlPoint(size / 2.f, size / 2.f), size / 4.f,
683 DlPoint(size / 2.f, size / 2.f), size / 2.f),
684 std::make_tuple(DlPoint(size / 4.f, size / 4.f), 0.f,
685 DlPoint(size / 2.f, size / 2.f), size / 2.f),
686 std::make_tuple(DlPoint(size / 4.f, size / 4.f), size / 2.f,
687 DlPoint(size / 2.f, size / 2.f), 0),
688 std::make_tuple(DlPoint(size / 4.f, size / 4.f), size / 4.f,
689 DlPoint(size / 2.f, size / 2.f), size / 2.f),
690 std::make_tuple(DlPoint(size / 4.f, size / 4.f), size / 16.f,
691 DlPoint(size / 2.f, size / 2.f), size / 8.f),
692 std::make_tuple(DlPoint(size / 4.f, size / 4.f), size / 8.f,
693 DlPoint(size / 2.f, size / 2.f), size / 16.f),
694 std::make_tuple(DlPoint(size / 8.f, size / 8.f), size / 8.f,
695 DlPoint(size / 2.f, size / 2.f), size / 8.f),
696 };
697 for (int i = 0; i < 8; i++) {
698 builder.Save();
699 builder.Translate((i % 3) * size, i / 3 * size);
700 paint.setColorSource(DlColorSource::MakeConical(
701 std::get<2>(array[i]), std::get<3>(array[i]), std::get<0>(array[i]),
702 std::get<1>(array[i]), stops.size(), colors.data(), stops.data(),
703 DlTileMode::kClamp));
704 builder.DrawRect(SkRect::MakeXYWH(0, 0, size, size), paint);
705 builder.Restore();
706 }
707 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
708 }
709
710 TEST_P(AiksTest, CanRenderGradientDecalWithBackground) {
711 std::vector<DlColor> colors = {
712 DlColor(Color::MakeRGBA8(0xF4, 0x43, 0x36, 0xFF).ToARGB()),
713 DlColor(Color::MakeRGBA8(0xFF, 0xEB, 0x3B, 0xFF).ToARGB()),
714 DlColor(Color::MakeRGBA8(0x4c, 0xAF, 0x50, 0xFF).ToARGB()),
715 DlColor(Color::MakeRGBA8(0x21, 0x96, 0xF3, 0xFF).ToARGB())};
716 std::vector<Scalar> stops = {0.0, 1.f / 3.f, 2.f / 3.f, 1.0};
717
718 std::array<std::shared_ptr<DlColorSource>, 3> color_sources = {
719 DlColorSource::MakeLinear({0, 0}, {100, 100}, stops.size(), colors.data(),
720 stops.data(), DlTileMode::kDecal),
721 DlColorSource::MakeRadial({100, 100}, 100, stops.size(), colors.data(),
722 stops.data(), DlTileMode::kDecal),
723 DlColorSource::MakeSweep({100, 100}, 45, 135, stops.size(), colors.data(),
724 stops.data(), DlTileMode::kDecal),
725 };
726
727 DisplayListBuilder builder;
728 DlPaint paint;
729 paint.setColor(DlColor::kWhite());
730 builder.DrawRect(SkRect::MakeLTRB(0, 0, 605, 205), paint);
731 for (int i = 0; i < 3; i++) {
732 builder.Save();
733 builder.Translate(i * 200.0f, 0);
734 paint.setColorSource(color_sources[i]);
735 builder.DrawRect(SkRect::MakeLTRB(0, 0, 200, 200), paint);
736 builder.Restore();
737 }
738 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
739 }
740
741 TEST_P(AiksTest, GradientStrokesRenderCorrectly) {
742 // Compare with https://fiddle.skia.org/c/027392122bec8ac2b5d5de00a4b9bbe2
743 auto callback = [&]() -> sk_sp<DisplayList> {
744 static float scale = 3;
745 static bool add_circle_clip = true;
746 const char* tile_mode_names[] = {"Clamp", "Repeat", "Mirror", "Decal"};
747 const DlTileMode tile_modes[] = {DlTileMode::kClamp, DlTileMode::kRepeat,
748 DlTileMode::kMirror, DlTileMode::kDecal};
749 static int selected_tile_mode = 0;
750 static float alpha = 1;
751
752 if (AiksTest::ImGuiBegin("Controls", nullptr,
753 ImGuiWindowFlags_AlwaysAutoResize)) {
754 ImGui::SliderFloat("Scale", &scale, 0, 6);
755 ImGui::Checkbox("Circle clip", &add_circle_clip);
756 ImGui::SliderFloat("Alpha", &alpha, 0, 1);
757 ImGui::Combo("Tile mode", &selected_tile_mode, tile_mode_names,
758 sizeof(tile_mode_names) / sizeof(char*));
759 ImGui::End();
760 }
761
762 DisplayListBuilder builder;
763 builder.Scale(GetContentScale().x, GetContentScale().y);
764 DlPaint paint;
765 paint.setColor(DlColor::kWhite());
766 builder.DrawPaint(paint);
767
768 paint.setDrawStyle(DlDrawStyle::kStroke);
769 paint.setColor(DlColor::kWhite().withAlpha(alpha * 255));
770 paint.setStrokeWidth(10);
771 auto tile_mode = tile_modes[selected_tile_mode];
772
773 std::vector<DlColor> colors = {
774 DlColor(Color{0.9568, 0.2627, 0.2118, 1.0}.ToARGB()),
775 DlColor(Color{0.1294, 0.5882, 0.9529, 1.0}.ToARGB())};
776 std::vector<Scalar> stops = {0.0, 1.0};
777
778 paint.setColorSource(DlColorSource::MakeLinear({0, 0}, {50, 50},
779 stops.size(), colors.data(),
780 stops.data(), tile_mode));
781
782 SkPath path;
783 path.moveTo(20, 20);
784 path.quadTo({60, 20}, {60, 60});
785 path.close();
786 path.moveTo(60, 20);
787 path.quadTo({60, 60}, {20, 60});
788
789 builder.Scale(scale, scale);
790
791 if (add_circle_clip) {
792 static PlaygroundPoint circle_clip_point_a(Point(60, 300), 20,
793 Color::Red());
794 static PlaygroundPoint circle_clip_point_b(Point(600, 300), 20,
795 Color::Red());
796 auto [handle_a, handle_b] =
797 DrawPlaygroundLine(circle_clip_point_a, circle_clip_point_b);
798
799 SkMatrix screen_to_canvas;
800 if (!builder.GetTransform().invert(&screen_to_canvas)) {
801 return nullptr;
802 }
803 Matrix ip_matrix = ToMatrix(screen_to_canvas);
804 Point point_a = ip_matrix * handle_a * GetContentScale();
805 Point point_b = ip_matrix * handle_b * GetContentScale();
806
807 Point middle = (point_a + point_b) / 2;
808 auto radius = point_a.GetDistance(middle);
809 SkPath circle;
810 circle.addCircle(middle.x, middle.y, radius);
811 builder.ClipPath(circle);
812 }
813
814 for (auto join :
815 {DlStrokeJoin::kBevel, DlStrokeJoin::kRound, DlStrokeJoin::kMiter}) {
816 paint.setStrokeJoin(join);
817 for (auto cap :
818 {DlStrokeCap::kButt, DlStrokeCap::kSquare, DlStrokeCap::kRound}) {
819 paint.setStrokeCap(cap);
820 builder.DrawPath(path, paint);
821 builder.Translate(80, 0);
822 }
823 builder.Translate(-240, 60);
824 }
825
826 return builder.Build();
827 };
828
829 ASSERT_TRUE(OpenPlaygroundHere(callback));
830 }
831
832 // Draws two gradients that should look identical (except that one is an RRECT).
833 TEST_P(AiksTest, FastGradientTestHorizontal) {
834 DisplayListBuilder builder;
835 DlPaint paint;
836 builder.Translate(100.0f, 0);
837
838 std::vector<DlColor> colors = {DlColor::kRed(), DlColor::kBlue(),
839 DlColor::kGreen()};
840 std::vector<Scalar> stops = {0.0, 0.1, 1.0};
841
842 paint.setColorSource(DlColorSource::MakeLinear({0, 0}, {300, 0}, stops.size(),
843 colors.data(), stops.data(),
844 DlTileMode::kClamp));
845
846 paint.setColor(DlColor::kWhite());
847 builder.DrawRect(SkRect::MakeXYWH(0, 0, 300, 300), paint);
848 builder.Translate(400, 0);
849 builder.DrawRRect(SkRRect::MakeRectXY(SkRect::MakeXYWH(0, 0, 300, 300), 4, 4),
850 paint);
851
852 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
853 }
854
855 // Draws two gradients that should look identical (except that one is an RRECT).
856 TEST_P(AiksTest, FastGradientTestVertical) {
857 DisplayListBuilder builder;
858 DlPaint paint;
859 builder.Translate(100.0f, 0);
860
861 std::vector<DlColor> colors = {DlColor::kRed(), DlColor::kBlue(),
862 DlColor::kGreen()};
863 std::vector<Scalar> stops = {0.0, 0.1, 1.0};
864
865 paint.setColorSource(DlColorSource::MakeLinear({0, 0}, {0, 300}, stops.size(),
866 colors.data(), stops.data(),
867 DlTileMode::kClamp));
868
869 paint.setColor(DlColor::kWhite());
870 builder.DrawRect(SkRect::MakeXYWH(0, 0, 300, 300), paint);
871 builder.Translate(400, 0);
872 builder.DrawRRect(SkRRect::MakeRectXY(SkRect::MakeXYWH(0, 0, 300, 300), 4, 4),
873 paint);
874
875 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
876 }
877
878 // Draws two gradients that should look identical (except that one is an RRECT).
879 TEST_P(AiksTest, FastGradientTestHorizontalReversed) {
880 DisplayListBuilder builder;
881 DlPaint paint;
882 builder.Translate(100.0f, 0);
883
884 std::vector<DlColor> colors = {DlColor::kRed(), DlColor::kBlue(),
885 DlColor::kGreen()};
886 std::vector<Scalar> stops = {0.0, 0.1, 1.0};
887
888 paint.setColorSource(DlColorSource::MakeLinear({300, 0}, {0, 0}, stops.size(),
889 colors.data(), stops.data(),
890 DlTileMode::kClamp));
891
892 paint.setColor(DlColor::kWhite());
893 builder.DrawRect(SkRect::MakeXYWH(0, 0, 300, 300), paint);
894 builder.Translate(400, 0);
895 builder.DrawRRect(SkRRect::MakeRectXY(SkRect::MakeXYWH(0, 0, 300, 300), 4, 4),
896 paint);
897
898 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
899 }
900
901 // Draws two gradients that should look identical (except that one is an RRECT).
902 TEST_P(AiksTest, FastGradientTestVerticalReversed) {
903 DisplayListBuilder builder;
904 DlPaint paint;
905 builder.Translate(100.0f, 0);
906
907 std::vector<DlColor> colors = {DlColor::kRed(), DlColor::kBlue(),
908 DlColor::kGreen()};
909 std::vector<Scalar> stops = {0.0, 0.1, 1.0};
910
911 paint.setColorSource(DlColorSource::MakeLinear({0, 300}, {0, 0}, stops.size(),
912 colors.data(), stops.data(),
913 DlTileMode::kClamp));
914
915 paint.setColor(DlColor::kWhite());
916 builder.DrawRect(SkRect::MakeXYWH(0, 0, 300, 300), paint);
917 builder.Translate(400, 0);
918 builder.DrawRRect(SkRRect::MakeRectXY(SkRect::MakeXYWH(0, 0, 300, 300), 4, 4),
919 paint);
920
921 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
922 }
923
924 TEST_P(AiksTest, VerifyNonOptimizedGradient) {
925 DisplayListBuilder builder;
926 DlPaint paint;
927 builder.Translate(100.0f, 0);
928
929 std::vector<DlColor> colors = {DlColor::kRed(), DlColor::kBlue(),
930 DlColor::kGreen()};
931 std::vector<Scalar> stops = {0.0, 0.1, 1.0};
932
933 // Inset the start and end point to verify that we do not apply
934 // the fast gradient condition.
935 paint.setColorSource(
936 DlColorSource::MakeLinear({0, 150}, {0, 100}, stops.size(), colors.data(),
937 stops.data(), DlTileMode::kRepeat));
938
939 paint.setColor(DlColor::kWhite());
940 builder.DrawRect(SkRect::MakeXYWH(0, 0, 300, 300), paint);
941 builder.Translate(400, 0);
942 builder.DrawRRect(SkRRect::MakeRectXY(SkRect::MakeXYWH(0, 0, 300, 300), 4, 4),
943 paint);
944
945 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
946 }
947
948 } // namespace testing
949 } // namespace impeller
impeller::AiksPlayground
Definition: aiks_playground.h:16
impeller::TPoint::y
Type y
Definition: point.h:31
impeller::Scalar
float Scalar
Definition: scalar.h:18
aiks_unittests.h
impeller::testing::AiksTest
AiksPlayground AiksTest
Definition: aiks_unittests.h:17
impeller::Color
Definition: color.h:123
impeller::AiksPlayground::OpenPlaygroundHere
bool OpenPlaygroundHere(const AiksDlPlaygroundCallback &callback)
Definition: aiks_playground.cc:43
impeller::skia_conversions::ToMatrix
Matrix ToMatrix(const SkMatrix &m)
Definition: skia_conversions.cc:165
impeller::testing::CanRenderRadialGradientWithDithering
static void CanRenderRadialGradientWithDithering(AiksTest *aiks_test)
Definition: aiks_dl_gradient_unittests.cc:124
impeller::Color::ToARGB
constexpr uint32_t ToARGB() const
Convert to ARGB 32 bit color.
Definition: color.h:258
x
int32_t x
Definition: dl_golden_unittests.cc:443
impeller::testing::TEST_P
TEST_P(AiksTest, VerifyNonOptimizedGradient)
Definition: aiks_dl_gradient_unittests.cc:924
offset
SeparatedVector2 offset
Definition: stroke_path_geometry.cc:319
impeller::Matrix::vec
Vector4 vec[4]
Definition: matrix.h:41
impeller::Point
TPoint< Scalar > Point
Definition: point.h:327
widgets.h
type
GLenum type
Definition: blit_command_gles.cc:151
flutter
Definition: dl_golden_blur_unittests.cc:16
impeller::testing::CanRenderConicalGradientWithDithering
static void CanRenderConicalGradientWithDithering(AiksTest *aiks_test)
Definition: aiks_dl_gradient_unittests.cc:167
impeller::TPoint::x
Type x
Definition: point.h:30
impeller::Playground::GetContentScale
Point GetContentScale() const
Definition: playground.cc:189
impeller::PlaygroundPoint
Definition: widgets.h:17
impeller::testing::CanRenderLinearGradientWithDithering
static void CanRenderLinearGradientWithDithering(AiksTest *aiks_test)
Definition: aiks_dl_gradient_unittests.cc:104
impeller::DlPoint
flutter::DlPoint DlPoint
Definition: dl_dispatcher.h:24
impeller::TPoint< Scalar >
scale
const Scalar scale
Definition: stroke_path_geometry.cc:316
impeller::TPoint::GetDistance
constexpr Type GetDistance(const TPoint &p) const
Definition: point.h:200
impeller::DlScalar
flutter::DlScalar DlScalar
Definition: dl_dispatcher.h:23
impeller
Definition: allocation.cc:12
impeller::testing::CanRenderSweepGradientWithDithering
static void CanRenderSweepGradientWithDithering(AiksTest *aiks_test)
Definition: aiks_dl_gradient_unittests.cc:144
impeller::Matrix
A 4x4 matrix using column-major storage.
Definition: matrix.h:37
impeller::DrawPlaygroundLine
std::tuple< Point, Point > DrawPlaygroundLine(PlaygroundPoint &point_a, PlaygroundPoint &point_b)
Definition: widgets.cc:50