Clean up duplicate code in Ganesh, moving more function onto GrGLShaderBuilder.

http://codereview.appspot.com/6245082/



git-svn-id: http://skia.googlecode.com/svn/trunk@4116 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/src/gpu/gl/GrGLProgram.cpp b/src/gpu/gl/GrGLProgram.cpp
index a49aa61..0d674ee 100644
--- a/src/gpu/gl/GrGLProgram.cpp
+++ b/src/gpu/gl/GrGLProgram.cpp
@@ -1485,35 +1485,19 @@
 
     /// Fragment Shader Stuff
 
-    // Function used to access the shader, may be made projective.
-    GrStringBuilder texFunc("texture2D");
+    segments->fSampleCoords = varyingFSName;
+
+    GrGLShaderBuilder::SamplerMode sampleMode =
+        GrGLShaderBuilder::kExplicitDivide_SamplerMode;
     if (desc.fOptFlags & (StageDesc::kIdentityMatrix_OptFlagBit |
                           StageDesc::kNoPerspective_OptFlagBit)) {
-        GrAssert(segments->fVaryingDims == segments->fCoordDims);
-        segments->fSampleCoords = varyingFSName;
-    } 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. Otherwise, we can use a Proj func.
-        if  (StageDesc::kIdentity_CoordMapping == desc.fCoordMapping &&
-             StageDesc::kSingle_FetchMode == desc.fFetchMode) {
-            texFunc.append("Proj");
-            segments->fSampleCoords = varyingFSName;
-        } else {
-            // This block is replicated in GrGLProgramStage::emitTextureLookup()
-            segments->fSampleCoords = "inCoord";
-            segments->fSampleCoords.appendS32(stageNum);
-            segments->fFSCode.appendf("\t%s %s = %s%s / %s%s;\n",
-                GrGLShaderVar::TypeString(GrSLFloatVectorType(segments->fCoordDims)),
-                segments->fSampleCoords.c_str(),
-                varyingFSName,
-                GrGLSLVectorNonhomogCoords(segments->fVaryingDims),
-                varyingFSName,
-                GrGLSLVectorHomogCoord(segments->fVaryingDims));
-        }
+        sampleMode = GrGLShaderBuilder::kDefault_SamplerMode;
+    } else if (StageDesc::kIdentity_CoordMapping == desc.fCoordMapping &&
+               StageDesc::kSingle_FetchMode == desc.fFetchMode) {
+        sampleMode = GrGLShaderBuilder::kProj_SamplerMode;
     }
+    segments->setupTextureAccess(sampleMode, stageNum);
 
-    segments->fComplexCoord = false;
     // NOTE: GrGLProgramStages will soon responsible for mapping
     //if (NULL == customStage) {
         switch (desc.fCoordMapping) {
@@ -1566,24 +1550,14 @@
         locations->fTexDomUni = kUseUniform;
     }
 
-    if (desc.fOptFlags & (StageDesc::kIdentityMatrix_OptFlagBit |
-                          StageDesc::kNoPerspective_OptFlagBit)) {
-        segments->setSamplerMode(GrGLShaderBuilder::kDefault_SamplerMode);
-    } else if (StageDesc::kIdentity_CoordMapping == desc.fCoordMapping &&
-               StageDesc::kSingle_FetchMode == desc.fFetchMode) {
-        segments->setSamplerMode(GrGLShaderBuilder::kProj_SamplerMode);
-    } else {
-        segments->setSamplerMode(
-            GrGLShaderBuilder::kExplicitDivide_SamplerMode);
-    }
-
     // NOTE: GrGLProgramStages are now responsible for fetching
     if (NULL == customStage) {
         switch (desc.fFetchMode) {
         case StageDesc::k2x2_FetchMode:
             GrAssert(!(desc.fInConfigFlags & kMulByAlphaMask));
             gen2x2FS(stageNum, segments, locations,
-                samplerName.c_str(), texelSizeName, fsOutColor, texFunc);
+                samplerName.c_str(), texelSizeName, fsOutColor,
+                segments->fTexFunc);
             break;
         default:
             if (desc.fInConfigFlags & kMulByAlphaMask) {
@@ -1594,7 +1568,8 @@
                 GrAssert(!(desc.fInConfigFlags & 
                            StageDesc::kSmearRed_InConfigFlag));
                 segments->fFSCode.appendf("\t%s = %s(%s, %s)%s;\n",
-                                          fsOutColor, texFunc.c_str(), 
+                                          fsOutColor,
+                                          segments->fTexFunc.c_str(), 
                                           samplerName.c_str(),
                                           segments->fSampleCoords.c_str(),
                                           segments->fSwizzle.c_str());
@@ -1618,7 +1593,6 @@
         // Enclose custom code in a block to avoid namespace conflicts
         segments->fFSCode.appendf("\t{ // stage %d %s \n",
                                   stageNum, customStage->name());
-        segments->emitTextureSetup();
         customStage->emitFS(segments, fsOutColor, fsInColor,
                             samplerName.c_str());
         segments->fFSCode.appendf("\t}\n");
diff --git a/src/gpu/gl/GrGLShaderBuilder.cpp b/src/gpu/gl/GrGLShaderBuilder.cpp
index e0e8622..0f9331c 100644
--- a/src/gpu/gl/GrGLShaderBuilder.cpp
+++ b/src/gpu/gl/GrGLShaderBuilder.cpp
@@ -34,7 +34,6 @@
     , fFSOutputs(sMaxFSOutputs)
     , fUsesGS(false)
     , fVaryingDims(0)
-    , fSamplerMode(kDefault_SamplerMode)
     , fComplexCoord(false) {
 
 }
@@ -72,18 +71,23 @@
     }
 }
 
-void GrGLShaderBuilder::emitTextureSetup() {
+void GrGLShaderBuilder::setupTextureAccess(SamplerMode samplerMode,
+                                           int stageNum) {
     GrStringBuilder retval;
 
-    switch (fSamplerMode) {
+    fTexFunc = "texture2D";
+    switch (samplerMode) {
         case kDefault_SamplerMode:
-            // Fall through
-        case kProj_SamplerMode:
+            GrAssert(fVaryingDims == fCoordDims);
             // Do nothing
             break;
+        case kProj_SamplerMode:
+            fTexFunc.append("Proj");
+            break;
         case kExplicitDivide_SamplerMode:
             retval = "inCoord";
-            fFSCode.appendf("\t %s %s = %s%s / %s%s\n",
+            retval.appendS32(stageNum);
+            fFSCode.appendf("\t%s %s = %s%s / %s%s;\n",
                 GrGLShaderVar::TypeString
                     (GrSLFloatVectorType(fCoordDims)),
                 retval.c_str(),
@@ -94,6 +98,7 @@
             fSampleCoords = retval;
             break;
     }
+    fComplexCoord = false;
 }
 
 void GrGLShaderBuilder::emitTextureLookup(const char* samplerName,
@@ -101,20 +106,7 @@
     if (NULL == coordName) {
         coordName = fSampleCoords.c_str();
     }
-    switch (fSamplerMode) {
-        default:
-            SkDEBUGFAIL("Unknown sampler mode");
-            // Fall through
-        case kDefault_SamplerMode:
-            // Fall through
-        case kExplicitDivide_SamplerMode:
-            fFSCode.appendf("texture2D(%s, %s)", samplerName, coordName);
-            break;
-        case kProj_SamplerMode:
-            fFSCode.appendf("texture2DProj(%s, %s)", samplerName, coordName);
-            break;
-    }
-
+    fFSCode.appendf("%s(%s, %s)", fTexFunc.c_str(), samplerName, coordName);
 }
 
 void GrGLShaderBuilder::emitDefaultFetch(const char* outColor,
diff --git a/src/gpu/gl/GrGLShaderBuilder.h b/src/gpu/gl/GrGLShaderBuilder.h
index 1192637..cc8bc00 100644
--- a/src/gpu/gl/GrGLShaderBuilder.h
+++ b/src/gpu/gl/GrGLShaderBuilder.h
@@ -29,7 +29,17 @@
     void computeSwizzle(uint32_t configFlags);
     void computeModulate(const char* fsInColor);
 
-    void emitTextureSetup();
+    // TODO: needs a better name
+    enum SamplerMode {
+        kDefault_SamplerMode,
+        kProj_SamplerMode,
+        kExplicitDivide_SamplerMode  // must do an explicit divide
+    };
+
+    /** Determines whether we should use texture2D() or texture2Dproj(),
+        and if an explicit divide is required for the sample coordinates,
+        creates the new variable and emits the code to initialize it. */
+    void setupTextureAccess(SamplerMode samplerMode, int stageNum);
 
     /** texture2D(samplerName, coordName), with projection
         if necessary; if coordName is not specified,
@@ -82,21 +92,6 @@
                     const char** vsOutName = NULL,
                     const char** fsInName = NULL);
 
-    // TODO: needs a better name
-    enum SamplerMode {
-        kDefault_SamplerMode,
-        kProj_SamplerMode,
-        kExplicitDivide_SamplerMode  // must do an explicit divide
-    };
-
-    // TODO: computing this requires information about fetch mode
-    // && coord mapping, as well as StageDesc::fOptFlags - proably
-    // need to set up default value and have some custom stages
-    // override as necessary?
-    void setSamplerMode(SamplerMode samplerMode) {
-        fSamplerMode = samplerMode;
-    }
-
 
     GrStringBuilder fHeader; // VS+FS, GLSL version, etc
     VarArray        fVSUnis;
@@ -121,12 +116,6 @@
     int              fVaryingDims;
     static const int fCoordDims = 2;
 
-protected:
-
-    SamplerMode      fSamplerMode;
-
-public:
-
     /// True if fSampleCoords is an expression; false if it's a bare
     /// variable name
     bool             fComplexCoord;
@@ -135,6 +124,8 @@
     GrStringBuilder  fSwizzle;
     GrStringBuilder  fModulate;
 
+    GrStringBuilder  fTexFunc;
+
     //@}
 
 };