diff --git a/impeller/display_list/dl_dispatcher.cc b/impeller/display_list/dl_dispatcher.cc index 75fabadd11fdc..12abfe87c010c 100644 --- a/impeller/display_list/dl_dispatcher.cc +++ b/impeller/display_list/dl_dispatcher.cc @@ -814,7 +814,7 @@ void DlDispatcherBase::drawCircle(const SkPoint& center, SkScalar radius) { // |flutter::DlOpReceiver| void DlDispatcherBase::drawRRect(const SkRRect& rrect) { - if (rrect.isSimple()) { + if (skia_conversions::IsNearlySimpleRRect(rrect)) { GetCanvas().DrawRRect(skia_conversions::ToRect(rrect.rect()), skia_conversions::ToSize(rrect.getSimpleRadii()), paint_); diff --git a/impeller/display_list/skia_conversions.cc b/impeller/display_list/skia_conversions.cc index f356e9973a57a..8ac11c81a2803 100644 --- a/impeller/display_list/skia_conversions.cc +++ b/impeller/display_list/skia_conversions.cc @@ -9,6 +9,20 @@ namespace impeller { namespace skia_conversions { +bool IsNearlySimpleRRect(const SkRRect& rr) { + auto [a, b] = rr.radii(SkRRect::kUpperLeft_Corner); + auto [c, d] = rr.radii(SkRRect::kLowerLeft_Corner); + auto [e, f] = rr.radii(SkRRect::kUpperRight_Corner); + auto [g, h] = rr.radii(SkRRect::kLowerRight_Corner); + return SkScalarNearlyEqual(a, b, kEhCloseEnough) && + SkScalarNearlyEqual(a, c, kEhCloseEnough) && + SkScalarNearlyEqual(a, d, kEhCloseEnough) && + SkScalarNearlyEqual(a, e, kEhCloseEnough) && + SkScalarNearlyEqual(a, f, kEhCloseEnough) && + SkScalarNearlyEqual(a, g, kEhCloseEnough) && + SkScalarNearlyEqual(a, h, kEhCloseEnough); +} + Rect ToRect(const SkRect& rect) { return Rect::MakeLTRB(rect.fLeft, rect.fTop, rect.fRight, rect.fBottom); } diff --git a/impeller/display_list/skia_conversions.h b/impeller/display_list/skia_conversions.h index a0fe839d29b87..a52f31236eec9 100644 --- a/impeller/display_list/skia_conversions.h +++ b/impeller/display_list/skia_conversions.h @@ -24,6 +24,13 @@ namespace impeller { namespace skia_conversions { +/// @brief Like SkRRect.isSimple, but allows the corners to differ by +/// kEhCloseEnough. +/// +/// An RRect is simple if all corner radii are approximately +/// equal. +bool IsNearlySimpleRRect(const SkRRect& rr); + Rect ToRect(const SkRect& rect); std::optional ToRect(const SkRect* rect); diff --git a/impeller/display_list/skia_conversions_unittests.cc b/impeller/display_list/skia_conversions_unittests.cc index e31005e322c9f..257f2039d8ea1 100644 --- a/impeller/display_list/skia_conversions_unittests.cc +++ b/impeller/display_list/skia_conversions_unittests.cc @@ -7,6 +7,7 @@ #include "flutter/testing/testing.h" #include "impeller/display_list/skia_conversions.h" #include "impeller/geometry/scalar.h" +#include "include/core/SkRRect.h" namespace impeller { namespace testing { @@ -174,5 +175,14 @@ TEST(SkiaConversionsTest, GradientConversionNonMonotonic) { ASSERT_TRUE(ScalarNearlyEqual(converted_stops[3], 1.0f)); } +TEST(SkiaConversionsTest, IsNearlySimpleRRect) { + EXPECT_TRUE(skia_conversions::IsNearlySimpleRRect( + SkRRect::MakeRectXY(SkRect::MakeLTRB(0, 0, 10, 10), 10, 10))); + EXPECT_TRUE(skia_conversions::IsNearlySimpleRRect( + SkRRect::MakeRectXY(SkRect::MakeLTRB(0, 0, 10, 10), 10, 9.999))); + EXPECT_FALSE(skia_conversions::IsNearlySimpleRRect( + SkRRect::MakeRectXY(SkRect::MakeLTRB(0, 0, 10, 10), 10, 9))); +} + } // namespace testing } // namespace impeller