| Flutter Impeller |

aiks_dl_basic_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_sampling_options.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_image_filter.h"
11 #include "display_list/effects/dl_mask_filter.h"
12 #include "flutter/impeller/display_list/aiks_unittests.h"
13
14 #include "flutter/display_list/dl_blend_mode.h"
15 #include "flutter/display_list/dl_builder.h"
16 #include "flutter/display_list/dl_color.h"
17 #include "flutter/display_list/dl_paint.h"
18 #include "flutter/impeller/display_list/dl_image_impeller.h"
19 #include "flutter/impeller/geometry/scalar.h"
20 #include "flutter/testing/display_list_testing.h"
21 #include "flutter/testing/testing.h"
22 #include "impeller/playground/widgets.h"
23
24 namespace impeller {
25 namespace testing {
26
27 using namespace flutter;
28
29 TEST_P(AiksTest, CanRenderColoredRect) {
30 DisplayListBuilder builder;
31 DlPaint paint;
32 paint.setColor(DlColor::kBlue());
33 builder.DrawPath(DlPath::MakeRectXYWH(100.0f, 100.0f, 100.0f, 100.0f), paint);
34 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
35 }
36
37 TEST_P(AiksTest, CanRenderImage) {
38 DisplayListBuilder builder;
39 DlPaint paint;
40 paint.setColor(DlColor::kRed());
41 auto image = DlImageImpeller::Make(CreateTextureForFixture("kalimba.jpg"));
42 builder.DrawImage(image, DlPoint(100.0, 100.0),
43 DlImageSampling::kNearestNeighbor, &paint);
44 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
45 }
46
47 TEST_P(AiksTest, CanRenderInvertedImageWithColorFilter) {
48 DisplayListBuilder builder;
49 DlPaint paint;
50 paint.setColor(DlColor::kRed());
51 paint.setColorFilter(
52 DlColorFilter::MakeBlend(DlColor::kYellow(), DlBlendMode::kSrcOver));
53 paint.setInvertColors(true);
54 auto image = DlImageImpeller::Make(CreateTextureForFixture("kalimba.jpg"));
55
56 builder.DrawImage(image, DlPoint(100.0, 100.0),
57 DlImageSampling::kNearestNeighbor, &paint);
58 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
59 }
60
61 TEST_P(AiksTest, CanRenderColorFilterWithInvertColors) {
62 DisplayListBuilder builder;
63 DlPaint paint;
64 paint.setColor(DlColor::kRed());
65 paint.setColorFilter(
66 DlColorFilter::MakeBlend(DlColor::kYellow(), DlBlendMode::kSrcOver));
67 paint.setInvertColors(true);
68
69 builder.DrawRect(DlRect::MakeLTRB(0, 0, 100, 100), paint);
70 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
71 }
72
73 TEST_P(AiksTest, CanRenderColorFilterWithInvertColorsDrawPaint) {
74 DisplayListBuilder builder;
75 DlPaint paint;
76 paint.setColor(DlColor::kRed());
77 paint.setColorFilter(
78 DlColorFilter::MakeBlend(DlColor::kYellow(), DlBlendMode::kSrcOver));
79 paint.setInvertColors(true);
80
81 builder.DrawPaint(paint);
82 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
83 }
84
85 namespace {
86 bool GenerateMipmap(const std::shared_ptr<Context>& context,
87 std::shared_ptr<Texture> texture,
88 std::string_view label) {
89 auto buffer = context->CreateCommandBuffer();
90 if (!buffer) {
91 return false;
92 }
93 auto pass = buffer->CreateBlitPass();
94 if (!pass) {
95 return false;
96 }
97 pass->GenerateMipmap(std::move(texture), label);
98
99 pass->EncodeCommands();
100 return context->GetCommandQueue()->Submit({buffer}).ok();
101 }
102
103 void CanRenderTiledTexture(AiksTest* aiks_test,
104 DlTileMode tile_mode,
105 Matrix local_matrix = {}) {
106 auto context = aiks_test->GetContext();
107 ASSERT_TRUE(context);
108 auto texture = aiks_test->CreateTextureForFixture("table_mountain_nx.png",
109 /*enable_mipmapping=*/true);
110 GenerateMipmap(context, texture, "table_mountain_nx");
111 auto image = DlImageImpeller::Make(texture);
112 auto color_source = DlColorSource::MakeImage(
113 image, tile_mode, tile_mode, DlImageSampling::kNearestNeighbor,
114 &local_matrix);
115
116 DisplayListBuilder builder;
117 DlPaint paint;
118 paint.setColor(DlColor::kWhite());
119 paint.setColorSource(color_source);
120
121 builder.Scale(aiks_test->GetContentScale().x, aiks_test->GetContentScale().y);
122 builder.Translate(100.0f, 100.0f);
123 builder.DrawRect(DlRect::MakeXYWH(0, 0, 600, 600), paint);
124
125 // Should not change the image.
126 constexpr auto stroke_width = 64;
127 paint.setDrawStyle(DlDrawStyle::kStroke);
128 paint.setStrokeWidth(stroke_width);
129 if (tile_mode == DlTileMode::kDecal) {
130 builder.DrawRect(DlRect::MakeXYWH(stroke_width, stroke_width, 600, 600),
131 paint);
132 } else {
133 builder.DrawRect(DlRect::MakeXYWH(0, 0, 600, 600), paint);
134 }
135
136 {
137 // Should not change the image.
138 DlPathBuilder path_builder;
139 path_builder.AddCircle(DlPoint(150, 150), 150);
140 path_builder.AddRoundRect(
141 RoundRect::MakeRectXY(DlRect::MakeLTRB(300, 300, 600, 600), 10, 10));
142 DlPath path(path_builder);
143
144 // Make sure path cannot be simplified...
145 EXPECT_FALSE(path.IsRect(nullptr));
146 EXPECT_FALSE(path.IsOval(nullptr));
147 EXPECT_FALSE(path.IsRoundRect(nullptr));
148
149 // Make sure path will not trigger the optimal convex code
150 EXPECT_FALSE(path.IsConvex());
151
152 paint.setDrawStyle(DlDrawStyle::kFill);
153 builder.DrawPath(path, paint);
154 }
155
156 {
157 // Should not change the image. Tests the Convex short-cut code.
158 DlPath circle = DlPath::MakeCircle(DlPoint(150, 450), 150);
159
160 // Unfortunately, the circle path can be simplified...
161 EXPECT_TRUE(circle.IsOval(nullptr));
162 // At least it's convex, though...
163 EXPECT_TRUE(circle.IsConvex());
164
165 // Let's make a copy that doesn't remember that it's just a circle...
166 DlPathBuilder path_builder;
167 // This moveTo confuses addPath into appending rather than replacing,
168 // which prevents it from noticing that it's just a circle...
169 path_builder.MoveTo({10, 10});
170 path_builder.AddPath(circle.GetPath());
171 path_builder.SetConvexity(Convexity::kConvex);
172 DlPath path(path_builder);
173
174 // Make sure path cannot be simplified...
175 EXPECT_FALSE(path.IsRect(nullptr));
176 EXPECT_FALSE(path.IsOval(nullptr));
177 EXPECT_FALSE(path.IsRoundRect(nullptr));
178
179 // But check that we will trigger the optimal convex code
180 EXPECT_TRUE(path.GetPath().IsConvex());
181
182 paint.setDrawStyle(DlDrawStyle::kFill);
183 builder.DrawPath(path, paint);
184 }
185
186 ASSERT_TRUE(aiks_test->OpenPlaygroundHere(builder.Build()));
187 }
188 } // namespace
189
190 TEST_P(AiksTest, CanRenderTiledTextureClamp) {
191 CanRenderTiledTexture(this, DlTileMode::kClamp);
192 }
193
194 TEST_P(AiksTest, CanRenderTiledTextureRepeat) {
195 CanRenderTiledTexture(this, DlTileMode::kRepeat);
196 }
197
198 TEST_P(AiksTest, CanRenderTiledTextureMirror) {
199 CanRenderTiledTexture(this, DlTileMode::kMirror);
200 }
201
202 TEST_P(AiksTest, CanRenderTiledTextureDecal) {
203 CanRenderTiledTexture(this, DlTileMode::kDecal);
204 }
205
206 TEST_P(AiksTest, CanRenderTiledTextureClampWithTranslate) {
207 CanRenderTiledTexture(this, DlTileMode::kClamp,
208 Matrix::MakeTranslation({172.f, 172.f, 0.f}));
209 }
210
211 TEST_P(AiksTest, CanRenderImageRect) {
212 DisplayListBuilder builder;
213 auto image = DlImageImpeller::Make(CreateTextureForFixture("kalimba.jpg"));
214
215 DlISize image_half_size = DlISize(image->dimensions().fWidth * 0.5f,
216 image->dimensions().fHeight * 0.5f);
217
218 // Render the bottom right quarter of the source image in a stretched rect.
219 auto source_rect = DlRect::MakeSize(image_half_size);
220 source_rect =
221 source_rect.Shift(image_half_size.width, image_half_size.height);
222
223 builder.DrawImageRect(image, source_rect,
224 DlRect::MakeXYWH(100, 100, 600, 600),
225 DlImageSampling::kNearestNeighbor);
226 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
227 }
228
229 TEST_P(AiksTest, DrawImageRectSrcOutsideBounds) {
230 DisplayListBuilder builder;
231 auto image = DlImageImpeller::Make(CreateTextureForFixture("kalimba.jpg"));
232
233 // Use a source rect that is partially outside the bounds of the image.
234 auto source_rect = DlRect::MakeXYWH(
235 image->dimensions().fWidth * 0.25f, image->dimensions().fHeight * 0.4f,
236 image->dimensions().fWidth, image->dimensions().fHeight);
237
238 auto dest_rect = DlRect::MakeXYWH(100, 100, 600, 600);
239
240 DlPaint paint;
241 paint.setColor(DlColor::kMidGrey());
242 builder.DrawRect(dest_rect, paint);
243
244 builder.DrawImageRect(image, source_rect, dest_rect,
245 DlImageSampling::kNearestNeighbor);
246 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
247 }
248
249 TEST_P(AiksTest, CanRenderSimpleClips) {
250 DisplayListBuilder builder;
251 builder.Scale(GetContentScale().x, GetContentScale().y);
252 DlPaint paint;
253
254 paint.setColor(DlColor::kWhite());
255 builder.DrawPaint(paint);
256
257 auto draw = [&builder](const DlPaint& paint, Scalar x, Scalar y) {
258 builder.Save();
259 builder.Translate(x, y);
260 {
261 builder.Save();
262 builder.ClipRect(DlRect::MakeLTRB(50, 50, 150, 150));
263 builder.DrawPaint(paint);
264 builder.Restore();
265 }
266 {
267 builder.Save();
268 builder.ClipOval(DlRect::MakeLTRB(200, 50, 300, 150));
269 builder.DrawPaint(paint);
270 builder.Restore();
271 }
272 {
273 builder.Save();
274 builder.ClipRoundRect(
275 DlRoundRect::MakeRectXY(DlRect::MakeLTRB(50, 200, 150, 300), 20, 20));
276 builder.DrawPaint(paint);
277 builder.Restore();
278 }
279 {
280 builder.Save();
281 builder.ClipRoundRect(DlRoundRect::MakeRectXY(
282 DlRect::MakeLTRB(200, 230, 300, 270), 20, 20));
283 builder.DrawPaint(paint);
284 builder.Restore();
285 }
286 {
287 builder.Save();
288 builder.ClipRoundRect(DlRoundRect::MakeRectXY(
289 DlRect::MakeLTRB(230, 200, 270, 300), 20, 20));
290 builder.DrawPaint(paint);
291 builder.Restore();
292 }
293 builder.Restore();
294 };
295
296 paint.setColor(DlColor::kBlue());
297 draw(paint, 0, 0);
298
299 DlColor gradient_colors[7] = {
300 DlColor::RGBA(0x1f / 255.0, 0.0, 0x5c / 255.0, 1.0),
301 DlColor::RGBA(0x5b / 255.0, 0.0, 0x60 / 255.0, 1.0),
302 DlColor::RGBA(0x87 / 255.0, 0x01 / 255.0, 0x60 / 255.0, 1.0),
303 DlColor::RGBA(0xac / 255.0, 0x25 / 255.0, 0x53 / 255.0, 1.0),
304 DlColor::RGBA(0xe1 / 255.0, 0x6b / 255.0, 0x5c / 255.0, 1.0),
305 DlColor::RGBA(0xf3 / 255.0, 0x90 / 255.0, 0x60 / 255.0, 1.0),
306 DlColor::RGBA(0xff / 255.0, 0xb5 / 255.0, 0x6b / 250.0, 1.0),
307 };
308 Scalar stops[7] = {
309 0.0,
310 (1.0 / 6.0) * 1,
311 (1.0 / 6.0) * 2,
312 (1.0 / 6.0) * 3,
313 (1.0 / 6.0) * 4,
314 (1.0 / 6.0) * 5,
315 1.0,
316 };
317 auto texture = CreateTextureForFixture("airplane.jpg",
318 /*enable_mipmapping=*/true);
319 auto image = DlImageImpeller::Make(texture);
320
321 paint.setColorSource(DlColorSource::MakeRadial(
322 DlPoint(500, 600), 75, 7, gradient_colors, stops, DlTileMode::kMirror));
323 draw(paint, 0, 300);
324
325 paint.setColorSource(
326 DlColorSource::MakeImage(image, DlTileMode::kRepeat, DlTileMode::kRepeat,
327 DlImageSampling::kNearestNeighbor));
328 draw(paint, 300, 0);
329
330 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
331 }
332
333 TEST_P(AiksTest, CanSaveLayerStandalone) {
334 DisplayListBuilder builder;
335
336 DlPaint red;
337 red.setColor(DlColor::kRed());
338
339 DlPaint alpha;
340 alpha.setColor(DlColor::kRed().modulateOpacity(0.5));
341
342 builder.SaveLayer(std::nullopt, &alpha);
343
344 builder.DrawCircle(DlPoint(125, 125), 125, red);
345
346 builder.Restore();
347
348 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
349 }
350
351 TEST_P(AiksTest, CanRenderDifferentShapesWithSameColorSource) {
352 DisplayListBuilder builder;
353 DlPaint paint;
354
355 DlColor colors[2] = {
356 DlColor::RGBA(0.9568, 0.2627, 0.2118, 1.0),
357 DlColor::RGBA(0.1294, 0.5882, 0.9529, 1.0),
358 };
359 DlScalar stops[2] = {
360 0.0,
361 1.0,
362 };
363
364 paint.setColorSource(DlColorSource::MakeLinear(
365 /*start_point=*/DlPoint(0, 0), //
366 /*end_point=*/DlPoint(100, 100), //
367 /*stop_count=*/2, //
368 /*colors=*/colors, //
369 /*stops=*/stops, //
370 /*tile_mode=*/DlTileMode::kRepeat //
371 ));
372
373 builder.Save();
374 builder.Translate(100, 100);
375 builder.DrawRect(DlRect::MakeXYWH(0, 0, 200, 200), paint);
376 builder.Restore();
377
378 builder.Save();
379 builder.Translate(100, 400);
380 builder.DrawCircle(DlPoint(100, 100), 100, paint);
381 builder.Restore();
382 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
383 }
384
385 TEST_P(AiksTest, CanRenderRoundedRectWithNonUniformRadii) {
386 DisplayListBuilder builder;
387 DlPaint paint;
388 paint.setColor(DlColor::kRed());
389
390 RoundingRadii radii = {
391 .top_left = DlSize(50, 25),
392 .top_right = DlSize(25, 50),
393 .bottom_left = DlSize(25, 50),
394 .bottom_right = DlSize(50, 25),
395 };
396 DlRoundRect rrect =
397 DlRoundRect::MakeRectRadii(DlRect::MakeXYWH(100, 100, 500, 500), radii);
398
399 builder.DrawRoundRect(rrect, paint);
400
401 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
402 }
403
404 TEST_P(AiksTest, CanDrawPaint) {
405 auto medium_turquoise =
406 DlColor::RGBA(72.0f / 255.0f, 209.0f / 255.0f, 204.0f / 255.0f, 1.0f);
407
408 DisplayListBuilder builder;
409 builder.Scale(0.2, 0.2);
410 builder.DrawPaint(DlPaint().setColor(medium_turquoise));
411 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
412 }
413
414 TEST_P(AiksTest, CanDrawPaintMultipleTimes) {
415 auto medium_turquoise =
416 DlColor::RGBA(72.0f / 255.0f, 209.0f / 255.0f, 204.0f / 255.0f, 1.0f);
417 auto orange_red =
418 DlColor::RGBA(255.0f / 255.0f, 69.0f / 255.0f, 0.0f / 255.0f, 1.0f);
419
420 DisplayListBuilder builder;
421 builder.Scale(0.2, 0.2);
422 builder.DrawPaint(DlPaint().setColor(medium_turquoise));
423 builder.DrawPaint(DlPaint().setColor(orange_red.modulateOpacity(0.5f)));
424 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
425 }
426
427 TEST_P(AiksTest, FilledCirclesRenderCorrectly) {
428 DisplayListBuilder builder;
429 builder.Scale(GetContentScale().x, GetContentScale().y);
430 DlPaint paint;
431 const int color_count = 3;
432 DlColor colors[color_count] = {
433 DlColor::kBlue(),
434 DlColor::kGreen(),
435 DlColor::RGBA(220.0f / 255.0f, 20.0f / 255.0f, 60.0f / 255.0f, 1.0f),
436 };
437
438 paint.setColor(DlColor::kWhite());
439 builder.DrawPaint(paint);
440
441 int c_index = 0;
442 int radius = 600;
443 while (radius > 0) {
444 paint.setColor(colors[(c_index++) % color_count]);
445 builder.DrawCircle(DlPoint(10, 10), radius, paint);
446 if (radius > 30) {
447 radius -= 10;
448 } else {
449 radius -= 2;
450 }
451 }
452
453 DlColor gradient_colors[7] = {
454 DlColor::RGBA(0x1f / 255.0, 0.0, 0x5c / 255.0, 1.0),
455 DlColor::RGBA(0x5b / 255.0, 0.0, 0x60 / 255.0, 1.0),
456 DlColor::RGBA(0x87 / 255.0, 0x01 / 255.0, 0x60 / 255.0, 1.0),
457 DlColor::RGBA(0xac / 255.0, 0x25 / 255.0, 0x53 / 255.0, 1.0),
458 DlColor::RGBA(0xe1 / 255.0, 0x6b / 255.0, 0x5c / 255.0, 1.0),
459 DlColor::RGBA(0xf3 / 255.0, 0x90 / 255.0, 0x60 / 255.0, 1.0),
460 DlColor::RGBA(0xff / 255.0, 0xb5 / 255.0, 0x6b / 250.0, 1.0),
461 };
462 DlScalar stops[7] = {
463 0.0,
464 (1.0 / 6.0) * 1,
465 (1.0 / 6.0) * 2,
466 (1.0 / 6.0) * 3,
467 (1.0 / 6.0) * 4,
468 (1.0 / 6.0) * 5,
469 1.0,
470 };
471 auto texture = CreateTextureForFixture("airplane.jpg",
472 /*enable_mipmapping=*/true);
473 auto image = DlImageImpeller::Make(texture);
474
475 paint.setColorSource(DlColorSource::MakeRadial(
476 DlPoint(500, 600), 75, 7, gradient_colors, stops, DlTileMode::kMirror));
477 builder.DrawCircle(DlPoint(500, 600), 100, paint);
478
479 DlMatrix local_matrix = DlMatrix::MakeTranslation({700, 200});
480 paint.setColorSource(DlColorSource::MakeImage(
481 image, DlTileMode::kRepeat, DlTileMode::kRepeat,
482 DlImageSampling::kNearestNeighbor, &local_matrix));
483 builder.DrawCircle(DlPoint(800, 300), 100, paint);
484
485 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
486 }
487
488 TEST_P(AiksTest, StrokedCirclesRenderCorrectly) {
489 DisplayListBuilder builder;
490 builder.Scale(GetContentScale().x, GetContentScale().y);
491 DlPaint paint;
492 const int color_count = 3;
493 DlColor colors[color_count] = {
494 DlColor::kBlue(),
495 DlColor::kGreen(),
496 DlColor::RGBA(220.0f / 255.0f, 20.0f / 255.0f, 60.0f / 255.0f, 1.0f),
497 };
498
499 paint.setColor(DlColor::kWhite());
500 builder.DrawPaint(paint);
501
502 int c_index = 0;
503
504 auto draw = [&paint, &colors, &c_index](DlCanvas& canvas, DlPoint center,
505 Scalar r, Scalar dr, int n) {
506 for (int i = 0; i < n; i++) {
507 paint.setColor(colors[(c_index++) % color_count]);
508 canvas.DrawCircle(center, r, paint);
509 r += dr;
510 }
511 };
512
513 paint.setDrawStyle(DlDrawStyle::kStroke);
514 paint.setStrokeWidth(1);
515 draw(builder, DlPoint(10, 10), 2, 2, 14); // r = [2, 28], covers [1,29]
516 paint.setStrokeWidth(5);
517 draw(builder, DlPoint(10, 10), 35, 10, 56); // r = [35, 585], covers [30,590]
518
519 DlColor gradient_colors[7] = {
520 DlColor::RGBA(0x1f / 255.0, 0.0, 0x5c / 255.0, 1.0),
521 DlColor::RGBA(0x5b / 255.0, 0.0, 0x60 / 255.0, 1.0),
522 DlColor::RGBA(0x87 / 255.0, 0x01 / 255.0, 0x60 / 255.0, 1.0),
523 DlColor::RGBA(0xac / 255.0, 0x25 / 255.0, 0x53 / 255.0, 1.0),
524 DlColor::RGBA(0xe1 / 255.0, 0x6b / 255.0, 0x5c / 255.0, 1.0),
525 DlColor::RGBA(0xf3 / 255.0, 0x90 / 255.0, 0x60 / 255.0, 1.0),
526 DlColor::RGBA(0xff / 255.0, 0xb5 / 255.0, 0x6b / 250.0, 1.0),
527 };
528 DlScalar stops[7] = {
529 0.0,
530 (1.0 / 6.0) * 1,
531 (1.0 / 6.0) * 2,
532 (1.0 / 6.0) * 3,
533 (1.0 / 6.0) * 4,
534 (1.0 / 6.0) * 5,
535 1.0,
536 };
537 auto texture = CreateTextureForFixture("airplane.jpg",
538 /*enable_mipmapping=*/true);
539 auto image = DlImageImpeller::Make(texture);
540
541 paint.setColorSource(DlColorSource::MakeRadial(
542 DlPoint(500, 600), 75, 7, gradient_colors, stops, DlTileMode::kMirror));
543 draw(builder, DlPoint(500, 600), 5, 10, 10);
544
545 DlMatrix local_matrix = DlMatrix::MakeTranslation({700, 200});
546 paint.setColorSource(DlColorSource::MakeImage(
547 image, DlTileMode::kRepeat, DlTileMode::kRepeat,
548 DlImageSampling::kNearestNeighbor, &local_matrix));
549 draw(builder, DlPoint(800, 300), 5, 10, 10);
550
551 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
552 }
553
554 TEST_P(AiksTest, FilledEllipsesRenderCorrectly) {
555 DisplayListBuilder builder;
556 builder.Scale(GetContentScale().x, GetContentScale().y);
557 DlPaint paint;
558 const int color_count = 3;
559 DlColor colors[color_count] = {
560 DlColor::kBlue(),
561 DlColor::kGreen(),
562 DlColor::RGBA(220.0f / 255.0f, 20.0f / 255.0f, 60.0f / 255.0f, 1.0f),
563 };
564
565 paint.setColor(DlColor::kWhite());
566 builder.DrawPaint(paint);
567
568 int c_index = 0;
569 int long_radius = 600;
570 int short_radius = 600;
571 while (long_radius > 0 && short_radius > 0) {
572 paint.setColor(colors[(c_index++) % color_count]);
573 builder.DrawOval(DlRect::MakeXYWH(10 - long_radius, 10 - short_radius,
574 long_radius * 2, short_radius * 2),
575 paint);
576 builder.DrawOval(DlRect::MakeXYWH(1000 - short_radius, 750 - long_radius,
577 short_radius * 2, long_radius * 2),
578 paint);
579 if (short_radius > 30) {
580 short_radius -= 10;
581 long_radius -= 5;
582 } else {
583 short_radius -= 2;
584 long_radius -= 1;
585 }
586 }
587
588 DlColor gradient_colors[7] = {
589 DlColor::RGBA(0x1f / 255.0, 0.0, 0x5c / 255.0, 1.0),
590 DlColor::RGBA(0x5b / 255.0, 0.0, 0x60 / 255.0, 1.0),
591 DlColor::RGBA(0x87 / 255.0, 0x01 / 255.0, 0x60 / 255.0, 1.0),
592 DlColor::RGBA(0xac / 255.0, 0x25 / 255.0, 0x53 / 255.0, 1.0),
593 DlColor::RGBA(0xe1 / 255.0, 0x6b / 255.0, 0x5c / 255.0, 1.0),
594 DlColor::RGBA(0xf3 / 255.0, 0x90 / 255.0, 0x60 / 255.0, 1.0),
595 DlColor::RGBA(0xff / 255.0, 0xb5 / 255.0, 0x6b / 250.0, 1.0),
596 };
597 DlScalar stops[7] = {
598 0.0,
599 (1.0 / 6.0) * 1,
600 (1.0 / 6.0) * 2,
601 (1.0 / 6.0) * 3,
602 (1.0 / 6.0) * 4,
603 (1.0 / 6.0) * 5,
604 1.0,
605 };
606 auto texture = CreateTextureForFixture("airplane.jpg",
607 /*enable_mipmapping=*/true);
608 auto image = DlImageImpeller::Make(texture);
609
610 paint.setColor(DlColor::kWhite().modulateOpacity(0.5));
611
612 paint.setColorSource(DlColorSource::MakeRadial(
613 DlPoint(300, 650), 75, 7, gradient_colors, stops, DlTileMode::kMirror));
614 builder.DrawOval(DlRect::MakeXYWH(200, 625, 200, 50), paint);
615 builder.DrawOval(DlRect::MakeXYWH(275, 550, 50, 200), paint);
616
617 DlMatrix local_matrix = DlMatrix::MakeTranslation({610, 15});
618 paint.setColorSource(DlColorSource::MakeImage(
619 image, DlTileMode::kRepeat, DlTileMode::kRepeat,
620 DlImageSampling::kNearestNeighbor, &local_matrix));
621 builder.DrawOval(DlRect::MakeXYWH(610, 90, 200, 50), paint);
622 builder.DrawOval(DlRect::MakeXYWH(685, 15, 50, 200), paint);
623
624 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
625 }
626
627 TEST_P(AiksTest, FilledRoundRectsRenderCorrectly) {
628 DisplayListBuilder builder;
629 builder.Scale(GetContentScale().x, GetContentScale().y);
630 DlPaint paint;
631 const int color_count = 3;
632 DlColor colors[color_count] = {
633 DlColor::kBlue(),
634 DlColor::kGreen(),
635 DlColor::RGBA(220.0f / 255.0f, 20.0f / 255.0f, 60.0f / 255.0f, 1.0f),
636 };
637
638 paint.setColor(DlColor::kWhite());
639 builder.DrawPaint(paint);
640
641 int c_index = 0;
642 for (int i = 0; i < 4; i++) {
643 for (int j = 0; j < 4; j++) {
644 paint.setColor(colors[(c_index++) % color_count]);
645 builder.DrawRoundRect(
646 DlRoundRect::MakeRectXY(
647 DlRect::MakeXYWH(i * 100 + 10, j * 100 + 20, 80, 80), //
648 i * 5 + 10, j * 5 + 10),
649 paint);
650 }
651 }
652 paint.setColor(colors[(c_index++) % color_count]);
653 builder.DrawRoundRect(
654 DlRoundRect::MakeRectXY(DlRect::MakeXYWH(10, 420, 380, 80), 40, 40),
655 paint);
656 paint.setColor(colors[(c_index++) % color_count]);
657 builder.DrawRoundRect(
658 DlRoundRect::MakeRectXY(DlRect::MakeXYWH(410, 20, 80, 380), 40, 40),
659 paint);
660
661 DlColor gradient_colors[7] = {
662 DlColor::RGBA(0x1f / 255.0, 0.0, 0x5c / 255.0, 1.0),
663 DlColor::RGBA(0x5b / 255.0, 0.0, 0x60 / 255.0, 1.0),
664 DlColor::RGBA(0x87 / 255.0, 0x01 / 255.0, 0x60 / 255.0, 1.0),
665 DlColor::RGBA(0xac / 255.0, 0x25 / 255.0, 0x53 / 255.0, 1.0),
666 DlColor::RGBA(0xe1 / 255.0, 0x6b / 255.0, 0x5c / 255.0, 1.0),
667 DlColor::RGBA(0xf3 / 255.0, 0x90 / 255.0, 0x60 / 255.0, 1.0),
668 DlColor::RGBA(0xff / 255.0, 0xb5 / 255.0, 0x6b / 250.0, 1.0),
669 };
670 DlScalar stops[7] = {
671 0.0,
672 (1.0 / 6.0) * 1,
673 (1.0 / 6.0) * 2,
674 (1.0 / 6.0) * 3,
675 (1.0 / 6.0) * 4,
676 (1.0 / 6.0) * 5,
677 1.0,
678 };
679 auto texture = CreateTextureForFixture("airplane.jpg",
680 /*enable_mipmapping=*/true);
681 auto image = DlImageImpeller::Make(texture);
682
683 paint.setColor(DlColor::kWhite().modulateOpacity(0.1));
684 paint.setColorSource(DlColorSource::MakeRadial(
685 DlPoint(550, 550), 75, 7, gradient_colors, stops, DlTileMode::kMirror));
686 for (int i = 1; i <= 10; i++) {
687 int j = 11 - i;
688 builder.DrawRoundRect(
689 DlRoundRect::MakeRectXY(DlRect::MakeLTRB(550 - i * 20, 550 - j * 20, //
690 550 + i * 20, 550 + j * 20),
691 i * 10, j * 10),
692 paint);
693 }
694
695 paint.setColor(DlColor::kWhite().modulateOpacity(0.5));
696 paint.setColorSource(DlColorSource::MakeRadial(
697 DlPoint(200, 650), 75, 7, gradient_colors, stops, DlTileMode::kMirror));
698 paint.setColor(DlColor::kWhite().modulateOpacity(0.5));
699 builder.DrawRoundRect(
700 DlRoundRect::MakeRectXY(DlRect::MakeLTRB(100, 610, 300, 690), 40, 40),
701 paint);
702 builder.DrawRoundRect(
703 DlRoundRect::MakeRectXY(DlRect::MakeLTRB(160, 550, 240, 750), 40, 40),
704 paint);
705
706 paint.setColor(DlColor::kWhite().modulateOpacity(0.1));
707 DlMatrix local_matrix = DlMatrix::MakeTranslation({520, 20});
708 paint.setColorSource(DlColorSource::MakeImage(
709 image, DlTileMode::kRepeat, DlTileMode::kRepeat,
710 DlImageSampling::kNearestNeighbor, &local_matrix));
711 for (int i = 1; i <= 10; i++) {
712 int j = 11 - i;
713 builder.DrawRoundRect(
714 DlRoundRect::MakeRectXY(DlRect::MakeLTRB(720 - i * 20, 220 - j * 20, //
715 720 + i * 20, 220 + j * 20),
716 i * 10, j * 10),
717 paint);
718 }
719
720 paint.setColor(DlColor::kWhite().modulateOpacity(0.5));
721 local_matrix = DlMatrix::MakeTranslation({800, 300});
722 paint.setColorSource(DlColorSource::MakeImage(
723 image, DlTileMode::kRepeat, DlTileMode::kRepeat,
724 DlImageSampling::kNearestNeighbor, &local_matrix));
725 builder.DrawRoundRect(
726 DlRoundRect::MakeRectXY(DlRect::MakeLTRB(800, 410, 1000, 490), 40, 40),
727 paint);
728 builder.DrawRoundRect(
729 DlRoundRect::MakeRectXY(DlRect::MakeLTRB(860, 350, 940, 550), 40, 40),
730 paint);
731
732 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
733 }
734
735 TEST_P(AiksTest, SolidColorCirclesOvalsRRectsMaskBlurCorrectly) {
736 DisplayListBuilder builder;
737 builder.Scale(GetContentScale().x, GetContentScale().y);
738 DlPaint paint;
739 paint.setMaskFilter(DlBlurMaskFilter::Make(DlBlurStyle::kNormal, 1.0f));
740
741 builder.DrawPaint(DlPaint().setColor(DlColor::kWhite()));
742
743 paint.setColor(
744 DlColor::RGBA(220.0f / 255.0f, 20.0f / 255.0f, 60.0f / 255.0f, 1.0f));
745 Scalar y = 100.0f;
746 for (int i = 0; i < 5; i++) {
747 Scalar x = (i + 1) * 100;
748 Scalar radius = x / 10.0f;
749 builder.DrawRect(DlRect::MakeXYWH(x + 25 - radius / 2, y + radius / 2, //
750 radius, 60.0f - radius),
751 paint);
752 }
753
754 paint.setColor(DlColor::kBlue());
755 y += 100.0f;
756 for (int i = 0; i < 5; i++) {
757 Scalar x = (i + 1) * 100;
758 Scalar radius = x / 10.0f;
759 builder.DrawCircle(DlPoint(x + 25, y + 25), radius, paint);
760 }
761
762 paint.setColor(DlColor::kGreen());
763 y += 100.0f;
764 for (int i = 0; i < 5; i++) {
765 Scalar x = (i + 1) * 100;
766 Scalar radius = x / 10.0f;
767 builder.DrawOval(DlRect::MakeXYWH(x + 25 - radius / 2, y + radius / 2, //
768 radius, 60.0f - radius),
769 paint);
770 }
771
772 paint.setColor(
773 DlColor::RGBA(128.0f / 255.0f, 0.0f / 255.0f, 128.0f / 255.0f, 1.0f));
774 y += 100.0f;
775 for (int i = 0; i < 5; i++) {
776 Scalar x = (i + 1) * 100;
777 Scalar radius = x / 20.0f;
778 builder.DrawRoundRect(
779 DlRoundRect::MakeRectXY(DlRect::MakeXYWH(x, y, 60.0f, 60.0f), //
780 radius, radius),
781 paint);
782 }
783
784 paint.setColor(
785 DlColor::RGBA(255.0f / 255.0f, 165.0f / 255.0f, 0.0f / 255.0f, 1.0f));
786 y += 100.0f;
787 for (int i = 0; i < 5; i++) {
788 Scalar x = (i + 1) * 100;
789 Scalar radius = x / 20.0f;
790 builder.DrawRoundRect(
791 DlRoundRect::MakeRectXY(DlRect::MakeXYWH(x, y, 60.0f, 60.0f), //
792 radius, 5.0f),
793 paint);
794 }
795
796 auto dl = builder.Build();
797 ASSERT_TRUE(OpenPlaygroundHere(dl));
798 }
799
800 TEST_P(AiksTest, CanRenderClippedBackdropFilter) {
801 DisplayListBuilder builder;
802
803 builder.Scale(GetContentScale().x, GetContentScale().y);
804
805 // Draw something interesting in the background.
806 std::vector<DlColor> colors = {DlColor::RGBA(0.9568, 0.2627, 0.2118, 1.0),
807 DlColor::RGBA(0.1294, 0.5882, 0.9529, 1.0)};
808 std::vector<Scalar> stops = {
809 0.0,
810 1.0,
811 };
812 DlPaint paint;
813 paint.setColorSource(DlColorSource::MakeLinear(
814 /*start_point=*/DlPoint(0, 0), //
815 /*end_point=*/DlPoint(100, 100), //
816 /*stop_count=*/2, //
817 /*colors=*/colors.data(), //
818 /*stops=*/stops.data(), //
819 /*tile_mode=*/DlTileMode::kRepeat //
820 ));
821
822 builder.DrawPaint(paint);
823
824 DlRect clip_rect = DlRect::MakeLTRB(50, 50, 400, 300);
825 DlRoundRect clip_rrect = DlRoundRect::MakeRectXY(clip_rect, 100, 100);
826
827 // Draw a clipped SaveLayer, where the clip coverage and SaveLayer size are
828 // the same.
829 builder.ClipRoundRect(clip_rrect, DlClipOp::kIntersect);
830
831 DlPaint save_paint;
832 auto backdrop_filter = DlImageFilter::MakeColorFilter(
833 DlColorFilter::MakeBlend(DlColor::kRed(), DlBlendMode::kExclusion));
834 builder.SaveLayer(clip_rect, &save_paint, backdrop_filter.get());
835
836 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
837 }
838
839 TEST_P(AiksTest, CanDrawPerspectiveTransformWithClips) {
840 // Avoiding `GetSecondsElapsed()` to reduce risk of golden flakiness.
841 int time = 0;
842 auto callback = [&]() -> sk_sp<DisplayList> {
843 DisplayListBuilder builder;
844
845 builder.Save();
846 {
847 builder.Translate(300, 300);
848
849 // 1. Draw/restore a clip before drawing the image, which will get drawn
850 // to the depth buffer behind the image.
851 builder.Save();
852 {
853 DlPaint paint;
854 paint.setColor(DlColor::kGreen());
855 builder.DrawPaint(paint);
856 builder.ClipRect(DlRect::MakeLTRB(-180, -180, 180, 180),
857 DlClipOp::kDifference);
858
859 paint.setColor(DlColor::kBlack());
860 builder.DrawPaint(paint);
861 }
862 builder.Restore(); // Restore rectangle difference clip.
863
864 builder.Save();
865 {
866 // 2. Draw an oval clip that applies to the image, which will get drawn
867 // in front of the image on the depth buffer.
868 builder.ClipOval(DlRect::MakeLTRB(-200, -200, 200, 200));
869
870 Matrix result =
871 Matrix(1.0, 0.0, 0.0, 0.0, //
872 0.0, 1.0, 0.0, 0.0, //
873 0.0, 0.0, 1.0, 0.003, //
874 0.0, 0.0, 0.0, 1.0) *
875 Matrix::MakeRotationY({Radians{-1.0f + (time++ / 60.0f)}});
876
877 // 3. Draw the rotating image with a perspective transform.
878 builder.Transform(result);
879
880 auto image =
881 DlImageImpeller::Make(CreateTextureForFixture("airplane.jpg"));
882 auto position =
883 -DlPoint(image->dimensions().fWidth, image->dimensions().fHeight) *
884 0.5;
885 builder.DrawImage(image, position, {});
886 }
887 builder.Restore(); // Restore oval intersect clip.
888
889 // 4. Draw a semi-translucent blue circle atop all previous draws.
890 DlPaint paint;
891 paint.setColor(DlColor::kBlue().modulateOpacity(0.4));
892 builder.DrawCircle(DlPoint(), 230, paint);
893 }
894 builder.Restore(); // Restore translation.
895
896 return builder.Build();
897 };
898 ASSERT_TRUE(OpenPlaygroundHere(callback));
899 }
900
901 TEST_P(AiksTest, ImageColorSourceEffectTransform) {
902 // Compare with https://fiddle.skia.org/c/6cdc5aefb291fda3833b806ca347a885
903
904 DisplayListBuilder builder;
905 auto texture = DlImageImpeller::Make(CreateTextureForFixture("monkey.png"));
906
907 DlPaint paint;
908 paint.setColor(DlColor::kWhite());
909 builder.DrawPaint(paint);
910
911 // Translation
912 {
913 DlMatrix matrix = DlMatrix::MakeTranslation({50, 50});
914 DlPaint paint;
915 paint.setColorSource(DlColorSource::MakeImage(
916 texture, DlTileMode::kRepeat, DlTileMode::kRepeat,
917 DlImageSampling::kNearestNeighbor, &matrix));
918
919 builder.DrawRect(DlRect::MakeLTRB(0, 0, 100, 100), paint);
920 }
921
922 // Rotation/skew
923 {
924 builder.Save();
925 builder.Rotate(45);
926 DlPaint paint;
927
928 Matrix matrix(1, -1, 0, 0, //
929 1, 1, 0, 0, //
930 0, 0, 1, 0, //
931 0, 0, 0, 1);
932 paint.setColorSource(DlColorSource::MakeImage(
933 texture, DlTileMode::kRepeat, DlTileMode::kRepeat,
934 DlImageSampling::kNearestNeighbor, &matrix));
935 builder.DrawRect(DlRect::MakeLTRB(100, 0, 200, 100), paint);
936 builder.Restore();
937 }
938
939 // Scale
940 {
941 builder.Save();
942 builder.Translate(100, 0);
943 builder.Scale(100, 100);
944 DlPaint paint;
945
946 DlMatrix matrix = DlMatrix::MakeScale({0.005, 0.005, 1});
947 paint.setColorSource(DlColorSource::MakeImage(
948 texture, DlTileMode::kRepeat, DlTileMode::kRepeat,
949 DlImageSampling::kNearestNeighbor, &matrix));
950
951 builder.DrawRect(DlRect::MakeLTRB(0, 0, 1, 1), paint);
952 builder.Restore();
953 }
954
955 // Perspective
956 {
957 builder.Save();
958 builder.Translate(150, 150);
959 DlPaint paint;
960
961 DlMatrix matrix =
962 DlMatrix::MakePerspective(Radians{0.5}, ISize{200, 200}, 0.05, 1);
963 paint.setColorSource(DlColorSource::MakeImage(
964 texture, DlTileMode::kRepeat, DlTileMode::kRepeat,
965 DlImageSampling::kNearestNeighbor, &matrix));
966
967 builder.DrawRect(DlRect::MakeLTRB(0, 0, 200, 200), paint);
968 builder.Restore();
969 }
970
971 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
972 }
973
974 TEST_P(AiksTest, SubpassWithClearColorOptimization) {
975 DisplayListBuilder builder;
976
977 // Use a non-srcOver blend mode to ensure that we don't detect this as an
978 // opacity peephole optimization.
979 DlPaint paint;
980 paint.setColor(DlColor::kBlue().modulateOpacity(0.5));
981 paint.setBlendMode(DlBlendMode::kSrc);
982
983 DlRect bounds = DlRect::MakeLTRB(0, 0, 200, 200);
984 builder.SaveLayer(bounds, &paint);
985
986 paint.setColor(DlColor::kTransparent());
987 paint.setBlendMode(DlBlendMode::kSrc);
988 builder.DrawPaint(paint);
989 builder.Restore();
990
991 paint.setColor(DlColor::kBlue());
992 paint.setBlendMode(DlBlendMode::kDstOver);
993 builder.SaveLayer(std::nullopt, &paint);
994 builder.Restore();
995
996 // This playground should appear blank on CI since we are only drawing
997 // transparent black. If the clear color optimization is broken, the texture
998 // will be filled with NaNs and may produce a magenta texture on macOS or iOS.
999 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1000 }
1001
1002 // Render a white circle at the top left corner of the screen.
1003 TEST_P(AiksTest, MatrixImageFilterDoesntCullWhenTranslatedFromOffscreen) {
1004 DisplayListBuilder builder;
1005 builder.Scale(GetContentScale().x, GetContentScale().y);
1006 builder.Translate(100, 100);
1007 // Draw a circle in a SaveLayer at -300, but move it back on-screen with a
1008 // +300 translation applied by a SaveLayer image filter.
1009 DlPaint paint;
1010 DlMatrix translate = DlMatrix::MakeTranslation({300, 0});
1011 paint.setImageFilter(
1012 DlImageFilter::MakeMatrix(translate, DlImageSampling::kLinear));
1013 builder.SaveLayer(std::nullopt, &paint);
1014
1015 DlPaint circle_paint;
1016 circle_paint.setColor(DlColor::kGreen());
1017 builder.DrawCircle(DlPoint(-300, 0), 100, circle_paint);
1018 builder.Restore();
1019
1020 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1021 }
1022
1023 // Render a white circle at the top left corner of the screen.
1024 TEST_P(AiksTest,
1025 MatrixImageFilterDoesntCullWhenScaledAndTranslatedFromOffscreen) {
1026 DisplayListBuilder builder;
1027 builder.Scale(GetContentScale().x, GetContentScale().y);
1028 builder.Translate(100, 100);
1029 // Draw a circle in a SaveLayer at -300, but move it back on-screen with a
1030 // +300 translation applied by a SaveLayer image filter.
1031
1032 DlPaint paint;
1033 paint.setImageFilter(DlImageFilter::MakeMatrix(
1034 DlMatrix::MakeTranslation({300, 0}) * DlMatrix::MakeScale({2, 2, 1}),
1035 DlImageSampling::kNearestNeighbor));
1036 builder.SaveLayer(std::nullopt, &paint);
1037
1038 DlPaint circle_paint;
1039 circle_paint.setColor(DlColor::kGreen());
1040 builder.DrawCircle(DlPoint(-150, 0), 50, circle_paint);
1041 builder.Restore();
1042
1043 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1044 }
1045
1046 // This should be solid red, if you see a little red box this is broken.
1047 TEST_P(AiksTest, ClearColorOptimizationWhenSubpassIsBiggerThanParentPass) {
1048 SetWindowSize({400, 400});
1049 DisplayListBuilder builder;
1050
1051 builder.Scale(GetContentScale().x, GetContentScale().y);
1052
1053 DlPaint paint;
1054 paint.setColor(DlColor::kRed());
1055 builder.DrawRect(DlRect::MakeLTRB(200, 200, 300, 300), paint);
1056
1057 paint.setImageFilter(DlImageFilter::MakeMatrix(DlMatrix::MakeScale({2, 2, 1}),
1058 DlImageSampling::kLinear));
1059 builder.SaveLayer(std::nullopt, &paint);
1060 // Draw a rectangle that would fully cover the parent pass size, but not
1061 // the subpass that it is rendered in.
1062 paint.setColor(DlColor::kGreen());
1063 builder.DrawRect(DlRect::MakeLTRB(0, 0, 400, 400), paint);
1064 // Draw a bigger rectangle to force the subpass to be bigger.
1065
1066 paint.setColor(DlColor::kRed());
1067 builder.DrawRect(DlRect::MakeLTRB(0, 0, 800, 800), paint);
1068 builder.Restore();
1069
1070 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1071 }
1072
1073 TEST_P(AiksTest, EmptySaveLayerIgnoresPaint) {
1074 DisplayListBuilder builder;
1075 builder.Scale(GetContentScale().x, GetContentScale().y);
1076
1077 DlPaint paint;
1078 paint.setColor(DlColor::kRed());
1079 builder.DrawPaint(paint);
1080 builder.ClipRect(DlRect::MakeXYWH(100, 100, 200, 200));
1081 paint.setColor(DlColor::kBlue());
1082 builder.SaveLayer(std::nullopt, &paint);
1083 builder.Restore();
1084
1085 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1086 }
1087
1088 TEST_P(AiksTest, EmptySaveLayerRendersWithClear) {
1089 DisplayListBuilder builder;
1090 builder.Scale(GetContentScale().x, GetContentScale().y);
1091 auto image = DlImageImpeller::Make(CreateTextureForFixture("airplane.jpg"));
1092 builder.DrawImage(image, DlPoint(10, 10), {});
1093 builder.ClipRect(DlRect::MakeXYWH(100, 100, 200, 200));
1094
1095 DlPaint paint;
1096 paint.setBlendMode(DlBlendMode::kClear);
1097 builder.SaveLayer(std::nullopt, &paint);
1098 builder.Restore();
1099
1100 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1101 }
1102
1103 TEST_P(AiksTest,
1104 CanPerformSaveLayerWithBoundsAndLargerIntermediateIsNotAllocated) {
1105 DisplayListBuilder builder;
1106
1107 DlPaint red;
1108 red.setColor(DlColor::kRed());
1109
1110 DlPaint green;
1111 green.setColor(DlColor::kGreen());
1112
1113 DlPaint blue;
1114 blue.setColor(DlColor::kBlue());
1115
1116 DlPaint save;
1117 save.setColor(DlColor::kBlack().modulateOpacity(0.5));
1118
1119 DlRect huge_bounds = DlRect::MakeXYWH(0, 0, 100000, 100000);
1120 builder.SaveLayer(huge_bounds, &save);
1121
1122 builder.DrawRect(DlRect::MakeXYWH(0, 0, 100, 100), red);
1123 builder.DrawRect(DlRect::MakeXYWH(10, 10, 100, 100), green);
1124 builder.DrawRect(DlRect::MakeXYWH(20, 20, 100, 100), blue);
1125
1126 builder.Restore();
1127
1128 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1129 }
1130
1131 // This makes sure the WideGamut named tests use 16bit float pixel format.
1132 TEST_P(AiksTest, FormatWideGamut) {
1133 EXPECT_EQ(GetContext()->GetCapabilities()->GetDefaultColorFormat(),
1134 PixelFormat::kB10G10R10A10XR);
1135 }
1136
1137 TEST_P(AiksTest, FormatSRGB) {
1138 PixelFormat pixel_format =
1139 GetContext()->GetCapabilities()->GetDefaultColorFormat();
1140 EXPECT_TRUE(pixel_format == PixelFormat::kR8G8B8A8UNormInt ||
1141 pixel_format == PixelFormat::kB8G8R8A8UNormInt)
1142 << "pixel format: " << PixelFormatToString(pixel_format);
1143 }
1144
1145 TEST_P(AiksTest, CoordinateConversionsAreCorrect) {
1146 DisplayListBuilder builder;
1147
1148 // Render a texture directly.
1149 {
1150 auto image = DlImageImpeller::Make(CreateTextureForFixture("kalimba.jpg"));
1151
1152 builder.Save();
1153 builder.Translate(100, 200);
1154 builder.Scale(0.5, 0.5);
1155 builder.DrawImage(image, DlPoint(100.0, 100.0),
1156 DlImageSampling::kNearestNeighbor);
1157 builder.Restore();
1158 }
1159
1160 // Render an offscreen rendered texture.
1161 {
1162 DlPaint alpha;
1163 alpha.setColor(DlColor::kRed().modulateOpacity(0.5));
1164
1165 builder.SaveLayer(std::nullopt, &alpha);
1166
1167 DlPaint paint;
1168 paint.setColor(DlColor::kRed());
1169 builder.DrawRect(DlRect::MakeXYWH(000, 000, 100, 100), paint);
1170 paint.setColor(DlColor::kGreen());
1171 builder.DrawRect(DlRect::MakeXYWH(020, 020, 100, 100), paint);
1172 paint.setColor(DlColor::kBlue());
1173 builder.DrawRect(DlRect::MakeXYWH(040, 040, 100, 100), paint);
1174
1175 builder.Restore();
1176 }
1177
1178 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1179 }
1180
1181 TEST_P(AiksTest, CanPerformFullScreenMSAA) {
1182 DisplayListBuilder builder;
1183
1184 DlPaint paint;
1185 paint.setColor(DlColor::kRed());
1186 builder.DrawCircle(DlPoint(250, 250), 125, paint);
1187
1188 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1189 }
1190
1191 TEST_P(AiksTest, CanPerformSkew) {
1192 DisplayListBuilder builder;
1193
1194 DlPaint red;
1195 red.setColor(DlColor::kRed());
1196 builder.Skew(2, 5);
1197 builder.DrawRect(DlRect::MakeXYWH(0, 0, 100, 100), red);
1198
1199 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1200 }
1201
1202 TEST_P(AiksTest, CanPerformSaveLayerWithBounds) {
1203 DisplayListBuilder builder;
1204
1205 DlPaint save;
1206 save.setColor(DlColor::kBlack());
1207
1208 DlRect save_bounds = DlRect::MakeXYWH(0, 0, 50, 50);
1209 builder.SaveLayer(save_bounds, &save);
1210
1211 DlPaint paint;
1212 paint.setColor(DlColor::kRed());
1213 builder.DrawRect(DlRect::MakeXYWH(0, 0, 100, 100), paint);
1214 paint.setColor(DlColor::kGreen());
1215 builder.DrawRect(DlRect::MakeXYWH(10, 10, 100, 100), paint);
1216 paint.setColor(DlColor::kBlue());
1217 builder.DrawRect(DlRect::MakeXYWH(20, 20, 100, 100), paint);
1218
1219 builder.Restore();
1220
1221 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1222 }
1223
1224 TEST_P(AiksTest, FilledRoundRectPathsRenderCorrectly) {
1225 DisplayListBuilder builder;
1226 builder.Scale(GetContentScale().x, GetContentScale().y);
1227
1228 DlPaint paint;
1229 const int color_count = 3;
1230 DlColor colors[color_count] = {
1231 DlColor::kBlue(),
1232 DlColor::kGreen(),
1233 DlColor::ARGB(1.0, 220.0f / 255.0f, 20.0f / 255.0f, 60.0f / 255.0f),
1234 };
1235
1236 paint.setColor(DlColor::kWhite());
1237 builder.DrawPaint(paint);
1238
1239 auto draw_rrect_as_path = [&builder](const DlRect& rect, Scalar x, Scalar y,
1240 const DlPaint& paint) {
1241 builder.DrawPath(DlPath::MakeRoundRectXY(rect, x, y), paint);
1242 };
1243
1244 int c_index = 0;
1245 for (int i = 0; i < 4; i++) {
1246 for (int j = 0; j < 4; j++) {
1247 paint.setColor(colors[(c_index++) % color_count]);
1248 draw_rrect_as_path(DlRect::MakeXYWH(i * 100 + 10, j * 100 + 20, 80, 80),
1249 i * 5 + 10, j * 5 + 10, paint);
1250 }
1251 }
1252 paint.setColor(colors[(c_index++) % color_count]);
1253 draw_rrect_as_path(DlRect::MakeXYWH(10, 420, 380, 80), 40, 40, paint);
1254 paint.setColor(colors[(c_index++) % color_count]);
1255 draw_rrect_as_path(DlRect::MakeXYWH(410, 20, 80, 380), 40, 40, paint);
1256
1257 std::vector<DlColor> gradient_colors = {
1258 DlColor::RGBA(0x1f / 255.0, 0.0, 0x5c / 255.0, 1.0),
1259 DlColor::RGBA(0x5b / 255.0, 0.0, 0x60 / 255.0, 1.0),
1260 DlColor::RGBA(0x87 / 255.0, 0x01 / 255.0, 0x60 / 255.0, 1.0),
1261 DlColor::RGBA(0xac / 255.0, 0x25 / 255.0, 0x53 / 255.0, 1.0),
1262 DlColor::RGBA(0xe1 / 255.0, 0x6b / 255.0, 0x5c / 255.0, 1.0),
1263 DlColor::RGBA(0xf3 / 255.0, 0x90 / 255.0, 0x60 / 255.0, 1.0),
1264 DlColor::RGBA(0xff / 255.0, 0xb5 / 255.0, 0x6b / 250.0, 1.0)};
1265 std::vector<Scalar> stops = {
1266 0.0,
1267 (1.0 / 6.0) * 1,
1268 (1.0 / 6.0) * 2,
1269 (1.0 / 6.0) * 3,
1270 (1.0 / 6.0) * 4,
1271 (1.0 / 6.0) * 5,
1272 1.0,
1273 };
1274 auto texture = DlImageImpeller::Make(
1275 CreateTextureForFixture("airplane.jpg",
1276 /*enable_mipmapping=*/true));
1277
1278 paint.setColor(DlColor::kWhite().modulateOpacity(0.1));
1279 paint.setColorSource(DlColorSource::MakeRadial(
1280 /*center=*/DlPoint(550, 550),
1281 /*radius=*/75,
1282 /*stop_count=*/gradient_colors.size(),
1283 /*colors=*/gradient_colors.data(),
1284 /*stops=*/stops.data(),
1285 /*tile_mode=*/DlTileMode::kMirror));
1286 for (int i = 1; i <= 10; i++) {
1287 int j = 11 - i;
1288 draw_rrect_as_path(DlRect::MakeLTRB(550 - i * 20, 550 - j * 20, //
1289 550 + i * 20, 550 + j * 20),
1290 i * 10, j * 10, paint);
1291 }
1292 paint.setColor(DlColor::kWhite().modulateOpacity(0.5));
1293 paint.setColorSource(DlColorSource::MakeRadial(
1294 /*center=*/DlPoint(200, 650),
1295 /*radius=*/75,
1296 /*stop_count=*/gradient_colors.size(),
1297 /*colors=*/gradient_colors.data(),
1298 /*stops=*/stops.data(),
1299 /*tile_mode=*/DlTileMode::kMirror));
1300 draw_rrect_as_path(DlRect::MakeLTRB(100, 610, 300, 690), 40, 40, paint);
1301 draw_rrect_as_path(DlRect::MakeLTRB(160, 550, 240, 750), 40, 40, paint);
1302
1303 auto matrix = DlMatrix::MakeTranslation({520, 20});
1304 paint.setColor(DlColor::kWhite().modulateOpacity(0.1));
1305 paint.setColorSource(DlColorSource::MakeImage(
1306 texture, DlTileMode::kRepeat, DlTileMode::kRepeat,
1307 DlImageSampling::kMipmapLinear, &matrix));
1308 for (int i = 1; i <= 10; i++) {
1309 int j = 11 - i;
1310 draw_rrect_as_path(DlRect::MakeLTRB(720 - i * 20, 220 - j * 20, //
1311 720 + i * 20, 220 + j * 20),
1312 i * 10, j * 10, paint);
1313 }
1314 matrix = DlMatrix::MakeTranslation({800, 300});
1315 paint.setColor(DlColor::kWhite().modulateOpacity(0.5));
1316 paint.setColorSource(DlColorSource::MakeImage(
1317 texture, DlTileMode::kRepeat, DlTileMode::kRepeat,
1318 DlImageSampling::kMipmapLinear, &matrix));
1319
1320 draw_rrect_as_path(DlRect::MakeLTRB(800, 410, 1000, 490), 40, 40, paint);
1321 draw_rrect_as_path(DlRect::MakeLTRB(860, 350, 940, 550), 40, 40, paint);
1322
1323 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1324 }
1325
1326 TEST_P(AiksTest, CoverageOriginShouldBeAccountedForInSubpasses) {
1327 auto callback = [&]() -> sk_sp<DisplayList> {
1328 DisplayListBuilder builder;
1329 builder.Scale(GetContentScale().x, GetContentScale().y);
1330
1331 DlPaint alpha;
1332 alpha.setColor(DlColor::kRed().modulateOpacity(0.5));
1333
1334 auto current = Point{25, 25};
1335 const auto offset = Point{25, 25};
1336 const auto size = Size(100, 100);
1337
1338 static PlaygroundPoint point_a(Point(40, 40), 10, Color::White());
1339 static PlaygroundPoint point_b(Point(160, 160), 10, Color::White());
1340 auto [b0, b1] = DrawPlaygroundLine(point_a, point_b);
1341 DlRect bounds = DlRect::MakeLTRB(b0.x, b0.y, b1.x, b1.y);
1342
1343 DlPaint stroke_paint;
1344 stroke_paint.setColor(DlColor::kYellow());
1345 stroke_paint.setStrokeWidth(5);
1346 stroke_paint.setDrawStyle(DlDrawStyle::kStroke);
1347 builder.DrawRect(bounds, stroke_paint);
1348
1349 builder.SaveLayer(bounds, &alpha);
1350
1351 DlPaint paint;
1352 paint.setColor(DlColor::kRed());
1353 builder.DrawRect(
1354 DlRect::MakeXYWH(current.x, current.y, size.width, size.height), paint);
1355
1356 paint.setColor(DlColor::kGreen());
1357 current += offset;
1358 builder.DrawRect(
1359 DlRect::MakeXYWH(current.x, current.y, size.width, size.height), paint);
1360
1361 paint.setColor(DlColor::kBlue());
1362 current += offset;
1363 builder.DrawRect(
1364 DlRect::MakeXYWH(current.x, current.y, size.width, size.height), paint);
1365
1366 builder.Restore();
1367
1368 return builder.Build();
1369 };
1370
1371 ASSERT_TRUE(OpenPlaygroundHere(callback));
1372 }
1373
1374 TEST_P(AiksTest, SaveLayerDrawsBehindSubsequentEntities) {
1375 // Compare with https://fiddle.skia.org/c/9e03de8567ffb49e7e83f53b64bcf636
1376 DisplayListBuilder builder;
1377 DlPaint paint;
1378
1379 paint.setColor(DlColor::kBlack());
1380 DlRect rect = DlRect::MakeXYWH(25, 25, 25, 25);
1381 builder.DrawRect(rect, paint);
1382
1383 builder.Translate(10, 10);
1384
1385 DlPaint save_paint;
1386 builder.SaveLayer(std::nullopt, &save_paint);
1387
1388 paint.setColor(DlColor::kGreen());
1389 builder.DrawRect(rect, paint);
1390
1391 builder.Restore();
1392
1393 builder.Translate(10, 10);
1394 paint.setColor(DlColor::kRed());
1395 builder.DrawRect(rect, paint);
1396
1397 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1398 }
1399
1400 TEST_P(AiksTest, SiblingSaveLayerBoundsAreRespected) {
1401 DisplayListBuilder builder;
1402 DlPaint paint;
1403 DlRect rect = DlRect::MakeXYWH(0, 0, 1000, 1000);
1404
1405 // Black, green, and red squares offset by [10, 10].
1406 {
1407 DlPaint save_paint;
1408 DlRect bounds = DlRect::MakeXYWH(25, 25, 25, 25);
1409 builder.SaveLayer(bounds, &save_paint);
1410 paint.setColor(DlColor::kBlack());
1411 builder.DrawRect(rect, paint);
1412 builder.Restore();
1413 }
1414
1415 {
1416 DlPaint save_paint;
1417 DlRect bounds = DlRect::MakeXYWH(35, 35, 25, 25);
1418 builder.SaveLayer(bounds, &save_paint);
1419 paint.setColor(DlColor::kGreen());
1420 builder.DrawRect(rect, paint);
1421 builder.Restore();
1422 }
1423
1424 {
1425 DlPaint save_paint;
1426 DlRect bounds = DlRect::MakeXYWH(45, 45, 25, 25);
1427 builder.SaveLayer(bounds, &save_paint);
1428 paint.setColor(DlColor::kRed());
1429 builder.DrawRect(rect, paint);
1430 builder.Restore();
1431 }
1432
1433 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1434 }
1435
1436 TEST_P(AiksTest, CanRenderClippedLayers) {
1437 DisplayListBuilder builder;
1438
1439 DlPaint paint;
1440 paint.setColor(DlColor::kWhite());
1441 builder.DrawPaint(paint);
1442
1443 // Draw a green circle on the screen.
1444 {
1445 // Increase the clip depth for the savelayer to contend with.
1446 DlPath path = DlPath::MakeCircle(DlPoint(100, 100), 50);
1447 builder.ClipPath(path);
1448
1449 DlRect bounds = DlRect::MakeXYWH(50, 50, 100, 100);
1450 DlPaint save_paint;
1451 builder.SaveLayer(bounds, &save_paint);
1452
1453 // Fill the layer with white.
1454 paint.setColor(DlColor::kWhite());
1455 builder.DrawRect(DlRect::MakeSize(DlSize(400, 400)), paint);
1456 // Fill the layer with green, but do so with a color blend that can't be
1457 // collapsed into the parent pass.
1458 paint.setColor(DlColor::kGreen());
1459 paint.setBlendMode(DlBlendMode::kHardLight);
1460 builder.DrawRect(DlRect::MakeSize(DlSize(400, 400)), paint);
1461 }
1462
1463 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1464 }
1465
1466 TEST_P(AiksTest, SaveLayerFiltersScaleWithTransform) {
1467 DisplayListBuilder builder;
1468
1469 builder.Scale(GetContentScale().x, GetContentScale().y);
1470 builder.Translate(100, 100);
1471
1472 auto texture = DlImageImpeller::Make(CreateTextureForFixture("boston.jpg"));
1473 auto draw_image_layer = [&builder, &texture](const DlPaint& paint) {
1474 builder.SaveLayer(std::nullopt, &paint);
1475 builder.DrawImage(texture, DlPoint(), DlImageSampling::kLinear);
1476 builder.Restore();
1477 };
1478
1479 DlPaint effect_paint;
1480 effect_paint.setMaskFilter(DlBlurMaskFilter::Make(DlBlurStyle::kNormal, 6));
1481 draw_image_layer(effect_paint);
1482
1483 builder.Translate(300, 300);
1484 builder.Scale(3, 3);
1485 draw_image_layer(effect_paint);
1486
1487 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1488 }
1489
1490 TEST_P(AiksTest, FastEllipticalRRectMaskBlursRenderCorrectly) {
1491 DisplayListBuilder builder;
1492
1493 builder.Scale(GetContentScale().x, GetContentScale().y);
1494 DlPaint paint;
1495 paint.setMaskFilter(DlBlurMaskFilter::Make(DlBlurStyle::kNormal, 1));
1496
1497 DlPaint save_paint;
1498 save_paint.setColor(DlColor::kWhite());
1499 builder.DrawPaint(save_paint);
1500
1501 paint.setColor(DlColor::kBlue());
1502 for (int i = 0; i < 5; i++) {
1503 Scalar y = i * 125;
1504 Scalar y_radius = i * 15;
1505 for (int j = 0; j < 5; j++) {
1506 Scalar x = j * 125;
1507 Scalar x_radius = j * 15;
1508 builder.DrawRoundRect(
1509 DlRoundRect::MakeRectXY(
1510 DlRect::MakeXYWH(x + 50, y + 50, 100.0f, 100.0f), //
1511 x_radius, y_radius),
1512 paint);
1513 }
1514 }
1515
1516 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1517 }
1518
1519 TEST_P(AiksTest, PipelineBlendSingleParameter) {
1520 DisplayListBuilder builder;
1521
1522 // Should render a green square in the middle of a blue circle.
1523 DlPaint paint;
1524 builder.SaveLayer(std::nullopt, &paint);
1525 {
1526 builder.Translate(100, 100);
1527 paint.setColor(DlColor::kBlue());
1528 builder.DrawCircle(DlPoint(200, 200), 200, paint);
1529 builder.ClipRect(DlRect::MakeXYWH(100, 100, 200, 200));
1530
1531 paint.setColor(DlColor::kGreen());
1532 paint.setBlendMode(DlBlendMode::kSrcOver);
1533 paint.setImageFilter(DlImageFilter::MakeColorFilter(
1534 DlColorFilter::MakeBlend(DlColor::kWhite(), DlBlendMode::kDst)));
1535 builder.DrawCircle(DlPoint(200, 200), 200, paint);
1536 builder.Restore();
1537 }
1538
1539 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1540 }
1541
1542 // Creates an image matrix filter that scales large content such that it would
1543 // exceed the max texture size. See
1544 // https://github.com/flutter/flutter/issues/128912
1545 TEST_P(AiksTest, MassiveScalingMatrixImageFilter) {
1546 if (GetBackend() == PlaygroundBackend::kVulkan) {
1547 GTEST_SKIP() << "Swiftshader is running out of memory on this example.";
1548 }
1549 DisplayListBuilder builder(DlRect::MakeSize(DlSize(1000, 1000)));
1550
1551 auto filter = DlImageFilter::MakeMatrix(
1552 DlMatrix::MakeScale({0.001, 0.001, 1}), DlImageSampling::kLinear);
1553
1554 DlPaint paint;
1555 paint.setImageFilter(filter);
1556 builder.SaveLayer(std::nullopt, &paint);
1557 {
1558 DlPaint paint;
1559 paint.setColor(DlColor::kRed());
1560 builder.DrawRect(DlRect::MakeLTRB(0, 0, 100000, 100000), paint);
1561 }
1562 builder.Restore();
1563
1564 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1565 }
1566
1567 TEST_P(AiksTest, NoDimplesInRRectPath) {
1568 Scalar width = 200.f;
1569 Scalar height = 60.f;
1570 Scalar corner = 1.f;
1571 auto callback = [&]() -> sk_sp<DisplayList> {
1572 if (AiksTest::ImGuiBegin("Controls", nullptr,
1573 ImGuiWindowFlags_AlwaysAutoResize)) {
1574 ImGui::SliderFloat("width", &width, 0, 200);
1575 ImGui::SliderFloat("height", &height, 0, 200);
1576 ImGui::SliderFloat("corner", &corner, 0, 1);
1577 ImGui::End();
1578 }
1579
1580 DisplayListBuilder builder;
1581 builder.Scale(GetContentScale().x, GetContentScale().y);
1582
1583 DlPaint background_paint;
1584 background_paint.setColor(DlColor(1, 0.1, 0.1, 0.1, DlColorSpace::kSRGB));
1585 builder.DrawPaint(background_paint);
1586
1587 std::vector<DlColor> colors = {DlColor::kRed(), DlColor::kBlue()};
1588 std::vector<Scalar> stops = {0.0, 1.0};
1589
1590 DlPaint paint;
1591 auto gradient = DlColorSource::MakeLinear(DlPoint(0, 0), DlPoint(200, 200),
1592 2, colors.data(), stops.data(),
1593 DlTileMode::kClamp);
1594 paint.setColorSource(gradient);
1595 paint.setColor(DlColor::kWhite());
1596 paint.setDrawStyle(DlDrawStyle::kStroke);
1597 paint.setStrokeWidth(20);
1598
1599 builder.Save();
1600 builder.Translate(100, 100);
1601
1602 Scalar corner_x = ((1 - corner) * 50) + 50;
1603 Scalar corner_y = corner * 50 + 50;
1604 DlRoundRect rrect = DlRoundRect::MakeRectXY(
1605 DlRect::MakeXYWH(0, 0, width, height), corner_x, corner_y);
1606 builder.DrawRoundRect(rrect, paint);
1607 builder.Restore();
1608 return builder.Build();
1609 };
1610 ASSERT_TRUE(OpenPlaygroundHere(callback));
1611 }
1612
1613 TEST_P(AiksTest, BackdropFilterOverUnclosedClip) {
1614 DisplayListBuilder builder;
1615
1616 builder.DrawPaint(DlPaint().setColor(DlColor::kWhite()));
1617 builder.Save();
1618 {
1619 builder.ClipRect(DlRect::MakeLTRB(100, 100, 800, 800));
1620
1621 builder.Save();
1622 {
1623 builder.ClipRect(DlRect::MakeLTRB(600, 600, 800, 800));
1624 builder.DrawPaint(DlPaint().setColor(DlColor::kRed()));
1625 builder.DrawPaint(DlPaint().setColor(DlColor::kBlue().withAlphaF(0.5)));
1626 builder.ClipRect(DlRect::MakeLTRB(700, 700, 750, 800));
1627 builder.DrawPaint(DlPaint().setColor(DlColor::kRed().withAlphaF(0.5)));
1628 }
1629 builder.Restore();
1630
1631 auto image_filter = DlImageFilter::MakeBlur(10, 10, DlTileMode::kDecal);
1632 builder.SaveLayer(std::nullopt, nullptr, image_filter.get());
1633 }
1634 builder.Restore();
1635 builder.DrawCircle(DlPoint(100, 100), 100,
1636 DlPaint().setColor(DlColor::kAqua()));
1637
1638 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1639 }
1640
1641 } // namespace testing
1642 } // namespace impeller
aiks_unittests.h
impeller::AiksPlayground
Definition: aiks_playground.h:16
impeller::AiksPlayground::ImGuiBegin
static bool ImGuiBegin(const char *name, bool *p_open, ImGuiWindowFlags flags)
Definition: aiks_playground.cc:31
impeller::DlImageImpeller::Make
static sk_sp< DlImageImpeller > Make(std::shared_ptr< Texture > texture, OwningContext owning_context=OwningContext::kIO)
Definition: dl_image_impeller.cc:23
x
int32_t x
Definition: dl_golden_unittests.cc:458
dl_image_impeller.h
flutter
Definition: dl_golden_blur_unittests.cc:16
impeller::testing::AiksTest
AiksPlayground AiksTest
Definition: aiks_unittests.h:17
impeller::testing::TEST_P
TEST_P(AiksTest, DrawAtlasNoColor)
Definition: aiks_dl_atlas_unittests.cc:60
impeller
Definition: allocation.cc:12
impeller::DlRect
flutter::DlRect DlRect
Definition: dl_dispatcher.h:25
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::DlRoundRect
flutter::DlRoundRect DlRoundRect
Definition: dl_dispatcher.h:27
impeller::Point
TPoint< Scalar > Point
Definition: point.h:327
impeller::Convexity::kConvex
@ kConvex
impeller::PixelFormat
PixelFormat
The Pixel formats supported by Impeller. The naming convention denotes the usage of the component,...
Definition: formats.h:99
impeller::PixelFormat::kB10G10R10A10XR
@ kB10G10R10A10XR
impeller::PixelFormat::kB8G8R8A8UNormInt
@ kB8G8R8A8UNormInt
impeller::PixelFormat::kR8G8B8A8UNormInt
@ kR8G8B8A8UNormInt
impeller::DlPoint
flutter::DlPoint DlPoint
Definition: dl_dispatcher.h:24
impeller::DlPath
flutter::DlPath DlPath
Definition: dl_dispatcher.h:29
impeller::PlaygroundBackend::kVulkan
@ kVulkan
impeller::Size
TSize< Scalar > Size
Definition: size.h:159
impeller::PixelFormatToString
constexpr const char * PixelFormatToString(PixelFormat format)
Definition: formats.h:140
impeller::DlScalar
flutter::DlScalar DlScalar
Definition: dl_dispatcher.h:23
scalar.h
stroke_width
const Scalar stroke_width
Definition: stroke_path_geometry.cc:315
offset
SeparatedVector2 offset
Definition: stroke_path_geometry.cc:322
impeller::Color::White
static constexpr Color White()
Definition: color.h:264
impeller::Matrix
A 4x4 matrix using column-major storage.
Definition: matrix.h:37
impeller::Matrix::MakeTranslation
static constexpr Matrix MakeTranslation(const Vector3 &t)
Definition: matrix.h:95
impeller::Matrix::MakeRotationY
static Matrix MakeRotationY(Radians r)
Definition: matrix.h:208
impeller::Matrix::Transform
constexpr Quad Transform(const Quad &quad) const
Definition: matrix.h:556
impeller::PlaygroundPoint
Definition: widgets.h:17
impeller::Radians
Definition: scalar.h:43
impeller::RoundRect::MakeRectXY
constexpr static RoundRect MakeRectXY(const Rect &rect, Scalar x_radius, Scalar y_radius)
Definition: round_rect.h:30
impeller::RoundingRadii
Definition: rounding_radii.h:14
impeller::RoundingRadii::top_left
Size top_left
Definition: rounding_radii.h:15
impeller::TPoint< Scalar >
impeller::TSize
Definition: size.h:25
widgets.h