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