Flutter Impeller
aiks_blend_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 
6 
7 #include "flutter/testing/testing.h"
8 #include "impeller/aiks/canvas.h"
12 
13 ////////////////////////////////////////////////////////////////////////////////
14 // This is for tests of Canvas that are interested the results of rendering
15 // blends.
16 ////////////////////////////////////////////////////////////////////////////////
17 
18 namespace impeller {
19 namespace testing {
20 
21 TEST_P(AiksTest, CanRenderAdvancedBlendColorFilterWithSaveLayer) {
22  Canvas canvas;
23 
24  Rect layer_rect = Rect::MakeXYWH(0, 0, 500, 500);
25  canvas.ClipRect(layer_rect);
26 
27  canvas.SaveLayer(
28  {
30  Color(0, 1, 0, 0.5)),
31  },
32  layer_rect);
33 
34  Paint paint;
35  canvas.DrawPaint({.color = Color::Black()});
36  canvas.DrawRect(Rect::MakeXYWH(100, 100, 300, 300),
37  {.color = Color::White()});
38  canvas.Restore();
39 
40  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
41 }
42 
43 TEST_P(AiksTest, BlendModeShouldCoverWholeScreen) {
44  Canvas canvas;
45  Paint paint;
46 
47  paint.color = Color::Red();
48  canvas.DrawPaint(paint);
49 
50  paint.blend_mode = BlendMode::kSourceOver;
51  canvas.SaveLayer(paint);
52 
53  paint.color = Color::White();
54  canvas.DrawRect(Rect::MakeXYWH(100, 100, 400, 400), paint);
55 
56  paint.blend_mode = BlendMode::kSource;
57  canvas.SaveLayer(paint);
58 
59  paint.color = Color::Blue();
60  canvas.DrawRect(Rect::MakeXYWH(200, 200, 200, 200), paint);
61 
62  canvas.Restore();
63  canvas.Restore();
64 
65  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
66 }
67 
68 TEST_P(AiksTest, CanDrawPaintWithAdvancedBlend) {
69  Canvas canvas;
70  canvas.Scale(Vector2(0.2, 0.2));
71  canvas.DrawPaint({.color = Color::MediumTurquoise()});
72  canvas.DrawPaint({.color = Color::Color::OrangeRed().WithAlpha(0.5),
73  .blend_mode = BlendMode::kHue});
74  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
75 }
76 
77 TEST_P(AiksTest, DrawPaintWithAdvancedBlendOverFilter) {
78  Paint filtered = {
79  .color = Color::Black(),
80  .mask_blur_descriptor =
83  .sigma = Sigma(60),
84  },
85  };
86 
87  Canvas canvas;
88  canvas.DrawPaint({.color = Color::White()});
89  canvas.DrawCircle({300, 300}, 200, filtered);
90  canvas.DrawPaint({.color = Color::Green(), .blend_mode = BlendMode::kScreen});
91  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
92 }
93 
94 TEST_P(AiksTest, DrawAdvancedBlendPartlyOffscreen) {
95  std::vector<Color> colors = {Color{0.9568, 0.2627, 0.2118, 1.0},
96  Color{0.1294, 0.5882, 0.9529, 1.0}};
97  std::vector<Scalar> stops = {0.0, 1.0};
98 
99  Paint paint = {
100  .color_source = ColorSource::MakeLinearGradient(
101  {0, 0}, {100, 100}, std::move(colors), std::move(stops),
103  .blend_mode = BlendMode::kLighten,
104  };
105 
106  Canvas canvas;
107  canvas.DrawPaint({.color = Color::Blue()});
108  canvas.Scale(Vector2(2, 2));
109  canvas.ClipRect(Rect::MakeLTRB(0, 0, 200, 200));
110  canvas.DrawCircle({100, 100}, 100, paint);
111  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
112 }
113 
114 TEST_P(AiksTest, PaintBlendModeIsRespected) {
115  Paint paint;
116  Canvas canvas;
117  // Default is kSourceOver.
118  paint.color = Color(1, 0, 0, 0.5);
119  canvas.DrawCircle(Point(150, 200), 100, paint);
120  paint.color = Color(0, 1, 0, 0.5);
121  canvas.DrawCircle(Point(250, 200), 100, paint);
122 
123  paint.blend_mode = BlendMode::kPlus;
124  paint.color = Color::Red();
125  canvas.DrawCircle(Point(450, 250), 100, paint);
126  paint.color = Color::Green();
127  canvas.DrawCircle(Point(550, 250), 100, paint);
128  paint.color = Color::Blue();
129  canvas.DrawCircle(Point(500, 150), 100, paint);
130  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
131 }
132 
133 // Bug: https://github.com/flutter/flutter/issues/142549
134 TEST_P(AiksTest, BlendModePlusAlphaWideGamut) {
135  EXPECT_EQ(GetContext()->GetCapabilities()->GetDefaultColorFormat(),
137  auto texture = CreateTextureForFixture("airplane.jpg",
138  /*enable_mipmapping=*/true);
139 
140  Canvas canvas;
141  canvas.Scale(GetContentScale());
142  canvas.DrawPaint({.color = Color(0.9, 1.0, 0.9, 1.0)});
143  canvas.SaveLayer({});
144  Paint paint;
145  paint.blend_mode = BlendMode::kPlus;
146  paint.color = Color::Red();
147  canvas.DrawRect(Rect::MakeXYWH(100, 100, 400, 400), paint);
148  paint.color = Color::White();
149  canvas.DrawImageRect(
150  std::make_shared<Image>(texture), Rect::MakeSize(texture->GetSize()),
151  Rect::MakeXYWH(100, 100, 400, 400).Expand(-100, -100), paint);
152  canvas.Restore();
153  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
154 }
155 
156 // Bug: https://github.com/flutter/flutter/issues/142549
157 TEST_P(AiksTest, BlendModePlusAlphaColorFilterWideGamut) {
158  EXPECT_EQ(GetContext()->GetCapabilities()->GetDefaultColorFormat(),
160  auto texture = CreateTextureForFixture("airplane.jpg",
161  /*enable_mipmapping=*/true);
162 
163  Canvas canvas;
164  canvas.Scale(GetContentScale());
165  canvas.DrawPaint({.color = Color(0.1, 0.2, 0.1, 1.0)});
166  canvas.SaveLayer({
167  .color_filter =
169  });
170  Paint paint;
171  paint.color = Color::Red();
172  canvas.DrawRect(Rect::MakeXYWH(100, 100, 400, 400), paint);
173  paint.color = Color::White();
174  canvas.DrawImageRect(
175  std::make_shared<Image>(texture), Rect::MakeSize(texture->GetSize()),
176  Rect::MakeXYWH(100, 100, 400, 400).Expand(-100, -100), paint);
177  canvas.Restore();
178  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
179 }
180 
181 #define BLEND_MODE_TUPLE(blend_mode) {#blend_mode, BlendMode::k##blend_mode},
182 
184  std::vector<const char*> blend_mode_names;
185  std::vector<BlendMode> blend_mode_values;
186 };
187 
189  std::vector<const char*> blend_mode_names;
190  std::vector<BlendMode> blend_mode_values;
191  {
192  const std::vector<std::tuple<const char*, BlendMode>> blends = {
194  assert(blends.size() ==
195  static_cast<size_t>(Entity::kLastAdvancedBlendMode) + 1);
196  for (const auto& [name, mode] : blends) {
197  blend_mode_names.push_back(name);
198  blend_mode_values.push_back(mode);
199  }
200  }
201 
202  return {blend_mode_names, blend_mode_values};
203 }
204 
205 TEST_P(AiksTest, ColorWheel) {
206  // Compare with https://fiddle.skia.org/c/@BlendModes
207 
209 
210  auto draw_color_wheel = [](Canvas& canvas) {
211  /// color_wheel_sampler: r=0 -> fuchsia, r=2pi/3 -> yellow, r=4pi/3 ->
212  /// cyan domain: r >= 0 (because modulo used is non euclidean)
213  auto color_wheel_sampler = [](Radians r) {
214  Scalar x = r.radians / k2Pi + 1;
215 
216  // https://www.desmos.com/calculator/6nhjelyoaj
217  auto color_cycle = [](Scalar x) {
218  Scalar cycle = std::fmod(x, 6.0f);
219  return std::max(0.0f, std::min(1.0f, 2 - std::abs(2 - cycle)));
220  };
221  return Color(color_cycle(6 * x + 1), //
222  color_cycle(6 * x - 1), //
223  color_cycle(6 * x - 3), //
224  1);
225  };
226 
227  Paint paint;
228  paint.blend_mode = BlendMode::kSourceOver;
229 
230  // Draw a fancy color wheel for the backdrop.
231  // https://www.desmos.com/calculator/xw7kafthwd
232  const int max_dist = 900;
233  for (int i = 0; i <= 900; i++) {
234  Radians r(kPhi / k2Pi * i);
235  Scalar distance = r.radians / std::powf(4.12, 0.0026 * r.radians);
236  Scalar normalized_distance = static_cast<Scalar>(i) / max_dist;
237 
238  paint.color =
239  color_wheel_sampler(r).WithAlpha(1.0f - normalized_distance);
240  Point position(distance * std::sin(r.radians),
241  -distance * std::cos(r.radians));
242 
243  canvas.DrawCircle(position, 9 + normalized_distance * 3, paint);
244  }
245  };
246 
247  std::shared_ptr<Image> color_wheel_image;
248  Matrix color_wheel_transform;
249 
250  auto callback = [&](AiksContext& renderer) -> std::optional<Picture> {
251  // UI state.
252  static bool cache_the_wheel = true;
253  static int current_blend_index = 3;
254  static float dst_alpha = 1;
255  static float src_alpha = 1;
256  static Color color0 = Color::Red();
257  static Color color1 = Color::Green();
258  static Color color2 = Color::Blue();
259 
260  if (AiksTest::ImGuiBegin("Controls", nullptr,
261  ImGuiWindowFlags_AlwaysAutoResize)) {
262  ImGui::Checkbox("Cache the wheel", &cache_the_wheel);
263  ImGui::ListBox("Blending mode", &current_blend_index,
264  blend_modes.blend_mode_names.data(),
265  blend_modes.blend_mode_names.size());
266  ImGui::SliderFloat("Source alpha", &src_alpha, 0, 1);
267  ImGui::ColorEdit4("Color A", reinterpret_cast<float*>(&color0));
268  ImGui::ColorEdit4("Color B", reinterpret_cast<float*>(&color1));
269  ImGui::ColorEdit4("Color C", reinterpret_cast<float*>(&color2));
270  ImGui::SliderFloat("Destination alpha", &dst_alpha, 0, 1);
271  ImGui::End();
272  }
273 
274  static Point content_scale;
275  Point new_content_scale = GetContentScale();
276 
277  if (!cache_the_wheel || new_content_scale != content_scale) {
278  content_scale = new_content_scale;
279 
280  // Render the color wheel to an image.
281 
282  Canvas canvas;
283  canvas.Scale(content_scale);
284 
285  canvas.Translate(Vector2(500, 400));
286  canvas.Scale(Vector2(3, 3));
287 
288  draw_color_wheel(canvas);
289  auto color_wheel_picture = canvas.EndRecordingAsPicture();
290  auto snapshot = color_wheel_picture.Snapshot(renderer);
291  if (!snapshot.has_value() || !snapshot->texture) {
292  return std::nullopt;
293  }
294  color_wheel_image = std::make_shared<Image>(snapshot->texture);
295  color_wheel_transform = snapshot->transform;
296  }
297 
298  Canvas canvas;
299 
300  // Blit the color wheel backdrop to the screen with managed alpha.
301  canvas.SaveLayer({.color = Color::White().WithAlpha(dst_alpha),
302  .blend_mode = BlendMode::kSource});
303  {
304  canvas.DrawPaint({.color = Color::White()});
305 
306  canvas.Save();
307  canvas.Transform(color_wheel_transform);
308  canvas.DrawImage(color_wheel_image, Point(), Paint());
309  canvas.Restore();
310  }
311  canvas.Restore();
312 
313  canvas.Scale(content_scale);
314  canvas.Translate(Vector2(500, 400));
315  canvas.Scale(Vector2(3, 3));
316 
317  // Draw 3 circles to a subpass and blend it in.
318  canvas.SaveLayer(
319  {.color = Color::White().WithAlpha(src_alpha),
320  .blend_mode = blend_modes.blend_mode_values[current_blend_index]});
321  {
322  Paint paint;
323  paint.blend_mode = BlendMode::kPlus;
324  const Scalar x = std::sin(k2Pi / 3);
325  const Scalar y = -std::cos(k2Pi / 3);
326  paint.color = color0;
327  canvas.DrawCircle(Point(-x, y) * 45, 65, paint);
328  paint.color = color1;
329  canvas.DrawCircle(Point(0, -1) * 45, 65, paint);
330  paint.color = color2;
331  canvas.DrawCircle(Point(x, y) * 45, 65, paint);
332  }
333  canvas.Restore();
334 
335  return canvas.EndRecordingAsPicture();
336  };
337 
338  ASSERT_TRUE(OpenPlaygroundHere(callback));
339 }
340 
341 TEST_P(AiksTest, ForegroundBlendSubpassCollapseOptimization) {
342  Canvas canvas;
343 
344  canvas.SaveLayer({
345  .color_filter =
347  });
348 
349  canvas.Translate({500, 300, 0});
350  canvas.Rotate(Radians(2 * kPi / 3));
351  canvas.DrawRect(Rect::MakeXYWH(100, 100, 200, 200), {.color = Color::Blue()});
352 
353  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
354 }
355 
356 TEST_P(AiksTest, ClearBlend) {
357  Canvas canvas;
358  Paint white;
359  white.color = Color::Blue();
360  canvas.DrawRect(Rect::MakeXYWH(0, 0, 600.0, 600.0), white);
361 
362  Paint clear;
364 
365  canvas.DrawCircle(Point::MakeXY(300.0, 300.0), 200.0, clear);
366 }
367 
368 static Picture BlendModeTest(Vector2 content_scale,
369  BlendMode blend_mode,
370  const std::shared_ptr<Image>& src_image,
371  const std::shared_ptr<Image>& dst_image,
372  Scalar src_alpha) {
373  if (AiksTest::ImGuiBegin("Controls", nullptr,
374  ImGuiWindowFlags_AlwaysAutoResize)) {
375  ImGui::SliderFloat("Source alpha", &src_alpha, 0, 1);
376  ImGui::End();
377  }
378 
379  Color destination_color = Color::CornflowerBlue().WithAlpha(0.75);
380  auto source_colors = std::vector<Color>({Color::White().WithAlpha(0.75),
381  Color::LimeGreen().WithAlpha(0.75),
382  Color::Black().WithAlpha(0.75)});
383 
384  Canvas canvas;
385  canvas.DrawPaint({.color = Color::Black()});
386  // TODO(bdero): Why does this cause the left image to double scale on high DPI
387  // displays.
388  // canvas.Scale(content_scale);
389 
390  //----------------------------------------------------------------------------
391  /// 1. Save layer blending (top squares).
392  ///
393 
394  canvas.Save();
395  for (const auto& color : source_colors) {
396  canvas.Save();
397  {
398  canvas.ClipRect(Rect::MakeXYWH(25, 25, 100, 100));
399  // Perform the blend in a SaveLayer so that the initial backdrop color is
400  // fully transparent black. SourceOver blend the result onto the parent
401  // pass.
402  canvas.SaveLayer({});
403  {
404  canvas.DrawPaint({.color = destination_color});
405  // Draw the source color in an offscreen pass and blend it to the parent
406  // pass.
407  canvas.SaveLayer({.blend_mode = blend_mode});
408  { //
409  canvas.DrawRect(Rect::MakeXYWH(25, 25, 100, 100), {.color = color});
410  }
411  canvas.Restore();
412  }
413  canvas.Restore();
414  }
415  canvas.Restore();
416  canvas.Translate(Vector2(100, 0));
417  }
418  canvas.RestoreToCount(0);
419 
420  //----------------------------------------------------------------------------
421  /// 2. CPU blend modes (bottom squares).
422  ///
423 
424  canvas.Save();
425  canvas.Translate({0, 100});
426  // Perform the blend in a SaveLayer so that the initial backdrop color is
427  // fully transparent black. SourceOver blend the result onto the parent pass.
428  canvas.SaveLayer({});
429  for (const auto& color : source_colors) {
430  // Simply write the CPU blended color to the pass.
431  canvas.DrawRect(Rect::MakeXYWH(25, 25, 100, 100),
432  {.color = destination_color.Blend(color, blend_mode),
433  .blend_mode = BlendMode::kSourceOver});
434  canvas.Translate(Vector2(100, 0));
435  }
436  canvas.Restore();
437  canvas.Restore();
438 
439  //----------------------------------------------------------------------------
440  /// 3. Image blending (bottom images).
441  ///
442  /// Compare these results with the images in the Flutter blend mode
443  /// documentation: https://api.flutter.dev/flutter/dart-ui/BlendMode.html
444  ///
445 
446  canvas.Translate({0, 250});
447 
448  // Draw grid behind the images.
449  canvas.DrawRect(Rect::MakeLTRB(0, 0, 800, 400),
450  {.color = Color::MakeRGBA8(41, 41, 41, 255)});
451  Paint square_paint = {.color = Color::MakeRGBA8(15, 15, 15, 255)};
452  for (int y = 0; y < 400 / 8; y++) {
453  for (int x = 0; x < 800 / 16; x++) {
454  canvas.DrawRect(Rect::MakeXYWH(x * 16 + (y % 2) * 8, y * 8, 8, 8),
455  square_paint);
456  }
457  }
458 
459  // Uploaded image source (left image).
460  canvas.Save();
461  canvas.SaveLayer({.blend_mode = BlendMode::kSourceOver});
462  {
463  canvas.DrawImage(dst_image, {0, 0},
464  {
465  .blend_mode = BlendMode::kSourceOver,
466  });
467  canvas.DrawImage(src_image, {0, 0},
468  {
469  .color = Color::White().WithAlpha(src_alpha),
470  .blend_mode = blend_mode,
471  });
472  }
473  canvas.Restore();
474  canvas.Restore();
475 
476  // Rendered image source (right image).
477  canvas.Save();
478  canvas.SaveLayer({.blend_mode = BlendMode::kSourceOver});
479  {
480  canvas.DrawImage(dst_image, {400, 0},
481  {.blend_mode = BlendMode::kSourceOver});
482  canvas.SaveLayer({.color = Color::White().WithAlpha(src_alpha),
483  .blend_mode = blend_mode});
484  {
485  canvas.DrawImage(src_image, {400, 0},
486  {.blend_mode = BlendMode::kSourceOver});
487  }
488  canvas.Restore();
489  }
490  canvas.Restore();
491  canvas.Restore();
492 
493  return canvas.EndRecordingAsPicture();
494 }
495 
496 #define BLEND_MODE_TEST(blend_mode) \
497  TEST_P(AiksTest, BlendMode##blend_mode) { \
498  auto src_image = std::make_shared<Image>( \
499  CreateTextureForFixture("blend_mode_src.png")); \
500  auto dst_image = std::make_shared<Image>( \
501  CreateTextureForFixture("blend_mode_dst.png")); \
502  auto callback = [&](AiksContext& renderer) -> std::optional<Picture> { \
503  return BlendModeTest(GetContentScale(), BlendMode::k##blend_mode, \
504  src_image, dst_image, /*src_alpha=*/1.0); \
505  }; \
506  OpenPlaygroundHere(callback); \
507  }
509 
510 #define BLEND_MODE_SRC_ALPHA_TEST(blend_mode) \
511  TEST_P(AiksTest, BlendModeSrcAlpha##blend_mode) { \
512  auto src_image = std::make_shared<Image>( \
513  CreateTextureForFixture("blend_mode_src.png")); \
514  auto dst_image = std::make_shared<Image>( \
515  CreateTextureForFixture("blend_mode_dst.png")); \
516  auto callback = [&](AiksContext& renderer) -> std::optional<Picture> { \
517  return BlendModeTest(GetContentScale(), BlendMode::k##blend_mode, \
518  src_image, dst_image, /*src_alpha=*/0.5); \
519  }; \
520  OpenPlaygroundHere(callback); \
521  }
523 
524 TEST_P(AiksTest, CanDrawPaintMultipleTimesInteractive) {
525  auto modes = GetBlendModeSelection();
526 
527  auto callback = [&](AiksContext& renderer) -> std::optional<Picture> {
528  static Color background = Color::MediumTurquoise();
529  static Color foreground = Color::Color::OrangeRed().WithAlpha(0.5);
530  static int current_blend_index = 3;
531 
532  if (AiksTest::ImGuiBegin("Controls", nullptr,
533  ImGuiWindowFlags_AlwaysAutoResize)) {
534  ImGui::ColorEdit4("Background", reinterpret_cast<float*>(&background));
535  ImGui::ColorEdit4("Foreground", reinterpret_cast<float*>(&foreground));
536  ImGui::ListBox("Blend mode", &current_blend_index,
537  modes.blend_mode_names.data(),
538  modes.blend_mode_names.size());
539  ImGui::End();
540  }
541 
542  Canvas canvas;
543  canvas.Scale(Vector2(0.2, 0.2));
544  canvas.DrawPaint({.color = background});
545  canvas.DrawPaint(
546  {.color = foreground,
547  .blend_mode = static_cast<BlendMode>(current_blend_index)});
548  return canvas.EndRecordingAsPicture();
549  };
550  ASSERT_TRUE(OpenPlaygroundHere(callback));
551 }
552 
553 TEST_P(AiksTest, ForegroundPipelineBlendAppliesTransformCorrectly) {
554  auto texture = CreateTextureForFixture("airplane.jpg",
555  /*enable_mipmapping=*/true);
556 
557  Canvas canvas;
558  canvas.Rotate(Degrees(30));
559  canvas.DrawImage(std::make_shared<Image>(texture), {200, 200},
561  Color::Orange())});
562 
563  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
564 }
565 
566 TEST_P(AiksTest, ForegroundAdvancedBlendAppliesTransformCorrectly) {
567  auto texture = CreateTextureForFixture("airplane.jpg",
568  /*enable_mipmapping=*/true);
569 
570  Canvas canvas;
571  canvas.Rotate(Degrees(30));
572  canvas.DrawImage(std::make_shared<Image>(texture), {200, 200},
573  {.color_filter = ColorFilter::MakeBlend(
575 
576  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
577 }
578 
579 TEST_P(AiksTest, FramebufferAdvancedBlendCoverage) {
580  auto texture = CreateTextureForFixture("airplane.jpg",
581  /*enable_mipmapping=*/true);
582 
583  // Draw with an advanced blend that can use FramebufferBlendContents and
584  // verify that the scale transform is correctly applied to the image.
585  Canvas canvas;
586  canvas.DrawPaint({.color = Color::DarkGray()});
587  canvas.Scale(Vector2(0.4, 0.4));
588  canvas.DrawImage(std::make_shared<Image>(texture), {20, 20},
589  {.blend_mode = BlendMode::kMultiply});
590 
591  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
592 }
593 
594 } // namespace testing
595 } // namespace impeller
impeller::Color::Blue
static constexpr Color Blue()
Definition: color.h:278
impeller::AiksPlayground
Definition: aiks_playground.h:17
impeller::Canvas::EndRecordingAsPicture
Picture EndRecordingAsPicture()
Definition: canvas.cc:804
impeller::Scalar
float Scalar
Definition: scalar.h:18
impeller::AiksContext
Definition: aiks_context.h:19
impeller::Canvas::DrawImageRect
void DrawImageRect(const std::shared_ptr< Image > &image, Rect source, Rect dest, const Paint &paint, SamplerDescriptor sampler={}, SourceRectConstraint src_rect_constraint=SourceRectConstraint::kFast)
Definition: canvas.cc:766
BLEND_MODE_TEST
#define BLEND_MODE_TEST(blend_mode)
Definition: aiks_blend_unittests.cc:496
impeller::Color::DarkGray
static constexpr Color DarkGray()
Definition: color.h:372
impeller::PixelFormat::kB10G10R10A10XR
@ kB10G10R10A10XR
impeller::Color::Red
static constexpr Color Red()
Definition: color.h:274
aiks_unittests.h
impeller::ColorSource::MakeLinearGradient
static ColorSource MakeLinearGradient(Point start_point, Point end_point, std::vector< Color > colors, std::vector< Scalar > stops, Entity::TileMode tile_mode, Matrix effect_transform)
Definition: color_source.cc:166
impeller::Paint
Definition: paint.h:23
impeller::TRect< Scalar >::MakeXYWH
constexpr static TRect MakeXYWH(Type x, Type y, Type width, Type height)
Definition: rect.h:136
impeller::BlendMode
BlendMode
Definition: color.h:59
impeller::Color::MakeRGBA8
static constexpr Color MakeRGBA8(uint8_t r, uint8_t g, uint8_t b, uint8_t a)
Definition: color.h:154
impeller::Color
Definition: color.h:124
impeller::Vector4
Definition: vector.h:232
impeller::Paint::color
Color color
Definition: paint.h:68
impeller::BlendMode::kSource
@ kSource
impeller::BlendMode::kColorDodge
@ kColorDodge
impeller::Canvas
Definition: canvas.h:60
impeller::Paint::MaskBlurDescriptor::style
FilterContents::BlurStyle style
Definition: paint.h:49
impeller::Vector2
Point Vector2
Definition: point.h:326
impeller::kPi
constexpr float kPi
Definition: constants.h:26
impeller::BlendMode::kPlus
@ kPlus
impeller::Paint::MaskBlurDescriptor
Definition: paint.h:48
impeller::Color::CornflowerBlue
static constexpr Color CornflowerBlue()
Definition: color.h:344
impeller::Radians::radians
Scalar radians
Definition: scalar.h:39
impeller::FilterContents::BlurStyle::kNormal
@ kNormal
Blurred inside and outside.
impeller::Entity::TileMode::kRepeat
@ kRepeat
impeller::Canvas::DrawRect
void DrawRect(const Rect &rect, const Paint &paint)
Definition: canvas.cc:495
impeller::testing::BlendModeTest
static Picture BlendModeTest(Vector2 content_scale, BlendMode blend_mode, const std::shared_ptr< Image > &src_image, const std::shared_ptr< Image > &dst_image, Scalar src_alpha)
Definition: aiks_blend_unittests.cc:368
impeller::Canvas::DrawImage
void DrawImage(const std::shared_ptr< Image > &image, Point offset, const Paint &paint, SamplerDescriptor sampler={})
Definition: canvas.cc:752
impeller::testing::TEST_P
TEST_P(AiksTest, CanRenderAdvancedBlendColorFilterWithSaveLayer)
Definition: aiks_blend_unittests.cc:21
impeller::BlendMode::kDifference
@ kDifference
impeller::kPhi
constexpr float kPhi
Definition: constants.h:53
impeller::saturated::distance
SI distance
Definition: saturated_math.h:57
impeller::BlendMode::kLighten
@ kLighten
impeller::Picture
Definition: picture.h:17
impeller::Point
TPoint< Scalar > Point
Definition: point.h:322
impeller::k2Pi
constexpr float k2Pi
Definition: constants.h:29
BLEND_MODE_TUPLE
#define BLEND_MODE_TUPLE(blend_mode)
Definition: aiks_blend_unittests.cc:181
impeller::Canvas::Scale
void Scale(const Vector2 &scale)
Definition: canvas.cc:315
impeller::ColorFilter::MakeBlend
static std::shared_ptr< ColorFilter > MakeBlend(BlendMode blend_mode, Color color)
Definition: color_filter.cc:23
impeller::testing::GetBlendModeSelection
static BlendModeSelection GetBlendModeSelection()
Definition: aiks_blend_unittests.cc:188
impeller::Picture::Snapshot
std::optional< Snapshot > Snapshot(AiksContext &context)
Definition: picture.cc:17
impeller::BlendMode::kClear
@ kClear
impeller::Color::WithAlpha
constexpr Color WithAlpha(Scalar new_alpha) const
Definition: color.h:280
impeller::Entity::kLastAdvancedBlendMode
static constexpr BlendMode kLastAdvancedBlendMode
Definition: entity.h:23
impeller::Canvas::DrawCircle
void DrawCircle(const Point &center, Scalar radius, const Paint &paint)
Definition: canvas.cc:566
impeller::Color::White
static constexpr Color White()
Definition: color.h:266
impeller::Sigma
In filters that use Gaussian distributions, "sigma" is a size of one standard deviation in terms of t...
Definition: sigma.h:32
impeller::Canvas::Restore
virtual bool Restore()
Definition: canvas.cc:257
impeller::Radians
Definition: scalar.h:38
canvas.h
impeller::Color::Green
static constexpr Color Green()
Definition: color.h:276
impeller::Canvas::DrawPaint
void DrawPaint(const Paint &paint)
Definition: canvas.cc:352
impeller::testing::BlendModeSelection
Definition: aiks_blend_unittests.cc:183
IMPELLER_FOR_EACH_BLEND_MODE
#define IMPELLER_FOR_EACH_BLEND_MODE(V)
Definition: color.h:19
scalar.h
impeller::Color::MediumTurquoise
static constexpr Color MediumTurquoise()
Definition: color.h:648
impeller::Canvas::Rotate
void Rotate(Radians radians)
Definition: canvas.cc:327
impeller::Color::Orange
static constexpr Color Orange()
Definition: color.h:692
impeller::TRect< Scalar >::MakeSize
constexpr static TRect MakeSize(const TSize< U > &size)
Definition: rect.h:146
impeller::TPoint< Scalar >
impeller::Canvas::Transform
void Transform(const Matrix &transform)
Definition: canvas.cc:294
impeller::Color::Black
static constexpr Color Black()
Definition: color.h:268
impeller::Canvas::Save
virtual void Save(uint32_t total_content_depth=kMaxDepth)
Definition: canvas.cc:184
impeller::BlendMode::kSourceIn
@ kSourceIn
impeller::testing::BlendModeSelection::blend_mode_values
std::vector< BlendMode > blend_mode_values
Definition: aiks_blend_unittests.cc:185
impeller::BlendMode::kScreen
@ kScreen
paint
const Paint & paint
Definition: color_source.cc:38
impeller::AiksPlayground::ImGuiBegin
static bool ImGuiBegin(const char *name, bool *p_open, ImGuiWindowFlags flags)
Definition: aiks_playground.cc:69
impeller::Degrees
Definition: scalar.h:46
color.h
impeller::Color::LimeGreen
static constexpr Color LimeGreen()
Definition: color.h:604
color_filter.h
color
DlColor color
Definition: dl_golden_blur_unittests.cc:23
impeller::BlendMode::kHue
@ kHue
impeller::Canvas::ClipRect
void ClipRect(const Rect &rect, Entity::ClipOperation clip_op=Entity::ClipOperation::kIntersect)
Definition: canvas.cc:599
impeller::TRect< Scalar >::MakeLTRB
constexpr static TRect MakeLTRB(Type left, Type top, Type right, Type bottom)
Definition: rect.h:129
impeller::testing::BlendModeSelection::blend_mode_names
std::vector< const char * > blend_mode_names
Definition: aiks_blend_unittests.cc:184
impeller
Definition: aiks_blend_unittests.cc:18
BLEND_MODE_SRC_ALPHA_TEST
#define BLEND_MODE_SRC_ALPHA_TEST(blend_mode)
Definition: aiks_blend_unittests.cc:510
impeller::Matrix::MakeScale
static constexpr Matrix MakeScale(const Vector3 &s)
Definition: matrix.h:104
impeller::BlendMode::kMultiply
@ kMultiply
impeller::Canvas::SaveLayer
virtual void SaveLayer(const Paint &paint, std::optional< Rect > bounds=std::nullopt, const std::shared_ptr< ImageFilter > &backdrop_filter=nullptr, ContentBoundsPromise bounds_promise=ContentBoundsPromise::kUnknown, uint32_t total_content_depth=kMaxDepth, bool can_distribute_opacity=false)
Definition: canvas.cc:842
impeller::TRect
Definition: rect.h:122
impeller::Matrix
A 4x4 matrix using column-major storage.
Definition: matrix.h:37
impeller::Vector3
Definition: vector.h:20
impeller::BlendMode::kSourceOver
@ kSourceOver
impeller::Paint::blend_mode
BlendMode blend_mode
Definition: paint.h:76
impeller::TRect::Expand
constexpr TRect< T > Expand(T left, T top, T right, T bottom) const
Returns a rectangle with expanded edges. Negative expansion results in shrinking.
Definition: rect.h:605
impeller::TPoint< Scalar >::MakeXY
static constexpr TPoint< Type > MakeXY(Type x, Type y)
Definition: point.h:46
impeller::Canvas::Translate
void Translate(const Vector3 &offset)
Definition: canvas.cc:311
impeller::Color::Blend
Color Blend(Color source, BlendMode blend_mode) const
Blends an unpremultiplied destination color into a given unpremultiplied source color to form a new u...
Definition: color.cc:234