@@ -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
188195GaussianBlurFilterContents::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