Encapsulate code required to create a uniform var into a single function on
GrGLShaderBuilder. This isolates internal dependencies from somebody
writing a CustomStage.

http://codereview.appspot.com/6248050/



git-svn-id: http://skia.googlecode.com/svn/trunk@4081 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/src/gpu/gl/GrGLProgram.cpp b/src/gpu/gl/GrGLProgram.cpp
index 2fdcd77..3e4f966 100644
--- a/src/gpu/gl/GrGLProgram.cpp
+++ b/src/gpu/gl/GrGLProgram.cpp
@@ -385,9 +385,8 @@
             *inColor = fsName;
             } break;
         case GrGLProgram::ProgramDesc::kUniform_ColorInput:
-            segments->fFSUnis.push_back().set(kVec4f_GrSLType,
-                GrGLShaderVar::kUniform_TypeModifier,
-                COL_UNI_NAME);
+            segments->addUniform(GrGLShaderBuilder::kFragment_VariableLifetime,
+                                 kVec4f_GrSLType, COL_UNI_NAME);
             programData->fUniLocations.fColorUni = kUseUniform;
             *inColor = COL_UNI_NAME;
             break;
@@ -422,9 +421,8 @@
 void genUniformCoverage(GrGLShaderBuilder* segments,
                         GrGLProgram::CachedData* programData,
                         GrStringBuilder* inOutCoverage) {
-    segments->fFSUnis.push_back().set(kVec4f_GrSLType,
-                                      GrGLShaderVar::kUniform_TypeModifier,
-                                      COV_UNI_NAME);
+    segments->addUniform(GrGLShaderBuilder::kFragment_VariableLifetime,
+                         kVec4f_GrSLType, COV_UNI_NAME);
     programData->fUniLocations.fCoverageUni = kUseUniform;
     if (inOutCoverage->size()) {
         segments->fFSCode.appendf("\tvec4 uniCoverage = %s * %s;\n",
@@ -554,8 +552,8 @@
         segments.fFSOutputs.push_back(colorOutput);
     }
 
-    segments.fVSUnis.push_back().set(kMat33f_GrSLType,
-        GrGLShaderVar::kUniform_TypeModifier, VIEW_MATRIX_NAME);
+    segments.addUniform(GrGLShaderBuilder::kVertex_VariableLifetime,
+                        kMat33f_GrSLType, VIEW_MATRIX_NAME);
     programData->fUniLocations.fViewMatrixUni = kUseUniform;
 
     segments.fVSAttrs.push_back().set(kVec2f_GrSLType,
@@ -662,9 +660,8 @@
         }
     }
     if (needColorFilterUniform) {
-        segments.fFSUnis.push_back().set(kVec4f_GrSLType,
-                                         GrGLShaderVar::kUniform_TypeModifier,
-                                         COL_FILTER_UNI_NAME);
+        segments.addUniform(GrGLShaderBuilder::kFragment_VariableLifetime,
+                            kVec4f_GrSLType, COL_FILTER_UNI_NAME);
         programData->fUniLocations.fColorFilterUni = kUseUniform;
     }
     bool wroteFragColorZero = false;
@@ -683,12 +680,10 @@
         inColor = "filteredColor";
     }
     if (applyColorMatrix) {
-        segments.fFSUnis.push_back().set(kMat44f_GrSLType,
-                                         GrGLShaderVar::kUniform_TypeModifier,
-                                         COL_MATRIX_UNI_NAME);
-        segments.fFSUnis.push_back().set(kVec4f_GrSLType,
-                                         GrGLShaderVar::kUniform_TypeModifier,
-                                         COL_MATRIX_VEC_UNI_NAME);
+        segments.addUniform(GrGLShaderBuilder::kFragment_VariableLifetime,
+                            kMat44f_GrSLType, COL_MATRIX_UNI_NAME);
+        segments.addUniform(GrGLShaderBuilder::kFragment_VariableLifetime,
+                            kVec4f_GrSLType, COL_MATRIX_VEC_UNI_NAME);
         programData->fUniLocations.fColorMatrixUni = kUseUniform;
         programData->fUniLocations.fColorMatrixVecUni = kUseUniform;
         segments.fFSCode.append("\tvec4 matrixedColor;\n");
@@ -1253,20 +1248,17 @@
         GrGLProgram::StageDesc::kRadial2GradientDegenerate_CoordMapping == mapping);
 }
 
-GrGLShaderVar* genRadialVS(int stageNum,
+const GrGLShaderVar* genRadialVS(int stageNum,
                         GrGLShaderBuilder* segments,
                         GrGLProgram::StageUniLocations* locations,
                         const char** radial2VaryingVSName,
                         const char** radial2VaryingFSName,
                         const char* varyingVSName) {
-
-    GrGLShaderVar* radial2FSParams = &segments->fFSUnis.push_back();
-    radial2FSParams->setType(kFloat_GrSLType);
-    radial2FSParams->setTypeModifier(GrGLShaderVar::kUniform_TypeModifier);
-    radial2FSParams->setArrayCount(6);
-    radial2_param_name(stageNum, radial2FSParams->accessName());
-    segments->fVSUnis.push_back(*radial2FSParams).setEmitPrecision(true);
-
+    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
@@ -1297,7 +1289,7 @@
 void genRadial2GradientCoordMapping(int stageNum,
                                     GrGLShaderBuilder* segments,
                                     const char* radial2VaryingFSName,
-                                    GrGLShaderVar* radial2Params) {
+                                    const GrGLShaderVar* radial2Params) {
     GrStringBuilder cName("c");
     GrStringBuilder ac4Name("ac4");
     GrStringBuilder rootName("root");
@@ -1361,7 +1353,7 @@
 void genRadial2GradientDegenerateCoordMapping(int stageNum,
                                               GrGLShaderBuilder* segments,
                                               const char* radial2VaryingFSName,
-                                              GrGLShaderVar* radial2Params) {
+                                              const GrGLShaderVar* radial2Params) {
     GrStringBuilder cName("c");
 
     cName.appendS32(stageNum);
@@ -1434,16 +1426,15 @@
                      GrGLProgram::StageUniLocations* locations,
                      const char** imageIncrementName,
                      const char* varyingVSName) {
-    GrGLShaderVar* imgInc = &segments->fFSUnis.push_back();
-    imgInc->setType(kVec2f_GrSLType);
-    imgInc->setTypeModifier(GrGLShaderVar::kUniform_TypeModifier);
 
-    image_increment_param_name(stageNum, imgInc->accessName());
+    GrStringBuilder iiName;
+    image_increment_param_name(stageNum, &iiName);
+    const GrGLShaderVar* imgInc =
+        &segments->addUniform(
+            GrGLShaderBuilder::kBoth_VariableLifetime, kVec2f_GrSLType, 
+            iiName.c_str());
     *imageIncrementName = imgInc->getName().c_str();
 
-    // need image increment in both VS and FS
-    segments->fVSUnis.push_back(*imgInc).setEmitPrecision(true);
-
     locations->fImageIncrementUni = kUseUniform;
     segments->fVSCode.appendf("\t%s -= vec2(%d, %d) * %s;\n",
                                   varyingVSName, desc.fKernelWidth,
@@ -1516,14 +1507,14 @@
     if (desc.fOptFlags & StageDesc::kIdentityMatrix_OptFlagBit) {
         segments->fVaryingDims = segments->fCoordDims;
     } else {
-        GrGLShaderVar* mat;
-        mat = &segments->fVSUnis.push_back();
-        mat->setTypeModifier(GrGLShaderVar::kUniform_TypeModifier);
-        locations->fTextureMatrixUni = kUseUniform;
-
-        tex_matrix_name(stageNum, mat->accessName());
-        mat->setType(kMat33f_GrSLType);
+        GrStringBuilder texMatName;
+        tex_matrix_name(stageNum, &texMatName);
+        const GrGLShaderVar* mat = &segments->addUniform(
+            GrGLShaderBuilder::kVertex_VariableLifetime, kMat33f_GrSLType,
+            texMatName.c_str());
+        // Can't use texMatName.c_str() because it's on the stack!
         matName = mat->getName().c_str();
+        locations->fTextureMatrixUni = kUseUniform;
 
         if (desc.fOptFlags & StageDesc::kNoPerspective_OptFlagBit) {
             segments->fVaryingDims = segments->fCoordDims;
@@ -1533,18 +1524,20 @@
     }
     GrAssert(segments->fVaryingDims > 0);
 
-    segments->fFSUnis.push_back().set(kSampler2D_GrSLType,
-        GrGLShaderVar::kUniform_TypeModifier, "");
-    sampler_name(stageNum, segments->fFSUnis.back().accessName());
+    GrStringBuilder samplerName;
+    sampler_name(stageNum, &samplerName);
+    const GrGLShaderVar* sampler = &segments->addUniform(
+        GrGLShaderBuilder::kFragment_VariableLifetime, kSampler2D_GrSLType,
+        samplerName.c_str());
     locations->fSamplerUni = kUseUniform;
-    const char* samplerName = segments->fFSUnis.back().getName().c_str();
 
     const char* texelSizeName = NULL;
     if (StageDesc::k2x2_FetchMode == desc.fFetchMode) {
-        segments->fFSUnis.push_back().set(kVec2f_GrSLType,
-            GrGLShaderVar::kUniform_TypeModifier, "");
-        normalized_texel_size_name(stageNum, segments->fFSUnis.back().accessName());
-        texelSizeName = segments->fFSUnis.back().getName().c_str();
+        GrStringBuilder ntsName;
+        normalized_texel_size_name(stageNum, &ntsName);
+        texelSizeName = segments->addUniform(
+            GrGLShaderBuilder::kFragment_VariableLifetime,
+            kVec2f_GrSLType, ntsName.c_str()).getName().c_str();
     }
 
     const char *varyingVSName, *varyingFSName;
@@ -1564,7 +1557,7 @@
                                   vector_all_coords(segments->fVaryingDims));
     }
 
-    GrGLShaderVar* radial2Params = NULL;
+    const GrGLShaderVar* radial2Params = NULL;
     const char* radial2VaryingVSName = NULL;
     const char* radial2VaryingFSName = NULL;
 
@@ -1660,12 +1653,13 @@
     segments->computeSwizzle(desc.fInConfigFlags);
     segments->computeModulate(fsInColor);
 
-    if (desc.fOptFlags &
-        StageDesc::kCustomTextureDomain_OptFlagBit) {
+    if (desc.fOptFlags & StageDesc::kCustomTextureDomain_OptFlagBit) {
         GrStringBuilder texDomainName;
         tex_domain_name(stageNum, &texDomainName);
-        segments->fFSUnis.push_back().set(kVec4f_GrSLType,
-            GrGLShaderVar::kUniform_TypeModifier, texDomainName);
+        const GrGLShaderVar* texDomain =
+            &segments->addUniform(
+                GrGLShaderBuilder::kFragment_VariableLifetime,
+                kVec4f_GrSLType, texDomainName.c_str());
         GrStringBuilder coordVar("clampCoord");
         segments->fFSCode.appendf("\t%s %s = clamp(%s, %s.xy, %s.zw);\n",
                                   float_vector_type_str(segments->fCoordDims),
@@ -1694,7 +1688,7 @@
         case StageDesc::k2x2_FetchMode:
             GrAssert(!(desc.fInConfigFlags & kMulByAlphaMask));
             gen2x2FS(stageNum, segments, locations,
-                samplerName, texelSizeName, fsOutColor, texFunc);
+                samplerName.c_str(), texelSizeName, fsOutColor, texFunc);
             break;
         case StageDesc::kConvolution_FetchMode:
             GrAssert(!(desc.fInConfigFlags & kMulByAlphaMask));
@@ -1703,7 +1697,7 @@
         case StageDesc::kErode_FetchMode:
             GrAssert(!(desc.fInConfigFlags & kMulByAlphaMask));
             genMorphologyFS(stageNum, desc, segments,
-                samplerName, imageIncrementName, fsOutColor, texFunc);
+                samplerName.c_str(), imageIncrementName, fsOutColor, texFunc);
             break;
         default:
             if (desc.fInConfigFlags & kMulByAlphaMask) {
@@ -1715,7 +1709,7 @@
                            StageDesc::kSmearRed_InConfigFlag));
                 segments->fFSCode.appendf("\t%s = %s(%s, %s)%s;\n",
                                           fsOutColor, texFunc.c_str(), 
-                                          samplerName,
+                                          samplerName.c_str(),
                                           segments->fSampleCoords.c_str(),
                                           segments->fSwizzle.c_str());
                 if (desc.fInConfigFlags &
@@ -1729,7 +1723,7 @@
                                               fsOutColor, segments->fModulate.c_str());
                 }
             } else {
-                segments->emitDefaultFetch(fsOutColor, samplerName);
+                segments->emitDefaultFetch(fsOutColor, samplerName.c_str());
             }
         }
     }
@@ -1739,7 +1733,8 @@
         segments->fFSCode.appendf("\t{ // stage %d %s \n",
                                   stageNum, customStage->name());
         segments->emitTextureSetup();
-        customStage->emitFS(segments, fsOutColor, fsInColor, samplerName);
+        customStage->emitFS(segments, fsOutColor, fsInColor,
+                            samplerName.c_str());
         segments->fFSCode.appendf("\t}\n");
     }
 }