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 d4d25943552..599c46ea44b 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 @@ -470,6 +470,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 25d50268e03..d1af556ad96 100644 --- a/engine/src/flutter/testing/impeller_golden_tests_output.txt +++ b/engine/src/flutter/testing/impeller_golden_tests_output.txt @@ -802,6 +802,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