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

Commit 2e606f4

Browse files
committed
Reapply "[Impeller] new blur: refactored math and fixed expanded padding size (#49206)"
This reverts commit 8b9a0bb.
1 parent 75f3a9c commit 2e606f4

File tree

4 files changed

+44
-65
lines changed

4 files changed

+44
-65
lines changed

impeller/aiks/aiks_unittests.cc

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3976,6 +3976,5 @@ 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-
39803979
} // namespace testing
39813980
} // namespace impeller

impeller/entity/contents/filters/gaussian_blur_filter_contents.cc

Lines changed: 38 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -19,16 +19,6 @@ 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-
3222
SamplerDescriptor MakeSamplerDescriptor(MinMagFilter filter,
3323
SamplerAddressMode address_mode) {
3424
SamplerDescriptor sampler_desc;
@@ -48,12 +38,6 @@ void BindVertices(Command& cmd,
4838
cmd.BindVertices(vtx_builder.CreateVertexBuffer(host_buffer));
4939
}
5040

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-
5741
void SetTileMode(SamplerDescriptor* descriptor,
5842
const ContentContext& renderer,
5943
Entity::TileMode tile_mode) {
@@ -87,7 +71,6 @@ std::shared_ptr<Texture> MakeDownsampleSubpass(
8771
const SamplerDescriptor& sampler_descriptor,
8872
const Quad& uvs,
8973
const ISize& subpass_size,
90-
const Vector2 padding,
9174
Entity::TileMode tile_mode) {
9275
ContentContext::SubpassCallback subpass_callback =
9376
[&](const ContentContext& renderer, RenderPass& pass) {
@@ -104,23 +87,13 @@ std::shared_ptr<Texture> MakeDownsampleSubpass(
10487
frame_info.texture_sampler_y_coord_scale = 1.0;
10588
frame_info.alpha = 1.0;
10689

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-
});
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+
});
12497

12598
SamplerDescriptor linear_sampler_descriptor = sampler_descriptor;
12699
SetTileMode(&linear_sampler_descriptor, renderer, tile_mode);
@@ -270,17 +243,17 @@ std::optional<Entity> GaussianBlurFilterContents::RenderFilter(
270243
Vector2 blur_radius = {CalculateBlurRadius(scaled_sigma.x),
271244
CalculateBlurRadius(scaled_sigma.y)};
272245
Vector2 padding(ceil(blur_radius.x), ceil(blur_radius.y));
246+
Vector2 local_padding =
247+
(entity.GetTransform().Basis() * effect_transform.Basis() * padding)
248+
.Abs();
273249

274250
// Apply as much of the desired padding as possible from the source. This may
275251
// be ignored so must be accounted for in the downsample pass by adding a
276252
// transparent gutter.
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.
253+
std::optional<Rect> expanded_coverage_hint;
254+
if (coverage_hint.has_value()) {
255+
expanded_coverage_hint = coverage_hint->Expand(local_padding);
256+
}
284257

285258
std::optional<Snapshot> input_snapshot =
286259
inputs[0]->GetSnapshot("GaussianBlur", renderer, entity,
@@ -300,21 +273,28 @@ std::optional<Entity> GaussianBlurFilterContents::RenderFilter(
300273
// gutter from the expanded_coverage_hint, we can skip the downsample pass.
301274
// pass.
302275
Vector2 downsample_scalar(desired_scalar, desired_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.
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;
308288
ISize subpass_size =
309289
ISize(round(downsampled_size.x), round(downsampled_size.y));
310-
Vector2 effective_scalar = subpass_size / padded_size;
290+
Vector2 effective_scalar = Vector2(subpass_size) / source_rect_padded.size;
311291

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

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

319299
Vector2 pass1_pixel_size = 1.0 / Vector2(pass1_out_texture->GetSize());
320300

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

345325
return Entity::FromSnapshot(
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},
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},
353332
entity.GetBlendMode(), entity.GetClipDepth());
354333
}
355334

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

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

impeller/entity/contents/filters/gaussian_blur_filter_contents.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,10 +41,12 @@ 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 texture_size The size of the texture_size the uvs will be used for.
44+
/// @param source_rect The rect in source coordinates to convert to uvs.
45+
/// @param texture_size The rect to convert in source coordinates.
4546
static Quad CalculateUVs(const std::shared_ptr<FilterInput>& filter_input,
4647
const Entity& entity,
47-
const ISize& pass_size);
48+
const Rect& source_rect,
49+
const ISize& texture_size);
4850

4951
/// Calculate the scale factor for the downsample pass given a sigma value.
5052
///

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(filter_input, entity,
289-
ISize(100, 100));
288+
Quad uvs = GaussianBlurFilterContents::CalculateUVs(
289+
filter_input, entity, Rect::MakeSize(ISize(100, 100)), 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)