Revert "Remove generalized gradient code"

This reverts commit 0c63006b88a16e3418d92852a62771615799839d.

BUG=skia:
NOTREECHECKS=true
GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=2235953003

Review-Url: https://codereview.chromium.org/2235953003
diff --git a/src/effects/gradients/SkGradientShader.cpp b/src/effects/gradients/SkGradientShader.cpp
index 2c686ec..820c5b2 100644
--- a/src/effects/gradients/SkGradientShader.cpp
+++ b/src/effects/gradients/SkGradientShader.cpp
@@ -228,52 +228,22 @@
     desc.flatten(buffer);
 }
 
-#if SK_SUPPORT_GPU
-
-static inline bool close_to_one_half(const SkFixed& val) {
-    return SkScalarNearlyEqual(SkFixedToScalar(val), SK_ScalarHalf);
-}
-
-GrGradientEffect::ColorType GrGradientEffect::determineColorTypeAndNumHardStops(
-        const SkGradientShaderBase& shader) {
-#if GR_GL_USE_ACCURATE_HARD_STOP_GRADIENTS
-    if (shader.fOrigPos) {
-        if (4 == shader.fColorCount) {
-            if (SkScalarNearlyEqual(shader.fOrigPos[0], 0.0f) &&
-                SkScalarNearlyEqual(shader.fOrigPos[1], 0.5f) &&
-                SkScalarNearlyEqual(shader.fOrigPos[2], 0.5f) &&
-                SkScalarNearlyEqual(shader.fOrigPos[3], 1.0f)) {
-
-                return kHardStopCentered_ColorType;
-            }
-        } else if (3 == shader.fColorCount) {
-            if (SkScalarNearlyEqual(shader.fOrigPos[0], 0.0f) &&
-                SkScalarNearlyEqual(shader.fOrigPos[1], 0.0f) &&
-                SkScalarNearlyEqual(shader.fOrigPos[2], 1.0f)) {
-
-                return kHardStopLeftEdged_ColorType;
-            } else if (SkScalarNearlyEqual(shader.fOrigPos[0], 0.0f) &&
-                       SkScalarNearlyEqual(shader.fOrigPos[1], 1.0f) &&
-                       SkScalarNearlyEqual(shader.fOrigPos[2], 1.0f)) {
-                
-                return kHardStopRightEdged_ColorType;
-            }
-        }
-    }
-#endif
-
-    if (SkShader::kClamp_TileMode == shader.getTileMode()) {
-        if (2 == shader.fColorCount) {
-            return kTwo_ColorType;
-        } else if (3 == shader.fColorCount &&
-                   close_to_one_half(shader.getRecs()[1].fPos)) {
-            return kThree_ColorType;
-        }
+SkGradientShaderBase::GpuColorType SkGradientShaderBase::getGpuColorType(SkColor colors[3]) const {
+    if (fColorCount <= 3) {
+        memcpy(colors, fOrigColors, fColorCount * sizeof(SkColor));
     }
 
-    return kTexture_ColorType;
+    if (SkShader::kClamp_TileMode == fTileMode) {
+        if (2 == fColorCount) {
+            return kTwo_GpuColorType;
+        } else if (3 == fColorCount &&
+                   (SkScalarAbs(
+                    SkFixedToScalar(fRecs[1].fPos) - SK_ScalarHalf) < SK_Scalar1 / 1000)) {
+            return kThree_GpuColorType;
+        }
+    }
+    return kTexture_GpuColorType;
 }
-#endif
 
 void SkGradientShaderBase::FlipGradientColors(SkColor* colorDst, Rec* recDst,
                                               SkColor* colorSrc, Rec* recSrc,
@@ -941,147 +911,114 @@
 #include "glsl/GrGLSLUniformHandler.h"
 #include "SkGr.h"
 
-static inline int color_type_to_color_count(GrGradientEffect::ColorType colorType) {
-    switch (colorType) {
-#if GR_GL_USE_ACCURATE_HARD_STOP_GRADIENTS
-        case GrGradientEffect::kHardStopCentered_ColorType:
-            return 4;
-        case GrGradientEffect::kHardStopLeftEdged_ColorType:
-        case GrGradientEffect::kHardStopRightEdged_ColorType:
-            return 3;
-#endif
-        case GrGradientEffect::kTwo_ColorType:
-            return 2;
-        case GrGradientEffect::kThree_ColorType:
-            return 3;
-        case GrGradientEffect::kTexture_ColorType:
-            return 0;
-    }
-
-    SkDEBUGFAIL("Unhandled ColorType in color_type_to_color_count()");
-    return -1;
+GrGradientEffect::GLSLProcessor::GLSLProcessor()
+    : fCachedYCoord(SK_ScalarMax) {
 }
 
 void GrGradientEffect::GLSLProcessor::emitUniforms(GrGLSLUniformHandler* uniformHandler,
                                                    const GrGradientEffect& ge) {
-    if (int colorCount = color_type_to_color_count(ge.getColorType())) {
-        fColorsUni = uniformHandler->addUniformArray(kFragment_GrShaderFlag,
-                                                     kVec4f_GrSLType,
-                                                     kDefault_GrSLPrecision,
-                                                     "Colors",
-                                                     colorCount);
-    } else {
+
+    if (SkGradientShaderBase::kTwo_GpuColorType == ge.getColorType()) { // 2 Color case
+        fColorStartUni = uniformHandler->addUniform(kFragment_GrShaderFlag,
+                                                    kVec4f_GrSLType, kDefault_GrSLPrecision,
+                                                    "GradientStartColor");
+        fColorEndUni = uniformHandler->addUniform(kFragment_GrShaderFlag,
+                                                  kVec4f_GrSLType, kDefault_GrSLPrecision,
+                                                  "GradientEndColor");
+
+    } else if (SkGradientShaderBase::kThree_GpuColorType == ge.getColorType()) { // 3 Color Case
+        fColorStartUni = uniformHandler->addUniform(kFragment_GrShaderFlag,
+                                                    kVec4f_GrSLType,  kDefault_GrSLPrecision,
+                                                    "GradientStartColor");
+        fColorMidUni = uniformHandler->addUniform(kFragment_GrShaderFlag,
+                                                  kVec4f_GrSLType, kDefault_GrSLPrecision,
+                                                  "GradientMidColor");
+        fColorEndUni = uniformHandler->addUniform(kFragment_GrShaderFlag,
+                                                  kVec4f_GrSLType, kDefault_GrSLPrecision,
+                                                  "GradientEndColor");
+
+    } else { // if not a fast case
         fFSYUni = uniformHandler->addUniform(kFragment_GrShaderFlag,
                                              kFloat_GrSLType, kDefault_GrSLPrecision,
                                              "GradientYCoordFS");
     }
 }
 
-static inline void set_after_interp_color_uni_array(const GrGLSLProgramDataManager& pdman,
-                                       const GrGLSLProgramDataManager::UniformHandle uni,
-                                       const SkTDArray<SkColor>& colors) {
-    int count = colors.count();
-    constexpr int kSmallCount = 10;
-
-    SkAutoSTArray<4*kSmallCount, float> vals(4*count);
-
-    for (int i = 0; i < colors.count(); i++) {
-        // RGBA
-        vals[4*i + 0] = SkColorGetR(colors[i]) / 255.f;
-        vals[4*i + 1] = SkColorGetG(colors[i]) / 255.f;
-        vals[4*i + 2] = SkColorGetB(colors[i]) / 255.f;
-        vals[4*i + 3] = SkColorGetA(colors[i]) / 255.f;
-    }
-
-    pdman.set4fv(uni, colors.count(), vals.get());
+static inline void set_color_uni(const GrGLSLProgramDataManager& pdman,
+                                 const GrGLSLProgramDataManager::UniformHandle uni,
+                                 const SkColor* color) {
+       pdman.set4f(uni,
+                   SkColorGetR(*color) / 255.f,
+                   SkColorGetG(*color) / 255.f,
+                   SkColorGetB(*color) / 255.f,
+                   SkColorGetA(*color) / 255.f);
 }
 
-static inline void set_before_interp_color_uni_array(const GrGLSLProgramDataManager& pdman,
-                                              const GrGLSLProgramDataManager::UniformHandle uni,
-                                              const SkTDArray<SkColor>& colors) {
-    int count = colors.count();
-    constexpr int kSmallCount = 10;
-
-    SkAutoSTArray<4*kSmallCount, float> vals(4*count);
-
-    for (int i = 0; i < count; i++) {
-        float a = SkColorGetA(colors[i]) / 255.f;
-        float aDiv255 = a / 255.f;
-
-        // RGBA
-        vals[4*i + 0] = SkColorGetR(colors[i]) * aDiv255;
-        vals[4*i + 1] = SkColorGetG(colors[i]) * aDiv255;
-        vals[4*i + 2] = SkColorGetB(colors[i]) * aDiv255;
-        vals[4*i + 3] = a;
-    }
-
-    pdman.set4fv(uni, count, vals.get());
+static inline void set_mul_color_uni(const GrGLSLProgramDataManager& pdman,
+                                     const GrGLSLProgramDataManager::UniformHandle uni,
+                                     const SkColor* color){
+       float a = SkColorGetA(*color) / 255.f;
+       float aDiv255 = a / 255.f;
+       pdman.set4f(uni,
+                   SkColorGetR(*color) * aDiv255,
+                   SkColorGetG(*color) * aDiv255,
+                   SkColorGetB(*color) * aDiv255,
+                   a);
 }
 
 void GrGradientEffect::GLSLProcessor::onSetData(const GrGLSLProgramDataManager& pdman,
                                                 const GrProcessor& processor) {
+
     const GrGradientEffect& e = processor.cast<GrGradientEffect>();
 
-    switch (e.getColorType()) {
-#if GR_GL_USE_ACCURATE_HARD_STOP_GRADIENTS
-        case GrGradientEffect::kHardStopCentered_ColorType:
-        case GrGradientEffect::kHardStopLeftEdged_ColorType:
-        case GrGradientEffect::kHardStopRightEdged_ColorType:
-#endif
-        case GrGradientEffect::kTwo_ColorType:
-        case GrGradientEffect::kThree_ColorType: {
-            if (GrGradientEffect::kBeforeInterp_PremulType == e.getPremulType()) {
-                set_before_interp_color_uni_array(pdman, fColorsUni, e.fColors);
-            } else {
-                set_after_interp_color_uni_array(pdman, fColorsUni, e.fColors);
-            }
 
-            break;
+    if (SkGradientShaderBase::kTwo_GpuColorType == e.getColorType()){
+
+        if (GrGradientEffect::kBeforeInterp_PremulType == e.getPremulType()) {
+            set_mul_color_uni(pdman, fColorStartUni, e.getColors(0));
+            set_mul_color_uni(pdman, fColorEndUni,   e.getColors(1));
+        } else {
+            set_color_uni(pdman, fColorStartUni, e.getColors(0));
+            set_color_uni(pdman, fColorEndUni,   e.getColors(1));
         }
 
-        case GrGradientEffect::kTexture_ColorType: {
-            SkScalar yCoord = e.getYCoord();
-            if (yCoord != fCachedYCoord) {
-                pdman.set1f(fFSYUni, yCoord);
-                fCachedYCoord = yCoord;
-            }
-            break;
+    } else if (SkGradientShaderBase::kThree_GpuColorType == e.getColorType()){
+
+        if (GrGradientEffect::kBeforeInterp_PremulType == e.getPremulType()) {
+            set_mul_color_uni(pdman, fColorStartUni, e.getColors(0));
+            set_mul_color_uni(pdman, fColorMidUni,   e.getColors(1));
+            set_mul_color_uni(pdman, fColorEndUni,   e.getColors(2));
+        } else {
+            set_color_uni(pdman, fColorStartUni, e.getColors(0));
+            set_color_uni(pdman, fColorMidUni,   e.getColors(1));
+            set_color_uni(pdman, fColorEndUni,   e.getColors(2));
+        }
+    } else {
+
+        SkScalar yCoord = e.getYCoord();
+        if (yCoord != fCachedYCoord) {
+            pdman.set1f(fFSYUni, yCoord);
+            fCachedYCoord = yCoord;
         }
     }
 }
 
+
 uint32_t GrGradientEffect::GLSLProcessor::GenBaseGradientKey(const GrProcessor& processor) {
     const GrGradientEffect& e = processor.cast<GrGradientEffect>();
 
     uint32_t key = 0;
 
+    if (SkGradientShaderBase::kTwo_GpuColorType == e.getColorType()) {
+        key |= kTwoColorKey;
+    } else if (SkGradientShaderBase::kThree_GpuColorType == e.getColorType()) {
+        key |= kThreeColorKey;
+    }
+
     if (GrGradientEffect::kBeforeInterp_PremulType == e.getPremulType()) {
         key |= kPremulBeforeInterpKey;
     }
 
-    if (GrGradientEffect::kTwo_ColorType == e.getColorType()) {
-        key |= kTwoColorKey;
-    } else if (GrGradientEffect::kThree_ColorType == e.getColorType()) {
-        key |= kThreeColorKey;
-    }
-#if GR_GL_USE_ACCURATE_HARD_STOP_GRADIENTS
-    else if (GrGradientEffect::kHardStopCentered_ColorType == e.getColorType()) {
-        key |= kHardStopCenteredKey;
-    } else if (GrGradientEffect::kHardStopLeftEdged_ColorType == e.getColorType()) {
-        key |= kHardStopZeroZeroOneKey;
-    } else if (GrGradientEffect::kHardStopRightEdged_ColorType == e.getColorType()) {
-        key |= kHardStopZeroOneOneKey;
-    }
-   
-    if (SkShader::TileMode::kClamp_TileMode == e.fTileMode) {
-        key |= kClampTileMode;
-    } else if (SkShader::TileMode::kRepeat_TileMode == e.fTileMode) {
-        key |= kRepeatTileMode;
-    } else {
-        key |= kMirrorTileMode;
-    }
-#endif
-
     return key;
 }
 
@@ -1093,183 +1030,56 @@
                                                 const char* outputColor,
                                                 const char* inputColor,
                                                 const SamplerHandle* texSamplers) {
-    switch (ge.getColorType()) {
-#if GR_GL_USE_ACCURATE_HARD_STOP_GRADIENTS
-        case kHardStopCentered_ColorType: {
-            const char* t      = gradientTValue;
-            const char* colors = uniformHandler->getUniformCStr(fColorsUni);
-
-            fragBuilder->codeAppendf("float clamp_t = clamp(%s, 0.0, 1.0);", t);
-
-            // Account for tile mode
-            if (SkShader::kRepeat_TileMode == ge.fTileMode) {
-                fragBuilder->codeAppendf("clamp_t = fract(%s);", t);
-            } else if (SkShader::kMirror_TileMode == ge.fTileMode) {
-                fragBuilder->codeAppendf("if (%s < 0.0 || %s > 1.0) {", t, t);
-                fragBuilder->codeAppendf("    if (mod(floor(%s), 2.0) == 0.0) {", t);
-                fragBuilder->codeAppendf("        clamp_t = fract(%s);", t);
-                fragBuilder->codeAppendf("    } else {");
-                fragBuilder->codeAppendf("        clamp_t = 1.0 - fract(%s);", t);
-                fragBuilder->codeAppendf("    }");
-                fragBuilder->codeAppendf("}");
-            }
-
-            // Calculate color
-            fragBuilder->codeAppendf("float relative_t = fract(2.0 * clamp_t);");
-            if (SkShader::kClamp_TileMode == ge.fTileMode) {
-                fragBuilder->codeAppendf("relative_t += step(1.0, %s);", t);
-            }
-            fragBuilder->codeAppendf("vec4 colorTemp = mix(%s[0], %s[1], relative_t);", colors,
-                                     colors);
-            fragBuilder->codeAppendf("if (clamp_t >= 0.5) {");
-            fragBuilder->codeAppendf("    colorTemp = mix(%s[2], %s[3], relative_t);", colors,
-                                     colors);
-            fragBuilder->codeAppendf("}");
-
-            if (GrGradientEffect::kAfterInterp_PremulType == ge.getPremulType()) {
-                fragBuilder->codeAppend("colorTemp.rgb *= colorTemp.a;");
-            }
-            fragBuilder->codeAppendf("%s = %s;", outputColor,
-                                     (GrGLSLExpr4(inputColor) * GrGLSLExpr4("colorTemp")).c_str());
-
-            break;
+    if (SkGradientShaderBase::kTwo_GpuColorType == ge.getColorType()){
+        fragBuilder->codeAppendf("\tvec4 colorTemp = mix(%s, %s, clamp(%s, 0.0, 1.0));\n",
+                                 uniformHandler->getUniformVariable(fColorStartUni).c_str(),
+                                 uniformHandler->getUniformVariable(fColorEndUni).c_str(),
+                                 gradientTValue);
+        // Note that we could skip this step if both 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.
+        if (GrGradientEffect::kAfterInterp_PremulType == ge.getPremulType()) {
+            fragBuilder->codeAppend("\tcolorTemp.rgb *= colorTemp.a;\n");
         }
 
-        case kHardStopLeftEdged_ColorType: {
-            const char* t      = gradientTValue;
-            const char* colors = uniformHandler->getUniformCStr(fColorsUni);
-
-            fragBuilder->codeAppendf("float clamp_t = clamp(%s, 0.0, 1.0);", t);
-
-            // Account for tile mode
-            if (SkShader::kRepeat_TileMode == ge.fTileMode) {
-                fragBuilder->codeAppendf("clamp_t = fract(%s);", t);
-            } else if (SkShader::kMirror_TileMode == ge.fTileMode) {
-                fragBuilder->codeAppendf("if (%s < 0.0 || %s > 1.0) {", t, t);
-                fragBuilder->codeAppendf("    if (mod(floor(%s), 2.0) == 0.0) {", t);
-                fragBuilder->codeAppendf("        clamp_t = fract(%s);", t);
-                fragBuilder->codeAppendf("    } else {");
-                fragBuilder->codeAppendf("        clamp_t = 1.0 - fract(%s);", t);
-                fragBuilder->codeAppendf("    }");
-                fragBuilder->codeAppendf("}");
-            }
-
-            fragBuilder->codeAppendf("vec4 colorTemp = mix(%s[1], %s[2], clamp_t);", colors,
-                                     colors);
-            if (SkShader::kClamp_TileMode == ge.fTileMode) {
-                fragBuilder->codeAppendf("if (%s < 0.0) {", t);
-                fragBuilder->codeAppendf("    colorTemp = %s[0];", colors);
-                fragBuilder->codeAppendf("}");
-            }
-
-            if (GrGradientEffect::kAfterInterp_PremulType == ge.getPremulType()) {
-                fragBuilder->codeAppend("colorTemp.rgb *= colorTemp.a;");
-            }
-            fragBuilder->codeAppendf("%s = %s;", outputColor,
-                                     (GrGLSLExpr4(inputColor) * GrGLSLExpr4("colorTemp")).c_str());
-
-            break;
+        fragBuilder->codeAppendf("\t%s = %s;\n", outputColor,
+                                 (GrGLSLExpr4(inputColor) * GrGLSLExpr4("colorTemp")).c_str());
+    } else if (SkGradientShaderBase::kThree_GpuColorType == ge.getColorType()) {
+        fragBuilder->codeAppendf("\tfloat oneMinus2t = 1.0 - (2.0 * (%s));\n",
+                                 gradientTValue);
+        fragBuilder->codeAppendf("\tvec4 colorTemp = clamp(oneMinus2t, 0.0, 1.0) * %s;\n",
+                                 uniformHandler->getUniformVariable(fColorStartUni).c_str());
+        if (!glslCaps->canUseMinAndAbsTogether()) {
+            // The Tegra3 compiler will sometimes never return if we have
+            // min(abs(oneMinus2t), 1.0), or do the abs first in a separate expression.
+            fragBuilder->codeAppend("\tfloat minAbs = abs(oneMinus2t);\n");
+            fragBuilder->codeAppend("\tminAbs = minAbs > 1.0 ? 1.0 : minAbs;\n");
+            fragBuilder->codeAppendf("\tcolorTemp += (1.0 - minAbs) * %s;\n",
+                                     uniformHandler->getUniformVariable(fColorMidUni).c_str());
+        } else {
+            fragBuilder->codeAppendf("\tcolorTemp += (1.0 - min(abs(oneMinus2t), 1.0)) * %s;\n",
+                                     uniformHandler->getUniformVariable(fColorMidUni).c_str());
+        }
+        fragBuilder->codeAppendf("\tcolorTemp += clamp(-oneMinus2t, 0.0, 1.0) * %s;\n",
+                                 uniformHandler->getUniformVariable(fColorEndUni).c_str());
+        if (GrGradientEffect::kAfterInterp_PremulType == ge.getPremulType()) {
+            fragBuilder->codeAppend("\tcolorTemp.rgb *= colorTemp.a;\n");
         }
 
-        case kHardStopRightEdged_ColorType: {
-            const char* t      = gradientTValue;
-            const char* colors = uniformHandler->getUniformCStr(fColorsUni);
-
-            fragBuilder->codeAppendf("float clamp_t = clamp(%s, 0.0, 1.0);", t);
-
-            // Account for tile mode
-            if (SkShader::kRepeat_TileMode == ge.fTileMode) {
-                fragBuilder->codeAppendf("clamp_t = fract(%s);", t);
-            } else if (SkShader::kMirror_TileMode == ge.fTileMode) {
-                fragBuilder->codeAppendf("if (%s < 0.0 || %s > 1.0) {", t, t);
-                fragBuilder->codeAppendf("    if (mod(floor(%s), 2.0) == 0.0) {", t);
-                fragBuilder->codeAppendf("        clamp_t = fract(%s);", t);
-                fragBuilder->codeAppendf("    } else {");
-                fragBuilder->codeAppendf("        clamp_t = 1.0 - fract(%s);", t);
-                fragBuilder->codeAppendf("    }");
-                fragBuilder->codeAppendf("}");
-            }
-
-            fragBuilder->codeAppendf("vec4 colorTemp = mix(%s[0], %s[1], clamp_t);", colors,
-                                     colors);
-            if (SkShader::kClamp_TileMode == ge.fTileMode) {
-                fragBuilder->codeAppendf("if (%s > 1.0) {", t);
-                fragBuilder->codeAppendf("    colorTemp = %s[2];", colors);
-                fragBuilder->codeAppendf("}");
-            }
-
-            if (GrGradientEffect::kAfterInterp_PremulType == ge.getPremulType()) {
-                fragBuilder->codeAppend("colorTemp.rgb *= colorTemp.a;");
-            }
-            fragBuilder->codeAppendf("%s = %s;", outputColor,
-                                     (GrGLSLExpr4(inputColor) * GrGLSLExpr4("colorTemp")).c_str());
-
-            break;
-        }
-#endif
-
-        case kTwo_ColorType: {
-            const char* t      = gradientTValue;
-            const char* colors = uniformHandler->getUniformCStr(fColorsUni);
-
-            fragBuilder->codeAppendf("vec4 colorTemp = mix(%s[0], %s[1], clamp(%s, 0.0, 1.0));",
-                                     colors, colors, t);
-
-            // We could skip this step if both 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.
-            if (GrGradientEffect::kAfterInterp_PremulType == ge.getPremulType()) {
-                fragBuilder->codeAppend("colorTemp.rgb *= colorTemp.a;");
-            }
-
-            fragBuilder->codeAppendf("%s = %s;", outputColor,
-                                     (GrGLSLExpr4(inputColor) * GrGLSLExpr4("colorTemp")).c_str());
-
-            break;
-        }
-
-        case kThree_ColorType: {
-            const char* t      = gradientTValue;
-            const char* colors = uniformHandler->getUniformCStr(fColorsUni);
-
-            fragBuilder->codeAppendf("float oneMinus2t = 1.0 - (2.0 * %s);", t);
-            fragBuilder->codeAppendf("vec4 colorTemp = clamp(oneMinus2t, 0.0, 1.0) * %s[0];",
-                                     colors);
-            if (!glslCaps->canUseMinAndAbsTogether()) {
-                // The Tegra3 compiler will sometimes never return if we have
-                // min(abs(oneMinus2t), 1.0), or do the abs first in a separate expression.
-                fragBuilder->codeAppendf("float minAbs = abs(oneMinus2t);");
-                fragBuilder->codeAppendf("minAbs = minAbs > 1.0 ? 1.0 : minAbs;");
-                fragBuilder->codeAppendf("colorTemp += (1.0 - minAbs) * %s[1];", colors);
-            } else {
-                fragBuilder->codeAppendf("colorTemp += (1.0 - min(abs(oneMinus2t), 1.0)) * %s[1];",
-                                         colors);
-            }
-            fragBuilder->codeAppendf("colorTemp += clamp(-oneMinus2t, 0.0, 1.0) * %s[2];", colors);
-
-            if (GrGradientEffect::kAfterInterp_PremulType == ge.getPremulType()) {
-                fragBuilder->codeAppend("colorTemp.rgb *= colorTemp.a;");
-            }
-
-            fragBuilder->codeAppendf("%s = %s;", outputColor,
-                                     (GrGLSLExpr4(inputColor) * GrGLSLExpr4("colorTemp")).c_str());
-
-            break;
-        }
-
-        case kTexture_ColorType: {
-            const char* fsyuni = uniformHandler->getUniformCStr(fFSYUni);
-
-            fragBuilder->codeAppendf("vec2 coord = vec2(%s, %s);", gradientTValue, fsyuni);
-            fragBuilder->codeAppendf("%s = ", outputColor);
-            fragBuilder->appendTextureLookupAndModulate(inputColor, texSamplers[0], "coord");
-            fragBuilder->codeAppend(";");
-
-            break;
-        }
+        fragBuilder->codeAppendf("\t%s = %s;\n", outputColor,
+                                 (GrGLSLExpr4(inputColor) * GrGLSLExpr4("colorTemp")).c_str());
+    } else {
+        fragBuilder->codeAppendf("\tvec2 coord = vec2(%s, %s);\n",
+                                 gradientTValue,
+                                 uniformHandler->getUniformVariable(fFSYUni).c_str());
+        fragBuilder->codeAppendf("\t%s = ", outputColor);
+        fragBuilder->appendTextureLookupAndModulate(inputColor,
+                                                    texSamplers[0],
+                                                    "coord");
+        fragBuilder->codeAppend(";\n");
     }
 }
 
@@ -1282,87 +1092,56 @@
 
     fIsOpaque = shader.isOpaque();
 
-    fColorType = this->determineColorTypeAndNumHardStops(shader);
+    fColorType = shader.getGpuColorType(&fColors[0]);
 
-    if (kTexture_ColorType != fColorType) {
-        if (shader.fOrigColors) {
-            fColors = SkTDArray<SkColor>(shader.fOrigColors, shader.fColorCount);
-        }
+    // The two and three color specializations do not currently support tiling.
+    if (SkGradientShaderBase::kTwo_GpuColorType == fColorType ||
+        SkGradientShaderBase::kThree_GpuColorType == fColorType) {
+        fRow = -1;
 
-#if GR_GL_USE_ACCURATE_HARD_STOP_GRADIENTS
-        if (shader.fOrigPos) {
-            fPositions = SkTDArray<SkScalar>(shader.fOrigPos, shader.fColorCount);
-        }
-
-        fTileMode = tileMode;
-#endif
-    }
-
-    switch (fColorType) {
-        // The two and three color specializations do not currently support tiling.
-        case kTwo_ColorType:
-        case kThree_ColorType:
-#if GR_GL_USE_ACCURATE_HARD_STOP_GRADIENTS
-        case kHardStopLeftEdged_ColorType:
-        case kHardStopRightEdged_ColorType:
-        case kHardStopCentered_ColorType:
-#endif
-            fRow = -1;
-
-            if (SkGradientShader::kInterpolateColorsInPremul_Flag & shader.getGradFlags()) {
-                fPremulType = kBeforeInterp_PremulType;
-            } else {
-                fPremulType = kAfterInterp_PremulType;
-            }
-
-            fCoordTransform.reset(kCoordSet, matrix);
-
-            break;
-        case kTexture_ColorType:
-            // doesn't matter how this is set, just be consistent because it is part of the
-            // effect key.
+        if (SkGradientShader::kInterpolateColorsInPremul_Flag & shader.getGradFlags()) {
             fPremulType = kBeforeInterp_PremulType;
+        } else {
+            fPremulType = kAfterInterp_PremulType;
+        }
+        fCoordTransform.reset(kCoordSet, matrix);
+    } else {
+        // doesn't matter how this is set, just be consistent because it is part of the effect key.
+        fPremulType = kBeforeInterp_PremulType;
+        SkBitmap bitmap;
+        shader.getGradientTableBitmap(&bitmap);
 
-            SkBitmap bitmap;
-            shader.getGradientTableBitmap(&bitmap);
+        GrTextureStripAtlas::Desc desc;
+        desc.fWidth  = bitmap.width();
+        desc.fHeight = 32;
+        desc.fRowHeight = bitmap.height();
+        desc.fContext = ctx;
+        desc.fConfig = SkImageInfo2GrPixelConfig(bitmap.info(), *ctx->caps());
+        fAtlas = GrTextureStripAtlas::GetAtlas(desc);
+        SkASSERT(fAtlas);
 
-            GrTextureStripAtlas::Desc desc;
-            desc.fWidth  = bitmap.width();
-            desc.fHeight = 32;
-            desc.fRowHeight = bitmap.height();
-            desc.fContext = ctx;
-            desc.fConfig = SkImageInfo2GrPixelConfig(bitmap.info(), *ctx->caps());
-            fAtlas = GrTextureStripAtlas::GetAtlas(desc);
-            SkASSERT(fAtlas);
+        // We always filter the gradient table. Each table is one row of a texture, always y-clamp.
+        GrTextureParams params;
+        params.setFilterMode(GrTextureParams::kBilerp_FilterMode);
+        params.setTileModeX(tileMode);
 
-            // We always filter the gradient table. Each table is one row of a texture, always
-            // y-clamp.
-            GrTextureParams params;
-            params.setFilterMode(GrTextureParams::kBilerp_FilterMode);
-            params.setTileModeX(tileMode);
-
-            fRow = fAtlas->lockRow(bitmap);
-            if (-1 != fRow) {
-                fYCoord = fAtlas->getYOffset(fRow)+SK_ScalarHalf*fAtlas->getNormalizedTexelHeight();
-                fCoordTransform.reset(kCoordSet, matrix, fAtlas->getTexture(), params.filterMode());
-                fTextureAccess.reset(fAtlas->getTexture(), params);
-            } else {
-                SkAutoTUnref<GrTexture> texture(
-                    GrRefCachedBitmapTexture(ctx, bitmap, params,
-                                             SkSourceGammaTreatment::kRespect));
-                if (!texture) {
-                    return;
-                }
-                fCoordTransform.reset(kCoordSet, matrix, texture, params.filterMode());
-                fTextureAccess.reset(texture, params);
-                fYCoord = SK_ScalarHalf;
+        fRow = fAtlas->lockRow(bitmap);
+        if (-1 != fRow) {
+            fYCoord = fAtlas->getYOffset(fRow) + SK_ScalarHalf * fAtlas->getNormalizedTexelHeight();
+            fCoordTransform.reset(kCoordSet, matrix, fAtlas->getTexture(), params.filterMode());
+            fTextureAccess.reset(fAtlas->getTexture(), params);
+        } else {
+            SkAutoTUnref<GrTexture> texture(
+                GrRefCachedBitmapTexture(ctx, bitmap, params, SkSourceGammaTreatment::kRespect));
+            if (!texture) {
+                return;
             }
-
-            this->addTextureAccess(&fTextureAccess);
-
-            break;
+            fCoordTransform.reset(kCoordSet, matrix, texture, params.filterMode());
+            fTextureAccess.reset(texture, params);
+            fYCoord = SK_ScalarHalf;
+        }
+        this->addTextureAccess(&fTextureAccess);
     }
-
     this->addCoordTransform(&fCoordTransform);
 }
 
@@ -1373,27 +1152,30 @@
 }
 
 bool GrGradientEffect::onIsEqual(const GrFragmentProcessor& processor) const {
-    const GrGradientEffect& ge = processor.cast<GrGradientEffect>();
+    const GrGradientEffect& s = processor.cast<GrGradientEffect>();
 
-    if (this->fColorType == ge.getColorType()) {
-        if (kTexture_ColorType == fColorType) {
-            if (fYCoord != ge.getYCoord()) {
+    if (this->fColorType == s.getColorType()){
+
+        if (SkGradientShaderBase::kTwo_GpuColorType == fColorType) {
+            if (this->getPremulType() != s.getPremulType() ||
+                *this->getColors(0) != *s.getColors(0) ||
+                *this->getColors(1) != *s.getColors(1)) {
+                return false;
+            }
+        } else if (SkGradientShaderBase::kThree_GpuColorType == fColorType) {
+            if (this->getPremulType() != s.getPremulType() ||
+                *this->getColors(0) != *s.getColors(0) ||
+                *this->getColors(1) != *s.getColors(1) ||
+                *this->getColors(2) != *s.getColors(2)) {
                 return false;
             }
         } else {
-            if (this->getPremulType() != ge.getPremulType() ||
-                this->fColors.count() != ge.fColors.count()) {
+            if (fYCoord != s.getYCoord()) {
                 return false;
             }
-
-            for (int i = 0; i < this->fColors.count(); i++) {
-                if (*this->getColors(i) != *ge.getColors(i)) {
-                    return false;
-                }
-            }
         }
 
-        SkASSERT(this->useAtlas() == ge.useAtlas());
+        SkASSERT(this->useAtlas() == s.useAtlas());
         return true;
     }