From 4c9f3be164f59aa089f25e505d636dcb555b2b84 Mon Sep 17 00:00:00 2001 From: Aaron Clarke Date: Thu, 30 Nov 2023 08:56:21 -0800 Subject: [PATCH 1/5] [Impeller] Started expanding the clip region (thus implementing proper clipping) --- .../filters/gaussian_blur_filter_contents.cc | 25 ++++++++++++------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/impeller/entity/contents/filters/gaussian_blur_filter_contents.cc b/impeller/entity/contents/filters/gaussian_blur_filter_contents.cc index bcbf85f55e9cd..caa199ffb4071 100644 --- a/impeller/entity/contents/filters/gaussian_blur_filter_contents.cc +++ b/impeller/entity/contents/filters/gaussian_blur_filter_contents.cc @@ -200,9 +200,24 @@ std::optional GaussianBlurFilterContents::RenderFilter( return std::nullopt; } + Scalar blur_radius = CalculateBlurRadius(sigma_); + Scalar desired_scalar = CalculateScale(sigma_); + // TODO(jonahwilliams): if scaling value is 1.0, then skip the downsample + // pass. + + Vector2 downsample_scalar(desired_scalar, desired_scalar); + Vector2 padding(ceil(blur_radius), ceil(blur_radius)); + + std::optional expanded_coverage_hint; + if (coverage_hint.has_value()) { + Matrix transform = entity.GetTransform() * effect_transform.Basis(); + Vector2 transformed_padding = (transform * padding).Abs(); + expanded_coverage_hint = coverage_hint->Expand(transformed_padding); + } + std::optional input_snapshot = inputs[0]->GetSnapshot("GaussianBlur", renderer, entity, - /*coverage_limit=*/coverage_hint); + /*coverage_limit=*/expanded_coverage_hint); if (!input_snapshot.has_value()) { return std::nullopt; } @@ -212,14 +227,6 @@ std::optional GaussianBlurFilterContents::RenderFilter( entity.GetClipDepth()); // No blur to render. } - Scalar blur_radius = CalculateBlurRadius(sigma_); - Scalar desired_scalar = CalculateScale(sigma_); - // TODO(jonahwilliams): if scaling value is 1.0, then skip the downsample - // pass. - - Vector2 downsample_scalar(desired_scalar, desired_scalar); - Vector2 padding(ceil(blur_radius), ceil(blur_radius)); - Vector2 padded_size = Vector2(input_snapshot->texture->GetSize()) + 2.0 * padding; Vector2 downsampled_size = padded_size * downsample_scalar; From 3f6ee319f34ba655e08059cac20b20715974abda Mon Sep 17 00:00:00 2001 From: Aaron Clarke Date: Thu, 30 Nov 2023 09:43:53 -0800 Subject: [PATCH 2/5] cleanup --- .../contents/filters/filter_contents.cc | 2 + .../filters/gaussian_blur_filter_contents.cc | 39 +++++++++++++------ 2 files changed, 29 insertions(+), 12 deletions(-) diff --git a/impeller/entity/contents/filters/filter_contents.cc b/impeller/entity/contents/filters/filter_contents.cc index 27b2bd77dc404..4e9347498031e 100644 --- a/impeller/entity/contents/filters/filter_contents.cc +++ b/impeller/entity/contents/filters/filter_contents.cc @@ -50,6 +50,8 @@ std::shared_ptr FilterContents::MakeDirectionalGaussianBlur( return blur; } +#define IMPELLER_ENABLE_NEW_GAUSSIAN_FILTER 1 + std::shared_ptr FilterContents::MakeGaussianBlur( const FilterInput::Ref& input, Sigma sigma_x, diff --git a/impeller/entity/contents/filters/gaussian_blur_filter_contents.cc b/impeller/entity/contents/filters/gaussian_blur_filter_contents.cc index caa199ffb4071..70bffd2486f7d 100644 --- a/impeller/entity/contents/filters/gaussian_blur_filter_contents.cc +++ b/impeller/entity/contents/filters/gaussian_blur_filter_contents.cc @@ -17,6 +17,17 @@ using GaussianBlurVertexShader = GaussianBlurPipeline::VertexShader; using GaussianBlurFragmentShader = GaussianBlurPipeline::FragmentShader; namespace { + +std::optional ExpandCoverageHint(const std::optional& coverage_hint, + const Matrix& source_to_local_transform, + const Vector2& padding) { + if (!coverage_hint.has_value()) { + return std::nullopt; + } + Vector2 transformed_padding = (source_to_local_transform * padding).Abs(); + return coverage_hint->Expand(transformed_padding); +} + SamplerDescriptor MakeSamplerDescriptor(MinMagFilter filter, SamplerAddressMode address_mode) { SamplerDescriptor sampler_desc; @@ -66,7 +77,8 @@ std::shared_ptr MakeDownsampleSubpass( frame_info.alpha = 1.0; // Insert transparent gutter around the downsampled image so the blur - // creates a halo effect. + // creates a halo effect. This compensates for when the expanded clip + // region can't give us the full gutter we want. Vector2 texture_size = Vector2(input_texture->GetSize()); Quad vertices = MakeAnchorScale({0.5, 0.5}, @@ -106,6 +118,8 @@ std::shared_ptr MakeBlurSubpass( std::shared_ptr input_texture, const SamplerDescriptor& sampler_descriptor, const GaussianBlurFragmentShader::BlurInfo& blur_info) { + // TODO(gaaclarke): This blurs the whole image, but because we know the clip + // region we could focus on just blurring that. ISize subpass_size = input_texture->GetSize(); ContentContext::SubpassCallback subpass_callback = [&](const ContentContext& renderer, RenderPass& pass) { @@ -201,19 +215,18 @@ std::optional GaussianBlurFilterContents::RenderFilter( } Scalar blur_radius = CalculateBlurRadius(sigma_); - Scalar desired_scalar = CalculateScale(sigma_); - // TODO(jonahwilliams): if scaling value is 1.0, then skip the downsample - // pass. - - Vector2 downsample_scalar(desired_scalar, desired_scalar); Vector2 padding(ceil(blur_radius), ceil(blur_radius)); - std::optional expanded_coverage_hint; - if (coverage_hint.has_value()) { - Matrix transform = entity.GetTransform() * effect_transform.Basis(); - Vector2 transformed_padding = (transform * padding).Abs(); - expanded_coverage_hint = coverage_hint->Expand(transformed_padding); - } + // Apply as much of the desired padding as possible from the source. This may + // be ignored so must be accounted for in the downsample pass by adding a + // transparent gutter. + std::optional expanded_coverage_hint = ExpandCoverageHint( + coverage_hint, entity.GetTransform() * effect_transform, padding); + // TODO(gaaclarke): How much of the gutter is thrown away can be used to + // adjust the padding that is added in the downsample pass. + // For example, if we get all the padding we requested from + // the expanded_coverage_hint, there is no need to add a + // transparent gutter. std::optional input_snapshot = inputs[0]->GetSnapshot("GaussianBlur", renderer, entity, @@ -227,6 +240,8 @@ std::optional GaussianBlurFilterContents::RenderFilter( entity.GetClipDepth()); // No blur to render. } + Scalar desired_scalar = CalculateScale(sigma_); + Vector2 downsample_scalar(desired_scalar, desired_scalar); Vector2 padded_size = Vector2(input_snapshot->texture->GetSize()) + 2.0 * padding; Vector2 downsampled_size = padded_size * downsample_scalar; From e1b467519993960cbcd610c4ff95cd460275aee5 Mon Sep 17 00:00:00 2001 From: Aaron Clarke Date: Thu, 30 Nov 2023 09:46:48 -0800 Subject: [PATCH 3/5] remove stray define --- impeller/entity/contents/filters/filter_contents.cc | 2 -- 1 file changed, 2 deletions(-) diff --git a/impeller/entity/contents/filters/filter_contents.cc b/impeller/entity/contents/filters/filter_contents.cc index 4e9347498031e..27b2bd77dc404 100644 --- a/impeller/entity/contents/filters/filter_contents.cc +++ b/impeller/entity/contents/filters/filter_contents.cc @@ -50,8 +50,6 @@ std::shared_ptr FilterContents::MakeDirectionalGaussianBlur( return blur; } -#define IMPELLER_ENABLE_NEW_GAUSSIAN_FILTER 1 - std::shared_ptr FilterContents::MakeGaussianBlur( const FilterInput::Ref& input, Sigma sigma_x, From b035cd100dd07c82350e2d82b79d6fe63883c4ed Mon Sep 17 00:00:00 2001 From: Aaron Clarke Date: Thu, 30 Nov 2023 09:50:25 -0800 Subject: [PATCH 4/5] added docstring --- .../entity/contents/filters/gaussian_blur_filter_contents.cc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/impeller/entity/contents/filters/gaussian_blur_filter_contents.cc b/impeller/entity/contents/filters/gaussian_blur_filter_contents.cc index 70bffd2486f7d..a6c92e2513921 100644 --- a/impeller/entity/contents/filters/gaussian_blur_filter_contents.cc +++ b/impeller/entity/contents/filters/gaussian_blur_filter_contents.cc @@ -54,6 +54,8 @@ Matrix MakeAnchorScale(const Point& anchor, Vector2 scale) { Matrix::MakeTranslation({-anchor.x, -anchor.y, 0}); } +/// Makes a subpass that will render the scaled down input and add the +/// transparent gutter required for the blur halo. std::shared_ptr MakeDownsampleSubpass( const ContentContext& renderer, std::shared_ptr input_texture, From f90e5809bfc23d3168aca88e336ab9618f336353 Mon Sep 17 00:00:00 2001 From: Aaron Clarke Date: Thu, 30 Nov 2023 09:53:16 -0800 Subject: [PATCH 5/5] updated jonahs comment --- .../entity/contents/filters/gaussian_blur_filter_contents.cc | 3 +++ 1 file changed, 3 insertions(+) diff --git a/impeller/entity/contents/filters/gaussian_blur_filter_contents.cc b/impeller/entity/contents/filters/gaussian_blur_filter_contents.cc index a6c92e2513921..7b8f01cc90ab6 100644 --- a/impeller/entity/contents/filters/gaussian_blur_filter_contents.cc +++ b/impeller/entity/contents/filters/gaussian_blur_filter_contents.cc @@ -243,6 +243,9 @@ std::optional GaussianBlurFilterContents::RenderFilter( } Scalar desired_scalar = CalculateScale(sigma_); + // TODO(jonahwilliams): If desired_scalar is 1.0 and we fully acquired the + // gutter from the expanded_coverage_hint, we can skip the downsample pass. + // pass. Vector2 downsample_scalar(desired_scalar, desired_scalar); Vector2 padded_size = Vector2(input_snapshot->texture->GetSize()) + 2.0 * padding;