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

Commit ed59191

Browse files
authored
Revert "[Impeller] new blur: refactored math and fixed expanded padding size" (#49298)
Reverts #49206
1 parent 7b6227f commit ed59191

File tree

4 files changed

+65
-44
lines changed

4 files changed

+65
-44
lines changed

impeller/aiks/aiks_unittests.cc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3976,5 +3976,6 @@ TEST_P(AiksTest, SubpassWithClearColorOptimization) {
39763976
// will be filled with NaNs and may produce a magenta texture on macOS or iOS.
39773977
ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
39783978
}
3979+
39793980
} // namespace testing
39803981
} // namespace impeller

impeller/entity/contents/filters/gaussian_blur_filter_contents.cc

Lines changed: 60 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,16 @@ using GaussianBlurFragmentShader = GaussianBlurPipeline::FragmentShader;
1919

2020
namespace {
2121

22+
std::optional<Rect> ExpandCoverageHint(const std::optional<Rect>& coverage_hint,
23+
const Matrix& source_to_local_transform,
24+
const Vector2& padding) {
25+
if (!coverage_hint.has_value()) {
26+
return std::nullopt;
27+
}
28+
Vector2 transformed_padding = (source_to_local_transform * padding).Abs();
29+
return coverage_hint->Expand(transformed_padding);
30+
}
31+
2232
SamplerDescriptor MakeSamplerDescriptor(MinMagFilter filter,
2333
SamplerAddressMode address_mode) {
2434
SamplerDescriptor sampler_desc;
@@ -38,6 +48,12 @@ void BindVertices(Command& cmd,
3848
cmd.BindVertices(vtx_builder.CreateVertexBuffer(host_buffer));
3949
}
4050

51+
Matrix MakeAnchorScale(const Point& anchor, Vector2 scale) {
52+
return Matrix::MakeTranslation({anchor.x, anchor.y, 0}) *
53+
Matrix::MakeScale(scale) *
54+
Matrix::MakeTranslation({-anchor.x, -anchor.y, 0});
55+
}
56+
4157
void SetTileMode(SamplerDescriptor* descriptor,
4258
const ContentContext& renderer,
4359
Entity::TileMode tile_mode) {
@@ -71,6 +87,7 @@ std::shared_ptr<Texture> MakeDownsampleSubpass(
7187
const SamplerDescriptor& sampler_descriptor,
7288
const Quad& uvs,
7389
const ISize& subpass_size,
90+
const Vector2 padding,
7491
Entity::TileMode tile_mode) {
7592
ContentContext::SubpassCallback subpass_callback =
7693
[&](const ContentContext& renderer, RenderPass& pass) {
@@ -87,13 +104,23 @@ std::shared_ptr<Texture> MakeDownsampleSubpass(
87104
frame_info.texture_sampler_y_coord_scale = 1.0;
88105
frame_info.alpha = 1.0;
89106

90-
BindVertices<TextureFillVertexShader>(cmd, host_buffer,
91-
{
92-
{Point(0, 0), uvs[0]},
93-
{Point(1, 0), uvs[1]},
94-
{Point(0, 1), uvs[2]},
95-
{Point(1, 1), uvs[3]},
96-
});
107+
// Insert transparent gutter around the downsampled image so the blur
108+
// creates a halo effect. This compensates for when the expanded clip
109+
// region can't give us the full gutter we want.
110+
Vector2 texture_size = Vector2(input_texture->GetSize());
111+
Quad guttered_uvs =
112+
MakeAnchorScale({0.5, 0.5},
113+
(texture_size + padding * 2) / texture_size)
114+
.Transform(uvs);
115+
116+
BindVertices<TextureFillVertexShader>(
117+
cmd, host_buffer,
118+
{
119+
{Point(0, 0), guttered_uvs[0]},
120+
{Point(1, 0), guttered_uvs[1]},
121+
{Point(0, 1), guttered_uvs[2]},
122+
{Point(1, 1), guttered_uvs[3]},
123+
});
97124

98125
SamplerDescriptor linear_sampler_descriptor = sampler_descriptor;
99126
SetTileMode(&linear_sampler_descriptor, renderer, tile_mode);
@@ -243,17 +270,17 @@ std::optional<Entity> GaussianBlurFilterContents::RenderFilter(
243270
Vector2 blur_radius = {CalculateBlurRadius(scaled_sigma.x),
244271
CalculateBlurRadius(scaled_sigma.y)};
245272
Vector2 padding(ceil(blur_radius.x), ceil(blur_radius.y));
246-
Vector2 local_padding =
247-
(entity.GetTransform().Basis() * effect_transform.Basis() * padding)
248-
.Abs();
249273

250274
// Apply as much of the desired padding as possible from the source. This may
251275
// be ignored so must be accounted for in the downsample pass by adding a
252276
// transparent gutter.
253-
std::optional<Rect> expanded_coverage_hint;
254-
if (coverage_hint.has_value()) {
255-
expanded_coverage_hint = coverage_hint->Expand(local_padding);
256-
}
277+
std::optional<Rect> expanded_coverage_hint = ExpandCoverageHint(
278+
coverage_hint, entity.GetTransform() * effect_transform, padding);
279+
// TODO(gaaclarke): How much of the gutter is thrown away can be used to
280+
// adjust the padding that is added in the downsample pass.
281+
// For example, if we get all the padding we requested from
282+
// the expanded_coverage_hint, there is no need to add a
283+
// transparent gutter.
257284

258285
std::optional<Snapshot> input_snapshot =
259286
inputs[0]->GetSnapshot("GaussianBlur", renderer, entity,
@@ -273,28 +300,21 @@ std::optional<Entity> GaussianBlurFilterContents::RenderFilter(
273300
// gutter from the expanded_coverage_hint, we can skip the downsample pass.
274301
// pass.
275302
Vector2 downsample_scalar(desired_scalar, desired_scalar);
276-
Rect source_rect = Rect::MakeSize(input_snapshot->texture->GetSize());
277-
Rect source_rect_padded = source_rect.Expand(padding);
278-
Matrix padding_snapshot_adjustment = Matrix::MakeTranslation(-padding);
279-
// TODO(gaaclarke): The padding could be removed if we know it's not needed or
280-
// resized to account for the expanded_clip_coverage. There doesn't appear
281-
// to be the math to make those calculations though. The following
282-
// optimization works, but causes a shimmer as a result of
283-
// https://github.com/flutter/flutter/issues/140193 so it isn't applied.
284-
//
285-
// !input_snapshot->GetCoverage()->Expand(-local_padding)
286-
// .Contains(coverage_hint.value()))
287-
Vector2 downsampled_size = source_rect_padded.size * downsample_scalar;
303+
Vector2 padded_size =
304+
Vector2(input_snapshot->texture->GetSize()) + 2.0 * padding;
305+
Vector2 downsampled_size = padded_size * downsample_scalar;
306+
// TODO(gaaclarke): I don't think we are correctly handling this fractional
307+
// amount we are throwing away.
288308
ISize subpass_size =
289309
ISize(round(downsampled_size.x), round(downsampled_size.y));
290-
Vector2 effective_scalar = Vector2(subpass_size) / source_rect_padded.size;
310+
Vector2 effective_scalar = subpass_size / padded_size;
291311

292-
Quad uvs = CalculateUVs(inputs[0], entity, source_rect_padded,
293-
input_snapshot->texture->GetSize());
312+
Quad uvs =
313+
CalculateUVs(inputs[0], entity, input_snapshot->texture->GetSize());
294314

295315
std::shared_ptr<Texture> pass1_out_texture = MakeDownsampleSubpass(
296316
renderer, input_snapshot->texture, input_snapshot->sampler_descriptor,
297-
uvs, subpass_size, tile_mode_);
317+
uvs, subpass_size, padding, tile_mode_);
298318

299319
Vector2 pass1_pixel_size = 1.0 / Vector2(pass1_out_texture->GetSize());
300320

@@ -323,12 +343,13 @@ std::optional<Entity> GaussianBlurFilterContents::RenderFilter(
323343
MinMagFilter::kLinear, SamplerAddressMode::kClampToEdge);
324344

325345
return Entity::FromSnapshot(
326-
Snapshot{.texture = pass3_out_texture,
327-
.transform = input_snapshot->transform *
328-
padding_snapshot_adjustment *
329-
Matrix::MakeScale(1 / effective_scalar),
330-
.sampler_descriptor = sampler_desc,
331-
.opacity = input_snapshot->opacity},
346+
Snapshot{
347+
.texture = pass3_out_texture,
348+
.transform = input_snapshot->transform *
349+
Matrix::MakeTranslation({-padding.x, -padding.y, 0}) *
350+
Matrix::MakeScale(1 / effective_scalar),
351+
.sampler_descriptor = sampler_desc,
352+
.opacity = input_snapshot->opacity},
332353
entity.GetBlendMode(), entity.GetClipDepth());
333354
}
334355

@@ -339,10 +360,11 @@ Scalar GaussianBlurFilterContents::CalculateBlurRadius(Scalar sigma) {
339360
Quad GaussianBlurFilterContents::CalculateUVs(
340361
const std::shared_ptr<FilterInput>& filter_input,
341362
const Entity& entity,
342-
const Rect& source_rect,
343363
const ISize& texture_size) {
344364
Matrix input_transform = filter_input->GetLocalTransform(entity);
345-
Quad coverage_quad = source_rect.GetTransformedPoints(input_transform);
365+
Rect snapshot_rect =
366+
Rect::MakeXYWH(0, 0, texture_size.width, texture_size.height);
367+
Quad coverage_quad = snapshot_rect.GetTransformedPoints(input_transform);
346368

347369
Matrix uv_transform = Matrix::MakeScale(
348370
{1.0f / texture_size.width, 1.0f / texture_size.height, 1.0f});

impeller/entity/contents/filters/gaussian_blur_filter_contents.h

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -41,12 +41,10 @@ class GaussianBlurFilterContents final : public FilterContents {
4141
/// Calculate the UV coordinates for rendering the filter_input.
4242
/// @param filter_input The FilterInput that should be rendered.
4343
/// @param entity The associated entity for the filter_input.
44-
/// @param source_rect The rect in source coordinates to convert to uvs.
45-
/// @param texture_size The rect to convert in source coordinates.
44+
/// @param texture_size The size of the texture_size the uvs will be used for.
4645
static Quad CalculateUVs(const std::shared_ptr<FilterInput>& filter_input,
4746
const Entity& entity,
48-
const Rect& source_rect,
49-
const ISize& texture_size);
47+
const ISize& pass_size);
5048

5149
/// Calculate the scale factor for the downsample pass given a sigma value.
5250
///

impeller/entity/contents/filters/gaussian_blur_filter_contents_unittests.cc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -285,8 +285,8 @@ TEST_P(GaussianBlurFilterContentsTest, CalculateUVsSimple) {
285285
std::shared_ptr<Texture> texture = MakeTexture(desc);
286286
auto filter_input = FilterInput::Make(texture);
287287
Entity entity;
288-
Quad uvs = GaussianBlurFilterContents::CalculateUVs(
289-
filter_input, entity, Rect::MakeSize(ISize(100, 100)), ISize(100, 100));
288+
Quad uvs = GaussianBlurFilterContents::CalculateUVs(filter_input, entity,
289+
ISize(100, 100));
290290
std::optional<Rect> uvs_bounds = Rect::MakePointBounds(uvs);
291291
EXPECT_TRUE(uvs_bounds.has_value());
292292
if (uvs_bounds.has_value()) {

0 commit comments

Comments
 (0)