From 5000ea89b5273778e84f18ad3952f2049d1c017a Mon Sep 17 00:00:00 2001 From: Jim Graham Date: Fri, 31 Jan 2025 07:16:29 -0800 Subject: [PATCH] =?UTF-8?q?[Impeller]=20Avoid=20NaN=20values=20when=20sett?= =?UTF-8?q?ing=20up=20for=20the=20fast=20squircle=20blu=E2=80=A6=20(#16248?= =?UTF-8?q?5)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes https://github.com/flutter/flutter/issues/162128 Zero dimensioned rectangle blurs were causing the setup code to generate NaN values. This condition could also happen for some very thin or short rectangles so rather than just rule out zero-dimensioned rectangles, the uniforms are checked for NaN values and the operation is skipped in those cases. --- .../display_list/aiks_dl_blur_unittests.cc | 22 +++++++++++++++++++ .../contents/solid_rrect_blur_contents.cc | 18 ++++++++++++--- .../testing/impeller_golden_tests_output.txt | 1 + 3 files changed, 38 insertions(+), 3 deletions(-) diff --git a/engine/src/flutter/impeller/display_list/aiks_dl_blur_unittests.cc b/engine/src/flutter/impeller/display_list/aiks_dl_blur_unittests.cc index 63a3d5443ac..85215fa176d 100644 --- a/engine/src/flutter/impeller/display_list/aiks_dl_blur_unittests.cc +++ b/engine/src/flutter/impeller/display_list/aiks_dl_blur_unittests.cc @@ -472,6 +472,28 @@ TEST_P(AiksTest, MaskBlurWithZeroSigmaIsSkipped) { ASSERT_TRUE(OpenPlaygroundHere(builder.Build())); } +TEST_P(AiksTest, MaskBlurOnZeroDimensionIsSkippedWideGamut) { + // Making sure this test is run on a wide gamut enabled backend + EXPECT_EQ(GetContext()->GetCapabilities()->GetDefaultColorFormat(), + PixelFormat::kB10G10R10A10XR); + + DisplayListBuilder builder; + builder.DrawColor(DlColor::kWhite(), DlBlendMode::kSrc); + + DlPaint paint; + paint.setColor(DlColor::kBlue()); + paint.setMaskFilter(DlBlurMaskFilter::Make(DlBlurStyle::kNormal, 10)); + + // Zero height above + builder.DrawRect(DlRect::MakeLTRB(100, 250, 500, 250), paint); + // Regular rect + builder.DrawRect(DlRect::MakeLTRB(100, 300, 500, 600), paint); + // Zero width to the right + builder.DrawRect(DlRect::MakeLTRB(550, 300, 550, 600), paint); + + ASSERT_TRUE(OpenPlaygroundHere(builder.Build())); +} + struct MaskBlurTestConfig { DlBlurStyle style = DlBlurStyle::kNormal; Scalar sigma = 1.0f; diff --git a/engine/src/flutter/impeller/entity/contents/solid_rrect_blur_contents.cc b/engine/src/flutter/impeller/entity/contents/solid_rrect_blur_contents.cc index 20f01723587..2e69cff52a3 100644 --- a/engine/src/flutter/impeller/entity/contents/solid_rrect_blur_contents.cc +++ b/engine/src/flutter/impeller/entity/contents/solid_rrect_blur_contents.cc @@ -68,7 +68,7 @@ static Point NegPos(Scalar v) { return {std::min(v, 0.0f), std::max(v, 0.0f)}; } -static void SetupFragInfo( +static bool SetupFragInfo( RRectBlurPipeline::FragmentShader::FragInfo& frag_info, Scalar blurSigma, Point center, @@ -96,6 +96,15 @@ static void SetupFragInfo( frag_info.scale = 0.5 * computeErf7(frag_info.sInv * 0.5 * (std::max(rSize.x, rSize.y) - 0.5 * radius)); + + return frag_info.center.IsFinite() && // + frag_info.adjust.IsFinite() && // + std::isfinite(frag_info.minEdge) && // + std::isfinite(frag_info.r1) && // + std::isfinite(frag_info.exponent) && // + std::isfinite(frag_info.sInv) && // + std::isfinite(frag_info.exponentInv) && // + std::isfinite(frag_info.scale); } std::optional SolidRRectBlurContents::GetCoverage( @@ -159,8 +168,11 @@ bool SolidRRectBlurContents::Render(const ContentContext& renderer, positive_rect.GetWidth() * 0.5f), std::clamp(corner_radii_.height, kEhCloseEnough, positive_rect.GetHeight() * 0.5f)); - SetupFragInfo(frag_info, blur_sigma, positive_rect.GetCenter(), - Point(positive_rect.GetSize()), radius); + if (!SetupFragInfo(frag_info, blur_sigma, positive_rect.GetCenter(), + Point(positive_rect.GetSize()), radius)) { + return true; + } + auto& host_buffer = renderer.GetTransientsBuffer(); pass.SetCommandLabel("RRect Shadow"); pass.SetPipeline(renderer.GetRRectBlurPipeline(opts)); diff --git a/engine/src/flutter/testing/impeller_golden_tests_output.txt b/engine/src/flutter/testing/impeller_golden_tests_output.txt index 65c0616f3c8..7f03adad666 100644 --- a/engine/src/flutter/testing/impeller_golden_tests_output.txt +++ b/engine/src/flutter/testing/impeller_golden_tests_output.txt @@ -799,6 +799,7 @@ impeller_Play_AiksTest_LinearToSrgbFilterSubpassCollapseOptimization_Vulkan.png impeller_Play_AiksTest_MaskBlurDoesntStretchContents_Metal.png impeller_Play_AiksTest_MaskBlurDoesntStretchContents_OpenGLES.png impeller_Play_AiksTest_MaskBlurDoesntStretchContents_Vulkan.png +impeller_Play_AiksTest_MaskBlurOnZeroDimensionIsSkippedWideGamut_Metal.png impeller_Play_AiksTest_MaskBlurTexture_Metal.png impeller_Play_AiksTest_MaskBlurTexture_OpenGLES.png impeller_Play_AiksTest_MaskBlurTexture_Vulkan.png