| Flutter Impeller |

aiks_dl_unittests.cc
Go to the documentation of this file.
1
2 // Copyright 2013 The Flutter Authors. All rights reserved.
3 // Use of this source code is governed by a BSD-style license that can be
4 // found in the LICENSE file.
5
6 #include <vector>
7 #include "display_list/dl_sampling_options.h"
8 #include "display_list/dl_tile_mode.h"
9 #include "display_list/effects/dl_color_filter.h"
10 #include "display_list/effects/dl_color_source.h"
11 #include "display_list/effects/dl_image_filter.h"
12 #include "display_list/geometry/dl_geometry_types.h"
13 #include "display_list/geometry/dl_path.h"
14 #include "display_list/image/dl_image.h"
15 #include "flutter/impeller/display_list/aiks_unittests.h"
16
17 #include "flutter/display_list/dl_blend_mode.h"
18 #include "flutter/display_list/dl_builder.h"
19 #include "flutter/display_list/dl_color.h"
20 #include "flutter/display_list/dl_paint.h"
21 #include "flutter/testing/testing.h"
22 #include "fml/synchronization/count_down_latch.h"
23 #include "imgui.h"
24 #include "impeller/core/device_buffer.h"
25 #include "impeller/core/device_buffer_descriptor.h"
26 #include "impeller/core/formats.h"
27 #include "impeller/core/texture_descriptor.h"
28 #include "impeller/display_list/dl_dispatcher.h"
29 #include "impeller/display_list/dl_image_impeller.h"
30 #include "impeller/geometry/path_builder.h"
31 #include "impeller/geometry/scalar.h"
32 #include "include/core/SkCanvas.h"
33 #include "include/core/SkMatrix.h"
34 #include "include/core/SkPath.h"
35 #include "include/core/SkRefCnt.h"
36
37 namespace impeller {
38 namespace testing {
39
40 using namespace flutter;
41
42 namespace {
43 SkRect GetCullRect(ISize window_size) {
44 return SkRect::MakeSize(SkSize::Make(window_size.width, window_size.height));
45 }
46 } // namespace
47
48 TEST_P(AiksTest, CollapsedDrawPaintInSubpass) {
49 DisplayListBuilder builder;
50
51 DlPaint paint;
52 paint.setColor(DlColor::kYellow());
53 paint.setBlendMode(DlBlendMode::kSrc);
54 builder.DrawPaint(paint);
55
56 DlPaint save_paint;
57 save_paint.setBlendMode(DlBlendMode::kMultiply);
58 builder.SaveLayer(nullptr, &save_paint);
59
60 DlPaint draw_paint;
61 draw_paint.setColor(DlColor::kCornflowerBlue().modulateOpacity(0.75f));
62 builder.DrawPaint(draw_paint);
63
64 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
65 }
66
67 TEST_P(AiksTest, CollapsedDrawPaintInSubpassBackdropFilter) {
68 // Bug: https://github.com/flutter/flutter/issues/131576
69 DisplayListBuilder builder;
70
71 DlPaint paint;
72 paint.setColor(DlColor::kYellow());
73 paint.setBlendMode(DlBlendMode::kSrc);
74 builder.DrawPaint(paint);
75
76 auto filter = DlImageFilter::MakeBlur(20.0, 20.0, DlTileMode::kDecal);
77 builder.SaveLayer(nullptr, nullptr, filter.get());
78
79 DlPaint draw_paint;
80 draw_paint.setColor(DlColor::kCornflowerBlue());
81 builder.DrawPaint(draw_paint);
82
83 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
84 }
85
86 TEST_P(AiksTest, ColorMatrixFilterSubpassCollapseOptimization) {
87 DisplayListBuilder builder(GetCullRect(GetWindowSize()));
88
89 const float matrix[20] = {
90 -1.0, 0, 0, 1.0, 0, //
91 0, -1.0, 0, 1.0, 0, //
92 0, 0, -1.0, 1.0, 0, //
93 1.0, 1.0, 1.0, 1.0, 0 //
94 };
95 auto filter = DlColorFilter::MakeMatrix(matrix);
96
97 DlPaint paint;
98 paint.setColorFilter(filter);
99 builder.SaveLayer(nullptr, &paint);
100
101 builder.Translate(500, 300);
102 builder.Rotate(120); // 120 deg
103
104 DlPaint draw_paint;
105 draw_paint.setColor(DlColor::kBlue());
106 builder.DrawRect(SkRect::MakeXYWH(100, 100, 200, 200), draw_paint);
107
108 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
109 }
110
111 TEST_P(AiksTest, LinearToSrgbFilterSubpassCollapseOptimization) {
112 DisplayListBuilder builder(GetCullRect(GetWindowSize()));
113
114 DlPaint paint;
115 paint.setColorFilter(DlColorFilter::MakeLinearToSrgbGamma());
116 builder.SaveLayer(nullptr, &paint);
117
118 builder.Translate(500, 300);
119 builder.Rotate(120); // 120 deg.
120
121 DlPaint draw_paint;
122 draw_paint.setColor(DlColor::kBlue());
123 builder.DrawRect(SkRect::MakeXYWH(100, 100, 200, 200), draw_paint);
124
125 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
126 }
127
128 TEST_P(AiksTest, SrgbToLinearFilterSubpassCollapseOptimization) {
129 DisplayListBuilder builder(GetCullRect(GetWindowSize()));
130
131 DlPaint paint;
132 paint.setColorFilter(DlColorFilter::MakeLinearToSrgbGamma());
133 builder.SaveLayer(nullptr, &paint);
134
135 builder.Translate(500, 300);
136 builder.Rotate(120); // 120 deg
137
138 DlPaint draw_paint;
139 draw_paint.setColor(DlColor::kBlue());
140 builder.DrawRect(SkRect::MakeXYWH(100, 100, 200, 200), draw_paint);
141
142 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
143 }
144
145 TEST_P(AiksTest, TranslucentSaveLayerDrawsCorrectly) {
146 DisplayListBuilder builder(GetCullRect(GetWindowSize()));
147
148 DlPaint paint;
149 paint.setColor(DlColor::kBlue());
150 builder.DrawRect(SkRect::MakeXYWH(100, 100, 300, 300), paint);
151
152 DlPaint save_paint;
153 save_paint.setColor(DlColor::kBlack().withAlpha(128));
154 builder.SaveLayer(nullptr, &save_paint);
155 builder.DrawRect(SkRect::MakeXYWH(100, 500, 300, 300), paint);
156 builder.Restore();
157
158 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
159 }
160
161 TEST_P(AiksTest, TranslucentSaveLayerWithBlendColorFilterDrawsCorrectly) {
162 DisplayListBuilder builder(GetCullRect(GetWindowSize()));
163
164 DlPaint paint;
165 paint.setColor(DlColor::kBlue());
166 builder.DrawRect(SkRect::MakeXYWH(100, 100, 300, 300), paint);
167
168 DlPaint save_paint;
169 paint.setColor(DlColor::kBlack().withAlpha(128));
170 paint.setColorFilter(
171 DlColorFilter::MakeBlend(DlColor::kRed(), DlBlendMode::kDstOver));
172 builder.Save();
173 builder.ClipRect(SkRect::MakeXYWH(100, 500, 300, 300));
174 builder.SaveLayer(nullptr, &paint);
175
176 DlPaint draw_paint;
177 draw_paint.setColor(DlColor::kBlue());
178 builder.DrawRect(SkRect::MakeXYWH(100, 500, 300, 300), draw_paint);
179 builder.Restore();
180 builder.Restore();
181
182 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
183 }
184
185 TEST_P(AiksTest, TranslucentSaveLayerWithBlendImageFilterDrawsCorrectly) {
186 DisplayListBuilder builder(GetCullRect(GetWindowSize()));
187
188 DlPaint paint;
189 paint.setColor(DlColor::kBlue());
190 builder.DrawRect(SkRect::MakeXYWH(100, 100, 300, 300), paint);
191
192 DlPaint save_paint;
193 save_paint.setColor(DlColor::kBlack().withAlpha(128));
194 save_paint.setImageFilter(DlImageFilter::MakeColorFilter(
195 DlColorFilter::MakeBlend(DlColor::kRed(), DlBlendMode::kDstOver)));
196
197 builder.SaveLayer(nullptr, &save_paint);
198
199 DlPaint draw_paint;
200 draw_paint.setColor(DlColor::kBlue());
201 builder.DrawRect(SkRect::MakeXYWH(100, 500, 300, 300), draw_paint);
202 builder.Restore();
203
204 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
205 }
206
207 TEST_P(AiksTest, TranslucentSaveLayerWithColorAndImageFilterDrawsCorrectly) {
208 DisplayListBuilder builder(GetCullRect(GetWindowSize()));
209
210 DlPaint paint;
211 paint.setColor(DlColor::kBlue());
212 builder.DrawRect(SkRect::MakeXYWH(100, 100, 300, 300), paint);
213
214 DlPaint save_paint;
215 save_paint.setColor(DlColor::kBlack().withAlpha(128));
216 save_paint.setColorFilter(
217 DlColorFilter::MakeBlend(DlColor::kRed(), DlBlendMode::kDstOver));
218 builder.Save();
219 builder.ClipRect(SkRect::MakeXYWH(100, 500, 300, 300));
220 builder.SaveLayer(nullptr, &save_paint);
221
222 DlPaint draw_paint;
223 draw_paint.setColor(DlColor::kBlue());
224 builder.DrawRect(SkRect::MakeXYWH(100, 500, 300, 300), draw_paint);
225 builder.Restore();
226 builder.Restore();
227
228 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
229 }
230
231 TEST_P(AiksTest, ImageFilteredUnboundedSaveLayerWithUnboundedContents) {
232 DisplayListBuilder builder(GetCullRect(GetWindowSize()));
233 builder.Scale(GetContentScale().x, GetContentScale().y);
234
235 DlPaint save_paint;
236 save_paint.setImageFilter(
237 DlImageFilter::MakeBlur(10.0, 10.0, DlTileMode::kDecal));
238 builder.SaveLayer(nullptr, &save_paint);
239
240 {
241 // DrawPaint to verify correct behavior when the contents are unbounded.
242 DlPaint draw_paint;
243 draw_paint.setColor(DlColor::kYellow());
244 builder.DrawPaint(draw_paint);
245
246 // Contrasting rectangle to see interior blurring
247 DlPaint draw_rect;
248 draw_rect.setColor(DlColor::kBlue());
249 builder.DrawRect(SkRect::MakeLTRB(125, 125, 175, 175), draw_rect);
250 }
251 builder.Restore();
252
253 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
254 }
255
256 TEST_P(AiksTest, TranslucentSaveLayerImageDrawsCorrectly) {
257 DisplayListBuilder builder(GetCullRect(GetWindowSize()));
258
259 auto image = DlImageImpeller::Make(CreateTextureForFixture("airplane.jpg"));
260 builder.DrawImage(image, SkPoint{100, 100}, DlImageSampling::kMipmapLinear);
261
262 DlPaint paint;
263 paint.setColor(DlColor::kBlack().withAlpha(128));
264 builder.SaveLayer(nullptr, &paint);
265 builder.DrawImage(image, SkPoint{100, 500}, DlImageSampling::kMipmapLinear);
266 builder.Restore();
267
268 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
269 }
270
271 TEST_P(AiksTest, TranslucentSaveLayerWithColorMatrixColorFilterDrawsCorrectly) {
272 DisplayListBuilder builder(GetCullRect(GetWindowSize()));
273
274 auto image = DlImageImpeller::Make(CreateTextureForFixture("airplane.jpg"));
275 builder.DrawImage(image, SkPoint{100, 100}, {});
276
277 const float matrix[20] = {
278 1, 0, 0, 0, 0, //
279 0, 1, 0, 0, 0, //
280 0, 0, 1, 0, 0, //
281 0, 0, 0, 2, 0 //
282 };
283 DlPaint paint;
284 paint.setColor(DlColor::kBlack().withAlpha(128));
285 paint.setColorFilter(DlColorFilter::MakeMatrix(matrix));
286 builder.SaveLayer(nullptr, &paint);
287 builder.DrawImage(image, SkPoint{100, 500}, {});
288 builder.Restore();
289
290 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
291 }
292
293 TEST_P(AiksTest, TranslucentSaveLayerWithColorMatrixImageFilterDrawsCorrectly) {
294 DisplayListBuilder builder(GetCullRect(GetWindowSize()));
295
296 auto image = DlImageImpeller::Make(CreateTextureForFixture("airplane.jpg"));
297 builder.DrawImage(image, SkPoint{100, 100}, {});
298
299 const float matrix[20] = {
300 1, 0, 0, 0, 0, //
301 0, 1, 0, 0, 0, //
302 0, 0, 1, 0, 0, //
303 0, 0, 0, 2, 0 //
304 };
305 DlPaint paint;
306 paint.setColor(DlColor::kBlack().withAlpha(128));
307 paint.setColorFilter(DlColorFilter::MakeMatrix(matrix));
308 builder.SaveLayer(nullptr, &paint);
309 builder.DrawImage(image, SkPoint{100, 500}, {});
310 builder.Restore();
311
312 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
313 }
314
315 TEST_P(AiksTest,
316 TranslucentSaveLayerWithColorFilterAndImageFilterDrawsCorrectly) {
317 DisplayListBuilder builder(GetCullRect(GetWindowSize()));
318
319 auto image = DlImageImpeller::Make(CreateTextureForFixture("airplane.jpg"));
320 builder.DrawImage(image, SkPoint{100, 100}, {});
321
322 const float matrix[20] = {
323 1, 0, 0, 0, 0, //
324 0, 1, 0, 0, 0, //
325 0, 0.2, 1, 0, 0, //
326 0, 0, 0, 0.5, 0 //
327 };
328 DlPaint paint;
329 paint.setColor(DlColor::kBlack().withAlpha(128));
330 paint.setImageFilter(
331 DlImageFilter::MakeColorFilter(DlColorFilter::MakeMatrix(matrix)));
332 paint.setColorFilter(
333 DlColorFilter::MakeBlend(DlColor::kGreen(), DlBlendMode::kModulate));
334 builder.SaveLayer(nullptr, &paint);
335 builder.DrawImage(image, SkPoint{100, 500}, {});
336 builder.Restore();
337
338 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
339 }
340
341 TEST_P(AiksTest, TranslucentSaveLayerWithAdvancedBlendModeDrawsCorrectly) {
342 DisplayListBuilder builder(GetCullRect(GetWindowSize()));
343
344 DlPaint paint;
345 paint.setColor(DlColor::kRed());
346 builder.DrawRect(SkRect::MakeXYWH(0, 0, 400, 400), paint);
347
348 DlPaint save_paint;
349 save_paint.setAlpha(128);
350 save_paint.setBlendMode(DlBlendMode::kLighten);
351 builder.SaveLayer(nullptr, &save_paint);
352
353 DlPaint draw_paint;
354 draw_paint.setColor(DlColor::kGreen());
355 builder.DrawCircle(SkPoint{200, 200}, 100, draw_paint);
356 builder.Restore();
357
358 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
359 }
360
361 /// This is a regression check for https://github.com/flutter/engine/pull/41129
362 /// The entire screen is green if successful. If failing, no frames will render,
363 /// or the entire screen will be transparent black.
364 TEST_P(AiksTest, CanRenderTinyOverlappingSubpasses) {
365 DisplayListBuilder builder(GetCullRect(GetWindowSize()));
366
367 DlPaint paint;
368 paint.setColor(DlColor::kRed());
369 builder.DrawPaint(paint);
370
371 // Draw two overlapping subpixel circles.
372 builder.SaveLayer({});
373
374 DlPaint yellow_paint;
375 yellow_paint.setColor(DlColor::kYellow());
376 builder.DrawCircle(SkPoint{100, 100}, 0.1, yellow_paint);
377 builder.Restore();
378 builder.SaveLayer({});
379 builder.DrawCircle(SkPoint{100, 100}, 0.1, yellow_paint);
380 builder.Restore();
381
382 DlPaint draw_paint;
383 draw_paint.setColor(DlColor::kGreen());
384 builder.DrawPaint(draw_paint);
385
386 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
387 }
388
389 TEST_P(AiksTest, CanRenderDestructiveSaveLayer) {
390 DisplayListBuilder builder(GetCullRect(GetWindowSize()));
391
392 DlPaint paint;
393 paint.setColor(DlColor::kRed());
394 builder.DrawPaint(paint);
395 // Draw an empty savelayer with a destructive blend mode, which will replace
396 // the entire red screen with fully transparent black, except for the green
397 // circle drawn within the layer.
398
399 DlPaint save_paint;
400 save_paint.setBlendMode(DlBlendMode::kSrc);
401 builder.SaveLayer(nullptr, &save_paint);
402
403 DlPaint draw_paint;
404 draw_paint.setColor(DlColor::kGreen());
405 builder.DrawCircle(SkPoint{300, 300}, 100, draw_paint);
406 builder.Restore();
407
408 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
409 }
410
411 TEST_P(AiksTest, CanDrawPoints) {
412 std::vector<SkPoint> points = {
413 {0, 0}, //
414 {100, 100}, //
415 {100, 0}, //
416 {0, 100}, //
417 {0, 0}, //
418 {48, 48}, //
419 {52, 52}, //
420 };
421 DlPaint paint_round;
422 paint_round.setColor(DlColor::kYellow().withAlpha(128));
423 paint_round.setStrokeCap(DlStrokeCap::kRound);
424 paint_round.setStrokeWidth(20);
425
426 DlPaint paint_square;
427 paint_square.setColor(DlColor::kYellow().withAlpha(128));
428 paint_square.setStrokeCap(DlStrokeCap::kSquare);
429 paint_square.setStrokeWidth(20);
430
431 DlPaint background;
432 background.setColor(DlColor::kBlack());
433
434 DisplayListBuilder builder(GetCullRect(GetWindowSize()));
435 builder.DrawPaint(background);
436 builder.Translate(200, 200);
437
438 builder.DrawPoints(DlCanvas::PointMode::kPoints, points.size(), points.data(),
439 paint_round);
440 builder.Translate(150, 0);
441 builder.DrawPoints(DlCanvas::PointMode::kPoints, points.size(), points.data(),
442 paint_square);
443
444 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
445 }
446
447 TEST_P(AiksTest, CanDrawPointsWithTextureMap) {
448 auto texture = DlImageImpeller::Make(
449 CreateTextureForFixture("table_mountain_nx.png",
450 /*enable_mipmapping=*/true));
451
452 std::vector<SkPoint> points = {
453 {0, 0}, //
454 {100, 100}, //
455 {100, 0}, //
456 {0, 100}, //
457 {0, 0}, //
458 {48, 48}, //
459 {52, 52}, //
460 };
461
462 auto image_src =
463 DlColorSource::MakeImage(texture, DlTileMode::kClamp, DlTileMode::kClamp);
464
465 DlPaint paint_round;
466 paint_round.setStrokeCap(DlStrokeCap::kRound);
467 paint_round.setColorSource(image_src);
468 paint_round.setStrokeWidth(200);
469
470 DlPaint paint_square;
471 paint_square.setStrokeCap(DlStrokeCap::kSquare);
472 paint_square.setColorSource(image_src);
473 paint_square.setStrokeWidth(200);
474
475 DisplayListBuilder builder(GetCullRect(GetWindowSize()));
476 builder.Translate(200, 200);
477
478 builder.DrawPoints(DlCanvas::PointMode::kPoints, points.size(), points.data(),
479 paint_round);
480 builder.Translate(150, 0);
481 builder.DrawPoints(DlCanvas::PointMode::kPoints, points.size(), points.data(),
482 paint_square);
483
484 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
485 }
486
487 TEST_P(AiksTest, MipmapGenerationWorksCorrectly) {
488 TextureDescriptor texture_descriptor;
489 texture_descriptor.size = ISize{1024, 1024};
490 texture_descriptor.format = PixelFormat::kR8G8B8A8UNormInt;
491 texture_descriptor.storage_mode = StorageMode::kHostVisible;
492 texture_descriptor.mip_count = texture_descriptor.size.MipCount();
493
494 std::vector<uint8_t> bytes(4194304);
495 bool alternate = false;
496 for (auto i = 0u; i < 4194304; i += 4) {
497 if (alternate) {
498 bytes[i] = 255;
499 bytes[i + 1] = 0;
500 bytes[i + 2] = 0;
501 bytes[i + 3] = 255;
502 } else {
503 bytes[i] = 0;
504 bytes[i + 1] = 255;
505 bytes[i + 2] = 0;
506 bytes[i + 3] = 255;
507 }
508 alternate = !alternate;
509 }
510
511 ASSERT_EQ(texture_descriptor.GetByteSizeOfBaseMipLevel(), bytes.size());
512 auto mapping = std::make_shared<fml::NonOwnedMapping>(
513 bytes.data(), // data
514 texture_descriptor.GetByteSizeOfBaseMipLevel() // size
515 );
516 auto texture =
517 GetContext()->GetResourceAllocator()->CreateTexture(texture_descriptor);
518
519 auto device_buffer =
520 GetContext()->GetResourceAllocator()->CreateBufferWithCopy(*mapping);
521 auto command_buffer = GetContext()->CreateCommandBuffer();
522 auto blit_pass = command_buffer->CreateBlitPass();
523
524 blit_pass->AddCopy(DeviceBuffer::AsBufferView(std::move(device_buffer)),
525 texture);
526 blit_pass->GenerateMipmap(texture);
527 EXPECT_TRUE(blit_pass->EncodeCommands());
528 EXPECT_TRUE(GetContext()->GetCommandQueue()->Submit({command_buffer}).ok());
529
530 auto image = DlImageImpeller::Make(texture);
531
532 DisplayListBuilder builder;
533 builder.DrawImageRect(
534 image,
535 SkRect::MakeSize(
536 SkSize::Make(texture->GetSize().width, texture->GetSize().height)),
537 SkRect::MakeLTRB(0, 0, 100, 100), DlImageSampling::kMipmapLinear);
538
539 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
540 }
541
542 // https://github.com/flutter/flutter/issues/146648
543 TEST_P(AiksTest, StrokedPathWithMoveToThenCloseDrawnCorrectly) {
544 SkPath path;
545 path.moveTo(0, 400)
546 .lineTo(0, 0)
547 .lineTo(400, 0)
548 // MoveTo implicitly adds a contour, ensure that close doesn't
549 // add another nearly-empty contour.
550 .moveTo(0, 400)
551 .close();
552
553 DisplayListBuilder builder;
554 builder.Translate(50, 50);
555
556 DlPaint paint;
557 paint.setColor(DlColor::kBlue());
558 paint.setStrokeCap(DlStrokeCap::kRound);
559 paint.setStrokeWidth(10);
560 paint.setDrawStyle(DlDrawStyle::kStroke);
561 builder.DrawPath(path, paint);
562
563 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
564 }
565
566 TEST_P(AiksTest, SetContentsWithRegion) {
567 auto bridge = CreateTextureForFixture("bay_bridge.jpg");
568
569 // Replace part of the texture with a red rectangle.
570 std::vector<uint8_t> bytes(100 * 100 * 4);
571 for (auto i = 0u; i < bytes.size(); i += 4) {
572 bytes[i] = 255;
573 bytes[i + 1] = 0;
574 bytes[i + 2] = 0;
575 bytes[i + 3] = 255;
576 }
577 auto mapping =
578 std::make_shared<fml::NonOwnedMapping>(bytes.data(), bytes.size());
579 auto device_buffer =
580 GetContext()->GetResourceAllocator()->CreateBufferWithCopy(*mapping);
581 auto cmd_buffer = GetContext()->CreateCommandBuffer();
582 auto blit_pass = cmd_buffer->CreateBlitPass();
583 blit_pass->AddCopy(DeviceBuffer::AsBufferView(device_buffer), bridge,
584 IRect::MakeLTRB(50, 50, 150, 150));
585
586 auto did_submit =
587 blit_pass->EncodeCommands() &&
588 GetContext()->GetCommandQueue()->Submit({std::move(cmd_buffer)}).ok();
589 ASSERT_TRUE(did_submit);
590
591 auto image = DlImageImpeller::Make(bridge);
592
593 DisplayListBuilder builder;
594 builder.DrawImage(image, SkPoint{0, 0}, {});
595
596 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
597 }
598
599 // Regression test for https://github.com/flutter/flutter/issues/134678.
600 TEST_P(AiksTest, ReleasesTextureOnTeardown) {
601 auto context = MakeContext();
602 std::weak_ptr<Texture> weak_texture;
603
604 {
605 auto texture = CreateTextureForFixture("table_mountain_nx.png");
606 weak_texture = texture;
607
608 DisplayListBuilder builder;
609 builder.Scale(GetContentScale().x, GetContentScale().y);
610 builder.Translate(100.0f, 100.0f);
611
612 DlPaint paint;
613 paint.setColorSource(DlColorSource::MakeImage(
614 DlImageImpeller::Make(texture), DlTileMode::kClamp, DlTileMode::kClamp,
615 DlImageSampling::kLinear, nullptr));
616
617 builder.DrawRect(SkRect::MakeXYWH(0, 0, 600, 600), paint);
618
619 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
620 }
621
622 // See https://github.com/flutter/flutter/issues/134751.
623 //
624 // If the fence waiter was working this may not be released by the end of the
625 // scope above. Adding a manual shutdown so that future changes to the fence
626 // waiter will not flake this test.
627 context->Shutdown();
628
629 // The texture should be released by now.
630 ASSERT_TRUE(weak_texture.expired()) << "When the texture is no longer in use "
631 "by the backend, it should be "
632 "released.";
633 }
634
635 TEST_P(AiksTest, MatrixImageFilterMagnify) {
636 Scalar scale = 2.0;
637 auto callback = [&]() -> sk_sp<DisplayList> {
638 if (AiksTest::ImGuiBegin("Controls", nullptr,
639 ImGuiWindowFlags_AlwaysAutoResize)) {
640 ImGui::SliderFloat("Scale", &scale, 1, 2);
641 ImGui::End();
642 }
643 DisplayListBuilder builder;
644 builder.Scale(GetContentScale().x, GetContentScale().y);
645 auto image = DlImageImpeller::Make(CreateTextureForFixture("airplane.jpg"));
646
647 builder.Translate(600, -200);
648
649 DlMatrix matrix = DlMatrix::MakeScale({scale, scale, 1});
650 DlPaint paint;
651 paint.setImageFilter(
652 DlImageFilter::MakeMatrix(matrix, DlImageSampling::kLinear));
653 builder.SaveLayer(nullptr, &paint);
654
655 DlPaint rect_paint;
656 rect_paint.setAlpha(0.5 * 255);
657 builder.DrawImage(image, SkPoint{0, 0}, DlImageSampling::kLinear,
658 &rect_paint);
659 builder.Restore();
660
661 return builder.Build();
662 };
663
664 ASSERT_TRUE(OpenPlaygroundHere(callback));
665 }
666
667 TEST_P(AiksTest, ImageFilteredSaveLayerWithUnboundedContents) {
668 DisplayListBuilder builder;
669 builder.Scale(GetContentScale().x, GetContentScale().y);
670
671 auto test = [&builder](const std::shared_ptr<DlImageFilter>& filter) {
672 auto DrawLine = [&builder](const SkPoint& p0, const SkPoint& p1,
673 const DlPaint& p) {
674 DlPaint paint = p;
675 paint.setDrawStyle(DlDrawStyle::kStroke);
676 builder.DrawPath(SkPath::Line(p0, p1), paint);
677 };
678 // Registration marks for the edge of the SaveLayer
679 DlPaint paint;
680 paint.setColor(DlColor::kWhite());
681 DrawLine(SkPoint::Make(75, 100), SkPoint::Make(225, 100), paint);
682 DrawLine(SkPoint::Make(75, 200), SkPoint::Make(225, 200), paint);
683 DrawLine(SkPoint::Make(100, 75), SkPoint::Make(100, 225), paint);
684 DrawLine(SkPoint::Make(200, 75), SkPoint::Make(200, 225), paint);
685
686 DlPaint save_paint;
687 save_paint.setImageFilter(filter);
688 SkRect bounds = SkRect::MakeLTRB(100, 100, 200, 200);
689 builder.SaveLayer(&bounds, &save_paint);
690
691 {
692 // DrawPaint to verify correct behavior when the contents are unbounded.
693 DlPaint paint;
694 paint.setColor(DlColor::kYellow());
695 builder.DrawPaint(paint);
696
697 // Contrasting rectangle to see interior blurring
698 paint.setColor(DlColor::kBlue());
699 builder.DrawRect(SkRect::MakeLTRB(125, 125, 175, 175), paint);
700 }
701 builder.Restore();
702 };
703
704 test(DlImageFilter::MakeBlur(10.0, 10.0, DlTileMode::kDecal));
705
706 builder.Translate(200.0, 0.0);
707
708 test(DlImageFilter::MakeDilate(10.0, 10.0));
709
710 builder.Translate(200.0, 0.0);
711
712 test(DlImageFilter::MakeErode(10.0, 10.0));
713
714 builder.Translate(-400.0, 200.0);
715
716 DlMatrix matrix = DlMatrix::MakeRotationZ(DlDegrees(10));
717
718 auto rotate_filter =
719 DlImageFilter::MakeMatrix(matrix, DlImageSampling::kLinear);
720 test(rotate_filter);
721
722 builder.Translate(200.0, 0.0);
723
724 const float m[20] = {
725 0, 1, 0, 0, 0, //
726 0, 0, 1, 0, 0, //
727 1, 0, 0, 0, 0, //
728 0, 0, 0, 1, 0 //
729 };
730 auto rgb_swap_filter =
731 DlImageFilter::MakeColorFilter(DlColorFilter::MakeMatrix(m));
732 test(rgb_swap_filter);
733
734 builder.Translate(200.0, 0.0);
735
736 test(DlImageFilter::MakeCompose(rotate_filter, rgb_swap_filter));
737
738 builder.Translate(-400.0, 200.0);
739
740 test(rotate_filter->makeWithLocalMatrix(
741 DlMatrix::MakeTranslation({25.0, 25.0})));
742
743 builder.Translate(200.0, 0.0);
744
745 test(rgb_swap_filter->makeWithLocalMatrix(
746 DlMatrix::MakeTranslation({25.0, 25.0})));
747
748 builder.Translate(200.0, 0.0);
749
750 test(DlImageFilter::MakeCompose(rotate_filter, rgb_swap_filter)
751 ->makeWithLocalMatrix(DlMatrix::MakeTranslation({25.0, 25.0})));
752
753 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
754 }
755
756 TEST_P(AiksTest, MatrixBackdropFilter) {
757 DisplayListBuilder builder;
758
759 DlPaint paint;
760 paint.setColor(DlColor::kBlack());
761 builder.DrawPaint(paint);
762 builder.SaveLayer(nullptr, nullptr);
763 {
764 DlPaint paint;
765 paint.setColor(DlColor::kGreen().withAlpha(0.5 * 255));
766 paint.setBlendMode(DlBlendMode::kPlus);
767
768 DlPaint rect_paint;
769 rect_paint.setColor(DlColor::kRed());
770 rect_paint.setStrokeWidth(4);
771 rect_paint.setDrawStyle(DlDrawStyle::kStroke);
772 builder.DrawRect(SkRect::MakeLTRB(0, 0, 300, 300), rect_paint);
773 builder.DrawCircle(SkPoint::Make(200, 200), 100, paint);
774 // Should render a second circle, centered on the bottom-right-most edge of
775 // the circle.
776 DlMatrix matrix = DlMatrix::MakeTranslation({(100 + 100 * k1OverSqrt2),
777 (100 + 100 * k1OverSqrt2)}) *
778 DlMatrix::MakeScale({0.5, 0.5, 1}) *
779 DlMatrix::MakeTranslation({-100, -100});
780 auto backdrop_filter =
781 DlImageFilter::MakeMatrix(matrix, DlImageSampling::kLinear);
782 builder.SaveLayer(nullptr, nullptr, backdrop_filter.get());
783 builder.Restore();
784 }
785 builder.Restore();
786
787 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
788 }
789
790 TEST_P(AiksTest, MatrixSaveLayerFilter) {
791 DisplayListBuilder builder;
792
793 DlPaint paint;
794 paint.setColor(DlColor::kBlack());
795 builder.DrawPaint(paint);
796 builder.SaveLayer(nullptr, nullptr);
797 {
798 paint.setColor(DlColor::kGreen().withAlpha(255 * 0.5));
799 paint.setBlendMode(DlBlendMode::kPlus);
800 builder.DrawCircle(SkPoint{200, 200}, 100, paint);
801 // Should render a second circle, centered on the bottom-right-most edge of
802 // the circle.
803
804 DlMatrix matrix = DlMatrix::MakeTranslation({(200 + 100 * k1OverSqrt2),
805 (200 + 100 * k1OverSqrt2)}) *
806 DlMatrix::MakeScale({0.5, 0.5, 1}) *
807 DlMatrix::MakeTranslation({-200, -200});
808 DlPaint save_paint;
809 save_paint.setImageFilter(
810 DlImageFilter::MakeMatrix(matrix, DlImageSampling::kLinear));
811
812 builder.SaveLayer(nullptr, &save_paint);
813
814 DlPaint circle_paint;
815 circle_paint.setColor(DlColor::kGreen().withAlpha(255 * 0.5));
816 circle_paint.setBlendMode(DlBlendMode::kPlus);
817 builder.DrawCircle(SkPoint{200, 200}, 100, circle_paint);
818 builder.Restore();
819 }
820 builder.Restore();
821
822 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
823 }
824
825 // Regression test for flutter/flutter#152780
826 TEST_P(AiksTest, CanDrawScaledPointsSmallScaleLargeRadius) {
827 std::vector<SkPoint> point = {
828 {0, 0}, //
829 };
830
831 DlPaint paint;
832 paint.setStrokeCap(DlStrokeCap::kRound);
833 paint.setColor(DlColor::kRed());
834 paint.setStrokeWidth(100 * 1000000);
835
836 DisplayListBuilder builder(GetCullRect(GetWindowSize()));
837 builder.Translate(200, 200);
838 builder.Scale(0.000001, 0.000001);
839
840 builder.DrawPoints(DlCanvas::PointMode::kPoints, point.size(), point.data(),
841 paint);
842
843 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
844 }
845
846 // Regression test for flutter/flutter#152780
847 TEST_P(AiksTest, CanDrawScaledPointsLargeScaleSmallRadius) {
848 std::vector<SkPoint> point = {
849 {0, 0}, //
850 };
851
852 DlPaint paint;
853 paint.setStrokeCap(DlStrokeCap::kRound);
854 paint.setColor(DlColor::kRed());
855 paint.setStrokeWidth(100 * 0.000001);
856
857 DisplayListBuilder builder(GetCullRect(GetWindowSize()));
858 builder.Translate(200, 200);
859 builder.Scale(1000000, 1000000);
860
861 builder.DrawPoints(DlCanvas::PointMode::kPoints, point.size(), point.data(),
862 paint);
863 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
864 }
865
866 TEST_P(AiksTest, TransparentShadowProducesCorrectColor) {
867 DisplayListBuilder builder;
868 builder.Save();
869 builder.Scale(1.618, 1.618);
870 SkPath path = SkPath{}.addRect(SkRect::MakeXYWH(0, 0, 200, 100));
871
872 builder.DrawShadow(path, flutter::DlColor::kTransparent(), 15, false, 1);
873 builder.Restore();
874
875 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
876 }
877
878 // Regression test for https://github.com/flutter/flutter/issues/130613
879 TEST_P(AiksTest, DispatcherDoesNotCullPerspectiveTransformedChildDisplayLists) {
880 flutter::DisplayListBuilder sub_builder(true);
881 sub_builder.DrawRect(SkRect::MakeXYWH(0, 0, 50, 50),
882 flutter::DlPaint(flutter::DlColor::kRed()));
883 auto display_list = sub_builder.Build();
884
885 AiksContext context(GetContext(), nullptr);
886 RenderTarget render_target =
887 context.GetContentContext().GetRenderTargetCache()->CreateOffscreen(
888 *context.GetContext(), {2400, 1800}, 1);
889
890 DisplayListBuilder builder;
891
892 builder.Scale(2.0, 2.0);
893 builder.Translate(-93.0, 0.0);
894
895 // clang-format off
896 builder.TransformFullPerspective(
897 0.8, -0.2, -0.1, -0.0,
898 0.0, 1.0, 0.0, 0.0,
899 1.4, 1.3, 1.0, 0.0,
900 63.2, 65.3, 48.6, 1.1
901 );
902 // clang-format on
903 builder.Translate(35.0, 75.0);
904 builder.DrawDisplayList(display_list, 1.0f);
905
906 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
907 }
908
909 // Results in a 100x100 green square. If any red is drawn, there is a bug.
910 TEST_P(AiksTest, BackdropRestoreUsesCorrectCoverageForFirstRestoredClip) {
911 DisplayListBuilder builder;
912
913 DlPaint paint;
914 // Add a difference clip that cuts out the bottom right corner
915 builder.ClipRect(SkRect::MakeLTRB(50, 50, 100, 100),
916 DlCanvas::ClipOp::kDifference);
917
918 // Draw a red rectangle that's going to be completely covered by green later.
919 paint.setColor(DlColor::kRed());
920 builder.DrawRect(SkRect::MakeLTRB(0, 0, 100, 100), paint);
921
922 // Add a clip restricting the backdrop filter to the top right corner.
923 auto count = builder.GetSaveCount();
924 builder.Save();
925 {
926 builder.ClipRect(SkRect::MakeLTRB(0, 0, 100, 100));
927 {
928 // Create a save layer with a backdrop blur filter.
929 auto backdrop_filter =
930 DlImageFilter::MakeBlur(10.0, 10.0, DlTileMode::kDecal);
931 builder.SaveLayer(nullptr, nullptr, backdrop_filter.get());
932 }
933 }
934 builder.RestoreToCount(count);
935
936 // Finally, overwrite all the previous stuff with green.
937 paint.setColor(DlColor::kGreen());
938 builder.DrawRect(SkRect::MakeLTRB(0, 0, 100, 100), paint);
939
940 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
941 }
942
943 TEST_P(AiksTest, CanPictureConvertToImage) {
944 DisplayListBuilder recorder_canvas;
945 DlPaint paint;
946 paint.setColor(DlColor::RGBA(0.9568, 0.2627, 0.2118, 1.0));
947 recorder_canvas.DrawRect(SkRect::MakeXYWH(100.0, 100.0, 600, 600), paint);
948 paint.setColor(DlColor::RGBA(0.1294, 0.5882, 0.9529, 1.0));
949 recorder_canvas.DrawRect(SkRect::MakeXYWH(200.0, 200.0, 600, 600), paint);
950
951 DisplayListBuilder canvas;
952 AiksContext renderer(GetContext(), nullptr);
953 paint.setColor(DlColor::kTransparent());
954 canvas.DrawPaint(paint);
955
956 auto image =
957 DisplayListToTexture(recorder_canvas.Build(), {1000, 1000}, renderer);
958 if (image) {
959 canvas.DrawImage(DlImageImpeller::Make(image), SkPoint{}, {});
960 paint.setColor(DlColor::RGBA(0.1, 0.1, 0.1, 0.2));
961 canvas.DrawRect(SkRect::MakeSize({1000, 1000}), paint);
962 }
963
964 ASSERT_TRUE(OpenPlaygroundHere(canvas.Build()));
965 }
966
967 // Regression test for https://github.com/flutter/flutter/issues/142358 .
968 // Without a change to force render pass construction the image is left in an
969 // undefined layout and triggers a validation error.
970 TEST_P(AiksTest, CanEmptyPictureConvertToImage) {
971 DisplayListBuilder recorder_builder;
972
973 DisplayListBuilder builder;
974 AiksContext renderer(GetContext(), nullptr);
975
976 DlPaint paint;
977 paint.setColor(DlColor::kTransparent());
978 builder.DrawPaint(paint);
979
980 auto result_image =
981 DisplayListToTexture(builder.Build(), ISize{1000, 1000}, renderer);
982 if (result_image) {
983 recorder_builder.DrawImage(DlImageImpeller::Make(result_image), SkPoint{},
984 {});
985
986 paint.setColor(DlColor::RGBA(0.1, 0.1, 0.1, 0.2));
987 recorder_builder.DrawRect(SkRect::MakeSize({1000, 1000}), paint);
988 }
989
990 ASSERT_TRUE(OpenPlaygroundHere(recorder_builder.Build()));
991 }
992
993 TEST_P(AiksTest, DepthValuesForLineMode) {
994 // Ensures that the additional draws created by line/polygon mode all
995 // have the same depth values.
996 DisplayListBuilder builder;
997
998 SkPath path = SkPath::Circle(100, 100, 100);
999
1000 builder.DrawPath(path, DlPaint()
1001 .setColor(DlColor::kRed())
1002 .setDrawStyle(DlDrawStyle::kStroke)
1003 .setStrokeWidth(5));
1004 builder.Save();
1005 builder.ClipPath(path);
1006
1007 std::vector<DlPoint> points = {
1008 DlPoint::MakeXY(0, -200), DlPoint::MakeXY(400, 200),
1009 DlPoint::MakeXY(0, -100), DlPoint::MakeXY(400, 300),
1010 DlPoint::MakeXY(0, 0), DlPoint::MakeXY(400, 400),
1011 DlPoint::MakeXY(0, 100), DlPoint::MakeXY(400, 500),
1012 DlPoint::MakeXY(0, 150), DlPoint::MakeXY(400, 600)};
1013
1014 builder.DrawPoints(DisplayListBuilder::PointMode::kLines, points.size(),
1015 points.data(),
1016 DlPaint().setColor(DlColor::kBlue()).setStrokeWidth(10));
1017 builder.Restore();
1018
1019 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1020 }
1021
1022 TEST_P(AiksTest, DepthValuesForPolygonMode) {
1023 // Ensures that the additional draws created by line/polygon mode all
1024 // have the same depth values.
1025 DisplayListBuilder builder;
1026
1027 SkPath path = SkPath::Circle(100, 100, 100);
1028
1029 builder.DrawPath(path, DlPaint()
1030 .setColor(DlColor::kRed())
1031 .setDrawStyle(DlDrawStyle::kStroke)
1032 .setStrokeWidth(5));
1033 builder.Save();
1034 builder.ClipPath(path);
1035
1036 std::vector<DlPoint> points = {
1037 DlPoint::MakeXY(0, -200), DlPoint::MakeXY(400, 200),
1038 DlPoint::MakeXY(0, -100), DlPoint::MakeXY(400, 300),
1039 DlPoint::MakeXY(0, 0), DlPoint::MakeXY(400, 400),
1040 DlPoint::MakeXY(0, 100), DlPoint::MakeXY(400, 500),
1041 DlPoint::MakeXY(0, 150), DlPoint::MakeXY(400, 600)};
1042
1043 builder.DrawPoints(DisplayListBuilder::PointMode::kPolygon, points.size(),
1044 points.data(),
1045 DlPaint().setColor(DlColor::kBlue()).setStrokeWidth(10));
1046 builder.Restore();
1047
1048 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1049 }
1050
1051 // Verifies that an image rasterized and readback is in the correct orientation
1052 // by re-uploading it.
1053 TEST_P(AiksTest, ToImageFromImage) {
1054 DisplayListBuilder builder;
1055 Path ip_path = PathBuilder{}
1056 .AddArc(DlRect::MakeLTRB(0, 0, 100, 100), Radians(0),
1057 Radians(3.14 / 2))
1058 .TakePath();
1059 DlPath path = DlPath(ip_path);
1060
1061 builder.DrawPath(path, DlPaint().setColor(DlColor::kRed()));
1062
1063 AiksContext renderer(GetContext(), nullptr);
1064 auto texture =
1065 DisplayListToTexture(builder.Build(), ISize(100, 100), renderer);
1066
1067 // First, Readback the texture data into a host buffer.
1068 impeller::DeviceBufferDescriptor desc;
1069 desc.size = texture->GetTextureDescriptor().GetByteSizeOfBaseMipLevel();
1070 desc.readback = true;
1071 desc.storage_mode = StorageMode::kHostVisible;
1072
1073 auto device_buffer = GetContext()->GetResourceAllocator()->CreateBuffer(desc);
1074 {
1075 auto cmd_buffer = GetContext()->CreateCommandBuffer();
1076 auto blit_pass = cmd_buffer->CreateBlitPass();
1077
1078 blit_pass->AddCopy(texture, device_buffer);
1079 blit_pass->EncodeCommands();
1080
1081 auto latch = std::make_shared<fml::CountDownLatch>(1u);
1082 GetContext()->GetCommandQueue()->Submit(
1083 {cmd_buffer},
1084 [latch](CommandBuffer::Status status) { latch->CountDown(); });
1085 latch->Wait();
1086 }
1087
1088 impeller::TextureDescriptor tex_desc = texture->GetTextureDescriptor();
1089 auto reupload_texture =
1090 GetContext()->GetResourceAllocator()->CreateTexture(tex_desc);
1091
1092 // Next, Re-upload the data into a new texture.
1093 {
1094 auto cmd_buffer = GetContext()->CreateCommandBuffer();
1095 auto blit_pass = cmd_buffer->CreateBlitPass();
1096 blit_pass->AddCopy(DeviceBuffer::AsBufferView(device_buffer),
1097 reupload_texture);
1098 blit_pass->ConvertTextureToShaderRead(texture);
1099 blit_pass->EncodeCommands();
1100
1101 auto latch = std::make_shared<fml::CountDownLatch>(1u);
1102 GetContext()->GetCommandQueue()->Submit(
1103 {cmd_buffer},
1104 [latch](CommandBuffer::Status status) { latch->CountDown(); });
1105 latch->Wait();
1106 }
1107
1108 // Draw the results side by side. These should look the same.
1109 DisplayListBuilder canvas;
1110 DlPaint paint = DlPaint();
1111 canvas.DrawRect(
1112 DlRect::MakeLTRB(0, 0, 100, 100),
1113 DlPaint().setColor(DlColor::kBlue()).setDrawStyle(DlDrawStyle::kStroke));
1114 canvas.DrawImage(DlImageImpeller::Make(texture), DlPoint(0, 0),
1115 DlImageSampling::kNearestNeighbor, &paint);
1116
1117 canvas.DrawRect(
1118 DlRect::MakeLTRB(0, 100, 100, 200),
1119 DlPaint().setColor(DlColor::kRed()).setDrawStyle(DlDrawStyle::kStroke));
1120 canvas.DrawImage(DlImageImpeller::Make(reupload_texture), DlPoint(0, 100),
1121 DlImageSampling::kNearestNeighbor, &paint);
1122 OpenPlaygroundHere(canvas.Build());
1123 }
1124
1125 } // namespace testing
1126 } // namespace impeller
impeller::DeviceBuffer::AsBufferView
static BufferView AsBufferView(std::shared_ptr< DeviceBuffer > buffer)
Create a buffer view of this entire buffer.
Definition: device_buffer.cc:18
impeller::ISize
ISize64 ISize
Definition: size.h:174
impeller::AiksPlayground
Definition: aiks_playground.h:16
impeller::k1OverSqrt2
constexpr float k1OverSqrt2
Definition: constants.h:50
impeller::Scalar
float Scalar
Definition: scalar.h:18
impeller::AiksContext
Definition: aiks_context.h:19
impeller::AiksContext::GetContentContext
ContentContext & GetContentContext() const
Definition: aiks_context.cc:42
aiks_unittests.h
impeller::DeviceBufferDescriptor
Definition: device_buffer_descriptor.h:14
device_buffer.h
impeller::DlPath
flutter::DlPath DlPath
Definition: dl_dispatcher.h:28
impeller::TextureDescriptor::format
PixelFormat format
Definition: texture_descriptor.h:41
impeller::PixelFormat::kR8G8B8A8UNormInt
@ kR8G8B8A8UNormInt
dl_dispatcher.h
texture_descriptor.h
impeller::PathBuilder
Definition: path_builder.h:15
impeller::TextureDescriptor::mip_count
size_t mip_count
Definition: texture_descriptor.h:43
path_builder.h
formats.h
impeller::DeviceBufferDescriptor::size
size_t size
Definition: device_buffer_descriptor.h:16
impeller::StorageMode::kHostVisible
@ kHostVisible
x
int32_t x
Definition: dl_golden_unittests.cc:443
impeller::DlImageImpeller::Make
static sk_sp< DlImageImpeller > Make(std::shared_ptr< Texture > texture, OwningContext owning_context=OwningContext::kIO)
Definition: dl_image_impeller.cc:23
impeller::TSize
Definition: size.h:25
impeller::Path
Paths are lightweight objects that describe a collection of linear, quadratic, or cubic segments....
Definition: path.h:53
impeller::DeviceBufferDescriptor::storage_mode
StorageMode storage_mode
Definition: device_buffer_descriptor.h:15
impeller::Radians
Definition: scalar.h:43
flutter
Definition: dl_golden_blur_unittests.cc:16
impeller::RenderTarget
Definition: render_target.h:38
impeller::PathBuilder::TakePath
Path TakePath(FillType fill=FillType::kNonZero)
Definition: path_builder.cc:28
impeller::testing::TEST_P
TEST_P(AiksTest, DrawAtlasNoColor)
Definition: aiks_dl_atlas_unittests.cc:57
scalar.h
impeller::AiksContext::GetContext
std::shared_ptr< Context > GetContext() const
Definition: aiks_context.cc:38
impeller::TextureDescriptor::size
ISize size
Definition: texture_descriptor.h:42
impeller::ContentContext::GetRenderTargetCache
const std::shared_ptr< RenderTargetAllocator > & GetRenderTargetCache() const
Definition: content_context.h:838
impeller::TextureDescriptor::GetByteSizeOfBaseMipLevel
constexpr size_t GetByteSizeOfBaseMipLevel() const
Definition: texture_descriptor.h:48
impeller::DlPoint
flutter::DlPoint DlPoint
Definition: dl_dispatcher.h:24
impeller::DeviceBufferDescriptor::readback
bool readback
Definition: device_buffer_descriptor.h:19
scale
const Scalar scale
Definition: stroke_path_geometry.cc:316
impeller::AiksPlayground::ImGuiBegin
static bool ImGuiBegin(const char *name, bool *p_open, ImGuiWindowFlags flags)
Definition: aiks_playground.cc:31
impeller::DisplayListToTexture
std::shared_ptr< Texture > DisplayListToTexture(const sk_sp< flutter::DisplayList > &display_list, ISize size, AiksContext &context, bool reset_host_buffer, bool generate_mips)
Render the provided display list to a texture with the given size.
Definition: dl_dispatcher.cc:1249
impeller::TextureDescriptor::storage_mode
StorageMode storage_mode
Definition: texture_descriptor.h:39
impeller::CommandBuffer::Status
Status
Definition: command_buffer.h:49
impeller::TRect::MakeLTRB
constexpr static TRect MakeLTRB(Type left, Type top, Type right, Type bottom)
Definition: rect.h:129
device_buffer_descriptor.h
impeller::TextureDescriptor
A lightweight object that describes the attributes of a texture that can then used an allocator to cr...
Definition: texture_descriptor.h:38
impeller::TSize::MipCount
constexpr size_t MipCount() const
Definition: size.h:140
impeller
Definition: allocation.cc:12
impeller::PathBuilder::AddArc
PathBuilder & AddArc(const Rect &oval_bounds, Radians start, Radians sweep, bool use_center=false)
Definition: path_builder.cc:338
dl_image_impeller.h