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..47dadff5c895a 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 * scale; + 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;