Added varying struct
authorjoshualitt <joshualitt@chromium.org>
Fri, 24 Oct 2014 14:56:04 +0000 (07:56 -0700)
committerCommit bot <commit-bot@chromium.org>
Fri, 24 Oct 2014 14:56:04 +0000 (07:56 -0700)
TBR=
BUG=skia:

Review URL: https://codereview.chromium.org/671023002

17 files changed:
include/gpu/GrGeometryProcessor.h
src/gpu/GrAAConvexPathRenderer.cpp
src/gpu/GrAARectRenderer.cpp
src/gpu/GrOvalRenderer.cpp
src/gpu/effects/GrBezierEffect.cpp
src/gpu/effects/GrCustomCoordsTextureEffect.cpp
src/gpu/effects/GrDashingEffect.cpp
src/gpu/effects/GrDistanceFieldTextureEffect.cpp
src/gpu/gl/builders/GrGLFragmentShaderBuilder.cpp
src/gpu/gl/builders/GrGLFragmentShaderBuilder.h
src/gpu/gl/builders/GrGLGeometryShaderBuilder.cpp
src/gpu/gl/builders/GrGLGeometryShaderBuilder.h
src/gpu/gl/builders/GrGLNvprProgramBuilder.cpp
src/gpu/gl/builders/GrGLProgramBuilder.cpp
src/gpu/gl/builders/GrGLProgramBuilder.h
src/gpu/gl/builders/GrGLVertexShaderBuilder.cpp
src/gpu/gl/builders/GrGLVertexShaderBuilder.h

index 60928f2..287d7e1 100644 (file)
@@ -23,7 +23,8 @@
  */
 class GrGeometryProcessor : public GrProcessor {
 public:
-    GrGeometryProcessor() {}
+    GrGeometryProcessor()
+        : fWillUseGeoShader(false) {}
 
     virtual const GrBackendGeometryProcessorFactory& getFactory() const = 0;
 
@@ -37,6 +38,8 @@ public:
 
     const VertexAttribArray& getVertexAttribs() const { return fVertexAttribs; }
 
+    bool willUseGeoShader() const { return fWillUseGeoShader; }
+
     /** Returns true if this and other processor conservatively draw identically. It can only return
         true when the two prcoessors are of the same subclass (i.e. they return the same object from
         from getFactory()).
@@ -61,10 +64,13 @@ protected:
         return fVertexAttribs.push_back(var);
     }
 
+    void setWillUseGeoShader() { fWillUseGeoShader = true; }
+
 private:
     virtual bool onIsEqual(const GrGeometryProcessor&) const = 0;
 
     SkSTArray<kMaxVertexAttribs, GrShaderVar, true> fVertexAttribs;
+    bool fWillUseGeoShader;
 
     typedef GrProcessor INHERITED;
 };
index ef4a171..eecc722 100644 (file)
@@ -529,38 +529,38 @@ public:
             : INHERITED (factory) {}
 
         virtual void emitCode(const EmitArgs& args) SK_OVERRIDE {
-            const char *vsName, *fsName;
-            args.fPB->addVarying(kVec4f_GrSLType, "QuadEdge", &vsName, &fsName);
+            GrGLVertToFrag v(kVec4f_GrSLType);
+            args.fPB->addVarying("QuadEdge", &v);
 
             GrGLGPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder();
 
             SkAssertResult(fsBuilder->enableFeature(
                     GrGLFragmentShaderBuilder::kStandardDerivatives_GLSLFeature));
-            fsBuilder->codeAppendf("\t\tfloat edgeAlpha;\n");
+            fsBuilder->codeAppendf("float edgeAlpha;");
 
             // keep the derivative instructions outside the conditional
-            fsBuilder->codeAppendf("\t\tvec2 duvdx = dFdx(%s.xy);\n", fsName);
-            fsBuilder->codeAppendf("\t\tvec2 duvdy = dFdy(%s.xy);\n", fsName);
-            fsBuilder->codeAppendf("\t\tif (%s.z > 0.0 && %s.w > 0.0) {\n", fsName, fsName);
+            fsBuilder->codeAppendf("vec2 duvdx = dFdx(%s.xy);", v.fsIn());
+            fsBuilder->codeAppendf("vec2 duvdy = dFdy(%s.xy);", v.fsIn());
+            fsBuilder->codeAppendf("if (%s.z > 0.0 && %s.w > 0.0) {", v.fsIn(), v.fsIn());
             // today we know z and w are in device space. We could use derivatives
-            fsBuilder->codeAppendf("\t\t\tedgeAlpha = min(min(%s.z, %s.w) + 0.5, 1.0);\n", fsName,
-                                    fsName);
-            fsBuilder->codeAppendf ("\t\t} else {\n");
-            fsBuilder->codeAppendf("\t\t\tvec2 gF = vec2(2.0*%s.x*duvdx.x - duvdx.y,\n"
-                                   "\t\t\t               2.0*%s.x*duvdy.x - duvdy.y);\n",
-                                   fsName, fsName);
-            fsBuilder->codeAppendf("\t\t\tedgeAlpha = (%s.x*%s.x - %s.y);\n", fsName, fsName,
-                                    fsName);
-            fsBuilder->codeAppendf("\t\t\tedgeAlpha = "
-                                   "clamp(0.5 - edgeAlpha / length(gF), 0.0, 1.0);\n\t\t}\n");
-
-
-            fsBuilder->codeAppendf("\t%s = %s;\n", args.fOutput,
+            fsBuilder->codeAppendf("edgeAlpha = min(min(%s.z, %s.w) + 0.5, 1.0);", v.fsIn(),
+                                    v.fsIn());
+            fsBuilder->codeAppendf ("} else {");
+            fsBuilder->codeAppendf("vec2 gF = vec2(2.0*%s.x*duvdx.x - duvdx.y,"
+                                   "               2.0*%s.x*duvdy.x - duvdy.y);",
+                                   v.fsIn(), v.fsIn());
+            fsBuilder->codeAppendf("edgeAlpha = (%s.x*%s.x - %s.y);", v.fsIn(), v.fsIn(),
+                                    v.fsIn());
+            fsBuilder->codeAppendf("edgeAlpha = "
+                                   "clamp(0.5 - edgeAlpha / length(gF), 0.0, 1.0);}");
+
+
+            fsBuilder->codeAppendf("%s = %s;", args.fOutput,
                                    (GrGLSLExpr4(args.fInput) * GrGLSLExpr1("edgeAlpha")).c_str());
 
             const GrShaderVar& inQuadEdge = args.fGP.cast<QuadEdgeEffect>().inQuadEdge();
             GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder();
-            vsBuilder->codeAppendf("\t%s = %s;\n", vsName, inQuadEdge.c_str());
+            vsBuilder->codeAppendf("\t%s = %s;\n", v.vsOut(), inQuadEdge.c_str());
         }
 
         static inline void GenKey(const GrProcessor&, const GrGLCaps&, GrProcessorKeyBuilder*) {}
index e5d1593..18bba5a 100644 (file)
@@ -45,17 +45,17 @@ public:
             // setup the varying for the Axis aligned rect effect
             //      xy -> interpolated offset
             //      zw -> w/2+0.5, h/2+0.5
-            const char *vsRectName, *fsRectName;
-            args.fPB->addVarying(kVec4f_GrSLType, "Rect", &vsRectName, &fsRectName);
+            GrGLVertToFrag v(kVec4f_GrSLType);
+            args.fPB->addVarying("Rect", &v);
 
             const GrShaderVar& inRect = args.fGP.cast<GrAlignedRectEffect>().inRect();
             GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder();
-            vsBuilder->codeAppendf("\t%s = %s;\n", vsRectName, inRect.c_str());
+            vsBuilder->codeAppendf("\t%s = %s;\n", v.fsIn(), inRect.c_str());
 
             GrGLGPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder();
             // TODO: compute all these offsets, spans, and scales in the VS
-            fsBuilder->codeAppendf("\tfloat insetW = min(1.0, %s.z) - 0.5;\n", fsRectName);
-            fsBuilder->codeAppendf("\tfloat insetH = min(1.0, %s.w) - 0.5;\n", fsRectName);
+            fsBuilder->codeAppendf("\tfloat insetW = min(1.0, %s.z) - 0.5;\n", v.fsIn());
+            fsBuilder->codeAppendf("\tfloat insetH = min(1.0, %s.w) - 0.5;\n", v.fsIn());
             fsBuilder->codeAppend("\tfloat outset = 0.5;\n");
             // For rects > 1 pixel wide and tall the span's are noops (i.e., 1.0). For rects
             // < 1 pixel wide or tall they serve to normalize the < 1 ramp to a 0 .. 1 range.
@@ -69,12 +69,12 @@ public:
 
             // Compute the coverage for the rect's width
             fsBuilder->codeAppendf(
-                "\tfloat coverage = scaleW*clamp((%s.z-abs(%s.x))/spanW, 0.0, 1.0);\n", fsRectName,
-                fsRectName);
+                "\tfloat coverage = scaleW*clamp((%s.z-abs(%s.x))/spanW, 0.0, 1.0);\n", v.fsIn(),
+                v.fsIn());
             // Compute the coverage for the rect's height and merge with the width
             fsBuilder->codeAppendf(
                 "\tcoverage = coverage*scaleH*clamp((%s.w-abs(%s.y))/spanH, 0.0, 1.0);\n",
-                fsRectName, fsRectName);
+                v.fsIn(), v.fsIn());
 
 
             fsBuilder->codeAppendf("\t%s = %s;\n", args.fOutput,
@@ -163,26 +163,24 @@ public:
         virtual void emitCode(const EmitArgs& args) SK_OVERRIDE {
             // setup the varying for the center point and the unit vector
             // that points down the height of the rect
-            const char *vsRectEdgeName, *fsRectEdgeName;
-            args.fPB->addVarying(kVec4f_GrSLType, "RectEdge",
-                                &vsRectEdgeName, &fsRectEdgeName);
+            GrGLVertToFrag rectEdge(kVec4f_GrSLType);
+            args.fPB->addVarying("RectEdge", &rectEdge);
 
             const GrRectEffect& rectEffect = args.fGP.cast<GrRectEffect>();
             GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder();
-            vsBuilder->codeAppendf("%s = %s;", vsRectEdgeName, rectEffect.inRectEdge().c_str());
+            vsBuilder->codeAppendf("%s = %s;", rectEdge.vsOut(), rectEffect.inRectEdge().c_str());
 
             // setup the varying for width/2+.5 and height/2+.5
-            const char *vsWidthHeightName, *fsWidthHeightName;
-            args.fPB->addVarying(kVec2f_GrSLType, "WidthHeight",
-                                &vsWidthHeightName, &fsWidthHeightName);
+            GrGLVertToFrag widthHeight(kVec2f_GrSLType);
+            args.fPB->addVarying("WidthHeight", &widthHeight);
             vsBuilder->codeAppendf("%s = %s;",
-                                   vsWidthHeightName,
+                                   widthHeight.vsOut(),
                                    rectEffect.inWidthHeight().c_str());
 
             GrGLGPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder();
             // TODO: compute all these offsets, spans, and scales in the VS
-            fsBuilder->codeAppendf("\tfloat insetW = min(1.0, %s.x) - 0.5;\n", fsWidthHeightName);
-            fsBuilder->codeAppendf("\tfloat insetH = min(1.0, %s.y) - 0.5;\n", fsWidthHeightName);
+            fsBuilder->codeAppendf("\tfloat insetW = min(1.0, %s.x) - 0.5;\n", widthHeight.fsIn());
+            fsBuilder->codeAppendf("\tfloat insetH = min(1.0, %s.y) - 0.5;\n", widthHeight.fsIn());
             fsBuilder->codeAppend("\tfloat outset = 0.5;\n");
             // For rects > 1 pixel wide and tall the span's are noops (i.e., 1.0). For rects
             // < 1 pixel wide or tall they serve to normalize the < 1 ramp to a 0 .. 1 range.
@@ -196,19 +194,19 @@ public:
 
             // Compute the coverage for the rect's width
             fsBuilder->codeAppendf("\tvec2 offset = %s.xy - %s.xy;\n",
-                                   fsBuilder->fragmentPosition(), fsRectEdgeName);
+                                   fsBuilder->fragmentPosition(), rectEdge.fsIn());
             fsBuilder->codeAppendf("\tfloat perpDot = abs(offset.x * %s.w - offset.y * %s.z);\n",
-                                   fsRectEdgeName, fsRectEdgeName);
+                                   rectEdge.fsIn(), rectEdge.fsIn());
             fsBuilder->codeAppendf(
                 "\tfloat coverage = scaleW*clamp((%s.x-perpDot)/spanW, 0.0, 1.0);\n",
-                fsWidthHeightName);
+                widthHeight.fsIn());
 
             // Compute the coverage for the rect's height and merge with the width
             fsBuilder->codeAppendf("\tperpDot = abs(dot(offset, %s.zw));\n",
-                                   fsRectEdgeName);
+                                   rectEdge.fsIn());
             fsBuilder->codeAppendf(
                     "\tcoverage = coverage*scaleH*clamp((%s.y-perpDot)/spanH, 0.0, 1.0);\n",
-                    fsWidthHeightName);
+                    widthHeight.fsIn());
 
 
             fsBuilder->codeAppendf("\t%s = %s;\n", args.fOutput,
index 8c3b99c..72a0181 100644 (file)
@@ -94,21 +94,22 @@ public:
 
         virtual void emitCode(const EmitArgs& args) SK_OVERRIDE {
             const CircleEdgeEffect& circleEffect = args.fGP.cast<CircleEdgeEffect>();
-            const char *vsName, *fsName;
-            args.fPB->addVarying(kVec4f_GrSLType, "CircleEdge", &vsName, &fsName);
+            GrGLVertToFrag v(kVec4f_GrSLType);
+            args.fPB->addVarying("CircleEdge", &v);
 
             GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder();;
-            vsBuilder->codeAppendf("\t%s = %s;\n", vsName, circleEffect.inCircleEdge().c_str());
+            vsBuilder->codeAppendf("%s = %s;", v.vsOut(), circleEffect.inCircleEdge().c_str());
 
             GrGLGPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder();
-            fsBuilder->codeAppendf("\tfloat d = length(%s.xy);\n", fsName);
-            fsBuilder->codeAppendf("\tfloat edgeAlpha = clamp(%s.z - d, 0.0, 1.0);\n", fsName);
+            fsBuilder->codeAppendf("float d = length(%s.xy);", v.fsIn());
+            fsBuilder->codeAppendf("float edgeAlpha = clamp(%s.z - d, 0.0, 1.0);", v.fsIn());
             if (circleEffect.isStroked()) {
-                fsBuilder->codeAppendf("\tfloat innerAlpha = clamp(d - %s.w, 0.0, 1.0);\n", fsName);
-                fsBuilder->codeAppend("\tedgeAlpha *= innerAlpha;\n");
+                fsBuilder->codeAppendf("float innerAlpha = clamp(d - %s.w, 0.0, 1.0);",
+                                       v.fsIn());
+                fsBuilder->codeAppend("edgeAlpha *= innerAlpha;");
             }
 
-            fsBuilder->codeAppendf("\t%s = %s;\n", args.fOutput,
+            fsBuilder->codeAppendf("%s = %s;\n", args.fOutput,
                                    (GrGLSLExpr4(args.fInput) * GrGLSLExpr1("edgeAlpha")).c_str());
         }
 
@@ -206,39 +207,43 @@ public:
         virtual void emitCode(const EmitArgs& args) SK_OVERRIDE {
             const EllipseEdgeEffect& ellipseEffect = args.fGP.cast<EllipseEdgeEffect>();
 
-            const char *vsOffsetName, *fsOffsetName;
-            const char *vsRadiiName, *fsRadiiName;
-
-            args.fPB->addVarying(kVec2f_GrSLType, "EllipseOffsets", &vsOffsetName, &fsOffsetName);
+            GrGLVertToFrag ellipseOffsets(kVec2f_GrSLType);
+            args.fPB->addVarying("EllipseOffsets", &ellipseOffsets);
 
             GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder();
-            vsBuilder->codeAppendf("%s = %s;", vsOffsetName,
+            vsBuilder->codeAppendf("%s = %s;", ellipseOffsets.vsOut(),
                                    ellipseEffect.inEllipseOffset().c_str());
 
-            args.fPB->addVarying(kVec4f_GrSLType, "EllipseRadii", &vsRadiiName, &fsRadiiName);
-            vsBuilder->codeAppendf("%s = %s;", vsRadiiName, ellipseEffect.inEllipseRadii().c_str());
+            GrGLVertToFrag ellipseRadii(kVec4f_GrSLType);
+            args.fPB->addVarying("EllipseRadii", &ellipseRadii);
+            vsBuilder->codeAppendf("%s = %s;", ellipseRadii.vsOut(),
+                                   ellipseEffect.inEllipseRadii().c_str());
 
             // for outer curve
             GrGLGPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder();
-            fsBuilder->codeAppendf("\tvec2 scaledOffset = %s*%s.xy;\n", fsOffsetName, fsRadiiName);
-            fsBuilder->codeAppend("\tfloat test = dot(scaledOffset, scaledOffset) - 1.0;\n");
-            fsBuilder->codeAppendf("\tvec2 grad = 2.0*scaledOffset*%s.xy;\n", fsRadiiName);
-            fsBuilder->codeAppend("\tfloat grad_dot = dot(grad, grad);\n");
+            fsBuilder->codeAppendf("vec2 scaledOffset = %s*%s.xy;", ellipseOffsets.fsIn(),
+                                   ellipseRadii.fsIn());
+            fsBuilder->codeAppend("float test = dot(scaledOffset, scaledOffset) - 1.0;");
+            fsBuilder->codeAppendf("vec2 grad = 2.0*scaledOffset*%s.xy;", ellipseRadii.fsIn());
+            fsBuilder->codeAppend("float grad_dot = dot(grad, grad);");
+
             // avoid calling inversesqrt on zero.
-            fsBuilder->codeAppend("\tgrad_dot = max(grad_dot, 1.0e-4);\n");
-            fsBuilder->codeAppend("\tfloat invlen = inversesqrt(grad_dot);\n");
-            fsBuilder->codeAppend("\tfloat edgeAlpha = clamp(0.5-test*invlen, 0.0, 1.0);\n");
+            fsBuilder->codeAppend("grad_dot = max(grad_dot, 1.0e-4);");
+            fsBuilder->codeAppend("float invlen = inversesqrt(grad_dot);");
+            fsBuilder->codeAppend("float edgeAlpha = clamp(0.5-test*invlen, 0.0, 1.0);");
 
             // for inner curve
             if (ellipseEffect.isStroked()) {
-                fsBuilder->codeAppendf("\tscaledOffset = %s*%s.zw;\n", fsOffsetName, fsRadiiName);
-                fsBuilder->codeAppend("\ttest = dot(scaledOffset, scaledOffset) - 1.0;\n");
-                fsBuilder->codeAppendf("\tgrad = 2.0*scaledOffset*%s.zw;\n", fsRadiiName);
-                fsBuilder->codeAppend("\tinvlen = inversesqrt(dot(grad, grad));\n");
-                fsBuilder->codeAppend("\tedgeAlpha *= clamp(0.5+test*invlen, 0.0, 1.0);\n");
+                fsBuilder->codeAppendf("scaledOffset = %s*%s.zw;",
+                                       ellipseOffsets.fsIn(), ellipseRadii.fsIn());
+                fsBuilder->codeAppend("test = dot(scaledOffset, scaledOffset) - 1.0;");
+                fsBuilder->codeAppendf("grad = 2.0*scaledOffset*%s.zw;",
+                                       ellipseRadii.fsIn());
+                fsBuilder->codeAppend("invlen = inversesqrt(dot(grad, grad));");
+                fsBuilder->codeAppend("edgeAlpha *= clamp(0.5+test*invlen, 0.0, 1.0);");
             }
 
-            fsBuilder->codeAppendf("\t%s = %s;\n", args.fOutput,
+            fsBuilder->codeAppendf("%s = %s;", args.fOutput,
                                    (GrGLSLExpr4(args.fInput) * GrGLSLExpr1("edgeAlpha")).c_str());
         }
 
@@ -348,57 +353,57 @@ public:
         virtual void emitCode(const EmitArgs& args) SK_OVERRIDE {
             const DIEllipseEdgeEffect& ellipseEffect = args.fGP.cast<DIEllipseEdgeEffect>();
 
-            const char *vsOffsetName0, *fsOffsetName0;
-            args.fPB->addVarying(kVec2f_GrSLType, "EllipseOffsets0",
-                                      &vsOffsetName0, &fsOffsetName0);
+            GrGLVertToFrag offsets0(kVec2f_GrSLType);
+            args.fPB->addVarying("EllipseOffsets0", &offsets0);
 
             GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder();
-            vsBuilder->codeAppendf("%s = %s;", vsOffsetName0,
+            vsBuilder->codeAppendf("%s = %s;", offsets0.vsOut(),
                                    ellipseEffect.inEllipseOffsets0().c_str());
-            const char *vsOffsetName1, *fsOffsetName1;
-            args.fPB->addVarying(kVec2f_GrSLType, "EllipseOffsets1",
-                                      &vsOffsetName1, &fsOffsetName1);
-            vsBuilder->codeAppendf("\t%s = %s;\n", vsOffsetName1,
+
+            GrGLVertToFrag offsets1(kVec2f_GrSLType);
+            args.fPB->addVarying("EllipseOffsets1", &offsets1);
+            vsBuilder->codeAppendf("%s = %s;", offsets1.vsOut(),
                                    ellipseEffect.inEllipseOffsets1().c_str());
 
             GrGLGPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder();
             SkAssertResult(fsBuilder->enableFeature(
                     GrGLFragmentShaderBuilder::kStandardDerivatives_GLSLFeature));
             // for outer curve
-            fsBuilder->codeAppendf("\tvec2 scaledOffset = %s.xy;\n", fsOffsetName0);
-            fsBuilder->codeAppend("\tfloat test = dot(scaledOffset, scaledOffset) - 1.0;\n");
-            fsBuilder->codeAppendf("\tvec2 duvdx = dFdx(%s);\n", fsOffsetName0);
-            fsBuilder->codeAppendf("\tvec2 duvdy = dFdy(%s);\n", fsOffsetName0);
-            fsBuilder->codeAppendf("\tvec2 grad = vec2(2.0*%s.x*duvdx.x + 2.0*%s.y*duvdx.y,\n"
-                                   "\t                 2.0*%s.x*duvdy.x + 2.0*%s.y*duvdy.y);\n",
-                                   fsOffsetName0, fsOffsetName0, fsOffsetName0, fsOffsetName0);
-
-            fsBuilder->codeAppend("\tfloat grad_dot = dot(grad, grad);\n");
+            fsBuilder->codeAppendf("vec2 scaledOffset = %s.xy;", offsets0.fsIn());
+            fsBuilder->codeAppend("float test = dot(scaledOffset, scaledOffset) - 1.0;");
+            fsBuilder->codeAppendf("vec2 duvdx = dFdx(%s);", offsets0.fsIn());
+            fsBuilder->codeAppendf("vec2 duvdy = dFdy(%s);", offsets0.fsIn());
+            fsBuilder->codeAppendf("vec2 grad = vec2(2.0*%s.x*duvdx.x + 2.0*%s.y*duvdx.y,"
+                                   "                 2.0*%s.x*duvdy.x + 2.0*%s.y*duvdy.y);",
+                                   offsets0.fsIn(), offsets0.fsIn(), offsets0.fsIn(), offsets0.fsIn());
+
+            fsBuilder->codeAppend("float grad_dot = dot(grad, grad);");
             // avoid calling inversesqrt on zero.
-            fsBuilder->codeAppend("\tgrad_dot = max(grad_dot, 1.0e-4);\n");
-            fsBuilder->codeAppend("\tfloat invlen = inversesqrt(grad_dot);\n");
+            fsBuilder->codeAppend("grad_dot = max(grad_dot, 1.0e-4);");
+            fsBuilder->codeAppend("float invlen = inversesqrt(grad_dot);");
             if (kHairline == ellipseEffect.getMode()) {
                 // can probably do this with one step
-                fsBuilder->codeAppend("\tfloat edgeAlpha = clamp(1.0-test*invlen, 0.0, 1.0);\n");
-                fsBuilder->codeAppend("\tedgeAlpha *= clamp(1.0+test*invlen, 0.0, 1.0);\n");
+                fsBuilder->codeAppend("float edgeAlpha = clamp(1.0-test*invlen, 0.0, 1.0);");
+                fsBuilder->codeAppend("edgeAlpha *= clamp(1.0+test*invlen, 0.0, 1.0);");
             } else {
-                fsBuilder->codeAppend("\tfloat edgeAlpha = clamp(0.5-test*invlen, 0.0, 1.0);\n");
+                fsBuilder->codeAppend("float edgeAlpha = clamp(0.5-test*invlen, 0.0, 1.0);");
             }
 
             // for inner curve
             if (kStroke == ellipseEffect.getMode()) {
-                fsBuilder->codeAppendf("\tscaledOffset = %s.xy;\n", fsOffsetName1);
-                fsBuilder->codeAppend("\ttest = dot(scaledOffset, scaledOffset) - 1.0;\n");
-                fsBuilder->codeAppendf("\tduvdx = dFdx(%s);\n", fsOffsetName1);
-                fsBuilder->codeAppendf("\tduvdy = dFdy(%s);\n", fsOffsetName1);
-                fsBuilder->codeAppendf("\tgrad = vec2(2.0*%s.x*duvdx.x + 2.0*%s.y*duvdx.y,\n"
-                                       "\t            2.0*%s.x*duvdy.x + 2.0*%s.y*duvdy.y);\n",
-                                       fsOffsetName1, fsOffsetName1, fsOffsetName1, fsOffsetName1);
-                fsBuilder->codeAppend("\tinvlen = inversesqrt(dot(grad, grad));\n");
-                fsBuilder->codeAppend("\tedgeAlpha *= clamp(0.5+test*invlen, 0.0, 1.0);\n");
+                fsBuilder->codeAppendf("scaledOffset = %s.xy;", offsets1.fsIn());
+                fsBuilder->codeAppend("test = dot(scaledOffset, scaledOffset) - 1.0;");
+                fsBuilder->codeAppendf("duvdx = dFdx(%s);", offsets1.fsIn());
+                fsBuilder->codeAppendf("duvdy = dFdy(%s);", offsets1.fsIn());
+                fsBuilder->codeAppendf("grad = vec2(2.0*%s.x*duvdx.x + 2.0*%s.y*duvdx.y,"
+                                       "            2.0*%s.x*duvdy.x + 2.0*%s.y*duvdy.y);",
+                                       offsets1.fsIn(), offsets1.fsIn(), offsets1.fsIn(),
+                                       offsets1.fsIn());
+                fsBuilder->codeAppend("invlen = inversesqrt(dot(grad, grad));");
+                fsBuilder->codeAppend("edgeAlpha *= clamp(0.5+test*invlen, 0.0, 1.0);");
             }
 
-            fsBuilder->codeAppendf("\t%s = %s;\n", args.fOutput,
+            fsBuilder->codeAppendf("%s = %s;", args.fOutput,
                                    (GrGLSLExpr4(args.fInput) * GrGLSLExpr1("edgeAlpha")).c_str());
         }
 
index 661923d..196168c 100644 (file)
@@ -37,13 +37,12 @@ GrGLConicEffect::GrGLConicEffect(const GrBackendProcessorFactory& factory,
 }
 
 void GrGLConicEffect::emitCode(const EmitArgs& args) {
-    const char *vsName, *fsName;
-
-    args.fPB->addVarying(kVec4f_GrSLType, "ConicCoeffs", &vsName, &fsName);
+    GrGLVertToFrag v(kVec4f_GrSLType);
+    args.fPB->addVarying("ConicCoeffs", &v);
 
     const GrShaderVar& inConicCoeffs = args.fGP.cast<GrConicEffect>().inConicCoeffs();
     GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder();
-    vsBuilder->codeAppendf("%s = %s;", vsName, inConicCoeffs.c_str());
+    vsBuilder->codeAppendf("%s = %s;", v.vsOut(), inConicCoeffs.c_str());
 
     GrGLGPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder();
     fsBuilder->codeAppend("float edgeAlpha;");
@@ -52,18 +51,18 @@ void GrGLConicEffect::emitCode(const EmitArgs& args) {
         case kHairlineAA_GrProcessorEdgeType: {
             SkAssertResult(fsBuilder->enableFeature(
                     GrGLFragmentShaderBuilder::kStandardDerivatives_GLSLFeature));
-            fsBuilder->codeAppendf("vec3 dklmdx = dFdx(%s.xyz);", fsName);
-            fsBuilder->codeAppendf("vec3 dklmdy = dFdy(%s.xyz);", fsName);
+            fsBuilder->codeAppendf("vec3 dklmdx = dFdx(%s.xyz);", v.fsIn());
+            fsBuilder->codeAppendf("vec3 dklmdy = dFdy(%s.xyz);", v.fsIn());
             fsBuilder->codeAppendf("float dfdx ="
                                    "2.0 * %s.x * dklmdx.x - %s.y * dklmdx.z - %s.z * dklmdx.y;",
-                                   fsName, fsName, fsName);
+                                   v.fsIn(), v.fsIn(), v.fsIn());
             fsBuilder->codeAppendf("float dfdy ="
                                    "2.0 * %s.x * dklmdy.x - %s.y * dklmdy.z - %s.z * dklmdy.y;",
-                                   fsName, fsName, fsName);
+                                   v.fsIn(), v.fsIn(), v.fsIn());
             fsBuilder->codeAppend("vec2 gF = vec2(dfdx, dfdy);");
             fsBuilder->codeAppend("float gFM = sqrt(dot(gF, gF));");
-            fsBuilder->codeAppendf("float func = %s.x*%s.x - %s.y*%s.z;", fsName, fsName,
-                                   fsName, fsName);
+            fsBuilder->codeAppendf("float func = %s.x*%s.x - %s.y*%s.z;", v.fsIn(), v.fsIn(),
+                                   v.fsIn(), v.fsIn());
             fsBuilder->codeAppend("func = abs(func);");
             fsBuilder->codeAppend("edgeAlpha = func / gFM;");
             fsBuilder->codeAppend("edgeAlpha = max(1.0 - edgeAlpha, 0.0);");
@@ -74,18 +73,18 @@ void GrGLConicEffect::emitCode(const EmitArgs& args) {
         case kFillAA_GrProcessorEdgeType: {
             SkAssertResult(fsBuilder->enableFeature(
                     GrGLFragmentShaderBuilder::kStandardDerivatives_GLSLFeature));
-            fsBuilder->codeAppendf("vec3 dklmdx = dFdx(%s.xyz);", fsName);
-            fsBuilder->codeAppendf("vec3 dklmdy = dFdy(%s.xyz);", fsName);
+            fsBuilder->codeAppendf("vec3 dklmdx = dFdx(%s.xyz);", v.fsIn());
+            fsBuilder->codeAppendf("vec3 dklmdy = dFdy(%s.xyz);", v.fsIn());
             fsBuilder->codeAppendf("float dfdx ="
                                    "2.0 * %s.x * dklmdx.x - %s.y * dklmdx.z - %s.z * dklmdx.y;",
-                                   fsName, fsName, fsName);
+                                   v.fsIn(), v.fsIn(), v.fsIn());
             fsBuilder->codeAppendf("float dfdy ="
                                    "2.0 * %s.x * dklmdy.x - %s.y * dklmdy.z - %s.z * dklmdy.y;",
-                                   fsName, fsName, fsName);
+                                   v.fsIn(), v.fsIn(), v.fsIn());
             fsBuilder->codeAppend("vec2 gF = vec2(dfdx, dfdy);");
             fsBuilder->codeAppend("float gFM = sqrt(dot(gF, gF));");
-            fsBuilder->codeAppendf("float func = %s.x * %s.x - %s.y * %s.z;", fsName, fsName,
-                                   fsName, fsName);
+            fsBuilder->codeAppendf("float func = %s.x * %s.x - %s.y * %s.z;", v.fsIn(), v.fsIn(),
+                                   v.fsIn(), v.fsIn());
             fsBuilder->codeAppend("edgeAlpha = func / gFM;");
             fsBuilder->codeAppend("edgeAlpha = clamp(1.0 - edgeAlpha, 0.0, 1.0);");
             // Add line below for smooth cubic ramp
@@ -93,8 +92,8 @@ void GrGLConicEffect::emitCode(const EmitArgs& args) {
             break;
         }
         case kFillBW_GrProcessorEdgeType: {
-            fsBuilder->codeAppendf("edgeAlpha = %s.x * %s.x - %s.y * %s.z;", fsName, fsName,
-                                   fsName, fsName);
+            fsBuilder->codeAppendf("edgeAlpha = %s.x * %s.x - %s.y * %s.z;", v.fsIn(), v.fsIn(),
+                                   v.fsIn(), v.fsIn());
             fsBuilder->codeAppend("edgeAlpha = float(edgeAlpha < 0.0);");
             break;
         }
@@ -178,12 +177,12 @@ GrGLQuadEffect::GrGLQuadEffect(const GrBackendProcessorFactory& factory,
 }
 
 void GrGLQuadEffect::emitCode(const EmitArgs& args) {
-    const char *vsName, *fsName;
-    args.fPB->addVarying(kVec4f_GrSLType, "HairQuadEdge", &vsName, &fsName);
+    GrGLVertToFrag v(kVec4f_GrSLType);
+    args.fPB->addVarying("HairQuadEdge", &v);
 
     GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder();
     const GrShaderVar& inHairQuadEdge = args.fGP.cast<GrQuadEffect>().inHairQuadEdge();
-    vsBuilder->codeAppendf("%s = %s;", vsName, inHairQuadEdge.c_str());
+    vsBuilder->codeAppendf("%s = %s;", v.vsOut(), inHairQuadEdge.c_str());
 
     GrGLGPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder();
     fsBuilder->codeAppendf("float edgeAlpha;");
@@ -192,12 +191,12 @@ void GrGLQuadEffect::emitCode(const EmitArgs& args) {
         case kHairlineAA_GrProcessorEdgeType: {
             SkAssertResult(fsBuilder->enableFeature(
                     GrGLFragmentShaderBuilder::kStandardDerivatives_GLSLFeature));
-            fsBuilder->codeAppendf("vec2 duvdx = dFdx(%s.xy);", fsName);
-            fsBuilder->codeAppendf("vec2 duvdy = dFdy(%s.xy);", fsName);
+            fsBuilder->codeAppendf("vec2 duvdx = dFdx(%s.xy);", v.fsIn());
+            fsBuilder->codeAppendf("vec2 duvdy = dFdy(%s.xy);", v.fsIn());
             fsBuilder->codeAppendf("vec2 gF = vec2(2.0 * %s.x * duvdx.x - duvdx.y,"
                                    "               2.0 * %s.x * duvdy.x - duvdy.y);",
-                                   fsName, fsName);
-            fsBuilder->codeAppendf("edgeAlpha = (%s.x * %s.x - %s.y);", fsName, fsName, fsName);
+                                   v.fsIn(), v.fsIn());
+            fsBuilder->codeAppendf("edgeAlpha = (%s.x * %s.x - %s.y);", v.fsIn(), v.fsIn(), v.fsIn());
             fsBuilder->codeAppend("edgeAlpha = sqrt(edgeAlpha * edgeAlpha / dot(gF, gF));");
             fsBuilder->codeAppend("edgeAlpha = max(1.0 - edgeAlpha, 0.0);");
             // Add line below for smooth cubic ramp
@@ -207,12 +206,12 @@ void GrGLQuadEffect::emitCode(const EmitArgs& args) {
         case kFillAA_GrProcessorEdgeType: {
             SkAssertResult(fsBuilder->enableFeature(
                     GrGLFragmentShaderBuilder::kStandardDerivatives_GLSLFeature));
-            fsBuilder->codeAppendf("vec2 duvdx = dFdx(%s.xy);", fsName);
-            fsBuilder->codeAppendf("vec2 duvdy = dFdy(%s.xy);", fsName);
+            fsBuilder->codeAppendf("vec2 duvdx = dFdx(%s.xy);", v.fsIn());
+            fsBuilder->codeAppendf("vec2 duvdy = dFdy(%s.xy);", v.fsIn());
             fsBuilder->codeAppendf("vec2 gF = vec2(2.0 * %s.x * duvdx.x - duvdx.y,"
                                    "               2.0 * %s.x * duvdy.x - duvdy.y);",
-                                   fsName, fsName);
-            fsBuilder->codeAppendf("edgeAlpha = (%s.x * %s.x - %s.y);", fsName, fsName, fsName);
+                                   v.fsIn(), v.fsIn());
+            fsBuilder->codeAppendf("edgeAlpha = (%s.x * %s.x - %s.y);", v.fsIn(), v.fsIn(), v.fsIn());
             fsBuilder->codeAppend("edgeAlpha = edgeAlpha / sqrt(dot(gF, gF));");
             fsBuilder->codeAppend("edgeAlpha = clamp(1.0 - edgeAlpha, 0.0, 1.0);");
             // Add line below for smooth cubic ramp
@@ -220,7 +219,7 @@ void GrGLQuadEffect::emitCode(const EmitArgs& args) {
             break;
         }
         case kFillBW_GrProcessorEdgeType: {
-            fsBuilder->codeAppendf("edgeAlpha = (%s.x * %s.x - %s.y);", fsName, fsName, fsName);
+            fsBuilder->codeAppendf("edgeAlpha = (%s.x * %s.x - %s.y);", v.fsIn(), v.fsIn(), v.fsIn());
             fsBuilder->codeAppend("edgeAlpha = float(edgeAlpha < 0.0);");
             break;
         }
@@ -304,14 +303,12 @@ GrGLCubicEffect::GrGLCubicEffect(const GrBackendProcessorFactory& factory,
 }
 
 void GrGLCubicEffect::emitCode(const EmitArgs& args) {
-    const char *vsName, *fsName;
-
-    args.fPB->addVarying(kVec4f_GrSLType, "CubicCoeffs",
-                         &vsName, &fsName, GrGLShaderVar::kHigh_Precision);
+    GrGLVertToFrag v(kVec4f_GrSLType);
+    args.fPB->addVarying("CubicCoeffs", &v, GrGLShaderVar::kHigh_Precision);
 
     GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder();
     const GrShaderVar& inCubicCoeffs = args.fGP.cast<GrCubicEffect>().inCubicCoeffs();
-    vsBuilder->codeAppendf("%s = %s;", vsName, inCubicCoeffs.c_str());
+    vsBuilder->codeAppendf("%s = %s;", v.vsOut(), inCubicCoeffs.c_str());
 
     GrGLGPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder();
 
@@ -337,18 +334,18 @@ void GrGLCubicEffect::emitCode(const EmitArgs& args) {
         case kHairlineAA_GrProcessorEdgeType: {
             SkAssertResult(fsBuilder->enableFeature(
                     GrGLFragmentShaderBuilder::kStandardDerivatives_GLSLFeature));
-            fsBuilder->codeAppendf("%s = dFdx(%s.xyz);", dklmdx.c_str(), fsName);
-            fsBuilder->codeAppendf("%s = dFdy(%s.xyz);", dklmdy.c_str(), fsName);
+            fsBuilder->codeAppendf("%s = dFdx(%s.xyz);", dklmdx.c_str(), v.fsIn());
+            fsBuilder->codeAppendf("%s = dFdy(%s.xyz);", dklmdy.c_str(), v.fsIn());
             fsBuilder->codeAppendf("%s = 3.0 * %s.x * %s.x * %s.x - %s.y * %s.z - %s.z * %s.y;",
-                                   dfdx.c_str(), fsName, fsName, dklmdx.c_str(), fsName,
-                                   dklmdx.c_str(), fsName, dklmdx.c_str());
+                                   dfdx.c_str(), v.fsIn(), v.fsIn(), dklmdx.c_str(), v.fsIn(),
+                                   dklmdx.c_str(), v.fsIn(), dklmdx.c_str());
             fsBuilder->codeAppendf("%s = 3.0 * %s.x * %s.x * %s.x - %s.y * %s.z - %s.z * %s.y;",
-                                   dfdy.c_str(), fsName, fsName, dklmdy.c_str(), fsName,
-                                   dklmdy.c_str(), fsName, dklmdy.c_str());
+                                   dfdy.c_str(), v.fsIn(), v.fsIn(), dklmdy.c_str(), v.fsIn(),
+                                   dklmdy.c_str(), v.fsIn(), dklmdy.c_str());
             fsBuilder->codeAppendf("%s = vec2(%s, %s);", gF.c_str(), dfdx.c_str(), dfdy.c_str());
             fsBuilder->codeAppendf("%s = sqrt(dot(%s, %s));", gFM.c_str(), gF.c_str(), gF.c_str());
             fsBuilder->codeAppendf("%s = %s.x * %s.x * %s.x - %s.y * %s.z;",
-                                   func.c_str(), fsName, fsName, fsName, fsName, fsName);
+                                   func.c_str(), v.fsIn(), v.fsIn(), v.fsIn(), v.fsIn(), v.fsIn());
             fsBuilder->codeAppendf("%s = abs(%s);", func.c_str(), func.c_str());
             fsBuilder->codeAppendf("%s = %s / %s;",
                                    edgeAlpha.c_str(), func.c_str(), gFM.c_str());
@@ -363,19 +360,19 @@ void GrGLCubicEffect::emitCode(const EmitArgs& args) {
         case kFillAA_GrProcessorEdgeType: {
             SkAssertResult(fsBuilder->enableFeature(
                     GrGLFragmentShaderBuilder::kStandardDerivatives_GLSLFeature));
-            fsBuilder->codeAppendf("%s = dFdx(%s.xyz);", dklmdx.c_str(), fsName);
-            fsBuilder->codeAppendf("%s = dFdy(%s.xyz);", dklmdy.c_str(), fsName);
+            fsBuilder->codeAppendf("%s = dFdx(%s.xyz);", dklmdx.c_str(), v.fsIn());
+            fsBuilder->codeAppendf("%s = dFdy(%s.xyz);", dklmdy.c_str(), v.fsIn());
             fsBuilder->codeAppendf("%s ="
                                    "3.0 * %s.x * %s.x * %s.x - %s.y * %s.z - %s.z * %s.y;",
-                                   dfdx.c_str(), fsName, fsName, dklmdx.c_str(), fsName,
-                                   dklmdx.c_str(), fsName, dklmdx.c_str());
+                                   dfdx.c_str(), v.fsIn(), v.fsIn(), dklmdx.c_str(), v.fsIn(),
+                                   dklmdx.c_str(), v.fsIn(), dklmdx.c_str());
             fsBuilder->codeAppendf("%s = 3.0 * %s.x * %s.x * %s.x - %s.y * %s.z - %s.z * %s.y;",
-                                   dfdy.c_str(), fsName, fsName, dklmdy.c_str(), fsName,
-                                   dklmdy.c_str(), fsName, dklmdy.c_str());
+                                   dfdy.c_str(), v.fsIn(), v.fsIn(), dklmdy.c_str(), v.fsIn(),
+                                   dklmdy.c_str(), v.fsIn(), dklmdy.c_str());
             fsBuilder->codeAppendf("%s = vec2(%s, %s);", gF.c_str(), dfdx.c_str(), dfdy.c_str());
             fsBuilder->codeAppendf("%s = sqrt(dot(%s, %s));", gFM.c_str(), gF.c_str(), gF.c_str());
             fsBuilder->codeAppendf("%s = %s.x * %s.x * %s.x - %s.y * %s.z;",
-                                   func.c_str(), fsName, fsName, fsName, fsName, fsName);
+                                   func.c_str(), v.fsIn(), v.fsIn(), v.fsIn(), v.fsIn(), v.fsIn());
             fsBuilder->codeAppendf("%s = %s / %s;",
                                    edgeAlpha.c_str(), func.c_str(), gFM.c_str());
             fsBuilder->codeAppendf("%s = clamp(1.0 - %s, 0.0, 1.0);",
@@ -388,7 +385,7 @@ void GrGLCubicEffect::emitCode(const EmitArgs& args) {
         }
         case kFillBW_GrProcessorEdgeType: {
             fsBuilder->codeAppendf("%s = %s.x * %s.x * %s.x - %s.y * %s.z;",
-                                   edgeAlpha.c_str(), fsName, fsName, fsName, fsName, fsName);
+                                   edgeAlpha.c_str(), v.fsIn(), v.fsIn(), v.fsIn(), v.fsIn(), v.fsIn());
             fsBuilder->codeAppendf("%s = float(%s < 0.0);", edgeAlpha.c_str(), edgeAlpha.c_str());
             break;
         }
index 84f6b43..afa0754 100644 (file)
@@ -24,23 +24,20 @@ public:
                 args.fGP.cast<GrCustomCoordsTextureEffect>();
         SkASSERT(1 == customCoordsTextureEffect.getVertexAttribs().count());
 
-        SkString fsCoordName;
-        const char* vsVaryingName;
-        const char* fsVaryingNamePtr;
-        args.fPB->addVarying(kVec2f_GrSLType, "textureCoords", &vsVaryingName, &fsVaryingNamePtr);
-        fsCoordName = fsVaryingNamePtr;
+        GrGLVertToFrag v(kVec2f_GrSLType);
+        args.fPB->addVarying("TextureCoords", &v);
 
         GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder();
         const GrShaderVar& inTextureCoords = customCoordsTextureEffect.inTextureCoords();
-        vsBuilder->codeAppendf("\t%s = %s;\n", vsVaryingName, inTextureCoords.c_str());
+        vsBuilder->codeAppendf("%s = %s;", v.vsOut(), inTextureCoords.c_str());
 
         GrGLGPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder();
-        fsBuilder->codeAppendf("\t%s = ", args.fOutput);
+        fsBuilder->codeAppendf("%s = ", args.fOutput);
         fsBuilder->appendTextureLookupAndModulate(args.fInput,
                                                   args.fSamplers[0],
-                                                  fsCoordName.c_str(),
+                                                  v.fsIn(),
                                                   kVec2f_GrSLType);
-        fsBuilder->codeAppend(";\n");
+        fsBuilder->codeAppend(";");
     }
 
     virtual void setData(const GrGLProgramDataManager&,
index 4f6eef1..e15ffbe 100644 (file)
@@ -514,17 +514,17 @@ void GLDashingCircleEffect::emitCode(const EmitArgs& args) {
                                          "params",
                                          &paramName);
 
-    const char *vsCoordName, *fsCoordName;
-    args.fPB->addVarying(kVec2f_GrSLType, "Coord", &vsCoordName, &fsCoordName);
+    GrGLVertToFrag v(kVec2f_GrSLType);
+    args.fPB->addVarying("Coord", &v);
 
     GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder();
-    vsBuilder->codeAppendf("\t%s = %s;\n", vsCoordName, dce.inCoord().c_str());
+    vsBuilder->codeAppendf("\t%s = %s;\n", v.vsOut(), dce.inCoord().c_str());
 
     // transforms all points so that we can compare them to our test circle
     GrGLGPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder();
     fsBuilder->codeAppendf("\t\tfloat xShifted = %s.x - floor(%s.x / %s.z) * %s.z;\n",
-                           fsCoordName, fsCoordName, paramName, paramName);
-    fsBuilder->codeAppendf("\t\tvec2 fragPosShifted = vec2(xShifted, %s.y);\n", fsCoordName);
+                           v.fsIn(), v.fsIn(), paramName, paramName);
+    fsBuilder->codeAppendf("\t\tvec2 fragPosShifted = vec2(xShifted, %s.y);\n", v.fsIn());
     fsBuilder->codeAppendf("\t\tvec2 center = vec2(%s.y, 0.0);\n", paramName);
     fsBuilder->codeAppend("\t\tfloat dist = length(center - fragPosShifted);\n");
     if (GrProcessorEdgeTypeIsAA(dce.getEdgeType())) {
@@ -718,16 +718,16 @@ void GLDashingLineEffect::emitCode(const EmitArgs& args) {
                                             "interval",
                                             &intervalName);
 
-    const char *vsCoordName, *fsCoordName;
-    args.fPB->addVarying(kVec2f_GrSLType, "Coord", &vsCoordName, &fsCoordName);
+    GrGLVertToFrag v(kVec2f_GrSLType);
+    args.fPB->addVarying("Coord", &v);
     GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder();
-    vsBuilder->codeAppendf("\t%s = %s;\n", vsCoordName, de.inCoord().c_str());
+    vsBuilder->codeAppendf("\t%s = %s;\n", v.vsOut(), de.inCoord().c_str());
 
     // transforms all points so that we can compare them to our test rect
     GrGLGPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder();
     fsBuilder->codeAppendf("\t\tfloat xShifted = %s.x - floor(%s.x / %s) * %s;\n",
-                           fsCoordName, fsCoordName, intervalName, intervalName);
-    fsBuilder->codeAppendf("\t\tvec2 fragPosShifted = vec2(xShifted, %s.y);\n", fsCoordName);
+                           v.fsIn(), v.fsIn(), intervalName, intervalName);
+    fsBuilder->codeAppendf("\t\tvec2 fragPosShifted = vec2(xShifted, %s.y);\n", v.fsIn());
     if (GrProcessorEdgeTypeIsAA(de.getEdgeType())) {
         // The amount of coverage removed in x and y by the edges is computed as a pair of negative
         // numbers, xSub and ySub.
index ca38e84..e90ebfb 100755 (executable)
@@ -49,14 +49,11 @@ public:
         SkAssertResult(fsBuilder->enableFeature(
                 GrGLFragmentShaderBuilder::kStandardDerivatives_GLSLFeature));
 
-        SkString fsCoordName;
-        const char* vsCoordName;
-        const char* fsCoordNamePtr;
-        args.fPB->addVarying(kVec2f_GrSLType, "textureCoords", &vsCoordName, &fsCoordNamePtr);
-        fsCoordName = fsCoordNamePtr;
+        GrGLVertToFrag v(kVec2f_GrSLType);
+        args.fPB->addVarying("TextureCoords", &v);
 
         GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder();
-        vsBuilder->codeAppendf("\t%s = %s;\n", vsCoordName, dfTexEffect.inTextureCoords().c_str());
+        vsBuilder->codeAppendf("\t%s = %s;\n", v.vsOut(), dfTexEffect.inTextureCoords().c_str());
 
         const char* textureSizeUniName = NULL;
         fTextureSizeUni = args.fPB->addUniform(GrGLProgramBuilder::kFragment_Visibility,
@@ -65,7 +62,7 @@ public:
 
         fsBuilder->codeAppend("\tvec4 texColor = ");
         fsBuilder->appendTextureLookup(args.fSamplers[0],
-                                       fsCoordName.c_str(),
+                                       v.fsIn(),
                                        kVec2f_GrSLType);
         fsBuilder->codeAppend(";\n");
         fsBuilder->codeAppend("\tfloat distance = "
@@ -75,7 +72,7 @@ public:
         // we adjust for the effect of the transformation on the distance by using
         // the length of the gradient of the texture coordinates. We use st coordinates
         // to ensure we're mapping 1:1 from texel space to pixel space.
-        fsBuilder->codeAppendf("\tvec2 uv = %s;\n", fsCoordName.c_str());
+        fsBuilder->codeAppendf("\tvec2 uv = %s;\n", v.fsIn());
         fsBuilder->codeAppendf("\tvec2 st = uv*%s;\n", textureSizeUniName);
         fsBuilder->codeAppend("\tfloat afwidth;\n");
         if (dfTexEffect.getFlags() & kSimilarity_DistanceFieldEffectFlag) {
@@ -264,14 +261,11 @@ public:
         SkAssertResult(fsBuilder->enableFeature(
                                      GrGLFragmentShaderBuilder::kStandardDerivatives_GLSLFeature));
 
-        SkString fsCoordName;
-        const char* vsCoordName;
-        const char* fsCoordNamePtr;
-        args.fPB->addVarying(kVec2f_GrSLType, "textureCoords", &vsCoordName, &fsCoordNamePtr);
-        fsCoordName = fsCoordNamePtr;
+        GrGLVertToFrag v(kVec2f_GrSLType);
+        args.fPB->addVarying("TextureCoords", &v);
 
         GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder();
-        vsBuilder->codeAppendf("%s = %s;", vsCoordName, dfTexEffect.inTextureCoords().c_str());
+        vsBuilder->codeAppendf("%s = %s;", v.vsOut(), dfTexEffect.inTextureCoords().c_str());
 
         const char* textureSizeUniName = NULL;
         fTextureSizeUni = args.fPB->addUniform(GrGLProgramBuilder::kFragment_Visibility,
@@ -280,7 +274,7 @@ public:
 
         fsBuilder->codeAppend("vec4 texColor = ");
         fsBuilder->appendTextureLookup(args.fSamplers[0],
-                                       fsCoordName.c_str(),
+                                       v.fsIn(),
                                        kVec2f_GrSLType);
         fsBuilder->codeAppend(";");
         fsBuilder->codeAppend("float distance = "
@@ -289,7 +283,7 @@ public:
         // we adjust for the effect of the transformation on the distance by using
         // the length of the gradient of the texture coordinates. We use st coordinates
         // to ensure we're mapping 1:1 from texel space to pixel space.
-        fsBuilder->codeAppendf("vec2 uv = %s;", fsCoordName.c_str());
+        fsBuilder->codeAppendf("vec2 uv = %s;", v.fsIn());
         fsBuilder->codeAppendf("vec2 st = uv*%s;", textureSizeUniName);
         fsBuilder->codeAppend("float afwidth;");
         if (dfTexEffect.getFlags() & kSimilarity_DistanceFieldEffectFlag) {
@@ -421,14 +415,11 @@ public:
                 args.fGP.cast<GrDistanceFieldLCDTextureEffect>();
         SkASSERT(1 == dfTexEffect.getVertexAttribs().count());
 
-        SkString fsCoordName;
-        const char* vsCoordName;
-        const char* fsCoordNamePtr;
-        args.fPB->addVarying(kVec2f_GrSLType, "textureCoords", &vsCoordName, &fsCoordNamePtr);
-        fsCoordName = fsCoordNamePtr;
+        GrGLVertToFrag v(kVec2f_GrSLType);
+        args.fPB->addVarying("TextureCoords", &v);
 
         GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder();
-        vsBuilder->codeAppendf("\t%s = %s;\n", vsCoordName, dfTexEffect.inTextureCoords().c_str());
+        vsBuilder->codeAppendf("\t%s = %s;\n", v.vsOut(), dfTexEffect.inTextureCoords().c_str());
 
         const char* textureSizeUniName = NULL;
         // width, height, 1/(3*width)
@@ -442,7 +433,7 @@ public:
                 GrGLFragmentShaderBuilder::kStandardDerivatives_GLSLFeature));
 
         // create LCD offset adjusted by inverse of transform
-        fsBuilder->codeAppendf("\tvec2 uv = %s;\n", fsCoordName.c_str());
+        fsBuilder->codeAppendf("\tvec2 uv = %s;\n", v.fsIn());
         fsBuilder->codeAppendf("\tvec2 st = uv*%s.xy;\n", textureSizeUniName);
         bool isUniformScale = !!(dfTexEffect.getFlags() & kUniformScale_DistanceFieldEffectMask);
         if (isUniformScale) {
index 76558d8..ff3989b 100644 (file)
@@ -346,12 +346,10 @@ void GrGLFragmentShaderBuilder::bindFragmentShaderLocations(GrGLuint programID)
     }
 }
 
-void GrGLFragmentShaderBuilder::addVarying(GrSLType type,
-               const char* name,
-               const char** fsInName,
-               GrGLShaderVar::Precision fsPrecision) {
-    fInputs.push_back().set(type, GrGLShaderVar::kVaryingIn_TypeModifier, name, fsPrecision);
-    if (fsInName) {
-        *fsInName = name;
+void GrGLFragmentShaderBuilder::addVarying(GrGLVarying* v, GrGLShaderVar::Precision fsPrec) {
+    v->fFsIn = v->fVsOut;
+    if (v->fGsOut) {
+        v->fFsIn = v->fGsOut;
     }
+    fInputs.push_back().set(v->fType, GrGLShaderVar::kVaryingIn_TypeModifier, v->fFsIn, fsPrec);
 }
index 1637d25..67dfbe3 100644 (file)
@@ -10,6 +10,8 @@
 
 #include "GrGLShaderBuilder.h"
 
+class GrGLVarying;
+
 /*
  * This base class encapsulates the functionality which the GP uses to build fragment shaders
  */
@@ -91,6 +93,7 @@ public:
     virtual const char* fragmentPosition() SK_OVERRIDE;
     virtual const char* dstColor() SK_OVERRIDE;
 
+private:
     // Private public interface, used by GrGLProgramBuilder to build a fragment shader
     void emitCodeToReadDstTexture();
     void enableCustomOutput();
@@ -102,14 +105,6 @@ public:
     bool compileAndAttachShaders(GrGLuint programId, SkTDArray<GrGLuint>* shaderIds) const;
     void bindFragmentShaderLocations(GrGLuint programID);
 
-    /*
-     * An internal call for GrGLProgramBuilder to use to add varyings to the vertex shader
-     */
-    void addVarying(GrSLType type,
-                   const char* name,
-                   const char** fsInName,
-                   GrGLShaderVar::Precision fsPrecision = GrGLShaderVar::kDefault_Precision);
-
     // As GLProcessors emit code, there are some conditions we need to verify.  We use the below
     // state to track this.  The reset call is called per processor emitted.
     bool hasReadDstColor() const { return fHasReadDstColor; }
@@ -119,7 +114,12 @@ public:
         fHasReadFragmentPosition = false;
     }
 
-private:
+    /*
+     * An internal call for GrGLProgramBuilder to use to add varyings to the vertex shader
+     */
+    void addVarying(GrGLVarying* v,
+                    GrGLShaderVar::Precision fsPrec = GrGLShaderVar::kDefault_Precision);
+
     /**
      * Features that should only be enabled by GrGLFragmentShaderBuilder itself.
      */
index 8a3b1f4..af95f56 100644 (file)
@@ -15,25 +15,26 @@ GrGLGeometryBuilder::GrGLGeometryBuilder(GrGLProgramBuilder* program)
 
 }
 
-void GrGLGeometryBuilder::addVarying(GrSLType type,
-               const char* name,
-               const char** gsOutName) {
+void GrGLGeometryBuilder::addVarying(const char* name, GrGLVarying* v) {
     // if we have a GS take each varying in as an array
     // and output as non-array.
-    fInputs.push_back();
-    fInputs.back().setType(type);
-    fInputs.back().setTypeModifier(GrGLShaderVar::kVaryingIn_TypeModifier);
-    fInputs.back().setUnsizedArray();
-    *fInputs.back().accessName() = name;
-    fOutputs.push_back();
-    fOutputs.back().setType(type);
-    fOutputs.back().setTypeModifier(GrGLShaderVar::kVaryingOut_TypeModifier);
-    fProgramBuilder->nameVariable(fOutputs.back().accessName(), 'g', name);
-    if (gsOutName) {
-        *gsOutName = fOutputs.back().getName().c_str();
+    if (v->vsVarying()) {
+        fInputs.push_back();
+        fInputs.back().setType(v->fType);
+        fInputs.back().setTypeModifier(GrGLShaderVar::kVaryingIn_TypeModifier);
+        fInputs.back().setUnsizedArray();
+        *fInputs.back().accessName() = v->fVsOut;
+        v->fGsIn = v->fVsOut;
     }
-}
 
+    if (v->fsVarying()) {
+        fOutputs.push_back();
+        fOutputs.back().setType(v->fType);
+        fOutputs.back().setTypeModifier(GrGLShaderVar::kVaryingOut_TypeModifier);
+        fProgramBuilder->nameVariable(fOutputs.back().accessName(), 'g', name);
+        v->fGsOut = fOutputs.back().getName().c_str();
+    }
+}
 
 bool GrGLGeometryBuilder::compileAndAttachShaders(GrGLuint programId,
         SkTDArray<GrGLuint>* shaderIds) const {
index aa27f23..88fa298 100644 (file)
 
 #include "GrGLShaderBuilder.h"
 
+class GrGLVarying;
+
 class GrGLGeometryBuilder : public GrGLShaderBuilder {
 public:
     GrGLGeometryBuilder(GrGLProgramBuilder* program);
+
+private:
     /*
      * an internal call for GrGLFullProgramBuilder to add varyings
      */
-    void addVarying(GrSLType type,
-                   const char* name,
-                   const char** gsOutName);
+    void addVarying(const char* name, GrGLVarying*);
 
     bool compileAndAttachShaders(GrGLuint programId, SkTDArray<GrGLuint>* shaderIds) const;
 
+    friend class GrGLProgramBuilder;
+
     typedef GrGLShaderBuilder INHERITED;
 };
 
index a20b0d6..86b1d7f 100644 (file)
@@ -55,7 +55,6 @@ GrGLNvprProgramBuilder::addSeparableVarying(GrSLType type,
                                             const char* name,
                                             const char** vsOutName,
                                             const char** fsInName) {
-    addVarying(type, name, vsOutName, fsInName);
     SeparableVaryingInfo& varying = fSeparableVaryingInfos.push_back();
     varying.fVariable = fFS.fInputs.back();
     return GrGLInstalledFragProc::ShaderVarHandle(fSeparableVaryingInfos.count() - 1);
index a628feb..4a95f33 100644 (file)
@@ -126,13 +126,19 @@ GrGLProgramBuilder::GrGLProgramBuilder(GrGpuGL* gpu,
     , fUniforms(kVarsPerBlock) {
 }
 
-void GrGLProgramBuilder::addVarying(GrSLType type,
-                                    const char* name,
-                                    const char** vsOutName,
-                                    const char** fsInName,
+void GrGLProgramBuilder::addVarying(const char* name,
+                                    GrGLVarying* varying,
                                     GrGLShaderVar::Precision fsPrecision) {
-    SkString* fsInputName = fVS.addVarying(type, name, vsOutName);
-    fFS.addVarying(type, fsInputName->c_str(), fsInName, fsPrecision);
+    SkASSERT(varying);
+    if (varying->vsVarying()) {
+        fVS.addVarying(name, varying);
+    }
+    if (fOptState.hasGeometryProcessor() && fOptState.getGeometryProcessor()->willUseGeoShader()) {
+        fGS.addVarying(name, varying);
+    }
+    if (varying->fsVarying()) {
+        fFS.addVarying(varying);
+    }
 }
 
 void GrGLProgramBuilder::nameVariable(SkString* out, char prefix, const char* name) {
@@ -362,9 +368,8 @@ void GrGLProgramBuilder::emitTransforms(const GrFragmentStage& effectStage,
             suffixedVaryingName.appendf("_%i", t);
             varyingName = suffixedVaryingName.c_str();
         }
-        const char* vsVaryingName;
-        const char* fsVaryingName;
-        this->addVarying(varyingType, varyingName, &vsVaryingName, &fsVaryingName);
+        GrGLVertToFrag v(varyingType);
+        this->addVarying(varyingName, &v);
 
         const GrGLShaderVar& coords =
                 kPosition_GrCoordSet == effect->coordTransform(t).sourceCoords() ?
@@ -375,13 +380,13 @@ void GrGLProgramBuilder::emitTransforms(const GrFragmentStage& effectStage,
         SkASSERT(kVec2f_GrSLType == varyingType || kVec3f_GrSLType == varyingType);
         if (kVec2f_GrSLType == varyingType) {
             fVS.codeAppendf("%s = (%s * vec3(%s, 1)).xy;",
-                            vsVaryingName, uniName, coords.c_str());
+                            v.vsOut(), uniName, coords.c_str());
         } else {
             fVS.codeAppendf("%s = %s * vec3(%s, 1);",
-                            vsVaryingName, uniName, coords.c_str());
+                            v.vsOut(), uniName, coords.c_str());
         }
         SkNEW_APPEND_TO_TARRAY(outCoords, GrGLProcessor::TransformedCoords,
-                               (SkString(fsVaryingName), varyingType));
+                               (SkString(v.fsIn()), varyingType));
     }
 }
 
index 2afdd09..9d8e7e0 100644 (file)
@@ -69,13 +69,63 @@ public:
      */
 };
 
+// TODO move this into GrGLGPBuilder and move them both out of this file
+class GrGLVarying {
+public:
+    bool vsVarying() const { return kVertToFrag_Varying == fVarying ||
+                                    kVertToGeo_Varying == fVarying; }
+    bool fsVarying() const { return kVertToFrag_Varying == fVarying ||
+                                    kGeoToFrag_Varying == fVarying; }
+    const char* vsOut() const { return fVsOut; }
+    const char* gsIn() const { return fGsIn; }
+    const char* gsOut() const { return fGsOut; }
+    const char* fsIn() const { return fFsIn; }
+
+protected:
+    enum Varying {
+        kVertToFrag_Varying,
+        kVertToGeo_Varying,
+        kGeoToFrag_Varying,
+    };
+
+    GrGLVarying(GrSLType type, Varying varying)
+        : fVarying(varying), fType(type), fVsOut(NULL), fGsIn(NULL), fGsOut(NULL),
+          fFsIn(NULL) {}
+
+    Varying fVarying;
+
+private:
+    GrSLType fType;
+    const char* fVsOut;
+    const char* fGsIn;
+    const char* fGsOut;
+    const char* fFsIn;
+
+    friend class GrGLVertexBuilder;
+    friend class GrGLGeometryBuilder;
+    friend class GrGLFragmentShaderBuilder;
+};
+
+struct GrGLVertToFrag : public GrGLVarying {
+    GrGLVertToFrag(GrSLType type)
+        : GrGLVarying(type, kVertToFrag_Varying) {}
+};
+
+struct GrGLVertToGeo : public GrGLVarying {
+    GrGLVertToGeo(GrSLType type)
+        : GrGLVarying(type, kVertToGeo_Varying) {}
+};
+
+struct GrGLGeoToFrag : public GrGLVarying {
+    GrGLGeoToFrag(GrSLType type)
+        : GrGLVarying(type, kGeoToFrag_Varying) {}
+};
+
 /* a specialization of the above for GPs.  Lets the user add uniforms, varyings, and VS / FS code */
 class GrGLGPBuilder : public virtual GrGLUniformBuilder {
 public:
-    virtual void addVarying(GrSLType type,
-                            const char* name,
-                            const char** vsOutName = NULL,
-                            const char** fsInName = NULL,
+    virtual void addVarying(const char* name,
+                            GrGLVarying*,
                             GrGLShaderVar::Precision fsPrecision=GrGLShaderVar::kDefault_Precision) = 0;
 
     // TODO rename getFragmentBuilder
@@ -152,10 +202,8 @@ public:
     virtual GrGLVertexBuilder* getVertexShaderBuilder() SK_OVERRIDE { return &fVS; }
 
     virtual void addVarying(
-            GrSLType type,
             const char* name,
-            const char** vsOutName = NULL,
-            const char** fsInName = NULL,
+            GrGLVarying*,
             GrGLShaderVar::Precision fsPrecision=GrGLShaderVar::kDefault_Precision) SK_OVERRIDE;
 
     // Handles for program uniforms (other than per-effect uniforms)
index 76026b7..1fa9467 100644 (file)
@@ -23,17 +23,12 @@ GrGLVertexBuilder::GrGLVertexBuilder(GrGLProgramBuilder* program)
     , fEffectAttribOffset(0) {
 }
 
-SkString* GrGLVertexBuilder::addVarying(GrSLType type, const char* name,
-                                              const char** vsOutName) {
+void GrGLVertexBuilder::addVarying(const char* name, GrGLVarying* v) {
     fOutputs.push_back();
-    fOutputs.back().setType(type);
+    fOutputs.back().setType(v->fType);
     fOutputs.back().setTypeModifier(GrGLShaderVar::kVaryingOut_TypeModifier);
     fProgramBuilder->nameVariable(fOutputs.back().accessName(), 'v', name);
-
-    if (vsOutName) {
-        *vsOutName = fOutputs.back().getName().c_str();
-    }
-    return fOutputs.back().accessName();
+    v->fVsOut = fOutputs.back().getName().c_str();
 }
 
 void GrGLVertexBuilder::setupLocalCoords() {
@@ -63,15 +58,15 @@ void GrGLVertexBuilder::transformGLToSkiaCoords() {
 }
 
 void GrGLVertexBuilder::setupBuiltinVertexAttribute(const char* inName, GrGLSLExpr4* out) {
+    GrGLVertToFrag v(kVec4f_GrSLType);
+    fProgramBuilder->addVarying(inName, &v);
     SkString name(inName);
-    const char *vsName, *fsName;
-    fProgramBuilder->addVarying(kVec4f_GrSLType, name.c_str(), &vsName, &fsName);
     name.prepend("in");
     this->addAttribute(GrShaderVar(name.c_str(),
                                    kVec4f_GrSLType,
                                    GrShaderVar::kAttribute_TypeModifier));
-    this->codeAppendf("%s = %s;", vsName, name.c_str());
-    *out = fsName;
+    this->codeAppendf("%s = %s;", v.vsOut(), name.c_str());
+    *out = v.fsIn();
     fEffectAttribOffset++;
 }
 
index 6e1495a..31b4ad4 100644 (file)
 
 #include "GrGLShaderBuilder.h"
 
-class GrGLProgramBuilder;
+class GrGLVarying;
 
-// TODO we only actually ever need to return a GrGLShaderBuilder for this guy, none of the below
-// functions need to be part of VertexShaderBuilder's public interface
 class GrGLVertexBuilder : public GrGLShaderBuilder {
 public:
     GrGLVertexBuilder(GrGLProgramBuilder* program);
@@ -33,10 +31,11 @@ public:
       */
     const GrGLShaderVar& positionAttribute() const { return *fPositionVar; }
 
+private:
     /*
      * Internal call for GrGLProgramBuilder.addVarying
      */
-    SkString* addVarying(GrSLType type, const char* name, const char** vsOutName);
+    void addVarying(const char* name, GrGLVarying*);
 
     /*
      * private helpers for compilation by GrGLProgramBuilder
@@ -49,7 +48,6 @@ public:
     void bindVertexAttributes(GrGLuint programID);
     bool compileAndAttachShaders(GrGLuint programId, SkTDArray<GrGLuint>* shaderIds) const;
 
-private:
     // an internal call which checks for uniquness of a var before adding it to the list of inputs
     bool addAttribute(const GrShaderVar& var);
     struct AttributePair {
@@ -64,6 +62,8 @@ private:
     GrGLShaderVar*                      fLocalCoordsVar;
     int                                 fEffectAttribOffset;
 
+    friend class GrGLProgramBuilder;
+
     typedef GrGLShaderBuilder INHERITED;
 };