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

Commit 5b723f0

Browse files
committed
[Impeller] limit blur uvs to the clip region
1 parent 9d89f87 commit 5b723f0

File tree

1 file changed

+37
-7
lines changed

1 file changed

+37
-7
lines changed

impeller/entity/contents/filters/gaussian_blur_filter_contents.cc

Lines changed: 37 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,8 @@ fml::StatusOr<RenderTarget> MakeBlurSubpass(
121121
const SamplerDescriptor& sampler_descriptor,
122122
Entity::TileMode tile_mode,
123123
const GaussianBlurFragmentShader::BlurInfo& blur_info,
124-
std::optional<RenderTarget> destination_target) {
124+
std::optional<RenderTarget> destination_target,
125+
const Quad& blur_uvs) {
125126
if (blur_info.blur_sigma < kEhCloseEnough) {
126127
return input_pass;
127128
}
@@ -153,10 +154,10 @@ fml::StatusOr<RenderTarget> MakeBlurSubpass(
153154

154155
BindVertices<GaussianBlurVertexShader>(cmd, host_buffer,
155156
{
156-
{Point(0, 0), Point(0, 0)},
157-
{Point(1, 0), Point(1, 0)},
158-
{Point(0, 1), Point(0, 1)},
159-
{Point(1, 1), Point(1, 1)},
157+
{blur_uvs[0], blur_uvs[0]},
158+
{blur_uvs[1], blur_uvs[1]},
159+
{blur_uvs[2], blur_uvs[2]},
160+
{blur_uvs[3], blur_uvs[3]},
160161
});
161162

162163
SamplerDescriptor linear_sampler_descriptor = sampler_descriptor;
@@ -183,6 +184,12 @@ fml::StatusOr<RenderTarget> MakeBlurSubpass(
183184
}
184185
}
185186

187+
Rect MakeReferenceUVs(const Rect& reference, const Rect& rect) {
188+
Rect result = Rect::MakeOriginSize(rect.GetOrigin() - reference.GetOrigin(),
189+
rect.GetSize());
190+
return result.Scale(1.0f / Vector2(reference.GetSize()));
191+
}
192+
186193
} // namespace
187194

188195
GaussianBlurFilterContents::GaussianBlurFilterContents(
@@ -311,6 +318,29 @@ std::optional<Entity> GaussianBlurFilterContents::RenderFilter(
311318
Vector2 pass1_pixel_size =
312319
1.0 / Vector2(pass1_out.value().GetRenderTargetTexture()->GetSize());
313320

321+
std::optional<Rect> input_snapshot_coverage = input_snapshot->GetCoverage();
322+
Quad blur_uvs = {Point(0, 0), Point(1, 0), Point(0, 1), Point(1, 1)};
323+
if (expanded_coverage_hint.has_value() &&
324+
input_snapshot_coverage.has_value() &&
325+
// TODO(tbd): Remove this condition. There is some flaw in coverage
326+
// stopping us from using this today. I attempted to use source
327+
// coordinates to calculate the uvs, but that didn't work
328+
// either
329+
// (https://github.com/flutter/engine/pull/49299#issuecomment-1865311438).
330+
input_snapshot.has_value() &&
331+
input_snapshot.value().transform.IsTranslationScaleOnly()) {
332+
// Only process the uvs where the blur is happening, not the whole texture.
333+
std::optional<Rect> uvs = MakeReferenceUVs(input_snapshot_coverage.value(),
334+
expanded_coverage_hint.value())
335+
.Intersection(Rect::MakeSize(Size(1, 1)));
336+
if (uvs.has_value()) {
337+
blur_uvs[0] = uvs->GetLeftTop();
338+
blur_uvs[1] = uvs->GetRightTop();
339+
blur_uvs[2] = uvs->GetLeftBottom();
340+
blur_uvs[3] = uvs->GetRightBottom();
341+
}
342+
}
343+
314344
fml::StatusOr<RenderTarget> pass2_out =
315345
MakeBlurSubpass(renderer, /*input_pass=*/pass1_out.value(),
316346
input_snapshot->sampler_descriptor, tile_mode_,
@@ -320,7 +350,7 @@ std::optional<Entity> GaussianBlurFilterContents::RenderFilter(
320350
.blur_radius = blur_radius.y * effective_scalar.y,
321351
.step_size = 1.0,
322352
},
323-
/*destination_target=*/std::nullopt);
353+
/*destination_target=*/std::nullopt, blur_uvs);
324354

325355
if (!pass2_out.ok()) {
326356
return std::nullopt;
@@ -341,7 +371,7 @@ std::optional<Entity> GaussianBlurFilterContents::RenderFilter(
341371
.blur_radius = blur_radius.x * effective_scalar.x,
342372
.step_size = 1.0,
343373
},
344-
pass3_destination);
374+
pass3_destination, blur_uvs);
345375

346376
if (!pass3_out.ok()) {
347377
return std::nullopt;

0 commit comments

Comments
 (0)