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));
403 if (!EnsureContextSupportsWideGamut()) {
404 GTEST_SKIP() <<
"This backend doesn't yet support wide gamut.";
407 EXPECT_EQ(GetContext()->GetCapabilities()->GetDefaultColorFormat(),
409 auto texture = CreateTextureForFixture(
"airplane.jpg",
412 DisplayListBuilder builder;
414 builder.Scale(GetContentScale().
x, GetContentScale().y);
416 paint.setColor(DlColor::RGBA(0.9, 1, 0.9, 1.0));
417 builder.DrawPaint(paint);
418 builder.SaveLayer(std::nullopt);
420 paint.setBlendMode(DlBlendMode::kPlus);
421 paint.setColor(DlColor::kRed());
423 builder.DrawRect(DlRect::MakeXYWH(100, 100, 400, 400), paint);
424 paint.setColor(DlColor::kWhite());
427 builder.DrawImageRect(
429 DlRect::MakeWH(texture->GetSize().width, texture->GetSize().height),
430 DlRect::MakeLTRB(rect.GetLeft(), rect.GetTop(),
431 rect.GetRight(), rect.GetBottom()),
432 DlImageSampling::kMipmapLinear, &paint);
434 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
441 if (!EnsureContextSupportsWideGamut()) {
442 GTEST_SKIP() <<
"This backend doesn't yet support wide gamut.";
445 EXPECT_EQ(GetContext()->GetCapabilities()->GetDefaultColorFormat(),
447 auto texture = CreateTextureForFixture(
"airplane.jpg",
450 DisplayListBuilder builder;
451 builder.Scale(GetContentScale().
x, GetContentScale().y);
454 paint.setColor(DlColor::RGBA(0.1, 0.2, 0.1, 1.0));
455 builder.DrawPaint(paint);
458 save_paint.setColorFilter(
459 DlColorFilter::MakeBlend(DlColor::RGBA(1, 0, 0, 1), DlBlendMode::kPlus));
460 builder.SaveLayer(std::nullopt, &save_paint);
462 paint.setColor(DlColor::kRed());
463 builder.DrawRect(DlRect::MakeXYWH(100, 100, 400, 400), paint);
465 paint.setColor(DlColor::kWhite());
468 builder.DrawImageRect(
470 DlRect::MakeWH(texture->GetSize().width, texture->GetSize().height),
471 DlRect::MakeLTRB(rect.GetLeft(), rect.GetTop(),
472 rect.GetRight(), rect.GetBottom()),
473 DlImageSampling::kMipmapLinear, &paint);
476 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
480 DisplayListBuilder builder;
483 save_paint.setColorFilter(
484 DlColorFilter::MakeBlend(DlColor::kRed(), DlBlendMode::kColorDodge));
485 builder.SaveLayer(std::nullopt, &save_paint);
487 builder.Translate(500, 300);
491 paint.setColor(DlColor::kBlue());
492 builder.DrawRect(DlRect::MakeXYWH(100, 100, 200, 200), paint);
494 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
498 DisplayListBuilder builder;
501 blue.setColor(DlColor::kBlue());
502 builder.DrawRect(DlRect::MakeXYWH(0, 0, 600.0, 600.0), blue);
505 clear.setBlendMode(DlBlendMode::kClear);
507 builder.DrawCircle(
DlPoint(300.0, 300.0), 200.0, clear);
509 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
514 const sk_sp<DlImageImpeller>& src_image,
515 const sk_sp<DlImageImpeller>& dst_image,
518 ImGuiWindowFlags_AlwaysAutoResize)) {
519 ImGui::SliderFloat(
"Source alpha", &src_alpha, 0, 1);
528 DisplayListBuilder builder;
531 paint.setColor(DlColor::kBlack());
532 builder.DrawPaint(paint);
543 for (
const auto& color : source_colors) {
546 builder.ClipRect(DlRect::MakeXYWH(25, 25, 100, 100));
550 builder.SaveLayer(std::nullopt);
554 DlColor::RGBA(destination_color.
red, destination_color.
green,
555 destination_color.
blue, destination_color.
alpha));
556 builder.DrawPaint(draw_paint);
561 save_paint.setBlendMode(
static_cast<DlBlendMode
>(blend_mode));
562 builder.SaveLayer(std::nullopt, &save_paint);
566 DlColor::RGBA(color.red, color.green, color.blue, color.alpha));
567 builder.DrawRect(DlRect::MakeXYWH(25, 25, 100, 100), paint);
574 builder.Translate(100, 0);
576 builder.RestoreToCount(0);
583 builder.Translate(0, 100);
586 builder.SaveLayer(std::nullopt);
587 for (
const auto& color : source_colors) {
590 auto dest = destination_color.
Blend(color, blend_mode);
591 paint.setColor(DlColor::RGBA(dest.red, dest.green, dest.blue, dest.alpha));
592 paint.setBlendMode(DlBlendMode::kSrcOver);
593 builder.DrawRect(DlRect::MakeXYWH(25, 25, 100, 100), paint);
594 builder.Translate(100, 0);
606 builder.Translate(0, 250);
611 paint.setColor(DlColor::RGBA(41 / 255.0, 41 / 255.0, 41 / 255.0, 1));
612 builder.DrawRect(DlRect::MakeLTRB(0, 0, 800, 400), paint);
615 DlPaint square_paint;
616 square_paint.setColor(DlColor::RGBA(15 / 255.0, 15 / 255.0, 15 / 255.0, 1));
617 for (
int y = 0; y < 400 / 8; y++) {
618 for (
int x = 0;
x < 800 / 16;
x++) {
619 builder.DrawRect(DlRect::MakeXYWH(
x * 16 + (y % 2) * 8, y * 8, 8, 8),
626 paint.setBlendMode(DlBlendMode::kSrcOver);
628 builder.SaveLayer(std::nullopt, &paint);
630 builder.DrawImage(dst_image,
DlPoint(0, 0), DlImageSampling::kMipmapLinear,
633 paint.setColor(DlColor::kWhite().withAlpha(src_alpha * 255));
634 paint.setBlendMode(
static_cast<DlBlendMode
>(blend_mode));
635 builder.DrawImage(src_image,
DlPoint(0, 0), DlImageSampling::kMipmapLinear,
645 builder.SaveLayer(std::nullopt, &save_paint);
647 builder.DrawImage(dst_image,
DlPoint(400, 0),
648 DlImageSampling::kMipmapLinear,
nullptr);
651 save_paint.setColor(DlColor::kWhite().withAlpha(src_alpha * 255));
652 save_paint.setBlendMode(
static_cast<DlBlendMode
>(blend_mode));
653 builder.SaveLayer(std::nullopt, &save_paint);
655 builder.DrawImage(src_image,
DlPoint(400, 0),
656 DlImageSampling::kMipmapLinear,
nullptr);
663 return builder.Build();
666 #define BLEND_MODE_TEST(blend_mode) \
667 TEST_P(AiksTest, BlendMode##blend_mode) { \
669 DlImageImpeller::Make(CreateTextureForFixture("blend_mode_src.png")); \
671 DlImageImpeller::Make(CreateTextureForFixture("blend_mode_dst.png")); \
672 auto callback = [&]() -> sk_sp<DisplayList> { \
673 return BlendModeTest(GetContentScale(), BlendMode::k##blend_mode, \
674 src_image, dst_image,
1.0); \
676 OpenPlaygroundHere(callback); \
680 #define BLEND_MODE_SRC_ALPHA_TEST(blend_mode) \
681 TEST_P(AiksTest, BlendModeSrcAlpha##blend_mode) { \
683 DlImageImpeller::Make(CreateTextureForFixture("blend_mode_src.png")); \
685 DlImageImpeller::Make(CreateTextureForFixture("blend_mode_dst.png")); \
686 auto callback = [&]() -> sk_sp<DisplayList> { \
687 return BlendModeTest(GetContentScale(), BlendMode::k##blend_mode, \
688 src_image, dst_image,
0.5); \
690 OpenPlaygroundHere(callback); \
697 auto callback = [&]() -> sk_sp<DisplayList> {
699 static Color foreground = Color::Color::OrangeRed().
WithAlpha(0.5);
700 static int current_blend_index = 3;
703 ImGuiWindowFlags_AlwaysAutoResize)) {
704 ImGui::ColorEdit4(
"Background",
reinterpret_cast<float*
>(&background));
705 ImGui::ColorEdit4(
"Foreground",
reinterpret_cast<float*
>(&foreground));
706 ImGui::ListBox(
"Blend mode", ¤t_blend_index,
707 modes.blend_mode_names.data(),
708 modes.blend_mode_names.size());
712 DisplayListBuilder builder;
713 builder.Scale(0.2, 0.2);
715 paint.setColor(DlColor(background.
ToARGB()));
716 builder.DrawPaint(paint);
718 paint.setColor(DlColor(foreground.
ToARGB()));
719 paint.setBlendMode(
static_cast<DlBlendMode
>(current_blend_index));
720 builder.DrawPaint(paint);
721 return builder.Build();
723 ASSERT_TRUE(OpenPlaygroundHere(callback));
727 auto texture = CreateTextureForFixture(
"airplane.jpg",
730 DisplayListBuilder builder;
734 image_paint.setColorFilter(DlColorFilter::MakeBlend(
735 DlColor::RGBA(255.0f / 255.0f, 165.0f / 255.0f, 0.0f / 255.0f, 1.0f),
736 DlBlendMode::kSrcIn));
739 DlImageSampling::kMipmapLinear, &image_paint);
741 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
745 auto texture = CreateTextureForFixture(
"airplane.jpg",
748 DisplayListBuilder builder;
752 image_paint.setColorFilter(DlColorFilter::MakeBlend(
753 DlColor::RGBA(255.0f / 255.0f, 165.0f / 255.0f, 0.0f / 255.0f, 1.0f),
754 DlBlendMode::kColorDodge));
757 DlImageSampling::kMipmapLinear, &image_paint);
759 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
763 auto texture = CreateTextureForFixture(
"airplane.jpg",
768 DisplayListBuilder builder;
772 DlColor::RGBA(169.0f / 255.0f, 169.0f / 255.0f, 169.0f / 255.0f, 1.0f));
773 builder.DrawPaint(paint);
774 builder.Scale(0.4, 0.4);
777 image_paint.setBlendMode(DlBlendMode::kMultiply);
780 DlImageSampling::kMipmapLinear, &image_paint);
782 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
790 auto draw_color_wheel = [](DisplayListBuilder& builder) ->
void {
793 auto color_wheel_sampler = [](
Radians r) {
797 auto color_cycle = [](
Scalar x) {
798 Scalar cycle = std::fmod(
x, 6.0f);
799 return std::max(0.0f, std::min(1.0f, 2 - std::abs(2 - cycle)));
801 return Color(color_cycle(6 *
x + 1),
802 color_cycle(6 *
x - 1),
803 color_cycle(6 *
x - 3),
808 paint.setBlendMode(DlBlendMode::kSrcOver);
812 const int max_dist = 900;
813 for (
int i = 0; i <= 900; i++) {
816 Scalar normalized_distance =
static_cast<Scalar>(i) / max_dist;
818 auto color = color_wheel_sampler(r).WithAlpha(1.0f - normalized_distance);
820 DlColor::RGBA(color.red, color.green, color.blue, color.alpha));
824 builder.DrawCircle(position, 9 + normalized_distance * 3, paint);
828 auto callback = [&]() -> sk_sp<DisplayList> {
830 static bool cache_the_wheel =
true;
831 static int current_blend_index = 3;
832 static float dst_alpha = 1;
833 static float src_alpha = 1;
834 static DlColor color0 = DlColor::kRed();
835 static DlColor color1 = DlColor::kGreen();
836 static DlColor color2 = DlColor::kBlue();
839 ImGuiWindowFlags_AlwaysAutoResize)) {
840 ImGui::Checkbox(
"Cache the wheel", &cache_the_wheel);
841 ImGui::ListBox(
"Blending mode", ¤t_blend_index,
844 ImGui::SliderFloat(
"Source alpha", &src_alpha, 0, 1);
845 ImGui::ColorEdit4(
"Color A",
reinterpret_cast<float*
>(&color0));
846 ImGui::ColorEdit4(
"Color B",
reinterpret_cast<float*
>(&color1));
847 ImGui::ColorEdit4(
"Color C",
reinterpret_cast<float*
>(&color2));
848 ImGui::SliderFloat(
"Destination alpha", &dst_alpha, 0, 1);
852 DisplayListBuilder builder;
855 paint.setColor(DlColor::kWhite().withAlpha(dst_alpha * 255));
856 paint.setBlendMode(DlBlendMode::kSrc);
857 builder.SaveLayer(std::nullopt, &paint);
860 paint.setColor(DlColor::kWhite());
861 builder.DrawPaint(paint);
863 builder.SaveLayer(std::nullopt,
nullptr);
864 builder.Scale(GetContentScale().
x, GetContentScale().y);
865 builder.Translate(500, 400);
867 draw_color_wheel(builder);
872 builder.Scale(GetContentScale().
x, GetContentScale().y);
873 builder.Translate(500, 400);
878 save_paint.setColor(DlColor::kWhite().withAlpha(src_alpha * 255));
879 save_paint.setBlendMode(
static_cast<DlBlendMode
>(
881 builder.SaveLayer(std::nullopt, &save_paint);
884 paint.setBlendMode(DlBlendMode::kPlus);
887 paint.setColor(color0);
888 builder.DrawCircle(
DlPoint(-
x * 45, y * 45), 65, paint);
889 paint.setColor(color1);
890 builder.DrawCircle(
DlPoint(0, -45), 65, paint);
891 paint.setColor(color2);
892 builder.DrawCircle(
DlPoint(
x * 45, y * 45), 65, paint);
896 return builder.Build();
899 ASSERT_TRUE(OpenPlaygroundHere(callback));
903 DisplayListBuilder builder;
906 paint.setColor(DlColor::kBlue());
907 builder.DrawPaint(paint);
910 save_paint.setColorFilter(
911 DlColorFilter::MakeBlend(DlColor::kRed(), DlBlendMode::kSrc));
912 builder.SaveLayer(std::nullopt, &save_paint);
916 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
920 DisplayListBuilder builder;
922 builder.DrawPaint(DlPaint(DlColor::kWhite()));
925 save_paint.setOpacity(0.3);
926 save_paint.setColorFilter(DlColorFilter::MakeBlend(DlColor::kTransparent(),
927 DlBlendMode::kSaturation));
928 builder.SaveLayer(std::nullopt, &save_paint);
929 builder.DrawRect(DlRect::MakeXYWH(100, 100, 300, 300),
930 DlPaint(DlColor::kMaroon()));
931 builder.DrawRect(DlRect::MakeXYWH(200, 200, 300, 300),
932 DlPaint(DlColor::kBlue()));
936 ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
940 DisplayListBuilder builder;
942 builder.DrawPaint(DlPaint(DlColor::kWhite()));
944 builder.ClipRect(DlRect::MakeLTRB(100, 100, 400, 300));
947 builder.DrawRect(DlRect::MakeLTRB(0, 0, 400, 300),
949 .setColor(DlColor::kRed())
950 .setBlendMode(DlBlendMode::kDifference));
952 builder.DrawRect(DlRect::MakeLTRB(0, 0, 100, 100),
953 DlPaint().setColor(DlColor::kBlue()));
956 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