From 0a7db586a715ad313dbb2c27a754844568e77b12 Mon Sep 17 00:00:00 2001 From: Aaron Clarke Date: Fri, 29 Mar 2024 14:37:33 -0700 Subject: [PATCH 1/4] [Impeller] fixed alpha for advanced blend and added alpha blend goldens --- impeller/aiks/aiks_blend_unittests.cc | 46 ++++++++++++++++++++------- 1 file changed, 34 insertions(+), 12 deletions(-) diff --git a/impeller/aiks/aiks_blend_unittests.cc b/impeller/aiks/aiks_blend_unittests.cc index b94bd5be6e453..95faf3c1b922a 100644 --- a/impeller/aiks/aiks_blend_unittests.cc +++ b/impeller/aiks/aiks_blend_unittests.cc @@ -372,6 +372,15 @@ static Picture BlendModeTest(Vector2 content_scale, BlendMode blend_mode, const std::shared_ptr& src_image, const std::shared_ptr& dst_image) { + static Scalar src_alpha = 1.0; + static Scalar dst_alpha = 1.0; + if (AiksTest::ImGuiBegin("Controls", nullptr, + ImGuiWindowFlags_AlwaysAutoResize)) { + ImGui::SliderFloat("Source alpha", &src_alpha, 0, 1); + ImGui::SliderFloat("Destination alpha", &dst_alpha, 0, 1); + ImGui::End(); + } + Color destination_color = Color::CornflowerBlue().WithAlpha(0.75); auto source_colors = std::vector({Color::White().WithAlpha(0.75), Color::LimeGreen().WithAlpha(0.75), @@ -456,19 +465,29 @@ static Picture BlendModeTest(Vector2 content_scale, canvas.Save(); canvas.SaveLayer({.blend_mode = BlendMode::kSourceOver}); { - canvas.DrawImage(dst_image, {0, 0}, {.blend_mode = BlendMode::kSourceOver}); - canvas.DrawImage(src_image, {0, 0}, {.blend_mode = blend_mode}); + canvas.DrawImage(dst_image, {0, 0}, + { + .color = Color::White().WithAlpha(dst_alpha), + .blend_mode = BlendMode::kSourceOver, + }); + canvas.DrawImage(src_image, {0, 0}, + { + .color = Color::White().WithAlpha(src_alpha), + .blend_mode = blend_mode, + }); } canvas.Restore(); canvas.Restore(); // Rendered image source (right image). canvas.Save(); - canvas.SaveLayer({.blend_mode = BlendMode::kSourceOver}); + canvas.SaveLayer({.color = Color::White().WithAlpha(dst_alpha), + .blend_mode = BlendMode::kSourceOver}); { canvas.DrawImage(dst_image, {400, 0}, {.blend_mode = BlendMode::kSourceOver}); - canvas.SaveLayer({.blend_mode = blend_mode}); + canvas.SaveLayer({.color = Color::White().WithAlpha(src_alpha), + .blend_mode = blend_mode}); { canvas.DrawImage(src_image, {400, 0}, {.blend_mode = BlendMode::kSourceOver}); @@ -481,14 +500,17 @@ static Picture BlendModeTest(Vector2 content_scale, return canvas.EndRecordingAsPicture(); } -#define BLEND_MODE_TEST(blend_mode) \ - TEST_P(AiksTest, BlendMode##blend_mode) { \ - auto src_image = std::make_shared( \ - CreateTextureForFixture("blend_mode_src.png")); \ - auto dst_image = std::make_shared( \ - CreateTextureForFixture("blend_mode_dst.png")); \ - OpenPlaygroundHere(BlendModeTest( \ - GetContentScale(), BlendMode::k##blend_mode, src_image, dst_image)); \ +#define BLEND_MODE_TEST(blend_mode) \ + TEST_P(AiksTest, BlendMode##blend_mode) { \ + auto src_image = std::make_shared( \ + CreateTextureForFixture("blend_mode_src.png")); \ + auto dst_image = std::make_shared( \ + CreateTextureForFixture("blend_mode_dst.png")); \ + auto callback = [&](AiksContext& renderer) -> std::optional { \ + return BlendModeTest(GetContentScale(), BlendMode::k##blend_mode, \ + src_image, dst_image); \ + }; \ + OpenPlaygroundHere(callback); \ } IMPELLER_FOR_EACH_BLEND_MODE(BLEND_MODE_TEST) From cb0e0626f66ea378d45d8056a8be7cc7c00b3960 Mon Sep 17 00:00:00 2001 From: Aaron Clarke Date: Fri, 29 Mar 2024 14:44:59 -0700 Subject: [PATCH 2/4] added new tests --- impeller/aiks/aiks_blend_unittests.cc | 26 ++++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/impeller/aiks/aiks_blend_unittests.cc b/impeller/aiks/aiks_blend_unittests.cc index 95faf3c1b922a..396fb1ccb803f 100644 --- a/impeller/aiks/aiks_blend_unittests.cc +++ b/impeller/aiks/aiks_blend_unittests.cc @@ -371,13 +371,11 @@ TEST_P(AiksTest, ClearBlend) { static Picture BlendModeTest(Vector2 content_scale, BlendMode blend_mode, const std::shared_ptr& src_image, - const std::shared_ptr& dst_image) { - static Scalar src_alpha = 1.0; - static Scalar dst_alpha = 1.0; + const std::shared_ptr& dst_image, + Scalar src_alpha) { if (AiksTest::ImGuiBegin("Controls", nullptr, ImGuiWindowFlags_AlwaysAutoResize)) { ImGui::SliderFloat("Source alpha", &src_alpha, 0, 1); - ImGui::SliderFloat("Destination alpha", &dst_alpha, 0, 1); ImGui::End(); } @@ -467,7 +465,6 @@ static Picture BlendModeTest(Vector2 content_scale, { canvas.DrawImage(dst_image, {0, 0}, { - .color = Color::White().WithAlpha(dst_alpha), .blend_mode = BlendMode::kSourceOver, }); canvas.DrawImage(src_image, {0, 0}, @@ -481,8 +478,7 @@ static Picture BlendModeTest(Vector2 content_scale, // Rendered image source (right image). canvas.Save(); - canvas.SaveLayer({.color = Color::White().WithAlpha(dst_alpha), - .blend_mode = BlendMode::kSourceOver}); + canvas.SaveLayer({.blend_mode = BlendMode::kSourceOver}); { canvas.DrawImage(dst_image, {400, 0}, {.blend_mode = BlendMode::kSourceOver}); @@ -508,12 +504,26 @@ static Picture BlendModeTest(Vector2 content_scale, CreateTextureForFixture("blend_mode_dst.png")); \ auto callback = [&](AiksContext& renderer) -> std::optional { \ return BlendModeTest(GetContentScale(), BlendMode::k##blend_mode, \ - src_image, dst_image); \ + src_image, dst_image, /*src_alpha=*/1.0); \ }; \ OpenPlaygroundHere(callback); \ } IMPELLER_FOR_EACH_BLEND_MODE(BLEND_MODE_TEST) +#define BLEND_MODE_SRC_ALPHA_TEST(blend_mode) \ + TEST_P(AiksTest, BlendModeSrcAlpha##blend_mode) { \ + auto src_image = std::make_shared( \ + CreateTextureForFixture("blend_mode_src.png")); \ + auto dst_image = std::make_shared( \ + CreateTextureForFixture("blend_mode_dst.png")); \ + auto callback = [&](AiksContext& renderer) -> std::optional { \ + return BlendModeTest(GetContentScale(), BlendMode::k##blend_mode, \ + src_image, dst_image, /*src_alpha=*/0.5); \ + }; \ + OpenPlaygroundHere(callback); \ + } +IMPELLER_FOR_EACH_BLEND_MODE(BLEND_MODE_SRC_ALPHA_TEST) + TEST_P(AiksTest, CanDrawPaintMultipleTimesInteractive) { auto modes = GetBlendModeSelection(); From bf80066f65eb40341caac9de7de41cdd2bdc38a0 Mon Sep 17 00:00:00 2001 From: Aaron Clarke Date: Fri, 29 Mar 2024 14:46:31 -0700 Subject: [PATCH 3/4] added the fix --- impeller/entity/shaders/blending/framebuffer_blend.frag | 1 + 1 file changed, 1 insertion(+) diff --git a/impeller/entity/shaders/blending/framebuffer_blend.frag b/impeller/entity/shaders/blending/framebuffer_blend.frag index 1eba2de9a9b3a..af28df606fba7 100644 --- a/impeller/entity/shaders/blending/framebuffer_blend.frag +++ b/impeller/entity/shaders/blending/framebuffer_blend.frag @@ -51,6 +51,7 @@ void main() { int nblend_type = int(blend_type); if (nblend_type == /*BlendSelectValues::kPlusAdvanced*/ 14) { + premultiplied_src *= frag_info.src_input_alpha; frag_color = IPHalfPlusBlend(premultiplied_src, premultiplied_dst); } else { f16vec4 dst = IPHalfUnpremultiply(premultiplied_dst); From 48fb0c56cf50a59268bcbf8bfe8b05bca9861292 Mon Sep 17 00:00:00 2001 From: Aaron Clarke Date: Tue, 2 Apr 2024 13:25:09 -0700 Subject: [PATCH 4/4] golden --- testing/impeller_golden_tests_output.txt | 90 ++++++++++++++++++++++++ 1 file changed, 90 insertions(+) diff --git a/testing/impeller_golden_tests_output.txt b/testing/impeller_golden_tests_output.txt index 47b290d6c968b..aea657b901792 100644 --- a/testing/impeller_golden_tests_output.txt +++ b/testing/impeller_golden_tests_output.txt @@ -92,6 +92,96 @@ impeller_Play_AiksTest_BlendModeSourceOver_Vulkan.png impeller_Play_AiksTest_BlendModeSource_Metal.png impeller_Play_AiksTest_BlendModeSource_OpenGLES.png impeller_Play_AiksTest_BlendModeSource_Vulkan.png +impeller_Play_AiksTest_BlendModeSrcAlphaClear_Metal.png +impeller_Play_AiksTest_BlendModeSrcAlphaClear_OpenGLES.png +impeller_Play_AiksTest_BlendModeSrcAlphaClear_Vulkan.png +impeller_Play_AiksTest_BlendModeSrcAlphaColorBurn_Metal.png +impeller_Play_AiksTest_BlendModeSrcAlphaColorBurn_OpenGLES.png +impeller_Play_AiksTest_BlendModeSrcAlphaColorBurn_Vulkan.png +impeller_Play_AiksTest_BlendModeSrcAlphaColorDodge_Metal.png +impeller_Play_AiksTest_BlendModeSrcAlphaColorDodge_OpenGLES.png +impeller_Play_AiksTest_BlendModeSrcAlphaColorDodge_Vulkan.png +impeller_Play_AiksTest_BlendModeSrcAlphaColor_Metal.png +impeller_Play_AiksTest_BlendModeSrcAlphaColor_OpenGLES.png +impeller_Play_AiksTest_BlendModeSrcAlphaColor_Vulkan.png +impeller_Play_AiksTest_BlendModeSrcAlphaDarken_Metal.png +impeller_Play_AiksTest_BlendModeSrcAlphaDarken_OpenGLES.png +impeller_Play_AiksTest_BlendModeSrcAlphaDarken_Vulkan.png +impeller_Play_AiksTest_BlendModeSrcAlphaDestinationATop_Metal.png +impeller_Play_AiksTest_BlendModeSrcAlphaDestinationATop_OpenGLES.png +impeller_Play_AiksTest_BlendModeSrcAlphaDestinationATop_Vulkan.png +impeller_Play_AiksTest_BlendModeSrcAlphaDestinationIn_Metal.png +impeller_Play_AiksTest_BlendModeSrcAlphaDestinationIn_OpenGLES.png +impeller_Play_AiksTest_BlendModeSrcAlphaDestinationIn_Vulkan.png +impeller_Play_AiksTest_BlendModeSrcAlphaDestinationOut_Metal.png +impeller_Play_AiksTest_BlendModeSrcAlphaDestinationOut_OpenGLES.png +impeller_Play_AiksTest_BlendModeSrcAlphaDestinationOut_Vulkan.png +impeller_Play_AiksTest_BlendModeSrcAlphaDestinationOver_Metal.png +impeller_Play_AiksTest_BlendModeSrcAlphaDestinationOver_OpenGLES.png +impeller_Play_AiksTest_BlendModeSrcAlphaDestinationOver_Vulkan.png +impeller_Play_AiksTest_BlendModeSrcAlphaDestination_Metal.png +impeller_Play_AiksTest_BlendModeSrcAlphaDestination_OpenGLES.png +impeller_Play_AiksTest_BlendModeSrcAlphaDestination_Vulkan.png +impeller_Play_AiksTest_BlendModeSrcAlphaDifference_Metal.png +impeller_Play_AiksTest_BlendModeSrcAlphaDifference_OpenGLES.png +impeller_Play_AiksTest_BlendModeSrcAlphaDifference_Vulkan.png +impeller_Play_AiksTest_BlendModeSrcAlphaExclusion_Metal.png +impeller_Play_AiksTest_BlendModeSrcAlphaExclusion_OpenGLES.png +impeller_Play_AiksTest_BlendModeSrcAlphaExclusion_Vulkan.png +impeller_Play_AiksTest_BlendModeSrcAlphaHardLight_Metal.png +impeller_Play_AiksTest_BlendModeSrcAlphaHardLight_OpenGLES.png +impeller_Play_AiksTest_BlendModeSrcAlphaHardLight_Vulkan.png +impeller_Play_AiksTest_BlendModeSrcAlphaHue_Metal.png +impeller_Play_AiksTest_BlendModeSrcAlphaHue_OpenGLES.png +impeller_Play_AiksTest_BlendModeSrcAlphaHue_Vulkan.png +impeller_Play_AiksTest_BlendModeSrcAlphaLighten_Metal.png +impeller_Play_AiksTest_BlendModeSrcAlphaLighten_OpenGLES.png +impeller_Play_AiksTest_BlendModeSrcAlphaLighten_Vulkan.png +impeller_Play_AiksTest_BlendModeSrcAlphaLuminosity_Metal.png +impeller_Play_AiksTest_BlendModeSrcAlphaLuminosity_OpenGLES.png +impeller_Play_AiksTest_BlendModeSrcAlphaLuminosity_Vulkan.png +impeller_Play_AiksTest_BlendModeSrcAlphaModulate_Metal.png +impeller_Play_AiksTest_BlendModeSrcAlphaModulate_OpenGLES.png +impeller_Play_AiksTest_BlendModeSrcAlphaModulate_Vulkan.png +impeller_Play_AiksTest_BlendModeSrcAlphaMultiply_Metal.png +impeller_Play_AiksTest_BlendModeSrcAlphaMultiply_OpenGLES.png +impeller_Play_AiksTest_BlendModeSrcAlphaMultiply_Vulkan.png +impeller_Play_AiksTest_BlendModeSrcAlphaOverlay_Metal.png +impeller_Play_AiksTest_BlendModeSrcAlphaOverlay_OpenGLES.png +impeller_Play_AiksTest_BlendModeSrcAlphaOverlay_Vulkan.png +impeller_Play_AiksTest_BlendModeSrcAlphaPlusAdvanced_Metal.png +impeller_Play_AiksTest_BlendModeSrcAlphaPlusAdvanced_OpenGLES.png +impeller_Play_AiksTest_BlendModeSrcAlphaPlusAdvanced_Vulkan.png +impeller_Play_AiksTest_BlendModeSrcAlphaPlus_Metal.png +impeller_Play_AiksTest_BlendModeSrcAlphaPlus_OpenGLES.png +impeller_Play_AiksTest_BlendModeSrcAlphaPlus_Vulkan.png +impeller_Play_AiksTest_BlendModeSrcAlphaSaturation_Metal.png +impeller_Play_AiksTest_BlendModeSrcAlphaSaturation_OpenGLES.png +impeller_Play_AiksTest_BlendModeSrcAlphaSaturation_Vulkan.png +impeller_Play_AiksTest_BlendModeSrcAlphaScreen_Metal.png +impeller_Play_AiksTest_BlendModeSrcAlphaScreen_OpenGLES.png +impeller_Play_AiksTest_BlendModeSrcAlphaScreen_Vulkan.png +impeller_Play_AiksTest_BlendModeSrcAlphaSoftLight_Metal.png +impeller_Play_AiksTest_BlendModeSrcAlphaSoftLight_OpenGLES.png +impeller_Play_AiksTest_BlendModeSrcAlphaSoftLight_Vulkan.png +impeller_Play_AiksTest_BlendModeSrcAlphaSourceATop_Metal.png +impeller_Play_AiksTest_BlendModeSrcAlphaSourceATop_OpenGLES.png +impeller_Play_AiksTest_BlendModeSrcAlphaSourceATop_Vulkan.png +impeller_Play_AiksTest_BlendModeSrcAlphaSourceIn_Metal.png +impeller_Play_AiksTest_BlendModeSrcAlphaSourceIn_OpenGLES.png +impeller_Play_AiksTest_BlendModeSrcAlphaSourceIn_Vulkan.png +impeller_Play_AiksTest_BlendModeSrcAlphaSourceOut_Metal.png +impeller_Play_AiksTest_BlendModeSrcAlphaSourceOut_OpenGLES.png +impeller_Play_AiksTest_BlendModeSrcAlphaSourceOut_Vulkan.png +impeller_Play_AiksTest_BlendModeSrcAlphaSourceOver_Metal.png +impeller_Play_AiksTest_BlendModeSrcAlphaSourceOver_OpenGLES.png +impeller_Play_AiksTest_BlendModeSrcAlphaSourceOver_Vulkan.png +impeller_Play_AiksTest_BlendModeSrcAlphaSource_Metal.png +impeller_Play_AiksTest_BlendModeSrcAlphaSource_OpenGLES.png +impeller_Play_AiksTest_BlendModeSrcAlphaSource_Vulkan.png +impeller_Play_AiksTest_BlendModeSrcAlphaXor_Metal.png +impeller_Play_AiksTest_BlendModeSrcAlphaXor_OpenGLES.png +impeller_Play_AiksTest_BlendModeSrcAlphaXor_Vulkan.png impeller_Play_AiksTest_BlendModeXor_Metal.png impeller_Play_AiksTest_BlendModeXor_OpenGLES.png impeller_Play_AiksTest_BlendModeXor_Vulkan.png