Accept near-simple, near-circular rrects for shadow fast path.

SkRRectPriv::IsSimpleCircular does a tolerance-based check for the
rrect radii but not for determining if the rrect is simple. This adds
IsNearlySimpleCircular as a looser check, since we don't care in this
case that the rrect is perfectly simple.

Bug: skia:11717
Change-Id: Ibbd53ff8c120287339fa29f87f064e6fb633ee7c
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/382703
Reviewed-by: Leon Scroggins <scroggo@google.com>
Commit-Queue: Jim Van Verth <jvanverth@google.com>
diff --git a/src/core/SkRRect.cpp b/src/core/SkRRect.cpp
index f2f6ab3..060e956 100644
--- a/src/core/SkRRect.cpp
+++ b/src/core/SkRRect.cpp
@@ -317,6 +317,17 @@
     return dist <= SkScalarSquare(fRadii[index].fX * fRadii[index].fY);
 }
 
+bool SkRRectPriv::IsNearlySimpleCircular(const SkRRect& rr, SkScalar tolerance) {
+    SkScalar simpleRadius = rr.fRadii[0].fX;
+    return SkScalarNearlyEqual(simpleRadius, rr.fRadii[0].fY, tolerance) &&
+           SkScalarNearlyEqual(simpleRadius, rr.fRadii[1].fX, tolerance) &&
+           SkScalarNearlyEqual(simpleRadius, rr.fRadii[1].fY, tolerance) &&
+           SkScalarNearlyEqual(simpleRadius, rr.fRadii[2].fX, tolerance) &&
+           SkScalarNearlyEqual(simpleRadius, rr.fRadii[2].fY, tolerance) &&
+           SkScalarNearlyEqual(simpleRadius, rr.fRadii[3].fX, tolerance) &&
+           SkScalarNearlyEqual(simpleRadius, rr.fRadii[3].fY, tolerance);
+}
+
 bool SkRRectPriv::AllCornersCircular(const SkRRect& rr, SkScalar tolerance) {
     return SkScalarNearlyEqual(rr.fRadii[0].fX, rr.fRadii[0].fY, tolerance) &&
            SkScalarNearlyEqual(rr.fRadii[1].fX, rr.fRadii[1].fY, tolerance) &&
diff --git a/src/core/SkRRectPriv.h b/src/core/SkRRectPriv.h
index 03fa8a2..cea579c 100644
--- a/src/core/SkRRectPriv.h
+++ b/src/core/SkRRectPriv.h
@@ -28,6 +28,10 @@
         return rr.isSimple() && SkScalarNearlyEqual(rr.fRadii[0].fX, rr.fRadii[0].fY);
     }
 
+    // Looser version of IsSimpleCircular, where the x & y values of the radii
+    // only have to be nearly equal instead of strictly equal.
+    static bool IsNearlySimpleCircular(const SkRRect& rr, SkScalar tolerance = SK_ScalarNearlyZero);
+
     static bool EqualRadii(const SkRRect& rr) {
         return rr.isRect() || SkRRectPriv::IsCircle(rr)  || SkRRectPriv::IsSimpleCircular(rr);
     }
diff --git a/src/gpu/GrSurfaceDrawContext.cpp b/src/gpu/GrSurfaceDrawContext.cpp
index 57a252b..7556d15 100644
--- a/src/gpu/GrSurfaceDrawContext.cpp
+++ b/src/gpu/GrSurfaceDrawContext.cpp
@@ -977,9 +977,9 @@
 
     SkRRect rrect;
     SkRect rect;
-    // we can only handle rects, circles, and rrects with circular corners
-    bool isRRect = path.isRRect(&rrect) && SkRRectPriv::IsSimpleCircular(rrect) &&
-        rrect.radii(SkRRect::kUpperLeft_Corner).fX > SK_ScalarNearlyZero;
+    // we can only handle rects, circles, and simple rrects with circular corners
+    bool isRRect = path.isRRect(&rrect) && SkRRectPriv::IsNearlySimpleCircular(rrect) &&
+                   rrect.getSimpleRadii().fX > SK_ScalarNearlyZero;
     if (!isRRect &&
         path.isOval(&rect) && SkScalarNearlyEqual(rect.width(), rect.height()) &&
         rect.width() > SK_ScalarNearlyZero) {
@@ -1089,7 +1089,7 @@
         SkMatrix shadowTransform;
         shadowTransform.setScaleTranslate(spotScale, spotScale, spotOffset.fX, spotOffset.fY);
         rrect.transform(shadowTransform, &spotShadowRRect);
-        SkScalar spotRadius = SkRRectPriv::GetSimpleRadii(spotShadowRRect).fX;
+        SkScalar spotRadius = spotShadowRRect.getSimpleRadii().fX;
 
         // Compute the insetWidth
         SkScalar blurOutset = srcSpaceSpotBlur;
@@ -1132,7 +1132,7 @@
                                                          spotShadowRRect.rect().fBottom -
                                                          rrect.rect().fBottom - dr);
                 maxOffset = SkScalarSqrt(std::max(SkPointPriv::LengthSqd(upperLeftOffset),
-                                                SkPointPriv::LengthSqd(lowerRightOffset))) + dr;
+                                                  SkPointPriv::LengthSqd(lowerRightOffset))) + dr;
             }
             insetWidth += std::max(blurOutset, maxOffset);
         }