Make shader generator more legible. Get rid of some magic values.

Review URL: http://codereview.appspot.com/4531043/


git-svn-id: http://skia.googlecode.com/svn/trunk@1281 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/gpu/src/GrGLProgram.cpp b/gpu/src/GrGLProgram.cpp
index 76a7f10..f0245af 100644
--- a/gpu/src/GrGLProgram.cpp
+++ b/gpu/src/GrGLProgram.cpp
@@ -20,7 +20,6 @@
 #include "GrGLConfig.h"
 #include "GrGLEffect.h"
 #include "GrMemory.h"
-#include "GrStringBuilder.h"
 
 namespace {
 
@@ -28,7 +27,7 @@
     if (GR_GL_SUPPORT_ES2) {
         return "mediump";
     } else {
-        return "";
+        return " ";
     }
 }
 
@@ -54,9 +53,6 @@
 #define COL_ATTR_NAME "aColor"
 #define COL_UNI_NAME "uColor"
 
-// for variable names etc
-typedef GrStringBuilder GrTokenString;
-
 static inline void tex_attr_name(int coordIdx, GrStringBuilder* s) {
     *s = "aTexCoord";
     s->appendS32(coordIdx);
@@ -127,7 +123,6 @@
 }
 
 GrGLProgram::~GrGLProgram() {
-
 }
 
 void GrGLProgram::buildKey(GrBinHashKeyBuilder& key) const {
@@ -179,36 +174,40 @@
     }
 }
 
-void GrGLProgram::genProgram(GrGLProgram::CachedData* programData) const {
+bool GrGLProgram::genProgram(GrGLProgram::CachedData* programData) const {
 
     ShaderCodeSegments segments;
     const uint32_t& layout = fProgramDesc.fVertexLayout;
 
-    memset(&programData->fUniLocations, 0, sizeof(UniLocations));
+    programData->fUniLocations.reset();
 
 #if GR_GL_ATTRIBUTE_MATRICES
     segments.fVSAttrs += "attribute mat3 " VIEW_MATRIX_NAME ";\n";
+    programData->fUniLocations.fViewMatrixUni = kSetAsAttribute;
 #else
     segments.fVSUnis  += "uniform mat3 " VIEW_MATRIX_NAME ";\n";
+    programData->fUniLocations.fViewMatrixUni = kUseUniform;
 #endif
     segments.fVSAttrs += "attribute vec2 " POS_ATTR_NAME ";\n";
 
-    segments.fVSCode   = "void main() {\n"
-                         "\tvec3 pos3 = " VIEW_MATRIX_NAME " * vec3(" POS_ATTR_NAME ", 1);\n"
-                         "\tgl_Position = vec4(pos3.xy, 0, pos3.z);\n";
+    segments.fVSCode.append(
+        "void main() {\n"
+            "\tvec3 pos3 = " VIEW_MATRIX_NAME " * vec3("POS_ATTR_NAME", 1);\n"
+            "\tgl_Position = vec4(pos3.xy, 0, pos3.z);\n");
 
-        // incoming color to current stage being processed.
-    GrTokenString inColor;
+    // incoming color to current stage being processed.
+    GrStringBuilder inColor;
 
     switch (fProgramDesc.fColorType) {
     case ProgramDesc::kAttribute_ColorType:
-        segments.fVSAttrs += "attribute vec4 " COL_ATTR_NAME ";\n";
-        segments.fVaryings += "varying vec4 vColor;\n";
-        segments.fVSCode += "\tvColor = " COL_ATTR_NAME ";\n";
+        segments.fVSAttrs.append( "attribute vec4 " COL_ATTR_NAME ";\n");
+        segments.fVaryings.append("varying vec4 vColor;\n");
+        segments.fVSCode.append(    "\tvColor = " COL_ATTR_NAME ";\n");
         inColor = "vColor";
         break;
     case ProgramDesc::kUniform_ColorType:
-        segments.fFSUnis += "uniform vec4 " COL_UNI_NAME ";\n";
+        segments.fFSUnis.append(  "uniform vec4 " COL_UNI_NAME ";\n");
+        programData->fUniLocations.fColorUni = kUseUniform;
         inColor = COL_UNI_NAME;
         break;
     case ProgramDesc::kNone_ColorType:
@@ -217,20 +216,17 @@
     }
 
     if (fProgramDesc.fEmitsPointSize){
-        segments.fVSCode += "\tgl_PointSize = 1.0;\n";
+        segments.fVSCode.append("\tgl_PointSize = 1.0;\n");
     }
 
-    segments.fFSCode   = "void main() {\n";
+    segments.fFSCode.append("void main() {\n");
 
     // add texture coordinates that are used to the list of vertex attr decls
-    GrTokenString texCoordAttrs[GrDrawTarget::kMaxTexCoords];
+    GrStringBuilder texCoordAttrs[GrDrawTarget::kMaxTexCoords];
     for (int t = 0; t < GrDrawTarget::kMaxTexCoords; ++t) {
         if (GrDrawTarget::VertexUsesTexCoordIdx(t, layout)) {
             tex_attr_name(t, texCoordAttrs + t);
-
-            segments.fVSAttrs += "attribute vec2 ";
-            segments.fVSAttrs += texCoordAttrs[t];
-            segments.fVSAttrs += ";\n";
+            segments.fVSAttrs.appendf("attribute vec2 %s;\n", texCoordAttrs[t].c_str());
         }
     }
 
@@ -260,13 +256,11 @@
         int currActiveStage = 0;
         for (int s = 0; s < GrDrawTarget::kNumStages; ++s) {
             if (fProgramDesc.fStages[s].fEnabled) {
-                GrTokenString outColor;
+                GrStringBuilder outColor;
                 if (currActiveStage < (numActiveStages - 1)) {
                     outColor = "color";
                     outColor.appendS32(currActiveStage);
-                    segments.fFSCode += "\tvec4 ";
-                    segments.fFSCode += outColor;
-                    segments.fFSCode += ";\n";
+                    segments.fFSCode.appendf("\tvec4 %s;\n", outColor.c_str());
                 } else {
                     outColor = "gl_FragColor";
                 }
@@ -283,16 +277,27 @@
             }
         }
     } else {
-        segments.fFSCode += "\tgl_FragColor = ";
-        if (inColor.size()) {
-            segments.fFSCode += inColor;
-        } else {
-            segments.fFSCode += "vec4(1,1,1,1)";
-        }
-        segments.fFSCode += ";\n";
+        // we may not have any incoming color
+        segments.fFSCode.appendf("\tgl_FragColor = %s;\n", (inColor.size() ? inColor.c_str() : "vec4(1,1,1,1);\n"));
     }
-    segments.fFSCode += "}\n";
-    segments.fVSCode += "}\n";
+    segments.fVSCode.append("}\n");
+    segments.fFSCode.append("}\n");
+
+    if (!CompileFSAndVS(segments, programData)) {
+        return false;
+    }
+
+    if (!this->bindAttribsAndLinkProgram(texCoordAttrs, programData)) {
+        return false;
+    }
+
+    this->getUniformLocationsAndInitCache(programData);
+
+    return true;
+}
+
+bool GrGLProgram::CompileFSAndVS(const ShaderCodeSegments& segments,
+                                 CachedData* programData) {
 
     const char* strings[4];
     int lengths[4];
@@ -331,6 +336,10 @@
                                         strings,
                                         lengths);
 
+    if (!programData->fVShaderID) {
+        return false;
+    }
+
     stringCnt = 0;
 
     if (strlen(GrShaderPrecision()) > 1) {
@@ -366,151 +375,10 @@
                                             strings,
                                             lengths);
 
-    programData->fProgramID = GR_GL(CreateProgram());
-    const GrGLint& progID = programData->fProgramID;
-
-    GR_GL(AttachShader(progID, programData->fVShaderID));
-    GR_GL(AttachShader(progID, programData->fFShaderID));
-
-    // Bind the attrib locations to same values for all shaders
-    GR_GL(BindAttribLocation(progID, POS_ATTR_LOCATION, POS_ATTR_NAME));
-    for (int t = 0; t < GrDrawTarget::kMaxTexCoords; ++t) {
-        if (texCoordAttrs[t].size()) {
-            GR_GL(BindAttribLocation(progID,
-                                     TEX_ATTR_LOCATION(t),
-                                     texCoordAttrs[t].c_str()));
-        }
+    if (!programData->fFShaderID) {
+        return false;
     }
-
-#if GR_GL_ATTRIBUTE_MATRICES
-    // set unis to a bogus value so that checks against -1 before
-    // flushing will pass.
-    GR_GL(BindAttribLocation(progID,
-                             VIEWMAT_ATTR_LOCATION,
-                             VIEW_MATRIX_NAME));
-
-    program->fUniLocations.fViewMatrixUni = BOGUS_MATRIX_UNI_LOCATION;
-
-    for (int s = 0; s < kNumStages; ++s) {
-        if (fProgramDesc.fStages[s].fEnabled) {
-            GrStringBuilder matName;
-            tex_matrix_name(s, &matName);
-            GR_GL(BindAttribLocation(progID,
-                                     TEXMAT_ATTR_LOCATION(s),
-                                     matName.c_str()));
-            program->fUniLocations.fStages[s].fTextureMatrixUni =
-                                                    BOGUS_MATRIX_UNI_LOCATION;
-        }
-    }
-#endif
-
-    GR_GL(BindAttribLocation(progID, COL_ATTR_LOCATION, COL_ATTR_NAME));
-
-    GR_GL(LinkProgram(progID));
-
-    GrGLint linked = GR_GL_INIT_ZERO;
-    GR_GL(GetProgramiv(progID, GR_GL_LINK_STATUS, &linked));
-    if (!linked) {
-        GrGLint infoLen = GR_GL_INIT_ZERO;
-        GR_GL(GetProgramiv(progID, GR_GL_INFO_LOG_LENGTH, &infoLen));
-        GrAutoMalloc log(sizeof(char)*(infoLen+1));  // outside if for debugger
-        if (infoLen > 0) {
-            GR_GL(GetProgramInfoLog(progID,
-                                    infoLen+1,
-                                    NULL,
-                                    (char*)log.get()));
-            GrPrintf((char*)log.get());
-        }
-        GrAssert(!"Error linking program");
-        GR_GL(DeleteProgram(progID));
-        programData->fProgramID = 0;
-        return;
-    }
-
-    // Get uniform locations
-#if !GR_GL_ATTRIBUTE_MATRICES
-    programData->fUniLocations.fViewMatrixUni =
-                    GR_GL(GetUniformLocation(progID, VIEW_MATRIX_NAME));
-    GrAssert(-1 != programData->fUniLocations.fViewMatrixUni);
-#endif
-    if (ProgramDesc::kUniform_ColorType == fProgramDesc.fColorType) {
-        programData->fUniLocations.fColorUni = 
-                                GR_GL(GetUniformLocation(progID, COL_UNI_NAME));
-        GrAssert(-1 != programData->fUniLocations.fColorUni);
-    } else {
-        programData->fUniLocations.fColorUni = -1;
-    }
-
-    for (int s = 0; s < GrDrawTarget::kNumStages; ++s) {
-        StageUniLocations& locations = programData->fUniLocations.fStages[s];
-        if (fProgramDesc.fStages[s].fEnabled) {
-#if !GR_GL_ATTRIBUTE_MATRICES
-            if (locations.fTextureMatrixUni) {
-                GrTokenString texMName;
-                tex_matrix_name(s, &texMName);
-                locations.fTextureMatrixUni = GR_GL(GetUniformLocation(
-                                                progID,
-                                                texMName.c_str()));
-                GrAssert(-1 != locations.fTextureMatrixUni);
-            } else {
-                locations.fTextureMatrixUni = -1;
-
-            }
-#endif
-
-            if (locations.fSamplerUni) {
-                GrTokenString samplerName;
-                sampler_name(s, &samplerName);
-                locations.fSamplerUni = GR_GL(GetUniformLocation(
-                                                     progID,
-                                                     samplerName.c_str()));
-                GrAssert(-1 != locations.fSamplerUni);
-            } else {
-                locations.fSamplerUni = -1;
-            }
-
-            if (locations.fNormalizedTexelSizeUni) {
-                GrTokenString texelSizeName;
-                normalized_texel_size_name(s, &texelSizeName);
-                locations.fNormalizedTexelSizeUni = 
-                   GR_GL(GetUniformLocation(progID, texelSizeName.c_str()));
-                GrAssert(-1 != locations.fNormalizedTexelSizeUni);
-            } else {
-                locations.fNormalizedTexelSizeUni = -1;
-            }
-
-            if (locations.fRadial2Uni) {
-                GrTokenString radial2ParamName;
-                radial2_param_name(s, &radial2ParamName);
-                locations.fRadial2Uni = GR_GL(GetUniformLocation(
-                                             progID,
-                                             radial2ParamName.c_str()));
-                GrAssert(-1 != locations.fRadial2Uni);
-            } else {
-                locations.fRadial2Uni = -1;
-            }
-        } else {
-            locations.fSamplerUni = -1;
-            locations.fRadial2Uni = -1;
-            locations.fTextureMatrixUni = -1;
-            locations.fNormalizedTexelSizeUni = -1;
-        }
-    }
-    GR_GL(UseProgram(progID));
-
-    // init sampler unis and set bogus values for state tracking
-    for (int s = 0; s < GrDrawTarget::kNumStages; ++s) {
-        if (-1 != programData->fUniLocations.fStages[s].fSamplerUni) {
-            GR_GL(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->fViewMatrix = GrMatrix::InvalidMatrix();
-    programData->fColor = GrColor_ILLEGAL;
+    return true;
 }
 
 GrGLuint GrGLProgram::CompileShader(GrGLenum type,
@@ -549,6 +417,141 @@
     return shader;
 }
 
+bool GrGLProgram::bindAttribsAndLinkProgram(GrStringBuilder texCoordAttrNames[],
+                                            CachedData* programData) const {
+    programData->fProgramID = GR_GL(CreateProgram());
+    if (!programData->fProgramID) {
+        return false;
+    }
+    const GrGLint& progID = programData->fProgramID;
+
+    GR_GL(AttachShader(progID, programData->fVShaderID));
+    GR_GL(AttachShader(progID, programData->fFShaderID));
+
+    // Bind the attrib locations to same values for all shaders
+    GR_GL(BindAttribLocation(progID, PositionAttributeIdx(), POS_ATTR_NAME));
+    for (int t = 0; t < GrDrawTarget::kMaxTexCoords; ++t) {
+        if (texCoordAttrNames[t].size()) {
+            GR_GL(BindAttribLocation(progID,
+                                     TexCoordAttributeIdx(t),
+                                     texCoordAttrNames[t].c_str()));
+        }
+    }
+
+
+    if (kSetAsAttribute == programData->fUniLocations.fViewMatrixUni) {
+        GR_GL(BindAttribLocation(progID,
+                             ViewMatrixAttributeIdx(),
+                             VIEW_MATRIX_NAME));
+    }
+
+    for (int s = 0; s < GrDrawTarget::kNumStages; ++s) {
+        const ProgramDesc::StageDesc& desc = fProgramDesc.fStages[s];
+        if (kSetAsAttribute == programData->fUniLocations.fStages[s].fTextureMatrixUni) {
+            GrStringBuilder matName;
+            tex_matrix_name(s, &matName);
+            GR_GL(BindAttribLocation(progID,
+                                     TextureMatrixAttributeIdx(s),
+                                     matName.c_str()));
+        }
+    }
+
+
+    GR_GL(BindAttribLocation(progID, ColorAttributeIdx(), COL_ATTR_NAME));
+
+    GR_GL(LinkProgram(progID));
+
+    GrGLint linked = GR_GL_INIT_ZERO;
+    GR_GL(GetProgramiv(progID, GR_GL_LINK_STATUS, &linked));
+    if (!linked) {
+        GrGLint infoLen = GR_GL_INIT_ZERO;
+        GR_GL(GetProgramiv(progID, GR_GL_INFO_LOG_LENGTH, &infoLen));
+        GrAutoMalloc log(sizeof(char)*(infoLen+1));  // outside if for debugger
+        if (infoLen > 0) {
+            GR_GL(GetProgramInfoLog(progID,
+                                    infoLen+1,
+                                    NULL,
+                                    (char*)log.get()));
+            GrPrintf((char*)log.get());
+        }
+        GrAssert(!"Error linking program");
+        GR_GL(DeleteProgram(progID));
+        programData->fProgramID = 0;
+        return false;
+    }
+    return true;
+}
+
+void GrGLProgram::getUniformLocationsAndInitCache(CachedData* programData) const {
+    const GrGLint& progID = programData->fProgramID;
+
+    if (kUseUniform == programData->fUniLocations.fViewMatrixUni) {
+        programData->fUniLocations.fViewMatrixUni =
+                        GR_GL(GetUniformLocation(progID, VIEW_MATRIX_NAME));
+        GrAssert(kUnusedUniform != programData->fUniLocations.fViewMatrixUni);
+    }
+    if (kUseUniform == programData->fUniLocations.fColorUni) {
+        programData->fUniLocations.fColorUni = 
+                                GR_GL(GetUniformLocation(progID, COL_UNI_NAME));
+        GrAssert(kUnusedUniform != programData->fUniLocations.fColorUni);
+    }
+
+    for (int s = 0; s < GrDrawTarget::kNumStages; ++s) {
+        StageUniLocations& locations = programData->fUniLocations.fStages[s];
+        if (fProgramDesc.fStages[s].fEnabled) {
+            if (kUseUniform == locations.fTextureMatrixUni) {
+                GrStringBuilder texMName;
+                tex_matrix_name(s, &texMName);
+                locations.fTextureMatrixUni = GR_GL(GetUniformLocation(
+                                                progID,
+                                                texMName.c_str()));
+                GrAssert(kUnusedUniform != locations.fTextureMatrixUni);
+            }
+
+            if (kUseUniform == locations.fSamplerUni) {
+                GrStringBuilder samplerName;
+                sampler_name(s, &samplerName);
+                locations.fSamplerUni = GR_GL(GetUniformLocation(
+                                                     progID,
+                                                     samplerName.c_str()));
+                GrAssert(kUnusedUniform != locations.fSamplerUni);
+            }
+
+            if (kUseUniform == locations.fNormalizedTexelSizeUni) {
+                GrStringBuilder texelSizeName;
+                normalized_texel_size_name(s, &texelSizeName);
+                locations.fNormalizedTexelSizeUni = 
+                   GR_GL(GetUniformLocation(progID, texelSizeName.c_str()));
+                GrAssert(kUnusedUniform != locations.fNormalizedTexelSizeUni);
+            }
+
+            if (kUseUniform == locations.fRadial2Uni) {
+                GrStringBuilder radial2ParamName;
+                radial2_param_name(s, &radial2ParamName);
+                locations.fRadial2Uni = GR_GL(GetUniformLocation(
+                                             progID,
+                                             radial2ParamName.c_str()));
+                GrAssert(kUnusedUniform != locations.fRadial2Uni);
+            }
+        }
+    }
+    GR_GL(UseProgram(progID));
+
+    // init sampler unis and set bogus values for state tracking
+    for (int s = 0; s < GrDrawTarget::kNumStages; ++s) {
+        if (kUnusedUniform != programData->fUniLocations.fStages[s].fSamplerUni) {
+            GR_GL(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->fViewMatrix = GrMatrix::InvalidMatrix();
+    programData->fColor = GrColor_ILLEGAL;
+}
+
 //============================================================================
 // Stage code generation
 //============================================================================
@@ -563,7 +566,7 @@
 
     GrAssert(stageNum >= 0 && stageNum <= 9);
 
-    GrTokenString varyingName;
+    GrStringBuilder varyingName;
     stage_varying_name(stageNum, &varyingName);
 
     // First decide how many coords are needed to access the texture
@@ -575,20 +578,17 @@
 
     // decide whether we need a matrix to transform texture coords
     // and whether the varying needs a perspective coord.
-    GrTokenString texMName;
+    GrStringBuilder texMName;
     tex_matrix_name(stageNum, &texMName);
     if (desc.fOptFlags & ProgramDesc::StageDesc::kIdentityMatrix_OptFlagBit) {
         varyingDims = coordDims;
     } else {
     #if GR_GL_ATTRIBUTE_MATRICES
-        segments->fVSAttrs += "attribute mat3 ";
-        segments->fVSAttrs += texMName;
-        segments->fVSAttrs += ";\n";
+        segments->fVSAttrs.appendf("attribute mat3 %s;\n", texMName.c_str());
+        locations->fTextureMatrixUni = kSetAsAttribute;
     #else
-        segments->fVSUnis += "uniform mat3 ";
-        segments->fVSUnis += texMName;
-        segments->fVSUnis += ";\n";
-        locations->fTextureMatrixUni = 1;
+        segments->fVSUnis.appendf("uniform mat3 %s;\n", texMName.c_str());
+        locations->fTextureMatrixUni = kUseUniform;
     #endif
         if (desc.fOptFlags & ProgramDesc::StageDesc::kNoPerspective_OptFlagBit) {
             varyingDims = coordDims;
@@ -597,92 +597,61 @@
         }
     }
 
-    GrTokenString samplerName;
+    GrStringBuilder samplerName;
     sampler_name(stageNum, &samplerName);
-    segments->fFSUnis += "uniform sampler2D ";
-    segments->fFSUnis += samplerName;
-    segments->fFSUnis += ";\n";
-    locations->fSamplerUni = 1;
+    segments->fFSUnis.appendf("uniform sampler2D %s;\n", samplerName.c_str());
+    locations->fSamplerUni = kUseUniform;
 
-    GrTokenString texelSizeName;
+    GrStringBuilder texelSizeName;
     if (ProgramDesc::StageDesc::k2x2_FetchMode == desc.fFetchMode) {
         normalized_texel_size_name(stageNum, &texelSizeName);
-        segments->fFSUnis += "uniform vec2 ";
-        segments->fFSUnis += texelSizeName;
-        segments->fFSUnis += ";\n";
+        segments->fFSUnis.appendf("uniform vec2 %s;\n", texelSizeName.c_str());
     }
 
-    segments->fVaryings += "varying ";
-    segments->fVaryings += float_vector_type(varyingDims);
-    segments->fVaryings += " ";
-    segments->fVaryings += varyingName;
-    segments->fVaryings += ";\n";
+    segments->fVaryings.appendf("varying %s %s;\n", 
+                                float_vector_type(varyingDims), varyingName.c_str());
 
     if (desc.fOptFlags & ProgramDesc::StageDesc::kIdentityMatrix_OptFlagBit) {
         GrAssert(varyingDims == coordDims);
-        segments->fVSCode += "\t";
-        segments->fVSCode += varyingName;
-        segments->fVSCode += " = ";
-        segments->fVSCode += vsInCoord;
-        segments->fVSCode += ";\n";
+        segments->fVSCode.appendf("\t%s = %s;\n", varyingName.c_str(), vsInCoord);
     } else {
-        segments->fVSCode += "\t";
-        segments->fVSCode += varyingName;
-        segments->fVSCode += " = (";
-        segments->fVSCode += texMName;
-        segments->fVSCode += " * vec3(";
-        segments->fVSCode += vsInCoord;
-        segments->fVSCode += ", 1))";
-        segments->fVSCode += vector_all_coords(varyingDims);
-        segments->fVSCode += ";\n";
+        // varying = texMatrix * texCoord
+        segments->fVSCode.appendf("\t%s = (%s * vec3(%s, 1))%s;\n",
+                                  varyingName.c_str(), texMName.c_str(),
+                                  vsInCoord, vector_all_coords(varyingDims));
     }
 
-    GrTokenString radial2ParamsName;
+    GrStringBuilder radial2ParamsName;
     radial2_param_name(stageNum, &radial2ParamsName);
     // for radial grads without perspective we can pass the linear
     // part of the quadratic as a varying.
-    GrTokenString radial2VaryingName;
+    GrStringBuilder radial2VaryingName;
     radial2_varying_name(stageNum, &radial2VaryingName);
 
     if (ProgramDesc::StageDesc::kRadial2Gradient_CoordMapping == desc.fCoordMapping) {
 
-        segments->fVSUnis += "uniform ";
-        segments->fVSUnis += GrPrecision();
-        segments->fVSUnis += " float ";
-        segments->fVSUnis += radial2ParamsName;
-        segments->fVSUnis += "[6];\n";
-
-        segments->fFSUnis += "uniform ";
-        segments->fFSUnis += GrPrecision();
-        segments->fFSUnis += " float ";
-        segments->fFSUnis += radial2ParamsName;
-        segments->fFSUnis += "[6];\n";
-        locations->fRadial2Uni = 1;
+        segments->fVSUnis.appendf("uniform %sfloat %s[6];\n", 
+                                  GrPrecision(), radial2ParamsName.c_str());
+        segments->fFSUnis.appendf("uniform float %s[6];\n", 
+                                  radial2ParamsName.c_str());
+        locations->fRadial2Uni = kUseUniform;
 
         // if there is perspective we don't interpolate this
         if (varyingDims == coordDims) {
             GrAssert(2 == coordDims);
-            segments->fVaryings += "varying float ";
-            segments->fVaryings += radial2VaryingName;
-            segments->fVaryings += ";\n";
+            segments->fVaryings.appendf("varying float %s;\n", radial2VaryingName.c_str());
 
-            segments->fVSCode += "\t";
-            segments->fVSCode += radial2VaryingName;
-            segments->fVSCode += " = 2.0 * (";
-            segments->fVSCode += radial2ParamsName;
-            segments->fVSCode += "[2] * ";
-            segments->fVSCode += varyingName;
-            segments->fVSCode += ".x ";
-            segments->fVSCode += " - ";
-            segments->fVSCode += radial2ParamsName;
-            segments->fVSCode += "[3]);\n";
+            // r2Var = 2 * (r2Parm[2] * varCoord.x - r2Param[3])
+            segments->fVSCode.appendf("\t%s = 2.0 *(%s[2] * %s.x - %s[3]);\n",
+                                      radial2VaryingName.c_str(), radial2ParamsName.c_str(),
+                                      varyingName.c_str(), radial2ParamsName.c_str());
         }
     }
 
     /// Fragment Shader Stuff
-    GrTokenString fsCoordName;
+    GrStringBuilder fsCoordName;
     // function used to access the shader, may be made projective
-    GrTokenString texFunc("texture2D");
+    GrStringBuilder texFunc("texture2D");
     if (desc.fOptFlags & (ProgramDesc::StageDesc::kIdentityMatrix_OptFlagBit |
                           ProgramDesc::StageDesc::kNoPerspective_OptFlagBit)) {
         GrAssert(varyingDims == coordDims);
@@ -690,26 +659,21 @@
     } else {
         // if we have to do some special op on the varyings to get
         // our final tex coords then when in perspective we have to
-        // do an explicit divide
+        // do an explicit divide. Otherwise, we can use a Proj func.
         if  (ProgramDesc::StageDesc::kIdentity_CoordMapping == desc.fCoordMapping &&
              ProgramDesc::StageDesc::kSingle_FetchMode == desc.fFetchMode) {
-            texFunc += "Proj";
+            texFunc.append("Proj");
             fsCoordName = varyingName;
         } else {
             fsCoordName = "inCoord";
             fsCoordName.appendS32(stageNum);
-
-            segments->fFSCode += "\t";
-            segments->fFSCode += float_vector_type(coordDims);
-            segments->fFSCode += " ";
-            segments->fFSCode += fsCoordName;
-            segments->fFSCode += " = ";
-            segments->fFSCode += varyingName;
-            segments->fFSCode += vector_nonhomog_coords(varyingDims);
-            segments->fFSCode += " / ";
-            segments->fFSCode += varyingName;
-            segments->fFSCode += vector_homog_coord(varyingDims);
-            segments->fFSCode += ";\n";
+            segments->fFSCode.appendf("\t%s %s = %s%s / %s%s;\n",
+                                       float_vector_type(coordDims),
+                                       fsCoordName.c_str(),
+                                       varyingName.c_str(),
+                                       vector_nonhomog_coords(varyingDims),
+                                       varyingName.c_str(),
+                                       vector_homog_coord(varyingDims));
         }
     }
 
@@ -720,29 +684,25 @@
         sampleCoords = fsCoordName;
         break;
     case ProgramDesc::StageDesc::kSweepGradient_CoordMapping:
-        sampleCoords = "vec2(atan(-";
-        sampleCoords += fsCoordName;
-        sampleCoords += ".y, -";
-        sampleCoords += fsCoordName;
-        sampleCoords += ".x)*0.1591549430918 + 0.5, 0.5)";
+        sampleCoords.printf("vec2(atan(- %s.y, - %s.x) * 0.1591549430918 + 0.5, 0.5)", fsCoordName.c_str(), fsCoordName.c_str());
         complexCoord = true;
         break;
     case ProgramDesc::StageDesc::kRadialGradient_CoordMapping:
-        sampleCoords = "vec2(length(";
-        sampleCoords += fsCoordName;
-        sampleCoords += ".xy), 0.5)";
+        sampleCoords.printf("vec2(length(%s.xy), 0.5)", fsCoordName.c_str());
         complexCoord = true;
         break;
     case ProgramDesc::StageDesc::kRadial2Gradient_CoordMapping: {
-        GrTokenString cName("c");
-        GrTokenString ac4Name("ac4");
-        GrTokenString rootName("root");
+        GrStringBuilder cName("c");
+        GrStringBuilder ac4Name("ac4");
+        GrStringBuilder rootName("root");
 
         cName.appendS32(stageNum);
         ac4Name.appendS32(stageNum);
         rootName.appendS32(stageNum);
 
-        GrTokenString bVar;
+        // if we were able to interpolate the linear component bVar is the varying
+        // otherwise compute it
+        GrStringBuilder bVar;
         if (coordDims == varyingDims) {
             bVar = radial2VaryingName;
             GrAssert(2 == varyingDims);
@@ -750,134 +710,68 @@
             GrAssert(3 == varyingDims);
             bVar = "b";
             bVar.appendS32(stageNum);
-            segments->fFSCode += "\tfloat ";
-            segments->fFSCode += bVar;
-            segments->fFSCode += " = 2.0 * (";
-            segments->fFSCode += radial2ParamsName;
-            segments->fFSCode += "[2] * ";
-            segments->fFSCode += fsCoordName;
-            segments->fFSCode += ".x ";
-            segments->fFSCode += " - ";
-            segments->fFSCode += radial2ParamsName;
-            segments->fFSCode += "[3]);\n";
+            segments->fFSCode.appendf("\tfloat %s = 2.0 * (%s[2] * %s.x - %s[3]);\n",
+                                        bVar.c_str(), radial2ParamsName.c_str(),
+                                        fsCoordName.c_str(), radial2ParamsName.c_str());
         }
 
-        segments->fFSCode += "\tfloat ";
-        segments->fFSCode += cName;
-        segments->fFSCode += " = dot(";
-        segments->fFSCode += fsCoordName;
-        segments->fFSCode += ", ";
-        segments->fFSCode += fsCoordName;
-        segments->fFSCode += ") + ";
-        segments->fFSCode += " - ";
-        segments->fFSCode += radial2ParamsName;
-        segments->fFSCode += "[4];\n";
+        // c = (x^2)+(y^2) - params[4]
+        segments->fFSCode.appendf("\tfloat %s = dot(%s, %s) - %s[4];\n",
+                                  cName.c_str(), fsCoordName.c_str(),
+                                  fsCoordName.c_str(),
+                                  radial2ParamsName.c_str());
+        // ac4 = 4.0 * params[0] * c
+        segments->fFSCode.appendf("\tfloat %s = %s[0] * 4.0 * %s;\n",
+                                  ac4Name.c_str(), radial2ParamsName.c_str(),
+                                  cName.c_str());
 
-        segments->fFSCode += "\tfloat ";
-        segments->fFSCode += ac4Name;
-        segments->fFSCode += " = ";
-        segments->fFSCode += radial2ParamsName;
-        segments->fFSCode += "[0] * 4.0 * ";
-        segments->fFSCode += cName;
-        segments->fFSCode += ";\n";
+        // 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());
 
-        segments->fFSCode += "\tfloat ";
-        segments->fFSCode += rootName;
-        segments->fFSCode += " = sqrt(abs(";
-        segments->fFSCode += bVar;
-        segments->fFSCode += " * ";
-        segments->fFSCode += bVar;
-        segments->fFSCode += " - ";
-        segments->fFSCode += ac4Name;
-        segments->fFSCode += "));\n";
-
-        sampleCoords = "vec2((-";
-        sampleCoords += bVar;
-        sampleCoords += " + ";
-        sampleCoords += radial2ParamsName;
-        sampleCoords += "[5] * ";
-        sampleCoords += rootName;
-        sampleCoords += ") * ";
-        sampleCoords += radial2ParamsName;
-        sampleCoords += "[1], 0.5)\n";
+        // x coord is: (-b + params[5] * sqrt(b^2-4ac)) * params[1]
+        // y coord is 0.5 (texture is effectively 1D)
+        sampleCoords.printf("vec2((-%s + %s[5] * %s) * %s[1], 0.5)",
+                            bVar.c_str(), radial2ParamsName.c_str(),
+                            rootName.c_str(), radial2ParamsName.c_str());
         complexCoord = true;
         break;}
     };
 
+    const char* smear;
+    if (desc.fModulation == ProgramDesc::StageDesc::kAlpha_Modulation) {
+        smear = ".aaaa";
+    } else {
+        smear = "";
+    }
+    GrStringBuilder modulate;
+    if (NULL != fsInColor) {
+        modulate.printf(" * %s", fsInColor);
+    }
+
     if (ProgramDesc::StageDesc::k2x2_FetchMode == desc.fFetchMode) {
-        locations->fNormalizedTexelSizeUni = 1;
+        locations->fNormalizedTexelSizeUni = kUseUniform;
         if (complexCoord) {
-            GrTokenString coordVar("tCoord");
+            // assign the coord to a var rather than compute 4x.
+            GrStringBuilder coordVar("tCoord");
             coordVar.appendS32(stageNum);
-            segments->fFSCode += "\t";
-            segments->fFSCode += float_vector_type(coordDims);
-            segments->fFSCode += " ";
-            segments->fFSCode += coordVar;
-            segments->fFSCode += " = ";
-            segments->fFSCode += sampleCoords;
-            segments->fFSCode += ";\n";
+            segments->fFSCode.appendf("\t%s %s = %s;\n",
+                                      float_vector_type(coordDims),
+                                      coordVar.c_str(), sampleCoords.c_str());
             sampleCoords = coordVar;
         }
-        static const char sign[] = {'-','+'};
-        GrTokenString stageAccumVar("stage2x2Accum");
-        stageAccumVar.appendS32(stageNum);
-        segments->fFSCode += "\tvec4 ";
-        segments->fFSCode += stageAccumVar;
-        segments->fFSCode += " = ";
         GrAssert(2 == coordDims);
-        for (int y = 0; y < 2; ++y) {
-            for (int x = 0; x < 2; ++x) {
-                segments->fFSCode += texFunc;
-                segments->fFSCode += "(";
-                segments->fFSCode += samplerName;
-                segments->fFSCode += ", ";
-                segments->fFSCode += sampleCoords;
-                segments->fFSCode += " + vec2(";
-                segments->fFSCode += sign[x];
-                segments->fFSCode += texelSizeName;
-                segments->fFSCode += ".x, ";
-                segments->fFSCode += sign[y];
-                segments->fFSCode += texelSizeName;
-                segments->fFSCode += ".y))";
-                if (desc.fModulation == ProgramDesc::StageDesc::kAlpha_Modulation) {
-                    segments->fFSCode += ".aaaa";
-                }
-                segments->fFSCode += ";\n";
-                if (1 != x || 1 !=y ) {
-                    segments->fFSCode += "\t";
-                    segments->fFSCode += stageAccumVar;
-                    segments->fFSCode += " += ";
-                }
-            }
-        }
-        segments->fFSCode += "\t";
-        segments->fFSCode += fsOutColor;
-        segments->fFSCode += " = ";
-        if (NULL != fsInColor) {
-            segments->fFSCode += fsInColor;
-            segments->fFSCode += " * ";
-        }
-        segments->fFSCode += stageAccumVar;
-        segments->fFSCode += " / 4;\n";
+        GrStringBuilder accumVar("accum");
+        accumVar.appendS32(stageNum);
+        segments->fFSCode.appendf("\tvec4 %s  = %s(%s, %s + vec2(-%s.x,-%s.y))%s;\n", accumVar.c_str(), texFunc.c_str(), samplerName.c_str(), sampleCoords.c_str(), texelSizeName.c_str(), texelSizeName.c_str(), smear);
+        segments->fFSCode.appendf("\t%s += %s(%s, %s + vec2(+%s.x,-%s.y))%s;\n", accumVar.c_str(), texFunc.c_str(), samplerName.c_str(), sampleCoords.c_str(), texelSizeName.c_str(), texelSizeName.c_str(), smear);
+        segments->fFSCode.appendf("\t%s += %s(%s, %s + vec2(-%s.x,+%s.y))%s;\n", accumVar.c_str(), texFunc.c_str(), samplerName.c_str(), sampleCoords.c_str(), texelSizeName.c_str(), texelSizeName.c_str(), smear);
+        segments->fFSCode.appendf("\t%s += %s(%s, %s + vec2(+%s.x,+%s.y))%s;\n", accumVar.c_str(), texFunc.c_str(), samplerName.c_str(), sampleCoords.c_str(), texelSizeName.c_str(), texelSizeName.c_str(), smear);
+        segments->fFSCode.appendf("\t%s = .25 * %s%s;\n", fsOutColor, accumVar.c_str(), modulate.c_str());
     } else {
-        segments->fFSCode += "\t";
-        segments->fFSCode += fsOutColor;
-        segments->fFSCode += " = ";
-        if (NULL != fsInColor) {
-            segments->fFSCode += fsInColor;
-            segments->fFSCode += " * ";
-        }
-
-        segments->fFSCode += texFunc;
-        segments->fFSCode += "(";
-        segments->fFSCode += samplerName;
-        segments->fFSCode += ", ";
-        segments->fFSCode += sampleCoords;
-        segments->fFSCode += ")";
-        if (desc.fModulation == ProgramDesc::StageDesc::kAlpha_Modulation) {
-            segments->fFSCode += ".aaaa";
-        }
-        segments->fFSCode += ";\n";
+        segments->fFSCode.appendf("\t%s = %s(%s, %s)%s %s;\n", fsOutColor, texFunc.c_str(), samplerName.c_str(), sampleCoords.c_str(), smear, modulate.c_str());
     }
 
     if(fStageEffects[stageNum]) {