Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit a72a9d8

Browse files
[Impeller] relax conditions for SkRRect.isSimple conversion to impeller::RRect. (#53083)
The flickering in flutter/flutter#148412 is caused by us switching between the RRect fast path and a gaussian blur. The reason is that the SkRect.isSimple check doesn't handle fp precision very well. On one of the frames the difference was : ``` D/skia (18362): SkRect::MakeLTRB(74, 179.666672f, 374, 479.666656f); D/skia (18362): const SkPoint corners[] = { D/skia (18362): { 150, 149.999969f }, D/skia (18362): { 150, 150 }, D/skia (18362): { 150, 149.999969f }, D/skia (18362): { 150, 150 }, D/skia (18362): }; ``` So lets used a relaxed check for RRect.isSimple instead. Fixes flutter/flutter#148412
1 parent d624767 commit a72a9d8

File tree

4 files changed

+32
-1
lines changed

4 files changed

+32
-1
lines changed

impeller/display_list/dl_dispatcher.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -814,7 +814,7 @@ void DlDispatcherBase::drawCircle(const SkPoint& center, SkScalar radius) {
814814

815815
// |flutter::DlOpReceiver|
816816
void DlDispatcherBase::drawRRect(const SkRRect& rrect) {
817-
if (rrect.isSimple()) {
817+
if (skia_conversions::IsNearlySimpleRRect(rrect)) {
818818
GetCanvas().DrawRRect(skia_conversions::ToRect(rrect.rect()),
819819
skia_conversions::ToSize(rrect.getSimpleRadii()),
820820
paint_);

impeller/display_list/skia_conversions.cc

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,20 @@
99
namespace impeller {
1010
namespace skia_conversions {
1111

12+
bool IsNearlySimpleRRect(const SkRRect& rr) {
13+
auto [a, b] = rr.radii(SkRRect::kUpperLeft_Corner);
14+
auto [c, d] = rr.radii(SkRRect::kLowerLeft_Corner);
15+
auto [e, f] = rr.radii(SkRRect::kUpperRight_Corner);
16+
auto [g, h] = rr.radii(SkRRect::kLowerRight_Corner);
17+
return SkScalarNearlyEqual(a, b, kEhCloseEnough) &&
18+
SkScalarNearlyEqual(a, c, kEhCloseEnough) &&
19+
SkScalarNearlyEqual(a, d, kEhCloseEnough) &&
20+
SkScalarNearlyEqual(a, e, kEhCloseEnough) &&
21+
SkScalarNearlyEqual(a, f, kEhCloseEnough) &&
22+
SkScalarNearlyEqual(a, g, kEhCloseEnough) &&
23+
SkScalarNearlyEqual(a, h, kEhCloseEnough);
24+
}
25+
1226
Rect ToRect(const SkRect& rect) {
1327
return Rect::MakeLTRB(rect.fLeft, rect.fTop, rect.fRight, rect.fBottom);
1428
}

impeller/display_list/skia_conversions.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,13 @@
2424
namespace impeller {
2525
namespace skia_conversions {
2626

27+
/// @brief Like SkRRect.isSimple, but allows the corners to differ by
28+
/// kEhCloseEnough.
29+
///
30+
/// An RRect is simple if all corner radii are approximately
31+
/// equal.
32+
bool IsNearlySimpleRRect(const SkRRect& rr);
33+
2734
Rect ToRect(const SkRect& rect);
2835

2936
std::optional<Rect> ToRect(const SkRect* rect);

impeller/display_list/skia_conversions_unittests.cc

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
#include "flutter/testing/testing.h"
88
#include "impeller/display_list/skia_conversions.h"
99
#include "impeller/geometry/scalar.h"
10+
#include "include/core/SkRRect.h"
1011

1112
namespace impeller {
1213
namespace testing {
@@ -174,5 +175,14 @@ TEST(SkiaConversionsTest, GradientConversionNonMonotonic) {
174175
ASSERT_TRUE(ScalarNearlyEqual(converted_stops[3], 1.0f));
175176
}
176177

178+
TEST(SkiaConversionsTest, IsNearlySimpleRRect) {
179+
EXPECT_TRUE(skia_conversions::IsNearlySimpleRRect(
180+
SkRRect::MakeRectXY(SkRect::MakeLTRB(0, 0, 10, 10), 10, 10)));
181+
EXPECT_TRUE(skia_conversions::IsNearlySimpleRRect(
182+
SkRRect::MakeRectXY(SkRect::MakeLTRB(0, 0, 10, 10), 10, 9.999)));
183+
EXPECT_FALSE(skia_conversions::IsNearlySimpleRRect(
184+
SkRRect::MakeRectXY(SkRect::MakeLTRB(0, 0, 10, 10), 10, 9)));
185+
}
186+
177187
} // namespace testing
178188
} // namespace impeller

0 commit comments

Comments
 (0)