Skip to content

Commit e6185c3

Browse files
authored
[Impeller] Avoid NaN values when setting up for the fast squircle blur shader (#162421)
Fixes flutter/flutter#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.
1 parent 01a9aec commit e6185c3

File tree

3 files changed

+38
-3
lines changed

3 files changed

+38
-3
lines changed

engine/src/flutter/impeller/display_list/aiks_dl_blur_unittests.cc

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -470,6 +470,28 @@ TEST_P(AiksTest, MaskBlurWithZeroSigmaIsSkipped) {
470470
ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
471471
}
472472

473+
TEST_P(AiksTest, MaskBlurOnZeroDimensionIsSkippedWideGamut) {
474+
// Making sure this test is run on a wide gamut enabled backend
475+
EXPECT_EQ(GetContext()->GetCapabilities()->GetDefaultColorFormat(),
476+
PixelFormat::kB10G10R10A10XR);
477+
478+
DisplayListBuilder builder;
479+
builder.DrawColor(DlColor::kWhite(), DlBlendMode::kSrc);
480+
481+
DlPaint paint;
482+
paint.setColor(DlColor::kBlue());
483+
paint.setMaskFilter(DlBlurMaskFilter::Make(DlBlurStyle::kNormal, 10));
484+
485+
// Zero height above
486+
builder.DrawRect(DlRect::MakeLTRB(100, 250, 500, 250), paint);
487+
// Regular rect
488+
builder.DrawRect(DlRect::MakeLTRB(100, 300, 500, 600), paint);
489+
// Zero width to the right
490+
builder.DrawRect(DlRect::MakeLTRB(550, 300, 550, 600), paint);
491+
492+
ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
493+
}
494+
473495
struct MaskBlurTestConfig {
474496
DlBlurStyle style = DlBlurStyle::kNormal;
475497
Scalar sigma = 1.0f;

engine/src/flutter/impeller/entity/contents/solid_rrect_blur_contents.cc

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ static Point NegPos(Scalar v) {
6868
return {std::min(v, 0.0f), std::max(v, 0.0f)};
6969
}
7070

71-
static void SetupFragInfo(
71+
static bool SetupFragInfo(
7272
RRectBlurPipeline::FragmentShader::FragInfo& frag_info,
7373
Scalar blurSigma,
7474
Point center,
@@ -96,6 +96,15 @@ static void SetupFragInfo(
9696
frag_info.scale =
9797
0.5 * computeErf7(frag_info.sInv * 0.5 *
9898
(std::max(rSize.x, rSize.y) - 0.5 * radius));
99+
100+
return frag_info.center.IsFinite() && //
101+
frag_info.adjust.IsFinite() && //
102+
std::isfinite(frag_info.minEdge) && //
103+
std::isfinite(frag_info.r1) && //
104+
std::isfinite(frag_info.exponent) && //
105+
std::isfinite(frag_info.sInv) && //
106+
std::isfinite(frag_info.exponentInv) && //
107+
std::isfinite(frag_info.scale);
99108
}
100109

101110
std::optional<Rect> SolidRRectBlurContents::GetCoverage(
@@ -159,8 +168,11 @@ bool SolidRRectBlurContents::Render(const ContentContext& renderer,
159168
positive_rect.GetWidth() * 0.5f),
160169
std::clamp(corner_radii_.height, kEhCloseEnough,
161170
positive_rect.GetHeight() * 0.5f));
162-
SetupFragInfo(frag_info, blur_sigma, positive_rect.GetCenter(),
163-
Point(positive_rect.GetSize()), radius);
171+
if (!SetupFragInfo(frag_info, blur_sigma, positive_rect.GetCenter(),
172+
Point(positive_rect.GetSize()), radius)) {
173+
return true;
174+
}
175+
164176
auto& host_buffer = renderer.GetTransientsBuffer();
165177
pass.SetCommandLabel("RRect Shadow");
166178
pass.SetPipeline(renderer.GetRRectBlurPipeline(opts));

engine/src/flutter/testing/impeller_golden_tests_output.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -802,6 +802,7 @@ impeller_Play_AiksTest_LinearToSrgbFilterSubpassCollapseOptimization_Vulkan.png
802802
impeller_Play_AiksTest_MaskBlurDoesntStretchContents_Metal.png
803803
impeller_Play_AiksTest_MaskBlurDoesntStretchContents_OpenGLES.png
804804
impeller_Play_AiksTest_MaskBlurDoesntStretchContents_Vulkan.png
805+
impeller_Play_AiksTest_MaskBlurOnZeroDimensionIsSkippedWideGamut_Metal.png
805806
impeller_Play_AiksTest_MaskBlurTexture_Metal.png
806807
impeller_Play_AiksTest_MaskBlurTexture_OpenGLES.png
807808
impeller_Play_AiksTest_MaskBlurTexture_Vulkan.png

0 commit comments

Comments
 (0)