Added varying struct

TBR=
BUG=skia:

Committed: https://skia.googlesource.com/skia/+/852ae80b9c3c6fd53f993ac35133d80863993cbe

Review URL: https://codereview.chromium.org/671023002
diff --git a/src/gpu/gl/builders/GrGLFragmentShaderBuilder.cpp b/src/gpu/gl/builders/GrGLFragmentShaderBuilder.cpp
index 76558d8..ff3989b 100644
--- a/src/gpu/gl/builders/GrGLFragmentShaderBuilder.cpp
+++ b/src/gpu/gl/builders/GrGLFragmentShaderBuilder.cpp
@@ -346,12 +346,10 @@
     }
 }
 
-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);
 }
diff --git a/src/gpu/gl/builders/GrGLFragmentShaderBuilder.h b/src/gpu/gl/builders/GrGLFragmentShaderBuilder.h
index 1637d25..b5f83d4 100644
--- a/src/gpu/gl/builders/GrGLFragmentShaderBuilder.h
+++ b/src/gpu/gl/builders/GrGLFragmentShaderBuilder.h
@@ -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 @@
     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 @@
     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,11 @@
         fHasReadFragmentPosition = false;
     }
 
-private:
+    /*
+     * An internal call for GrGLProgramBuilder to use to add varyings to the vertex shader
+     */
+    void addVarying(GrGLVarying*, GrGLShaderVar::Precision);
+
     /**
      * Features that should only be enabled by GrGLFragmentShaderBuilder itself.
      */
diff --git a/src/gpu/gl/builders/GrGLGeometryShaderBuilder.cpp b/src/gpu/gl/builders/GrGLGeometryShaderBuilder.cpp
index 8a3b1f4..af95f56 100644
--- a/src/gpu/gl/builders/GrGLGeometryShaderBuilder.cpp
+++ b/src/gpu/gl/builders/GrGLGeometryShaderBuilder.cpp
@@ -15,26 +15,27 @@
 
 }
 
-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 {
     const GrGLContext& glCtx = fProgramBuilder->gpu()->glContext();
diff --git a/src/gpu/gl/builders/GrGLGeometryShaderBuilder.h b/src/gpu/gl/builders/GrGLGeometryShaderBuilder.h
index aa27f23..88fa298 100644
--- a/src/gpu/gl/builders/GrGLGeometryShaderBuilder.h
+++ b/src/gpu/gl/builders/GrGLGeometryShaderBuilder.h
@@ -10,18 +10,22 @@
 
 #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;
 };
 
diff --git a/src/gpu/gl/builders/GrGLNvprProgramBuilder.cpp b/src/gpu/gl/builders/GrGLNvprProgramBuilder.cpp
index a20b0d6..86b1d7f 100644
--- a/src/gpu/gl/builders/GrGLNvprProgramBuilder.cpp
+++ b/src/gpu/gl/builders/GrGLNvprProgramBuilder.cpp
@@ -55,7 +55,6 @@
                                             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);
diff --git a/src/gpu/gl/builders/GrGLProgramBuilder.cpp b/src/gpu/gl/builders/GrGLProgramBuilder.cpp
index a628feb..28d1517 100644
--- a/src/gpu/gl/builders/GrGLProgramBuilder.cpp
+++ b/src/gpu/gl/builders/GrGLProgramBuilder.cpp
@@ -126,13 +126,19 @@
     , 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, fsPrecision);
+    }
 }
 
 void GrGLProgramBuilder::nameVariable(SkString* out, char prefix, const char* name) {
@@ -362,9 +368,8 @@
             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 @@
         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));
     }
 }
 
diff --git a/src/gpu/gl/builders/GrGLProgramBuilder.h b/src/gpu/gl/builders/GrGLProgramBuilder.h
index 2afdd09..9d8e7e0 100644
--- a/src/gpu/gl/builders/GrGLProgramBuilder.h
+++ b/src/gpu/gl/builders/GrGLProgramBuilder.h
@@ -69,13 +69,63 @@
      */
 };
 
+// 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 @@
     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)
diff --git a/src/gpu/gl/builders/GrGLVertexShaderBuilder.cpp b/src/gpu/gl/builders/GrGLVertexShaderBuilder.cpp
index 76026b7..1fa9467 100644
--- a/src/gpu/gl/builders/GrGLVertexShaderBuilder.cpp
+++ b/src/gpu/gl/builders/GrGLVertexShaderBuilder.cpp
@@ -23,17 +23,12 @@
     , 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::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++;
 }
 
diff --git a/src/gpu/gl/builders/GrGLVertexShaderBuilder.h b/src/gpu/gl/builders/GrGLVertexShaderBuilder.h
index 6e1495a..31b4ad4 100644
--- a/src/gpu/gl/builders/GrGLVertexShaderBuilder.h
+++ b/src/gpu/gl/builders/GrGLVertexShaderBuilder.h
@@ -10,10 +10,8 @@
 
 #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 @@
       */
     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 @@
     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 @@
     GrGLShaderVar*                      fLocalCoordsVar;
     int                                 fEffectAttribOffset;
 
+    friend class GrGLProgramBuilder;
+
     typedef GrGLShaderBuilder INHERITED;
 };