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

Commit 7b34ed1

Browse files
committed
[Impeller] limit blur uvs to the clip region
1 parent c372642 commit 7b34ed1

File tree

2 files changed

+32
-7
lines changed

2 files changed

+32
-7
lines changed

impeller/entity/contents/filters/filter_contents.cc

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,8 @@ std::shared_ptr<FilterContents> FilterContents::MakeDirectionalGaussianBlur(
5050
return blur;
5151
}
5252

53+
#define IMPELLER_ENABLE_NEW_GAUSSIAN_FILTER 1
54+
5355
std::shared_ptr<FilterContents> FilterContents::MakeGaussianBlur(
5456
const FilterInput::Ref& input,
5557
Sigma sigma_x,

impeller/entity/contents/filters/gaussian_blur_filter_contents.cc

Lines changed: 30 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(
@@ -268,6 +275,7 @@ std::optional<Entity> GaussianBlurFilterContents::RenderFilter(
268275
if (!input_snapshot.has_value()) {
269276
return std::nullopt;
270277
}
278+
std::optional<Rect> input_snapshot_coverage = input_snapshot->GetCoverage();
271279

272280
if (scaled_sigma.x < kEhCloseEnough && scaled_sigma.y < kEhCloseEnough) {
273281
return Entity::FromSnapshot(input_snapshot.value(), entity.GetBlendMode(),
@@ -311,6 +319,21 @@ std::optional<Entity> GaussianBlurFilterContents::RenderFilter(
311319
Vector2 pass1_pixel_size =
312320
1.0 / Vector2(pass1_out.value().GetRenderTargetTexture()->GetSize());
313321

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+
std::optional<Rect> uvs = MakeReferenceUVs(input_snapshot_coverage.value(),
326+
expanded_coverage_hint.value())
327+
.Intersection(Rect::MakeSize(Size(1, 1)));
328+
FML_DCHECK(uvs.has_value());
329+
if (uvs.has_value()) {
330+
blur_uvs[0] = uvs->GetLeftTop();
331+
blur_uvs[1] = uvs->GetRightTop();
332+
blur_uvs[2] = uvs->GetLeftBottom();
333+
blur_uvs[3] = uvs->GetRightBottom();
334+
}
335+
}
336+
314337
fml::StatusOr<RenderTarget> pass2_out =
315338
MakeBlurSubpass(renderer, /*input_pass=*/pass1_out.value(),
316339
input_snapshot->sampler_descriptor, tile_mode_,
@@ -320,7 +343,7 @@ std::optional<Entity> GaussianBlurFilterContents::RenderFilter(
320343
.blur_radius = blur_radius.y * effective_scalar.y,
321344
.step_size = 1.0,
322345
},
323-
/*destination_texture=*/std::nullopt);
346+
/*destination_texture=*/std::nullopt, blur_uvs);
324347

325348
if (!pass2_out.ok()) {
326349
return std::nullopt;
@@ -341,7 +364,7 @@ std::optional<Entity> GaussianBlurFilterContents::RenderFilter(
341364
.blur_radius = blur_radius.x * effective_scalar.x,
342365
.step_size = 1.0,
343366
},
344-
pass3_destination);
367+
pass3_destination, blur_uvs);
345368

346369
if (!pass3_out.ok()) {
347370
return std::nullopt;

0 commit comments

Comments
 (0)