Split up the conical gradient fragment shader (#164058)

fixes: https://github.com/flutter/flutter/issues/163580

testing: There are existing tests (AiksTest.CanRenderConicalGradient).
The compilation failure of the nexus 5 cannot be reproduced locally so
we can't assert this fixes the problem in a test.

## 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], including [Features
we expect every widget to implement].
- [x] I signed the [CLA].
- [x] I listed at least one issue that this PR fixes in the description
above.
- [x] I updated/added relevant documentation (doc comments with `///`).
- [ ] I added new tests to check the change I am making, or this PR is
[test-exempt].
- [x] I followed the [breaking change policy] and added [Data Driven
Fixes] where supported.
- [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/blob/main/docs/contributing/Tree-hygiene.md#overview
[Tree Hygiene]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md
[test-exempt]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#tests
[Flutter Style Guide]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md
[Features we expect every widget to implement]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md#features-we-expect-every-widget-to-implement
[CLA]: https://cla.developers.google.com/
[flutter/tests]: https://github.com/flutter/tests
[breaking change policy]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#handling-breaking-changes
[Discord]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Chat.md
[Data Driven Fixes]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Data-driven-Fixes.md
This commit is contained in:
gaaclarke
2025-02-27 15:30:53 -08:00
committed by GitHub
parent 244c61133c
commit bffe0ffc50
20 changed files with 1700 additions and 235 deletions

View File

@@ -41648,6 +41648,8 @@ ORIGIN: ../../../flutter/impeller/compiler/shader_lib/flutter/runtime_effect.gls
ORIGIN: ../../../flutter/impeller/compiler/shader_lib/impeller/blending.glsl + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/impeller/compiler/shader_lib/impeller/branching.glsl + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/impeller/compiler/shader_lib/impeller/color.glsl + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/impeller/compiler/shader_lib/impeller/conical_gradient_fill.glsl + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/impeller/compiler/shader_lib/impeller/conical_gradient_uniform_fill.glsl + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/impeller/compiler/shader_lib/impeller/constants.glsl + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/impeller/compiler/shader_lib/impeller/conversions.glsl + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/impeller/compiler/shader_lib/impeller/dithering.glsl + ../../../flutter/LICENSE
@@ -41874,9 +41876,15 @@ ORIGIN: ../../../flutter/impeller/entity/shaders/filters/srgb_to_linear_filter.f
ORIGIN: ../../../flutter/impeller/entity/shaders/filters/yuv_to_rgb_filter.frag + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/impeller/entity/shaders/glyph_atlas.frag + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/impeller/entity/shaders/glyph_atlas.vert + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/impeller/entity/shaders/gradients/conical_gradient_fill.frag + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/impeller/entity/shaders/gradients/conical_gradient_fill_conical.frag + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/impeller/entity/shaders/gradients/conical_gradient_fill_radial.frag + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/impeller/entity/shaders/gradients/conical_gradient_fill_strip.frag + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/impeller/entity/shaders/gradients/conical_gradient_fill_strip_radial.frag + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/impeller/entity/shaders/gradients/conical_gradient_ssbo_fill.frag + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/impeller/entity/shaders/gradients/conical_gradient_uniform_fill.frag + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/impeller/entity/shaders/gradients/conical_gradient_uniform_fill_conical.frag + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/impeller/entity/shaders/gradients/conical_gradient_uniform_fill_radial.frag + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/impeller/entity/shaders/gradients/conical_gradient_uniform_fill_strip.frag + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/impeller/entity/shaders/gradients/conical_gradient_uniform_fill_strip_radial.frag + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/impeller/entity/shaders/gradients/fast_gradient.frag + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/impeller/entity/shaders/gradients/fast_gradient.vert + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/impeller/entity/shaders/gradients/gradient_fill.vert + ../../../flutter/LICENSE
@@ -44567,6 +44575,8 @@ FILE: ../../../flutter/impeller/compiler/shader_lib/flutter/runtime_effect.glsl
FILE: ../../../flutter/impeller/compiler/shader_lib/impeller/blending.glsl
FILE: ../../../flutter/impeller/compiler/shader_lib/impeller/branching.glsl
FILE: ../../../flutter/impeller/compiler/shader_lib/impeller/color.glsl
FILE: ../../../flutter/impeller/compiler/shader_lib/impeller/conical_gradient_fill.glsl
FILE: ../../../flutter/impeller/compiler/shader_lib/impeller/conical_gradient_uniform_fill.glsl
FILE: ../../../flutter/impeller/compiler/shader_lib/impeller/constants.glsl
FILE: ../../../flutter/impeller/compiler/shader_lib/impeller/conversions.glsl
FILE: ../../../flutter/impeller/compiler/shader_lib/impeller/dithering.glsl
@@ -44793,9 +44803,15 @@ FILE: ../../../flutter/impeller/entity/shaders/filters/srgb_to_linear_filter.fra
FILE: ../../../flutter/impeller/entity/shaders/filters/yuv_to_rgb_filter.frag
FILE: ../../../flutter/impeller/entity/shaders/glyph_atlas.frag
FILE: ../../../flutter/impeller/entity/shaders/glyph_atlas.vert
FILE: ../../../flutter/impeller/entity/shaders/gradients/conical_gradient_fill.frag
FILE: ../../../flutter/impeller/entity/shaders/gradients/conical_gradient_fill_conical.frag
FILE: ../../../flutter/impeller/entity/shaders/gradients/conical_gradient_fill_radial.frag
FILE: ../../../flutter/impeller/entity/shaders/gradients/conical_gradient_fill_strip.frag
FILE: ../../../flutter/impeller/entity/shaders/gradients/conical_gradient_fill_strip_radial.frag
FILE: ../../../flutter/impeller/entity/shaders/gradients/conical_gradient_ssbo_fill.frag
FILE: ../../../flutter/impeller/entity/shaders/gradients/conical_gradient_uniform_fill.frag
FILE: ../../../flutter/impeller/entity/shaders/gradients/conical_gradient_uniform_fill_conical.frag
FILE: ../../../flutter/impeller/entity/shaders/gradients/conical_gradient_uniform_fill_radial.frag
FILE: ../../../flutter/impeller/entity/shaders/gradients/conical_gradient_uniform_fill_strip.frag
FILE: ../../../flutter/impeller/entity/shaders/gradients/conical_gradient_uniform_fill_strip_radial.frag
FILE: ../../../flutter/impeller/entity/shaders/gradients/fast_gradient.frag
FILE: ../../../flutter/impeller/entity/shaders/gradients/fast_gradient.vert
FILE: ../../../flutter/impeller/entity/shaders/gradients/gradient_fill.vert

View File

@@ -7,6 +7,7 @@ copy("impeller") {
"blending.glsl",
"branching.glsl",
"color.glsl",
"conical_gradient_uniform_fill.glsl",
"constants.glsl",
"conversions.glsl",
"dithering.glsl",

View File

@@ -2,12 +2,10 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
precision highp float;
#ifndef CONICAL_GRADIENT_UNIFORM_FILL_GLSL_
#define CONICAL_GRADIENT_UNIFORM_FILL_GLSL_
#include <impeller/color.glsl>
#include <impeller/gradient.glsl>
#include <impeller/texture.glsl>
#include <impeller/types.glsl>
uniform sampler2D texture_sampler;
@@ -24,25 +22,21 @@ uniform FragInfo {
}
frag_info;
highp in vec2 v_position;
out vec4 frag_color;
void main() {
vec2 res = IPComputeConicalT(frag_info.focus, frag_info.focus_radius,
frag_info.center, frag_info.radius, v_position);
vec4 DoConicalGradientTextureFill(vec2 res) {
if (res.y < 0.0) {
frag_color = vec4(0);
return;
return vec4(0);
}
float t = res.x;
frag_color =
vec4 result =
IPSampleLinearWithTileMode(texture_sampler, //
vec2(t, 0.5), //
frag_info.texture_sampler_y_coord_scale, //
frag_info.half_texel, //
frag_info.tile_mode, //
frag_info.decal_border_color);
frag_color = IPPremultiply(frag_color) * frag_info.alpha;
result = IPPremultiply(result) * frag_info.alpha;
return result;
}
#endif // CONICAL_GRADIENT_UNIFORM_FILL_GLSL_

View File

@@ -2,13 +2,12 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CONICAL_GRADIENT_UNIFORM_FILL_GLSL_
#define CONICAL_GRADIENT_UNIFORM_FILL_GLSL_
precision highp float;
#include <impeller/color.glsl>
#include <impeller/dithering.glsl>
#include <impeller/gradient.glsl>
#include <impeller/texture.glsl>
#include <impeller/types.glsl>
uniform FragInfo {
highp vec2 center;
@@ -24,14 +23,7 @@ uniform FragInfo {
}
frag_info;
highp in vec2 v_position;
out vec4 frag_color;
void main() {
vec2 res = IPComputeConicalT(frag_info.focus, frag_info.focus_radius,
frag_info.center, frag_info.radius, v_position);
vec4 DoConicalGradientUniformFill(vec2 res) {
float t = res.x;
vec4 result_color = vec4(0);
if (res.y < 0.0 ||
@@ -64,5 +56,8 @@ void main() {
}
}
frag_color = IPPremultiply(result_color) * frag_info.alpha;
result_color = IPPremultiply(result_color) * frag_info.alpha;
return result_color;
}
#endif // CONICAL_GRADIENT_UNIFORM_FILL_GLSL_

View File

@@ -16,6 +16,101 @@ mat3 IPMapToUnitX(vec2 p0, vec2 p1) {
p1.y - p0.y, 0.0, p0.x, p0.y, 1.0));
}
vec2 IPComputeConicalTRadial(vec2 c0, float r0, vec2 c1, float r1, vec2 pos) {
float d_radius = r1 - r0;
float scale = 1.0 / d_radius;
float scale_sign = sign(d_radius);
float bias = r0 / d_radius;
vec2 pt = (pos - c0) * scale;
float t = length(pt) * scale_sign - bias;
return vec2(t, 1.0);
}
vec2 IPComputeConicalTStrip(vec2 c0, float r0, vec2 c1, float r1, vec2 pos) {
float d_center = distance(c0, c1);
mat3 transform = IPMapToUnitX(c0, c1);
float r = r0 / d_center;
float r_2 = r * r;
vec2 pt = (transform * vec3(pos.xy, 1.0)).xy;
float t = r_2 - pt.y * pt.y;
if (t < 0.0) {
return vec2(0.0, -1.0);
}
t = pt.x + sqrt(t);
return vec2(t, 1.0);
}
vec2 IPComputeConicalTConical(vec2 c0, float r0, vec2 c1, float r1, vec2 pos) {
const float scalar_nearly_zero = 1.0 / float(1 << 12);
float d_center = distance(c0, c1);
// See https://skia.org/docs/dev/design/conical/ for details on how this
// algorithm works. Calculate f and swap inputs if necessary (steps 1 and
// 2).
float f = r0 / (r0 - r1);
bool is_swapped = abs(f - 1.0) < scalar_nearly_zero;
if (is_swapped) {
vec2 tmp_pt = c0;
c0 = c1;
c1 = tmp_pt;
f = 0.0;
}
// Apply mapping from [Cf, C1] to unit x, and apply the precalculations from
// steps 3 and 4, all in the same transform.
vec2 cf = c0 * (1.0 - f) + c1 * f;
mat3 transform = IPMapToUnitX(cf, c1);
float scale_x = abs(1.0 - f);
float scale_y = scale_x;
float local_r1 = abs(r1 - r0) / d_center;
bool is_focal_on_circle = abs(local_r1 - 1.0) < scalar_nearly_zero;
if (is_focal_on_circle) {
scale_x *= 0.5;
scale_y *= 0.5;
} else {
scale_x *= local_r1 / (local_r1 * local_r1 - 1.0);
scale_y /= sqrt(abs(local_r1 * local_r1 - 1.0));
}
transform =
mat3(scale_x, 0.0, 0.0, 0.0, scale_y, 0.0, 0.0, 0.0, 1.0) * transform;
vec2 pt = (transform * vec3(pos.xy, 1.0)).xy;
// Continue with step 5 onward.
float inv_r1 = 1.0 / local_r1;
float d_radius_sign = sign(1.0 - f);
bool is_well_behaved = !is_focal_on_circle && local_r1 > 1.0;
float x_t = -1.0;
if (is_focal_on_circle) {
x_t = dot(pt, pt) / pt.x;
} else if (is_well_behaved) {
x_t = length(pt) - pt.x * inv_r1;
} else {
float temp = pt.x * pt.x - pt.y * pt.y;
if (temp >= 0.0) {
if (is_swapped || d_radius_sign < 0.0) {
x_t = -sqrt(temp) - pt.x * inv_r1;
} else {
x_t = sqrt(temp) - pt.x * inv_r1;
}
}
}
if (!is_well_behaved && x_t < 0.0) {
return vec2(0.0, -1.0);
}
float t = f + d_radius_sign * x_t;
if (is_swapped) {
t = 1.0 - t;
}
return vec2(t, 1.0);
}
/// Compute the t value for a conical gradient at point `p` between the 2
/// circles defined by (c0, r0) and (c1, r1). The returned vec2 encapsulates 't'
/// as its x component and validity status as its y component, with positive y
@@ -23,111 +118,20 @@ mat3 IPMapToUnitX(vec2 p0, vec2 p1) {
///
/// The code is migrated from Skia Graphite. See
/// https://github.com/google/skia/blob/ddf987d2ab3314ee0e80ac1ae7dbffb44a87d394/src/sksl/sksl_graphite_frag.sksl#L541-L666.
vec2 IPComputeConicalT(vec2 c0, float r0, vec2 c1, float r1, vec2 pos) {
const float scalar_nearly_zero = 1.0 / float(1 << 12);
float d_center = distance(c0, c1);
float d_radius = r1 - r0;
// Degenerate case: a radial gradient (p0 = p1).
bool radial = d_center < scalar_nearly_zero;
// Degenerate case: a strip with bandwidth 2r (r0 = r1).
bool strip = abs(d_radius) < scalar_nearly_zero;
if (radial) {
if (strip) {
// The start and end inputs are the same in both position and radius.
// We don't expect to see this input, but just in case we avoid dividing
// by zero.
return vec2(0.0, -1.0);
}
float scale = 1.0 / d_radius;
float scale_sign = sign(d_radius);
float bias = r0 / d_radius;
vec2 pt = (pos - c0) * scale;
float t = length(pt) * scale_sign - bias;
return vec2(t, 1.0);
} else if (strip) {
mat3 transform = IPMapToUnitX(c0, c1);
float r = r0 / d_center;
float r_2 = r * r;
vec2 pt = (transform * vec3(pos.xy, 1.0)).xy;
float t = r_2 - pt.y * pt.y;
if (t < 0.0) {
return vec2(0.0, -1.0);
}
t = pt.x + sqrt(t);
return vec2(t, 1.0);
vec2 IPComputeConicalT(float kind,
vec2 c0,
float r0,
vec2 c1,
float r1,
vec2 pos) {
if (kind == 0.0) {
return vec2(0.0, -1.0);
} else if (kind == 1.0) {
return IPComputeConicalTRadial(c0, r0, c1, r1, pos);
} else if (kind == 2.0) {
return IPComputeConicalTStrip(c0, r0, c1, r1, pos);
} else {
// See https://skia.org/docs/dev/design/conical/ for details on how this
// algorithm works. Calculate f and swap inputs if necessary (steps 1 and
// 2).
float f = r0 / (r0 - r1);
bool is_swapped = abs(f - 1.0) < scalar_nearly_zero;
if (is_swapped) {
vec2 tmp_pt = c0;
c0 = c1;
c1 = tmp_pt;
f = 0.0;
}
// Apply mapping from [Cf, C1] to unit x, and apply the precalculations from
// steps 3 and 4, all in the same transform.
vec2 cf = c0 * (1.0 - f) + c1 * f;
mat3 transform = IPMapToUnitX(cf, c1);
float scale_x = abs(1.0 - f);
float scale_y = scale_x;
float r1 = abs(r1 - r0) / d_center;
bool is_focal_on_circle = abs(r1 - 1.0) < scalar_nearly_zero;
if (is_focal_on_circle) {
scale_x *= 0.5;
scale_y *= 0.5;
} else {
scale_x *= r1 / (r1 * r1 - 1.0);
scale_y /= sqrt(abs(r1 * r1 - 1.0));
}
transform =
mat3(scale_x, 0.0, 0.0, 0.0, scale_y, 0.0, 0.0, 0.0, 1.0) * transform;
vec2 pt = (transform * vec3(pos.xy, 1.0)).xy;
// Continue with step 5 onward.
float inv_r1 = 1.0 / r1;
float d_radius_sign = sign(1.0 - f);
bool is_well_behaved = !is_focal_on_circle && r1 > 1.0;
float x_t = -1.0;
if (is_focal_on_circle) {
x_t = dot(pt, pt) / pt.x;
} else if (is_well_behaved) {
x_t = length(pt) - pt.x * inv_r1;
} else {
float temp = pt.x * pt.x - pt.y * pt.y;
if (temp >= 0.0) {
if (is_swapped || d_radius_sign < 0.0) {
x_t = -sqrt(temp) - pt.x * inv_r1;
} else {
x_t = sqrt(temp) - pt.x * inv_r1;
}
}
}
if (!is_well_behaved && x_t < 0.0) {
return vec2(0.0, -1.0);
}
float t = f + d_radius_sign * x_t;
if (is_swapped) {
t = 1.0 - t;
}
return vec2(t, 1.0);
return IPComputeConicalTConical(c0, r0, c1, r1, pos);
}
}

View File

@@ -685,9 +685,14 @@ TEST_P(AiksTest, CanRenderConicalGradient) {
builder.Save();
builder.Translate((i % 3) * size, i / 3 * size);
paint.setColorSource(DlColorSource::MakeConical(
std::get<2>(array[i]), std::get<3>(array[i]), std::get<0>(array[i]),
std::get<1>(array[i]), stops.size(), colors.data(), stops.data(),
DlTileMode::kClamp));
/*start_center=*/std::get<2>(array[i]),
/*start_radius=*/std::get<3>(array[i]),
/*end_center=*/std::get<0>(array[i]),
/*end_radius=*/std::get<1>(array[i]),
/*stop_count=*/stops.size(),
/*colors=*/colors.data(),
/*stops=*/stops.data(),
/*tile_mode=*/DlTileMode::kClamp));
builder.DrawRect(DlRect::MakeXYWH(0, 0, size, size), paint);
builder.Restore();
}

View File

@@ -21,8 +21,14 @@ impeller_shaders("entity_shaders") {
"shaders/glyph_atlas.frag",
"shaders/glyph_atlas.vert",
"shaders/gradients/gradient_fill.vert",
"shaders/gradients/conical_gradient_fill.frag",
"shaders/gradients/conical_gradient_uniform_fill.frag",
"shaders/gradients/conical_gradient_fill_conical.frag",
"shaders/gradients/conical_gradient_fill_strip.frag",
"shaders/gradients/conical_gradient_fill_radial.frag",
"shaders/gradients/conical_gradient_fill_strip_radial.frag",
"shaders/gradients/conical_gradient_uniform_fill_conical.frag",
"shaders/gradients/conical_gradient_uniform_fill_strip.frag",
"shaders/gradients/conical_gradient_uniform_fill_radial.frag",
"shaders/gradients/conical_gradient_uniform_fill_strip_radial.frag",
"shaders/gradients/linear_gradient_fill.frag",
"shaders/gradients/linear_gradient_uniform_fill.frag",
"shaders/gradients/radial_gradient_fill.frag",

View File

@@ -14,6 +14,28 @@
namespace impeller {
namespace {
ConicalKind GetConicalKind(Point center,
Scalar radius,
std::optional<Point> focus,
Scalar focus_radius) {
ConicalKind kind = ConicalKind::kConical;
if (!focus.has_value() ||
center.GetDistance(focus.value()) < kEhCloseEnough) {
kind = ConicalKind::kRadial;
}
if (focus.has_value() && std::fabsf(radius - focus_radius) < kEhCloseEnough) {
if (kind == ConicalKind::kRadial) {
kind = ConicalKind::kStripAndRadial;
} else {
kind = ConicalKind::kStrip;
}
}
return kind;
}
} // namespace
ConicalGradientContents::ConicalGradientContents() = default;
ConicalGradientContents::~ConicalGradientContents() = default;
@@ -51,7 +73,7 @@ void ConicalGradientContents::SetFocus(std::optional<Point> focus,
#define ARRAY_LEN(a) (sizeof(a) / sizeof(a[0]))
#define UNIFORM_FRAG_INFO(t) \
t##GradientUniformFillPipeline::FragmentShader::FragInfo
t##GradientUniformFillConicalPipeline::FragmentShader::FragInfo
#define UNIFORM_COLOR_SIZE ARRAY_LEN(UNIFORM_FRAG_INFO(Conical)::colors)
#define UNIFORM_STOP_SIZE ARRAY_LEN(UNIFORM_FRAG_INFO(Conical)::stop_pairs)
static_assert(UNIFORM_COLOR_SIZE == kMaxUniformGradientStops);
@@ -79,9 +101,10 @@ bool ConicalGradientContents::RenderSSBO(const ContentContext& renderer,
VS::FrameInfo frame_info;
frame_info.matrix = GetInverseEffectTransform();
ConicalKind kind = GetConicalKind(center_, radius_, focus_, focus_radius_);
PipelineBuilderCallback pipeline_callback =
[&renderer](ContentContextOptions options) {
return renderer.GetConicalGradientSSBOFillPipeline(options);
[&renderer, kind](ContentContextOptions options) {
return renderer.GetConicalGradientSSBOFillPipeline(options, kind);
};
return ColorSourceContents::DrawGeometry<VS>(
renderer, entity, pass, pipeline_callback, frame_info,
@@ -122,15 +145,16 @@ bool ConicalGradientContents::RenderSSBO(const ContentContext& renderer,
bool ConicalGradientContents::RenderUniform(const ContentContext& renderer,
const Entity& entity,
RenderPass& pass) const {
using VS = ConicalGradientUniformFillPipeline::VertexShader;
using FS = ConicalGradientUniformFillPipeline::FragmentShader;
using VS = ConicalGradientUniformFillConicalPipeline::VertexShader;
using FS = ConicalGradientUniformFillConicalPipeline::FragmentShader;
VS::FrameInfo frame_info;
frame_info.matrix = GetInverseEffectTransform();
ConicalKind kind = GetConicalKind(center_, radius_, focus_, focus_radius_);
PipelineBuilderCallback pipeline_callback =
[&renderer](ContentContextOptions options) {
return renderer.GetConicalGradientUniformFillPipeline(options);
[&renderer, kind](ContentContextOptions options) {
return renderer.GetConicalGradientUniformFillPipeline(options, kind);
};
return ColorSourceContents::DrawGeometry<VS>(
renderer, entity, pass, pipeline_callback, frame_info,
@@ -165,8 +189,8 @@ bool ConicalGradientContents::RenderUniform(const ContentContext& renderer,
bool ConicalGradientContents::RenderTexture(const ContentContext& renderer,
const Entity& entity,
RenderPass& pass) const {
using VS = ConicalGradientFillPipeline::VertexShader;
using FS = ConicalGradientFillPipeline::FragmentShader;
using VS = ConicalGradientFillConicalPipeline::VertexShader;
using FS = ConicalGradientFillConicalPipeline::FragmentShader;
auto gradient_data = CreateGradientBuffer(colors_, stops_);
auto gradient_texture =
@@ -178,9 +202,10 @@ bool ConicalGradientContents::RenderTexture(const ContentContext& renderer,
VS::FrameInfo frame_info;
frame_info.matrix = GetInverseEffectTransform();
ConicalKind kind = GetConicalKind(center_, radius_, focus_, focus_radius_);
PipelineBuilderCallback pipeline_callback =
[&renderer](ContentContextOptions options) {
return renderer.GetConicalGradientFillPipeline(options);
[&renderer, kind](ContentContextOptions options) {
return renderer.GetConicalGradientFillPipeline(options, kind);
};
return ColorSourceContents::DrawGeometry<VS>(
renderer, entity, pass, pipeline_callback, frame_info,

View File

@@ -326,18 +326,35 @@ ContentContext::ContentContext(
if (context_->GetCapabilities()->SupportsSSBO()) {
linear_gradient_ssbo_fill_pipelines_.CreateDefault(*context_, options);
radial_gradient_ssbo_fill_pipelines_.CreateDefault(*context_, options);
conical_gradient_ssbo_fill_pipelines_.CreateDefault(*context_, options);
conical_gradient_ssbo_fill_pipelines_.CreateDefault(*context_, options,
{3.0});
conical_gradient_ssbo_fill_radial_pipelines_.CreateDefault(
*context_, options, {1.0});
conical_gradient_ssbo_fill_strip_pipelines_.CreateDefault(*context_,
options, {2.0});
conical_gradient_ssbo_fill_strip_and_radial_pipelines_.CreateDefault(
*context_, options, {0.0});
sweep_gradient_ssbo_fill_pipelines_.CreateDefault(*context_, options);
} else {
linear_gradient_uniform_fill_pipelines_.CreateDefault(*context_, options);
radial_gradient_uniform_fill_pipelines_.CreateDefault(*context_, options);
conical_gradient_uniform_fill_pipelines_.CreateDefault(*context_,
options);
conical_gradient_uniform_fill_radial_pipelines_.CreateDefault(*context_,
options);
conical_gradient_uniform_fill_strip_pipelines_.CreateDefault(*context_,
options);
conical_gradient_uniform_fill_strip_and_radial_pipelines_.CreateDefault(
*context_, options);
sweep_gradient_uniform_fill_pipelines_.CreateDefault(*context_, options);
linear_gradient_fill_pipelines_.CreateDefault(*context_, options);
radial_gradient_fill_pipelines_.CreateDefault(*context_, options);
conical_gradient_fill_pipelines_.CreateDefault(*context_, options);
conical_gradient_fill_radial_pipelines_.CreateDefault(*context_, options);
conical_gradient_fill_strip_pipelines_.CreateDefault(*context_, options);
conical_gradient_fill_strip_and_radial_pipelines_.CreateDefault(*context_,
options);
sweep_gradient_fill_pipelines_.CreateDefault(*context_, options);
}

View File

@@ -28,7 +28,10 @@
#include "impeller/entity/clip.frag.h"
#include "impeller/entity/clip.vert.h"
#include "impeller/entity/color_matrix_color_filter.frag.h"
#include "impeller/entity/conical_gradient_fill.frag.h"
#include "impeller/entity/conical_gradient_fill_conical.frag.h"
#include "impeller/entity/conical_gradient_fill_radial.frag.h"
#include "impeller/entity/conical_gradient_fill_strip.frag.h"
#include "impeller/entity/conical_gradient_fill_strip_radial.frag.h"
#include "impeller/entity/fast_gradient.frag.h"
#include "impeller/entity/fast_gradient.vert.h"
#include "impeller/entity/filter_position.vert.h"
@@ -57,7 +60,10 @@
#include "impeller/entity/tiled_texture_fill.frag.h"
#include "impeller/entity/yuv_to_rgb_filter.frag.h"
#include "impeller/entity/conical_gradient_uniform_fill.frag.h"
#include "impeller/entity/conical_gradient_uniform_fill_conical.frag.h"
#include "impeller/entity/conical_gradient_uniform_fill_radial.frag.h"
#include "impeller/entity/conical_gradient_uniform_fill_strip.frag.h"
#include "impeller/entity/conical_gradient_uniform_fill_strip_radial.frag.h"
#include "impeller/entity/linear_gradient_uniform_fill.frag.h"
#include "impeller/entity/radial_gradient_uniform_fill.frag.h"
#include "impeller/entity/sweep_gradient_uniform_fill.frag.h"
@@ -92,18 +98,36 @@ using SolidFillPipeline =
using RadialGradientFillPipeline =
RenderPipelineHandle<GradientFillVertexShader,
RadialGradientFillFragmentShader>;
using ConicalGradientFillPipeline =
using ConicalGradientFillConicalPipeline =
RenderPipelineHandle<GradientFillVertexShader,
ConicalGradientFillFragmentShader>;
ConicalGradientFillConicalFragmentShader>;
using ConicalGradientFillStripPipeline =
RenderPipelineHandle<GradientFillVertexShader,
ConicalGradientFillStripFragmentShader>;
using ConicalGradientFillRadialPipeline =
RenderPipelineHandle<GradientFillVertexShader,
ConicalGradientFillRadialFragmentShader>;
using ConicalGradientFillStripRadialPipeline =
RenderPipelineHandle<GradientFillVertexShader,
ConicalGradientFillStripRadialFragmentShader>;
using SweepGradientFillPipeline =
RenderPipelineHandle<GradientFillVertexShader,
SweepGradientFillFragmentShader>;
using LinearGradientUniformFillPipeline =
RenderPipelineHandle<GradientFillVertexShader,
LinearGradientUniformFillFragmentShader>;
using ConicalGradientUniformFillPipeline =
using ConicalGradientUniformFillConicalPipeline =
RenderPipelineHandle<GradientFillVertexShader,
ConicalGradientUniformFillFragmentShader>;
ConicalGradientUniformFillConicalFragmentShader>;
using ConicalGradientUniformFillStripPipeline =
RenderPipelineHandle<GradientFillVertexShader,
ConicalGradientUniformFillStripFragmentShader>;
using ConicalGradientUniformFillRadialPipeline =
RenderPipelineHandle<GradientFillVertexShader,
ConicalGradientUniformFillRadialFragmentShader>;
using ConicalGradientUniformFillStripRadialPipeline =
RenderPipelineHandle<GradientFillVertexShader,
ConicalGradientUniformFillStripRadialFragmentShader>;
using RadialGradientUniformFillPipeline =
RenderPipelineHandle<GradientFillVertexShader,
RadialGradientUniformFillFragmentShader>;
@@ -365,6 +389,13 @@ struct ContentContextOptions {
void ApplyToPipelineDescriptor(PipelineDescriptor& desc) const;
};
enum ConicalKind {
kConical,
kRadial,
kStrip,
kStripAndRadial,
};
class Tessellator;
class RenderTargetCache;
@@ -399,9 +430,21 @@ class ContentContext {
return GetPipeline(radial_gradient_uniform_fill_pipelines_, opts);
}
PipelineRef GetConicalGradientUniformFillPipeline(
ContentContextOptions opts) const {
return GetPipeline(conical_gradient_uniform_fill_pipelines_, opts);
PipelineRef GetConicalGradientUniformFillPipeline(ContentContextOptions opts,
ConicalKind kind) const {
switch (kind) {
case ConicalKind::kConical:
return GetPipeline(conical_gradient_uniform_fill_pipelines_, opts);
case ConicalKind::kRadial:
return GetPipeline(conical_gradient_uniform_fill_radial_pipelines_,
opts);
case ConicalKind::kStrip:
return GetPipeline(conical_gradient_uniform_fill_strip_pipelines_,
opts);
case ConicalKind::kStripAndRadial:
return GetPipeline(
conical_gradient_uniform_fill_strip_and_radial_pipelines_, opts);
}
}
PipelineRef GetSweepGradientUniformFillPipeline(
@@ -421,10 +464,20 @@ class ContentContext {
return GetPipeline(radial_gradient_ssbo_fill_pipelines_, opts);
}
PipelineRef GetConicalGradientSSBOFillPipeline(
ContentContextOptions opts) const {
PipelineRef GetConicalGradientSSBOFillPipeline(ContentContextOptions opts,
ConicalKind kind) const {
FML_DCHECK(GetDeviceCapabilities().SupportsSSBO());
return GetPipeline(conical_gradient_ssbo_fill_pipelines_, opts);
switch (kind) {
case ConicalKind::kConical:
return GetPipeline(conical_gradient_ssbo_fill_pipelines_, opts);
case ConicalKind::kRadial:
return GetPipeline(conical_gradient_ssbo_fill_radial_pipelines_, opts);
case ConicalKind::kStrip:
return GetPipeline(conical_gradient_ssbo_fill_strip_pipelines_, opts);
case ConicalKind::kStripAndRadial:
return GetPipeline(
conical_gradient_ssbo_fill_strip_and_radial_pipelines_, opts);
}
}
PipelineRef GetSweepGradientSSBOFillPipeline(
@@ -437,8 +490,19 @@ class ContentContext {
return GetPipeline(radial_gradient_fill_pipelines_, opts);
}
PipelineRef GetConicalGradientFillPipeline(ContentContextOptions opts) const {
return GetPipeline(conical_gradient_fill_pipelines_, opts);
PipelineRef GetConicalGradientFillPipeline(ContentContextOptions opts,
ConicalKind kind) const {
switch (kind) {
case ConicalKind::kConical:
return GetPipeline(conical_gradient_fill_pipelines_, opts);
case ConicalKind::kRadial:
return GetPipeline(conical_gradient_fill_radial_pipelines_, opts);
case ConicalKind::kStrip:
return GetPipeline(conical_gradient_fill_strip_pipelines_, opts);
case ConicalKind::kStripAndRadial:
return GetPipeline(conical_gradient_fill_strip_and_radial_pipelines_,
opts);
}
}
PipelineRef GetRRectBlurPipeline(ContentContextOptions opts) const {
@@ -988,15 +1052,27 @@ class ContentContext {
mutable Variants<FastGradientPipeline> fast_gradient_pipelines_;
mutable Variants<LinearGradientFillPipeline> linear_gradient_fill_pipelines_;
mutable Variants<RadialGradientFillPipeline> radial_gradient_fill_pipelines_;
mutable Variants<ConicalGradientFillPipeline>
mutable Variants<ConicalGradientFillConicalPipeline>
conical_gradient_fill_pipelines_;
mutable Variants<ConicalGradientFillRadialPipeline>
conical_gradient_fill_radial_pipelines_;
mutable Variants<ConicalGradientFillStripPipeline>
conical_gradient_fill_strip_pipelines_;
mutable Variants<ConicalGradientFillStripRadialPipeline>
conical_gradient_fill_strip_and_radial_pipelines_;
mutable Variants<SweepGradientFillPipeline> sweep_gradient_fill_pipelines_;
mutable Variants<LinearGradientUniformFillPipeline>
linear_gradient_uniform_fill_pipelines_;
mutable Variants<RadialGradientUniformFillPipeline>
radial_gradient_uniform_fill_pipelines_;
mutable Variants<ConicalGradientUniformFillPipeline>
mutable Variants<ConicalGradientUniformFillConicalPipeline>
conical_gradient_uniform_fill_pipelines_;
mutable Variants<ConicalGradientUniformFillRadialPipeline>
conical_gradient_uniform_fill_radial_pipelines_;
mutable Variants<ConicalGradientUniformFillStripPipeline>
conical_gradient_uniform_fill_strip_pipelines_;
mutable Variants<ConicalGradientUniformFillStripRadialPipeline>
conical_gradient_uniform_fill_strip_and_radial_pipelines_;
mutable Variants<SweepGradientUniformFillPipeline>
sweep_gradient_uniform_fill_pipelines_;
mutable Variants<LinearGradientSSBOFillPipeline>
@@ -1005,6 +1081,12 @@ class ContentContext {
radial_gradient_ssbo_fill_pipelines_;
mutable Variants<ConicalGradientSSBOFillPipeline>
conical_gradient_ssbo_fill_pipelines_;
mutable Variants<ConicalGradientSSBOFillPipeline>
conical_gradient_ssbo_fill_radial_pipelines_;
mutable Variants<ConicalGradientSSBOFillPipeline>
conical_gradient_ssbo_fill_strip_pipelines_;
mutable Variants<ConicalGradientSSBOFillPipeline>
conical_gradient_ssbo_fill_strip_and_radial_pipelines_;
mutable Variants<SweepGradientSSBOFillPipeline>
sweep_gradient_ssbo_fill_pipelines_;
mutable Variants<RRectBlurPipeline> rrect_blur_pipelines_;

View File

@@ -0,0 +1,22 @@
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
precision highp float;
#include <impeller/color.glsl>
#include <impeller/conical_gradient_fill.glsl>
#include <impeller/gradient.glsl>
#include <impeller/texture.glsl>
#include <impeller/types.glsl>
highp in vec2 v_position;
out vec4 frag_color;
void main() {
vec2 res =
IPComputeConicalTConical(frag_info.focus, frag_info.focus_radius,
frag_info.center, frag_info.radius, v_position);
frag_color = DoConicalGradientTextureFill(res);
}

View File

@@ -0,0 +1,22 @@
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
precision highp float;
#include <impeller/color.glsl>
#include <impeller/conical_gradient_fill.glsl>
#include <impeller/gradient.glsl>
#include <impeller/texture.glsl>
#include <impeller/types.glsl>
highp in vec2 v_position;
out vec4 frag_color;
void main() {
vec2 res =
IPComputeConicalTRadial(frag_info.focus, frag_info.focus_radius,
frag_info.center, frag_info.radius, v_position);
frag_color = DoConicalGradientTextureFill(res);
}

View File

@@ -0,0 +1,22 @@
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
precision highp float;
#include <impeller/color.glsl>
#include <impeller/conical_gradient_fill.glsl>
#include <impeller/gradient.glsl>
#include <impeller/texture.glsl>
#include <impeller/types.glsl>
highp in vec2 v_position;
out vec4 frag_color;
void main() {
vec2 res =
IPComputeConicalTStrip(frag_info.focus, frag_info.focus_radius,
frag_info.center, frag_info.radius, v_position);
frag_color = DoConicalGradientTextureFill(res);
}

View File

@@ -0,0 +1,20 @@
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
precision highp float;
#include <impeller/color.glsl>
#include <impeller/conical_gradient_fill.glsl>
#include <impeller/gradient.glsl>
#include <impeller/texture.glsl>
#include <impeller/types.glsl>
highp in vec2 v_position;
out vec4 frag_color;
void main() {
vec2 res = vec2(0.0, -1.0);
frag_color = DoConicalGradientTextureFill(res);
}

View File

@@ -10,6 +10,8 @@ precision highp float;
#include <impeller/texture.glsl>
#include <impeller/types.glsl>
layout(constant_id = 0) const float kind = 3.0;
struct ColorPoint {
vec4 color;
float stop;
@@ -37,7 +39,7 @@ highp in vec2 v_position;
out vec4 frag_color;
void main() {
vec2 res = IPComputeConicalT(frag_info.focus, frag_info.focus_radius,
vec2 res = IPComputeConicalT(kind, frag_info.focus, frag_info.focus_radius,
frag_info.center, frag_info.radius, v_position);
float t = res.x;

View File

@@ -0,0 +1,23 @@
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
precision highp float;
#include <impeller/color.glsl>
#include <impeller/conical_gradient_uniform_fill.glsl>
#include <impeller/dithering.glsl>
#include <impeller/gradient.glsl>
#include <impeller/texture.glsl>
#include <impeller/types.glsl>
highp in vec2 v_position;
out vec4 frag_color;
void main() {
vec2 res =
IPComputeConicalTConical(frag_info.focus, frag_info.focus_radius,
frag_info.center, frag_info.radius, v_position);
frag_color = DoConicalGradientUniformFill(res);
}

View File

@@ -0,0 +1,24 @@
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
precision highp float;
#include <impeller/color.glsl>
#include <impeller/conical_gradient_uniform_fill.glsl>
#include <impeller/dithering.glsl>
#include <impeller/gradient.glsl>
#include <impeller/texture.glsl>
#include <impeller/types.glsl>
highp in vec2 v_position;
out vec4 frag_color;
void main() {
vec2 res =
IPComputeConicalTRadial(frag_info.focus, frag_info.focus_radius,
frag_info.center, frag_info.radius, v_position);
frag_color = DoConicalGradientUniformFill(res);
}

View File

@@ -0,0 +1,24 @@
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
precision highp float;
#include <impeller/color.glsl>
#include <impeller/conical_gradient_uniform_fill.glsl>
#include <impeller/dithering.glsl>
#include <impeller/gradient.glsl>
#include <impeller/texture.glsl>
#include <impeller/types.glsl>
highp in vec2 v_position;
out vec4 frag_color;
void main() {
vec2 res =
IPComputeConicalTStrip(frag_info.focus, frag_info.focus_radius,
frag_info.center, frag_info.radius, v_position);
frag_color = DoConicalGradientUniformFill(res);
}

View File

@@ -0,0 +1,21 @@
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
precision highp float;
#include <impeller/color.glsl>
#include <impeller/conical_gradient_uniform_fill.glsl>
#include <impeller/dithering.glsl>
#include <impeller/gradient.glsl>
#include <impeller/texture.glsl>
#include <impeller/types.glsl>
highp in vec2 v_position;
out vec4 frag_color;
void main() {
vec2 res = vec2(0.0, -1.0);
frag_color = DoConicalGradientUniformFill(res);
}

File diff suppressed because it is too large Load Diff