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