Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit ef60a95

Browse files
authored
[Impeller] fixes PlusAdvanced alpha blending / adds alpha blending tests (#51787)
#51756 had a bug in it when src alpha was not 1. There was no test coverage for this. I've added the fix and test coverage for all the blends. ## Pre-launch Checklist - [x] I read the [Contributor Guide] and followed the process outlined there for submitting PRs. - [x] I read the [Tree Hygiene] wiki page, which explains my responsibilities. - [x] I read and followed the [Flutter Style Guide] and the [C++, Objective-C, Java style guides]. - [ ] I listed at least one issue that this PR fixes in the description above. - [x] I added new tests to check the change I am making or feature I am adding, or the PR is [test-exempt]. See [testing the engine] for instructions on writing and running engine tests. - [x] I updated/added relevant documentation (doc comments with `///`). - [x] I signed the [CLA]. - [x] All existing and new tests are passing. If you need help, consider asking for advice on the #hackers-new channel on [Discord]. <!-- Links --> [Contributor Guide]: https://github.com/flutter/flutter/wiki/Tree-hygiene#overview [Tree Hygiene]: https://github.com/flutter/flutter/wiki/Tree-hygiene [test-exempt]: https://github.com/flutter/flutter/wiki/Tree-hygiene#tests [Flutter Style Guide]: https://github.com/flutter/flutter/wiki/Style-guide-for-Flutter-repo [C++, Objective-C, Java style guides]: https://github.com/flutter/engine/blob/main/CONTRIBUTING.md#style [testing the engine]: https://github.com/flutter/flutter/wiki/Testing-the-engine [CLA]: https://cla.developers.google.com/ [flutter/tests]: https://github.com/flutter/tests [breaking change policy]: https://github.com/flutter/flutter/wiki/Tree-hygiene#handling-breaking-changes [Discord]: https://github.com/flutter/flutter/wiki/Chat
1 parent bb4ec2d commit ef60a95

File tree

3 files changed

+135
-12
lines changed

3 files changed

+135
-12
lines changed

impeller/aiks/aiks_blend_unittests.cc

Lines changed: 44 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -371,7 +371,14 @@ TEST_P(AiksTest, ClearBlend) {
371371
static Picture BlendModeTest(Vector2 content_scale,
372372
BlendMode blend_mode,
373373
const std::shared_ptr<Image>& src_image,
374-
const std::shared_ptr<Image>& dst_image) {
374+
const std::shared_ptr<Image>& dst_image,
375+
Scalar src_alpha) {
376+
if (AiksTest::ImGuiBegin("Controls", nullptr,
377+
ImGuiWindowFlags_AlwaysAutoResize)) {
378+
ImGui::SliderFloat("Source alpha", &src_alpha, 0, 1);
379+
ImGui::End();
380+
}
381+
375382
Color destination_color = Color::CornflowerBlue().WithAlpha(0.75);
376383
auto source_colors = std::vector<Color>({Color::White().WithAlpha(0.75),
377384
Color::LimeGreen().WithAlpha(0.75),
@@ -456,8 +463,15 @@ static Picture BlendModeTest(Vector2 content_scale,
456463
canvas.Save();
457464
canvas.SaveLayer({.blend_mode = BlendMode::kSourceOver});
458465
{
459-
canvas.DrawImage(dst_image, {0, 0}, {.blend_mode = BlendMode::kSourceOver});
460-
canvas.DrawImage(src_image, {0, 0}, {.blend_mode = blend_mode});
466+
canvas.DrawImage(dst_image, {0, 0},
467+
{
468+
.blend_mode = BlendMode::kSourceOver,
469+
});
470+
canvas.DrawImage(src_image, {0, 0},
471+
{
472+
.color = Color::White().WithAlpha(src_alpha),
473+
.blend_mode = blend_mode,
474+
});
461475
}
462476
canvas.Restore();
463477
canvas.Restore();
@@ -468,7 +482,8 @@ static Picture BlendModeTest(Vector2 content_scale,
468482
{
469483
canvas.DrawImage(dst_image, {400, 0},
470484
{.blend_mode = BlendMode::kSourceOver});
471-
canvas.SaveLayer({.blend_mode = blend_mode});
485+
canvas.SaveLayer({.color = Color::White().WithAlpha(src_alpha),
486+
.blend_mode = blend_mode});
472487
{
473488
canvas.DrawImage(src_image, {400, 0},
474489
{.blend_mode = BlendMode::kSourceOver});
@@ -481,17 +496,34 @@ static Picture BlendModeTest(Vector2 content_scale,
481496
return canvas.EndRecordingAsPicture();
482497
}
483498

484-
#define BLEND_MODE_TEST(blend_mode) \
485-
TEST_P(AiksTest, BlendMode##blend_mode) { \
486-
auto src_image = std::make_shared<Image>( \
487-
CreateTextureForFixture("blend_mode_src.png")); \
488-
auto dst_image = std::make_shared<Image>( \
489-
CreateTextureForFixture("blend_mode_dst.png")); \
490-
OpenPlaygroundHere(BlendModeTest( \
491-
GetContentScale(), BlendMode::k##blend_mode, src_image, dst_image)); \
499+
#define BLEND_MODE_TEST(blend_mode) \
500+
TEST_P(AiksTest, BlendMode##blend_mode) { \
501+
auto src_image = std::make_shared<Image>( \
502+
CreateTextureForFixture("blend_mode_src.png")); \
503+
auto dst_image = std::make_shared<Image>( \
504+
CreateTextureForFixture("blend_mode_dst.png")); \
505+
auto callback = [&](AiksContext& renderer) -> std::optional<Picture> { \
506+
return BlendModeTest(GetContentScale(), BlendMode::k##blend_mode, \
507+
src_image, dst_image, /*src_alpha=*/1.0); \
508+
}; \
509+
OpenPlaygroundHere(callback); \
492510
}
493511
IMPELLER_FOR_EACH_BLEND_MODE(BLEND_MODE_TEST)
494512

513+
#define BLEND_MODE_SRC_ALPHA_TEST(blend_mode) \
514+
TEST_P(AiksTest, BlendModeSrcAlpha##blend_mode) { \
515+
auto src_image = std::make_shared<Image>( \
516+
CreateTextureForFixture("blend_mode_src.png")); \
517+
auto dst_image = std::make_shared<Image>( \
518+
CreateTextureForFixture("blend_mode_dst.png")); \
519+
auto callback = [&](AiksContext& renderer) -> std::optional<Picture> { \
520+
return BlendModeTest(GetContentScale(), BlendMode::k##blend_mode, \
521+
src_image, dst_image, /*src_alpha=*/0.5); \
522+
}; \
523+
OpenPlaygroundHere(callback); \
524+
}
525+
IMPELLER_FOR_EACH_BLEND_MODE(BLEND_MODE_SRC_ALPHA_TEST)
526+
495527
TEST_P(AiksTest, CanDrawPaintMultipleTimesInteractive) {
496528
auto modes = GetBlendModeSelection();
497529

impeller/entity/shaders/blending/framebuffer_blend.frag

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ void main() {
5151
int nblend_type = int(blend_type);
5252

5353
if (nblend_type == /*BlendSelectValues::kPlusAdvanced*/ 14) {
54+
premultiplied_src *= frag_info.src_input_alpha;
5455
frag_color = IPHalfPlusBlend(premultiplied_src, premultiplied_dst);
5556
} else {
5657
f16vec4 dst = IPHalfUnpremultiply(premultiplied_dst);

testing/impeller_golden_tests_output.txt

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,96 @@ impeller_Play_AiksTest_BlendModeSourceOver_Vulkan.png
9292
impeller_Play_AiksTest_BlendModeSource_Metal.png
9393
impeller_Play_AiksTest_BlendModeSource_OpenGLES.png
9494
impeller_Play_AiksTest_BlendModeSource_Vulkan.png
95+
impeller_Play_AiksTest_BlendModeSrcAlphaClear_Metal.png
96+
impeller_Play_AiksTest_BlendModeSrcAlphaClear_OpenGLES.png
97+
impeller_Play_AiksTest_BlendModeSrcAlphaClear_Vulkan.png
98+
impeller_Play_AiksTest_BlendModeSrcAlphaColorBurn_Metal.png
99+
impeller_Play_AiksTest_BlendModeSrcAlphaColorBurn_OpenGLES.png
100+
impeller_Play_AiksTest_BlendModeSrcAlphaColorBurn_Vulkan.png
101+
impeller_Play_AiksTest_BlendModeSrcAlphaColorDodge_Metal.png
102+
impeller_Play_AiksTest_BlendModeSrcAlphaColorDodge_OpenGLES.png
103+
impeller_Play_AiksTest_BlendModeSrcAlphaColorDodge_Vulkan.png
104+
impeller_Play_AiksTest_BlendModeSrcAlphaColor_Metal.png
105+
impeller_Play_AiksTest_BlendModeSrcAlphaColor_OpenGLES.png
106+
impeller_Play_AiksTest_BlendModeSrcAlphaColor_Vulkan.png
107+
impeller_Play_AiksTest_BlendModeSrcAlphaDarken_Metal.png
108+
impeller_Play_AiksTest_BlendModeSrcAlphaDarken_OpenGLES.png
109+
impeller_Play_AiksTest_BlendModeSrcAlphaDarken_Vulkan.png
110+
impeller_Play_AiksTest_BlendModeSrcAlphaDestinationATop_Metal.png
111+
impeller_Play_AiksTest_BlendModeSrcAlphaDestinationATop_OpenGLES.png
112+
impeller_Play_AiksTest_BlendModeSrcAlphaDestinationATop_Vulkan.png
113+
impeller_Play_AiksTest_BlendModeSrcAlphaDestinationIn_Metal.png
114+
impeller_Play_AiksTest_BlendModeSrcAlphaDestinationIn_OpenGLES.png
115+
impeller_Play_AiksTest_BlendModeSrcAlphaDestinationIn_Vulkan.png
116+
impeller_Play_AiksTest_BlendModeSrcAlphaDestinationOut_Metal.png
117+
impeller_Play_AiksTest_BlendModeSrcAlphaDestinationOut_OpenGLES.png
118+
impeller_Play_AiksTest_BlendModeSrcAlphaDestinationOut_Vulkan.png
119+
impeller_Play_AiksTest_BlendModeSrcAlphaDestinationOver_Metal.png
120+
impeller_Play_AiksTest_BlendModeSrcAlphaDestinationOver_OpenGLES.png
121+
impeller_Play_AiksTest_BlendModeSrcAlphaDestinationOver_Vulkan.png
122+
impeller_Play_AiksTest_BlendModeSrcAlphaDestination_Metal.png
123+
impeller_Play_AiksTest_BlendModeSrcAlphaDestination_OpenGLES.png
124+
impeller_Play_AiksTest_BlendModeSrcAlphaDestination_Vulkan.png
125+
impeller_Play_AiksTest_BlendModeSrcAlphaDifference_Metal.png
126+
impeller_Play_AiksTest_BlendModeSrcAlphaDifference_OpenGLES.png
127+
impeller_Play_AiksTest_BlendModeSrcAlphaDifference_Vulkan.png
128+
impeller_Play_AiksTest_BlendModeSrcAlphaExclusion_Metal.png
129+
impeller_Play_AiksTest_BlendModeSrcAlphaExclusion_OpenGLES.png
130+
impeller_Play_AiksTest_BlendModeSrcAlphaExclusion_Vulkan.png
131+
impeller_Play_AiksTest_BlendModeSrcAlphaHardLight_Metal.png
132+
impeller_Play_AiksTest_BlendModeSrcAlphaHardLight_OpenGLES.png
133+
impeller_Play_AiksTest_BlendModeSrcAlphaHardLight_Vulkan.png
134+
impeller_Play_AiksTest_BlendModeSrcAlphaHue_Metal.png
135+
impeller_Play_AiksTest_BlendModeSrcAlphaHue_OpenGLES.png
136+
impeller_Play_AiksTest_BlendModeSrcAlphaHue_Vulkan.png
137+
impeller_Play_AiksTest_BlendModeSrcAlphaLighten_Metal.png
138+
impeller_Play_AiksTest_BlendModeSrcAlphaLighten_OpenGLES.png
139+
impeller_Play_AiksTest_BlendModeSrcAlphaLighten_Vulkan.png
140+
impeller_Play_AiksTest_BlendModeSrcAlphaLuminosity_Metal.png
141+
impeller_Play_AiksTest_BlendModeSrcAlphaLuminosity_OpenGLES.png
142+
impeller_Play_AiksTest_BlendModeSrcAlphaLuminosity_Vulkan.png
143+
impeller_Play_AiksTest_BlendModeSrcAlphaModulate_Metal.png
144+
impeller_Play_AiksTest_BlendModeSrcAlphaModulate_OpenGLES.png
145+
impeller_Play_AiksTest_BlendModeSrcAlphaModulate_Vulkan.png
146+
impeller_Play_AiksTest_BlendModeSrcAlphaMultiply_Metal.png
147+
impeller_Play_AiksTest_BlendModeSrcAlphaMultiply_OpenGLES.png
148+
impeller_Play_AiksTest_BlendModeSrcAlphaMultiply_Vulkan.png
149+
impeller_Play_AiksTest_BlendModeSrcAlphaOverlay_Metal.png
150+
impeller_Play_AiksTest_BlendModeSrcAlphaOverlay_OpenGLES.png
151+
impeller_Play_AiksTest_BlendModeSrcAlphaOverlay_Vulkan.png
152+
impeller_Play_AiksTest_BlendModeSrcAlphaPlusAdvanced_Metal.png
153+
impeller_Play_AiksTest_BlendModeSrcAlphaPlusAdvanced_OpenGLES.png
154+
impeller_Play_AiksTest_BlendModeSrcAlphaPlusAdvanced_Vulkan.png
155+
impeller_Play_AiksTest_BlendModeSrcAlphaPlus_Metal.png
156+
impeller_Play_AiksTest_BlendModeSrcAlphaPlus_OpenGLES.png
157+
impeller_Play_AiksTest_BlendModeSrcAlphaPlus_Vulkan.png
158+
impeller_Play_AiksTest_BlendModeSrcAlphaSaturation_Metal.png
159+
impeller_Play_AiksTest_BlendModeSrcAlphaSaturation_OpenGLES.png
160+
impeller_Play_AiksTest_BlendModeSrcAlphaSaturation_Vulkan.png
161+
impeller_Play_AiksTest_BlendModeSrcAlphaScreen_Metal.png
162+
impeller_Play_AiksTest_BlendModeSrcAlphaScreen_OpenGLES.png
163+
impeller_Play_AiksTest_BlendModeSrcAlphaScreen_Vulkan.png
164+
impeller_Play_AiksTest_BlendModeSrcAlphaSoftLight_Metal.png
165+
impeller_Play_AiksTest_BlendModeSrcAlphaSoftLight_OpenGLES.png
166+
impeller_Play_AiksTest_BlendModeSrcAlphaSoftLight_Vulkan.png
167+
impeller_Play_AiksTest_BlendModeSrcAlphaSourceATop_Metal.png
168+
impeller_Play_AiksTest_BlendModeSrcAlphaSourceATop_OpenGLES.png
169+
impeller_Play_AiksTest_BlendModeSrcAlphaSourceATop_Vulkan.png
170+
impeller_Play_AiksTest_BlendModeSrcAlphaSourceIn_Metal.png
171+
impeller_Play_AiksTest_BlendModeSrcAlphaSourceIn_OpenGLES.png
172+
impeller_Play_AiksTest_BlendModeSrcAlphaSourceIn_Vulkan.png
173+
impeller_Play_AiksTest_BlendModeSrcAlphaSourceOut_Metal.png
174+
impeller_Play_AiksTest_BlendModeSrcAlphaSourceOut_OpenGLES.png
175+
impeller_Play_AiksTest_BlendModeSrcAlphaSourceOut_Vulkan.png
176+
impeller_Play_AiksTest_BlendModeSrcAlphaSourceOver_Metal.png
177+
impeller_Play_AiksTest_BlendModeSrcAlphaSourceOver_OpenGLES.png
178+
impeller_Play_AiksTest_BlendModeSrcAlphaSourceOver_Vulkan.png
179+
impeller_Play_AiksTest_BlendModeSrcAlphaSource_Metal.png
180+
impeller_Play_AiksTest_BlendModeSrcAlphaSource_OpenGLES.png
181+
impeller_Play_AiksTest_BlendModeSrcAlphaSource_Vulkan.png
182+
impeller_Play_AiksTest_BlendModeSrcAlphaXor_Metal.png
183+
impeller_Play_AiksTest_BlendModeSrcAlphaXor_OpenGLES.png
184+
impeller_Play_AiksTest_BlendModeSrcAlphaXor_Vulkan.png
95185
impeller_Play_AiksTest_BlendModeXor_Metal.png
96186
impeller_Play_AiksTest_BlendModeXor_OpenGLES.png
97187
impeller_Play_AiksTest_BlendModeXor_Vulkan.png

0 commit comments

Comments
 (0)