@@ -17,6 +17,17 @@ using GaussianBlurVertexShader = GaussianBlurPipeline::VertexShader;
17
17
using GaussianBlurFragmentShader = GaussianBlurPipeline::FragmentShader;
18
18
19
19
namespace {
20
+
21
+ std::optional<Rect> ExpandCoverageHint (const std::optional<Rect>& coverage_hint,
22
+ const Matrix& source_to_local_transform,
23
+ const Vector2& padding) {
24
+ if (!coverage_hint.has_value ()) {
25
+ return std::nullopt ;
26
+ }
27
+ Vector2 transformed_padding = (source_to_local_transform * padding).Abs ();
28
+ return coverage_hint->Expand (transformed_padding);
29
+ }
30
+
20
31
SamplerDescriptor MakeSamplerDescriptor (MinMagFilter filter,
21
32
SamplerAddressMode address_mode) {
22
33
SamplerDescriptor sampler_desc;
@@ -66,7 +77,8 @@ std::shared_ptr<Texture> MakeDownsampleSubpass(
66
77
frame_info.alpha = 1.0 ;
67
78
68
79
// Insert transparent gutter around the downsampled image so the blur
69
- // creates a halo effect.
80
+ // creates a halo effect. This compensates for when the expanded clip
81
+ // region can't give us the full gutter we want.
70
82
Vector2 texture_size = Vector2 (input_texture->GetSize ());
71
83
Quad vertices =
72
84
MakeAnchorScale ({0.5 , 0.5 },
@@ -106,6 +118,8 @@ std::shared_ptr<Texture> MakeBlurSubpass(
106
118
std::shared_ptr<Texture> input_texture,
107
119
const SamplerDescriptor& sampler_descriptor,
108
120
const GaussianBlurFragmentShader::BlurInfo& blur_info) {
121
+ // TODO(gaaclarke): This blurs the whole image, but because we know the clip
122
+ // region we could focus on just blurring that.
109
123
ISize subpass_size = input_texture->GetSize ();
110
124
ContentContext::SubpassCallback subpass_callback =
111
125
[&](const ContentContext& renderer, RenderPass& pass) {
@@ -201,19 +215,18 @@ std::optional<Entity> GaussianBlurFilterContents::RenderFilter(
201
215
}
202
216
203
217
Scalar blur_radius = CalculateBlurRadius (sigma_);
204
- Scalar desired_scalar = CalculateScale (sigma_);
205
- // TODO(jonahwilliams): if scaling value is 1.0, then skip the downsample
206
- // pass.
207
-
208
- Vector2 downsample_scalar (desired_scalar, desired_scalar);
209
218
Vector2 padding (ceil (blur_radius), ceil (blur_radius));
210
219
211
- std::optional<Rect> expanded_coverage_hint;
212
- if (coverage_hint.has_value ()) {
213
- Matrix transform = entity.GetTransform () * effect_transform.Basis ();
214
- Vector2 transformed_padding = (transform * padding).Abs ();
215
- expanded_coverage_hint = coverage_hint->Expand (transformed_padding);
216
- }
220
+ // Apply as much of the desired padding as possible from the source. This may
221
+ // be ignored so must be accounted for in the downsample pass by adding a
222
+ // transparent gutter.
223
+ std::optional<Rect> expanded_coverage_hint = ExpandCoverageHint (
224
+ coverage_hint, entity.GetTransform () * effect_transform, padding);
225
+ // TODO(gaaclarke): How much of the gutter is thrown away can be used to
226
+ // adjust the padding that is added in the downsample pass.
227
+ // For example, if we get all the padding we requested from
228
+ // the expanded_coverage_hint, there is no need to add a
229
+ // transparent gutter.
217
230
218
231
std::optional<Snapshot> input_snapshot =
219
232
inputs[0 ]->GetSnapshot (" GaussianBlur" , renderer, entity,
@@ -227,6 +240,8 @@ std::optional<Entity> GaussianBlurFilterContents::RenderFilter(
227
240
entity.GetClipDepth ()); // No blur to render.
228
241
}
229
242
243
+ Scalar desired_scalar = CalculateScale (sigma_);
244
+ Vector2 downsample_scalar (desired_scalar, desired_scalar);
230
245
Vector2 padded_size =
231
246
Vector2 (input_snapshot->texture ->GetSize ()) + 2.0 * padding;
232
247
Vector2 downsampled_size = padded_size * downsample_scalar;
0 commit comments