Move state onto GrGLShaderBuilder, to let us implement mappings
authortomhudson@google.com <tomhudson@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>
Fri, 18 May 2012 14:57:40 +0000 (14:57 +0000)
committertomhudson@google.com <tomhudson@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>
Fri, 18 May 2012 14:57:40 +0000 (14:57 +0000)
as GrCustomStage objects.

http://codereview.appspot.com/6216057/

git-svn-id: http://skia.googlecode.com/svn/trunk@3996 2bbb7eff-a529-9590-31e7-b0007b416f81

src/gpu/gl/GrGLProgram.cpp
src/gpu/gl/GrGLProgramStage.cpp
src/gpu/gl/GrGLProgramStage.h
src/gpu/gl/GrGLShaderBuilder.cpp
src/gpu/gl/GrGLShaderBuilder.h

index 5bd0440..e576163 100644 (file)
@@ -1294,12 +1294,10 @@ GrGLShaderVar* genRadialVS(int stageNum,
     return radial2FSParams;
 }
 
-bool genRadial2GradientCoordMapping(int stageNum,
+void genRadial2GradientCoordMapping(int stageNum,
                                     GrGLShaderBuilder* segments,
                                     const char* radial2VaryingFSName,
-                                    GrGLShaderVar* radial2Params,
-                                    GrStringBuilder& sampleCoords,
-                                    GrStringBuilder& fsCoordName) {
+                                    GrGLShaderVar* radial2Params) {
     GrStringBuilder cName("c");
     GrStringBuilder ac4Name("ac4");
     GrStringBuilder rootName("root");
@@ -1333,13 +1331,13 @@ bool genRadial2GradientCoordMapping(int stageNum,
         bVar.appendS32(stageNum);
         segments->fFSCode.appendf("\tfloat %s = 2.0 * (%s * %s.x - %s);\n",
                                     bVar.c_str(), radial2p2.c_str(),
-                                    fsCoordName.c_str(), radial2p3.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(), fsCoordName.c_str(),
-                              fsCoordName.c_str(),
+                              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",
@@ -1354,18 +1352,16 @@ bool genRadial2GradientCoordMapping(int stageNum,
 
     // 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 * %s) * %s, 0.5)",
+    segments->fSampleCoords.printf("vec2((-%s + %s * %s) * %s, 0.5)",
                         bVar.c_str(), radial2p5.c_str(),
                         rootName.c_str(), radial2p1.c_str());
-    return true;
+    segments->fComplexCoord = true;
 }
 
-bool genRadial2GradientDegenerateCoordMapping(int stageNum,
+void genRadial2GradientDegenerateCoordMapping(int stageNum,
                                               GrGLShaderBuilder* segments,
                                               const char* radial2VaryingFSName,
-                                              GrGLShaderVar* radial2Params,
-                                              GrStringBuilder& sampleCoords,
-                                              GrStringBuilder& fsCoordName) {
+                                              GrGLShaderVar* radial2Params) {
     GrStringBuilder cName("c");
 
     cName.appendS32(stageNum);
@@ -1389,49 +1385,47 @@ bool genRadial2GradientDegenerateCoordMapping(int stageNum,
         bVar.appendS32(stageNum);
         segments->fFSCode.appendf("\tfloat %s = 2.0 * (%s * %s.x - %s);\n",
                                     bVar.c_str(), radial2p2.c_str(),
-                                    fsCoordName.c_str(), radial2p3.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(), fsCoordName.c_str(),
-                              fsCoordName.c_str(),
+                              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)
-    sampleCoords.printf("vec2((-%s / %s), 0.5)", cName.c_str(), bVar.c_str());
-    return true;
+    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,
-              GrStringBuilder* sampleCoords,
               const char* samplerName,
               const char* texelSizeName,
               const char* swizzle,
               const char* fsOutColor,
               GrStringBuilder& texFunc,
-              GrStringBuilder& modulate,
-              bool complexCoord) {
+              GrStringBuilder& modulate) {
     locations->fNormalizedTexelSizeUni = kUseUniform;
-    if (complexCoord) {
+    if (segments->fComplexCoord) {
         // assign the coord to a var rather than compute 4x.
         GrStringBuilder coordVar("tCoord");
         coordVar.appendS32(stageNum);
         segments->fFSCode.appendf("\t%s %s = %s;\n",
                             float_vector_type_str(segments->fCoordDims),
-                            coordVar.c_str(), sampleCoords->c_str());
-        *sampleCoords = coordVar;
+                            coordVar.c_str(), segments->fSampleCoords.c_str());
+        segments->fSampleCoords = coordVar;
     }
     GrAssert(2 == segments->fCoordDims);
     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, sampleCoords->c_str(), texelSizeName, texelSizeName, swizzle);
-    segments->fFSCode.appendf("\t%s += %s(%s, %s + vec2(+%s.x,-%s.y))%s;\n", accumVar.c_str(), texFunc.c_str(), samplerName, sampleCoords->c_str(), texelSizeName, texelSizeName, swizzle);
-    segments->fFSCode.appendf("\t%s += %s(%s, %s + vec2(-%s.x,+%s.y))%s;\n", accumVar.c_str(), texFunc.c_str(), samplerName, sampleCoords->c_str(), texelSizeName, texelSizeName, swizzle);
-    segments->fFSCode.appendf("\t%s += %s(%s, %s + vec2(+%s.x,+%s.y))%s;\n", accumVar.c_str(), texFunc.c_str(), samplerName, sampleCoords->c_str(), texelSizeName, texelSizeName, swizzle);
+    segments->fFSCode.appendf("\tvec4 %s  = %s(%s, %s + vec2(-%s.x,-%s.y))%s;\n", accumVar.c_str(), texFunc.c_str(), samplerName, segments->fSampleCoords.c_str(), texelSizeName, texelSizeName, swizzle);
+    segments->fFSCode.appendf("\t%s += %s(%s, %s + vec2(+%s.x,-%s.y))%s;\n", accumVar.c_str(), texFunc.c_str(), samplerName, segments->fSampleCoords.c_str(), texelSizeName, texelSizeName, swizzle);
+    segments->fFSCode.appendf("\t%s += %s(%s, %s + vec2(-%s.x,+%s.y))%s;\n", accumVar.c_str(), texFunc.c_str(), samplerName, segments->fSampleCoords.c_str(), texelSizeName, texelSizeName, swizzle);
+    segments->fFSCode.appendf("\t%s += %s(%s, %s + vec2(+%s.x,+%s.y))%s;\n", accumVar.c_str(), texFunc.c_str(), samplerName, segments->fSampleCoords.c_str(), texelSizeName, texelSizeName, swizzle);
     segments->fFSCode.appendf("\t%s = .25 * %s%s;\n", fsOutColor, accumVar.c_str(), modulate.c_str());
 
 }
@@ -1465,7 +1459,6 @@ void genMorphologyFS(int stageNum,
                      const char* swizzle,
                      const char* imageIncrementName,
                      const char* fsOutColor,
-                     GrStringBuilder& sampleCoords,
                      GrStringBuilder& texFunc,
                      GrStringBuilder& modulate) {
     GrStringBuilder valueVar("value");
@@ -1483,7 +1476,7 @@ void genMorphologyFS(int stageNum,
     }
     segments->fFSCode.appendf("\tvec2 %s = %s;\n", 
                               coordVar.c_str(),
-                              sampleCoords.c_str());
+                              segments->fSampleCoords.c_str());
     segments->fFSCode.appendf("\tfor (int i = 0; i < %d; i++) {\n",
                               desc.fKernelWidth * 2 + 1);
     segments->fFSCode.appendf("\t\t%s = %s(%s, %s(%s, %s)%s);\n",
@@ -1609,27 +1602,27 @@ void GrGLProgram::genStageCode(const GrGLContextInfo& gl,
         customStage->setupFSUnis(&segments->fFSUnis, stageNum);
     }
 
-    GrStringBuilder fsCoordName;
-    // function used to access the shader, may be made projective
+    // Function used to access the shader, may be made projective.
     GrStringBuilder texFunc("texture2D");
     if (desc.fOptFlags & (StageDesc::kIdentityMatrix_OptFlagBit |
                           StageDesc::kNoPerspective_OptFlagBit)) {
         GrAssert(segments->fVaryingDims == segments->fCoordDims);
-        fsCoordName = varyingFSName;
+        segments->fSampleCoords = varyingFSName;
     } else {
-        // if we have to do some special op on the varyings to get
+        // 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");
-            fsCoordName = varyingFSName;
+            segments->fSampleCoords = varyingFSName;
         } else {
-            fsCoordName = "inCoord";
-            fsCoordName.appendS32(stageNum);
+            // 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)),
-                fsCoordName.c_str(),
+                segments->fSampleCoords.c_str(),
                 varyingFSName,
                 GrGLSLVectorNonhomogCoords(segments->fVaryingDims),
                 varyingFSName,
@@ -1637,31 +1630,28 @@ void GrGLProgram::genStageCode(const GrGLContextInfo& gl,
         }
     }
 
-    GrStringBuilder sampleCoords;
-    bool complexCoord = false;
+    segments->fComplexCoord = false;
     switch (desc.fCoordMapping) {
     case StageDesc::kIdentity_CoordMapping:
-        sampleCoords = fsCoordName;
+        // Do nothing
         break;
     case StageDesc::kSweepGradient_CoordMapping:
-        sampleCoords.printf("vec2(atan(- %s.y, - %s.x) * 0.1591549430918 + 0.5, 0.5)", fsCoordName.c_str(), fsCoordName.c_str());
-        complexCoord = true;
+        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:
-        sampleCoords.printf("vec2(length(%s.xy), 0.5)", fsCoordName.c_str());
-        complexCoord = true;
+        segments->fSampleCoords.printf("vec2(length(%s.xy), 0.5)", segments->fSampleCoords.c_str());
+        segments->fComplexCoord = true;
         break;
     case StageDesc::kRadial2Gradient_CoordMapping:
-        complexCoord = genRadial2GradientCoordMapping(
+        genRadial2GradientCoordMapping(
                            stageNum, segments,
-                           radial2VaryingFSName, radial2Params,
-                           sampleCoords, fsCoordName);
+                           radial2VaryingFSName, radial2Params);
         break;
     case StageDesc::kRadial2GradientDegenerate_CoordMapping:
-        complexCoord = genRadial2GradientDegenerateCoordMapping(
+        genRadial2GradientDegenerateCoordMapping(
                            stageNum, segments,
-                           radial2VaryingFSName, radial2Params,
-                           sampleCoords, fsCoordName);
+                           radial2VaryingFSName, radial2Params);
         break;
 
     };
@@ -1700,19 +1690,19 @@ void GrGLProgram::genStageCode(const GrGLContextInfo& gl,
         segments->fFSCode.appendf("\t%s %s = clamp(%s, %s.xy, %s.zw);\n",
                                   float_vector_type_str(segments->fCoordDims),
                                   coordVar.c_str(),
-                                  sampleCoords.c_str(),
+                                  segments->fSampleCoords.c_str(),
                                   texDomainName.c_str(),
                                   texDomainName.c_str());
-        sampleCoords = coordVar;
+        segments->fSampleCoords = coordVar;
         locations->fTexDomUni = kUseUniform;
     }
 
     switch (desc.fFetchMode) {
     case StageDesc::k2x2_FetchMode:
         GrAssert(!(desc.fInConfigFlags & kMulByAlphaMask));
-        gen2x2FS(stageNum, segments, locations, &sampleCoords,
+        gen2x2FS(stageNum, segments, locations,
             samplerName, texelSizeName, swizzle, fsOutColor,
-            texFunc, modulate, complexCoord);
+            texFunc, modulate);
         break;
     case StageDesc::kConvolution_FetchMode:
         GrAssert(!(desc.fInConfigFlags & kMulByAlphaMask));
@@ -1722,7 +1712,7 @@ void GrGLProgram::genStageCode(const GrGLContextInfo& gl,
         GrAssert(!(desc.fInConfigFlags & kMulByAlphaMask));
         genMorphologyFS(stageNum, desc, segments,
             samplerName, swizzle, imageIncrementName, fsOutColor,
-            sampleCoords, texFunc, modulate);
+            texFunc, modulate);
         break;
     default:
         if (desc.fInConfigFlags & kMulByAlphaMask) {
@@ -1734,7 +1724,8 @@ void GrGLProgram::genStageCode(const GrGLContextInfo& gl,
                        StageDesc::kSmearRed_InConfigFlag));
             segments->fFSCode.appendf("\t%s = %s(%s, %s)%s;\n",
                                       fsOutColor, texFunc.c_str(), 
-                                      samplerName, sampleCoords.c_str(),
+                                      samplerName,
+                                      segments->fSampleCoords.c_str(),
                                       swizzle);
             if (desc.fInConfigFlags &
                 StageDesc::kMulRGBByAlpha_RoundUp_InConfigFlag) {
@@ -1749,7 +1740,8 @@ void GrGLProgram::genStageCode(const GrGLContextInfo& gl,
         } else {
             segments->fFSCode.appendf("\t%s = %s(%s, %s)%s%s;\n",
                                       fsOutColor, texFunc.c_str(), 
-                                      samplerName, sampleCoords.c_str(),
+                                      samplerName, 
+                                      segments->fSampleCoords.c_str(),
                                       swizzle, modulate.c_str());
         }
     }
@@ -1766,17 +1758,12 @@ void GrGLProgram::genStageCode(const GrGLContextInfo& gl,
                 GrGLProgramStage::kExplicitDivide_SamplerMode);
         }
 
-        GrStringBuilder fragmentShader;
-        fsCoordName = customStage->emitTextureSetup(
-                          &fragmentShader, sampleCoords.c_str(),
-                          stageNum, segments);
-        customStage->emitFS(&fragmentShader, fsOutColor, fsInColor,
-                            samplerName, fsCoordName.c_str());
-      
         // Enclose custom code in a block to avoid namespace conflicts
         segments->fFSCode.appendf("\t{ // stage %d %s \n",
                                   stageNum, customStage->name());
-        segments->fFSCode.append(fragmentShader);
+        customStage->emitTextureSetup(segments);
+        customStage->emitFS(&segments->fFSCode, fsOutColor, fsInColor,
+                            samplerName, segments->fSampleCoords.c_str());
         segments->fFSCode.appendf("\t}\n");
     }
 }
index 07a6b33..06c4d93 100644 (file)
@@ -30,10 +30,7 @@ void GrGLProgramStage::setData(const GrGLInterface*, GrCustomStage*,
 
 }
 
-GrStringBuilder GrGLProgramStage::emitTextureSetup(GrStringBuilder* code,
-                    const char* coordName,
-                    int stageNum,
-                    GrGLShaderBuilder* segments) {
+void GrGLProgramStage::emitTextureSetup(GrGLShaderBuilder* segments) {
     GrStringBuilder retval;
 
     switch (fSamplerMode) {
@@ -41,22 +38,20 @@ GrStringBuilder GrGLProgramStage::emitTextureSetup(GrStringBuilder* code,
             // Fall through
         case kProj_SamplerMode:
             // Do nothing
-            retval = coordName;
             break;
         case kExplicitDivide_SamplerMode:
             retval = "inCoord";
-            retval.appendS32(stageNum);
-            code->appendf("\t %s %s = %s%s / %s%s\n",
+            segments->fFSCode.appendf("\t %s %s = %s%s / %s%s\n",
                 GrGLShaderVar::TypeString
                     (GrSLFloatVectorType(segments->fCoordDims)),
-                fCoordName.c_str(),
-                coordName,
+                retval.c_str(),
+                segments->fSampleCoords.c_str(),
                 GrGLSLVectorNonhomogCoords(segments->fVaryingDims),
-                coordName,
+                segments->fSampleCoords.c_str(),
                 GrGLSLVectorHomogCoord(segments->fVaryingDims));
+            segments->fSampleCoords = retval;
             break;
     }
-    return retval;
 }
 
 void GrGLProgramStage::emitTextureLookup(GrStringBuilder* code,
index 4778e7e..61e62e5 100644 (file)
@@ -102,12 +102,9 @@ public:
 
     void setSamplerMode(SamplerMode samplerMode) { fSamplerMode = samplerMode; }
 
-    /** Returns the *effective* coord name after any perspective divide
-        or other transform. */
-    GrStringBuilder emitTextureSetup(GrStringBuilder* code,
-                                     const char* coordName,
-                                     int stageNum,
-                                     GrGLShaderBuilder* segments);
+    /** Does perspective divide or other necessary transform, then
+        updates the name of the sample coordinates. */
+    void emitTextureSetup(GrGLShaderBuilder* segments);
 
 protected:
 
@@ -118,8 +115,6 @@ protected:
                            const char* coordName);
 
     SamplerMode fSamplerMode;
-    GrStringBuilder fCoordName;
-
 };
 
 #endif
index 244b286..321e507 100644 (file)
@@ -31,8 +31,9 @@ GrGLShaderBuilder::GrGLShaderBuilder()
     , fFSInputs(sVarsPerBlock)
     , fFSUnis(sVarsPerBlock)
     , fFSOutputs(sMaxFSOutputs)
+    , fUsesGS(false)
     , fVaryingDims(0)
-    , fUsesGS(false) {
+    , fComplexCoord(false) {
 
 }
 
index 19ec6e1..6a7e279 100644 (file)
@@ -51,11 +51,20 @@ public:
     GrStringBuilder fVSCode;
     GrStringBuilder fGSCode;
     GrStringBuilder fFSCode;
+    bool            fUsesGS;
+
+    /// Per-stage settings
+    //@{
 
     int             fVaryingDims;
     static const int fCoordDims = 2;
 
-    bool            fUsesGS;
+    /// True if fSampleCoords is an expression; false if it's a bare
+    /// variable name
+    bool            fComplexCoord;
+    GrStringBuilder fSampleCoords;
+
+    //@}
 
 };