[Impeller] rrect_blur: scale max radius clamp by transform (#161238)

migrated PR https://github.com/flutter/engine/pull/54350

## Pre-launch Checklist

- [x] I read the [Contributor Guide] and followed the process outlined
there for submitting PRs.
- [x] I read the [Tree Hygiene] wiki page, which explains my
responsibilities.
- [x] I read and followed the [Flutter Style Guide], including [Features
we expect every widget to implement].
- [x] I signed the [CLA].
- [x] I listed at least one issue that this PR fixes in the description
above.
- [x] I updated/added relevant documentation (doc comments with `///`).
- [x] I added new tests to check the change I am making, or this PR is
[test-exempt].
- [x] I followed the [breaking change policy] and added [Data Driven
Fixes] where supported.
- [x] All existing and new tests are passing.

If you need help, consider asking for advice on the #hackers-new channel
on [Discord].

<!-- Links -->
[Contributor Guide]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#overview
[Tree Hygiene]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md
[test-exempt]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#tests
[Flutter Style Guide]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md
[Features we expect every widget to implement]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md#features-we-expect-every-widget-to-implement
[CLA]: https://cla.developers.google.com/
[flutter/tests]: https://github.com/flutter/tests
[breaking change policy]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#handling-breaking-changes
[Discord]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Chat.md
[Data Driven Fixes]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Data-driven-Fixes.md
This commit is contained in:
gaaclarke 2025-02-10 11:23:16 -08:00 committed by GitHub
parent a5ed6aea7a
commit 58bc9643b5
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 43 additions and 4 deletions

View File

@ -154,7 +154,6 @@ TEST_P(DlGoldenTest, ShimmerTest) {
TEST_P(DlGoldenTest, StrokedRRectFastBlur) {
impeller::Point content_scale = GetContentScale();
DlRect rect = DlRect::MakeXYWH(50, 50, 100, 100);
DlRoundRect rrect = DlRoundRect::MakeRectRadius(rect, 10.0f);
DlPaint fill = DlPaint().setColor(DlColor::kBlue());
@ -176,5 +175,37 @@ TEST_P(DlGoldenTest, StrokedRRectFastBlur) {
ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
}
// Top left and bottom right circles are expected to be comparable (not exactly
// equal).
// See also: https://github.com/flutter/flutter/issues/152778
TEST_P(DlGoldenTest, LargeDownscaleRrect) {
impeller::Point content_scale = GetContentScale();
auto draw = [&](DlCanvas* canvas, const std::vector<sk_sp<DlImage>>& images) {
canvas->Scale(content_scale.x, content_scale.y);
canvas->DrawColor(DlColor(0xff111111));
{
canvas->Save();
canvas->Scale(0.25, 0.25);
DlPaint paint;
paint.setColor(DlColor::kYellow());
paint.setMaskFilter(
DlBlurMaskFilter::Make(DlBlurStyle::kNormal, /*sigma=*/1000));
canvas->DrawCircle(SkPoint::Make(0, 0), 1200, paint);
canvas->Restore();
}
DlPaint paint;
paint.setColor(DlColor::kYellow());
paint.setMaskFilter(
DlBlurMaskFilter::Make(DlBlurStyle::kNormal, /*sigma=*/250));
canvas->DrawCircle(SkPoint::Make(1024, 768), 300, paint);
};
DisplayListBuilder builder;
draw(&builder, /*images=*/{});
ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
}
} // namespace testing
} // namespace flutter

View File

@ -128,10 +128,15 @@ bool SolidRRectBlurContents::Render(const ContentContext& renderer,
using VS = RRectBlurPipeline::VertexShader;
using FS = RRectBlurPipeline::FragmentShader;
// Clamp the max kernel width/height to 1000 to limit the extent
Matrix basis_invert = entity.GetTransform().Basis().Invert();
Vector2 max_sigmas =
Vector2((basis_invert * Vector2(500.f, 0.f)).GetLength(),
(basis_invert * Vector2(0.f, 500.f)).GetLength());
Scalar max_sigma = std::min(max_sigmas.x, max_sigmas.y);
// Clamp the max kernel width/height to 1000 (@ 2x) to limit the extent
// of the blur and to kEhCloseEnough to prevent NaN calculations
// trying to evaluate a Guassian distribution with a sigma of 0.
Scalar blur_sigma = std::clamp(sigma_.sigma, kEhCloseEnough, 250.0f);
// trying to evaluate a Gaussian distribution with a sigma of 0.
auto blur_sigma = std::clamp(sigma_.sigma, kEhCloseEnough, max_sigma);
// Increase quality by making the radius a bit bigger than the typical
// sigma->radius conversion we use for slower blurs.
Scalar blur_radius = PadForSigma(blur_sigma);

View File

@ -988,6 +988,9 @@ impeller_Play_DlGoldenTest_GaussianVsRRectBlurScaled_Vulkan.png
impeller_Play_DlGoldenTest_GaussianVsRRectBlur_Metal.png
impeller_Play_DlGoldenTest_GaussianVsRRectBlur_OpenGLES.png
impeller_Play_DlGoldenTest_GaussianVsRRectBlur_Vulkan.png
impeller_Play_DlGoldenTest_LargeDownscaleRrect_Metal.png
impeller_Play_DlGoldenTest_LargeDownscaleRrect_OpenGLES.png
impeller_Play_DlGoldenTest_LargeDownscaleRrect_Vulkan.png
impeller_Play_DlGoldenTest_SaveLayerAtFractionalValue_Metal.png
impeller_Play_DlGoldenTest_SaveLayerAtFractionalValue_OpenGLES.png
impeller_Play_DlGoldenTest_SaveLayerAtFractionalValue_Vulkan.png