Set ambient stroke to full width of blur.

Gives better blur behavior around corners and looks more like an
actual blur. Also removed the color members, as they're mostly
constant.

Bug: skia:7971
Change-Id: I22a5dcb93da1f39040148ca6ddb391844382cc73
Reviewed-on: https://skia-review.googlesource.com/153280
Commit-Queue: Jim Van Verth <jvanverth@google.com>
Reviewed-by: Robert Phillips <robertphillips@google.com>
diff --git a/src/gpu/GrRenderTargetContext.cpp b/src/gpu/GrRenderTargetContext.cpp
index 8df749f..c803491 100644
--- a/src/gpu/GrRenderTargetContext.cpp
+++ b/src/gpu/GrRenderTargetContext.cpp
@@ -1020,17 +1020,13 @@
             // set a large inset to force a fill
             devSpaceInsetWidth = ambientRRect.width();
         }
-        // the fraction of the blur we want to apply is devSpaceInsetWidth/devSpaceAmbientBlur,
-        // which is just 1/umbraRecipAlpha.
-        SkScalar blurClamp = SkScalarInvert(umbraRecipAlpha);
 
         std::unique_ptr<GrDrawOp> op = GrShadowRRectOp::Make(fContext,
                                                              ambientColor,
                                                              viewMatrix,
                                                              ambientRRect,
                                                              devSpaceAmbientBlur,
-                                                             devSpaceInsetWidth,
-                                                             blurClamp);
+                                                             devSpaceInsetWidth);
         SkASSERT(op);
         this->addDrawOp(clip, std::move(op));
     }
diff --git a/src/gpu/effects/GrShadowGeoProc.cpp b/src/gpu/effects/GrShadowGeoProc.cpp
index bf78f41..c883597 100644
--- a/src/gpu/effects/GrShadowGeoProc.cpp
+++ b/src/gpu/effects/GrShadowGeoProc.cpp
@@ -26,7 +26,7 @@
 
         // emit attributes
         varyingHandler->emitAttributes(rsgp);
-        fragBuilder->codeAppend("half4 shadowParams;");
+        fragBuilder->codeAppend("half3 shadowParams;");
         varyingHandler->addPassThroughAttribute(rsgp.inShadowParams(), "shadowParams");
 
         // setup pass through color
@@ -45,7 +45,7 @@
         fragBuilder->codeAppend("half d = length(shadowParams.xy);");
         fragBuilder->codeAppend("half distance = shadowParams.z * (1.0 - d);");
 
-        fragBuilder->codeAppend("half factor = 1.0 - clamp(distance, 0.0, shadowParams.w);");
+        fragBuilder->codeAppend("half factor = 1.0 - clamp(distance, 0.0, 1.0);");
         fragBuilder->codeAppend("factor = exp(-factor * factor * 4.0) - 0.018;");
         fragBuilder->codeAppendf("%s = half4(factor);",
                                  args.fOutputCoverage);
diff --git a/src/gpu/effects/GrShadowGeoProc.h b/src/gpu/effects/GrShadowGeoProc.h
index df3e501..a8880a2 100644
--- a/src/gpu/effects/GrShadowGeoProc.h
+++ b/src/gpu/effects/GrShadowGeoProc.h
@@ -45,7 +45,7 @@
 
     static constexpr Attribute kInPosition = {"inPosition", kFloat2_GrVertexAttribType};
     static constexpr Attribute kInColor = {"inColor", kUByte4_norm_GrVertexAttribType};
-    static constexpr Attribute kInShadowParams = {"inShadowParams", kHalf4_GrVertexAttribType};
+    static constexpr Attribute kInShadowParams = {"inShadowParams", kHalf3_GrVertexAttribType};
 
     GR_DECLARE_GEOMETRY_PROCESSOR_TEST
 
diff --git a/src/gpu/ops/GrShadowRRectOp.cpp b/src/gpu/ops/GrShadowRRectOp.cpp
index 69489a2..0a7d191 100644
--- a/src/gpu/ops/GrShadowRRectOp.cpp
+++ b/src/gpu/ops/GrShadowRRectOp.cpp
@@ -192,8 +192,7 @@
 
     // An insetWidth > 1/2 rect width or height indicates a simple fill.
     ShadowCircularRRectOp(GrColor color, const SkRect& devRect,
-                          float devRadius, bool isCircle, float blurRadius, float insetWidth,
-                          float blurClamp)
+                          float devRadius, bool isCircle, float blurRadius, float insetWidth)
             : INHERITED(ClassID()) {
         SkRect bounds = devRect;
         SkASSERT(insetWidth > 0);
@@ -204,10 +203,6 @@
         RRectType type = kFill_RRectType;
         if (isCircle) {
             umbraInset = 0;
-        } else if (insetWidth > 0 && insetWidth <= outerRadius) {
-            // If the client has requested a stroke smaller than the outer radius,
-            // we will assume they want no special umbra inset (this is for ambient shadows).
-            umbraInset = outerRadius;
         } else {
             umbraInset = SkTMax(outerRadius, blurRadius);
         }
@@ -229,7 +224,7 @@
         this->setBounds(bounds, HasAABloat::kNo, IsZeroArea::kNo);
 
         fGeoData.emplace_back(Geometry{color, outerRadius, umbraInset, innerRadius,
-                                       blurRadius, blurClamp, bounds, type, isCircle});
+                                       blurRadius, bounds, type, isCircle});
         if (isCircle) {
             fVertCount = circle_type_to_vert_count(kStroke_RRectType == type);
             fIndexCount = circle_type_to_index_count(kStroke_RRectType == type);
@@ -269,7 +264,6 @@
         SkScalar  fUmbraInset;
         SkScalar  fInnerRadius;
         SkScalar  fBlurRadius;
-        SkScalar  fClampValue;
         SkRect    fDevBounds;
         RRectType fType;
         bool      fIsCircle;
@@ -280,7 +274,6 @@
         GrColor fColor;
         SkPoint fOffset;
         SkScalar fDistanceCorrection;
-        SkScalar fClampValue;
     };
 
     void fillInCircleVerts(const Geometry& args, bool isStroked, CircleVertex** verts) const {
@@ -290,7 +283,6 @@
         SkScalar innerRadius = args.fInnerRadius;
         SkScalar blurRadius = args.fBlurRadius;
         SkScalar distanceCorrection = outerRadius / blurRadius;
-        SkScalar clampValue = args.fClampValue;
 
         const SkRect& bounds = args.fDevBounds;
 
@@ -305,56 +297,48 @@
         (*verts)->fColor = color;
         (*verts)->fOffset = SkPoint::Make(-octOffset, -1);
         (*verts)->fDistanceCorrection = distanceCorrection;
-        (*verts)->fClampValue = clampValue;
         (*verts)++;
 
         (*verts)->fPos = center + SkPoint::Make(octOffset * halfWidth, -halfWidth);
         (*verts)->fColor = color;
         (*verts)->fOffset = SkPoint::Make(octOffset, -1);
         (*verts)->fDistanceCorrection = distanceCorrection;
-        (*verts)->fClampValue = clampValue;
         (*verts)++;
 
         (*verts)->fPos = center + SkPoint::Make(halfWidth, -octOffset * halfWidth);
         (*verts)->fColor = color;
         (*verts)->fOffset = SkPoint::Make(1, -octOffset);
         (*verts)->fDistanceCorrection = distanceCorrection;
-        (*verts)->fClampValue = clampValue;
         (*verts)++;
 
         (*verts)->fPos = center + SkPoint::Make(halfWidth, octOffset * halfWidth);
         (*verts)->fColor = color;
         (*verts)->fOffset = SkPoint::Make(1, octOffset);
         (*verts)->fDistanceCorrection = distanceCorrection;
-        (*verts)->fClampValue = clampValue;
         (*verts)++;
 
         (*verts)->fPos = center + SkPoint::Make(octOffset * halfWidth, halfWidth);
         (*verts)->fColor = color;
         (*verts)->fOffset = SkPoint::Make(octOffset, 1);
         (*verts)->fDistanceCorrection = distanceCorrection;
-        (*verts)->fClampValue = clampValue;
         (*verts)++;
 
         (*verts)->fPos = center + SkPoint::Make(-octOffset * halfWidth, halfWidth);
         (*verts)->fColor = color;
         (*verts)->fOffset = SkPoint::Make(-octOffset, 1);
         (*verts)->fDistanceCorrection = distanceCorrection;
-        (*verts)->fClampValue = clampValue;
         (*verts)++;
 
         (*verts)->fPos = center + SkPoint::Make(-halfWidth, octOffset * halfWidth);
         (*verts)->fColor = color;
         (*verts)->fOffset = SkPoint::Make(-1, octOffset);
         (*verts)->fDistanceCorrection = distanceCorrection;
-        (*verts)->fClampValue = clampValue;
         (*verts)++;
 
         (*verts)->fPos = center + SkPoint::Make(-halfWidth, -octOffset * halfWidth);
         (*verts)->fColor = color;
         (*verts)->fOffset = SkPoint::Make(-1, -octOffset);
         (*verts)->fDistanceCorrection = distanceCorrection;
-        (*verts)->fClampValue = clampValue;
         (*verts)++;
 
         if (isStroked) {
@@ -369,56 +353,48 @@
             (*verts)->fColor = color;
             (*verts)->fOffset = SkPoint::Make(-s * innerRadius, -c * innerRadius);
             (*verts)->fDistanceCorrection = distanceCorrection;
-            (*verts)->fClampValue = clampValue;
             (*verts)++;
 
             (*verts)->fPos = center + SkPoint::Make(s * r, -c * r);
             (*verts)->fColor = color;
             (*verts)->fOffset = SkPoint::Make(s * innerRadius, -c * innerRadius);
             (*verts)->fDistanceCorrection = distanceCorrection;
-            (*verts)->fClampValue = clampValue;
             (*verts)++;
 
             (*verts)->fPos = center + SkPoint::Make(c * r, -s * r);
             (*verts)->fColor = color;
             (*verts)->fOffset = SkPoint::Make(c * innerRadius, -s * innerRadius);
             (*verts)->fDistanceCorrection = distanceCorrection;
-            (*verts)->fClampValue = clampValue;
             (*verts)++;
 
             (*verts)->fPos = center + SkPoint::Make(c * r, s * r);
             (*verts)->fColor = color;
             (*verts)->fOffset = SkPoint::Make(c * innerRadius, s * innerRadius);
             (*verts)->fDistanceCorrection = distanceCorrection;
-            (*verts)->fClampValue = clampValue;
             (*verts)++;
 
             (*verts)->fPos = center + SkPoint::Make(s * r, c * r);
             (*verts)->fColor = color;
             (*verts)->fOffset = SkPoint::Make(s * innerRadius, c * innerRadius);
             (*verts)->fDistanceCorrection = distanceCorrection;
-            (*verts)->fClampValue = clampValue;
             (*verts)++;
 
             (*verts)->fPos = center + SkPoint::Make(-s * r, c * r);
             (*verts)->fColor = color;
             (*verts)->fOffset = SkPoint::Make(-s * innerRadius, c * innerRadius);
             (*verts)->fDistanceCorrection = distanceCorrection;
-            (*verts)->fClampValue = clampValue;
             (*verts)++;
 
             (*verts)->fPos = center + SkPoint::Make(-c * r, s * r);
             (*verts)->fColor = color;
             (*verts)->fOffset = SkPoint::Make(-c * innerRadius, s * innerRadius);
             (*verts)->fDistanceCorrection = distanceCorrection;
-            (*verts)->fClampValue = clampValue;
             (*verts)++;
 
             (*verts)->fPos = center + SkPoint::Make(-c * r, -s * r);
             (*verts)->fColor = color;
             (*verts)->fOffset = SkPoint::Make(-c * innerRadius, -s * innerRadius);
             (*verts)->fDistanceCorrection = distanceCorrection;
-            (*verts)->fClampValue = clampValue;
             (*verts)++;
         } else {
             // filled
@@ -426,7 +402,6 @@
             (*verts)->fColor = color;
             (*verts)->fOffset = SkPoint::Make(0, 0);
             (*verts)->fDistanceCorrection = distanceCorrection;
-            (*verts)->fClampValue = clampValue;
             (*verts)++;
         }
     }
@@ -477,7 +452,6 @@
         SkScalar diagVal = umbraInset / (SK_ScalarSqrt2*(outerRadius - umbraInset) - outerRadius);
         SkVector diagVec = SkVector::Make(diagVal, diagVal);
         SkScalar distanceCorrection = umbraInset / blurRadius;
-        SkScalar clampValue = args.fClampValue;
 
         // build corner by corner
         for (int i = 0; i < 4; ++i) {
@@ -486,7 +460,6 @@
             (*verts)->fColor = color;
             (*verts)->fOffset = SkVector::Make(0, 0);
             (*verts)->fDistanceCorrection = distanceCorrection;
-            (*verts)->fClampValue = clampValue;
             (*verts)++;
 
             // outer points
@@ -494,35 +467,30 @@
             (*verts)->fColor = color;
             (*verts)->fOffset = SkVector::Make(0, -1);
             (*verts)->fDistanceCorrection = distanceCorrection;
-            (*verts)->fClampValue = clampValue;
             (*verts)++;
 
             (*verts)->fPos = SkPoint::Make(xOuter[i], yMid[i]);
             (*verts)->fColor = color;
             (*verts)->fOffset = outerVec;
             (*verts)->fDistanceCorrection = distanceCorrection;
-            (*verts)->fClampValue = clampValue;
             (*verts)++;
 
             (*verts)->fPos = SkPoint::Make(xOuter[i], yOuter[i]);
             (*verts)->fColor = color;
             (*verts)->fOffset = diagVec;
             (*verts)->fDistanceCorrection = distanceCorrection;
-            (*verts)->fClampValue = clampValue;
             (*verts)++;
 
             (*verts)->fPos = SkPoint::Make(xMid[i], yOuter[i]);
             (*verts)->fColor = color;
             (*verts)->fOffset = outerVec;
             (*verts)->fDistanceCorrection = distanceCorrection;
-            (*verts)->fClampValue = clampValue;
             (*verts)++;
 
             (*verts)->fPos = SkPoint::Make(xInner[i], yOuter[i]);
             (*verts)->fColor = color;
             (*verts)->fOffset = SkVector::Make(0, -1);
             (*verts)->fDistanceCorrection = distanceCorrection;
-            (*verts)->fClampValue = clampValue;
             (*verts)++;
         }
 
@@ -540,7 +508,6 @@
             (*verts)->fColor = color;
             (*verts)->fOffset = SkPoint::Make(0, 0);
             (*verts)->fDistanceCorrection = distanceCorrection;
-            (*verts)->fClampValue = clampValue;
             (*verts)++;
 
             // TR
@@ -548,7 +515,6 @@
             (*verts)->fColor = color;
             (*verts)->fOffset = SkPoint::Make(0, 0);
             (*verts)->fDistanceCorrection = distanceCorrection;
-            (*verts)->fClampValue = clampValue;
             (*verts)++;
 
             // BL
@@ -556,7 +522,6 @@
             (*verts)->fColor = color;
             (*verts)->fOffset = SkPoint::Make(0, 0);
             (*verts)->fDistanceCorrection = distanceCorrection;
-            (*verts)->fClampValue = clampValue;
             (*verts)++;
 
             // BR
@@ -564,7 +529,6 @@
             (*verts)->fColor = color;
             (*verts)->fOffset = SkPoint::Make(0, 0);
             (*verts)->fDistanceCorrection = distanceCorrection;
-            (*verts)->fClampValue = clampValue;
             (*verts)++;
         }
 
@@ -660,8 +624,7 @@
                                const SkMatrix& viewMatrix,
                                const SkRRect& rrect,
                                SkScalar blurWidth,
-                               SkScalar insetWidth,
-                               SkScalar blurClamp) {
+                               SkScalar insetWidth) {
     // Shadow rrect ops only handle simple circular rrects.
     SkASSERT(viewMatrix.isSimilarity() && SkRRectPriv::EqualRadii(rrect));
 
@@ -682,8 +645,7 @@
                                                  scaledRadius,
                                                  rrect.isOval(),
                                                  blurWidth,
-                                                 scaledInsetWidth,
-                                                 blurClamp);
+                                                 scaledInsetWidth);
 }
 }
 
@@ -706,23 +668,20 @@
     viewMatrix.postScale(scale, scale);
     SkScalar insetWidth = random->nextSScalar1() * 72.f;
     SkScalar blurWidth = random->nextSScalar1() * 72.f;
-    SkScalar blurClamp = random->nextSScalar1();
     bool isCircle = random->nextBool();
     // This op doesn't use a full GrPaint, just a color.
     GrColor color = paint.getColor();
     if (isCircle) {
         SkRect circle = GrTest::TestSquare(random);
         SkRRect rrect = SkRRect::MakeOval(circle);
-        return GrShadowRRectOp::Make(context, color, viewMatrix, rrect, blurWidth,
-                                     insetWidth, blurClamp);
+        return GrShadowRRectOp::Make(context, color, viewMatrix, rrect, blurWidth, insetWidth);
     } else {
         SkRRect rrect;
         do {
             // This may return a rrect with elliptical corners, which we don't support.
             rrect = GrTest::TestRRectSimple(random);
         } while (!SkRRectPriv::IsSimpleCircular(rrect));
-        return GrShadowRRectOp::Make(context, color, viewMatrix, rrect, blurWidth,
-                                     insetWidth, blurClamp);
+        return GrShadowRRectOp::Make(context, color, viewMatrix, rrect, blurWidth, insetWidth);
     }
 }
 
diff --git a/src/gpu/ops/GrShadowRRectOp.h b/src/gpu/ops/GrShadowRRectOp.h
index 2001129..a4607cb 100644
--- a/src/gpu/ops/GrShadowRRectOp.h
+++ b/src/gpu/ops/GrShadowRRectOp.h
@@ -24,8 +24,7 @@
                                const SkMatrix& viewMatrix,
                                const SkRRect& rrect,
                                SkScalar blurWidth,
-                               SkScalar insetWidth,
-                               SkScalar blurClamp = 1);
+                               SkScalar insetWidth);
 }
 
 #endif
diff --git a/src/utils/SkShadowTessellator.cpp b/src/utils/SkShadowTessellator.cpp
index 7956f0e..f78c16d 100644
--- a/src/utils/SkShadowTessellator.cpp
+++ b/src/utils/SkShadowTessellator.cpp
@@ -39,6 +39,8 @@
 
 protected:
     static constexpr auto kMinHeight = 0.1f;
+    static constexpr auto kPenumbraColor = SK_ColorTRANSPARENT;
+    static constexpr auto kUmbraColor = SK_ColorBLACK;
 
     int vertexCount() const { return fPositions.count(); }
     int indexCount() const { return fIndices.count(); }
@@ -52,8 +54,9 @@
     bool computeConvexShadow(SkScalar inset, SkScalar outset, bool doClip);
     void computeClipVectorsAndTestCentroid();
     bool clipUmbraPoint(const SkPoint& umbraPoint, const SkPoint& centroid, SkPoint* clipPoint);
-    void addEdge(const SkVector& nextPoint, const SkVector& nextNormal, bool lastEdge, bool doClip);
-    bool addInnerPoint(const SkPoint& pathPoint, int* currUmbraIndex);
+    void addEdge(const SkVector& nextPoint, const SkVector& nextNormal, SkColor umbraColor,
+                 bool lastEdge, bool doClip);
+    bool addInnerPoint(const SkPoint& pathPoint, SkColor umbraColor, int* currUmbraIndex);
     int getClosestUmbraPoint(const SkPoint& point);
 
     // concave shadow methods
@@ -110,9 +113,6 @@
     bool                fIsConvex;
     bool                fValidUmbra;
 
-    SkColor             fUmbraColor;
-    SkColor             fPenumbraColor;
-
     SkScalar            fDirection;
     int                 fPrevUmbraIndex;
     int                 fCurrUmbraIndex;
@@ -123,6 +123,10 @@
     SkPoint             fPrevPoint;
 };
 
+// make external linkage happy
+constexpr SkColor SkBaseShadowTessellator::kUmbraColor;
+constexpr SkColor SkBaseShadowTessellator::kPenumbraColor;
+
 static bool compute_normal(const SkPoint& p0, const SkPoint& p1, SkScalar dir,
                            SkVector* newNormal) {
     SkVector normal;
@@ -244,6 +248,36 @@
         this->computeClipVectorsAndTestCentroid();
     }
 
+    // adjust inset distance and umbra color if necessary
+    auto umbraColor = kUmbraColor;
+    SkScalar minDistSq = SkPointPriv::DistanceToLineSegmentBetweenSqd(fCentroid,
+                                                                      fPathPolygon[0],
+                                                                      fPathPolygon[1]);
+    SkRect bounds;
+    bounds.setBounds(&fPathPolygon[0], fPathPolygon.count());
+    for (int i = 1; i < fPathPolygon.count(); ++i) {
+        int j = i + 1;
+        if (i == fPathPolygon.count() - 1) {
+            j = 0;
+        }
+        SkPoint currPoint = fPathPolygon[i];
+        SkPoint nextPoint = fPathPolygon[j];
+        SkScalar distSq = SkPointPriv::DistanceToLineSegmentBetweenSqd(fCentroid, currPoint,
+                                                                       nextPoint);
+        if (distSq < minDistSq) {
+            minDistSq = distSq;
+        }
+    }
+    static constexpr auto kTolerance = 1.0e-2f;
+    if (minDistSq < (inset + kTolerance)*(inset + kTolerance)) {
+        // if the umbra would collapse, we back off a bit on inner blur and adjust the alpha
+        auto newInset = SkScalarSqrt(minDistSq) - kTolerance;
+        auto ratio = 128 * (newInset + inset) / inset;
+        // they aren't PMColors, but the interpolation algorithm is the same
+        umbraColor = SkPMLerp(kUmbraColor, kPenumbraColor, (unsigned)ratio);
+        inset = newInset;
+    }
+
     // generate inner ring
     if (!SkInsetConvexPolygon(&fPathPolygon[0], fPathPolygon.count(), inset,
                               &fUmbraPolygon)) {
@@ -254,7 +288,7 @@
     // walk around the path polygon, generate outer ring and connect to inner ring
     if (fTransparent) {
         fPositions.push_back(fCentroid);
-        fColors.push_back(fUmbraColor);
+        fColors.push_back(umbraColor);
     }
     fCurrUmbraIndex = 0;
 
@@ -273,7 +307,7 @@
     fPrevPoint = fFirstPoint;
     fPrevUmbraIndex = -1;
 
-    this->addInnerPoint(fFirstPoint, &fPrevUmbraIndex);
+    this->addInnerPoint(fFirstPoint, umbraColor, &fPrevUmbraIndex);
 
     if (!fTransparent && doClip) {
         SkPoint clipPoint;
@@ -281,7 +315,7 @@
                                               fCentroid, &clipPoint);
         if (isOutside) {
             fPositions.push_back(clipPoint);
-            fColors.push_back(fUmbraColor);
+            fColors.push_back(umbraColor);
         }
         fPrevUmbraOutside = isOutside;
         fFirstUmbraOutside = isOutside;
@@ -289,8 +323,8 @@
 
     SkPoint newPoint = fFirstPoint + fFirstOutset;
     fPositions.push_back(newPoint);
-    fColors.push_back(fPenumbraColor);
-    this->addEdge(fPathPolygon[0], fFirstOutset, false, doClip);
+    fColors.push_back(kPenumbraColor);
+    this->addEdge(fPathPolygon[0], fFirstOutset, umbraColor, false, doClip);
 
     for (int i = 1; i < polyCount; ++i) {
         SkVector normal;
@@ -299,7 +333,7 @@
         }
         normal *= outset;
         this->addArc(normal, outset, true);
-        this->addEdge(fPathPolygon[i], normal, i == polyCount - 1, doClip);
+        this->addEdge(fPathPolygon[i], normal, umbraColor, i == polyCount - 1, doClip);
     }
     SkASSERT(this->indexCount());
 
@@ -355,7 +389,7 @@
 }
 
 void SkBaseShadowTessellator::addEdge(const SkPoint& nextPoint, const SkVector& nextNormal,
-                                      bool lastEdge, bool doClip) {
+                                      SkColor umbraColor, bool lastEdge, bool doClip) {
     // add next umbra point
     int currUmbraIndex;
     bool duplicate;
@@ -364,7 +398,7 @@
         currUmbraIndex = fFirstVertexIndex;
         fPrevPoint = nextPoint;
     } else {
-        duplicate = this->addInnerPoint(nextPoint, &currUmbraIndex);
+        duplicate = this->addInnerPoint(nextPoint, umbraColor, &currUmbraIndex);
     }
     int prevPenumbraIndex = duplicate || (currUmbraIndex == fFirstVertexIndex)
         ? fPositions.count() - 1
@@ -382,7 +416,7 @@
             if (isOutside) {
                 if (!lastEdge) {
                     fPositions.push_back(clipPoint);
-                    fColors.push_back(fUmbraColor);
+                    fColors.push_back(umbraColor);
                 }
                 this->appendTriangle(fPrevUmbraIndex, currUmbraIndex, currUmbraIndex + 1);
                 if (fPrevUmbraOutside) {
@@ -402,7 +436,7 @@
     // add next penumbra point and quad
     SkPoint newPoint = nextPoint + nextNormal;
     fPositions.push_back(newPoint);
-    fColors.push_back(fPenumbraColor);
+    fColors.push_back(kPenumbraColor);
 
     if (!duplicate) {
         this->appendTriangle(fPrevUmbraIndex, prevPenumbraIndex, currUmbraIndex);
@@ -445,7 +479,8 @@
     return false;
 }
 
-bool SkBaseShadowTessellator::addInnerPoint(const SkPoint& pathPoint, int* currUmbraIndex) {
+bool SkBaseShadowTessellator::addInnerPoint(const SkPoint& pathPoint, SkColor umbraColor,
+                                            int* currUmbraIndex) {
     SkPoint umbraPoint;
     if (!fValidUmbra) {
         SkVector v = fCentroid - pathPoint;
@@ -466,7 +501,7 @@
         } else {
             *currUmbraIndex = fPositions.count();
             fPositions.push_back(umbraPoint);
-            fColors.push_back(fUmbraColor);
+            fColors.push_back(umbraColor);
         }
         return false;
     } else {
@@ -583,10 +618,10 @@
     }
 
     fPositions.push_back(penumbraPolygon[currPenumbra]);
-    fColors.push_back(fPenumbraColor);
+    fColors.push_back(kPenumbraColor);
     int prevPenumbraIndex = 0;
     fPositions.push_back(umbraPolygon[currUmbra]);
-    fColors.push_back(fUmbraColor);
+    fColors.push_back(kUmbraColor);
     fPrevUmbraIndex = 1;
     indexMap[currUmbra] = 1;
 
@@ -598,11 +633,11 @@
         if ((*umbraIndices)[nextUmbra] == (*penumbraIndices)[nextPenumbra]) {
             // advance both one step
             fPositions.push_back(penumbraPolygon[nextPenumbra]);
-            fColors.push_back(fPenumbraColor);
+            fColors.push_back(kPenumbraColor);
             int currPenumbraIndex = fPositions.count() - 1;
 
             fPositions.push_back(umbraPolygon[nextUmbra]);
-            fColors.push_back(fUmbraColor);
+            fColors.push_back(kUmbraColor);
             int currUmbraIndex = fPositions.count() - 1;
             indexMap[nextUmbra] = currUmbraIndex;
 
@@ -624,7 +659,7 @@
                (*penumbraIndices)[nextPenumbra] <= maxPenumbraIndex) {
             // fill out penumbra arc
             fPositions.push_back(penumbraPolygon[nextPenumbra]);
-            fColors.push_back(fPenumbraColor);
+            fColors.push_back(kPenumbraColor);
             int currPenumbraIndex = fPositions.count() - 1;
 
             this->appendTriangle(prevPenumbraIndex, currPenumbraIndex, fPrevUmbraIndex);
@@ -640,7 +675,7 @@
                (*umbraIndices)[nextUmbra] <= maxUmbraIndex) {
             // fill out umbra arc
             fPositions.push_back(umbraPolygon[nextUmbra]);
-            fColors.push_back(fUmbraColor);
+            fColors.push_back(kUmbraColor);
             int currUmbraIndex = fPositions.count() - 1;
             indexMap[nextUmbra] = currUmbraIndex;
 
@@ -655,11 +690,11 @@
     }
     // finish up by advancing both one step
     fPositions.push_back(penumbraPolygon[nextPenumbra]);
-    fColors.push_back(fPenumbraColor);
+    fColors.push_back(kPenumbraColor);
     int currPenumbraIndex = fPositions.count() - 1;
 
     fPositions.push_back(umbraPolygon[nextUmbra]);
-    fColors.push_back(fUmbraColor);
+    fColors.push_back(kUmbraColor);
     int currUmbraIndex = fPositions.count() - 1;
     indexMap[nextUmbra] = currUmbraIndex;
 
@@ -800,14 +835,14 @@
         currNormal.fX = prevNormal.fX*rotCos - prevNormal.fY*rotSin;
         currNormal.fY = prevNormal.fY*rotCos + prevNormal.fX*rotSin;
         fPositions.push_back(fPrevPoint + currNormal);
-        fColors.push_back(fPenumbraColor);
+        fColors.push_back(kPenumbraColor);
         this->appendTriangle(fPrevUmbraIndex, fPositions.count() - 1, fPositions.count() - 2);
 
         prevNormal = currNormal;
     }
     if (finishArc && numSteps) {
         fPositions.push_back(fPrevPoint + nextNormal);
-        fColors.push_back(fPenumbraColor);
+        fColors.push_back(kPenumbraColor);
         this->appendTriangle(fPrevUmbraIndex, fPositions.count() - 1, fPositions.count() - 2);
     }
     fPrevOutset = nextNormal;
@@ -846,8 +881,6 @@
 private:
     bool computePathPolygon(const SkPath& path, const SkMatrix& ctm);
 
-    static constexpr auto kInsetFactor = 0.5f;
-
     typedef SkBaseShadowTessellator INHERITED;
 };
 
@@ -857,15 +890,10 @@
                                                        bool transparent)
         : INHERITED(zPlaneParams, transparent) {
     // Set base colors
-    SkScalar baseZ = heightFunc(path.getBounds().centerX(), path.getBounds().centerY());
-    SkScalar umbraAlpha = SkScalarInvert(SkDrawShadowMetrics::AmbientRecipAlpha(baseZ));
+    auto baseZ = heightFunc(path.getBounds().centerX(), path.getBounds().centerY());
     // umbraColor is the interior value, penumbraColor the exterior value.
-    // umbraAlpha is the factor that is linearly interpolated from outside to inside, and
-    // then "blurred" by the GrBlurredEdgeFP. It is then multiplied by fAmbientAlpha to get
-    // the final alpha.
-    fUmbraColor = SkColorSetARGB(umbraAlpha * 255.9999f, 0, 0, 0);
-    fPenumbraColor = SkColorSetARGB(0, 0, 0, 0);
-    SkScalar outset = SkDrawShadowMetrics::AmbientBlurRadius(baseZ);
+    auto outset = SkDrawShadowMetrics::AmbientBlurRadius(baseZ);
+    auto inset = outset * SkDrawShadowMetrics::AmbientRecipAlpha(baseZ) - outset;
 
     if (!this->computePathPolygon(path, ctm)) {
         return;
@@ -885,9 +913,9 @@
     fIndices.setReserve(12 * path.countPoints());
 
     if (fIsConvex) {
-        fSucceeded = this->computeConvexShadow(kInsetFactor, outset, false);
+        fSucceeded = this->computeConvexShadow(inset, outset, false);
     } else {
-        fSucceeded = this->computeConcaveShadow(kInsetFactor, outset);
+        fSucceeded = this->computeConcaveShadow(inset, outset);
     }
 }
 
@@ -961,8 +989,6 @@
 
     // Set radius and colors
     SkScalar occluderHeight = this->heightFunc(pathBounds.centerX(), pathBounds.centerY());
-    fUmbraColor = SkColorSetARGB(255, 0, 0, 0);
-    fPenumbraColor = SkColorSetARGB(0, 0, 0, 0);
 
     // Compute the blur radius, scale and translation for the spot shadow.
     SkScalar outset;
@@ -1056,33 +1082,6 @@
     fIndices.setReserve(15 * path.countPoints());
 
     if (fIsConvex) {
-        SkScalar minDistSq = SkPointPriv::DistanceToLineSegmentBetweenSqd(fCentroid,
-                                                                          fPathPolygon[0],
-                                                                          fPathPolygon[1]);
-        SkRect bounds;
-        bounds.setBounds(&fPathPolygon[0], fPathPolygon.count());
-        for (int i = 1; i < fPathPolygon.count(); ++i) {
-            int j = i + 1;
-            if (i == fPathPolygon.count() - 1) {
-                j = 0;
-            }
-            SkPoint currPoint = fPathPolygon[i];
-            SkPoint nextPoint = fPathPolygon[j];
-            SkScalar distSq = SkPointPriv::DistanceToLineSegmentBetweenSqd(fCentroid, currPoint,
-                                                                           nextPoint);
-            if (distSq < minDistSq) {
-                minDistSq = distSq;
-            }
-        }
-        static constexpr auto kTolerance = 1.0e-2f;
-        if (minDistSq < (inset + kTolerance)*(inset + kTolerance)) {
-            // if the umbra would collapse, we back off a bit on inner blur and adjust the alpha
-            SkScalar newInset = SkScalarSqrt(minDistSq) - kTolerance;
-            SkScalar ratio = 128 * (newInset + inset) / inset;
-            // they aren't PMColors, but the interpolation algorithm is the same
-            fUmbraColor = SkPMLerp(fUmbraColor, fPenumbraColor, (unsigned)ratio);
-            inset = newInset;
-        }
         fSucceeded = this->computeConvexShadow(inset, outset, true);
     } else {
         fSucceeded = this->computeConcaveShadow(inset, outset);