7 #include "display_list/display_list.h"
8 #include "display_list/dl_sampling_options.h"
9 #include "display_list/dl_tile_mode.h"
10 #include "display_list/effects/dl_color_filter.h"
11 #include "display_list/effects/dl_color_source.h"
12 #include "display_list/effects/dl_mask_filter.h"
15 #include "flutter/display_list/dl_blend_mode.h"
16 #include "flutter/display_list/dl_builder.h"
17 #include "flutter/display_list/dl_color.h"
18 #include "flutter/display_list/dl_paint.h"
25 #include "impeller/renderer/testing/mocks.h"
37 #define BLEND_MODE_TUPLE(blend_mode) {#blend_mode, BlendMode::k##blend_mode},
45 std::vector<const char*> blend_mode_names;
46 std::vector<BlendMode> blend_mode_values;
48 const std::vector<std::tuple<const char*, BlendMode>> blends = {
50 assert(blends.size() ==
52 for (
const auto& [name, mode] : blends) {
53 blend_mode_names.push_back(name);
54 blend_mode_values.push_back(mode);
58 return {blend_mode_names, blend_mode_values};
62 DisplayListBuilder builder;
64 DlRect layer_rect = DlRect::MakeXYWH(0, 0, 500, 500);
65 builder.ClipRect(layer_rect);
68 save_paint.setColorFilter(DlColorFilter::MakeBlend(
69 DlColor::RGBA(0, 1, 0, 0.5), DlBlendMode::kDifference));
70 builder.SaveLayer(layer_rect, &save_paint);
73 paint.setColor(DlColor::kBlack());
74 builder.DrawPaint(paint);
75 paint.setColor(DlColor::kWhite());
76 builder.DrawRect(DlRect::MakeXYWH(100, 100, 300, 300), paint);
79 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
83 DisplayListBuilder builder;
86 paint.setColor(DlColor::kRed());
87 builder.DrawPaint(paint);
89 paint.setBlendMode(DlBlendMode::kSrcOver);
90 builder.SaveLayer(std::nullopt, &paint);
92 paint.setColor(DlColor::kWhite());
93 builder.DrawRect(DlRect::MakeXYWH(100, 100, 400, 400), paint);
95 paint.setBlendMode(DlBlendMode::kSrc);
96 builder.SaveLayer(std::nullopt, &paint);
98 paint.setColor(DlColor::kBlue());
99 builder.DrawRect(DlRect::MakeXYWH(200, 200, 200, 200), paint);
104 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
108 DisplayListBuilder builder;
110 builder.Scale(0.2, 0.2);
112 paint.setColor(DlColor::RGBA(
115 builder.DrawPaint(paint);
119 paint.setBlendMode(DlBlendMode::kHue);
120 builder.DrawPaint(paint);
122 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
127 paint.setColor(DlColor::kBlack());
128 paint.setMaskFilter(DlBlurMaskFilter::Make(DlBlurStyle::kNormal, 60));
130 DisplayListBuilder builder;
131 paint.setColor(DlColor::kWhite());
132 builder.DrawPaint(paint);
133 paint.setColor(DlColor::kBlack());
134 builder.DrawCircle(
DlPoint(300, 300), 200, paint);
135 paint.setColor(DlColor::kGreen());
136 paint.setBlendMode(DlBlendMode::kScreen);
137 builder.DrawPaint(paint);
139 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
143 DisplayListBuilder builder;
146 draw_paint.setColor(DlColor::kBlue());
147 builder.DrawPaint(draw_paint);
149 builder.ClipRect(DlRect::MakeLTRB(0, 0, 200, 200));
151 std::vector<DlColor> colors = {DlColor::RGBA(0.9568, 0.2627, 0.2118, 1.0),
152 DlColor::RGBA(0.1294, 0.5882, 0.9529, 1.0)};
153 std::vector<Scalar> stops = {0.0, 1.0};
156 DlMatrix matrix = DlMatrix::MakeScale({0.3, 0.3, 1.0});
157 paint.setColorSource(DlColorSource::MakeLinear(
166 paint.setBlendMode(DlBlendMode::kLighten);
168 builder.DrawCircle(
DlPoint(100, 100), 100, paint);
169 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
174 DisplayListBuilder builder;
177 paint.setColor(DlColor::RGBA(1, 0, 0, 0.5));
178 builder.DrawCircle(
DlPoint(150, 200), 100, paint);
180 paint.setColor(DlColor::RGBA(0, 1, 0, 0.5));
181 builder.DrawCircle(
DlPoint(250, 200), 100, paint);
183 paint.setBlendMode(DlBlendMode::kPlus);
185 paint.setColor(DlColor::kRed());
186 builder.DrawCircle(
DlPoint(450, 250), 100, paint);
188 paint.setColor(DlColor::kGreen());
189 builder.DrawCircle(
DlPoint(550, 250), 100, paint);
191 paint.setColor(DlColor::kBlue());
192 builder.DrawCircle(
DlPoint(500, 150), 100, paint);
194 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
199 bool has_color_filter =
true;
200 auto callback = [&]() -> sk_sp<DisplayList> {
202 ImGuiWindowFlags_AlwaysAutoResize)) {
203 ImGui::Checkbox(
"has color filter", &has_color_filter);
207 DisplayListBuilder builder;
208 builder.Scale(GetContentScale().
x, GetContentScale().y);
215 std::vector<DlBlendMode> blend_modes = {
216 DlBlendMode::kSrc, DlBlendMode::kSrcATop, DlBlendMode::kSrcOver,
217 DlBlendMode::kSrcIn, DlBlendMode::kSrcOut, DlBlendMode::kDst,
218 DlBlendMode::kDstATop, DlBlendMode::kDstOver, DlBlendMode::kDstIn,
219 DlBlendMode::kDstOut, DlBlendMode::kClear, DlBlendMode::kXor};
221 for (uint32_t i = 0; i < blend_modes.size(); ++i) {
223 builder.Translate((i % 5) * 200, (i / 5) * 200);
224 builder.Scale(0.4, 0.4);
227 builder.DrawImage(dst_image,
DlPoint(0, 0),
228 DlImageSampling::kMipmapLinear, &dstPaint);
232 srcPaint.setBlendMode(blend_modes[i]);
233 if (has_color_filter) {
234 std::shared_ptr<const DlColorFilter> color_filter =
235 DlColorFilter::MakeBlend(DlColor::RGBA(0.9, 0.5, 0.0, 1.0),
236 DlBlendMode::kSrcIn);
237 srcPaint.setColorFilter(color_filter);
239 builder.DrawImage(src_image,
DlPoint(0, 0),
240 DlImageSampling::kMipmapLinear, &srcPaint);
244 return builder.Build();
246 ASSERT_TRUE(OpenPlaygroundHere(callback));
251 bool has_color_filter =
true;
252 auto callback = [&]() -> sk_sp<DisplayList> {
254 ImGuiWindowFlags_AlwaysAutoResize)) {
255 ImGui::Checkbox(
"has color filter", &has_color_filter);
259 DisplayListBuilder builder;
260 builder.Scale(GetContentScale().
x, GetContentScale().y);
267 std::vector<DlBlendMode> blend_modes = {
268 DlBlendMode::kScreen, DlBlendMode::kOverlay,
269 DlBlendMode::kDarken, DlBlendMode::kLighten,
270 DlBlendMode::kColorDodge, DlBlendMode::kColorBurn,
271 DlBlendMode::kHardLight, DlBlendMode::kSoftLight,
272 DlBlendMode::kDifference, DlBlendMode::kExclusion,
273 DlBlendMode::kMultiply, DlBlendMode::kHue,
274 DlBlendMode::kSaturation, DlBlendMode::kColor,
275 DlBlendMode::kLuminosity,
278 for (uint32_t i = 0; i < blend_modes.size(); ++i) {
280 builder.Translate((i % 5) * 200, (i / 5) * 200);
281 builder.Scale(0.4, 0.4);
284 builder.DrawImage(dst_image,
DlPoint(0, 0),
285 DlImageSampling::kMipmapLinear, &dstPaint);
289 srcPaint.setBlendMode(blend_modes[i]);
290 if (has_color_filter) {
291 std::shared_ptr<const DlColorFilter> color_filter =
292 DlColorFilter::MakeBlend(DlColor::RGBA(0.9, 0.5, 0.0, 1.0),
293 DlBlendMode::kSrcIn);
294 srcPaint.setColorFilter(color_filter);
296 builder.DrawImage(src_image,
DlPoint(0, 0),
297 DlImageSampling::kMipmapLinear, &srcPaint);
301 return builder.Build();
303 ASSERT_TRUE(OpenPlaygroundHere(callback));
312 <<
"This backend doesn't yet support setting device capabilities.";
314 if (!WillRenderSomething()) {
315 GTEST_SKIP() <<
"This test requires playgrounds.";
318 std::shared_ptr<const Capabilities> old_capabilities =
319 GetContext()->GetCapabilities();
320 auto mock_capabilities = std::make_shared<MockCapabilities>();
321 EXPECT_CALL(*mock_capabilities, SupportsFramebufferFetch())
322 .Times(::testing::AtLeast(1))
323 .WillRepeatedly(::testing::Return(
false));
324 FLT_FORWARD(mock_capabilities, old_capabilities, GetDefaultColorFormat);
325 FLT_FORWARD(mock_capabilities, old_capabilities, GetDefaultStencilFormat);
326 FLT_FORWARD(mock_capabilities, old_capabilities,
327 GetDefaultDepthStencilFormat);
328 FLT_FORWARD(mock_capabilities, old_capabilities, SupportsOffscreenMSAA);
329 FLT_FORWARD(mock_capabilities, old_capabilities,
330 SupportsImplicitResolvingMSAA);
331 FLT_FORWARD(mock_capabilities, old_capabilities, SupportsReadFromResolve);
332 FLT_FORWARD(mock_capabilities, old_capabilities, SupportsSSBO);
333 FLT_FORWARD(mock_capabilities, old_capabilities, SupportsCompute);
334 FLT_FORWARD(mock_capabilities, old_capabilities,
335 SupportsTextureToTextureBlits);
336 FLT_FORWARD(mock_capabilities, old_capabilities, GetDefaultGlyphAtlasFormat);
337 FLT_FORWARD(mock_capabilities, old_capabilities, SupportsTriangleFan);
338 FLT_FORWARD(mock_capabilities, old_capabilities,
339 SupportsDecalSamplerAddressMode);
340 FLT_FORWARD(mock_capabilities, old_capabilities, SupportsPrimitiveRestart);
341 FLT_FORWARD(mock_capabilities, old_capabilities, GetMinimumUniformAlignment);
342 ASSERT_TRUE(SetCapabilities(mock_capabilities).ok());
344 bool has_color_filter =
true;
345 auto callback = [&]() -> sk_sp<DisplayList> {
347 ImGuiWindowFlags_AlwaysAutoResize)) {
348 ImGui::Checkbox(
"has color filter", &has_color_filter);
352 DisplayListBuilder builder;
353 builder.Scale(GetContentScale().
x, GetContentScale().y);
360 std::vector<DlBlendMode> blend_modes = {
361 DlBlendMode::kScreen, DlBlendMode::kOverlay,
362 DlBlendMode::kDarken, DlBlendMode::kLighten,
363 DlBlendMode::kColorDodge, DlBlendMode::kColorBurn,
364 DlBlendMode::kHardLight, DlBlendMode::kSoftLight,
365 DlBlendMode::kDifference, DlBlendMode::kExclusion,
366 DlBlendMode::kMultiply, DlBlendMode::kHue,
367 DlBlendMode::kSaturation, DlBlendMode::kColor,
368 DlBlendMode::kLuminosity,
371 for (uint32_t i = 0; i < blend_modes.size(); ++i) {
373 builder.Translate((i % 5) * 200, (i / 5) * 200);
374 builder.Scale(0.4, 0.4);
377 builder.DrawImage(dst_image,
DlPoint(0, 0),
378 DlImageSampling::kMipmapLinear, &dstPaint);
382 srcPaint.setBlendMode(blend_modes[i]);
383 if (has_color_filter) {
384 std::shared_ptr<const DlColorFilter> color_filter =
385 DlColorFilter::MakeBlend(DlColor::RGBA(0.9, 0.5, 0.0, 1.0),
386 DlBlendMode::kMultiply);
387 srcPaint.setColorFilter(color_filter);
389 builder.DrawImage(src_image,
DlPoint(0, 0),
390 DlImageSampling::kMipmapLinear, &srcPaint);
394 return builder.Build();
396 ASSERT_TRUE(OpenPlaygroundHere(callback));
401 EXPECT_EQ(GetContext()->GetCapabilities()->GetDefaultColorFormat(),
403 auto texture = CreateTextureForFixture(
"airplane.jpg",
406 DisplayListBuilder builder;
408 builder.Scale(GetContentScale().
x, GetContentScale().y);
410 paint.setColor(DlColor::RGBA(0.9, 1, 0.9, 1.0));
411 builder.DrawPaint(paint);
412 builder.SaveLayer(std::nullopt);
414 paint.setBlendMode(DlBlendMode::kPlus);
415 paint.setColor(DlColor::kRed());
417 builder.DrawRect(DlRect::MakeXYWH(100, 100, 400, 400), paint);
418 paint.setColor(DlColor::kWhite());
421 builder.DrawImageRect(
423 DlRect::MakeWH(texture->GetSize().width, texture->GetSize().height),
424 DlRect::MakeLTRB(rect.GetLeft(), rect.GetTop(),
425 rect.GetRight(), rect.GetBottom()),
426 DlImageSampling::kMipmapLinear, &paint);
428 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
433 EXPECT_EQ(GetContext()->GetCapabilities()->GetDefaultColorFormat(),
435 auto texture = CreateTextureForFixture(
"airplane.jpg",
438 DisplayListBuilder builder;
439 builder.Scale(GetContentScale().
x, GetContentScale().y);
442 paint.setColor(DlColor::RGBA(0.1, 0.2, 0.1, 1.0));
443 builder.DrawPaint(paint);
446 save_paint.setColorFilter(
447 DlColorFilter::MakeBlend(DlColor::RGBA(1, 0, 0, 1), DlBlendMode::kPlus));
448 builder.SaveLayer(std::nullopt, &save_paint);
450 paint.setColor(DlColor::kRed());
451 builder.DrawRect(DlRect::MakeXYWH(100, 100, 400, 400), paint);
453 paint.setColor(DlColor::kWhite());
456 builder.DrawImageRect(
458 DlRect::MakeWH(texture->GetSize().width, texture->GetSize().height),
459 DlRect::MakeLTRB(rect.GetLeft(), rect.GetTop(),
460 rect.GetRight(), rect.GetBottom()),
461 DlImageSampling::kMipmapLinear, &paint);
464 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
468 DisplayListBuilder builder;
471 save_paint.setColorFilter(
472 DlColorFilter::MakeBlend(DlColor::kRed(), DlBlendMode::kColorDodge));
473 builder.SaveLayer(std::nullopt, &save_paint);
475 builder.Translate(500, 300);
479 paint.setColor(DlColor::kBlue());
480 builder.DrawRect(DlRect::MakeXYWH(100, 100, 200, 200), paint);
482 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
486 DisplayListBuilder builder;
489 blue.setColor(DlColor::kBlue());
490 builder.DrawRect(DlRect::MakeXYWH(0, 0, 600.0, 600.0), blue);
493 clear.setBlendMode(DlBlendMode::kClear);
495 builder.DrawCircle(
DlPoint(300.0, 300.0), 200.0, clear);
497 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
502 const sk_sp<DlImageImpeller>& src_image,
503 const sk_sp<DlImageImpeller>& dst_image,
506 ImGuiWindowFlags_AlwaysAutoResize)) {
507 ImGui::SliderFloat(
"Source alpha", &src_alpha, 0, 1);
516 DisplayListBuilder builder;
519 paint.setColor(DlColor::kBlack());
520 builder.DrawPaint(paint);
531 for (
const auto& color : source_colors) {
534 builder.ClipRect(DlRect::MakeXYWH(25, 25, 100, 100));
538 builder.SaveLayer(std::nullopt);
542 DlColor::RGBA(destination_color.
red, destination_color.
green,
543 destination_color.
blue, destination_color.
alpha));
544 builder.DrawPaint(draw_paint);
549 save_paint.setBlendMode(
static_cast<DlBlendMode
>(blend_mode));
550 builder.SaveLayer(std::nullopt, &save_paint);
554 DlColor::RGBA(color.red, color.green, color.blue, color.alpha));
555 builder.DrawRect(DlRect::MakeXYWH(25, 25, 100, 100), paint);
562 builder.Translate(100, 0);
564 builder.RestoreToCount(0);
571 builder.Translate(0, 100);
574 builder.SaveLayer(std::nullopt);
575 for (
const auto& color : source_colors) {
578 auto dest = destination_color.
Blend(color, blend_mode);
579 paint.setColor(DlColor::RGBA(dest.red, dest.green, dest.blue, dest.alpha));
580 paint.setBlendMode(DlBlendMode::kSrcOver);
581 builder.DrawRect(DlRect::MakeXYWH(25, 25, 100, 100), paint);
582 builder.Translate(100, 0);
594 builder.Translate(0, 250);
599 paint.setColor(DlColor::RGBA(41 / 255.0, 41 / 255.0, 41 / 255.0, 1));
600 builder.DrawRect(DlRect::MakeLTRB(0, 0, 800, 400), paint);
603 DlPaint square_paint;
604 square_paint.setColor(DlColor::RGBA(15 / 255.0, 15 / 255.0, 15 / 255.0, 1));
605 for (
int y = 0; y < 400 / 8; y++) {
606 for (
int x = 0;
x < 800 / 16;
x++) {
607 builder.DrawRect(DlRect::MakeXYWH(
x * 16 + (y % 2) * 8, y * 8, 8, 8),
614 paint.setBlendMode(DlBlendMode::kSrcOver);
616 builder.SaveLayer(std::nullopt, &paint);
618 builder.DrawImage(dst_image,
DlPoint(0, 0), DlImageSampling::kMipmapLinear,
621 paint.setColor(DlColor::kWhite().withAlpha(src_alpha * 255));
622 paint.setBlendMode(
static_cast<DlBlendMode
>(blend_mode));
623 builder.DrawImage(src_image,
DlPoint(0, 0), DlImageSampling::kMipmapLinear,
633 builder.SaveLayer(std::nullopt, &save_paint);
635 builder.DrawImage(dst_image,
DlPoint(400, 0),
636 DlImageSampling::kMipmapLinear,
nullptr);
639 save_paint.setColor(DlColor::kWhite().withAlpha(src_alpha * 255));
640 save_paint.setBlendMode(
static_cast<DlBlendMode
>(blend_mode));
641 builder.SaveLayer(std::nullopt, &save_paint);
643 builder.DrawImage(src_image,
DlPoint(400, 0),
644 DlImageSampling::kMipmapLinear,
nullptr);
651 return builder.Build();
654 #define BLEND_MODE_TEST(blend_mode) \
655 TEST_P(AiksTest, BlendMode##blend_mode) { \
657 DlImageImpeller::Make(CreateTextureForFixture("blend_mode_src.png")); \
659 DlImageImpeller::Make(CreateTextureForFixture("blend_mode_dst.png")); \
660 auto callback = [&]() -> sk_sp<DisplayList> { \
661 return BlendModeTest(GetContentScale(), BlendMode::k##blend_mode, \
662 src_image, dst_image,
1.0); \
664 OpenPlaygroundHere(callback); \
668 #define BLEND_MODE_SRC_ALPHA_TEST(blend_mode) \
669 TEST_P(AiksTest, BlendModeSrcAlpha##blend_mode) { \
671 DlImageImpeller::Make(CreateTextureForFixture("blend_mode_src.png")); \
673 DlImageImpeller::Make(CreateTextureForFixture("blend_mode_dst.png")); \
674 auto callback = [&]() -> sk_sp<DisplayList> { \
675 return BlendModeTest(GetContentScale(), BlendMode::k##blend_mode, \
676 src_image, dst_image,
0.5); \
678 OpenPlaygroundHere(callback); \
685 auto callback = [&]() -> sk_sp<DisplayList> {
687 static Color foreground = Color::Color::OrangeRed().
WithAlpha(0.5);
688 static int current_blend_index = 3;
691 ImGuiWindowFlags_AlwaysAutoResize)) {
692 ImGui::ColorEdit4(
"Background",
reinterpret_cast<float*
>(&background));
693 ImGui::ColorEdit4(
"Foreground",
reinterpret_cast<float*
>(&foreground));
694 ImGui::ListBox(
"Blend mode", ¤t_blend_index,
695 modes.blend_mode_names.data(),
696 modes.blend_mode_names.size());
700 DisplayListBuilder builder;
701 builder.Scale(0.2, 0.2);
703 paint.setColor(DlColor(background.
ToARGB()));
704 builder.DrawPaint(paint);
706 paint.setColor(DlColor(foreground.
ToARGB()));
707 paint.setBlendMode(
static_cast<DlBlendMode
>(current_blend_index));
708 builder.DrawPaint(paint);
709 return builder.Build();
711 ASSERT_TRUE(OpenPlaygroundHere(callback));
715 auto texture = CreateTextureForFixture(
"airplane.jpg",
718 DisplayListBuilder builder;
722 image_paint.setColorFilter(DlColorFilter::MakeBlend(
723 DlColor::RGBA(255.0f / 255.0f, 165.0f / 255.0f, 0.0f / 255.0f, 1.0f),
724 DlBlendMode::kSrcIn));
727 DlImageSampling::kMipmapLinear, &image_paint);
729 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
733 auto texture = CreateTextureForFixture(
"airplane.jpg",
736 DisplayListBuilder builder;
740 image_paint.setColorFilter(DlColorFilter::MakeBlend(
741 DlColor::RGBA(255.0f / 255.0f, 165.0f / 255.0f, 0.0f / 255.0f, 1.0f),
742 DlBlendMode::kColorDodge));
745 DlImageSampling::kMipmapLinear, &image_paint);
747 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
751 auto texture = CreateTextureForFixture(
"airplane.jpg",
756 DisplayListBuilder builder;
760 DlColor::RGBA(169.0f / 255.0f, 169.0f / 255.0f, 169.0f / 255.0f, 1.0f));
761 builder.DrawPaint(paint);
762 builder.Scale(0.4, 0.4);
765 image_paint.setBlendMode(DlBlendMode::kMultiply);
768 DlImageSampling::kMipmapLinear, &image_paint);
770 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
778 auto draw_color_wheel = [](DisplayListBuilder& builder) ->
void {
781 auto color_wheel_sampler = [](
Radians r) {
785 auto color_cycle = [](
Scalar x) {
786 Scalar cycle = std::fmod(
x, 6.0f);
787 return std::max(0.0f, std::min(1.0f, 2 - std::abs(2 - cycle)));
789 return Color(color_cycle(6 *
x + 1),
790 color_cycle(6 *
x - 1),
791 color_cycle(6 *
x - 3),
796 paint.setBlendMode(DlBlendMode::kSrcOver);
800 const int max_dist = 900;
801 for (
int i = 0; i <= 900; i++) {
804 Scalar normalized_distance =
static_cast<Scalar>(i) / max_dist;
806 auto color = color_wheel_sampler(r).WithAlpha(1.0f - normalized_distance);
808 DlColor::RGBA(color.red, color.green, color.blue, color.alpha));
812 builder.DrawCircle(position, 9 + normalized_distance * 3, paint);
816 auto callback = [&]() -> sk_sp<DisplayList> {
818 static bool cache_the_wheel =
true;
819 static int current_blend_index = 3;
820 static float dst_alpha = 1;
821 static float src_alpha = 1;
822 static DlColor color0 = DlColor::kRed();
823 static DlColor color1 = DlColor::kGreen();
824 static DlColor color2 = DlColor::kBlue();
827 ImGuiWindowFlags_AlwaysAutoResize)) {
828 ImGui::Checkbox(
"Cache the wheel", &cache_the_wheel);
829 ImGui::ListBox(
"Blending mode", ¤t_blend_index,
832 ImGui::SliderFloat(
"Source alpha", &src_alpha, 0, 1);
833 ImGui::ColorEdit4(
"Color A",
reinterpret_cast<float*
>(&color0));
834 ImGui::ColorEdit4(
"Color B",
reinterpret_cast<float*
>(&color1));
835 ImGui::ColorEdit4(
"Color C",
reinterpret_cast<float*
>(&color2));
836 ImGui::SliderFloat(
"Destination alpha", &dst_alpha, 0, 1);
840 DisplayListBuilder builder;
843 paint.setColor(DlColor::kWhite().withAlpha(dst_alpha * 255));
844 paint.setBlendMode(DlBlendMode::kSrc);
845 builder.SaveLayer(std::nullopt, &paint);
848 paint.setColor(DlColor::kWhite());
849 builder.DrawPaint(paint);
851 builder.SaveLayer(std::nullopt,
nullptr);
852 builder.Scale(GetContentScale().
x, GetContentScale().y);
853 builder.Translate(500, 400);
855 draw_color_wheel(builder);
860 builder.Scale(GetContentScale().
x, GetContentScale().y);
861 builder.Translate(500, 400);
866 save_paint.setColor(DlColor::kWhite().withAlpha(src_alpha * 255));
867 save_paint.setBlendMode(
static_cast<DlBlendMode
>(
869 builder.SaveLayer(std::nullopt, &save_paint);
872 paint.setBlendMode(DlBlendMode::kPlus);
875 paint.setColor(color0);
876 builder.DrawCircle(
DlPoint(-
x * 45, y * 45), 65, paint);
877 paint.setColor(color1);
878 builder.DrawCircle(
DlPoint(0, -45), 65, paint);
879 paint.setColor(color2);
880 builder.DrawCircle(
DlPoint(
x * 45, y * 45), 65, paint);
884 return builder.Build();
887 ASSERT_TRUE(OpenPlaygroundHere(callback));
891 DisplayListBuilder builder;
894 paint.setColor(DlColor::kBlue());
895 builder.DrawPaint(paint);
898 save_paint.setColorFilter(
899 DlColorFilter::MakeBlend(DlColor::kRed(), DlBlendMode::kSrc));
900 builder.SaveLayer(std::nullopt, &save_paint);
904 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
908 DisplayListBuilder builder;
910 builder.DrawPaint(DlPaint(DlColor::kWhite()));
913 save_paint.setOpacity(0.3);
914 save_paint.setColorFilter(DlColorFilter::MakeBlend(DlColor::kTransparent(),
915 DlBlendMode::kSaturation));
916 builder.SaveLayer(std::nullopt, &save_paint);
917 builder.DrawRect(DlRect::MakeXYWH(100, 100, 300, 300),
918 DlPaint(DlColor::kMaroon()));
919 builder.DrawRect(DlRect::MakeXYWH(200, 200, 300, 300),
920 DlPaint(DlColor::kBlue()));
924 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
928 DisplayListBuilder builder;
930 builder.DrawPaint(DlPaint(DlColor::kWhite()));
932 builder.ClipRect(DlRect::MakeLTRB(100, 100, 400, 300));
935 builder.DrawRect(DlRect::MakeLTRB(0, 0, 400, 300),
937 .setColor(DlColor::kRed())
938 .setBlendMode(DlBlendMode::kDifference));
940 builder.DrawRect(DlRect::MakeLTRB(0, 0, 100, 100),
941 DlPaint().setColor(DlColor::kBlue()));
944 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
#define BLEND_MODE_TUPLE(blend_mode)
#define BLEND_MODE_SRC_ALPHA_TEST(blend_mode)
#define BLEND_MODE_TEST(blend_mode)
static bool ImGuiBegin(const char *name, bool *p_open, ImGuiWindowFlags flags)
static sk_sp< DlImageImpeller > Make(std::shared_ptr< Texture > texture, OwningContext owning_context=OwningContext::kIO)
static constexpr BlendMode kLastAdvancedBlendMode
#define IMPELLER_FOR_EACH_BLEND_MODE(V)
TEST_P(AiksTest, DrawAtlasNoColor)
static sk_sp< DisplayList > BlendModeTest(Vector2 content_scale, BlendMode blend_mode, const sk_sp< DlImageImpeller > &src_image, const sk_sp< DlImageImpeller > &dst_image, Scalar src_alpha)
static BlendModeSelection GetBlendModeSelection()
uint32_t ToARGB() const
Convert to ARGB 32 bit color.
static constexpr Color LimeGreen()
static constexpr Color Black()
static constexpr Color CornflowerBlue()
static constexpr Color MediumTurquoise()
static constexpr Color White()
constexpr Color WithAlpha(Scalar new_alpha) const
static constexpr Color OrangeRed()
Color Blend(Color source, BlendMode blend_mode) const
Blends an unpremultiplied destination color into a given unpremultiplied source color to form a new u...
constexpr TRect< T > Expand(T left, T top, T right, T bottom) const
Returns a rectangle with expanded edges. Negative expansion results in shrinking.
constexpr static TRect MakeXYWH(Type x, Type y, Type width, Type height)
std::vector< BlendMode > blend_mode_values
std::vector< const char * > blend_mode_names