Flip the switch to turn on GrCustomStage implementation of gradients;
remove old implementation, including enums & state on various structs.

http://codereview.appspot.com/6245078/



git-svn-id: http://skia.googlecode.com/svn/trunk@4129 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/src/gpu/SkGpuDevice.cpp b/src/gpu/SkGpuDevice.cpp
index 871dbb3..de9d973 100644
--- a/src/gpu/SkGpuDevice.cpp
+++ b/src/gpu/SkGpuDevice.cpp
@@ -6,13 +6,14 @@
  * found in the LICENSE file.
  */
 
+#include "SkGpuDevice.h"
 
+#include "effects/GrGradientEffects.h"
 
 #include "GrContext.h"
 #include "GrDefaultTextContext.h"
 #include "GrTextContext.h"
 
-#include "SkGpuDevice.h"
 #include "SkGrTexturePixelRef.h"
 
 #include "SkColorFilter.h"
@@ -421,14 +422,6 @@
                   shader_type_mismatch);
 SK_COMPILE_ASSERT(SkShader::kLast_BitmapType == 4, shader_type_mismatch);
 
-static const GrSamplerState::SampleMode sk_bmp_type_to_sample_mode[] = {
-    (GrSamplerState::SampleMode) -1,                    // kNone_BitmapType
-    GrSamplerState::kNormal_SampleMode,                 // kDefault_BitmapType
-    GrSamplerState::kRadial_SampleMode,                 // kRadial_BitmapType
-    GrSamplerState::kSweep_SampleMode,                  // kSweep_BitmapType
-    GrSamplerState::kRadial2_SampleMode,                // kTwoPointRadial_BitmapType
-};
-
 namespace {
 
 // converts a SkPaint to a GrPaint, ignoring the skPaint's shader
@@ -524,8 +517,7 @@
     SkShader::BitmapType bmptype = shader->asABitmap(&bitmap, matrix,
                                                      tileModes, twoPointParams);
 
-    GrSamplerState::SampleMode sampleMode = sk_bmp_type_to_sample_mode[bmptype];
-    if (-1 == sampleMode) {
+    if (SkShader::kNone_BitmapType == bmptype) {
         SkShader::GradientInfo info;
         SkColor                color;
 
@@ -546,7 +538,21 @@
         return false;
     }
     GrSamplerState* sampler = grPaint->textureSampler(kShaderTextureIdx);
-    sampler->setSampleMode(sampleMode);
+    switch (bmptype) {
+    case SkShader::kRadial_BitmapType: {
+        sampler->setCustomStage(new GrRadialGradient());
+        } break;
+    case SkShader::kSweep_BitmapType: {
+        sampler->setCustomStage(new GrSweepGradient());
+        } break;
+    case SkShader::kTwoPointRadial_BitmapType: {
+        sampler->setCustomStage(new GrRadial2Gradient(twoPointParams[0],
+                                                      twoPointParams[1],
+                                                      twoPointParams[2] < 0));
+        } break;
+    default:
+        break;
+    }
     if (skPaint.isFilterBitmap()) {
         sampler->setFilter(GrSamplerState::kBilinear_Filter);
     } else {
@@ -554,11 +560,6 @@
     }
     sampler->setWrapX(sk_tile_mode_to_grwrap(tileModes[0]));
     sampler->setWrapY(sk_tile_mode_to_grwrap(tileModes[1]));
-    if (GrSamplerState::kRadial2_SampleMode == sampleMode) {
-        sampler->setRadial2Params(twoPointParams[0],
-                                  twoPointParams[1],
-                                  twoPointParams[2] < 0);
-    }
 
     GrTexture* texture = act->set(dev, bitmap, sampler);
     if (NULL == texture) {
@@ -1354,7 +1355,6 @@
 
     sampler->setWrapX(GrSamplerState::kClamp_WrapMode);
     sampler->setWrapY(GrSamplerState::kClamp_WrapMode);
-    sampler->setSampleMode(GrSamplerState::kNormal_SampleMode);
     sampler->matrix()->reset();
 
     GrTexture* texture;
diff --git a/src/gpu/effects/GrGradientEffects.cpp b/src/gpu/effects/GrGradientEffects.cpp
index b1bf82f..000e0e5 100644
--- a/src/gpu/effects/GrGradientEffects.cpp
+++ b/src/gpu/effects/GrGradientEffects.cpp
@@ -212,7 +212,7 @@
 
     // If we aren't degenerate, emit some extra code, and accept a slightly
     // more complex coord.
-    if (fIsDegenerate) {
+    if (!fIsDegenerate) {
 
         // ac4 = 4.0 * params[0] * c
         code->appendf("\tfloat %s = %s * 4.0 * %s;\n",
diff --git a/src/gpu/effects/GrGradientEffects.h b/src/gpu/effects/GrGradientEffects.h
index 8d67c25..9bcf9dd 100644
--- a/src/gpu/effects/GrGradientEffects.h
+++ b/src/gpu/effects/GrGradientEffects.h
@@ -12,6 +12,29 @@
 #include "GrTypes.h"
 #include "GrScalar.h"
 
+/*
+ * The intepretation of the texture matrix depends on the sample mode. The
+ * texture matrix is applied both when the texture coordinates are explicit
+ * and  when vertex positions are used as texture  coordinates. In the latter
+ * case the texture matrix is applied to the pre-view-matrix position 
+ * values.
+ *
+ * Normal SampleMode
+ *  The post-matrix texture coordinates are in normalize space with (0,0) at
+ *  the top-left and (1,1) at the bottom right.
+ * RadialGradient
+ *  The matrix specifies the radial gradient parameters.
+ *  (0,0) in the post-matrix space is center of the radial gradient.
+ * Radial2Gradient
+ *   Matrix transforms to space where first circle is centered at the
+ *   origin. The second circle will be centered (x, 0) where x may be 
+ *   0 and is provided by setRadial2Params. The post-matrix space is 
+ *   normalized such that 1 is the second radius - first radius.
+ * SweepGradient
+ *  The angle from the origin of texture coordinates in post-matrix space
+ *  determines the gradient value.
+ */
+
 class GrGLRadialGradient;
 
 class GrRadialGradient : public GrCustomStage {
diff --git a/src/gpu/gl/GrGLProgram.cpp b/src/gpu/gl/GrGLProgram.cpp
index 7233233..6c22f46 100644
--- a/src/gpu/gl/GrGLProgram.cpp
+++ b/src/gpu/gl/GrGLProgram.cpp
@@ -1158,14 +1158,6 @@
                 GrAssert(kUnusedUniform != locations.fNormalizedTexelSizeUni);
             }
 
-            if (kUseUniform == locations.fRadial2Uni) {
-                GrStringBuilder radial2ParamName;
-                radial2_param_name(s, &radial2ParamName);
-                GL_CALL_RET(locations.fRadial2Uni,
-                            GetUniformLocation(progID, radial2ParamName.c_str()));
-                GrAssert(kUnusedUniform != locations.fRadial2Uni);
-            }
-
             if (kUseUniform == locations.fTexDomUni) {
                 GrStringBuilder texDomName;
                 tex_domain_name(s, &texDomName);
@@ -1188,8 +1180,6 @@
             GL_CALL(Uniform1i(programData->fUniLocations.fStages[s].fSamplerUni, s));
         }
         programData->fTextureMatrices[s] = GrMatrix::InvalidMatrix();
-        programData->fRadial2CenterX1[s] = GR_ScalarMax;
-        programData->fRadial2Radius0[s] = -GR_ScalarMax;
         programData->fTextureWidth[s] = -1;
         programData->fTextureHeight[s] = -1;
         programData->fTextureDomain[s].setEmpty();
@@ -1209,156 +1199,6 @@
 
 namespace {
 
-bool isRadialMapping(GrGLProgram::StageDesc::CoordMapping mapping) {
-    return
-       (GrGLProgram::StageDesc::kRadial2Gradient_CoordMapping == mapping ||
-        GrGLProgram::StageDesc::kRadial2GradientDegenerate_CoordMapping == mapping);
-}
-
-const GrGLShaderVar* genRadialVS(int stageNum,
-                        GrGLShaderBuilder* segments,
-                        GrGLProgram::StageUniLocations* locations,
-                        const char** radial2VaryingVSName,
-                        const char** radial2VaryingFSName,
-                        const char* varyingVSName) {
-    GrStringBuilder r2ParamsName;
-    radial2_param_name(stageNum, &r2ParamsName);
-    const GrGLShaderVar* radial2FSParams =
-        &segments->addUniform(GrGLShaderBuilder::kBoth_VariableLifetime,
-                              kFloat_GrSLType, r2ParamsName.c_str(), -1, 6);
-    locations->fRadial2Uni = kUseUniform;
-
-    // for radial grads without perspective we can pass the linear
-    // part of the quadratic as a varying.
-    if (segments->fVaryingDims == segments->fCoordDims) {
-        GrAssert(2 == segments->fCoordDims);
-        segments->addVarying(kFloat_GrSLType,
-                             "Radial2BCoeff",
-                             stageNum,
-                             radial2VaryingVSName,
-                             radial2VaryingFSName);
-
-        GrStringBuilder radial2p2;
-        GrStringBuilder radial2p3;
-        radial2FSParams->appendArrayAccess(2, &radial2p2);
-        radial2FSParams->appendArrayAccess(3, &radial2p3);
-
-        // r2Var = 2 * (r2Parm[2] * varCoord.x - r2Param[3])
-        const char* r2ParamName = radial2FSParams->getName().c_str();
-        segments->fVSCode.appendf("\t%s = 2.0 *(%s * %s.x - %s);\n",
-                                  *radial2VaryingVSName, radial2p2.c_str(),
-                                  varyingVSName, radial2p3.c_str());
-    }
-
-    return radial2FSParams;
-}
-
-void genRadial2GradientCoordMapping(int stageNum,
-                                    GrGLShaderBuilder* segments,
-                                    const char* radial2VaryingFSName,
-                                    const GrGLShaderVar* radial2Params) {
-    GrStringBuilder cName("c");
-    GrStringBuilder ac4Name("ac4");
-    GrStringBuilder rootName("root");
-
-    cName.appendS32(stageNum);
-    ac4Name.appendS32(stageNum);
-    rootName.appendS32(stageNum);
-
-    GrStringBuilder radial2p0;
-    GrStringBuilder radial2p1;
-    GrStringBuilder radial2p2;
-    GrStringBuilder radial2p3;
-    GrStringBuilder radial2p4;
-    GrStringBuilder radial2p5;
-    radial2Params->appendArrayAccess(0, &radial2p0);
-    radial2Params->appendArrayAccess(1, &radial2p1);
-    radial2Params->appendArrayAccess(2, &radial2p2);
-    radial2Params->appendArrayAccess(3, &radial2p3);
-    radial2Params->appendArrayAccess(4, &radial2p4);
-    radial2Params->appendArrayAccess(5, &radial2p5);
-
-    // if we were able to interpolate the linear component bVar is the varying
-    // otherwise compute it
-    GrStringBuilder bVar;
-    if (segments->fCoordDims == segments->fVaryingDims) {
-        bVar = radial2VaryingFSName;
-        GrAssert(2 == segments->fVaryingDims);
-    } else {
-        GrAssert(3 == segments->fVaryingDims);
-        bVar = "b";
-        bVar.appendS32(stageNum);
-        segments->fFSCode.appendf("\tfloat %s = 2.0 * (%s * %s.x - %s);\n",
-                                    bVar.c_str(), radial2p2.c_str(),
-                                    segments->fSampleCoords.c_str(), radial2p3.c_str());
-    }
-
-    // c = (x^2)+(y^2) - params[4]
-    segments->fFSCode.appendf("\tfloat %s = dot(%s, %s) - %s;\n",
-                              cName.c_str(), segments->fSampleCoords.c_str(),
-                              segments->fSampleCoords.c_str(),
-                              radial2p4.c_str());
-    // ac4 = 4.0 * params[0] * c
-    segments->fFSCode.appendf("\tfloat %s = %s * 4.0 * %s;\n",
-                              ac4Name.c_str(), radial2p0.c_str(),
-                              cName.c_str());
-
-    // root = sqrt(b^2-4ac)
-    // (abs to avoid exception due to fp precision)
-    segments->fFSCode.appendf("\tfloat %s = sqrt(abs(%s*%s - %s));\n",
-                              rootName.c_str(), bVar.c_str(), bVar.c_str(),
-                              ac4Name.c_str());
-
-    // x coord is: (-b + params[5] * sqrt(b^2-4ac)) * params[1]
-    // y coord is 0.5 (texture is effectively 1D)
-    segments->fSampleCoords.printf("vec2((-%s + %s * %s) * %s, 0.5)",
-                        bVar.c_str(), radial2p5.c_str(),
-                        rootName.c_str(), radial2p1.c_str());
-    segments->fComplexCoord = true;
-}
-
-void genRadial2GradientDegenerateCoordMapping(int stageNum,
-                                              GrGLShaderBuilder* segments,
-                                              const char* radial2VaryingFSName,
-                                              const GrGLShaderVar* radial2Params) {
-    GrStringBuilder cName("c");
-
-    cName.appendS32(stageNum);
-
-    GrStringBuilder radial2p2;
-    GrStringBuilder radial2p3;
-    GrStringBuilder radial2p4;
-    radial2Params->appendArrayAccess(2, &radial2p2);
-    radial2Params->appendArrayAccess(3, &radial2p3);
-    radial2Params->appendArrayAccess(4, &radial2p4);
-
-    // if we were able to interpolate the linear component bVar is the varying
-    // otherwise compute it
-    GrStringBuilder bVar;
-    if (segments->fCoordDims == segments->fVaryingDims) {
-        bVar = radial2VaryingFSName;
-        GrAssert(2 == segments->fVaryingDims);
-    } else {
-        GrAssert(3 == segments->fVaryingDims);
-        bVar = "b";
-        bVar.appendS32(stageNum);
-        segments->fFSCode.appendf("\tfloat %s = 2.0 * (%s * %s.x - %s);\n",
-                                    bVar.c_str(), radial2p2.c_str(),
-                                    segments->fSampleCoords.c_str(), radial2p3.c_str());
-    }
-
-    // c = (x^2)+(y^2) - params[4]
-    segments->fFSCode.appendf("\tfloat %s = dot(%s, %s) - %s;\n",
-                              cName.c_str(), segments->fSampleCoords.c_str(),
-                              segments->fSampleCoords.c_str(),
-                              radial2p4.c_str());
-
-    // x coord is: -c/b
-    // y coord is 0.5 (texture is effectively 1D)
-    segments->fSampleCoords.printf("vec2((-%s / %s), 0.5)", cName.c_str(), bVar.c_str());
-    segments->fComplexCoord = true;
-}
-
 void gen2x2FS(int stageNum,
               GrGLShaderBuilder* segments,
               GrGLProgram::StageUniLocations* locations,
@@ -1403,10 +1243,6 @@
     GrAssert((desc.fInConfigFlags & StageDesc::kInConfigBitMask) ==
              desc.fInConfigFlags);
 
-    if (NULL != customStage) {
-        customStage->setupVariables(segments, stageNum);
-    }
-
     /// Vertex Shader Stuff
 
     // decide whether we need a matrix to transform texture coords
@@ -1432,6 +1268,11 @@
     }
     GrAssert(segments->fVaryingDims > 0);
 
+    // Must setup variables after computing segments->fVaryingDims
+    if (NULL != customStage) {
+        customStage->setupVariables(segments, stageNum);
+    }
+
     GrStringBuilder samplerName;
     sampler_name(stageNum, &samplerName);
     const GrGLShaderVar* sampler = &segments->addUniform(
@@ -1465,18 +1306,6 @@
                                   vector_all_coords(segments->fVaryingDims));
     }
 
-    const GrGLShaderVar* radial2Params = NULL;
-    const char* radial2VaryingVSName = NULL;
-    const char* radial2VaryingFSName = NULL;
-
-    if (isRadialMapping((StageDesc::CoordMapping) desc.fCoordMapping)) {
-        radial2Params = genRadialVS(stageNum, segments,
-                                    locations,
-                                    &radial2VaryingVSName,
-                                    &radial2VaryingFSName,
-                                    varyingVSName);
-    }
-
     GrGLShaderVar* kernel = NULL;
     const char* imageIncrementName = NULL;
     if (NULL != customStage) {
@@ -1495,46 +1324,19 @@
     if (desc.fOptFlags & (StageDesc::kIdentityMatrix_OptFlagBit |
                           StageDesc::kNoPerspective_OptFlagBit)) {
         sampleMode = GrGLShaderBuilder::kDefault_SamplerMode;
-    } else if (StageDesc::kIdentity_CoordMapping == desc.fCoordMapping &&
+    } else if (NULL == customStage &&
                StageDesc::kSingle_FetchMode == desc.fFetchMode) {
         sampleMode = GrGLShaderBuilder::kProj_SamplerMode;
     }
     segments->setupTextureAccess(sampleMode, stageNum);
 
-    // NOTE: GrGLProgramStages will soon responsible for mapping
-    //if (NULL == customStage) {
-        switch (desc.fCoordMapping) {
-        case StageDesc::kIdentity_CoordMapping:
-            // Do nothing
-            break;
-        case StageDesc::kSweepGradient_CoordMapping:
-            segments->fSampleCoords.printf("vec2(atan(- %s.y, - %s.x) * 0.1591549430918 + 0.5, 0.5)", segments->fSampleCoords.c_str(), segments->fSampleCoords.c_str());
-            segments->fComplexCoord = true;
-            break;
-        case StageDesc::kRadialGradient_CoordMapping:
-            segments->fSampleCoords.printf("vec2(length(%s.xy), 0.5)", segments->fSampleCoords.c_str());
-            segments->fComplexCoord = true;
-            break;
-        case StageDesc::kRadial2Gradient_CoordMapping:
-            genRadial2GradientCoordMapping(
-                               stageNum, segments,
-                               radial2VaryingFSName, radial2Params);
-            break;
-        case StageDesc::kRadial2GradientDegenerate_CoordMapping:
-            genRadial2GradientDegenerateCoordMapping(
-                               stageNum, segments,
-                               radial2VaryingFSName, radial2Params);
-            break;
-        }
-    //}
+    segments->computeSwizzle(desc.fInConfigFlags);
+    segments->computeModulate(fsInColor);
 
     static const uint32_t kMulByAlphaMask =
         (StageDesc::kMulRGBByAlpha_RoundUp_InConfigFlag |
          StageDesc::kMulRGBByAlpha_RoundDown_InConfigFlag);
 
-    segments->computeSwizzle(desc.fInConfigFlags);
-    segments->computeModulate(fsInColor);
-
     if (desc.fOptFlags & StageDesc::kCustomTextureDomain_OptFlagBit) {
         GrStringBuilder texDomainName;
         tex_domain_name(stageNum, &texDomainName);
diff --git a/src/gpu/gl/GrGLProgram.h b/src/gpu/gl/GrGLProgram.h
index 393311e..f638eab 100644
--- a/src/gpu/gl/GrGLProgram.h
+++ b/src/gpu/gl/GrGLProgram.h
@@ -162,21 +162,10 @@
                 kInConfigBitMask = (kDummyInConfigFlag-1) |
                                    (kDummyInConfigFlag-2)
             };
-            enum CoordMapping {
-                kIdentity_CoordMapping,
-                kRadialGradient_CoordMapping,
-                kSweepGradient_CoordMapping,
-                kRadial2Gradient_CoordMapping,
-                // need different shader computation when quadratic
-                // eq describing the gradient degenerates to a linear eq.
-                kRadial2GradientDegenerate_CoordMapping,
-                kCoordMappingCnt
-            };
 
             uint8_t fOptFlags;
             uint8_t fInConfigFlags; // bitfield of InConfigFlags values
             uint8_t fFetchMode;     // casts to enum FetchMode
-            uint8_t fCoordMapping;  // casts to enum CoordMapping
 
             /** Non-zero if user-supplied code will write the stage's
                 contribution to the fragment shader. */
@@ -263,13 +252,11 @@
         GrGLint fTextureMatrixUni;
         GrGLint fNormalizedTexelSizeUni;
         GrGLint fSamplerUni;
-        GrGLint fRadial2Uni;
         GrGLint fTexDomUni;
         void reset() {
             fTextureMatrixUni = kUnusedUniform;
             fNormalizedTexelSizeUni = kUnusedUniform;
             fSamplerUni = kUnusedUniform;
-            fRadial2Uni = kUnusedUniform;
             fTexDomUni = kUnusedUniform;
         }
     };
@@ -333,9 +320,6 @@
         // width and height used for normalized texel size
         int                         fTextureWidth[GrDrawState::kNumStages];
         int                         fTextureHeight[GrDrawState::kNumStages]; 
-        GrScalar                    fRadial2CenterX1[GrDrawState::kNumStages];
-        GrScalar                    fRadial2Radius0[GrDrawState::kNumStages];
-        bool                        fRadial2PosRoot[GrDrawState::kNumStages];
         GrRect                      fTextureDomain[GrDrawState::kNumStages];
         // The texture domain and texture matrix sent to GL depend upon the
         // orientation.
diff --git a/src/gpu/gl/GrGpuGL.h b/src/gpu/gl/GrGpuGL.h
index fd6ba8f..b0a7bdc 100644
--- a/src/gpu/gl/GrGpuGL.h
+++ b/src/gpu/gl/GrGpuGL.h
@@ -181,7 +181,6 @@
 
     // adjusts texture matrix to account for orientation
     static void AdjustTextureMatrix(const GrGLTexture* texture,
-                                    GrSamplerState::SampleMode mode,
                                     GrMatrix* matrix);
 
     // subclass may try to take advantage of identity tex matrices.
diff --git a/src/gpu/gl/GrGpuGL_program.cpp b/src/gpu/gl/GrGpuGL_program.cpp
index afbe809..e79afe1 100644
--- a/src/gpu/gl/GrGpuGL_program.cpp
+++ b/src/gpu/gl/GrGpuGL_program.cpp
@@ -7,6 +7,8 @@
 
 #include "GrGpuGL.h"
 
+#include "effects/GrGradientEffects.h"
+
 #include "GrCustomStage.h"
 #include "GrGLProgramStage.h"
 #include "GrGpuVertex.h"
@@ -148,7 +150,6 @@
 // helpers for texture matrices
 
 void GrGpuGL::AdjustTextureMatrix(const GrGLTexture* texture,
-                                  GrSamplerState::SampleMode mode,
                                   GrMatrix* matrix) {
     GrAssert(NULL != texture);
     GrAssert(NULL != matrix);
@@ -200,9 +201,7 @@
             (orientationChange || !hwMatrix.cheapEqualTo(samplerMatrix))) {
 
             GrMatrix m = samplerMatrix;
-            GrSamplerState::SampleMode mode =
-                drawState.getSampler(s).getSampleMode();
-            AdjustTextureMatrix(texture, mode, &m);
+            AdjustTextureMatrix(texture, &m);
 
             // ES doesn't allow you to pass true to the transpose param,
             // so do our own transpose
@@ -251,40 +250,6 @@
     }
 }
 
-void GrGpuGL::flushRadial2(int s) {
-
-    const int &uni = fProgramData->fUniLocations.fStages[s].fRadial2Uni;
-    const GrSamplerState& sampler = this->getDrawState().getSampler(s);
-    if (GrGLProgram::kUnusedUniform != uni &&
-        (fProgramData->fRadial2CenterX1[s] != sampler.getRadial2CenterX1() ||
-         fProgramData->fRadial2Radius0[s]  != sampler.getRadial2Radius0()  ||
-         fProgramData->fRadial2PosRoot[s]  != sampler.isRadial2PosRoot())) {
-
-        GrScalar centerX1 = sampler.getRadial2CenterX1();
-        GrScalar radius0 = sampler.getRadial2Radius0();
-
-        GrScalar a = GrMul(centerX1, centerX1) - GR_Scalar1;
-
-        // when were in the degenerate (linear) case the second
-        // value will be INF but the program doesn't read it. (We
-        // use the same 6 uniforms even though we don't need them
-        // all in the linear case just to keep the code complexity
-        // down).
-        float values[6] = {
-            GrScalarToFloat(a),
-            1 / (2.f * GrScalarToFloat(a)),
-            GrScalarToFloat(centerX1),
-            GrScalarToFloat(radius0),
-            GrScalarToFloat(GrMul(radius0, radius0)),
-            sampler.isRadial2PosRoot() ? 1.f : -1.f
-        };
-        GL_CALL(Uniform1fv(uni, 6, values));
-        fProgramData->fRadial2CenterX1[s] = sampler.getRadial2CenterX1();
-        fProgramData->fRadial2Radius0[s]  = sampler.getRadial2Radius0();
-        fProgramData->fRadial2PosRoot[s]  = sampler.isRadial2PosRoot();
-    }
-}
-
 void GrGpuGL::flushTexelSize(int s) {
     const int& uni = fProgramData->fUniLocations.fStages[s].fNormalizedTexelSizeUni;
     if (GrGLProgram::kUnusedUniform != uni) {
@@ -475,8 +440,6 @@
         if (this->isStageEnabled(s)) {
             this->flushTextureMatrixAndDomain(s);
 
-            this->flushRadial2(s);
-
             this->flushTexelSize(s);
 
             if (NULL != fProgramData->fCustomStage[s]) {
@@ -773,29 +736,6 @@
             } else if (!sampler.getMatrix().hasPerspective()) {
                 stage.fOptFlags |= StageDesc::kNoPerspective_OptFlagBit;
             }
-            switch (sampler.getSampleMode()) {
-                case GrSamplerState::kNormal_SampleMode:
-                    stage.fCoordMapping = StageDesc::kIdentity_CoordMapping;
-                    break;
-                case GrSamplerState::kRadial_SampleMode:
-                    stage.fCoordMapping = StageDesc::kRadialGradient_CoordMapping;
-                    break;
-                case GrSamplerState::kRadial2_SampleMode:
-                    if (sampler.radial2IsDegenerate()) {
-                        stage.fCoordMapping =
-                            StageDesc::kRadial2GradientDegenerate_CoordMapping;
-                    } else {
-                        stage.fCoordMapping =
-                            StageDesc::kRadial2Gradient_CoordMapping;
-                    }
-                    break;
-                case GrSamplerState::kSweep_SampleMode:
-                    stage.fCoordMapping = StageDesc::kSweepGradient_CoordMapping;
-                    break;
-                default:
-                    GrCrash("Unexpected sample mode!");
-                    break;
-            }
 
             switch (sampler.getFilter()) {
                 // these both can use a regular texture2D()
@@ -858,7 +798,6 @@
 
         } else {
             stage.fOptFlags         = 0;
-            stage.fCoordMapping     = (StageDesc::CoordMapping) 0;
             stage.fInConfigFlags    = 0;
             stage.fFetchMode        = (StageDesc::FetchMode) 0;
             stage.fCustomStageKey   = 0;
diff --git a/src/gpu/gl/GrGpuGL_unittest.cpp b/src/gpu/gl/GrGpuGL_unittest.cpp
index 3f923f7..498823d 100644
--- a/src/gpu/gl/GrGpuGL_unittest.cpp
+++ b/src/gpu/gl/GrGpuGL_unittest.cpp
@@ -1,6 +1,7 @@
 #include "GrGpuGL.h"
 
 #include "effects/GrConvolutionEffect.h"
+#include "effects/GrGradientEffects.h"
 #include "effects/GrMorphologyEffect.h"
 #include "GrProgramStageFactory.h"
 #include "GrRandom.h"
@@ -32,6 +33,9 @@
         kConvolution_EffectType,
         kErode_EffectType,
         kDilate_EffectType,
+        kRadialGradient_EffectType,
+        kRadial2Gradient_EffectType,
+        kSweepGradient_EffectType,
 
         kEffectCount
     };
@@ -85,6 +89,21 @@
                                           kernelRadius,
                                           GrContext::kDilate_MorphologyType);
             }
+        case kRadialGradient_EffectType: {
+            return new GrRadialGradient();
+            }
+        case kRadial2Gradient_EffectType: {
+            float center;
+            do {
+                center = random->nextF();
+            } while (GR_Scalar1 == center);
+            float radius = random->nextF();
+            bool root = random_bool(random);
+            return new GrRadial2Gradient(center, radius, root);
+            }
+        case kSweepGradient_EffectType: {
+            return new GrSweepGradient();
+            }
         default:
             GrCrash("Unexpected custom effect type");
     }
@@ -99,7 +118,6 @@
     static const int STAGE_OPTS[] = {
         0,
         StageDesc::kNoPerspective_OptFlagBit,
-        StageDesc::kIdentity_CoordMapping
     };
     static const int IN_CONFIG_FLAGS[] = {
         StageDesc::kNone_InConfigFlag,
@@ -187,7 +205,6 @@
 
             stage.fOptFlags = STAGE_OPTS[random_int(&random, GR_ARRAY_COUNT(STAGE_OPTS))];
             stage.fInConfigFlags = IN_CONFIG_FLAGS[random_int(&random, GR_ARRAY_COUNT(IN_CONFIG_FLAGS))];
-            stage.fCoordMapping =  random_int(&random, StageDesc::kCoordMappingCnt);
             stage.fFetchMode = random_int(&random, StageDesc::kFetchModeCnt);
             stage.setEnabled(VertexUsesStage(s, pdesc.fVertexLayout));
             static const uint32_t kMulByAlphaMask =