Skip to content

Commit 4720fb8

Browse files
committed
commit
1 parent 9ead586 commit 4720fb8

12 files changed

Lines changed: 667 additions & 412 deletions

File tree

‎engine/src/flutter/impeller/display_list/canvas.cc‎

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -333,14 +333,19 @@ CreateUberSDFGradientParameters(const ContentContext& renderer,
333333
return std::nullopt;
334334
}
335335

336-
GradientData gradient_data = CreateGradientBuffer(colors, stops);
337-
std::shared_ptr<Texture> texture =
338-
CreateGradientTexture(gradient_data, renderer.GetContext());
339-
if (!texture) {
340-
return std::nullopt;
336+
if (renderer.GetContext()->GetCapabilities()->SupportsSSBO()) {
337+
gradient.colors = std::move(colors);
338+
gradient.stops = std::move(stops);
339+
} else {
340+
GradientData gradient_data = CreateGradientBuffer(colors, stops);
341+
std::shared_ptr<Texture> texture =
342+
CreateGradientTexture(gradient_data, renderer.GetContext());
343+
if (!texture) {
344+
return std::nullopt;
345+
}
346+
gradient.texture = std::move(texture);
341347
}
342348

343-
gradient.texture = std::move(texture);
344349
return gradient;
345350
}
346351

‎engine/src/flutter/impeller/entity/BUILD.gn‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ impeller_shaders("modern_entity_shaders") {
9191
"shaders/gradients/linear_gradient_ssbo_fill.frag",
9292
"shaders/gradients/radial_gradient_ssbo_fill.frag",
9393
"shaders/gradients/sweep_gradient_ssbo_fill.frag",
94+
"shaders/uber_sdf_ssbo.frag",
9495
]
9596
}
9697

‎engine/src/flutter/impeller/entity/contents/content_context.cc‎

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -304,6 +304,7 @@ struct ContentContext::Pipelines {
304304
Variants<VerticesUber1Shader> vertices_uber_1_;
305305
Variants<VerticesUber2Shader> vertices_uber_2_;
306306
Variants<UberSDFPipeline> uber_sdf;
307+
Variants<UberSDFSSBOPipeline> uber_sdf_ssbo;
307308
Variants<ComplexRSEPipeline> complex_rse;
308309
Variants<YUVToRGBFilterPipeline> yuv_to_rgb_filter;
309310

@@ -638,7 +639,11 @@ ContentContext::ContentContext(
638639
pipelines_->fast_gradient.CreateDefault(*context_, options);
639640
pipelines_->circle.CreateDefault(*context_, options);
640641
if (context_->GetFlags().use_sdfs) {
641-
pipelines_->uber_sdf.CreateDefault(*context_, options);
642+
if (context_->GetCapabilities()->SupportsSSBO()) {
643+
pipelines_->uber_sdf_ssbo.CreateDefault(*context_, options);
644+
} else {
645+
pipelines_->uber_sdf.CreateDefault(*context_, options);
646+
}
642647
pipelines_->complex_rse.CreateDefault(*context_, options);
643648
}
644649

@@ -1209,6 +1214,11 @@ PipelineRef ContentContext::GetUberSDFPipeline(
12091214
return GetPipeline(this, pipelines_->uber_sdf, opts);
12101215
}
12111216

1217+
PipelineRef ContentContext::GetUberSDFSSBOPipeline(
1218+
ContentContextOptions opts) const {
1219+
return GetPipeline(this, pipelines_->uber_sdf_ssbo, opts);
1220+
}
1221+
12121222
PipelineRef ContentContext::GetComplexRSEPipeline(
12131223
ContentContextOptions opts) const {
12141224
return GetPipeline(this, pipelines_->complex_rse, opts);

‎engine/src/flutter/impeller/entity/contents/content_context.h‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,7 @@ class ContentContext {
214214
PipelineRef GetXorBlendPipeline(ContentContextOptions opts) const;
215215
PipelineRef GetYUVToRGBFilterPipeline(ContentContextOptions opts) const;
216216
PipelineRef GetUberSDFPipeline(ContentContextOptions opts) const;
217+
PipelineRef GetUberSDFSSBOPipeline(ContentContextOptions opts) const;
217218
PipelineRef GetComplexRSEPipeline(ContentContextOptions opts) const;
218219
#ifdef IMPELLER_ENABLE_OPENGLES
219220
#if !defined(FML_OS_EMSCRIPTEN)

‎engine/src/flutter/impeller/entity/contents/pipelines.h‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@
6363
#include "impeller/entity/texture_uv_fill.vert.h"
6464
#include "impeller/entity/tiled_texture_fill.frag.h"
6565
#include "impeller/entity/uber_sdf.frag.h"
66+
#include "impeller/entity/uber_sdf_ssbo.frag.h"
6667
#include "impeller/entity/vertices_uber_1.frag.h"
6768
#include "impeller/entity/vertices_uber_2.frag.h"
6869
#include "impeller/entity/yuv_to_rgb_filter.frag.h"
@@ -160,6 +161,7 @@ using TiledTexturePipeline = RenderPipelineHandle<TextureUvFillVertexShader, Til
160161
using VerticesUber1Shader = RenderPipelineHandle<PorterDuffBlendVertexShader, VerticesUber1FragmentShader>;
161162
using VerticesUber2Shader = RenderPipelineHandle<PorterDuffBlendVertexShader, VerticesUber2FragmentShader>;
162163
using UberSDFPipeline = RenderPipelineHandle<CircleVertexShader, UberSdfFragmentShader>;
164+
using UberSDFSSBOPipeline = RenderPipelineHandle<CircleVertexShader, UberSdfSsboFragmentShader>;
163165
using ComplexRSEPipeline = RenderPipelineHandle<CircleVertexShader, ComplexRseFragmentShader>;
164166
using YUVToRGBFilterPipeline = RenderPipelineHandle<FilterPositionVertexShader, YuvToRgbFilterFragmentShader>;
165167
// clang-format on

‎engine/src/flutter/impeller/entity/contents/uber_sdf_contents.cc‎

Lines changed: 107 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
#include "flutter/fml/logging.h"
88
#include "impeller/entity/contents/color_source_contents.h"
99
#include "impeller/entity/contents/content_context.h"
10+
#include "impeller/entity/contents/gradient_generator.h"
1011
#include "impeller/entity/contents/pipelines.h"
1112
#include "impeller/entity/contents/uber_sdf_parameters.h"
1213
#include "impeller/geometry/stroke_parameters.h"
@@ -18,9 +19,6 @@ namespace {
1819
using PipelineBuilderCallback =
1920
std::function<PipelineRef(ContentContextOptions)>;
2021

21-
using VS = UberSDFPipeline::VertexShader;
22-
using FS = UberSDFPipeline::FragmentShader;
23-
2422
Scalar ToShaderType(UberSDFParameters::Type type) {
2523
switch (type) {
2624
case UberSDFParameters::Type::kCircle:
@@ -64,18 +62,12 @@ struct SamplerBinding {
6462
raw_ptr<const Sampler> sampler;
6563
};
6664

67-
/// @brief Populates the gradient uniform fields in `frag_info` and returns
68-
/// the texture and sampler for the gradient.
69-
SamplerBinding SetupGradientParameters(
65+
/// @brief Populates the gradient uniforms shared by both UberSDF variants.
66+
template <typename FragInfo>
67+
void SetupCommonGradientParameters(
7068
const UberSDFParameters::GradientParameters& gradient,
71-
const ContentContext& renderer,
72-
FS::FragInfo& frag_info) {
73-
FML_DCHECK(gradient.texture);
69+
FragInfo& frag_info) {
7470
frag_info.tile_mode = static_cast<Scalar>(gradient.tile_mode);
75-
auto texture_size = gradient.texture->GetSize();
76-
FML_DCHECK(!texture_size.IsEmpty());
77-
frag_info.half_texel = 0.5f / texture_size.width;
78-
7971
if (gradient.type == UberSDFParameters::GradientParameters::Type::kLinear) {
8072
Point delta = gradient.end - gradient.start;
8173
Scalar length_sq = delta.x * delta.x + delta.y * delta.y;
@@ -88,14 +80,42 @@ SamplerBinding SetupGradientParameters(
8880
frag_info.inv_gradient_length =
8981
gradient.end.x > 0.0f ? 1.0f / gradient.end.x : 0.0f;
9082
}
83+
}
9184

92-
SamplerDescriptor sampler_desc;
93-
sampler_desc.min_filter = MinMagFilter::kLinear;
94-
sampler_desc.mag_filter = MinMagFilter::kLinear;
95-
raw_ptr<const Sampler> sampler =
96-
renderer.GetContext()->GetSamplerLibrary()->GetSampler(sampler_desc);
85+
/// @brief Populates the `frag_info` fields shared by both UberSDF variants.
86+
template <typename FragInfo>
87+
void SetupCommonFragInfo(const UberSDFParameters& params,
88+
Scalar opacity,
89+
const Entity& entity,
90+
FragInfo& frag_info) {
91+
frag_info.type = ToShaderType(params.type);
92+
frag_info.color_source_type = ToShaderColorSourceType(params);
93+
frag_info.color = params.color.WithAlpha(params.color.alpha * opacity);
94+
frag_info.center = params.center;
95+
frag_info.size = params.size;
96+
Vector2 pixel_size = entity.GetTransform().GetTransformedPixelSize();
97+
frag_info.pixel_size = Point(pixel_size.x, pixel_size.y);
98+
frag_info.stroked = params.stroke ? 1.0f : 0.0f;
99+
frag_info.stroke_width = params.stroke ? params.stroke->width : 0.0f;
100+
frag_info.stroke_join =
101+
params.stroke ? ToShaderStrokeJoin(params.stroke->join) : 0.0f;
102+
frag_info.aa_pixels = UberSDFParameters::kAntialiasPixels;
103+
frag_info.superellipse_degree = params.superellipse_degree;
104+
frag_info.angle_span = params.angle_span;
105+
frag_info.circle_center_top = params.circle_center_top;
106+
frag_info.circle_center_right = params.circle_center_right;
107+
frag_info.radii = params.radii;
97108

98-
return {gradient.texture, sampler};
109+
// Gradient parameter defaults; overwritten if there is a gradient.
110+
frag_info.gradient_coords = Vector4();
111+
frag_info.half_texel = 0.0f;
112+
frag_info.tile_mode = 0.0f;
113+
frag_info.inv_gradient_length = 0.0f;
114+
frag_info.colors_length = 0.0f;
115+
116+
if (params.gradient) {
117+
SetupCommonGradientParameters(params.gradient.value(), frag_info);
118+
}
99119
}
100120

101121
} // namespace
@@ -116,37 +136,37 @@ UberSDFContents::~UberSDFContents() = default;
116136
bool UberSDFContents::Render(const ContentContext& renderer,
117137
const Entity& entity,
118138
RenderPass& pass) const {
139+
if (renderer.GetDeviceCapabilities().SupportsSSBO()) {
140+
return RenderSSBO(renderer, entity, pass);
141+
}
142+
return RenderTexture(renderer, entity, pass);
143+
}
144+
145+
bool UberSDFContents::RenderTexture(const ContentContext& renderer,
146+
const Entity& entity,
147+
RenderPass& pass) const {
148+
using VS = UberSDFPipeline::VertexShader;
149+
using FS = UberSDFPipeline::FragmentShader;
150+
119151
auto& data_host_buffer = renderer.GetTransientsDataBuffer();
120152

121153
VS::FrameInfo frame_info;
122154
FS::FragInfo frag_info;
123-
frag_info.type = ToShaderType(params_.type);
124-
frag_info.color_source_type = ToShaderColorSourceType(params_);
125-
frag_info.color =
126-
params_.color.WithAlpha(params_.color.alpha * GetOpacityFactor());
127-
frag_info.center = params_.center;
128-
frag_info.size = params_.size;
129-
Vector2 pixel_size = entity.GetTransform().GetTransformedPixelSize();
130-
frag_info.pixel_size = Point(pixel_size.x, pixel_size.y);
131-
frag_info.stroked = params_.stroke ? 1.0f : 0.0f;
132-
frag_info.stroke_width = params_.stroke ? params_.stroke->width : 0.0f;
133-
frag_info.stroke_join =
134-
params_.stroke ? ToShaderStrokeJoin(params_.stroke->join) : 0.0f;
135-
frag_info.aa_pixels = UberSDFParameters::kAntialiasPixels;
136-
frag_info.superellipse_degree = params_.superellipse_degree;
137-
frag_info.angle_span = params_.angle_span;
138-
frag_info.circle_center_top = params_.circle_center_top;
139-
frag_info.circle_center_right = params_.circle_center_right;
140-
frag_info.radii = params_.radii;
141-
frag_info.gradient_coords = Vector4();
142-
frag_info.half_texel = 0.0f;
143-
frag_info.tile_mode = 0.0f;
144-
frag_info.inv_gradient_length = 0.0f;
155+
SetupCommonFragInfo(params_, GetOpacityFactor(), entity, frag_info);
145156

146157
SamplerBinding sampler_binding;
147158
if (params_.gradient) {
148-
sampler_binding =
149-
SetupGradientParameters(params_.gradient.value(), renderer, frag_info);
159+
FML_DCHECK(params_.gradient->texture);
160+
auto texture_size = params_.gradient->texture->GetSize();
161+
FML_DCHECK(!texture_size.IsEmpty());
162+
frag_info.half_texel = 0.5f / texture_size.width;
163+
164+
SamplerDescriptor sampler_desc;
165+
sampler_desc.min_filter = MinMagFilter::kLinear;
166+
sampler_desc.mag_filter = MinMagFilter::kLinear;
167+
sampler_binding.texture = params_.gradient->texture;
168+
sampler_binding.sampler =
169+
renderer.GetContext()->GetSamplerLibrary()->GetSampler(sampler_desc);
150170
} else {
151171
sampler_binding.texture = renderer.GetEmptyTexture();
152172
sampler_binding.sampler =
@@ -171,6 +191,50 @@ bool UberSDFContents::Render(const ContentContext& renderer,
171191
});
172192
}
173193

194+
bool UberSDFContents::RenderSSBO(const ContentContext& renderer,
195+
const Entity& entity,
196+
RenderPass& pass) const {
197+
using VS = UberSDFSSBOPipeline::VertexShader;
198+
using FS = UberSDFSSBOPipeline::FragmentShader;
199+
200+
auto& data_host_buffer = renderer.GetTransientsDataBuffer();
201+
202+
VS::FrameInfo frame_info;
203+
FS::FragInfo frag_info;
204+
SetupCommonFragInfo(params_, GetOpacityFactor(), entity, frag_info);
205+
206+
std::vector<StopData> color_stops;
207+
if (params_.gradient) {
208+
color_stops =
209+
CreateGradientColors(params_.gradient->colors, params_.gradient->stops);
210+
} else {
211+
// The bound ColorData is required to be non-empty to be valid. This entry
212+
// is unused in the shader.
213+
color_stops.resize(1);
214+
}
215+
frag_info.colors_length = static_cast<Scalar>(color_stops.size());
216+
217+
BufferView color_buffer = data_host_buffer.Emplace(
218+
color_stops.data(), color_stops.size() * sizeof(StopData),
219+
renderer.GetDeviceCapabilities().GetMinimumStorageBufferAlignment());
220+
221+
PipelineBuilderCallback pipeline_callback =
222+
[&renderer](ContentContextOptions options) {
223+
return renderer.GetUberSDFSSBOPipeline(options);
224+
};
225+
226+
return ColorSourceContents::DrawGeometry<VS>(
227+
this, GetGeometry(), renderer, entity, pass, pipeline_callback,
228+
frame_info,
229+
/*bind_fragment_callback=*/
230+
[&frag_info, &data_host_buffer, &color_buffer](RenderPass& pass) {
231+
FS::BindFragInfo(pass, data_host_buffer.EmplaceUniform(frag_info));
232+
FS::BindColorData(pass, color_buffer);
233+
pass.SetCommandLabel("UberSDFSSBO");
234+
return true;
235+
});
236+
}
237+
174238
std::optional<Rect> UberSDFContents::GetCoverage(const Entity& entity) const {
175239
return GetGeometry()->GetCoverage(entity.GetTransform());
176240
}

‎engine/src/flutter/impeller/entity/contents/uber_sdf_contents.h‎

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,16 @@ class UberSDFContents : public ColorSourceContents {
4444
explicit UberSDFContents(const UberSDFParameters& params,
4545
std::unique_ptr<Geometry> geometry);
4646

47+
/// Renders using a pre-baked gradient ramp texture.
48+
bool RenderTexture(const ContentContext& renderer,
49+
const Entity& entity,
50+
RenderPass& pass) const;
51+
52+
/// Renders using a storage buffer of gradient stops.
53+
bool RenderSSBO(const ContentContext& renderer,
54+
const Entity& entity,
55+
RenderPass& pass) const;
56+
4757
UberSDFParameters params_;
4858
std::unique_ptr<Geometry> geometry_;
4959

‎engine/src/flutter/impeller/entity/contents/uber_sdf_parameters.h‎

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,19 @@ struct UberSDFParameters {
5656
Entity::TileMode tile_mode = Entity::TileMode::kClamp;
5757

5858
/// Texture for gradient ramp.
59+
///
60+
/// Mutually exclusive with `colors`/`stops`.
5961
std::shared_ptr<Texture> texture;
62+
63+
/// The gradient stop colors, unpremultiplied.
64+
///
65+
/// Mutually exclusive with `texture`.
66+
std::vector<Color> colors;
67+
68+
/// The normalized position of each entry in `colors`, in ascending order.
69+
///
70+
/// Always the same length as `colors`.
71+
std::vector<Scalar> stops;
6072
};
6173

6274
/// Creates UberSDFParameters for a rectangle.

0 commit comments

Comments
 (0)