mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
[Impeller] Fix handling of destination opacity in advanced blends (flutter/engine#56251)
The framebuffer blend pipeline needs to support a dst_input_alpha parameter in order to implement the AbsorbOpacity flag. Also, dst_input_alpha should only be applied to the alpha channel of the unpremultiplied destination color. Fixes https://github.com/flutter/flutter/issues/157716
This commit is contained in:
parent
f81ed55e63
commit
09c811781d
@ -906,5 +906,25 @@ TEST_P(AiksTest, DestructiveBlendColorFilterFloodsClip) {
|
||||
ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
|
||||
}
|
||||
|
||||
TEST_P(AiksTest, AdvancedBlendColorFilterWithDestinationOpacity) {
|
||||
DisplayListBuilder builder;
|
||||
|
||||
builder.DrawPaint(DlPaint(DlColor::kWhite()));
|
||||
|
||||
DlPaint save_paint;
|
||||
save_paint.setOpacity(0.3);
|
||||
save_paint.setColorFilter(DlBlendColorFilter::Make(DlColor::kTransparent(),
|
||||
DlBlendMode::kSaturation));
|
||||
builder.SaveLayer(nullptr, &save_paint);
|
||||
builder.DrawRect(SkRect::MakeXYWH(100, 100, 300, 300),
|
||||
DlPaint(DlColor::kMaroon()));
|
||||
builder.DrawRect(SkRect::MakeXYWH(200, 200, 300, 300),
|
||||
DlPaint(DlColor::kBlue()));
|
||||
builder.Restore();
|
||||
|
||||
// Should be solid red as the destructive color filter floods the clip.
|
||||
ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
|
||||
}
|
||||
|
||||
} // namespace testing
|
||||
} // namespace impeller
|
||||
|
||||
@ -850,6 +850,10 @@ std::optional<Entity> BlendFilterContents::CreateFramebufferAdvancedBlend(
|
||||
VS::BindFrameInfo(pass, host_buffer.EmplaceUniform(frame_info));
|
||||
|
||||
frag_info.src_input_alpha = 1.0;
|
||||
frag_info.dst_input_alpha =
|
||||
absorb_opacity == ColorFilterContents::AbsorbOpacity::kYes
|
||||
? dst_snapshot->opacity
|
||||
: 1.0;
|
||||
FS::BindFragInfo(pass, host_buffer.EmplaceUniform(frag_info));
|
||||
|
||||
return pass.Draw().ok();
|
||||
|
||||
@ -139,6 +139,7 @@ bool FramebufferBlendContents::Render(const ContentContext& renderer,
|
||||
VS::BindFrameInfo(pass, host_buffer.EmplaceUniform(frame_info));
|
||||
|
||||
frag_info.src_input_alpha = src_snapshot->opacity;
|
||||
frag_info.dst_input_alpha = 1.0;
|
||||
FS::BindFragInfo(pass, host_buffer.EmplaceUniform(frag_info));
|
||||
|
||||
return pass.Draw().ok();
|
||||
|
||||
@ -40,7 +40,7 @@ void main() {
|
||||
IPHalfUnpremultiply(Sample(texture_sampler_dst, // sampler
|
||||
v_dst_texture_coords // texture coordinates
|
||||
));
|
||||
dst *= blend_info.dst_input_alpha;
|
||||
dst.a *= blend_info.dst_input_alpha;
|
||||
f16vec4 src = blend_info.color_factor > 0.0hf
|
||||
? blend_info.color
|
||||
: IPHalfUnpremultiply(Sample(
|
||||
|
||||
@ -28,6 +28,7 @@ uniform sampler2D texture_sampler_src;
|
||||
|
||||
uniform FragInfo {
|
||||
float16_t src_input_alpha;
|
||||
float16_t dst_input_alpha;
|
||||
}
|
||||
frag_info;
|
||||
|
||||
@ -44,6 +45,7 @@ vec4 Sample(sampler2D texture_sampler, vec2 texture_coords) {
|
||||
|
||||
void main() {
|
||||
f16vec4 dst = IPHalfUnpremultiply(f16vec4(ReadDestination()));
|
||||
dst.a *= frag_info.dst_input_alpha;
|
||||
f16vec4 src = IPHalfUnpremultiply(
|
||||
f16vec4(Sample(texture_sampler_src, // sampler
|
||||
v_src_texture_coords // texture coordinates
|
||||
|
||||
@ -20,8 +20,8 @@
|
||||
"arith_fma"
|
||||
],
|
||||
"longest_path_cycles": [
|
||||
0.578125,
|
||||
0.578125,
|
||||
0.53125,
|
||||
0.53125,
|
||||
0.21875,
|
||||
0.125,
|
||||
0.0,
|
||||
@ -42,8 +42,8 @@
|
||||
"arith_fma"
|
||||
],
|
||||
"shortest_path_cycles": [
|
||||
0.53125,
|
||||
0.53125,
|
||||
0.484375,
|
||||
0.484375,
|
||||
0.203125,
|
||||
0.0625,
|
||||
0.0,
|
||||
@ -55,8 +55,8 @@
|
||||
"arith_fma"
|
||||
],
|
||||
"total_cycles": [
|
||||
0.578125,
|
||||
0.578125,
|
||||
0.53125,
|
||||
0.53125,
|
||||
0.296875,
|
||||
0.125,
|
||||
0.0,
|
||||
@ -1114,8 +1114,8 @@
|
||||
"arith_fma"
|
||||
],
|
||||
"longest_path_cycles": [
|
||||
0.578125,
|
||||
0.578125,
|
||||
0.53125,
|
||||
0.53125,
|
||||
0.265625,
|
||||
0.125,
|
||||
0.0,
|
||||
@ -1136,8 +1136,8 @@
|
||||
"arith_fma"
|
||||
],
|
||||
"shortest_path_cycles": [
|
||||
0.53125,
|
||||
0.53125,
|
||||
0.484375,
|
||||
0.484375,
|
||||
0.21875,
|
||||
0.0625,
|
||||
0.0,
|
||||
@ -1149,8 +1149,8 @@
|
||||
"arith_fma"
|
||||
],
|
||||
"total_cycles": [
|
||||
0.578125,
|
||||
0.578125,
|
||||
0.53125,
|
||||
0.53125,
|
||||
0.34375,
|
||||
0.125,
|
||||
0.0,
|
||||
@ -1178,7 +1178,7 @@
|
||||
"arithmetic"
|
||||
],
|
||||
"longest_path_cycles": [
|
||||
4.289999961853027,
|
||||
3.9600000381469727,
|
||||
2.0,
|
||||
2.0
|
||||
],
|
||||
|
||||
@ -1,5 +1,8 @@
|
||||
digest.json
|
||||
impeller_GoldenTests_ConicalGradient.png
|
||||
impeller_Play_AiksTest_AdvancedBlendColorFilterWithDestinationOpacity_Metal.png
|
||||
impeller_Play_AiksTest_AdvancedBlendColorFilterWithDestinationOpacity_OpenGLES.png
|
||||
impeller_Play_AiksTest_AdvancedBlendColorFilterWithDestinationOpacity_Vulkan.png
|
||||
impeller_Play_AiksTest_BackdropRestoreUsesCorrectCoverageForFirstRestoredClip_Metal.png
|
||||
impeller_Play_AiksTest_BackdropRestoreUsesCorrectCoverageForFirstRestoredClip_OpenGLES.png
|
||||
impeller_Play_AiksTest_BackdropRestoreUsesCorrectCoverageForFirstRestoredClip_Vulkan.png
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user