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

Commit 34112d7

Browse files
committed
[Impeller] made plus an advanced blend
1 parent 4069da3 commit 34112d7

File tree

11 files changed

+96
-18
lines changed

11 files changed

+96
-18
lines changed

impeller/aiks/aiks_unittests.cc

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1121,6 +1121,42 @@ TEST_P(AiksTest, BlendModePlusAlpha) {
11211121
ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
11221122
}
11231123

1124+
// Bug: https://github.com/flutter/flutter/issues/142549
1125+
TEST_P(AiksTest, BlendModePlusAlphaHalf) {
1126+
Canvas canvas;
1127+
canvas.Scale(GetContentScale());
1128+
canvas.DrawPaint({.color = Color(0.9, 1.0, 0.9, 1.0)});
1129+
canvas.DrawRect(Rect::MakeXYWH(0, 0, 300, 300),
1130+
{.color = Color(1, 0, 0, 0.5)});
1131+
canvas.SaveLayer({});
1132+
Paint paint;
1133+
paint.blend_mode = BlendMode::kPlus;
1134+
paint.color = Color(0, 0, 1, 0.5);
1135+
canvas.DrawRect(Rect::MakeXYWH(0, 0, 150, 300), paint);
1136+
paint.color = Color(1, 0, 1, 1);
1137+
canvas.DrawRect(Rect::MakeXYWH(150, 0, 150, 300), paint);
1138+
canvas.Restore();
1139+
ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
1140+
}
1141+
1142+
TEST_P(AiksTest, BlendModePlusAlphaFoo) {
1143+
Canvas canvas;
1144+
canvas.Scale(GetContentScale());
1145+
canvas.DrawPaint({.color = Color(0.9, 1.0, 0.9, 1.0)});
1146+
canvas.DrawRect(Rect::MakeXYWH(0, 0, 300, 300), {.color = Color(1, 0, 0, 1)});
1147+
canvas.SaveLayer({});
1148+
Paint paint;
1149+
paint.blend_mode = BlendMode::kPlus;
1150+
paint.color = Color(0, 0, 1, 10.0 / 255.0);
1151+
for (int i = 0; i < 20; ++i) {
1152+
canvas.DrawRect(Rect::MakeXYWH(0, 0, 150, 300), paint);
1153+
}
1154+
paint.color = Color(0, 0, 1, 200.0 / 255.0);
1155+
canvas.DrawRect(Rect::MakeXYWH(150, 0, 150, 300), paint);
1156+
canvas.Restore();
1157+
ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
1158+
}
1159+
11241160
TEST_P(AiksTest, ColorWheel) {
11251161
// Compare with https://fiddle.skia.org/c/@BlendModes
11261162

impeller/entity/contents/content_context.cc

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -128,15 +128,6 @@ void ContentContextOptions::ApplyToPipelineDescriptor(
128128
color0.src_alpha_blend_factor = BlendFactor::kOneMinusDestinationAlpha;
129129
color0.src_color_blend_factor = BlendFactor::kOneMinusDestinationAlpha;
130130
break;
131-
case BlendMode::kPlus:
132-
color0.dst_alpha_blend_factor =
133-
IsAlphaClampedToOne(color_attachment_pixel_format)
134-
? BlendFactor::kOne
135-
: BlendFactor::kOneMinusSourceAlpha;
136-
color0.dst_color_blend_factor = BlendFactor::kOne;
137-
color0.src_alpha_blend_factor = BlendFactor::kOne;
138-
color0.src_color_blend_factor = BlendFactor::kOne;
139-
break;
140131
case BlendMode::kModulate:
141132
color0.dst_alpha_blend_factor = BlendFactor::kSourceAlpha;
142133
color0.dst_color_blend_factor = BlendFactor::kSourceColor;
@@ -332,6 +323,9 @@ ContentContext::ContentContext(
332323
framebuffer_blend_lighten_pipelines_.CreateDefault(
333324
*context_, options_trianglestrip,
334325
{static_cast<Scalar>(BlendSelectValues::kLighten), supports_decal});
326+
framebuffer_blend_plus_pipelines_.CreateDefault(
327+
*context_, options_trianglestrip,
328+
{static_cast<Scalar>(BlendSelectValues::kPlus), supports_decal});
335329
framebuffer_blend_luminosity_pipelines_.CreateDefault(
336330
*context_, options_trianglestrip,
337331
{static_cast<Scalar>(BlendSelectValues::kLuminosity), supports_decal});
@@ -379,6 +373,9 @@ ContentContext::ContentContext(
379373
blend_lighten_pipelines_.CreateDefault(
380374
*context_, options_trianglestrip,
381375
{static_cast<Scalar>(BlendSelectValues::kLighten), supports_decal});
376+
blend_plus_pipelines_.CreateDefault(
377+
*context_, options_trianglestrip,
378+
{static_cast<Scalar>(BlendSelectValues::kPlus), supports_decal});
382379
blend_luminosity_pipelines_.CreateDefault(
383380
*context_, options_trianglestrip,
384381
{static_cast<Scalar>(BlendSelectValues::kLuminosity), supports_decal});

impeller/entity/contents/content_context.h

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,8 @@ using BlendHuePipeline =
197197
RenderPipelineT<AdvancedBlendVertexShader, AdvancedBlendFragmentShader>;
198198
using BlendLightenPipeline =
199199
RenderPipelineT<AdvancedBlendVertexShader, AdvancedBlendFragmentShader>;
200+
using BlendPlusPipeline =
201+
RenderPipelineT<AdvancedBlendVertexShader, AdvancedBlendFragmentShader>;
200202
using BlendLuminosityPipeline =
201203
RenderPipelineT<AdvancedBlendVertexShader, AdvancedBlendFragmentShader>;
202204
using BlendMultiplyPipeline =
@@ -237,6 +239,9 @@ using FramebufferBlendHuePipeline =
237239
using FramebufferBlendLightenPipeline =
238240
RenderPipelineT<FramebufferBlendVertexShader,
239241
FramebufferBlendFragmentShader>;
242+
using FramebufferBlendPlusPipeline =
243+
RenderPipelineT<FramebufferBlendVertexShader,
244+
FramebufferBlendFragmentShader>;
240245
using FramebufferBlendLuminosityPipeline =
241246
RenderPipelineT<FramebufferBlendVertexShader,
242247
FramebufferBlendFragmentShader>;
@@ -640,6 +645,11 @@ class ContentContext {
640645
return GetPipeline(blend_lighten_pipelines_, opts);
641646
}
642647

648+
std::shared_ptr<Pipeline<PipelineDescriptor>> GetBlendPlusPipeline(
649+
ContentContextOptions opts) const {
650+
return GetPipeline(blend_plus_pipelines_, opts);
651+
}
652+
643653
std::shared_ptr<Pipeline<PipelineDescriptor>> GetBlendLuminosityPipeline(
644654
ContentContextOptions opts) const {
645655
return GetPipeline(blend_luminosity_pipelines_, opts);
@@ -725,6 +735,12 @@ class ContentContext {
725735
return GetPipeline(framebuffer_blend_lighten_pipelines_, opts);
726736
}
727737

738+
std::shared_ptr<Pipeline<PipelineDescriptor>> GetFramebufferBlendPlusPipeline(
739+
ContentContextOptions opts) const {
740+
FML_DCHECK(GetDeviceCapabilities().SupportsFramebufferFetch());
741+
return GetPipeline(framebuffer_blend_plus_pipelines_, opts);
742+
}
743+
728744
std::shared_ptr<Pipeline<PipelineDescriptor>>
729745
GetFramebufferBlendLuminosityPipeline(ContentContextOptions opts) const {
730746
FML_DCHECK(GetDeviceCapabilities().SupportsFramebufferFetch());
@@ -993,6 +1009,7 @@ class ContentContext {
9931009
mutable Variants<BlendHardLightPipeline> blend_hardlight_pipelines_;
9941010
mutable Variants<BlendHuePipeline> blend_hue_pipelines_;
9951011
mutable Variants<BlendLightenPipeline> blend_lighten_pipelines_;
1012+
mutable Variants<BlendPlusPipeline> blend_plus_pipelines_;
9961013
mutable Variants<BlendLuminosityPipeline> blend_luminosity_pipelines_;
9971014
mutable Variants<BlendMultiplyPipeline> blend_multiply_pipelines_;
9981015
mutable Variants<BlendOverlayPipeline> blend_overlay_pipelines_;
@@ -1018,6 +1035,8 @@ class ContentContext {
10181035
framebuffer_blend_hue_pipelines_;
10191036
mutable Variants<FramebufferBlendLightenPipeline>
10201037
framebuffer_blend_lighten_pipelines_;
1038+
mutable Variants<FramebufferBlendPlusPipeline>
1039+
framebuffer_blend_plus_pipelines_;
10211040
mutable Variants<FramebufferBlendLuminosityPipeline>
10221041
framebuffer_blend_luminosity_pipelines_;
10231042
mutable Variants<FramebufferBlendMultiplyPipeline>

impeller/entity/contents/filters/blend_filter_contents.cc

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -338,6 +338,9 @@ std::optional<Entity> BlendFilterContents::CreateForegroundAdvancedBlend(
338338
case BlendMode::kColor:
339339
pass.SetPipeline(renderer.GetBlendColorPipeline(options));
340340
break;
341+
case BlendMode::kPlus:
342+
pass.SetPipeline(renderer.GetBlendPlusPipeline(options));
343+
break;
341344
case BlendMode::kLuminosity:
342345
pass.SetPipeline(renderer.GetBlendLuminosityPipeline(options));
343346
break;

impeller/entity/contents/filters/blend_filter_contents.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212

1313
namespace impeller {
1414

15-
constexpr std::array<std::array<Scalar, 5>, 15> kPorterDuffCoefficients = {{
15+
constexpr std::array<std::array<Scalar, 5>, 14> kPorterDuffCoefficients = {{
1616
{0, 0, 0, 0, 0}, // Clear
1717
{1, 0, 0, 0, 0}, // Source
1818
{0, 0, 1, 0, 0}, // Destination
@@ -25,7 +25,6 @@ constexpr std::array<std::array<Scalar, 5>, 15> kPorterDuffCoefficients = {{
2525
{0, 1, 1, -1, 0}, // SourceATop
2626
{1, -1, 0, 1, 0}, // DestinationATop
2727
{1, -1, 1, -1, 0}, // Xor
28-
{1, 0, 1, 0, 0}, // Plus
2928
{0, 0, 0, 0, 1}, // Modulate
3029
{0, 0, 1, 0, -1}, // Screen
3130
}};

impeller/entity/contents/framebuffer_blend_contents.cc

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,9 @@ bool FramebufferBlendContents::Render(const ContentContext& renderer,
118118
case BlendMode::kColor:
119119
pass.SetPipeline(renderer.GetFramebufferBlendColorPipeline(options));
120120
break;
121+
case BlendMode::kPlus:
122+
pass.SetPipeline(renderer.GetFramebufferBlendPlusPipeline(options));
123+
break;
121124
case BlendMode::kLuminosity:
122125
pass.SetPipeline(renderer.GetFramebufferBlendLuminosityPipeline(options));
123126
break;

impeller/entity/contents/framebuffer_blend_contents.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ enum class BlendSelectValues {
2727
kHue,
2828
kSaturation,
2929
kColor,
30+
kPlus,
3031
kLuminosity,
3132
};
3233

impeller/entity/shaders/blending/advanced_blend.frag

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,16 @@ void main() {
5151
src.a *= blend_info.src_input_alpha;
5252
}
5353

54-
f16vec3 blend_result = AdvancedBlend(dst.rgb, src.rgb, int(blend_type));
54+
int nblend_type = int(blend_type);
5555

56-
frag_color = IPApplyBlendedColor(dst, src, blend_result);
56+
if (nblend_type == /*BlendSelectValues::kPlus*/ 14) {
57+
f16vec4 plus = src + dst;
58+
if (plus.a > 1.0hf) {
59+
plus.a = 1.0hf;
60+
}
61+
frag_color = IPHalfPremultiply(plus);
62+
} else {
63+
f16vec3 blend_result = AdvancedBlend(dst.rgb, src.rgb, nblend_type);
64+
frag_color = IPApplyBlendedColor(dst, src, blend_result);
65+
}
5766
}

impeller/entity/shaders/blending/blend_select.glsl

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
// kHue,
2121
// kSaturation,
2222
// kColor,
23+
// kPlus,
2324
// kLuminosity,
2425
// Note, this isn't a switch as GLSL ES 1.0 does not support them.
2526
f16vec3 AdvancedBlend(f16vec3 dst, f16vec3 src, int blend_type) {
@@ -65,7 +66,8 @@ f16vec3 AdvancedBlend(f16vec3 dst, f16vec3 src, int blend_type) {
6566
if (blend_type == 13) {
6667
return IPBlendColor(dst, src);
6768
}
68-
if (blend_type == 14) {
69+
// 14 is `plus`, it's handled in advanced_blend.frag.
70+
if (blend_type == 15) {
6971
return IPBlendLuminosity(dst, src);
7072
}
7173
return f16vec3(0.0hf);

impeller/entity/shaders/blending/framebuffer_blend.frag

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,16 @@ void main() {
5050
)));
5151
src.a *= frag_info.src_input_alpha;
5252

53-
f16vec3 blend_result = AdvancedBlend(dst.rgb, src.rgb, int(blend_type));
53+
int nblend_type = int(blend_type);
5454

55-
frag_color = IPApplyBlendedColor(dst, src, blend_result);
55+
if (nblend_type == /*BlendSelectValues::kPlus*/ 14) {
56+
f16vec4 plus = src + dst;
57+
if (plus.a > 1.0hf) {
58+
plus.a = 1.0hf;
59+
}
60+
frag_color = IPHalfPremultiply(plus);
61+
} else {
62+
f16vec3 blend_result = AdvancedBlend(dst.rgb, src.rgb, nblend_type);
63+
frag_color = IPApplyBlendedColor(dst, src, blend_result);
64+
}
5665
}

0 commit comments

Comments
 (0)