OptState owns program descriptor
authorjoshualitt <joshualitt@chromium.org>
Wed, 29 Oct 2014 00:59:26 +0000 (17:59 -0700)
committerCommit bot <commit-bot@chromium.org>
Wed, 29 Oct 2014 00:59:26 +0000 (17:59 -0700)
BUG=skia:

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

24 files changed:
gyp/gpu.gypi
src/gpu/GrGpu.h
src/gpu/GrOptDrawState.cpp
src/gpu/GrOptDrawState.h
src/gpu/GrProgramDesc.h [new file with mode: 0644]
src/gpu/gl/GrGLProgram.cpp
src/gpu/gl/GrGLProgram.h
src/gpu/gl/GrGLProgramDesc.cpp
src/gpu/gl/GrGLProgramDesc.h
src/gpu/gl/GrGpuGL.cpp
src/gpu/gl/GrGpuGL.h
src/gpu/gl/GrGpuGL_program.cpp
src/gpu/gl/builders/GrGLFragmentShaderBuilder.cpp
src/gpu/gl/builders/GrGLFragmentShaderBuilder.h
src/gpu/gl/builders/GrGLGeometryShaderBuilder.cpp
src/gpu/gl/builders/GrGLLegacyNvprProgramBuilder.cpp
src/gpu/gl/builders/GrGLLegacyNvprProgramBuilder.h
src/gpu/gl/builders/GrGLNvprProgramBuilder.cpp
src/gpu/gl/builders/GrGLNvprProgramBuilder.h
src/gpu/gl/builders/GrGLProgramBuilder.cpp
src/gpu/gl/builders/GrGLProgramBuilder.h
src/gpu/gl/builders/GrGLShaderBuilder.h
src/gpu/gl/builders/GrGLVertexShaderBuilder.cpp
tests/GLProgramsTest.cpp

index 033d51c77d23ae5ef25a38d534dfc4e6bb1ff8c0..9db1d7febc147604e90b2ee1f838b082c5634cc6 100644 (file)
       '<(skia_src_path)/gpu/GrPathRendering.h',
       '<(skia_src_path)/gpu/GrPathUtils.cpp',
       '<(skia_src_path)/gpu/GrPathUtils.h',
+      '<(skia_src_path)/gpu/GrProgramDesc.h',
       '<(skia_src_path)/gpu/GrProgramElement.cpp',
       '<(skia_src_path)/gpu/GrProcessor.cpp',
       '<(skia_src_path)/gpu/GrGpuResourceRef.cpp',
index 9478530bb839ed2ac141e436e8009aaf19ab1ed6..6814ae979b681757b92755a3b59842a4566c3965 100644 (file)
@@ -11,6 +11,7 @@
 #include "GrDrawTarget.h"
 #include "GrClipMaskManager.h"
 #include "GrPathRendering.h"
+#include "GrProgramDesc.h"
 #include "SkPath.h"
 
 class GrContext;
@@ -324,6 +325,12 @@ public:
 
     GrContext::GPUStats* gpuStats() { return &fGPUStats; }
 
+    virtual void buildProgramDesc(const GrOptDrawState&,
+                                  const GrProgramDesc::DescInfo&,
+                                  GrGpu::DrawType,
+                                  const GrDeviceCoordTexture* dstCopy,
+                                  GrProgramDesc*) = 0;
+
 protected:
     DrawType PrimTypeToDrawType(GrPrimitiveType type) {
         switch (type) {
index 77a9fc8dc454a25672d849f9ec8d5fb1f10c2081..529e9ed75e9bbe5bc773de378474da442afe91d2 100644 (file)
@@ -9,12 +9,15 @@
 
 #include "GrDrawState.h"
 #include "GrDrawTargetCaps.h"
+#include "gl/GrGpuGL.h"
 
 GrOptDrawState::GrOptDrawState(const GrDrawState& drawState,
                                BlendOptFlags blendOptFlags,
                                GrBlendCoeff optSrcCoeff,
                                GrBlendCoeff optDstCoeff,
-                               const GrDrawTargetCaps& caps) {
+                               GrGpu* gpu,
+                               const GrDeviceCoordTexture* dstCopy,
+                               GrGpu::DrawType drawType) {
     fRenderTarget.set(SkSafeRef(drawState.getRenderTarget()), kWrite_GrIOType);
     fColor = drawState.getColor();
     fCoverage = drawState.getCoverage();
@@ -29,13 +32,14 @@ GrOptDrawState::GrOptDrawState(const GrDrawState& drawState,
     fBlendOptFlags = blendOptFlags;
     fSrcBlend = optSrcCoeff;
     fDstBlend = optDstCoeff;
+    GrProgramDesc::DescInfo descInfo;
 
-    memcpy(fFixedFunctionVertexAttribIndices,
+    memcpy(descInfo.fFixedFunctionVertexAttribIndices,
            drawState.getFixedFunctionVertexAttribIndices(),
-           sizeof(fFixedFunctionVertexAttribIndices));
+           sizeof(descInfo.fFixedFunctionVertexAttribIndices));
 
-    fInputColorIsUsed = true;
-    fInputCoverageIsUsed = true;
+    descInfo.fInputColorIsUsed = true;
+    descInfo.fInputCoverageIsUsed = true;
 
     int firstColorStageIdx = 0;
     int firstCoverageStageIdx = 0;
@@ -43,16 +47,18 @@ GrOptDrawState::GrOptDrawState(const GrDrawState& drawState,
 
     uint8_t fixedFunctionVAToRemove = 0;
 
-    this->computeEffectiveColorStages(drawState, &firstColorStageIdx, &fixedFunctionVAToRemove);
-    this->computeEffectiveCoverageStages(drawState, &firstCoverageStageIdx);
-    this->adjustFromBlendOpts(drawState, &firstColorStageIdx, &firstCoverageStageIdx,
+    this->computeEffectiveColorStages(drawState, &descInfo, &firstColorStageIdx,
+                                      &fixedFunctionVAToRemove);
+    this->computeEffectiveCoverageStages(drawState, &descInfo, &firstCoverageStageIdx);
+    this->adjustFromBlendOpts(drawState, &descInfo, &firstColorStageIdx, &firstCoverageStageIdx,
                               &fixedFunctionVAToRemove);
     // Should not be setting any more FFVA to be removed at this point
     if (0 != fixedFunctionVAToRemove) {
-        this->removeFixedFunctionVertexAttribs(fixedFunctionVAToRemove);
+        this->removeFixedFunctionVertexAttribs(fixedFunctionVAToRemove, &descInfo);
     }
-    this->getStageStats(drawState, firstColorStageIdx, firstCoverageStageIdx);
-    this->setOutputStateInfo(drawState, caps, firstCoverageStageIdx, &separateCoverageFromColor);
+    this->getStageStats(drawState, firstColorStageIdx, firstCoverageStageIdx, &descInfo);
+    this->setOutputStateInfo(drawState, *gpu->caps(), firstCoverageStageIdx, &descInfo,
+                             &separateCoverageFromColor);
 
     // Copy GeometryProcesssor from DS or ODS
     if (drawState.hasGeometryProcessor()) {
@@ -79,10 +85,16 @@ GrOptDrawState::GrOptDrawState(const GrDrawState& drawState,
             fNumColorStages = fFragmentStages.count();
         }
     }
+
+    // now create a key
+    gpu->buildProgramDesc(*this, descInfo, drawType, dstCopy, &fDesc);
 };
 
-GrOptDrawState* GrOptDrawState::Create(const GrDrawState& drawState, const GrDrawTargetCaps& caps,
+GrOptDrawState* GrOptDrawState::Create(const GrDrawState& drawState,
+                                       GrGpu* gpu,
+                                       const GrDeviceCoordTexture* dstCopy,
                                        GrGpu::DrawType drawType) {
+    const GrDrawTargetCaps& caps = *gpu->caps();
     if (NULL == drawState.fCachedOptState || caps.getUniqueID() != drawState.fCachedCapsID) {
         GrBlendCoeff srcCoeff;
         GrBlendCoeff dstCoeff;
@@ -100,7 +112,7 @@ GrOptDrawState* GrOptDrawState::Create(const GrDrawState& drawState, const GrDra
         }
 
         drawState.fCachedOptState = SkNEW_ARGS(GrOptDrawState, (drawState, blendFlags, srcCoeff,
-                                                                dstCoeff, caps));
+                                                                dstCoeff, gpu, dstCopy, drawType));
         drawState.fCachedCapsID = caps.getUniqueID();
     } else {
 #ifdef SK_DEBUG
@@ -109,8 +121,8 @@ GrOptDrawState* GrOptDrawState::Create(const GrDrawState& drawState, const GrDra
         BlendOptFlags blendFlags = (BlendOptFlags) drawState.getBlendOpts(false,
                                                                           &srcCoeff,
                                                                           &dstCoeff);
-        SkASSERT(GrOptDrawState(drawState, blendFlags, srcCoeff, dstCoeff, caps) ==
-                 *drawState.fCachedOptState);
+        SkASSERT(GrOptDrawState(drawState, blendFlags, srcCoeff, dstCoeff, gpu, dstCopy,
+                                drawType) == *drawState.fCachedOptState);
 #endif
     }
     drawState.fCachedOptState->ref();
@@ -120,45 +132,47 @@ GrOptDrawState* GrOptDrawState::Create(const GrDrawState& drawState, const GrDra
 void GrOptDrawState::setOutputStateInfo(const GrDrawState& ds,
                                         const GrDrawTargetCaps& caps,
                                         int firstCoverageStageIdx,
+                                        GrProgramDesc::DescInfo* descInfo,
                                         bool* separateCoverageFromColor) {
     // Set this default and then possibly change our mind if there is coverage.
-    fPrimaryOutputType = kModulate_PrimaryOutputType;
-    fSecondaryOutputType = kNone_SecondaryOutputType;
+    descInfo->fPrimaryOutputType = GrProgramDesc::kModulate_PrimaryOutputType;
+    descInfo->fSecondaryOutputType = GrProgramDesc::kNone_SecondaryOutputType;
 
     // If we do have coverage determine whether it matters.
     *separateCoverageFromColor = this->hasGeometryProcessor();
     if (!this->isCoverageDrawing() &&
         (ds.numCoverageStages() - firstCoverageStageIdx > 0 ||
          ds.hasGeometryProcessor() ||
-         this->hasCoverageVertexAttribute())) {
+         descInfo->hasCoverageVertexAttribute())) {
 
         if (caps.dualSourceBlendingSupport()) {
             if (kZero_GrBlendCoeff == fDstBlend) {
                 // write the coverage value to second color
-                fSecondaryOutputType =  kCoverage_SecondaryOutputType;
+                descInfo->fSecondaryOutputType = GrProgramDesc::kCoverage_SecondaryOutputType;
                 *separateCoverageFromColor = true;
                 fDstBlend = (GrBlendCoeff)GrGpu::kIS2C_GrBlendCoeff;
             } else if (kSA_GrBlendCoeff == fDstBlend) {
                 // SA dst coeff becomes 1-(1-SA)*coverage when dst is partially covered.
-                fSecondaryOutputType = kCoverageISA_SecondaryOutputType;
+                descInfo->fSecondaryOutputType = GrProgramDesc::kCoverageISA_SecondaryOutputType;
                 *separateCoverageFromColor = true;
                 fDstBlend = (GrBlendCoeff)GrGpu::kIS2C_GrBlendCoeff;
             } else if (kSC_GrBlendCoeff == fDstBlend) {
                 // SA dst coeff becomes 1-(1-SA)*coverage when dst is partially covered.
-                fSecondaryOutputType = kCoverageISC_SecondaryOutputType;
+                descInfo->fSecondaryOutputType = GrProgramDesc::kCoverageISC_SecondaryOutputType;
                 *separateCoverageFromColor = true;
                 fDstBlend = (GrBlendCoeff)GrGpu::kIS2C_GrBlendCoeff;
             }
-        } else if (fReadsDst &&
+        } else if (descInfo->fReadsDst &&
                    kOne_GrBlendCoeff == fSrcBlend &&
                    kZero_GrBlendCoeff == fDstBlend) {
-            fPrimaryOutputType = kCombineWithDst_PrimaryOutputType;
+            descInfo->fPrimaryOutputType = GrProgramDesc::kCombineWithDst_PrimaryOutputType;
             *separateCoverageFromColor = true;
         }
     }
 }
 
 void GrOptDrawState::adjustFromBlendOpts(const GrDrawState& ds,
+                                         GrProgramDesc::DescInfo* descInfo,
                                          int* firstColorStageIdx,
                                          int* firstCoverageStageIdx,
                                          uint8_t* fixedFunctionVAToRemove) {
@@ -171,15 +185,15 @@ void GrOptDrawState::adjustFromBlendOpts(const GrDrawState& ds,
             break;
         case kEmitCoverage_BlendOptFlag:
             fColor = 0xffffffff;
-            fInputColorIsUsed = true;
+            descInfo->fInputColorIsUsed = true;
             *firstColorStageIdx = ds.numColorStages();
             *fixedFunctionVAToRemove |= 0x1 << kColor_GrVertexAttribBinding;
             break;
         case kEmitTransBlack_BlendOptFlag:
             fColor = 0;
             fCoverage = 0xff;
-            fInputColorIsUsed = true;
-            fInputCoverageIsUsed = true;
+            descInfo->fInputColorIsUsed = true;
+            descInfo->fInputCoverageIsUsed = true;
             *firstColorStageIdx = ds.numColorStages();
             *firstCoverageStageIdx = ds.numCoverageStages();
             *fixedFunctionVAToRemove |= (0x1 << kColor_GrVertexAttribBinding |
@@ -190,12 +204,13 @@ void GrOptDrawState::adjustFromBlendOpts(const GrDrawState& ds,
     }
 }
 
-void GrOptDrawState::removeFixedFunctionVertexAttribs(uint8_t removeVAFlag) {
+void GrOptDrawState::removeFixedFunctionVertexAttribs(uint8_t removeVAFlag,
+                                                      GrProgramDesc::DescInfo* descInfo) {
     int numToRemove = 0;
     uint8_t maskCheck = 0x1;
     // Count the number of vertex attributes that we will actually remove
     for (int i = 0; i < kGrFixedFunctionVertexAttribBindingCnt; ++i) {
-        if ((maskCheck & removeVAFlag) && -1 != fFixedFunctionVertexAttribIndices[i]) {
+        if ((maskCheck & removeVAFlag) && -1 != descInfo->fFixedFunctionVertexAttribIndices[i]) {
             ++numToRemove;
         }
         maskCheck <<= 1;
@@ -211,11 +226,11 @@ void GrOptDrawState::removeFixedFunctionVertexAttribs(uint8_t removeVAFlag) {
         if (currAttrib.fBinding < kGrFixedFunctionVertexAttribBindingCnt) {
             uint8_t maskCheck = 0x1 << currAttrib.fBinding;
             if (maskCheck & removeVAFlag) {
-                SkASSERT(-1 != fFixedFunctionVertexAttribIndices[currAttrib.fBinding]);
-                fFixedFunctionVertexAttribIndices[currAttrib.fBinding] = -1;
+                SkASSERT(-1 != descInfo->fFixedFunctionVertexAttribIndices[currAttrib.fBinding]);
+                descInfo->fFixedFunctionVertexAttribIndices[currAttrib.fBinding] = -1;
                 continue;
             }
-            fFixedFunctionVertexAttribIndices[currAttrib.fBinding] = newIdx;
+            descInfo->fFixedFunctionVertexAttribIndices[currAttrib.fBinding] = newIdx;
         }
         memcpy(dst, src, sizeof(GrVertexAttrib));
         ++newIdx;
@@ -225,12 +240,14 @@ void GrOptDrawState::removeFixedFunctionVertexAttribs(uint8_t removeVAFlag) {
     fVAPtr = fOptVA.get();
 }
 
-void GrOptDrawState::computeEffectiveColorStages(const GrDrawState& ds, int* firstColorStageIdx,
+void GrOptDrawState::computeEffectiveColorStages(const GrDrawState& ds,
+                                                 GrProgramDesc::DescInfo* descInfo,
+                                                 int* firstColorStageIdx,
                                                  uint8_t* fixedFunctionVAToRemove) {
     // Set up color and flags for ConstantColorComponent checks
     GrProcessor::InvariantOutput inout;
     inout.fIsSingleComponent = false;
-    if (!this->hasColorVertexAttribute()) {
+    if (!descInfo->hasColorVertexAttribute()) {
         inout.fColor = ds.getColor();
         inout.fValidFlags = kRGBA_GrColorComponentFlags;
     } else {
@@ -249,12 +266,12 @@ void GrOptDrawState::computeEffectiveColorStages(const GrDrawState& ds, int* fir
         fp->computeInvariantOutput(&inout);
         if (!inout.fWillUseInputColor) {
             *firstColorStageIdx = i;
-            fInputColorIsUsed = false;
+            descInfo->fInputColorIsUsed = false;
         }
         if (kRGBA_GrColorComponentFlags == inout.fValidFlags) {
             *firstColorStageIdx = i + 1;
             fColor = inout.fColor;
-            fInputColorIsUsed = true;
+            descInfo->fInputColorIsUsed = true;
             *fixedFunctionVAToRemove |= 0x1 << kColor_GrVertexAttribBinding;
             // Since we are clearing all previous color stages we are in a state where we have found
             // zero stages that don't multiply the inputColor.
@@ -264,6 +281,7 @@ void GrOptDrawState::computeEffectiveColorStages(const GrDrawState& ds, int* fir
 }
 
 void GrOptDrawState::computeEffectiveCoverageStages(const GrDrawState& ds,
+                                                    GrProgramDesc::DescInfo* descInfo,
                                                     int* firstCoverageStageIdx) {
     // We do not try to optimize out constantColor coverage effects here. It is extremely rare
     // to have a coverage effect that returns a constant value for all four channels. Thus we
@@ -278,7 +296,7 @@ void GrOptDrawState::computeEffectiveCoverageStages(const GrDrawState& ds,
         fp->computeInvariantOutput(&inout);
         if (!inout.fWillUseInputColor) {
             *firstCoverageStageIdx = i;
-            fInputCoverageIsUsed = false;
+            descInfo->fInputCoverageIsUsed = false;
         }
     }
 #endif
@@ -294,26 +312,26 @@ static void get_stage_stats(const GrFragmentStage& stage, bool* readsDst, bool*
 }
 
 void GrOptDrawState::getStageStats(const GrDrawState& ds, int firstColorStageIdx,
-                                   int firstCoverageStageIdx) {
+                                   int firstCoverageStageIdx, GrProgramDesc::DescInfo* descInfo) {
     // We will need a local coord attrib if there is one currently set on the optState and we are
     // actually generating some effect code
-    fRequiresLocalCoordAttrib = this->hasLocalCoordAttribute() &&
+    descInfo->fRequiresLocalCoordAttrib = descInfo->hasLocalCoordAttribute() &&
         ds.numTotalStages() - firstColorStageIdx - firstCoverageStageIdx > 0;
 
-    fReadsDst = false;
-    fReadsFragPosition = false;
+    descInfo->fReadsDst = false;
+    descInfo->fReadsFragPosition = false;
 
     for (int s = firstColorStageIdx; s < ds.numColorStages(); ++s) {
         const GrFragmentStage& stage = ds.getColorStage(s);
-        get_stage_stats(stage, &fReadsDst, &fReadsFragPosition);
+        get_stage_stats(stage, &descInfo->fReadsDst, &descInfo->fReadsFragPosition);
     }
     for (int s = firstCoverageStageIdx; s < ds.numCoverageStages(); ++s) {
         const GrFragmentStage& stage = ds.getCoverageStage(s);
-        get_stage_stats(stage, &fReadsDst, &fReadsFragPosition);
+        get_stage_stats(stage, &descInfo->fReadsDst, &descInfo->fReadsFragPosition);
     }
     if (ds.hasGeometryProcessor()) {
         const GrGeometryProcessor& gp = *ds.getGeometryProcessor();
-        fReadsFragPosition = fReadsFragPosition || gp.willReadFragmentPosition();
+        descInfo->fReadsFragPosition = descInfo->fReadsFragPosition || gp.willReadFragmentPosition();
     }
 }
 
@@ -324,14 +342,15 @@ bool GrOptDrawState::operator== (const GrOptDrawState& that) const {
 }
 
 bool GrOptDrawState::isEqual(const GrOptDrawState& that) const {
-    bool usingVertexColors = this->hasColorVertexAttribute();
+    if (this->fDesc != that.fDesc) {
+        return false;
+    }
+    bool usingVertexColors = that.fDesc.header().fColorAttributeIndex != -1;
     if (!usingVertexColors && this->fColor != that.fColor) {
         return false;
     }
 
     if (this->getRenderTarget() != that.getRenderTarget() ||
-        this->fFragmentStages.count() != that.fFragmentStages.count() ||
-        this->fNumColorStages != that.fNumColorStages ||
         !this->fViewMatrix.cheapEqualTo(that.fViewMatrix) ||
         this->fSrcBlend != that.fSrcBlend ||
         this->fDstBlend != that.fDstBlend ||
@@ -341,23 +360,15 @@ bool GrOptDrawState::isEqual(const GrOptDrawState& that) const {
         this->fVAStride != that.fVAStride ||
         memcmp(this->fVAPtr, that.fVAPtr, this->fVACount * sizeof(GrVertexAttrib)) ||
         this->fStencilSettings != that.fStencilSettings ||
-        this->fDrawFace != that.fDrawFace ||
-        this->fInputColorIsUsed != that.fInputColorIsUsed ||
-        this->fInputCoverageIsUsed != that.fInputCoverageIsUsed ||
-        this->fReadsDst != that.fReadsDst ||
-        this->fReadsFragPosition != that.fReadsFragPosition ||
-        this->fRequiresLocalCoordAttrib != that.fRequiresLocalCoordAttrib ||
-        this->fPrimaryOutputType != that.fPrimaryOutputType ||
-        this->fSecondaryOutputType != that.fSecondaryOutputType) {
+        this->fDrawFace != that.fDrawFace) {
         return false;
     }
 
-    bool usingVertexCoverage = this->hasCoverageVertexAttribute();
+    bool usingVertexCoverage = this->fDesc.header().fCoverageAttributeIndex != -1;
     if (!usingVertexCoverage && this->fCoverage != that.fCoverage) {
         return false;
     }
 
-    bool explicitLocalCoords = this->hasLocalCoordAttribute();
     if (this->hasGeometryProcessor()) {
         if (!that.hasGeometryProcessor()) {
             return false;
@@ -368,17 +379,13 @@ bool GrOptDrawState::isEqual(const GrOptDrawState& that) const {
         return false;
     }
 
+    bool explicitLocalCoords = this->fDesc.header().fLocalCoordAttributeIndex != -1;
     for (int i = 0; i < this->numFragmentStages(); i++) {
         if (!GrFragmentStage::AreCompatible(this->getFragmentStage(i), that.getFragmentStage(i),
                                             explicitLocalCoords)) {
             return false;
         }
     }
-
-    SkASSERT(0 == memcmp(this->fFixedFunctionVertexAttribIndices,
-                         that.fFixedFunctionVertexAttribIndices,
-                         sizeof(this->fFixedFunctionVertexAttribIndices)));
-
     return true;
 }
 
index f47913a41ae049b2b214ac166a1291f4c09bf3a2..f495b8983a4e3c929ba32565c35809a42ae98399 100644 (file)
 #include "GrColor.h"
 #include "GrGpu.h"
 #include "GrProcessorStage.h"
+#include "GrProgramDesc.h"
 #include "GrStencil.h"
 #include "GrTypesPriv.h"
 #include "SkMatrix.h"
 #include "SkRefCnt.h"
 
+class GrDeviceCoordTexture;
 class GrDrawState;
 
 /**
@@ -30,8 +32,8 @@ public:
      * GrOptDrawState. In all cases the GrOptDrawState is reffed and ownership is given to the
      * caller.
      */
-    static GrOptDrawState* Create(const GrDrawState& drawState, const GrDrawTargetCaps& caps,
-                                  GrGpu::DrawType drawType);
+    static GrOptDrawState* Create(const GrDrawState& drawState, GrGpu*,
+                                  const GrDeviceCoordTexture* dstCopy, GrGpu::DrawType drawType);
 
     bool operator== (const GrOptDrawState& that) const;
 
@@ -48,35 +50,6 @@ public:
 
     size_t getVertexStride() const { return fVAStride; }
 
-    /**
-     * Getters for index into getVertexAttribs() for particular bindings. -1 is returned if the
-     * binding does not appear in the current attribs. These bindings should appear only once in
-     * the attrib array.
-     */
-
-    int positionAttributeIndex() const {
-        return fFixedFunctionVertexAttribIndices[kPosition_GrVertexAttribBinding];
-    }
-    int localCoordAttributeIndex() const {
-        return fFixedFunctionVertexAttribIndices[kLocalCoord_GrVertexAttribBinding];
-    }
-    int colorVertexAttributeIndex() const {
-        return fFixedFunctionVertexAttribIndices[kColor_GrVertexAttribBinding];
-    }
-    int coverageVertexAttributeIndex() const {
-        return fFixedFunctionVertexAttribIndices[kCoverage_GrVertexAttribBinding];
-    }
-
-    bool hasLocalCoordAttribute() const {
-        return -1 != fFixedFunctionVertexAttribIndices[kLocalCoord_GrVertexAttribBinding];
-    }
-    bool hasColorVertexAttribute() const {
-        return -1 != fFixedFunctionVertexAttribIndices[kColor_GrVertexAttribBinding];
-    }
-    bool hasCoverageVertexAttribute() const {
-        return -1 != fFixedFunctionVertexAttribIndices[kCoverage_GrVertexAttribBinding];
-    }
-
     /// @}
 
     ///////////////////////////////////////////////////////////////////////////
@@ -299,48 +272,10 @@ public:
         kB_CombinedState,
     };
 
-    bool inputColorIsUsed() const { return fInputColorIsUsed; }
-    bool inputCoverageIsUsed() const { return fInputCoverageIsUsed; }
-
-    bool readsDst() const { return fReadsDst; }
-    bool readsFragPosition() const { return fReadsFragPosition; }
-    bool requiresLocalCoordAttrib() const { return fRequiresLocalCoordAttrib; }
-
-    ///////////////////////////////////////////////////////////////////////////
-    /// @name Stage Output Types
-    ////
-
-    enum PrimaryOutputType {
-        // Modulate color and coverage, write result as the color output.
-        kModulate_PrimaryOutputType,
-        // Combines the coverage, dst, and color as coverage * color + (1 - coverage) * dst. This
-        // can only be set if fDstReadKey is non-zero.
-        kCombineWithDst_PrimaryOutputType,
-
-        kPrimaryOutputTypeCnt,
-    };
-
-    enum SecondaryOutputType {
-        // There is no secondary output
-        kNone_SecondaryOutputType,
-        // Writes coverage as the secondary output. Only set if dual source blending is supported
-        // and primary output is kModulate.
-        kCoverage_SecondaryOutputType,
-        // Writes coverage * (1 - colorA) as the secondary output. Only set if dual source blending
-        // is supported and primary output is kModulate.
-        kCoverageISA_SecondaryOutputType,
-        // Writes coverage * (1 - colorRGBA) as the secondary output. Only set if dual source
-        // blending is supported and primary output is kModulate.
-        kCoverageISC_SecondaryOutputType,
-
-        kSecondaryOutputTypeCnt,
-    };
-
-    PrimaryOutputType getPrimaryOutputType() const { return fPrimaryOutputType; }
-    SecondaryOutputType getSecondaryOutputType() const { return fSecondaryOutputType; }
-
     /// @}
 
+    const GrProgramDesc& programDesc() const { return fDesc; }
+
 private:
     /**
      * Optimizations for blending / coverage to that can be applied based on the current state.
@@ -376,7 +311,7 @@ private:
      */
     GrOptDrawState(const GrDrawState& drawState, BlendOptFlags blendOptFlags,
                    GrBlendCoeff optSrcCoeff, GrBlendCoeff optDstCoeff,
-                   const GrDrawTargetCaps& caps);
+                   GrGpu*, const GrDeviceCoordTexture* dstCopy, GrGpu::DrawType);
 
     /**
      * Loops through all the color stage effects to check if the stage will ignore color input or
@@ -384,35 +319,38 @@ private:
      * stages. In the constant color case, we can ignore all previous stages and
      * the current one and set the state color to the constant color.
      */
-    void computeEffectiveColorStages(const GrDrawState& ds, int* firstColorStageIdx,
-                                     uint8_t* fixFunctionVAToRemove);
+    void computeEffectiveColorStages(const GrDrawState& ds, GrProgramDesc::DescInfo*,
+                                     int* firstColorStageIdx, uint8_t* fixFunctionVAToRemove);
 
     /**
      * Loops through all the coverage stage effects to check if the stage will ignore color input.
      * If a coverage stage will ignore input, then we can ignore all coverage stages before it. We
      * loop to determine the first effective coverage stage.
      */
-    void computeEffectiveCoverageStages(const GrDrawState& ds, int* firstCoverageStageIdx);
+    void computeEffectiveCoverageStages(const GrDrawState& ds, GrProgramDesc::DescInfo* descInfo,
+                                        int* firstCoverageStageIdx);
 
     /**
      * This function takes in a flag and removes the corresponding fixed function vertex attributes.
      * The flags are in the same order as GrVertexAttribBinding array. If bit i of removeVAFlags is
      * set, then vertex attributes with binding (GrVertexAttribute)i will be removed.
      */
-    void removeFixedFunctionVertexAttribs(uint8_t removeVAFlags);
+    void removeFixedFunctionVertexAttribs(uint8_t removeVAFlags, GrProgramDesc::DescInfo*);
 
     /**
      * Alter the OptDrawState (adjusting stages, vertex attribs, flags, etc.) based on the
      * BlendOptFlags.
      */
-    void adjustFromBlendOpts(const GrDrawState& ds, int* firstColorStageIdx,
-                             int* firstCoverageStageIdx, uint8_t* fixedFunctionVAToRemove);
+    void adjustFromBlendOpts(const GrDrawState& ds, GrProgramDesc::DescInfo*,
+                             int* firstColorStageIdx, int* firstCoverageStageIdx,
+                             uint8_t* fixedFunctionVAToRemove);
 
     /**
      * Loop over the effect stages to determine various info like what data they will read and what
      * shaders they require.
      */
-    void getStageStats(const GrDrawState& ds, int firstColorStageIdx, int firstCoverageStageIdx);
+    void getStageStats(const GrDrawState& ds, int firstColorStageIdx, int firstCoverageStageIdx,
+                       GrProgramDesc::DescInfo*);
 
     /**
      * Calculates the primary and secondary output types of the shader. For certain output types
@@ -420,7 +358,8 @@ private:
      * blend coeffs will represent those used by backend API.
      */
     void setOutputStateInfo(const GrDrawState& ds, const GrDrawTargetCaps&,
-                            int firstCoverageStageIdx, bool* separateCoverageFromColor);
+                            int firstCoverageStageIdx, GrProgramDesc::DescInfo*,
+                            bool* separateCoverageFromColor);
 
     bool isEqual(const GrOptDrawState& that) const;
 
@@ -448,27 +387,11 @@ private:
     // This function is equivalent to the offset into fFragmentStages where coverage stages begin.
     int                                 fNumColorStages;
 
-    // This is simply a different representation of info in fVertexAttribs and thus does
-    // not need to be compared in op==.
-    int fFixedFunctionVertexAttribIndices[kGrFixedFunctionVertexAttribBindingCnt];
-
-    // These flags are needed to protect the code from creating an unused uniform color/coverage
-    // which will cause shader compiler errors.
-    bool            fInputColorIsUsed;
-    bool            fInputCoverageIsUsed;
-
-    // These flags give aggregated info on the effect stages that are used when building programs.
-    bool            fReadsDst;
-    bool            fReadsFragPosition;
-    bool            fRequiresLocalCoordAttrib;
-
     SkAutoSTArray<4, GrVertexAttrib> fOptVA;
 
     BlendOptFlags   fBlendOptFlags;
 
-    // Fragment shader color outputs
-    PrimaryOutputType  fPrimaryOutputType : 8;
-    SecondaryOutputType  fSecondaryOutputType : 8;
+    GrProgramDesc fDesc;
 
     typedef SkRefCnt INHERITED;
 };
diff --git a/src/gpu/GrProgramDesc.h b/src/gpu/GrProgramDesc.h
new file mode 100644 (file)
index 0000000..cc8a38a
--- /dev/null
@@ -0,0 +1,269 @@
+/*
+ * Copyright 2014 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef GrProgramDesc_DEFINED
+#define GrProgramDesc_DEFINED
+
+#include "GrBackendProcessorFactory.h"
+#include "GrColor.h"
+#include "GrTypesPriv.h"
+#include "SkChecksum.h"
+
+class GrGpuGL;
+
+/** This class describes a program to generate. It also serves as a program cache key. Very little
+    of this is GL-specific. The GL-specific parts could be factored out into a subclass. */
+class GrProgramDesc {
+public:
+    // Creates an uninitialized key that must be populated by GrGpu::buildProgramDesc()
+    GrProgramDesc() {}
+
+    // Returns this as a uint32_t array to be used as a key in the program cache.
+    const uint32_t* asKey() const {
+        return reinterpret_cast<const uint32_t*>(fKey.begin());
+    }
+
+    // Gets the number of bytes in asKey(). It will be a 4-byte aligned value. When comparing two
+    // keys the size of either key can be used with memcmp() since the lengths themselves begin the
+    // keys and thus the memcmp will exit early if the keys are of different lengths.
+    uint32_t keyLength() const { return *this->atOffset<uint32_t, kLengthOffset>(); }
+
+    // Gets the a checksum of the key. Can be used as a hash value for a fast lookup in a cache.
+    uint32_t getChecksum() const { return *this->atOffset<uint32_t, kChecksumOffset>(); }
+
+    GrProgramDesc& operator= (const GrProgramDesc& other) {
+        size_t keyLength = other.keyLength();
+        fKey.reset(keyLength);
+        memcpy(fKey.begin(), other.fKey.begin(), keyLength);
+        return *this;
+    }
+
+    bool operator== (const GrProgramDesc& other) const {
+        // The length is masked as a hint to the compiler that the address will be 4 byte aligned.
+        return 0 == memcmp(this->asKey(), other.asKey(), this->keyLength() & ~0x3);
+    }
+
+    bool operator!= (const GrProgramDesc& other) const {
+        return !(*this == other);
+    }
+
+    static bool Less(const GrProgramDesc& a, const GrProgramDesc& b) {
+        return memcmp(a.asKey(), b.asKey(), a.keyLength() & ~0x3) < 0;
+    }
+
+
+    ///////////////////////////////////////////////////////////////////////////
+    /// @name Stage Output Types
+    ////
+
+    enum PrimaryOutputType {
+        // Modulate color and coverage, write result as the color output.
+        kModulate_PrimaryOutputType,
+        // Combines the coverage, dst, and color as coverage * color + (1 - coverage) * dst. This
+        // can only be set if fDstReadKey is non-zero.
+        kCombineWithDst_PrimaryOutputType,
+
+        kPrimaryOutputTypeCnt,
+    };
+
+    enum SecondaryOutputType {
+        // There is no secondary output
+        kNone_SecondaryOutputType,
+        // Writes coverage as the secondary output. Only set if dual source blending is supported
+        // and primary output is kModulate.
+        kCoverage_SecondaryOutputType,
+        // Writes coverage * (1 - colorA) as the secondary output. Only set if dual source blending
+        // is supported and primary output is kModulate.
+        kCoverageISA_SecondaryOutputType,
+        // Writes coverage * (1 - colorRGBA) as the secondary output. Only set if dual source
+        // blending is supported and primary output is kModulate.
+        kCoverageISC_SecondaryOutputType,
+
+        kSecondaryOutputTypeCnt,
+    };
+
+    // Specifies where the initial color comes from before the stages are applied.
+    enum ColorInput {
+        kAllOnes_ColorInput,
+        kAttribute_ColorInput,
+        kUniform_ColorInput,
+
+        kColorInputCnt
+    };
+
+    struct KeyHeader {
+        uint8_t                     fDstReadKey;   // set by GrGLShaderBuilder if there
+                                                   // are effects that must read the dst.
+                                                   // Otherwise, 0.
+        uint8_t                     fFragPosKey;   // set by GrGLShaderBuilder if there are
+                                                   // effects that read the fragment position.
+                                                   // Otherwise, 0.
+
+        SkBool8                     fEmitsPointSize;
+
+        ColorInput                  fColorInput : 8;
+        ColorInput                  fCoverageInput : 8;
+
+        PrimaryOutputType           fPrimaryOutputType : 8;
+        SecondaryOutputType         fSecondaryOutputType : 8;
+
+        int8_t                      fPositionAttributeIndex;
+        int8_t                      fLocalCoordAttributeIndex;
+        int8_t                      fColorAttributeIndex;
+        int8_t                      fCoverageAttributeIndex;
+
+        SkBool8                     fHasGeometryProcessor;
+        int8_t                      fColorEffectCnt;
+        int8_t                      fCoverageEffectCnt;
+    };
+
+
+    bool hasGeometryProcessor() const {
+        return SkToBool(this->header().fHasGeometryProcessor);
+    }
+
+    int numColorEffects() const {
+        return this->header().fColorEffectCnt;
+    }
+
+    int numCoverageEffects() const {
+        return this->header().fCoverageEffectCnt;
+    }
+
+    int numTotalEffects() const { return this->numColorEffects() + this->numCoverageEffects(); }
+
+    // This should really only be used internally, base classes should return their own headers
+    const KeyHeader& header() const { return *this->atOffset<KeyHeader, kHeaderOffset>(); }
+
+    /** Used to provide effects' keys to their emitCode() function. */
+    class ProcKeyProvider {
+    public:
+        enum ProcessorType {
+            kGeometry_ProcessorType,
+            kFragment_ProcessorType,
+        };
+
+        ProcKeyProvider(const GrProgramDesc* desc, ProcessorType type, int effectOffset)
+            : fDesc(desc), fBaseIndex(0), fEffectOffset(effectOffset) {
+            switch (type) {
+                case kGeometry_ProcessorType:
+                    // there can be only one
+                    fBaseIndex = 0;
+                    break;
+                case kFragment_ProcessorType:
+                    fBaseIndex = desc->hasGeometryProcessor() ? 1 : 0;
+                    break;
+            }
+        }
+
+        GrProcessorKey get(int index) const {
+            const uint16_t* offsetsAndLengths = reinterpret_cast<const uint16_t*>(
+                fDesc->fKey.begin() + fEffectOffset);
+            // We store two uint16_ts per effect, one for the offset to the effect's key and one for
+            // its length. Here we just need the offset.
+            uint16_t offset = offsetsAndLengths[2 * (fBaseIndex + index) + 0];
+            uint16_t length = offsetsAndLengths[2 * (fBaseIndex + index) + 1];
+            // Currently effects must add to the key in units of uint32_t.
+            SkASSERT(0 == (length % sizeof(uint32_t)));
+            return GrProcessorKey(reinterpret_cast<const uint32_t*>(fDesc->fKey.begin() + offset),
+                               length / sizeof(uint32_t));
+        }
+    private:
+        const GrProgramDesc*  fDesc;
+        int                   fBaseIndex;
+        int                   fEffectOffset;
+    };
+
+    // A struct to communicate descriptor information to the program descriptor builder
+    struct DescInfo {
+        int positionAttributeIndex() const {
+            return fFixedFunctionVertexAttribIndices[kPosition_GrVertexAttribBinding];
+        }
+        int localCoordAttributeIndex() const {
+            return fFixedFunctionVertexAttribIndices[kLocalCoord_GrVertexAttribBinding];
+        }
+        int colorVertexAttributeIndex() const {
+            return fFixedFunctionVertexAttribIndices[kColor_GrVertexAttribBinding];
+        }
+        int coverageVertexAttributeIndex() const {
+            return fFixedFunctionVertexAttribIndices[kCoverage_GrVertexAttribBinding];
+        }
+        bool hasLocalCoordAttribute() const {
+            return -1 != fFixedFunctionVertexAttribIndices[kLocalCoord_GrVertexAttribBinding];
+        }
+        bool hasColorVertexAttribute() const {
+            return -1 != fFixedFunctionVertexAttribIndices[kColor_GrVertexAttribBinding];
+        }
+        bool hasCoverageVertexAttribute() const {
+            return -1 != fFixedFunctionVertexAttribIndices[kCoverage_GrVertexAttribBinding];
+        }
+
+        int fFixedFunctionVertexAttribIndices[kGrFixedFunctionVertexAttribBindingCnt];
+
+        // These flags are needed to protect the code from creating an unused uniform color/coverage
+        // which will cause shader compiler errors.
+        bool            fInputColorIsUsed;
+        bool            fInputCoverageIsUsed;
+
+        // These flags give aggregated info on the processor stages that are used when building
+        // programs.
+        bool            fReadsDst;
+        bool            fReadsFragPosition;
+        bool            fRequiresLocalCoordAttrib;
+
+        // Fragment shader color outputs
+        GrProgramDesc::PrimaryOutputType  fPrimaryOutputType : 8;
+        GrProgramDesc::SecondaryOutputType  fSecondaryOutputType : 8;
+    };
+
+private:
+    template<typename T, size_t OFFSET> T* atOffset() {
+        return reinterpret_cast<T*>(reinterpret_cast<intptr_t>(fKey.begin()) + OFFSET);
+    }
+
+    template<typename T, size_t OFFSET> const T* atOffset() const {
+        return reinterpret_cast<const T*>(reinterpret_cast<intptr_t>(fKey.begin()) + OFFSET);
+    }
+
+    void finalize() {
+        int keyLength = fKey.count();
+        SkASSERT(0 == (keyLength % 4));
+        *(this->atOffset<uint32_t, GrProgramDesc::kLengthOffset>()) = SkToU32(keyLength);
+
+        uint32_t* checksum = this->atOffset<uint32_t, GrProgramDesc::kChecksumOffset>();
+        *checksum = 0;
+        *checksum = SkChecksum::Compute(reinterpret_cast<uint32_t*>(fKey.begin()), keyLength);
+    }
+
+    // The key, stored in fKey, is composed of four parts:
+    // 1. uint32_t for total key length.
+    // 2. uint32_t for a checksum.
+    // 3. Header struct defined above.  Also room for extensions to the header
+    // 4. A Backend specific payload.  Room is preallocated for this
+    enum KeyOffsets {
+        // Part 1.
+        kLengthOffset = 0,
+        // Part 2.
+        kChecksumOffset = kLengthOffset + sizeof(uint32_t),
+        // Part 3.
+        kHeaderOffset = kChecksumOffset + sizeof(uint32_t),
+        kHeaderSize = SkAlign4(2 * sizeof(KeyHeader)),
+    };
+
+    enum {
+        kMaxPreallocProcessors = 8,
+        kIntsPerProcessor      = 4,    // This is an overestimate of the average effect key size.
+        kPreAllocSize = kHeaderOffset + kHeaderSize +
+                        kMaxPreallocProcessors * sizeof(uint32_t) * kIntsPerProcessor,
+    };
+
+    SkSTArray<kPreAllocSize, uint8_t, true> fKey;
+
+    friend class GrGLProgramDescBuilder;
+};
+
+#endif
index bfa5f3cbc155e7f18581e361933653d40bdaf357..f152173e990d650c7d055fe71730a5dce5b5c034 100644 (file)
@@ -56,7 +56,7 @@ static SkMatrix get_transform_matrix(const GrFragmentStage& processorStage,
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
 GrGLProgram::GrGLProgram(GrGpuGL* gpu,
-                         const GrGLProgramDesc& desc,
+                         const GrProgramDesc& desc,
                          const BuiltinUniformHandles& builtinUniforms,
                          GrGLuint programID,
                          const UniformInfoArray& uniforms,
@@ -201,12 +201,12 @@ void GrGLProgram::didSetData(GrGpu::DrawType drawType) {
 }
 
 void GrGLProgram::setColor(const GrOptDrawState& optState, GrColor color) {
-    const GrGLProgramDesc::KeyHeader& header = fDesc.getHeader();
+    const GrProgramDesc::KeyHeader& header = fDesc.header();
     switch (header.fColorInput) {
-        case GrGLProgramDesc::kAttribute_ColorInput:
+        case GrProgramDesc::kAttribute_ColorInput:
             // Attribute case is handled in GrGpuGL::setupGeometry
             break;
-        case GrGLProgramDesc::kUniform_ColorInput:
+        case GrProgramDesc::kUniform_ColorInput:
             if (fColor != color && fBuiltinUniformHandles.fColorUni.isValid()) {
                 // OpenGL ES doesn't support unsigned byte varieties of glUniform
                 GrGLfloat c[4];
@@ -215,7 +215,7 @@ void GrGLProgram::setColor(const GrOptDrawState& optState, GrColor color) {
                 fColor = color;
             }
             break;
-        case GrGLProgramDesc::kAllOnes_ColorInput:
+        case GrProgramDesc::kAllOnes_ColorInput:
             // Handled by shader creation
             break;
         default:
@@ -224,12 +224,12 @@ void GrGLProgram::setColor(const GrOptDrawState& optState, GrColor color) {
 }
 
 void GrGLProgram::setCoverage(const GrOptDrawState& optState, GrColor coverage) {
-    const GrGLProgramDesc::KeyHeader& header = fDesc.getHeader();
+    const GrProgramDesc::KeyHeader& header = fDesc.header();
     switch (header.fCoverageInput) {
-        case GrGLProgramDesc::kAttribute_ColorInput:
+        case GrProgramDesc::kAttribute_ColorInput:
             // Attribute case is handled in GrGpuGL::setupGeometry
             break;
-        case GrGLProgramDesc::kUniform_ColorInput:
+        case GrProgramDesc::kUniform_ColorInput:
             if (fCoverage != coverage) {
                 // OpenGL ES doesn't support unsigned byte varieties of glUniform
                 GrGLfloat c[4];
@@ -238,7 +238,7 @@ void GrGLProgram::setCoverage(const GrOptDrawState& optState, GrColor coverage)
                 fCoverage = coverage;
             }
             break;
-        case GrGLProgramDesc::kAllOnes_ColorInput:
+        case GrProgramDesc::kAllOnes_ColorInput:
             // Handled by shader creation
             break;
         default:
@@ -286,7 +286,7 @@ void GrGLProgram::onSetMatrixAndRenderTargetHeight(GrGpu::DrawType drawType,
 /////////////////////////////////////////////////////////////////////////////////////////
 
 GrGLNvprProgramBase::GrGLNvprProgramBase(GrGpuGL* gpu,
-                                         const GrGLProgramDesc& desc,
+                                         const GrProgramDesc& desc,
                                          const BuiltinUniformHandles& builtinUniforms,
                                          GrGLuint programID,
                                          const UniformInfoArray& uniforms,
@@ -306,7 +306,7 @@ void GrGLNvprProgramBase::onSetMatrixAndRenderTargetHeight(GrGpu::DrawType drawT
 /////////////////////////////////////////////////////////////////////////////////////////
 
 GrGLNvprProgram::GrGLNvprProgram(GrGpuGL* gpu,
-                                 const GrGLProgramDesc& desc,
+                                 const GrProgramDesc& desc,
                                  const BuiltinUniformHandles& builtinUniforms,
                                  GrGLuint programID,
                                  const UniformInfoArray& uniforms,
@@ -355,7 +355,7 @@ void GrGLNvprProgram::setTransformData(const GrFragmentStage& proc, GrGLInstalle
 //////////////////////////////////////////////////////////////////////////////////////
 
 GrGLLegacyNvprProgram::GrGLLegacyNvprProgram(GrGpuGL* gpu,
-                                             const GrGLProgramDesc& desc,
+                                             const GrProgramDesc& desc,
                                              const BuiltinUniformHandles& builtinUniforms,
                                              GrGLuint programID,
                                              const UniformInfoArray& uniforms,
index ca75e206f121bcd9c3badb90489de0cc431ca516..d7a7cf8fc77635a4dc3e1daf7d07a70f4db51369 100644 (file)
@@ -47,7 +47,7 @@ public:
      */
     void abandon();
 
-    const GrGLProgramDesc& getDesc() { return fDesc; }
+    const GrProgramDesc& getDesc() { return fDesc; }
 
     /**
      * Gets the GL program ID for this program.
@@ -138,7 +138,7 @@ protected:
     typedef GrGLProgramDataManager::UniformInfoArray UniformInfoArray;
 
     GrGLProgram(GrGpuGL*,
-                const GrGLProgramDesc&,
+                const GrProgramDesc&,
                 const BuiltinUniformHandles&,
                 GrGLuint programID,
                 const UniformInfoArray&,
@@ -184,7 +184,7 @@ protected:
     SkAutoTDelete<GrGLInstalledGeoProc> fGeometryProcessor;
     SkAutoTUnref<GrGLInstalledFragProcs> fFragmentProcessors;
 
-    GrGLProgramDesc fDesc;
+    GrProgramDesc fDesc;
     GrGpuGL* fGpu;
     GrGLProgramDataManager fProgramDataManager;
 
@@ -203,7 +203,7 @@ protected:
 class GrGLNvprProgramBase : public GrGLProgram {
 protected:
     GrGLNvprProgramBase(GrGpuGL*,
-                        const GrGLProgramDesc&,
+                        const GrProgramDesc&,
                         const BuiltinUniformHandles&,
                         GrGLuint programID,
                         const UniformInfoArray&,
@@ -221,7 +221,7 @@ private:
     typedef GrGLNvprProgramBuilder::SeparableVaryingInfo SeparableVaryingInfo;
     typedef GrGLNvprProgramBuilder::SeparableVaryingInfoArray SeparableVaryingInfoArray;
     GrGLNvprProgram(GrGpuGL*,
-                    const GrGLProgramDesc&,
+                    const GrProgramDesc&,
                     const BuiltinUniformHandles&,
                     GrGLuint programID,
                     const UniformInfoArray&,
@@ -249,7 +249,7 @@ public:
 
 private:
     GrGLLegacyNvprProgram(GrGpuGL* gpu,
-                          const GrGLProgramDesc& desc,
+                          const GrProgramDesc& desc,
                           const BuiltinUniformHandles&,
                           GrGLuint programID,
                           const UniformInfoArray&,
index 4a274c6bb1e8806b98043328031b18d12df8ac16..4a182b36e6f1fa45fac607618dc334e4a01f41bc 100644 (file)
@@ -4,15 +4,15 @@
  * Use of this source code is governed by a BSD-style license that can be
  * found in the LICENSE file.
  */
-
-#include "gl/builders/GrGLFragmentShaderBuilder.h"
 #include "GrGLProgramDesc.h"
+
+#include "GrGLProcessor.h"
 #include "GrBackendProcessorFactory.h"
 #include "GrProcessor.h"
 #include "GrGpuGL.h"
 #include "GrOptDrawState.h"
-
 #include "SkChecksum.h"
+#include "gl/builders/GrGLFragmentShaderBuilder.h"
 
 /**
  * The key for an individual coord transform is made up of a matrix type and a bit that
@@ -176,10 +176,10 @@ struct FragmentProcessorKeyBuilder {
 
 template <class ProcessorKeyBuilder>
 bool
-GrGLProgramDesc::BuildStagedProcessorKey(const typename ProcessorKeyBuilder::StagedProcessor& stage,
+GrGLProgramDescBuilder::BuildStagedProcessorKey(const typename ProcessorKeyBuilder::StagedProcessor& stage,
                                          const GrGLCaps& caps,
                                          bool requiresLocalCoordAttrib,
-                                         GrGLProgramDesc* desc,
+                                         GrProgramDesc* desc,
                                          int* offsetAndSizeIndex) {
     GrProcessorKeyBuilder b(&desc->fKey);
     uint16_t processorKeySize;
@@ -192,7 +192,7 @@ GrGLProgramDesc::BuildStagedProcessorKey(const typename ProcessorKeyBuilder::Sta
     }
 
     uint16_t* offsetAndSize =
-            reinterpret_cast<uint16_t*>(desc->fKey.begin() + kEffectKeyOffsetsAndLengthOffset +
+            reinterpret_cast<uint16_t*>(desc->fKey.begin() + kProcessorKeyOffsetsAndLengthOffset +
                                         *offsetAndSizeIndex * 2 * sizeof(uint16_t));
     offsetAndSize[0] = SkToU16(processorOffset);
     offsetAndSize[1] = processorKeySize;
@@ -200,27 +200,28 @@ GrGLProgramDesc::BuildStagedProcessorKey(const typename ProcessorKeyBuilder::Sta
     return true;
 }
 
-bool GrGLProgramDesc::Build(const GrOptDrawState& optState,
+bool GrGLProgramDescBuilder::Build(const GrOptDrawState& optState,
+                            const GrProgramDesc::DescInfo& descInfo,
                             GrGpu::DrawType drawType,
                             GrGpuGL* gpu,
                             const GrDeviceCoordTexture* dstCopy,
-                            GrGLProgramDesc* desc) {
-    bool inputColorIsUsed = optState.inputColorIsUsed();
-    bool inputCoverageIsUsed = optState.inputCoverageIsUsed();
+                            GrProgramDesc* desc) {
+    bool inputColorIsUsed = descInfo.fInputColorIsUsed;
+    bool inputCoverageIsUsed = descInfo.fInputCoverageIsUsed;
 
     // The descriptor is used as a cache key. Thus when a field of the
     // descriptor will not affect program generation (because of the attribute
     // bindings in use or other descriptor field settings) it should be set
     // to a canonical value to avoid duplicate programs with different keys.
 
-    bool requiresLocalCoordAttrib = optState.requiresLocalCoordAttrib();
+    bool requiresLocalCoordAttrib = descInfo.fRequiresLocalCoordAttrib;
 
     int numStages = optState.numTotalStages();
 
-    GR_STATIC_ASSERT(0 == kEffectKeyOffsetsAndLengthOffset % sizeof(uint32_t));
+    GR_STATIC_ASSERT(0 == kProcessorKeyOffsetsAndLengthOffset % sizeof(uint32_t));
     // Make room for everything up to and including the array of offsets to effect keys.
     desc->fKey.reset();
-    desc->fKey.push_back_n(kEffectKeyOffsetsAndLengthOffset + 2 * sizeof(uint16_t) * numStages);
+    desc->fKey.push_back_n(kProcessorKeyOffsetsAndLengthOffset + 2 * sizeof(uint16_t) * numStages);
 
     int offsetAndSizeIndex = 0;
 
@@ -248,7 +249,7 @@ bool GrGLProgramDesc::Build(const GrOptDrawState& optState,
     // --------DO NOT MOVE HEADER ABOVE THIS LINE--------------------------------------------------
     // Because header is a pointer into the dynamic array, we can't push any new data into the key
     // below here.
-    KeyHeader* header = desc->header();
+    GLKeyHeader* header = desc->atOffset<GLKeyHeader, kHeaderOffset>();
 
     // make sure any padding in the header is zeroed.
     memset(header, 0, kHeaderSize);
@@ -266,33 +267,33 @@ bool GrGLProgramDesc::Build(const GrOptDrawState& optState,
     }
 
     bool hasUniformColor = inputColorIsUsed &&
-                           (isPathRendering || !optState.hasColorVertexAttribute());
+                           (isPathRendering || !descInfo.hasColorVertexAttribute());
 
     bool hasUniformCoverage = inputCoverageIsUsed &&
-                              (isPathRendering || !optState.hasCoverageVertexAttribute());
+                              (isPathRendering || !descInfo.hasCoverageVertexAttribute());
 
     if (!inputColorIsUsed) {
-        header->fColorInput = kAllOnes_ColorInput;
+        header->fColorInput = GrProgramDesc::kAllOnes_ColorInput;
     } else if (hasUniformColor) {
-        header->fColorInput = kUniform_ColorInput;
+        header->fColorInput = GrProgramDesc::kUniform_ColorInput;
     } else {
-        header->fColorInput = kAttribute_ColorInput;
+        header->fColorInput = GrProgramDesc::kAttribute_ColorInput;
         SkASSERT(!header->fUseNvpr);
     }
 
-    bool covIsSolidWhite = !optState.hasCoverageVertexAttribute() &&
+    bool covIsSolidWhite = !descInfo.hasCoverageVertexAttribute() &&
                            0xffffffff == optState.getCoverageColor();
 
     if (covIsSolidWhite || !inputCoverageIsUsed) {
-        header->fCoverageInput = kAllOnes_ColorInput;
+        header->fCoverageInput = GrProgramDesc::kAllOnes_ColorInput;
     } else if (hasUniformCoverage) {
-        header->fCoverageInput = kUniform_ColorInput;
+        header->fCoverageInput = GrProgramDesc::kUniform_ColorInput;
     } else {
-        header->fCoverageInput = kAttribute_ColorInput;
+        header->fCoverageInput = GrProgramDesc::kAttribute_ColorInput;
         SkASSERT(!header->fUseNvpr);
     }
 
-    if (optState.readsDst()) {
+    if (descInfo.fReadsDst) {
         SkASSERT(dstCopy || gpu->caps()->dstReadInShaderSupport());
         const GrTexture* dstCopyTexture = NULL;
         if (dstCopy) {
@@ -305,7 +306,7 @@ bool GrGLProgramDesc::Build(const GrOptDrawState& optState,
         header->fDstReadKey = 0;
     }
 
-    if (optState.readsFragPosition()) {
+    if (descInfo.fReadsFragPosition) {
         header->fFragPosKey =
                 GrGLFragmentShaderBuilder::KeyForFragmentPosition(optState.getRenderTarget(),
                                                                   gpu->glCaps());
@@ -314,14 +315,14 @@ bool GrGLProgramDesc::Build(const GrOptDrawState& optState,
     }
 
     // Record attribute indices
-    header->fPositionAttributeIndex = optState.positionAttributeIndex();
-    header->fLocalCoordAttributeIndex = optState.localCoordAttributeIndex();
+    header->fPositionAttributeIndex = descInfo.positionAttributeIndex();
+    header->fLocalCoordAttributeIndex = descInfo.localCoordAttributeIndex();
 
     // For constant color and coverage we need an attribute with an index beyond those already set
     int availableAttributeIndex = optState.getVertexAttribCount();
-    if (optState.hasColorVertexAttribute()) {
-        header->fColorAttributeIndex = optState.colorVertexAttributeIndex();
-    } else if (GrGLProgramDesc::kAttribute_ColorInput == header->fColorInput) {
+    if (descInfo.hasColorVertexAttribute()) {
+        header->fColorAttributeIndex = descInfo.colorVertexAttributeIndex();
+    } else if (GrProgramDesc::kAttribute_ColorInput == header->fColorInput) {
         SkASSERT(availableAttributeIndex < GrDrawState::kMaxVertexAttribCnt);
         header->fColorAttributeIndex = availableAttributeIndex;
         availableAttributeIndex++;
@@ -329,37 +330,20 @@ bool GrGLProgramDesc::Build(const GrOptDrawState& optState,
         header->fColorAttributeIndex = -1;
     }
 
-    if (optState.hasCoverageVertexAttribute()) {
-        header->fCoverageAttributeIndex = optState.coverageVertexAttributeIndex();
-    } else if (GrGLProgramDesc::kAttribute_ColorInput == header->fCoverageInput) {
+    if (descInfo.hasCoverageVertexAttribute()) {
+        header->fCoverageAttributeIndex = descInfo.coverageVertexAttributeIndex();
+    } else if (GrProgramDesc::kAttribute_ColorInput == header->fCoverageInput) {
         SkASSERT(availableAttributeIndex < GrDrawState::kMaxVertexAttribCnt);
         header->fCoverageAttributeIndex = availableAttributeIndex;
     } else {
         header->fCoverageAttributeIndex = -1;
     }
 
-    header->fPrimaryOutputType = optState.getPrimaryOutputType();
-    header->fSecondaryOutputType = optState.getSecondaryOutputType();
+    header->fPrimaryOutputType = descInfo.fPrimaryOutputType;
+    header->fSecondaryOutputType = descInfo.fSecondaryOutputType;
 
     header->fColorEffectCnt = optState.numColorStages();
     header->fCoverageEffectCnt = optState.numCoverageStages();
     desc->finalize();
     return true;
 }
-
-void GrGLProgramDesc::finalize() {
-    int keyLength = fKey.count();
-    SkASSERT(0 == (keyLength % 4));
-    *this->atOffset<uint32_t, kLengthOffset>() = SkToU32(keyLength);
-
-    uint32_t* checksum = this->atOffset<uint32_t, kChecksumOffset>();
-    *checksum = 0;
-    *checksum = SkChecksum::Compute(reinterpret_cast<uint32_t*>(fKey.begin()), keyLength);
-}
-
-GrGLProgramDesc& GrGLProgramDesc::operator= (const GrGLProgramDesc& other) {
-    size_t keyLength = other.keyLength();
-    fKey.reset(keyLength);
-    memcpy(fKey.begin(), other.fKey.begin(), keyLength);
-    return *this;
-}
index d97bdfded5c88b5e0dbe47320561b6c1c8c352c5..8bfd506135cb91ce6001c8d52d072a8b4f9b38d0 100644 (file)
 #ifndef GrGLProgramDesc_DEFINED
 #define GrGLProgramDesc_DEFINED
 
-#include "GrGLProcessor.h"
-#include "GrDrawState.h"
+#include "GrColor.h"
+#include "GrProgramDesc.h"
 #include "GrGpu.h"
-#include "GrOptDrawState.h"
+#include "GrTypesPriv.h"
 
 class GrGpuGL;
 
-/** This class describes a program to generate. It also serves as a program cache key. Very little
-    of this is GL-specific. The GL-specific parts could be factored out into a subclass. */
-class GrGLProgramDesc {
+/**
+ * This class can be used to build a GrProgramDesc.  It also provides helpers for accessing
+ * GL specific info in the header.
+ */
+class GrGLProgramDescBuilder {
 public:
-    GrGLProgramDesc() {}
-    GrGLProgramDesc(const GrGLProgramDesc& desc) { *this = desc; }
-
-    // Returns this as a uint32_t array to be used as a key in the program cache.
-    const uint32_t* asKey() const {
-        return reinterpret_cast<const uint32_t*>(fKey.begin());
-    }
-
-    // Gets the number of bytes in asKey(). It will be a 4-byte aligned value. When comparing two
-    // keys the size of either key can be used with memcmp() since the lengths themselves begin the
-    // keys and thus the memcmp will exit early if the keys are of different lengths.
-    uint32_t keyLength() const { return *this->atOffset<uint32_t, kLengthOffset>(); }
-
-    // Gets the a checksum of the key. Can be used as a hash value for a fast lookup in a cache.
-    uint32_t getChecksum() const { return *this->atOffset<uint32_t, kChecksumOffset>(); }
-
-    /**
-     * Builds a program descriptor from a GrOptDrawState. Whether the primitive type is points, and
-     * the caps of the GrGpuGL are also inputs. It also outputs the color and coverage stages
-     * referenced by the generated descriptor. Coverage stages from the drawState may be treated as
-     * color stages in the output.
-     */
-    static bool Build(const GrOptDrawState&,
-                      GrGpu::DrawType,
-                      GrGpuGL*,
-                      const GrDeviceCoordTexture*,
-                      GrGLProgramDesc*);
-
-    bool hasGeometryProcessor() const {
-        return SkToBool(this->getHeader().fHasGeometryProcessor);
-    }
-
-    int numColorEffects() const {
-        return this->getHeader().fColorEffectCnt;
-    }
-
-    int numCoverageEffects() const {
-        return this->getHeader().fCoverageEffectCnt;
-    }
-
-    int numTotalEffects() const { return this->numColorEffects() + this->numCoverageEffects(); }
-
-    GrGLProgramDesc& operator= (const GrGLProgramDesc& other);
-
-    bool operator== (const GrGLProgramDesc& other) const {
-        // The length is masked as a hint to the compiler that the address will be 4 byte aligned.
-        return 0 == memcmp(this->asKey(), other.asKey(), this->keyLength() & ~0x3);
-    }
-
-    bool operator!= (const GrGLProgramDesc& other) const {
-        return !(*this == other);
-    }
-
-    static bool Less(const GrGLProgramDesc& a, const GrGLProgramDesc& b) {
-        return memcmp(a.asKey(), b.asKey(), a.keyLength() & ~0x3) < 0;
-    }
-
-private:
-    // Specifies where the initial color comes from before the stages are applied.
-    enum ColorInput {
-        kAllOnes_ColorInput,
-        kAttribute_ColorInput,
-        kUniform_ColorInput,
-
-        kColorInputCnt
+    struct GLKeyHeader : public GrProgramDesc::KeyHeader {
+        SkBool8 fUseNvpr;
     };
 
-    struct KeyHeader {
-        uint8_t                          fDstReadKey;   // set by GrGLShaderBuilder if there
-                                                        // are effects that must read the dst.
-                                                        // Otherwise, 0.
-        uint8_t                          fFragPosKey;   // set by GrGLShaderBuilder if there are
-                                                        // effects that read the fragment position.
-                                                        // Otherwise, 0.
-
-        SkBool8                     fUseNvpr;
-        SkBool8                     fEmitsPointSize;
-
-        ColorInput                       fColorInput : 8;
-        ColorInput                       fCoverageInput : 8;
-
-        GrOptDrawState::PrimaryOutputType    fPrimaryOutputType : 8;
-        GrOptDrawState::SecondaryOutputType  fSecondaryOutputType : 8;
-
-        int8_t                      fPositionAttributeIndex;
-        int8_t                      fLocalCoordAttributeIndex;
-        int8_t                      fColorAttributeIndex;
-        int8_t                      fCoverageAttributeIndex;
-
-        SkBool8                     fHasGeometryProcessor;
-        int8_t                      fColorEffectCnt;
-        int8_t                      fCoverageEffectCnt;
-    };
-
-    // The key, stored in fKey, is composed of five parts:
+    // The key, stored in fKey, is composed of five parts(first 2 are defined in the key itself):
     // 1. uint32_t for total key length.
     // 2. uint32_t for a checksum.
     // 3. Header struct defined above.
@@ -121,95 +33,49 @@ private:
     //    offset and size.
     // 5. per-effect keys. Each effect's key is a variable length array of uint32_t.
     enum {
-        // Part 1.
-        kLengthOffset = 0,
-        // Part 2.
-        kChecksumOffset = kLengthOffset + sizeof(uint32_t),
         // Part 3.
-        kHeaderOffset = kChecksumOffset + sizeof(uint32_t),
-        kHeaderSize = SkAlign4(sizeof(KeyHeader)),
+        kHeaderOffset = GrProgramDesc::kHeaderOffset,
+        kHeaderSize = SkAlign4(sizeof(GLKeyHeader)),
         // Part 4.
         // This is the offset in the overall key to the array of per-effect offset,length pairs.
-        kEffectKeyOffsetsAndLengthOffset = kHeaderOffset + kHeaderSize,
+        kProcessorKeyOffsetsAndLengthOffset = kHeaderOffset + kHeaderSize,
     };
 
-    template<typename T, size_t OFFSET> T* atOffset() {
-        return reinterpret_cast<T*>(reinterpret_cast<intptr_t>(fKey.begin()) + OFFSET);
-    }
+    /**
+     * Builds a GL specific program descriptor
+     *
+     * @param GrOptDrawState  The optimized drawstate.  The descriptor will represent a program
+     *                        which this optstate can use to draw with.  The optstate contains
+     *                        general draw information, as well as the specific color, geometry,
+     *                        and coverage stages which will be used to generate the GL Program for
+     *                        this optstate.
+     * @param DescInfo  A descriptor info struct, generated by the optstate, which contains a number
+     *                  of important facts about the program the built descriptor will represent
+     * @param DrawType
+     * @param GrGpuGL  A GL Gpu, the caps and Gpu object are used to output processor specific
+     *                 parts of the descriptor.
+     * @param GrDeviceCoordTexture  A dstCopy texture, which may be null if frame buffer fetch is
+     *                              supported
+     * @param GrProgramDesc  The built and finalized descriptor
+     **/
+    static bool Build(const GrOptDrawState&,
+                      const GrProgramDesc::DescInfo&,
+                      GrGpu::DrawType,
+                      GrGpuGL*,
+                      const GrDeviceCoordTexture*,
+                      GrProgramDesc*);
 
-    template<typename T, size_t OFFSET> const T* atOffset() const {
-        return reinterpret_cast<const T*>(reinterpret_cast<intptr_t>(fKey.begin()) + OFFSET);
+    static const GLKeyHeader& GetHeader(const GrProgramDesc& desc) {
+        return *desc.atOffset<GLKeyHeader, kHeaderOffset>();
     }
 
-    KeyHeader* header() { return this->atOffset<KeyHeader, kHeaderOffset>(); }
-
-    // a helper class to handle getting an individual processor's key
+private:
     template <class ProcessorKeyBuilder>
     static bool BuildStagedProcessorKey(const typename ProcessorKeyBuilder::StagedProcessor& stage,
                                         const GrGLCaps& caps,
                                         bool requiresLocalCoordAttrib,
-                                        GrGLProgramDesc* desc,
+                                        GrProgramDesc* desc,
                                         int* offsetAndSizeIndex);
-    void finalize();
-
-    const KeyHeader& getHeader() const { return *this->atOffset<KeyHeader, kHeaderOffset>(); }
-
-    /** Used to provide effects' keys to their emitCode() function. */
-    class ProcKeyProvider {
-    public:
-        enum ProcessorType {
-            kGeometry_ProcessorType,
-            kFragment_ProcessorType,
-        };
-
-        ProcKeyProvider(const GrGLProgramDesc* desc, ProcessorType type)
-            : fDesc(desc), fBaseIndex(0) {
-            switch (type) {
-                case kGeometry_ProcessorType:
-                    // there can be only one
-                    fBaseIndex = 0;
-                    break;
-                case kFragment_ProcessorType:
-                    fBaseIndex = desc->hasGeometryProcessor() ? 1 : 0;
-                    break;
-            }
-        }
-
-        GrProcessorKey get(int index) const {
-            const uint16_t* offsetsAndLengths = reinterpret_cast<const uint16_t*>(
-                fDesc->fKey.begin() + kEffectKeyOffsetsAndLengthOffset);
-            // We store two uint16_ts per effect, one for the offset to the effect's key and one for
-            // its length. Here we just need the offset.
-            uint16_t offset = offsetsAndLengths[2 * (fBaseIndex + index) + 0];
-            uint16_t length = offsetsAndLengths[2 * (fBaseIndex + index) + 1];
-            // Currently effects must add to the key in units of uint32_t.
-            SkASSERT(0 == (length % sizeof(uint32_t)));
-            return GrProcessorKey(reinterpret_cast<const uint32_t*>(fDesc->fKey.begin() + offset),
-                               length / sizeof(uint32_t));
-        }
-    private:
-        const GrGLProgramDesc*  fDesc;
-        int                     fBaseIndex;
-    };
-
-    enum {
-        kMaxPreallocEffects = 8,
-        kIntsPerEffect      = 4,    // This is an overestimate of the average effect key size.
-        kPreAllocSize = kEffectKeyOffsetsAndLengthOffset +
-                        kMaxPreallocEffects * sizeof(uint32_t) * kIntsPerEffect,
-    };
-
-    SkSTArray<kPreAllocSize, uint8_t, true> fKey;
-
-    // GrGLProgram and GrGLShaderBuilder read the private fields to generate code. TODO: Split out
-    // part of GrGLShaderBuilder that is used by effects so that this header doesn't need to be
-    // visible to GrGLProcessors. Then make public accessors as necessary and remove friends.
-    friend class GrGLProgram;
-    friend class GrGLProgramBuilder;
-    friend class GrGLLegacyNvprProgramBuilder;
-    friend class GrGLVertexBuilder;
-    friend class GrGLFragmentShaderBuilder;
-    friend class GrGLGeometryBuilder;
 };
 
 #endif
index b9cb2daf74d6e085f604074bedad7118b6c49a96..88e7be0ed190233c8efe30338afa9640d2a73798 100644 (file)
@@ -2583,6 +2583,7 @@ void GrGpuGL::didRemoveGpuTraceMarker() {
         GL_CALL(PopGroupMarker());
     }
 }
+
 ///////////////////////////////////////////////////////////////////////////////
 
 GrGLAttribArrayState* GrGpuGL::HWGeometryState::bindArrayAndBuffersToDraw(
index 808f97a21c92ee6d3faa83a830429d810483a268..46d970069bf675cb53103c28d9600056ac4160f8 100644 (file)
@@ -19,6 +19,7 @@
 #include "GrGLVertexArray.h"
 #include "GrGLVertexBuffer.h"
 #include "GrGpu.h"
+#include "GrOptDrawState.h"
 #include "SkTypes.h"
 
 #ifdef SK_DEVELOPER
@@ -105,6 +106,12 @@ protected:
                                   const SkIRect& srcRect,
                                   const SkIPoint& dstPoint) SK_OVERRIDE;
 
+    virtual void buildProgramDesc(const GrOptDrawState&,
+                                  const GrProgramDesc::DescInfo&,
+                                  GrGpu::DrawType,
+                                  const GrDeviceCoordTexture* dstCopy,
+                                  GrProgramDesc*) SK_OVERRIDE;
+
 private:
     // GrGpu overrides
     virtual void onResetContext(uint32_t resetBits) SK_OVERRIDE;
@@ -181,9 +188,7 @@ private:
         ~ProgramCache();
 
         void abandon();
-        GrGLProgram* getProgram(const GrOptDrawState&,
-                                const GrGLProgramDesc&,
-                                DrawType);
+        GrGLProgram* getProgram(const GrOptDrawState&, DrawType);
 
     private:
         enum {
@@ -199,7 +204,7 @@ private:
 
         // binary search for entry matching desc. returns index into fEntries that matches desc or ~
         // of the index of where it should be inserted.
-        int search(const GrGLProgramDesc& desc) const;
+        int search(const GrProgramDesc& desc) const;
 
         // sorted array of all the entries
         Entry*                      fEntries[kMaxEntries];
index a1259c9bf8bc240f842828aade7bbb1e4e8deb8f..23de7a8599ae5c41b55089878cf925dfcf8b6281 100644 (file)
@@ -31,14 +31,14 @@ struct GrGpuGL::ProgramCache::Entry {
 };
 
 struct GrGpuGL::ProgramCache::ProgDescLess {
-    bool operator() (const GrGLProgramDesc& desc, const Entry* entry) {
+    bool operator() (const GrProgramDesc& desc, const Entry* entry) {
         SkASSERT(entry->fProgram.get());
-        return GrGLProgramDesc::Less(desc, entry->fProgram->getDesc());
+        return GrProgramDesc::Less(desc, entry->fProgram->getDesc());
     }
 
-    bool operator() (const Entry* entry, const GrGLProgramDesc& desc) {
+    bool operator() (const Entry* entry, const GrProgramDesc& desc) {
         SkASSERT(entry->fProgram.get());
-        return GrGLProgramDesc::Less(entry->fProgram->getDesc(), desc);
+        return GrProgramDesc::Less(entry->fProgram->getDesc(), desc);
     }
 };
 
@@ -86,35 +86,33 @@ void GrGpuGL::ProgramCache::abandon() {
     fCount = 0;
 }
 
-int GrGpuGL::ProgramCache::search(const GrGLProgramDesc& desc) const {
+int GrGpuGL::ProgramCache::search(const GrProgramDesc& desc) const {
     ProgDescLess less;
     return SkTSearch(fEntries, fCount, desc, sizeof(Entry*), less);
 }
 
-GrGLProgram* GrGpuGL::ProgramCache::getProgram(const GrOptDrawState& optState,
-                                               const GrGLProgramDesc& desc,
-                                               DrawType type) {
+GrGLProgram* GrGpuGL::ProgramCache::getProgram(const GrOptDrawState& optState, DrawType type) {
 #ifdef PROGRAM_CACHE_STATS
     ++fTotalRequests;
 #endif
 
     Entry* entry = NULL;
 
-    uint32_t hashIdx = desc.getChecksum();
+    uint32_t hashIdx = optState.programDesc().getChecksum();
     hashIdx ^= hashIdx >> 16;
     if (kHashBits <= 8) {
         hashIdx ^= hashIdx >> 8;
     }
     hashIdx &=((1 << kHashBits) - 1);
     Entry* hashedEntry = fHashTable[hashIdx];
-    if (hashedEntry && hashedEntry->fProgram->getDesc() == desc) {
+    if (hashedEntry && hashedEntry->fProgram->getDesc() == optState.programDesc()) {
         SkASSERT(hashedEntry->fProgram);
         entry = hashedEntry;
     }
 
     int entryIdx;
     if (NULL == entry) {
-        entryIdx = this->search(desc);
+        entryIdx = this->search(optState.programDesc());
         if (entryIdx >= 0) {
             entry = fEntries[entryIdx];
 #ifdef PROGRAM_CACHE_STATS
@@ -128,7 +126,7 @@ GrGLProgram* GrGpuGL::ProgramCache::getProgram(const GrOptDrawState& optState,
 #ifdef PROGRAM_CACHE_STATS
         ++fCacheMisses;
 #endif
-        GrGLProgram* program = GrGLProgramBuilder::CreateProgram(optState, desc, type, fGpu);
+        GrGLProgram* program = GrGLProgramBuilder::CreateProgram(optState, type, fGpu);
         if (NULL == program) {
             return NULL;
         }
@@ -178,10 +176,10 @@ GrGLProgram* GrGpuGL::ProgramCache::getProgram(const GrOptDrawState& optState,
         SkASSERT(fEntries[0]->fProgram.get());
         for (int i = 0; i < fCount - 1; ++i) {
             SkASSERT(fEntries[i + 1]->fProgram.get());
-            const GrGLProgramDesc& a = fEntries[i]->fProgram->getDesc();
-            const GrGLProgramDesc& b = fEntries[i + 1]->fProgram->getDesc();
-            SkASSERT(GrGLProgramDesc::Less(a, b));
-            SkASSERT(!GrGLProgramDesc::Less(b, a));
+            const GrProgramDesc& a = fEntries[i]->fProgram->getDesc();
+            const GrProgramDesc& b = fEntries[i + 1]->fProgram->getDesc();
+            SkASSERT(GrProgramDesc::Less(a, b));
+            SkASSERT(!GrProgramDesc::Less(b, a));
         }
 #endif
     }
@@ -207,7 +205,8 @@ bool GrGpuGL::flushGraphicsState(DrawType type,
                                  const ScissorState& scissorState,
                                  const GrDeviceCoordTexture* dstCopy) {
     SkAutoTUnref<GrOptDrawState> optState(GrOptDrawState::Create(this->getDrawState(),
-                                                                 *this->caps(),
+                                                                 this,
+                                                                 dstCopy,
                                                                  type));
 
     if (!optState) {
@@ -234,13 +233,7 @@ bool GrGpuGL::flushGraphicsState(DrawType type,
             return false;
         }
 
-        GrGLProgramDesc desc;
-        if (!GrGLProgramDesc::Build(*optState.get(), type, this, dstCopy, &desc)) {
-            SkDEBUGFAIL("Failed to generate GL program descriptor");
-            return false;
-        }
-
-        fCurrentProgram.reset(fProgramCache->getProgram(*optState.get(), desc, type));
+        fCurrentProgram.reset(fProgramCache->getProgram(*optState.get(), type));
         if (NULL == fCurrentProgram.get()) {
             SkDEBUGFAIL("Failed to create program!");
             return false;
@@ -279,7 +272,7 @@ bool GrGpuGL::flushGraphicsState(DrawType type,
 
 void GrGpuGL::setupGeometry(const DrawInfo& info, size_t* indexOffsetInBytes) {
     SkAutoTUnref<GrOptDrawState> optState(
-        GrOptDrawState::Create(this->getDrawState(), *this->caps(),
+        GrOptDrawState::Create(this->getDrawState(), this, info.getDstCopy(),
                                PrimTypeToDrawType(info.primitiveType())));
 
     // If the optState would is NULL it should have been caught in flushGraphicsState before getting
@@ -361,3 +354,13 @@ void GrGpuGL::setupGeometry(const DrawInfo& info, size_t* indexOffsetInBytes) {
         attribState->disableUnusedArrays(this, usedAttribArraysMask);
     }
 }
+
+void GrGpuGL::buildProgramDesc(const GrOptDrawState& optState,
+                               const GrProgramDesc::DescInfo& descInfo,
+                               GrGpu::DrawType drawType,
+                               const GrDeviceCoordTexture* dstCopy,
+                               GrProgramDesc* desc) {
+    if (!GrGLProgramDescBuilder::Build(optState, descInfo, drawType, this, dstCopy, desc)) {
+        SkDEBUGFAIL("Failed to generate GL program descriptor");
+    }
+}
index ff3989bf634bbd2c2d9b7bff924e6cdf18bd0c25..6aeba7a9eed2a1e769b0026152edc3ce36cf4671 100644 (file)
@@ -69,12 +69,12 @@ GrGLFragmentShaderBuilder::KeyForFragmentPosition(const GrRenderTarget* dst, con
 }
 
 GrGLFragmentShaderBuilder::GrGLFragmentShaderBuilder(GrGLProgramBuilder* program,
-                                                     const GrGLProgramDesc& desc)
+                                                     uint8_t fragPosKey)
     : INHERITED(program)
     , fHasCustomColorOutput(false)
     , fHasSecondaryOutput(false)
     , fSetupFragPosition(false)
-    , fTopLeftFragPosRead(kTopLeftFragPosRead_FragPosKey == desc.getHeader().fFragPosKey)
+    , fTopLeftFragPosRead(kTopLeftFragPosRead_FragPosKey == fragPosKey)
     , fCustomColorOutputIndex(-1)
     , fHasReadDstColor(false)
     , fHasReadFragmentPosition(false) {
@@ -262,13 +262,13 @@ void GrGLFragmentShaderBuilder::enableSecondaryOutput(const GrGLSLExpr4& inputCo
     const char* secondaryOutputName = this->getSecondaryColorOutputName();
     GrGLSLExpr4 coeff(1);
     switch (fProgramBuilder->header().fSecondaryOutputType) {
-        case GrOptDrawState::kCoverage_SecondaryOutputType:
+        case GrProgramDesc::kCoverage_SecondaryOutputType:
             break;
-        case GrOptDrawState::kCoverageISA_SecondaryOutputType:
+        case GrProgramDesc::kCoverageISA_SecondaryOutputType:
             // Get (1-A) into coeff
             coeff = GrGLSLExpr4::VectorCast(GrGLSLExpr1(1) - inputColor.a());
             break;
-        case GrOptDrawState::kCoverageISC_SecondaryOutputType:
+        case GrProgramDesc::kCoverageISC_SecondaryOutputType:
             // Get (1-RGBA) into coeff
             coeff = GrGLSLExpr4(1) - inputColor;
             break;
@@ -283,9 +283,9 @@ void GrGLFragmentShaderBuilder::combineColorAndCoverage(const GrGLSLExpr4& input
                                                         const GrGLSLExpr4& inputCoverage) {
     GrGLSLExpr4 fragColor = inputColor * inputCoverage;
     switch (fProgramBuilder->header().fPrimaryOutputType) {
-        case GrOptDrawState::kModulate_PrimaryOutputType:
+        case GrProgramDesc::kModulate_PrimaryOutputType:
             break;
-        case GrOptDrawState::kCombineWithDst_PrimaryOutputType:
+        case GrProgramDesc::kCombineWithDst_PrimaryOutputType:
             {
                 // Tack on "+(1-coverage)dst onto the frag color.
                 GrGLSLExpr4 dstCoeff = GrGLSLExpr4(1) - inputCoverage;
index b5f83d46db8da880ffa7ab942e5d67aca10e1678..226be518c359ca03d7a216ec9b3e6c561b7ded8c 100644 (file)
@@ -84,7 +84,7 @@ public:
        the key is 0. */
     static FragPosKey KeyForFragmentPosition(const GrRenderTarget* dst, const GrGLCaps&);
 
-    GrGLFragmentShaderBuilder(GrGLProgramBuilder* program, const GrGLProgramDesc& desc);
+    GrGLFragmentShaderBuilder(GrGLProgramBuilder* program, uint8_t fragPosKey);
 
     // true public interface, defined explicitly in the abstract interfaces above
     virtual bool enableFeature(GLSLFeature) SK_OVERRIDE;
index af95f564cf885b54b024a78a2ae2ca02a5de036d..f35c9ba910533100baa6cee57df432daf23c51d5 100644 (file)
@@ -48,7 +48,7 @@ bool GrGLGeometryBuilder::compileAndAttachShaders(GrGLuint programId,
     geomShaderSrc.append("void main() {\n");
     geomShaderSrc.append("\tfor (int i = 0; i < 3; ++i) {\n"
                          "\t\tgl_Position = gl_in[i].gl_Position;\n");
-    if (fProgramBuilder->desc().getHeader().fEmitsPointSize) {
+    if (fProgramBuilder->desc().header().fEmitsPointSize) {
         geomShaderSrc.append("\t\tgl_PointSize = 1.0;\n");
     }
     SkASSERT(fInputs.count() == fOutputs.count());
index 1c1cb421223b366747058be5cd3775d8cd9e0e67..c0c4fbb46ed17eb2426013590b30698da7a3d8e4 100644 (file)
@@ -9,12 +9,9 @@
 #include "../GrGpuGL.h"
 
 GrGLLegacyNvprProgramBuilder::GrGLLegacyNvprProgramBuilder(GrGpuGL* gpu,
-                                                           const GrOptDrawState& optState,
-                                                           const GrGLProgramDesc& desc)
-    : INHERITED(gpu, optState, desc)
+                                                           const GrOptDrawState& optState)
+    : INHERITED(gpu, optState)
     , fTexCoordSetCnt(0) {
-    SkASSERT(GrGLProgramDesc::kAttribute_ColorInput != desc.getHeader().fColorInput);
-    SkASSERT(GrGLProgramDesc::kAttribute_ColorInput != desc.getHeader().fCoverageInput);
 }
 
 int GrGLLegacyNvprProgramBuilder::addTexCoordSets(int count) {
index dabec081b4e914c7a0ef83a1b96d85552864dd9a..cd2cfb74534912a6a38b8c9d9f042a02fe48ddd3 100644 (file)
@@ -12,7 +12,7 @@
 
 class GrGLLegacyNvprProgramBuilder : public GrGLProgramBuilder {
 public:
-    GrGLLegacyNvprProgramBuilder(GrGpuGL*, const GrOptDrawState&, const GrGLProgramDesc&);
+    GrGLLegacyNvprProgramBuilder(GrGpuGL*, const GrOptDrawState&);
 
     virtual GrGLProgram* createProgram(GrGLuint programID);
 
index 3d991a2e2c63a977c9ad9f924252fc416ff8a8c4..5488252b288c6abd8bd070bc1da1bb0f5b628829 100644 (file)
@@ -12,9 +12,8 @@
 #define GL_CALL_RET(R, X) GR_GL_CALL_RET(this->gpu()->glInterface(), R, X)
 
 GrGLNvprProgramBuilder::GrGLNvprProgramBuilder(GrGpuGL* gpu,
-                                               const GrOptDrawState& optState,
-                                               const GrGLProgramDesc& desc)
-        : INHERITED(gpu, optState, desc)
+                                               const GrOptDrawState& optState)
+        : INHERITED(gpu, optState)
         , fSeparableVaryingInfos(kVarsPerBlock) {
 }
 
index 008aff74d7ab35e06d1c1a33c68111cea83569b0..e9f6b3b872fedec97530665b1490c7ab10fd33dd 100644 (file)
@@ -12,7 +12,7 @@
 
 class GrGLNvprProgramBuilder : public GrGLProgramBuilder {
 public:
-    GrGLNvprProgramBuilder(GrGpuGL*, const GrOptDrawState&, const GrGLProgramDesc&);
+    GrGLNvprProgramBuilder(GrGpuGL*, const GrOptDrawState&);
 
     /*
      * The separable varying info must be passed to GrGLProgram so this must
index 65a7cdaa63cd326e633e64670a2c32d117f7522f..6df086c1a15f829a94943cd18347873af163d1eb 100644 (file)
@@ -29,19 +29,17 @@ static const GrGLShaderVar::Precision kDefaultFragmentPrecision = GrGLShaderVar:
 const int GrGLProgramBuilder::kVarsPerBlock = 8;
 
 GrGLProgram* GrGLProgramBuilder::CreateProgram(const GrOptDrawState& optState,
-                                               const GrGLProgramDesc& desc,
                                                GrGpu::DrawType drawType,
                                                GrGpuGL* gpu) {
     // create a builder.  This will be handed off to effects so they can use it to add
     // uniforms, varyings, textures, etc
-    SkAutoTDelete<GrGLProgramBuilder> builder(CreateProgramBuilder(desc,
-                                                                   optState,
+    SkAutoTDelete<GrGLProgramBuilder> builder(CreateProgramBuilder(optState,
                                                                    drawType,
                                                                    optState.hasGeometryProcessor(),
                                                                    gpu));
 
     GrGLProgramBuilder* pb = builder.get();
-    const GrGLProgramDesc::KeyHeader& header = pb->header();
+    const GrGLProgramDescBuilder::GLKeyHeader& header = GrGLProgramDescBuilder::GetHeader(pb->desc());
 
     // emit code to read the dst copy texture, if necessary
     if (GrGLFragmentShaderBuilder::kNoDstRead_DstReadKey != header.fDstReadKey
@@ -64,10 +62,10 @@ GrGLProgram* GrGLProgramBuilder::CreateProgram(const GrOptDrawState& optState,
         if (header.fEmitsPointSize) {
             pb->fVS.codeAppend("gl_PointSize = 1.0;");
         }
-        if (GrGLProgramDesc::kAttribute_ColorInput == header.fColorInput) {
+        if (GrProgramDesc::kAttribute_ColorInput == header.fColorInput) {
             pb->fVS.setupBuiltinVertexAttribute("Color", &inputColor);
         }
-        if (GrGLProgramDesc::kAttribute_ColorInput == header.fCoverageInput) {
+        if (GrProgramDesc::kAttribute_ColorInput == header.fCoverageInput) {
             pb->fVS.setupBuiltinVertexAttribute("Coverage", &inputCoverage);
         }
     }
@@ -79,7 +77,7 @@ GrGLProgram* GrGLProgramBuilder::CreateProgram(const GrOptDrawState& optState,
     }
 
     // write the secondary color output if necessary
-    if (GrOptDrawState::kNone_SecondaryOutputType != header.fSecondaryOutputType) {
+    if (GrProgramDesc::kNone_SecondaryOutputType != header.fSecondaryOutputType) {
         pb->fFS.enableSecondaryOutput(inputColor, inputCoverage);
     }
 
@@ -89,38 +87,38 @@ GrGLProgram* GrGLProgramBuilder::CreateProgram(const GrOptDrawState& optState,
 }
 
 GrGLProgramBuilder*
-GrGLProgramBuilder::CreateProgramBuilder(const GrGLProgramDesc& desc,
-                                         const GrOptDrawState& optState,
+GrGLProgramBuilder::CreateProgramBuilder(const GrOptDrawState& optState,
                                          GrGpu::DrawType drawType,
                                          bool hasGeometryProcessor,
                                          GrGpuGL* gpu) {
-    if (desc.getHeader().fUseNvpr) {
+    const GrProgramDesc& desc = optState.programDesc();
+    if (GrGLProgramDescBuilder::GetHeader(desc).fUseNvpr) {
         SkASSERT(gpu->glCaps().pathRenderingSupport());
+        SkASSERT(GrProgramDesc::kAttribute_ColorInput != desc.header().fColorInput);
+        SkASSERT(GrProgramDesc::kAttribute_ColorInput != desc.header().fCoverageInput);
         SkASSERT(!hasGeometryProcessor);
         if (gpu->glPathRendering()->texturingMode() ==
             GrGLPathRendering::FixedFunction_TexturingMode) {
-            return SkNEW_ARGS(GrGLLegacyNvprProgramBuilder, (gpu, optState, desc));
+            return SkNEW_ARGS(GrGLLegacyNvprProgramBuilder, (gpu, optState));
         } else {
-            return SkNEW_ARGS(GrGLNvprProgramBuilder, (gpu, optState, desc));
+            return SkNEW_ARGS(GrGLNvprProgramBuilder, (gpu, optState));
         }
     } else {
-        return SkNEW_ARGS(GrGLProgramBuilder, (gpu, optState, desc));
+        return SkNEW_ARGS(GrGLProgramBuilder, (gpu, optState));
     }
 }
 
 /////////////////////////////////////////////////////////////////////////////
 
-GrGLProgramBuilder::GrGLProgramBuilder(GrGpuGL* gpu,
-                                       const GrOptDrawState& optState,
-                                       const GrGLProgramDesc& desc)
+GrGLProgramBuilder::GrGLProgramBuilder(GrGpuGL* gpu, const GrOptDrawState& optState)
     : fVS(this)
     , fGS(this)
-    , fFS(this, desc)
+    , fFS(this, optState.programDesc().header().fFragPosKey)
     , fOutOfStage(true)
     , fStageIndex(-1)
     , fGeometryProcessor(NULL)
     , fOptState(optState)
-    , fDesc(desc)
+    , fDesc(optState.programDesc())
     , fGpu(gpu)
     , fUniforms(kVarsPerBlock) {
 }
@@ -202,8 +200,8 @@ const GrGLContextInfo& GrGLProgramBuilder::ctxInfo() const {
 
 void GrGLProgramBuilder::setupUniformColorAndCoverageIfNeeded(GrGLSLExpr4* inputColor,
                                                               GrGLSLExpr4* inputCoverage) {
-    const GrGLProgramDesc::KeyHeader& header = this->header();
-    if (GrGLProgramDesc::kUniform_ColorInput == header.fColorInput) {
+    const GrProgramDesc::KeyHeader& header = this->header();
+    if (GrProgramDesc::kUniform_ColorInput == header.fColorInput) {
         const char* name;
         fUniformHandles.fColorUni =
             this->addUniform(GrGLProgramBuilder::kFragment_Visibility,
@@ -211,10 +209,10 @@ void GrGLProgramBuilder::setupUniformColorAndCoverageIfNeeded(GrGLSLExpr4* input
                              "Color",
                              &name);
         *inputColor = GrGLSLExpr4(name);
-    } else if (GrGLProgramDesc::kAllOnes_ColorInput == header.fColorInput) {
+    } else if (GrProgramDesc::kAllOnes_ColorInput == header.fColorInput) {
         *inputColor = GrGLSLExpr4(1);
     }
-    if (GrGLProgramDesc::kUniform_ColorInput == header.fCoverageInput) {
+    if (GrProgramDesc::kUniform_ColorInput == header.fCoverageInput) {
         const char* name;
         fUniformHandles.fCoverageUni =
             this->addUniform(GrGLProgramBuilder::kFragment_Visibility,
@@ -222,7 +220,7 @@ void GrGLProgramBuilder::setupUniformColorAndCoverageIfNeeded(GrGLSLExpr4* input
                              "Coverage",
                              &name);
         *inputCoverage = GrGLSLExpr4(name);
-    } else if (GrGLProgramDesc::kAllOnes_ColorInput == header.fCoverageInput) {
+    } else if (GrProgramDesc::kAllOnes_ColorInput == header.fCoverageInput) {
         *inputCoverage = GrGLSLExpr4(1);
     }
 }
@@ -236,7 +234,9 @@ void GrGLProgramBuilder::emitAndInstallProcs(const GrOptDrawState& optState,
     if (optState.hasGeometryProcessor()) {
         const GrGeometryProcessor& gp = *optState.getGeometryProcessor();
         fVS.emitAttributes(gp);
-        ProcKeyProvider keyProvider(&fDesc, ProcKeyProvider::kGeometry_ProcessorType);
+        ProcKeyProvider keyProvider(&fDesc,
+                                    ProcKeyProvider::kGeometry_ProcessorType,
+                                    GrGLProgramDescBuilder::kProcessorKeyOffsetsAndLengthOffset);
         GrGLSLExpr4 output;
         this->emitAndInstallProc<GrGeometryProcessor>(gp, 0, keyProvider, *inputCoverage, &output);
         *inputCoverage = output;
@@ -245,7 +245,9 @@ void GrGLProgramBuilder::emitAndInstallProcs(const GrOptDrawState& optState,
 }
 
 void GrGLProgramBuilder::emitAndInstallFragProcs(int procOffset, int numProcs, GrGLSLExpr4* inOut) {
-    ProcKeyProvider keyProvider(&fDesc, ProcKeyProvider::kFragment_ProcessorType);
+    ProcKeyProvider keyProvider(&fDesc,
+                                ProcKeyProvider::kFragment_ProcessorType,
+                                GrGLProgramDescBuilder::kProcessorKeyOffsetsAndLengthOffset);
     for (int e = procOffset; e < numProcs; ++e) {
         GrGLSLExpr4 output;
         const GrFragmentStage& stage = fOptState.getFragmentStage(e);
@@ -259,7 +261,7 @@ void GrGLProgramBuilder::emitAndInstallFragProcs(int procOffset, int numProcs, G
 template <class Proc>
 void GrGLProgramBuilder::emitAndInstallProc(const Proc& proc,
                                             int index,
-                                            const ProcKeyProvider keyProvider,
+                                            const ProcKeyProvider& keyProvider,
                                             const GrGLSLExpr4& input,
                                             GrGLSLExpr4* output) {
     // Program builders have a bit of state we need to clear with each effect
@@ -419,7 +421,7 @@ GrGLProgram* GrGLProgramBuilder::finalize() {
         this->cleanupProgram(programID, shadersToDelete);
         return NULL;
     }
-    if (!(this->header().fUseNvpr &&
+    if (!(GrGLProgramDescBuilder::GetHeader(fDesc).fUseNvpr &&
           fGpu->glPathRendering()->texturingMode() ==
           GrGLPathRendering::FixedFunction_TexturingMode)) {
         if (!fVS.compileAndAttachShaders(programID, &shadersToDelete)) {
index 9d8e7e0ac9657ee6844d7b43a85c925be0305143..0abdf0a12229fc9928510782e485311bd8c2b5f3 100644 (file)
@@ -169,10 +169,7 @@ public:
      * to be used.
      * @return true if generation was successful.
      */
-    static GrGLProgram* CreateProgram(const GrOptDrawState&,
-                                      const GrGLProgramDesc&,
-                                      GrGpu::DrawType,
-                                      GrGpuGL* gpu);
+    static GrGLProgram* CreateProgram(const GrOptDrawState&, GrGpu::DrawType, GrGpuGL*);
 
     virtual UniformHandle addUniform(uint32_t visibility,
                                      GrSLType type,
@@ -224,21 +221,20 @@ public:
     };
 
 protected:
-    typedef GrGLProgramDesc::ProcKeyProvider ProcKeyProvider;
+    typedef GrProgramDesc::ProcKeyProvider ProcKeyProvider;
     typedef GrGLProgramDataManager::UniformInfo UniformInfo;
     typedef GrGLProgramDataManager::UniformInfoArray UniformInfoArray;
 
-    static GrGLProgramBuilder* CreateProgramBuilder(const GrGLProgramDesc&,
-                                                    const GrOptDrawState&,
+    static GrGLProgramBuilder* CreateProgramBuilder(const GrOptDrawState&,
                                                     GrGpu::DrawType,
                                                     bool hasGeometryProcessor,
                                                     GrGpuGL*);
 
-    GrGLProgramBuilder(GrGpuGL*, const GrOptDrawState&, const GrGLProgramDesc&);
+    GrGLProgramBuilder(GrGpuGL*, const GrOptDrawState&);
 
     const GrOptDrawState& optState() const { return fOptState; }
-    const GrGLProgramDesc& desc() const { return fDesc; }
-    const GrGLProgramDesc::KeyHeader& header() const { return fDesc.getHeader(); }
+    const GrProgramDesc& desc() const { return fDesc; }
+    const GrProgramDesc::KeyHeader& header() const { return fDesc.header(); }
 
     // Generates a name for a variable. The generated string will be name prefixed by the prefix
     // char (unless the prefix is '\0'). It also mangles the name to be stage-specific if we're
@@ -252,7 +248,7 @@ protected:
     template <class Proc>
     void emitAndInstallProc(const Proc&,
                             int index,
-                            const ProcKeyProvider,
+                            const ProcKeyProvider&,
                             const GrGLSLExpr4& input,
                             GrGLSLExpr4* output);
 
@@ -332,7 +328,7 @@ protected:
     SkAutoTUnref<GrGLInstalledFragProcs> fFragmentProcessors;
 
     const GrOptDrawState& fOptState;
-    const GrGLProgramDesc& fDesc;
+    const GrProgramDesc& fDesc;
     GrGpuGL* fGpu;
     UniformInfoArray fUniforms;
 
index cf7ae9b53d21f081b6452b312b7d546625c80c71..8b7b9f9974d9728d9cc52eae068f30163475acd7 100644 (file)
@@ -8,6 +8,7 @@
 #ifndef GrGLShaderBuilder_DEFINED
 #define GrGLShaderBuilder_DEFINED
 
+#include "gl/GrGLProcessor.h"
 #include "gl/GrGLProgramDesc.h"
 #include "gl/GrGLProgramDataManager.h"
 
index 1fa946793c64bead43fd59c8e1a83ed79d8d996d..5a65f71fccf460f8ccb14edc671b0762bd5c9600 100644 (file)
@@ -93,7 +93,7 @@ void GrGLVertexBuilder::transformSkiaToGLCoords() {
 
 void GrGLVertexBuilder::bindVertexAttributes(GrGLuint programID) {
     // Bind the attrib locations to same values for all shaders
-    const GrGLProgramDesc::KeyHeader& header = fProgramBuilder->header();
+    const GrProgramDesc::KeyHeader& header = fProgramBuilder->header();
     SkASSERT(-1 != header.fPositionAttributeIndex);
     GL_CALL(BindAttribLocation(programID,
                                header.fPositionAttributeIndex,
index 24d6203e35d7f6f238bb62f900f073919f40b810..c9e840e9c140b4853daf391b1389c6387c6c44c6 100644 (file)
@@ -447,32 +447,24 @@ bool GrGpuGL::programUnitTest(int maxStages) {
         set_random_blend_func(this, &random);
         set_random_stencil(this, &random);
 
+        GrDeviceCoordTexture dstCopy;
+
+        if (!this->setupDstReadIfNecessary(&dstCopy, NULL)) {
+            SkDebugf("Couldn't setup dst read texture");
+            return false;
+        }
+
         // create optimized draw state, setup readDst texture if required, and build a descriptor
         // and program.  ODS creation can fail, so we have to check
         SkAutoTUnref<GrOptDrawState> ods(GrOptDrawState::Create(this->getDrawState(),
-                                                                *this->caps(),
+                                                                this,
+                                                                &dstCopy,
                                                                 drawType));
         if (!ods.get()) {
             ds->reset();
             continue;
         }
-        GrGLProgramDesc desc;
-        GrDeviceCoordTexture dstCopy;
-
-        if (!this->setupDstReadIfNecessary(&dstCopy, NULL)) {
-            SkDebugf("Couldn't setup dst read texture");
-            return false;
-        }
-        if (!GrGLProgramDesc::Build(*ods,
-                                    drawType,
-                                    this,
-                                    dstCopy.texture() ? &dstCopy : NULL,
-                                    &desc)) {
-            SkDebugf("Failed to generate GL program descriptor");
-            return false;
-        }
-        SkAutoTUnref<GrGLProgram> program(
-                GrGLProgramBuilder::CreateProgram(*ods, desc, drawType, this));
+        SkAutoTUnref<GrGLProgram> program(GrGLProgramBuilder::CreateProgram(*ods, drawType, this));
         if (NULL == program.get()) {
             SkDebugf("Failed to create program!");
             return false;