diff --git a/impeller/aiks/aiks_blend_unittests.cc b/impeller/aiks/aiks_blend_unittests.cc index b94bd5be6e453..396fb1ccb803f 100644 --- a/impeller/aiks/aiks_blend_unittests.cc +++ b/impeller/aiks/aiks_blend_unittests.cc @@ -371,7 +371,14 @@ 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) { + 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::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,8 +463,15 @@ 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}, + { + .blend_mode = BlendMode::kSourceOver, + }); + canvas.DrawImage(src_image, {0, 0}, + { + .color = Color::White().WithAlpha(src_alpha), + .blend_mode = blend_mode, + }); } canvas.Restore(); canvas.Restore(); @@ -468,7 +482,8 @@ static Picture BlendModeTest(Vector2 content_scale, { 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,17 +496,34 @@ 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, /*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(); 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); 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