From d0d5c3bde8851005944837da499e5ff331e2f144 Mon Sep 17 00:00:00 2001 From: Brandon DeRosier Date: Fri, 19 Aug 2022 17:32:26 -0700 Subject: [PATCH 1/2] Downsample the gaussian blur bidirectionally Stop information loss on first pass Add secondary sigma param to directional gaussian blur --- .../contents/filters/filter_contents.cc | 6 ++-- .../entity/contents/filters/filter_contents.h | 1 + .../filters/gaussian_blur_filter_contents.cc | 36 ++++++++++++------- .../filters/gaussian_blur_filter_contents.h | 3 ++ 4 files changed, 32 insertions(+), 14 deletions(-) diff --git a/impeller/entity/contents/filters/filter_contents.cc b/impeller/entity/contents/filters/filter_contents.cc index 10e3601ea0212..ef5047966e71d 100644 --- a/impeller/entity/contents/filters/filter_contents.cc +++ b/impeller/entity/contents/filters/filter_contents.cc @@ -79,6 +79,7 @@ std::shared_ptr FilterContents::MakeDirectionalGaussianBlur( BlurStyle blur_style, Entity::TileMode tile_mode, FilterInput::Ref source_override, + Sigma secondary_sigma, const Matrix& effect_transform) { auto blur = std::make_shared(); blur->SetInputs({input}); @@ -87,6 +88,7 @@ std::shared_ptr FilterContents::MakeDirectionalGaussianBlur( blur->SetBlurStyle(blur_style); blur->SetTileMode(tile_mode); blur->SetSourceOverride(source_override); + blur->SetSecondarySigma(secondary_sigma); blur->SetEffectTransform(effect_transform); return blur; } @@ -100,10 +102,10 @@ std::shared_ptr FilterContents::MakeGaussianBlur( const Matrix& effect_transform) { auto x_blur = MakeDirectionalGaussianBlur(input, sigma_x, Point(1, 0), BlurStyle::kNormal, tile_mode, - nullptr, effect_transform); + nullptr, {}, effect_transform); auto y_blur = MakeDirectionalGaussianBlur(FilterInput::Make(x_blur), sigma_y, Point(0, 1), blur_style, tile_mode, - input, effect_transform); + input, sigma_x, effect_transform); return y_blur; } diff --git a/impeller/entity/contents/filters/filter_contents.h b/impeller/entity/contents/filters/filter_contents.h index 87333aed8f4f2..acffb71e8e540 100644 --- a/impeller/entity/contents/filters/filter_contents.h +++ b/impeller/entity/contents/filters/filter_contents.h @@ -48,6 +48,7 @@ class FilterContents : public Contents { BlurStyle blur_style = BlurStyle::kNormal, Entity::TileMode tile_mode = Entity::TileMode::kDecal, FilterInput::Ref alpha_mask = nullptr, + Sigma secondary_sigma = {}, const Matrix& effect_transform = Matrix()); static std::shared_ptr MakeGaussianBlur( diff --git a/impeller/entity/contents/filters/gaussian_blur_filter_contents.cc b/impeller/entity/contents/filters/gaussian_blur_filter_contents.cc index ea350055d2f01..b8f604ea55c5c 100644 --- a/impeller/entity/contents/filters/gaussian_blur_filter_contents.cc +++ b/impeller/entity/contents/filters/gaussian_blur_filter_contents.cc @@ -32,6 +32,10 @@ void DirectionalGaussianBlurFilterContents::SetSigma(Sigma sigma) { blur_sigma_ = sigma; } +void DirectionalGaussianBlurFilterContents::SetSecondarySigma(Sigma sigma) { + secondary_blur_sigma_ = sigma; +} + void DirectionalGaussianBlurFilterContents::SetDirection(Vector2 direction) { blur_direction_ = direction.Normalize(); if (blur_direction_.IsZero()) { @@ -221,12 +225,22 @@ std::optional DirectionalGaussianBlurFilterContents::RenderFilter( return pass.AddCommand(cmd); }; - Scalar x_scale = - 1.0 / - std::ceil(std::log2(std::max(2.0f, transformed_blur_radius_length))); - auto scaled_texture_width = pass_texture_rect.size.width * x_scale; - auto out_texture = renderer.MakeSubpass( - ISize(scaled_texture_width, pass_texture_rect.size.height), callback); + Vector2 scale; + { + scale.x = + 1.0 / + std::ceil(std::log2(std::max(2.0f, transformed_blur_radius_length))); + + Scalar y_radius = std::abs(pass_transform.GetDirectionScale(Vector2( + 0, source_override_ ? Radius{secondary_blur_sigma_}.radius : 1))); + scale.y = 1.0 / std::ceil(std::log2(std::max(2.0f, y_radius))); + } + + Vector2 scaled_size(pass_texture_rect.size); + ISize floored_size = ISize(scaled_size.x, scaled_size.y); + + auto out_texture = renderer.MakeSubpass(floored_size, callback); + if (!out_texture) { return std::nullopt; } @@ -238,12 +252,10 @@ std::optional DirectionalGaussianBlurFilterContents::RenderFilter( return Snapshot{ .texture = out_texture, - .transform = texture_rotate.Invert() * - Matrix::MakeTranslation(pass_texture_rect.origin) * - Matrix::MakeScale(Vector2( - (1 / x_scale) * (scaled_texture_width / - std::floor(scaled_texture_width)), - 1)), + .transform = + texture_rotate.Invert() * + Matrix::MakeTranslation(pass_texture_rect.origin) * + Matrix::MakeScale((1 / scale) * (scaled_size / floored_size)), .sampler_descriptor = sampler_desc}; } diff --git a/impeller/entity/contents/filters/gaussian_blur_filter_contents.h b/impeller/entity/contents/filters/gaussian_blur_filter_contents.h index 1e2ec6b3ab544..7c4e44d68ece5 100644 --- a/impeller/entity/contents/filters/gaussian_blur_filter_contents.h +++ b/impeller/entity/contents/filters/gaussian_blur_filter_contents.h @@ -19,6 +19,8 @@ class DirectionalGaussianBlurFilterContents final : public FilterContents { void SetSigma(Sigma sigma); + void SetSecondarySigma(Sigma sigma); + void SetDirection(Vector2 direction); void SetBlurStyle(BlurStyle blur_style); @@ -42,6 +44,7 @@ class DirectionalGaussianBlurFilterContents final : public FilterContents { const Matrix& effect_transform, const Rect& coverage) const override; Sigma blur_sigma_; + Sigma secondary_blur_sigma_; Vector2 blur_direction_; BlurStyle blur_style_ = BlurStyle::kNormal; Entity::TileMode tile_mode_ = Entity::TileMode::kDecal; From 56db52908cdf9eda2f3de1d103169e101028cdad Mon Sep 17 00:00:00 2001 From: Brandon DeRosier Date: Wed, 24 Aug 2022 14:02:05 -0700 Subject: [PATCH 2/2] Fix up blur --- .../entity/contents/filters/gaussian_blur_filter_contents.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/impeller/entity/contents/filters/gaussian_blur_filter_contents.cc b/impeller/entity/contents/filters/gaussian_blur_filter_contents.cc index b8f604ea55c5c..47dadff5c895a 100644 --- a/impeller/entity/contents/filters/gaussian_blur_filter_contents.cc +++ b/impeller/entity/contents/filters/gaussian_blur_filter_contents.cc @@ -236,7 +236,7 @@ std::optional DirectionalGaussianBlurFilterContents::RenderFilter( scale.y = 1.0 / std::ceil(std::log2(std::max(2.0f, y_radius))); } - Vector2 scaled_size(pass_texture_rect.size); + Vector2 scaled_size = pass_texture_rect.size * scale; ISize floored_size = ISize(scaled_size.x, scaled_size.y); auto out_texture = renderer.MakeSubpass(floored_size, callback);