Add clamped/unclamped xform to GrColorSpaceXform

Use that in analytic gradient setup for future-proofing. Also fixed
several out-of-date comments in gradient code.

Bug: skia:
Change-Id: I79726cad786c22f80e08cdc2b7a1e15ae27ecd5a
Reviewed-on: https://skia-review.googlesource.com/62320
Reviewed-by: Mike Klein <mtklein@chromium.org>
Commit-Queue: Brian Osman <brianosman@google.com>
diff --git a/src/gpu/GrColorSpaceXform.cpp b/src/gpu/GrColorSpaceXform.cpp
index 0e98a87..e43ccdc 100644
--- a/src/gpu/GrColorSpaceXform.cpp
+++ b/src/gpu/GrColorSpaceXform.cpp
@@ -121,11 +121,16 @@
     return a->fSrcToDst == b->fSrcToDst;
 }
 
-GrColor4f GrColorSpaceXform::apply(const GrColor4f& srcColor) {
+GrColor4f GrColorSpaceXform::unclampedXform(const GrColor4f& srcColor) {
     GrColor4f result;
     fSrcToDst.mapScalars(srcColor.fRGBA, result.fRGBA);
-    // We always operate on unpremul colors, so clamp to [0,1].
+    return result;
+}
+
+GrColor4f GrColorSpaceXform::clampedXform(const GrColor4f& srcColor) {
+    GrColor4f result = this->unclampedXform(srcColor);
     for (int i = 0; i < 4; ++i) {
+        // We always operate on unpremul colors, so clamp to [0,1].
         result.fRGBA[i] = SkTPin(result.fRGBA[i], 0.0f, 1.0f);
     }
     return result;
diff --git a/src/gpu/GrColorSpaceXform.h b/src/gpu/GrColorSpaceXform.h
index b871563..3f03e56 100644
--- a/src/gpu/GrColorSpaceXform.h
+++ b/src/gpu/GrColorSpaceXform.h
@@ -37,7 +37,8 @@
 
     static bool Equals(const GrColorSpaceXform* a, const GrColorSpaceXform* b);
 
-    GrColor4f apply(const GrColor4f& srcColor);
+    GrColor4f unclampedXform(const GrColor4f& srcColor);
+    GrColor4f clampedXform(const GrColor4f& srcColor);
 
 private:
     SkMatrix44 fSrcToDst;
diff --git a/src/gpu/SkGr.cpp b/src/gpu/SkGr.cpp
index 0c065f9..2d09f00 100644
--- a/src/gpu/SkGr.cpp
+++ b/src/gpu/SkGr.cpp
@@ -342,7 +342,7 @@
     }
 
     if (gamutXform) {
-        color = gamutXform->apply(color);
+        color = gamutXform->clampedXform(color);
     }
 
     return color;
diff --git a/src/shaders/SkColorShader.cpp b/src/shaders/SkColorShader.cpp
index 53bc94e..33d3166 100644
--- a/src/shaders/SkColorShader.cpp
+++ b/src/shaders/SkColorShader.cpp
@@ -213,7 +213,7 @@
                                                                        args.fDstColorSpace);
     GrColor4f color = GrColor4f::FromSkColor4f(fColor4);
     if (colorSpaceXform) {
-        color = colorSpaceXform->apply(color);
+        color = colorSpaceXform->clampedXform(color);
     }
     return GrConstColorProcessor::Make(color.premul(), GrConstColorProcessor::kModulateA_InputMode);
 }
diff --git a/src/shaders/gradients/SkGradientShader.cpp b/src/shaders/gradients/SkGradientShader.cpp
index 6dcc0ae..339f7ee 100644
--- a/src/shaders/gradients/SkGradientShader.cpp
+++ b/src/shaders/gradients/SkGradientShader.cpp
@@ -809,8 +809,7 @@
  *  over and over, we'd like to return exactly the same "bitmap" if possible,
  *  allowing the client to utilize a cache of our bitmap (e.g. with a GPU).
  *  To do that, we maintain a private cache of built-bitmaps, based on our
- *  colors and positions. Note: we don't try to flatten the fMapper, so if one
- *  is present, we skip the cache for now.
+ *  colors and positions.
  */
 void SkGradientShaderBase::getGradientTableBitmap(SkBitmap* bitmap,
                                                   GradientBitmapType bitmapType) const {
@@ -864,13 +863,11 @@
             switch (bitmapType) {
                 case GradientBitmapType::kSRGB:
                     info = SkImageInfo::Make(kCache32Count, 1, kRGBA_8888_SkColorType,
-                                             kPremul_SkAlphaType,
-                                             SkColorSpace::MakeSRGB());
+                                             kPremul_SkAlphaType, SkColorSpace::MakeSRGB());
                     break;
                 case GradientBitmapType::kHalfFloat:
-                    info = SkImageInfo::Make(
-                        kCache32Count, 1, kRGBA_F16_SkColorType, kPremul_SkAlphaType,
-                        SkColorSpace::MakeSRGBLinear());
+                    info = SkImageInfo::Make(kCache32Count, 1, kRGBA_F16_SkColorType,
+                                             kPremul_SkAlphaType, SkColorSpace::MakeSRGBLinear());
                     break;
                 default:
                     SK_ABORT("Unexpected bitmap type");
@@ -1483,12 +1480,10 @@
             break;
     }
 
-    // We could skip this step if both colors are known to be opaque. Two
-    // considerations:
+    // We could skip this step if all colors are known to be opaque. Two considerations:
     // The gradient SkShader reporting opaque is more restrictive than necessary in the two
     // pt case. Make sure the key reflects this optimization (and note that it can use the
-    // same shader as thekBeforeIterp case). This same optimization applies to the 3 color
-    // case below.
+    // same shader as the kBeforeInterp case).
     if (GrGradientEffect::kAfterInterp_PremulType == ge.getPremulType()) {
         fragBuilder->codeAppend("colorTemp.rgb *= colorTemp.a;");
     }
@@ -1569,7 +1564,8 @@
             }
 
             if (fColorSpaceXform) {
-                fColorSpaceXform->srcToDst().mapScalars(fColors4f[i].fRGBA, fColors4f[i].fRGBA);
+                // We defer clamping to after interpolation (see emitAnalyticalColor)
+                fColors4f[i] = fColorSpaceXform->unclampedXform(fColors4f[i]);
             }
         }
 
diff --git a/src/shaders/gradients/SkGradientShaderPriv.h b/src/shaders/gradients/SkGradientShaderPriv.h
index 23ff30f..1fd5ca9 100644
--- a/src/shaders/gradients/SkGradientShaderPriv.h
+++ b/src/shaders/gradients/SkGradientShaderPriv.h
@@ -516,11 +516,11 @@
                              const char* inputColor);
 
     enum {
-        // First bit for premul before/after interp
+        // First bit for premul before/after interpolation
         kPremulBeforeInterpKey  =  1,
 
         // Next three bits for 2/3 color type or different special
-        // hard stop cases (neither means using texture atlas)
+        // hard stop cases ('none' means using texture atlas)
         kTwoColorKey            =  2,
         kThreeColorKey          =  4,