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

Commit f794f94

Browse files
committed
SSBO, don't double-premultiply
1 parent cae105f commit f794f94

13 files changed

+120
-91
lines changed

impeller/aiks/aiks_unittests.cc

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -395,6 +395,30 @@ TEST_P(AiksTest, CanRenderLinearGradientDecal) {
395395
CanRenderLinearGradient(this, Entity::TileMode::kDecal);
396396
}
397397

398+
TEST_P(AiksTest, CanRenderLinearGradientDecalWithColorFilter) {
399+
Canvas canvas;
400+
canvas.Scale(GetContentScale());
401+
Paint paint;
402+
canvas.Translate({100.0f, 0, 0});
403+
404+
std::vector<Color> colors = {Color{0.9568, 0.2627, 0.2118, 1.0},
405+
Color{0.1294, 0.5882, 0.9529, 0.0}};
406+
std::vector<Scalar> stops = {0.0, 1.0};
407+
408+
paint.color_source = ColorSource::MakeLinearGradient(
409+
{0, 0}, {200, 200}, std::move(colors), std::move(stops),
410+
Entity::TileMode::kDecal, {});
411+
// Overlay the gradient with 50% green. This should appear as the entire
412+
// rectangle being drawn with 50% green, including the border area outside the
413+
// decal gradient.
414+
paint.color_filter = ColorFilter::MakeBlend(BlendMode::kSourceOver,
415+
Color::Green().WithAlpha(0.50));
416+
417+
paint.color = Color(1.0, 1.0, 1.0, 1.0);
418+
canvas.DrawRect({0, 0, 600, 600}, paint);
419+
ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
420+
}
421+
398422
namespace {
399423
void CanRenderLinearGradientWithOverlappingStops(AiksTest* aiks_test,
400424
Entity::TileMode tile_mode) {

impeller/entity/contents/conical_gradient_contents.cc

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ bool ConicalGradientContents::RenderSSBO(const ContentContext& renderer,
7070
frag_info.center = center_;
7171
frag_info.radius = radius_;
7272
frag_info.tile_mode = static_cast<Scalar>(tile_mode_);
73+
frag_info.decal_border_color = decal_border_color_;
7374
frag_info.alpha = GetOpacity();
7475
if (focus_) {
7576
frag_info.focus = focus_.value();
@@ -140,7 +141,7 @@ bool ConicalGradientContents::RenderTexture(const ContentContext& renderer,
140141
frag_info.center = center_;
141142
frag_info.radius = radius_;
142143
frag_info.tile_mode = static_cast<Scalar>(tile_mode_);
143-
frag_info.decal_border_color = decal_border_color_.Premultiply();
144+
frag_info.decal_border_color = decal_border_color_;
144145
frag_info.texture_sampler_y_coord_scale = gradient_texture->GetYCoordScale();
145146
frag_info.alpha = GetOpacity();
146147
frag_info.half_texel = Vector2(0.5 / gradient_texture->GetSize().width,

impeller/entity/contents/linear_gradient_contents.cc

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ bool LinearGradientContents::RenderTexture(const ContentContext& renderer,
8282
frag_info.start_point = start_point_;
8383
frag_info.end_point = end_point_;
8484
frag_info.tile_mode = static_cast<Scalar>(tile_mode_);
85-
frag_info.decal_border_color = decal_border_color_.Premultiply();
85+
frag_info.decal_border_color = decal_border_color_;
8686
frag_info.texture_sampler_y_coord_scale = gradient_texture->GetYCoordScale();
8787
frag_info.alpha = GetOpacity();
8888
frag_info.half_texel = Vector2(0.5 / gradient_texture->GetSize().width,
@@ -139,6 +139,7 @@ bool LinearGradientContents::RenderSSBO(const ContentContext& renderer,
139139
frag_info.start_point = start_point_;
140140
frag_info.end_point = end_point_;
141141
frag_info.tile_mode = static_cast<Scalar>(tile_mode_);
142+
frag_info.decal_border_color = decal_border_color_;
142143
frag_info.alpha = GetOpacity();
143144

144145
auto& host_buffer = pass.GetTransientsBuffer();

impeller/entity/contents/radial_gradient_contents.cc

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ bool RadialGradientContents::RenderSSBO(const ContentContext& renderer,
7676
frag_info.center = center_;
7777
frag_info.radius = radius_;
7878
frag_info.tile_mode = static_cast<Scalar>(tile_mode_);
79+
frag_info.decal_border_color = decal_border_color_;
7980
frag_info.alpha = GetOpacity();
8081

8182
auto& host_buffer = pass.GetTransientsBuffer();
@@ -139,7 +140,7 @@ bool RadialGradientContents::RenderTexture(const ContentContext& renderer,
139140
frag_info.center = center_;
140141
frag_info.radius = radius_;
141142
frag_info.tile_mode = static_cast<Scalar>(tile_mode_);
142-
frag_info.decal_border_color = decal_border_color_.Premultiply();
143+
frag_info.decal_border_color = decal_border_color_;
143144
frag_info.texture_sampler_y_coord_scale = gradient_texture->GetYCoordScale();
144145
frag_info.alpha = GetOpacity();
145146
frag_info.half_texel = Vector2(0.5 / gradient_texture->GetSize().width,

impeller/entity/contents/sweep_gradient_contents.cc

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ bool SweepGradientContents::RenderSSBO(const ContentContext& renderer,
8282
frag_info.bias = bias_;
8383
frag_info.scale = scale_;
8484
frag_info.tile_mode = static_cast<Scalar>(tile_mode_);
85+
frag_info.decal_border_color = decal_border_color_;
8586
frag_info.alpha = GetOpacity();
8687

8788
auto& host_buffer = pass.GetTransientsBuffer();
@@ -147,7 +148,7 @@ bool SweepGradientContents::RenderTexture(const ContentContext& renderer,
147148
frag_info.scale = scale_;
148149
frag_info.texture_sampler_y_coord_scale = gradient_texture->GetYCoordScale();
149150
frag_info.tile_mode = static_cast<Scalar>(tile_mode_);
150-
frag_info.decal_border_color = decal_border_color_.Premultiply();
151+
frag_info.decal_border_color = decal_border_color_;
151152
frag_info.alpha = GetOpacity();
152153
frag_info.half_texel = Vector2(0.5 / gradient_texture->GetSize().width,
153154
0.5 / gradient_texture->GetSize().height);

impeller/entity/shaders/conical_gradient_fill.frag

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
precision mediump float;
66

7+
#include <impeller/color.glsl>
78
#include <impeller/gradient.glsl>
89
#include <impeller/texture.glsl>
910
#include <impeller/types.glsl>
@@ -43,6 +44,5 @@ void main() {
4344
frag_info.half_texel, //
4445
frag_info.tile_mode, //
4546
frag_info.decal_border_color);
46-
frag_color =
47-
vec4(frag_color.xyz * frag_color.a, frag_color.a) * frag_info.alpha;
47+
frag_color = IPPremultiply(frag_color) * frag_info.alpha;
4848
}

impeller/entity/shaders/conical_gradient_ssbo_fill.frag

Lines changed: 21 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
precision mediump float;
66

7+
#include <impeller/color.glsl>
78
#include <impeller/gradient.glsl>
89
#include <impeller/texture.glsl>
910
#include <impeller/types.glsl>
@@ -22,6 +23,7 @@ uniform FragInfo {
2223
highp vec2 center;
2324
float radius;
2425
float tile_mode;
26+
vec4 decal_border_color;
2527
float alpha;
2628
int colors_length;
2729
vec2 focus;
@@ -36,33 +38,29 @@ out vec4 frag_color;
3638
void main() {
3739
vec2 res = IPComputeConicalT(frag_info.focus, frag_info.focus_radius,
3840
frag_info.center, frag_info.radius, v_position);
39-
if (res.y < 0.0) {
40-
frag_color = vec4(0);
41-
return;
42-
}
4341

4442
float t = res.x;
45-
if ((t < 0.0 || t > 1.0) && frag_info.tile_mode == kTileModeDecal) {
46-
frag_color = vec4(0);
47-
return;
48-
}
49-
t = IPFloatTile(t, frag_info.tile_mode);
43+
if (res.y < 0.0 ||
44+
((t < 0.0 || t > 1.0) && frag_info.tile_mode == kTileModeDecal)) {
45+
frag_color = frag_info.decal_border_color;
46+
} else {
47+
t = IPFloatTile(t, frag_info.tile_mode);
5048

51-
vec4 result_color = vec4(0);
52-
for (int i = 1; i < frag_info.colors_length; i++) {
53-
ColorPoint prev_point = color_data.colors[i - 1];
54-
ColorPoint current_point = color_data.colors[i];
55-
if (t >= prev_point.stop && t <= current_point.stop) {
56-
float delta = (current_point.stop - prev_point.stop);
57-
if (delta < 0.001) {
58-
result_color = current_point.color;
59-
} else {
60-
float ratio = (t - prev_point.stop) / delta;
61-
result_color = mix(prev_point.color, current_point.color, ratio);
49+
vec4 result_color = vec4(0);
50+
for (int i = 1; i < frag_info.colors_length; i++) {
51+
ColorPoint prev_point = color_data.colors[i - 1];
52+
ColorPoint current_point = color_data.colors[i];
53+
if (t >= prev_point.stop && t <= current_point.stop) {
54+
float delta = (current_point.stop - prev_point.stop);
55+
if (delta < 0.001) {
56+
result_color = current_point.color;
57+
} else {
58+
float ratio = (t - prev_point.stop) / delta;
59+
result_color = mix(prev_point.color, current_point.color, ratio);
60+
}
61+
break;
6262
}
63-
break;
6463
}
6564
}
66-
frag_color =
67-
vec4(result_color.xyz * result_color.a, result_color.a) * frag_info.alpha;
65+
frag_color = IPPremultiply(frag_color) * frag_info.alpha;
6866
}

impeller/entity/shaders/linear_gradient_fill.frag

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
precision mediump float;
66

7+
#include <impeller/color.glsl>
78
#include <impeller/texture.glsl>
89
#include <impeller/types.glsl>
910

@@ -36,6 +37,5 @@ void main() {
3637
frag_info.half_texel, //
3738
frag_info.tile_mode, //
3839
frag_info.decal_border_color);
39-
frag_color =
40-
vec4(frag_color.xyz * frag_color.a, frag_color.a) * frag_info.alpha;
40+
frag_color = IPPremultiply(frag_color) * frag_info.alpha;
4141
}

impeller/entity/shaders/linear_gradient_ssbo_fill.frag

Lines changed: 19 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
precision mediump float;
66

7+
#include <impeller/color.glsl>
78
#include <impeller/texture.glsl>
89
#include <impeller/types.glsl>
910

@@ -22,6 +23,7 @@ uniform FragInfo {
2223
highp vec2 end_point;
2324
float alpha;
2425
float tile_mode;
26+
vec4 decal_border_color;
2527
int colors_length;
2628
}
2729
frag_info;
@@ -37,25 +39,24 @@ void main() {
3739
dot(start_to_position, start_to_end) / dot(start_to_end, start_to_end);
3840

3941
if ((t < 0.0 || t > 1.0) && frag_info.tile_mode == kTileModeDecal) {
40-
frag_color = vec4(0);
41-
return;
42-
}
43-
t = IPFloatTile(t, frag_info.tile_mode);
44-
45-
for (int i = 1; i < frag_info.colors_length; i++) {
46-
ColorPoint prev_point = color_data.colors[i - 1];
47-
ColorPoint current_point = color_data.colors[i];
48-
if (t >= prev_point.stop && t <= current_point.stop) {
49-
float delta = (current_point.stop - prev_point.stop);
50-
if (delta < 0.001) {
51-
frag_color = current_point.color;
52-
} else {
53-
float ratio = (t - prev_point.stop) / delta;
54-
frag_color = mix(prev_point.color, current_point.color, ratio);
42+
frag_color = frag_info.decal_border_color;
43+
} else {
44+
t = IPFloatTile(t, frag_info.tile_mode);
45+
46+
for (int i = 1; i < frag_info.colors_length; i++) {
47+
ColorPoint prev_point = color_data.colors[i - 1];
48+
ColorPoint current_point = color_data.colors[i];
49+
if (t >= prev_point.stop && t <= current_point.stop) {
50+
float delta = (current_point.stop - prev_point.stop);
51+
if (delta < 0.001) {
52+
frag_color = current_point.color;
53+
} else {
54+
float ratio = (t - prev_point.stop) / delta;
55+
frag_color = mix(prev_point.color, current_point.color, ratio);
56+
}
57+
break;
5558
}
56-
break;
5759
}
5860
}
59-
frag_color =
60-
vec4(frag_color.xyz * frag_color.a, frag_color.a) * frag_info.alpha;
61+
frag_color = IPPremultiply(frag_color) * frag_info.alpha;
6162
}

impeller/entity/shaders/radial_gradient_fill.frag

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
precision mediump float;
66

7+
#include <impeller/color.glsl>
78
#include <impeller/texture.glsl>
89
#include <impeller/types.glsl>
910

@@ -34,6 +35,5 @@ void main() {
3435
frag_info.half_texel, //
3536
frag_info.tile_mode, //
3637
frag_info.decal_border_color);
37-
frag_color =
38-
vec4(frag_color.xyz * frag_color.a, frag_color.a) * frag_info.alpha;
38+
frag_color = IPPremultiply(frag_color) * frag_info.alpha;
3939
}

0 commit comments

Comments
 (0)