Cleanup of shader building system

this is a huge refactor and cleanup of the gl shader building system in
Skia.  The entire shader building pipeline is now part of
GrGLProgramCreator, which takes a gp, and some fps, and creates a
program.  I added some subclasses of GrGLProgram to handle the
eccentricities of Nvpr/Nvpres.  Outside of the builders folder
and GrGLPrograms, this change is basically just a rename

solo gp

BUG=skia:

Committed: https://skia.googlesource.com/skia/+/fe1233c3f12f81bb675718516bbb32f72af726ec

Review URL: https://codereview.chromium.org/611653002
diff --git a/src/gpu/gl/builders/GrGLFragmentShaderBuilder.cpp b/src/gpu/gl/builders/GrGLFragmentShaderBuilder.cpp
index 4266d9f..488d07b 100644
--- a/src/gpu/gl/builders/GrGLFragmentShaderBuilder.cpp
+++ b/src/gpu/gl/builders/GrGLFragmentShaderBuilder.cpp
@@ -10,15 +10,15 @@
 #include "GrGLProgramBuilder.h"
 #include "../GrGpuGL.h"
 
-namespace {
-#define GL_CALL(X) GR_GL_CALL(gpu->glInterface(), X)
-#define GL_CALL_RET(R, X) GR_GL_CALL_RET(gpu->glInterface(), R, X)
+#define GL_CALL(X) GR_GL_CALL(fProgramBuilder->gpu()->glInterface(), X)
+#define GL_CALL_RET(R, X) GR_GL_CALL_RET(fProgramBuilder->gpu()->glInterface(), R, X)
+
 // ES2 FS only guarantees mediump and lowp support
 static const GrGLShaderVar::Precision kDefaultFragmentPrecision = GrGLShaderVar::kMedium_Precision;
-static const char kDstCopyColorName[] = "_dstColor";
-inline const char* declared_color_output_name() { return "fsColorOut"; }
-inline const char* dual_source_output_name() { return "dualSourceOut"; }
-inline void append_default_precision_qualifier(GrGLShaderVar::Precision p,
+const char* GrGLFragmentShaderBuilder::kDstCopyColorName = "_dstColor";
+static const char* declared_color_output_name() { return "fsColorOut"; }
+static const char* dual_source_output_name() { return "dualSourceOut"; }
+static void append_default_precision_qualifier(GrGLShaderVar::Precision p,
                                                GrGLStandard standard,
                                                SkString* str) {
     // Desktop GLSL has added precision qualifiers but they don't do anything.
@@ -40,10 +40,10 @@
         }
     }
 }
-}
 
-GrGLFragmentShaderBuilder::DstReadKey GrGLFragmentShaderBuilder::KeyForDstRead(
-        const GrTexture* dstCopy, const GrGLCaps& caps) {
+GrGLFragmentShaderBuilder::DstReadKey
+GrGLFragmentShaderBuilder::KeyForDstRead(const GrTexture* dstCopy,
+                                                                 const GrGLCaps& caps) {
     uint32_t key = kYesDstRead_DstReadKeyBit;
     if (caps.fbFetchSupport()) {
         return key;
@@ -60,8 +60,9 @@
     return static_cast<DstReadKey>(key);
 }
 
-GrGLFragmentShaderBuilder::FragPosKey GrGLFragmentShaderBuilder::KeyForFragmentPosition(
-        const GrRenderTarget* dst, const GrGLCaps&) {
+GrGLFragmentShaderBuilder::FragPosKey
+GrGLFragmentShaderBuilder::KeyForFragmentPosition(const GrRenderTarget* dst,
+                                                                          const GrGLCaps&) {
     if (kTopLeft_GrSurfaceOrigin == dst->origin()) {
         return kTopLeftFragPosRead_FragPosKey;
     } else {
@@ -75,33 +76,9 @@
     , fHasCustomColorOutput(false)
     , fHasSecondaryOutput(false)
     , fSetupFragPosition(false)
-    , fTopLeftFragPosRead(kTopLeftFragPosRead_FragPosKey == desc.getHeader().fFragPosKey){
-}
-
-const char* GrGLFragmentShaderBuilder::dstColor() {
-    if (fProgramBuilder->fCodeStage.inStageCode()) {
-        const GrProcessor* effect = fProgramBuilder->fCodeStage.effectStage()->getProcessor();
-        // TODO GPs can't read dst color, and full program builder only returns a pointer to the
-        // base fragment shader builder which does not have this function.  Unfortunately,
-        // the code stage class only has a GrProcessor pointer so this is required for the time
-        // being
-        if (!static_cast<const GrFragmentProcessor*>(effect)->willReadDstColor()) {
-            SkDEBUGFAIL("GrGLProcessor asked for dst color but its generating GrProcessor "
-                        "did not request access.");
-            return "";
-        }
-    }
-
-    GrGpuGL* gpu = fProgramBuilder->gpu();
-    if (gpu->glCaps().fbFetchSupport()) {
-        this->addFeature(1 << (GrGLFragmentShaderBuilder::kLastGLSLPrivateFeature + 1),
-                         gpu->glCaps().fbFetchExtensionString());
-        return gpu->glCaps().fbFetchColorName();
-    } else if (fProgramBuilder->fUniformHandles.fDstCopySamplerUni.isValid()) {
-        return kDstCopyColorName;
-    } else {
-        return "";
-    }
+    , fTopLeftFragPosRead(kTopLeftFragPosRead_FragPosKey == desc.getHeader().fFragPosKey)
+    , fHasReadDstColor(false)
+    , fHasReadFragmentPosition(false) {
 }
 
 bool GrGLFragmentShaderBuilder::enableFeature(GLSLFeature feature) {
@@ -140,15 +117,7 @@
 }
 
 const char* GrGLFragmentShaderBuilder::fragmentPosition() {
-    GrGLProgramBuilder::CodeStage* cs = &fProgramBuilder->fCodeStage;
-    if (cs->inStageCode()) {
-        const GrProcessor* effect = cs->effectStage()->getProcessor();
-        if (!effect->willReadFragmentPosition()) {
-            SkDEBUGFAIL("GrGLProcessor asked for frag position but its generating GrProcessor "
-                        "did not request access.");
-            return "";
-        }
-    }
+    fHasReadFragmentPosition = true;
 
     GrGpuGL* gpu = fProgramBuilder->gpu();
     // We only declare "gl_FragCoord" when we're in the case where we want to use layout qualifiers
@@ -175,16 +144,15 @@
         static const char* kCoordName = "fragCoordYDown";
         if (!fSetupFragPosition) {
             // temporarily change the stage index because we're inserting non-stage code.
-            GrGLProgramBuilder::CodeStage::AutoStageRestore csar(cs, NULL);
-
+            GrGLProgramBuilder::AutoStageRestore asr(fProgramBuilder);
             SkASSERT(!fProgramBuilder->fUniformHandles.fRTHeightUni.isValid());
             const char* rtHeightName;
 
             fProgramBuilder->fUniformHandles.fRTHeightUni =
                     fProgramBuilder->addUniform(GrGLProgramBuilder::kFragment_Visibility,
-                                         kFloat_GrSLType,
-                                         "RTHeight",
-                                         &rtHeightName);
+                                                kFloat_GrSLType,
+                                                "RTHeight",
+                                                &rtHeightName);
 
             // Using glFragCoord.zw for the last two components tickles an Adreno driver bug that
             // causes programs to fail to link. Making this function return a vec2() didn't fix the
@@ -198,24 +166,133 @@
     }
 }
 
-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;
+const char* GrGLFragmentShaderBuilder::dstColor() {
+    fHasReadDstColor = true;
+
+    GrGpuGL* gpu = fProgramBuilder->gpu();
+    if (gpu->glCaps().fbFetchSupport()) {
+        this->addFeature(1 << (GrGLFragmentShaderBuilder::kLastGLSLPrivateFeature + 1),
+                         gpu->glCaps().fbFetchExtensionString());
+        return gpu->glCaps().fbFetchColorName();
+    } else if (fProgramBuilder->fUniformHandles.fDstCopySamplerUni.isValid()) {
+        return kDstCopyColorName;
+    } else {
+        return "";
     }
 }
 
-void GrGLFragmentShaderBuilder::bindProgramLocations(GrGLuint programId) {
-    GrGpuGL* gpu = fProgramBuilder->gpu();
-    if (fHasCustomColorOutput) {
-        GL_CALL(BindFragDataLocation(programId, 0, declared_color_output_name()));
+void GrGLFragmentShaderBuilder::emitCodeToReadDstTexture() {
+    bool topDown = SkToBool(kTopLeftOrigin_DstReadKeyBit & fProgramBuilder->header().fDstReadKey);
+    const char* dstCopyTopLeftName;
+    const char* dstCopyCoordScaleName;
+    const char* dstCopySamplerName;
+    uint32_t configMask;
+    if (SkToBool(kUseAlphaConfig_DstReadKeyBit & fProgramBuilder->header().fDstReadKey)) {
+        configMask = kA_GrColorComponentFlag;
+    } else {
+        configMask = kRGBA_GrColorComponentFlags;
     }
-    if (fHasSecondaryOutput) {
-        GL_CALL(BindFragDataLocationIndexed(programId, 0, 1, dual_source_output_name()));
+    fProgramBuilder->fUniformHandles.fDstCopySamplerUni =
+            fProgramBuilder->addUniform(GrGLProgramBuilder::kFragment_Visibility,
+                                        kSampler2D_GrSLType,
+                                        "DstCopySampler",
+                                        &dstCopySamplerName);
+    fProgramBuilder->fUniformHandles.fDstCopyTopLeftUni =
+            fProgramBuilder->addUniform(GrGLProgramBuilder::kFragment_Visibility,
+                                        kVec2f_GrSLType,
+                                        "DstCopyUpperLeft",
+                                        &dstCopyTopLeftName);
+    fProgramBuilder->fUniformHandles.fDstCopyScaleUni =
+            fProgramBuilder->addUniform(GrGLProgramBuilder::kFragment_Visibility,
+                                        kVec2f_GrSLType,
+                                        "DstCopyCoordScale",
+                                        &dstCopyCoordScaleName);
+    const char* fragPos = this->fragmentPosition();
+
+    this->codeAppend("// Read color from copy of the destination.\n");
+    this->codeAppendf("vec2 _dstTexCoord = (%s.xy - %s) * %s;",
+                      fragPos, dstCopyTopLeftName, dstCopyCoordScaleName);
+    if (!topDown) {
+        this->codeAppend("_dstTexCoord.y = 1.0 - _dstTexCoord.y;");
     }
+    this->codeAppendf("vec4 %s = ", GrGLFragmentShaderBuilder::kDstCopyColorName);
+    this->appendTextureLookup(dstCopySamplerName,
+                              "_dstTexCoord",
+                              configMask,
+                              "rgba");
+    this->codeAppend(";");
+}
+
+void GrGLFragmentShaderBuilder::enableCustomOutput() {
+    SkASSERT(!fHasCustomColorOutput);
+    fHasCustomColorOutput = true;
+    fOutputs.push_back().set(kVec4f_GrSLType,
+                             GrGLShaderVar::kOut_TypeModifier,
+                             declared_color_output_name());
+}
+
+void GrGLFragmentShaderBuilder::enableSecondaryOutput() {
+    SkASSERT(!fHasSecondaryOutput);
+    fHasSecondaryOutput = true;
+    fOutputs.push_back().set(kVec4f_GrSLType, GrGLShaderVar::kOut_TypeModifier,
+                             dual_source_output_name());
+}
+
+const char* GrGLFragmentShaderBuilder::getPrimaryColorOutputName() const {
+    return fHasCustomColorOutput ? declared_color_output_name() : "gl_FragColor";
+}
+
+const char* GrGLFragmentShaderBuilder::getSecondaryColorOutputName() const {
+    return dual_source_output_name();
+}
+
+void GrGLFragmentShaderBuilder::enableSecondaryOutput(const GrGLSLExpr4& inputColor,
+                                                      const GrGLSLExpr4& inputCoverage) {
+    this->enableSecondaryOutput();
+    const char* secondaryOutputName = this->getSecondaryColorOutputName();
+    GrGLSLExpr4 coeff(1);
+    switch (fProgramBuilder->header().fSecondaryOutputType) {
+        case GrOptDrawState::kCoverage_SecondaryOutputType:
+            break;
+        case GrOptDrawState::kCoverageISA_SecondaryOutputType:
+            // Get (1-A) into coeff
+            coeff = GrGLSLExpr4::VectorCast(GrGLSLExpr1(1) - inputColor.a());
+            break;
+        case GrOptDrawState::kCoverageISC_SecondaryOutputType:
+            // Get (1-RGBA) into coeff
+            coeff = GrGLSLExpr4(1) - inputColor;
+            break;
+        default:
+            SkFAIL("Unexpected Secondary Output");
+    }
+    // Get coeff * coverage into modulate and then write that to the dual source output.
+    this->codeAppendf("\t%s = %s;\n", secondaryOutputName, (coeff * inputCoverage).c_str());
+}
+
+void GrGLFragmentShaderBuilder::combineColorAndCoverage(const GrGLSLExpr4& inputColor,
+                                                        const GrGLSLExpr4& inputCoverage) {
+    GrGLSLExpr4 fragColor = inputColor * inputCoverage;
+    switch (fProgramBuilder->header().fPrimaryOutputType) {
+        case GrOptDrawState::kModulate_PrimaryOutputType:
+            break;
+        case GrOptDrawState::kCombineWithDst_PrimaryOutputType:
+            {
+                // Tack on "+(1-coverage)dst onto the frag color.
+                GrGLSLExpr4 dstCoeff = GrGLSLExpr4(1) - inputCoverage;
+                GrGLSLExpr4 dstContribution = dstCoeff * GrGLSLExpr4(this->dstColor());
+                fragColor = fragColor + dstContribution;
+            }
+            break;
+        default:
+            SkFAIL("Unknown Primary Output");
+    }
+
+    // On any post 1.10 GLSL supporting GPU, we declare custom output
+    if (k110_GrGLSLGeneration != fProgramBuilder->gpu()->glslGeneration()) {
+        this->enableCustomOutput();
+    }
+
+    this->codeAppendf("\t%s = %s;\n", this->getPrimaryColorOutputName(), fragColor.c_str());
 }
 
 bool GrGLFragmentShaderBuilder::compileAndAttachShaders(GrGLuint programId,
@@ -227,10 +304,10 @@
                                        gpu->glStandard(),
                                        &fragShaderSrc);
     fProgramBuilder->appendUniformDecls(GrGLProgramBuilder::kFragment_Visibility, &fragShaderSrc);
-    fProgramBuilder->appendDecls(fInputs, &fragShaderSrc);
+    this->appendDecls(fInputs, &fragShaderSrc);
     // We shouldn't have declared outputs on 1.10
     SkASSERT(k110_GrGLSLGeneration != gpu->glslGeneration() || fOutputs.empty());
-    fProgramBuilder->appendDecls(fOutputs, &fragShaderSrc);
+    this->appendDecls(fOutputs, &fragShaderSrc);
     fragShaderSrc.append(fFunctions);
     fragShaderSrc.append("void main() {\n");
     fragShaderSrc.append(fCode);
@@ -248,121 +325,21 @@
     return true;
 }
 
-void GrGLFragmentShaderBuilder::emitCodeBeforeEffects() {
-    const GrGLProgramDesc::KeyHeader& header = fProgramBuilder->desc().getHeader();
-    GrGpuGL* gpu = fProgramBuilder->gpu();
-
-    ///////////////////////////////////////////////////////////////////////////
-    // emit code to read the dst copy texture, if necessary
-    if (kNoDstRead_DstReadKey != header.fDstReadKey && !gpu->glCaps().fbFetchSupport()) {
-        bool topDown = SkToBool(kTopLeftOrigin_DstReadKeyBit & header.fDstReadKey);
-        const char* dstCopyTopLeftName;
-        const char* dstCopyCoordScaleName;
-        const char* dstCopySamplerName;
-        uint32_t configMask;
-        if (SkToBool(kUseAlphaConfig_DstReadKeyBit & header.fDstReadKey)) {
-            configMask = kA_GrColorComponentFlag;
-        } else {
-            configMask = kRGBA_GrColorComponentFlags;
-        }
-        fProgramBuilder->fUniformHandles.fDstCopySamplerUni =
-            fProgramBuilder->addUniform(GrGLProgramBuilder::kFragment_Visibility,
-                                 kSampler2D_GrSLType,
-                                 "DstCopySampler",
-                                 &dstCopySamplerName);
-        fProgramBuilder->fUniformHandles.fDstCopyTopLeftUni =
-            fProgramBuilder->addUniform(GrGLProgramBuilder::kFragment_Visibility,
-                                 kVec2f_GrSLType,
-                                 "DstCopyUpperLeft",
-                                 &dstCopyTopLeftName);
-        fProgramBuilder->fUniformHandles.fDstCopyScaleUni =
-            fProgramBuilder->addUniform(GrGLProgramBuilder::kFragment_Visibility,
-                                 kVec2f_GrSLType,
-                                 "DstCopyCoordScale",
-                                 &dstCopyCoordScaleName);
-        const char* fragPos = fragmentPosition();
-
-        this->codeAppend("// Read color from copy of the destination.\n");
-        this->codeAppendf("vec2 _dstTexCoord = (%s.xy - %s) * %s;",
-                          fragPos, dstCopyTopLeftName, dstCopyCoordScaleName);
-        if (!topDown) {
-            this->codeAppend("_dstTexCoord.y = 1.0 - _dstTexCoord.y;");
-        }
-        this->codeAppendf("vec4 %s = ", kDstCopyColorName);
-        this->appendTextureLookup(dstCopySamplerName,
-                                  "_dstTexCoord",
-                                  configMask,
-                                  "rgba");
-        this->codeAppend(";");
+void GrGLFragmentShaderBuilder::bindFragmentShaderLocations(GrGLuint programID) {
+    if (fHasCustomColorOutput) {
+        GL_CALL(BindFragDataLocation(programID, 0, declared_color_output_name()));
     }
-
-    if (k110_GrGLSLGeneration != gpu->glslGeneration()) {
-        fOutputs.push_back().set(kVec4f_GrSLType,
-                                 GrGLShaderVar::kOut_TypeModifier,
-                                 declared_color_output_name());
-        fHasCustomColorOutput = true;
+    if (fHasSecondaryOutput) {
+        GL_CALL(BindFragDataLocationIndexed(programID, 0, 1, dual_source_output_name()));
     }
 }
 
-void GrGLFragmentShaderBuilder::emitCodeAfterEffects(const GrGLSLExpr4& inputColor, const GrGLSLExpr4& inputCoverage) {
-    const GrGLProgramDesc::KeyHeader& header = fProgramBuilder->desc().getHeader();
-
-    ///////////////////////////////////////////////////////////////////////////
-    // write the secondary color output if necessary
-    if (GrOptDrawState::kNone_SecondaryOutputType != header.fSecondaryOutputType) {
-        const char* secondaryOutputName = this->enableSecondaryOutput();
-        GrGLSLExpr4 coeff(1);
-        switch (header.fSecondaryOutputType) {
-            case GrOptDrawState::kCoverage_SecondaryOutputType:
-                break;
-            case GrOptDrawState::kCoverageISA_SecondaryOutputType:
-                // Get (1-A) into coeff
-                coeff = GrGLSLExpr4::VectorCast(GrGLSLExpr1(1) - inputColor.a());
-                break;
-            case GrOptDrawState::kCoverageISC_SecondaryOutputType:
-                // Get (1-RGBA) into coeff
-                coeff = GrGLSLExpr4(1) - inputColor;
-                break;
-            default:
-                SkFAIL("Unexpected Secondary Output");
-        }
-        // Get coeff * coverage into modulate and then write that to the dual source output.
-        codeAppendf("\t%s = %s;\n", secondaryOutputName, (coeff * inputCoverage).c_str());
+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;
     }
-
-    ///////////////////////////////////////////////////////////////////////////
-    // combine color and coverage as frag color
-
-    // Get "color * coverage" into fragColor
-    GrGLSLExpr4 fragColor = inputColor * inputCoverage;
-    switch (header.fPrimaryOutputType) {
-        case GrOptDrawState::kModulate_PrimaryOutputType:
-            break;
-        case GrOptDrawState::kCombineWithDst_PrimaryOutputType:
-            {
-                // Tack on "+(1-coverage)dst onto the frag color.
-                GrGLSLExpr4 dstCoeff = GrGLSLExpr4(1) - inputCoverage;
-                GrGLSLExpr4 dstContribution = dstCoeff * GrGLSLExpr4(dstColor());
-                fragColor = fragColor + dstContribution;
-            }
-            break;
-        default:
-            SkFAIL("Unknown Primary Output");
-    }
-    codeAppendf("\t%s = %s;\n", this->getColorOutputName(), fragColor.c_str());
 }
-
-const char* GrGLFragmentShaderBuilder::enableSecondaryOutput() {
-    if (!fHasSecondaryOutput) {
-        fOutputs.push_back().set(kVec4f_GrSLType,
-                                 GrGLShaderVar::kOut_TypeModifier,
-                                 dual_source_output_name());
-        fHasSecondaryOutput = true;
-    }
-    return dual_source_output_name();
-}
-
-const char* GrGLFragmentShaderBuilder::getColorOutputName() const {
-    return fHasCustomColorOutput ? declared_color_output_name() : "gl_FragColor";
-}
-