Opt state takes a GP instead of a GeometryStage
authorjoshualitt <joshualitt@chromium.org>
Fri, 10 Oct 2014 16:56:55 +0000 (09:56 -0700)
committerCommit bot <commit-bot@chromium.org>
Fri, 10 Oct 2014 16:56:55 +0000 (09:56 -0700)
BUG=skia:

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

25 files changed:
include/gpu/GrProcessor.h
include/gpu/GrProcessorStage.h
src/effects/gradients/SkGradientShaderPriv.h
src/gpu/GrDrawState.cpp
src/gpu/GrDrawState.h
src/gpu/GrDrawTarget.cpp
src/gpu/GrOptDrawState.cpp
src/gpu/GrOptDrawState.h
src/gpu/GrProcessor.cpp
src/gpu/effects/GrConfigConversionEffect.h
src/gpu/gl/GrGLProcessor.h
src/gpu/gl/GrGLProgram.cpp
src/gpu/gl/GrGLProgram.h
src/gpu/gl/GrGLProgramDesc.cpp
src/gpu/gl/GrGLProgramDesc.h
src/gpu/gl/GrGpuGL.h
src/gpu/gl/GrGpuGL_program.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/GrGLVertexShaderBuilder.h
tests/GLProgramsTest.cpp

index c1755a895472a9973315de9bc575fc90fb928eca..a5c834168b48879b52b4def5de4e2b46c31829c9 100644 (file)
@@ -124,12 +124,6 @@ public:
         in generated shader code. */
     const char* name() const;
 
-    int numTransforms() const { return fCoordTransforms.count(); }
-
-    /** Returns the coordinate transformation at index. index must be valid according to
-        numTransforms(). */
-    const GrCoordTransform& coordTransform(int index) const { return *fCoordTransforms[index]; }
-
     int numTextures() const { return fTextureAccesses.count(); }
 
     /** Returns the access pattern for the texture at index. index must be valid according to
@@ -158,16 +152,6 @@ public:
     template <typename T> const T& cast() const { return *static_cast<const T*>(this); }
 
 protected:
-    /**
-     * Subclasses call this from their constructor to register coordinate transformations. The
-     * effect subclass manages the lifetime of the transformations (this function only stores a
-     * pointer). The GrCoordTransform is typically a member field of the GrProcessor subclass. When
-     * the matrix has perspective, the transformed coordinates will have 3 components. Otherwise
-     * they'll have 2. This must only be called from the constructor because GrProcessors are
-     * immutable.
-     */
-    void addCoordTransform(const GrCoordTransform* coordTransform);
-
     /**
      * Subclasses call this from their constructor to register GrTextureAccesses. The effect
      * subclass manages the lifetime of the accesses (this function only stores a pointer). The
@@ -198,9 +182,7 @@ private:
      * Subclass implements this to support getConstantColorComponents(...).
      */
     virtual void onComputeInvariantOutput(InvariantOutput* inout) const = 0;
-    friend class GrGeometryProcessor; // to set fRequiresVertexShader and build fVertexAttribTypes.
 
-    SkSTArray<4, const GrCoordTransform*, true>  fCoordTransforms;
     SkSTArray<4, const GrTextureAccess*, true>   fTextureAccesses;
     bool                                         fWillReadFragmentPosition;
 
@@ -216,6 +198,12 @@ public:
 
     virtual const GrBackendFragmentProcessorFactory& getFactory() const = 0;
 
+    int numTransforms() const { return fCoordTransforms.count(); }
+
+    /** Returns the coordinate transformation at index. index must be valid according to
+        numTransforms(). */
+    const GrCoordTransform& coordTransform(int index) const { return *fCoordTransforms[index]; }
+
     /** Will this effect read the destination pixel value? */
     bool willReadDstColor() const { return fWillReadDstColor; }
 
@@ -223,6 +211,16 @@ public:
     bool willUseInputColor() const { return fWillUseInputColor; }
 
 protected:
+    /**
+     * Fragment Processor subclasses call this from their constructor to register coordinate
+     * transformations. The processor subclass manages the lifetime of the transformations (this
+     * function only stores a pointer). The GrCoordTransform is typically a member field of the
+     * GrProcessor subclass. When the matrix has perspective, the transformed coordinates will have
+     * 3 components. Otherwise they'll have 2. This must only be called from the constructor because
+     * GrProcessors are immutable.
+     */
+    void addCoordTransform(const GrCoordTransform*);
+
     /**
      * If the effect subclass will read the destination pixel value then it must call this function
      * from its constructor. Otherwise, when its generated backend-specific effect class attempts
@@ -238,6 +236,7 @@ protected:
     void setWillNotUseInputColor() { fWillUseInputColor = false; }
 
 private:
+    SkSTArray<4, const GrCoordTransform*, true>  fCoordTransforms;
     bool                                         fWillReadDstColor;
     bool                                         fWillUseInputColor;
 
index 5cc06e78db3c298568535bb1aaf4ee523bf564ba..c961572c1dcc5076993a2409513186e6f971ec8b 100644 (file)
 // is immutable, and only owns pending execution refs. This requries removing the common base
 // class from GrDrawState and GrOptDrawState called GrRODrawState and converting to GrOptDrawState
 // when draws are enqueued in the GrInOrderDrawBuffer.
-class GrProcessorStage {
+class GrFragmentStage {
 public:
-    explicit GrProcessorStage(const GrProcessor* proc)
+    explicit GrFragmentStage(const GrFragmentProcessor* proc)
     : fProc(SkRef(proc)) {
         fCoordChangeMatrixSet = false;
     }
 
-    virtual ~GrProcessorStage() {}
-
-    GrProcessorStage(const GrProcessorStage& other) {
+    GrFragmentStage(const GrFragmentStage& other) {
         fCoordChangeMatrixSet = other.fCoordChangeMatrixSet;
         if (other.fCoordChangeMatrixSet) {
             fCoordChangeMatrix = other.fCoordChangeMatrix;
@@ -41,7 +39,7 @@ public:
         fProc.initAndRef(other.fProc);
     }
     
-    static bool AreCompatible(const GrProcessorStage& a, const GrProcessorStage& b,
+    static bool AreCompatible(const GrFragmentStage& a, const GrFragmentStage& b,
                               bool usingExplicitLocalCoords) {
         SkASSERT(a.fProc.get());
         SkASSERT(b.fProc.get());
@@ -90,7 +88,7 @@ public:
         SkMatrix fCoordChangeMatrix;
         SkDEBUGCODE(mutable uint32_t fEffectUniqueID;)
 
-        friend class GrProcessorStage;
+        friend class GrFragmentStage;
     };
 
     /**
@@ -149,38 +147,14 @@ public:
         }
     }
 
-    virtual const GrProcessor* getProcessor() const = 0;
+    const GrFragmentProcessor* getProcessor() const { return fProc.get(); }
 
     void convertToPendingExec() { fProc.convertToPendingExec(); }
 
 protected:
-    bool                                   fCoordChangeMatrixSet;
-    SkMatrix                               fCoordChangeMatrix;
-    GrProgramElementRef<const GrProcessor> fProc;
-};
-
-class GrFragmentStage : public GrProcessorStage {
-public:
-    GrFragmentStage(const GrFragmentProcessor* fp) : GrProcessorStage(fp) {}
-
-    virtual const GrFragmentProcessor* getProcessor() const {
-        return static_cast<const GrFragmentProcessor*>(fProc.get());
-    }
-
-    typedef GrFragmentProcessor   Processor;
-    typedef GrGLFragmentProcessor GLProcessor;
-};
-
-class GrGeometryStage : public GrProcessorStage {
-public:
-    GrGeometryStage(const GrGeometryProcessor* gp) : GrProcessorStage(gp) {}
-
-    virtual const GrGeometryProcessor* getProcessor() const {
-        return static_cast<const GrGeometryProcessor*>(fProc.get());
-    }
-
-    typedef GrGeometryProcessor   Processor;
-    typedef GrGLGeometryProcessor GLProcessor;
+    bool                                           fCoordChangeMatrixSet;
+    SkMatrix                                       fCoordChangeMatrix;
+    GrProgramElementRef<const GrFragmentProcessor> fProc;
 };
 
 #endif
index d1ac77bc920c5299e533cdbadc33b6e679a724f6..b3ad6f4b3483a810587211b3b9e96cbebc79c596 100644 (file)
@@ -300,7 +300,7 @@ static inline int next_dither_toggle16(int toggle) {
 #include "GrCoordTransform.h"
 #include "gl/GrGLProcessor.h"
 
-class GrProcessorStage;
+class GrFragmentStage;
 class GrBackendProcessorFactory;
 
 /*
index 288fa12730850316750b1992446ee7381a860d83..e1fa6da8774307cf1c115db2ba64d6e772e857a6 100644 (file)
@@ -43,9 +43,7 @@ bool GrDrawState::isEqual(const GrDrawState& that) const {
     if (this->hasGeometryProcessor()) {
         if (!that.hasGeometryProcessor()) {
             return false;
-        } else if (!GrProcessorStage::AreCompatible(*this->getGeometryProcessor(),
-                                                    *that.getGeometryProcessor(),
-                                                    explicitLocalCoords)) {
+        } else if (!this->getGeometryProcessor()->isEqual(*that.getGeometryProcessor())) {
             return false;
         }
     } else if (that.hasGeometryProcessor()) {
@@ -53,13 +51,13 @@ bool GrDrawState::isEqual(const GrDrawState& that) const {
     }
 
     for (int i = 0; i < this->numColorStages(); i++) {
-        if (!GrProcessorStage::AreCompatible(this->getColorStage(i), that.getColorStage(i),
+        if (!GrFragmentStage::AreCompatible(this->getColorStage(i), that.getColorStage(i),
                                              explicitLocalCoords)) {
             return false;
         }
     }
     for (int i = 0; i < this->numCoverageStages(); i++) {
-        if (!GrProcessorStage::AreCompatible(this->getCoverageStage(i), that.getCoverageStage(i),
+        if (!GrFragmentStage::AreCompatible(this->getCoverageStage(i), that.getCoverageStage(i),
                                              explicitLocalCoords)) {
             return false;
         }
@@ -116,9 +114,6 @@ GrDrawState::GrDrawState(const GrDrawState& state, const SkMatrix& preConcatMatr
     SkDEBUGCODE(fBlockEffectRemovalCnt = 0;)
     *this = state;
     if (!preConcatMatrix.isIdentity()) {
-        if (this->hasGeometryProcessor()) {
-            fGeometryProcessor->localCoordChange(preConcatMatrix);
-        }
         for (int i = 0; i < this->numColorStages(); ++i) {
             fColorStages[i].localCoordChange(preConcatMatrix);
         }
@@ -147,7 +142,7 @@ GrDrawState& GrDrawState::operator=(const GrDrawState& that) {
     fCoverage = that.fCoverage;
     fDrawFace = that.fDrawFace;
     if (that.hasGeometryProcessor()) {
-        fGeometryProcessor.reset(SkNEW_ARGS(GrGeometryStage, (*that.fGeometryProcessor.get())));
+        fGeometryProcessor.initAndRef(that.fGeometryProcessor);
     } else {
         fGeometryProcessor.reset(NULL);
     }
@@ -202,9 +197,6 @@ bool GrDrawState::setIdentityViewMatrix()  {
             // sad trombone sound
             return false;
         }
-        if (this->hasGeometryProcessor()) {
-            fGeometryProcessor->localCoordChange(invVM);
-        }
         for (int s = 0; s < this->numColorStages(); ++s) {
             fColorStages[s].localCoordChange(invVM);
         }
@@ -265,9 +257,7 @@ bool GrDrawState::validateVertexAttribs() const {
     }
 
     if (this->hasGeometryProcessor()) {
-        const GrGeometryStage& stage = *this->getGeometryProcessor();
-        const GrGeometryProcessor* gp = stage.getProcessor();
-        SkASSERT(gp);
+        const GrGeometryProcessor* gp = this->getGeometryProcessor();
         // make sure that any attribute indices have the correct binding type, that the attrib
         // type and effect's shader lang type are compatible, and that attributes shared by
         // multiple effects use the same shader lang type.
@@ -410,8 +400,7 @@ bool GrDrawState::hasSolidCoverage() const {
 
     // Run through the coverage stages and see if the coverage will be all ones at the end.
     if (this->hasGeometryProcessor()) {
-        const GrGeometryProcessor* gp = fGeometryProcessor->getProcessor();
-        gp->computeInvariantOutput(&inout);
+        fGeometryProcessor->computeInvariantOutput(&inout);
     }
 
     for (int s = 0; s < this->numCoverageStages(); ++s) {
@@ -456,7 +445,7 @@ void GrDrawState::AutoRestoreEffects::set(GrDrawState* ds) {
         if (SK_InvalidUniqueID == fOriginalGPID) {
             fDrawState->fGeometryProcessor.reset(NULL);
         } else {
-            SkASSERT(fDrawState->getGeometryProcessor()->getProcessor()->getUniqueID() ==
+            SkASSERT(fDrawState->getGeometryProcessor()->getUniqueID() ==
                      fOriginalGPID);
             fOriginalGPID = SK_InvalidUniqueID;
         }
@@ -477,7 +466,7 @@ void GrDrawState::AutoRestoreEffects::set(GrDrawState* ds) {
     if (NULL != ds) {
         SkASSERT(SK_InvalidUniqueID == fOriginalGPID);
         if (NULL != ds->getGeometryProcessor()) {
-            fOriginalGPID = ds->getGeometryProcessor()->getProcessor()->getUniqueID();
+            fOriginalGPID = ds->getGeometryProcessor()->getUniqueID();
         }
         fColorEffectCnt = ds->numColorStages();
         fCoverageEffectCnt = ds->numCoverageStages();
@@ -515,14 +504,9 @@ void GrDrawState::AutoViewMatrixRestore::restore() {
         fDrawState->fViewMatrix = fViewMatrix;
         SkASSERT(fDrawState->numColorStages() >= fNumColorStages);
         int numCoverageStages = fSavedCoordChanges.count() - fNumColorStages;
-        numCoverageStages -= fHasGeometryProcessor ? 1 : 0;
         SkASSERT(fDrawState->numCoverageStages() >= numCoverageStages);
 
         int i = 0;
-        if (fHasGeometryProcessor) {
-            SkASSERT(fDrawState->hasGeometryProcessor());
-            fDrawState->fGeometryProcessor->restoreCoordChange(fSavedCoordChanges[i++]);
-        }
         for (int s = 0; s < fNumColorStages; ++s, ++i) {
             fDrawState->fColorStages[s].restoreCoordChange(fSavedCoordChanges[i]);
         }
@@ -568,7 +552,6 @@ bool GrDrawState::AutoViewMatrixRestore::setIdentity(GrDrawState* drawState) {
     if (0 == drawState->numTotalStages()) {
         drawState->fViewMatrix.reset();
         fDrawState = drawState;
-        fHasGeometryProcessor = false;
         fNumColorStages = 0;
         fSavedCoordChanges.reset(0);
         SkDEBUGCODE(++fDrawState->fBlockEffectRemovalCnt;)
@@ -590,13 +573,6 @@ void GrDrawState::AutoViewMatrixRestore::doEffectCoordChanges(const SkMatrix& co
     fSavedCoordChanges.reset(fDrawState->numTotalStages());
     int i = 0;
 
-    fHasGeometryProcessor = false;
-    if (fDrawState->hasGeometryProcessor()) {
-        fDrawState->fGeometryProcessor->saveCoordChange(&fSavedCoordChanges[i++]);
-        fDrawState->fGeometryProcessor->localCoordChange(coordChangeMatrix);
-        fHasGeometryProcessor = true;
-    }
-
     fNumColorStages = fDrawState->numColorStages();
     for (int s = 0; s < fNumColorStages; ++s, ++i) {
         fDrawState->getColorStage(s).saveCoordChange(&fSavedCoordChanges[i]);
@@ -619,7 +595,7 @@ void GrDrawState::convertToPendingExec() {
         fColorStages[i].convertToPendingExec();
     }
     if (fGeometryProcessor) {
-        fGeometryProcessor->convertToPendingExec();
+        fGeometryProcessor.convertToPendingExec();
     }
     for (int i = 0; i < fCoverageStages.count(); ++i) {
         fCoverageStages[i].convertToPendingExec();
index 03af7b532f2504231e90ca0bd5782a36b8dbd13f..d58d8c64e7f924b5e36dac9a698e1d37c01e7927 100644 (file)
@@ -221,7 +221,7 @@ public:
     const GrGeometryProcessor* setGeometryProcessor(const GrGeometryProcessor* geometryProcessor) {
         SkASSERT(geometryProcessor);
         SkASSERT(!this->hasGeometryProcessor());
-        fGeometryProcessor.reset(new GrGeometryStage(geometryProcessor));
+        fGeometryProcessor.reset(SkRef(geometryProcessor));
         this->invalidateOptState();
         return geometryProcessor;
     }
@@ -254,7 +254,7 @@ public:
     }
 
     bool hasGeometryProcessor() const { return SkToBool(fGeometryProcessor.get()); }
-    const GrGeometryStage* getGeometryProcessor() const { return fGeometryProcessor.get(); }
+    const GrGeometryProcessor* getGeometryProcessor() const { return fGeometryProcessor.get(); }
     const GrFragmentStage& getColorStage(int idx) const { return fColorStages[idx]; }
     const GrFragmentStage& getCoverageStage(int idx) const { return fCoverageStages[idx]; }
 
@@ -485,8 +485,7 @@ public:
         GrDrawState*                                           fDrawState;
         SkMatrix                                               fViewMatrix;
         int                                                    fNumColorStages;
-        bool                                                   fHasGeometryProcessor;
-        SkAutoSTArray<8, GrProcessorStage::SavedCoordChange>   fSavedCoordChanges;
+        SkAutoSTArray<8, GrFragmentStage::SavedCoordChange>    fSavedCoordChanges;
     };
 
     /// @}
@@ -810,10 +809,11 @@ private:
     GrBlendCoeff                        fSrcBlend;
     GrBlendCoeff                        fDstBlend;
 
-    typedef SkSTArray<4, GrFragmentStage>   FragmentStageArray;
-    SkAutoTDelete<GrGeometryStage>          fGeometryProcessor;
-    FragmentStageArray                      fColorStages;
-    FragmentStageArray                      fCoverageStages;
+    typedef SkSTArray<4, GrFragmentStage> FragmentStageArray;
+    typedef GrProgramElementRef<const GrGeometryProcessor> ProgramGeometryProcessor;
+    ProgramGeometryProcessor            fGeometryProcessor;
+    FragmentStageArray                  fColorStages;
+    FragmentStageArray                  fCoverageStages;
 
     uint32_t                            fHints;
 
index 7265f4d23ab0f388e537625880f376032e6f2af3..b144caf63e647e19520515da0816bc7f591d2633 100644 (file)
@@ -391,7 +391,7 @@ bool GrDrawTarget::checkDraw(GrPrimitiveType type, int startVertex,
     SkASSERT(drawState.getRenderTarget());
 
     if (drawState.hasGeometryProcessor()) {
-        const GrGeometryProcessor* gp = drawState.getGeometryProcessor()->getProcessor();
+        const GrGeometryProcessor* gp = drawState.getGeometryProcessor();
         int numTextures = gp->numTextures();
         for (int t = 0; t < numTextures; ++t) {
             GrTexture* texture = gp->texture(t);
index b3d90f7310204f7958a2a29fb42050e640c11a0c..7c8710f7d6466fd8d6432732c0af904132a2f0b4 100644 (file)
@@ -54,7 +54,7 @@ GrOptDrawState::GrOptDrawState(const GrDrawState& drawState,
 
     // Copy GeometryProcesssor from DS or ODS
     if (drawState.hasGeometryProcessor()) {
-        fGeometryProcessor.reset(SkNEW_ARGS(GrGeometryStage, (*drawState.getGeometryProcessor())));
+        fGeometryProcessor.initAndRef(drawState.fGeometryProcessor);
     } else {
         fGeometryProcessor.reset(NULL);
     }
@@ -305,8 +305,8 @@ void GrOptDrawState::getStageStats(const GrDrawState& ds, int firstColorStageIdx
         get_stage_stats(stage, &fReadsDst, &fReadsFragPosition);
     }
     if (ds.hasGeometryProcessor()) {
-        const GrGeometryStage& stage = *ds.getGeometryProcessor();
-        fReadsFragPosition = fReadsFragPosition || stage.getProcessor()->willReadFragmentPosition();
+        const GrGeometryProcessor& gp = *ds.getGeometryProcessor();
+        fReadsFragPosition = fReadsFragPosition || gp.willReadFragmentPosition();
     }
 }
 
@@ -354,9 +354,7 @@ bool GrOptDrawState::isEqual(const GrOptDrawState& that) const {
     if (this->hasGeometryProcessor()) {
         if (!that.hasGeometryProcessor()) {
             return false;
-        } else if (!GrProcessorStage::AreCompatible(*this->getGeometryProcessor(),
-                                                    *that.getGeometryProcessor(),
-                                                    explicitLocalCoords)) {
+        } else if (!this->getGeometryProcessor()->isEqual(*that.getGeometryProcessor())) {
             return false;
         }
     } else if (that.hasGeometryProcessor()) {
@@ -364,8 +362,8 @@ bool GrOptDrawState::isEqual(const GrOptDrawState& that) const {
     }
 
     for (int i = 0; i < this->numFragmentStages(); i++) {
-        if (!GrProcessorStage::AreCompatible(this->getFragmentStage(i), that.getFragmentStage(i),
-                                             explicitLocalCoords)) {
+        if (!GrFragmentStage::AreCompatible(this->getFragmentStage(i), that.getFragmentStage(i),
+                                            explicitLocalCoords)) {
             return false;
         }
     }
index 1c439bbff132e2d55fa822609f211d3e2bb73a00..f47913a41ae049b2b214ac166a1291f4c09bf3a2 100644 (file)
@@ -127,7 +127,7 @@ public:
     }
 
     bool hasGeometryProcessor() const { return SkToBool(fGeometryProcessor.get()); }
-    const GrGeometryStage* getGeometryProcessor() const { return fGeometryProcessor.get(); }
+    const GrGeometryProcessor* getGeometryProcessor() const { return fGeometryProcessor.get(); }
     const GrFragmentStage& getColorStage(int idx) const {
         SkASSERT(idx < this->numColorStages());
         return fFragmentStages[idx];
@@ -441,11 +441,12 @@ private:
     GrBlendCoeff                        fDstBlend;
 
     typedef SkSTArray<8, GrFragmentStage> FragmentStageArray;
-    SkAutoTDelete<GrGeometryStage>        fGeometryProcessor;
-    FragmentStageArray                    fFragmentStages;
+    typedef GrProgramElementRef<const GrGeometryProcessor> ProgramGeometryProcessor;
+    ProgramGeometryProcessor            fGeometryProcessor;
+    FragmentStageArray                  fFragmentStages;
 
     // This function is equivalent to the offset into fFragmentStages where coverage stages begin.
-    int                                   fNumColorStages;
+    int                                 fNumColorStages;
 
     // This is simply a different representation of info in fVertexAttribs and thus does
     // not need to be compared in op==.
index 71dfaae9129a7d819048636ef767d4c17eb34f45..1732e3a27a4f6239658d1c08f1e8ba23406882e3 100644 (file)
@@ -103,11 +103,6 @@ const char* GrProcessor::name() const {
     return this->getFactory().name();
 }
 
-void GrProcessor::addCoordTransform(const GrCoordTransform* transform) {
-    fCoordTransforms.push_back(transform);
-    SkDEBUGCODE(transform->setInEffect();)
-}
-
 void GrProcessor::addTextureAccess(const GrTextureAccess* access) {
     fTextureAccesses.push_back(access);
     this->addGpuResource(access->getProgramTexture());
@@ -123,10 +118,6 @@ void GrProcessor::operator delete(void* target) {
 
 #ifdef SK_DEBUG
 void GrProcessor::assertEquality(const GrProcessor& other) const {
-    SkASSERT(this->numTransforms() == other.numTransforms());
-    for (int i = 0; i < this->numTransforms(); ++i) {
-        SkASSERT(this->coordTransform(i) == other.coordTransform(i));
-    }
     SkASSERT(this->numTextures() == other.numTextures());
     for (int i = 0; i < this->numTextures(); ++i) {
         SkASSERT(this->textureAccess(i) == other.textureAccess(i));
@@ -173,5 +164,11 @@ bool GrProcessor::InvariantOutput::validPreMulColor() const {
     }
     return true;
 }
-#endif
+#endif // end DEBUG
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
 
+void GrFragmentProcessor::addCoordTransform(const GrCoordTransform* transform) {
+    fCoordTransforms.push_back(transform);
+    SkDEBUGCODE(transform->setInEffect();)
+}
index aa2c87482e55891a765e1798a1be59d9a2589224..8c65dce50616189f6ccf7c1b957573a622651f1b 100644 (file)
@@ -10,7 +10,7 @@
 
 #include "GrSingleTextureEffect.h"
 
-class GrProcessorStage;
+class GrFragmentStage;
 class GrGLConfigConversionEffect;
 
 /**
index 5f698325fbbe3d0d50811af0ae47bdf151a342be..04870779a3231cf2e32b0b87691b0cd5be6ad893 100644 (file)
@@ -114,6 +114,7 @@ public:
         @param samplers     Contains one entry for each GrTextureAccess of the GrProcessor. These
                             can be passed to the builder to emit texture reads in the generated
                             code.
+        TODO this should take a struct
         */
     virtual void emitCode(GrGLFPBuilder* builder,
                           const GrFragmentProcessor& effect,
index e0d4939323b0f2438944fcaad78712d7b6120d63..2216fb1c5a82b9a04f51184a089e6cbaf5f7df9d 100644 (file)
@@ -10,6 +10,7 @@
 #include "GrAllocator.h"
 #include "GrProcessor.h"
 #include "GrCoordTransform.h"
+#include "GrGLGeometryProcessor.h"
 #include "GrGLProcessor.h"
 #include "GrGpuGL.h"
 #include "GrGLPathRendering.h"
@@ -24,7 +25,7 @@
 /**
  * Retrieves the final matrix that a transform needs to apply to its source coords.
  */
-static SkMatrix get_transform_matrix(const GrProcessorStage& processorStage,
+static SkMatrix get_transform_matrix(const GrFragmentStage& processorStage,
                                      bool useExplicitLocalCoords,
                                      int transformIdx) {
     const GrCoordTransform& coordTransform =
@@ -59,17 +60,15 @@ GrGLProgram::GrGLProgram(GrGpuGL* gpu,
                          const BuiltinUniformHandles& builtinUniforms,
                          GrGLuint programID,
                          const UniformInfoArray& uniforms,
-                         GrGLInstalledProcessors* geometryProcessor,
-                         GrGLInstalledProcessors* colorProcessors,
-                         GrGLInstalledProcessors* coverageProcessors)
+                         GrGLInstalledGeoProc* geometryProcessor,
+                         GrGLInstalledFragProcs* fragmentProcessors)
     : fColor(GrColor_ILLEGAL)
     , fCoverage(GrColor_ILLEGAL)
     , fDstCopyTexUnit(-1)
     , fBuiltinUniformHandles(builtinUniforms)
     , fProgramID(programID)
-    , fGeometryProcessor(SkSafeRef(geometryProcessor))
-    , fColorEffects(SkRef(colorProcessors))
-    , fCoverageEffects(SkRef(coverageProcessors))
+    , fGeometryProcessor(geometryProcessor)
+    , fFragmentProcessors(SkRef(fragmentProcessors))
     , fDesc(desc)
     , fGpu(gpu)
     , fProgramDataManager(gpu, uniforms) {
@@ -96,28 +95,24 @@ void GrGLProgram::initSamplerUniforms() {
     if (fGeometryProcessor.get()) {
         this->initSamplers(fGeometryProcessor.get(), &texUnitIdx);
     }
-    this->initSamplers(fColorEffects.get(), &texUnitIdx);
-    this->initSamplers(fCoverageEffects.get(), &texUnitIdx);
+    int numProcs = fFragmentProcessors->fProcs.count();
+    for (int i = 0; i < numProcs; i++) {
+        this->initSamplers(fFragmentProcessors->fProcs[i], &texUnitIdx);
+    }
 }
 
-void GrGLProgram::initSamplers(GrGLInstalledProcessors* ip, int* texUnitIdx) {
-    int numEffects = ip->fGLProcessors.count();
-    SkASSERT(numEffects == ip->fSamplers.count());
-    for (int e = 0; e < numEffects; ++e) {
-        SkTArray<GrGLInstalledProcessors::Sampler, true>& samplers = ip->fSamplers[e];
-        int numSamplers = samplers.count();
-        for (int s = 0; s < numSamplers; ++s) {
-            SkASSERT(samplers[s].fUniform.isValid());
-            fProgramDataManager.setSampler(samplers[s].fUniform, *texUnitIdx);
-            samplers[s].fTextureUnit = (*texUnitIdx)++;
-        }
+void GrGLProgram::initSamplers(GrGLInstalledProc* ip, int* texUnitIdx) {
+    SkTArray<GrGLInstalledProc::Sampler, true>& samplers = ip->fSamplers;
+    int numSamplers = samplers.count();
+    for (int s = 0; s < numSamplers; ++s) {
+        SkASSERT(samplers[s].fUniform.isValid());
+        fProgramDataManager.setSampler(samplers[s].fUniform, *texUnitIdx);
+        samplers[s].fTextureUnit = (*texUnitIdx)++;
     }
 }
 
-void GrGLProgram::bindTextures(const GrGLInstalledProcessors* ip,
-                               const GrProcessor& processor,
-                               int effectIdx) {
-    const SkTArray<GrGLInstalledProcessors::Sampler, true>& samplers = ip->fSamplers[effectIdx];
+void GrGLProgram::bindTextures(const GrGLInstalledProc* ip, const GrProcessor& processor) {
+    const SkTArray<GrGLInstalledProc::Sampler, true>& samplers = ip->fSamplers;
     int numSamplers = samplers.count();
     SkASSERT(numSamplers == processor.numTextures());
     for (int s = 0; s < numSamplers; ++s) {
@@ -134,9 +129,6 @@ void GrGLProgram::bindTextures(const GrGLInstalledProcessors* ip,
 
 void GrGLProgram::setData(const GrOptDrawState& optState,
                           GrGpu::DrawType drawType,
-                          const GrGeometryStage* geometryProcessor,
-                          const GrFragmentStage* colorStages[],
-                          const GrFragmentStage* coverageStages[],
                           const GrDeviceCoordTexture* dstCopy,
                           SharedGLState* sharedState) {
     GrColor color = optState.getColor();
@@ -170,25 +162,34 @@ void GrGLProgram::setData(const GrOptDrawState& optState,
     // we set the textures, and uniforms for installed processors in a generic way, but subclasses
     // of GLProgram determine how to set coord transforms
     if (fGeometryProcessor.get()) {
-        SkASSERT(geometryProcessor);
-        this->setData<GrGeometryStage>(&geometryProcessor, fGeometryProcessor.get());
+        SkASSERT(optState.hasGeometryProcessor());
+        const GrGeometryProcessor& gp = *optState.getGeometryProcessor();
+        fGeometryProcessor->fGLProc->setData(fProgramDataManager, gp);
+        this->bindTextures(fGeometryProcessor, gp);
     }
-    this->setData<GrFragmentStage>(colorStages, fColorEffects.get());
-    this->setData<GrFragmentStage>(coverageStages, fCoverageEffects.get());
+    this->setFragmentData(optState);
 
     // Some of GrGLProgram subclasses need to update state here
     this->didSetData(drawType);
 }
 
-void GrGLProgram::setTransformData(const GrProcessorStage& processor,
-                                   int effectIdx,
-                                   GrGLInstalledProcessors* ip) {
-    SkTArray<GrGLInstalledProcessors::Transform, true>& transforms = ip->fTransforms[effectIdx];
+void GrGLProgram::setFragmentData(const GrOptDrawState& optState) {
+    int numProcessors = fFragmentProcessors->fProcs.count();
+    for (int e = 0; e < numProcessors; ++e) {
+        const GrFragmentStage& stage = optState.getFragmentStage(e);
+        const GrProcessor& processor = *stage.getProcessor();
+        fFragmentProcessors->fProcs[e]->fGLProc->setData(fProgramDataManager, processor);
+        this->setTransformData(stage, fFragmentProcessors->fProcs[e]);
+        this->bindTextures(fFragmentProcessors->fProcs[e], processor);
+    }
+}
+void GrGLProgram::setTransformData(const GrFragmentStage& processor, GrGLInstalledFragProc* ip) {
+    SkTArray<GrGLInstalledFragProc::Transform, true>& transforms = ip->fTransforms;
     int numTransforms = transforms.count();
     SkASSERT(numTransforms == processor.getProcessor()->numTransforms());
     for (int t = 0; t < numTransforms; ++t) {
         SkASSERT(transforms[t].fHandle.isValid());
-        const SkMatrix& matrix = get_transform_matrix(processor, ip->fHasExplicitLocalCoords, t);
+        const SkMatrix& matrix = get_transform_matrix(processor, ip->fLocalCoordAttrib, t);
         if (!transforms[t].fCurrentValue.cheapEqualTo(matrix)) {
             fProgramDataManager.setSkMatrix(transforms[t].fHandle.convertToUniformHandle(), matrix);
             transforms[t].fCurrentValue = matrix;
@@ -321,10 +322,8 @@ GrGLNvprProgramBase::GrGLNvprProgramBase(GrGpuGL* gpu,
                                          const BuiltinUniformHandles& builtinUniforms,
                                          GrGLuint programID,
                                          const UniformInfoArray& uniforms,
-                                         GrGLInstalledProcessors* colorProcessors,
-                                         GrGLInstalledProcessors* coverageProcessors)
-    : INHERITED(gpu, desc, builtinUniforms, programID, uniforms, NULL, colorProcessors,
-                coverageProcessors) {
+                                         GrGLInstalledFragProcs* fragmentProcessors)
+    : INHERITED(gpu, desc, builtinUniforms, programID, uniforms, NULL, fragmentProcessors) {
 }
 
 void GrGLNvprProgramBase::onSetMatrixAndRenderTargetHeight(GrGpu::DrawType drawType,
@@ -343,11 +342,9 @@ GrGLNvprProgram::GrGLNvprProgram(GrGpuGL* gpu,
                                  const BuiltinUniformHandles& builtinUniforms,
                                  GrGLuint programID,
                                  const UniformInfoArray& uniforms,
-                                 GrGLInstalledProcessors* colorProcessors,
-                                 GrGLInstalledProcessors* coverageProcessors,
+                                 GrGLInstalledFragProcs* fragmentProcessors,
                                  const SeparableVaryingInfoArray& separableVaryings)
-    : INHERITED(gpu, desc, builtinUniforms, programID, uniforms, colorProcessors,
-                coverageProcessors) {
+    : INHERITED(gpu, desc, builtinUniforms, programID, uniforms, fragmentProcessors) {
     int count = separableVaryings.count();
     fVaryings.push_back_n(count);
     for (int i = 0; i < count; i++) {
@@ -365,15 +362,13 @@ void GrGLNvprProgram::didSetData(GrGpu::DrawType drawType) {
     SkASSERT(GrGpu::IsPathRenderingDrawType(drawType));
 }
 
-void GrGLNvprProgram::setTransformData(const GrProcessorStage& processor,
-                                       int effectIdx,
-                                       GrGLInstalledProcessors* ip) {
-    SkTArray<GrGLInstalledProcessors::Transform, true>& transforms = ip->fTransforms[effectIdx];
+void GrGLNvprProgram::setTransformData(const GrFragmentStage& proc, GrGLInstalledFragProc* ip) {
+    SkTArray<GrGLInstalledFragProc::Transform, true>& transforms = ip->fTransforms;
     int numTransforms = transforms.count();
-    SkASSERT(numTransforms == processor.getProcessor()->numTransforms());
+    SkASSERT(numTransforms == proc.getProcessor()->numTransforms());
     for (int t = 0; t < numTransforms; ++t) {
         SkASSERT(transforms[t].fHandle.isValid());
-        const SkMatrix& transform = get_transform_matrix(processor, ip->fHasExplicitLocalCoords, t);
+        const SkMatrix& transform = get_transform_matrix(proc, ip->fLocalCoordAttrib, t);
         if (transforms[t].fCurrentValue.cheapEqualTo(transform)) {
             continue;
         }
@@ -392,15 +387,13 @@ void GrGLNvprProgram::setTransformData(const GrProcessorStage& processor,
 //////////////////////////////////////////////////////////////////////////////////////
 
 GrGLLegacyNvprProgram::GrGLLegacyNvprProgram(GrGpuGL* gpu,
-                                 const GrGLProgramDesc& desc,
-                                 const BuiltinUniformHandles& builtinUniforms,
-                                 GrGLuint programID,
-                                 const UniformInfoArray& uniforms,
-                                 GrGLInstalledProcessors* colorProcessors,
-                                 GrGLInstalledProcessors* coverageProcessors,
-                                 int texCoordSetCnt)
-    : INHERITED(gpu, desc, builtinUniforms, programID, uniforms, colorProcessors,
-                coverageProcessors)
+                                             const GrGLProgramDesc& desc,
+                                             const BuiltinUniformHandles& builtinUniforms,
+                                             GrGLuint programID,
+                                             const UniformInfoArray& uniforms,
+                                             GrGLInstalledFragProcs* fps,
+                                             int texCoordSetCnt)
+    : INHERITED(gpu, desc, builtinUniforms, programID, uniforms, fps)
     , fTexCoordSetCnt(texCoordSetCnt) {
 }
 
@@ -409,17 +402,16 @@ void GrGLLegacyNvprProgram::didSetData(GrGpu::DrawType drawType) {
     fGpu->glPathRendering()->flushPathTexGenSettings(fTexCoordSetCnt);
 }
 
-void GrGLLegacyNvprProgram::setTransformData(const GrProcessorStage& processorStage,
-                                       int effectIdx,
-                                       GrGLInstalledProcessors* ip) {
+void
+GrGLLegacyNvprProgram::setTransformData(const GrFragmentStage& proc, GrGLInstalledFragProc* ip) {
     // We've hidden the texcoord index in the first entry of the transforms array for each effect
-    int texCoordIndex = ip->fTransforms[effectIdx][0].fHandle.handle();
-    int numTransforms = processorStage.getProcessor()->numTransforms();
+    int texCoordIndex = ip->fTransforms[0].fHandle.handle();
+    int numTransforms = proc.getProcessor()->numTransforms();
     for (int t = 0; t < numTransforms; ++t) {
-        const SkMatrix& transform = get_transform_matrix(processorStage, false, t);
+        const SkMatrix& transform = get_transform_matrix(proc, false, t);
         GrGLPathRendering::PathTexGenComponents components =
                 GrGLPathRendering::kST_PathTexGenComponents;
-        if (processorStage.isPerspectiveCoordTransform(t, false)) {
+        if (proc.isPerspectiveCoordTransform(t, false)) {
             components = GrGLPathRendering::kSTR_PathTexGenComponents;
         }
         fGpu->glPathRendering()->enablePathTexGen(texCoordIndex++, components, transform);
index fc441e5d76f9fe3e123fc5dad53ae078e4ffc9db..e8aef35f1decd9e26885dde35d303ada4d564b30 100644 (file)
@@ -152,9 +152,6 @@ public:
      */
     void setData(const GrOptDrawState&,
                  GrGpu::DrawType,
-                 const GrGeometryStage* geometryProcessor,
-                 const GrFragmentStage* colorStages[],
-                 const GrFragmentStage* coverageStages[],
                  const GrDeviceCoordTexture* dstCopy, // can be NULL
                  SharedGLState*);
 
@@ -167,13 +164,12 @@ protected:
                 const BuiltinUniformHandles&,
                 GrGLuint programID,
                 const UniformInfoArray&,
-                GrGLInstalledProcessors* geometryProcessor,
-                GrGLInstalledProcessors* colorProcessors,
-                GrGLInstalledProcessors* coverageProcessors);
+                GrGLInstalledGeoProc* geometryProcessor,
+                GrGLInstalledFragProcs* fragmentProcessors);
 
     // Sets the texture units for samplers.
     void initSamplerUniforms();
-    void initSamplers(GrGLInstalledProcessors* processors, int* texUnitIdx);
+    void initSamplers(GrGLInstalledProc*, int* texUnitIdx);
 
     // Helper for setData(). Makes GL calls to specify the initial color when there is not
     // per-vertex colors.
@@ -184,23 +180,9 @@ protected:
     void setCoverage(const GrOptDrawState&, GrColor coverage, SharedGLState*);
 
     // A templated helper to loop over effects, set the transforms(via subclass) and bind textures
-    template <class ProcessorStage>
-    void setData(const ProcessorStage* effectStages[],
-                 GrGLInstalledProcessors* installedProcessors) {
-        int numEffects = installedProcessors->fGLProcessors.count();
-        SkASSERT(numEffects == installedProcessors->fTransforms.count());
-        SkASSERT(numEffects == installedProcessors->fSamplers.count());
-        for (int e = 0; e < numEffects; ++e) {
-            const GrProcessor& effect = *effectStages[e]->getProcessor();
-            installedProcessors->fGLProcessors[e]->setData(fProgramDataManager, effect);
-            this->setTransformData(*effectStages[e], e, installedProcessors);
-            this->bindTextures(installedProcessors, effect, e);
-        }
-    }
-    virtual void setTransformData(const GrProcessorStage& effectStage,
-                                  int effectIdx,
-                                  GrGLInstalledProcessors* pe);
-    void bindTextures(const GrGLInstalledProcessors*, const GrProcessor&, int effectIdx);
+    void setFragmentData(const GrOptDrawState&);
+    virtual void setTransformData(const GrFragmentStage& effectStage, GrGLInstalledFragProc* pe);
+    void bindTextures(const GrGLInstalledProc*, const GrProcessor&);
 
     /*
      * Legacy NVPR needs a hook here to flush path tex gen settings.
@@ -221,9 +203,8 @@ protected:
     GrGLuint fProgramID;
 
     // the installed effects
-    SkAutoTUnref<GrGLInstalledProcessors> fGeometryProcessor;
-    SkAutoTUnref<GrGLInstalledProcessors> fColorEffects;
-    SkAutoTUnref<GrGLInstalledProcessors> fCoverageEffects;
+    SkAutoTDelete<GrGLInstalledGeoProc> fGeometryProcessor;
+    SkAutoTUnref<GrGLInstalledFragProcs> fFragmentProcessors;
 
     GrGLProgramDesc fDesc;
     GrGpuGL* fGpu;
@@ -248,8 +229,7 @@ protected:
                         const BuiltinUniformHandles&,
                         GrGLuint programID,
                         const UniformInfoArray&,
-                        GrGLInstalledProcessors* colorProcessors,
-                        GrGLInstalledProcessors* coverageProcessors);
+                        GrGLInstalledFragProcs* fragmentProcessors);
     virtual void onSetMatrixAndRenderTargetHeight(GrGpu::DrawType, const GrOptDrawState&);
 
     typedef GrGLProgram INHERITED;
@@ -267,13 +247,10 @@ private:
                     const BuiltinUniformHandles&,
                     GrGLuint programID,
                     const UniformInfoArray&,
-                    GrGLInstalledProcessors* colorProcessors,
-                    GrGLInstalledProcessors* coverageProcessors,
+                    GrGLInstalledFragProcs* fragmentProcessors,
                     const SeparableVaryingInfoArray& separableVaryings);
     virtual void didSetData(GrGpu::DrawType) SK_OVERRIDE;
-    virtual void setTransformData(const GrProcessorStage&,
-                                  int effectIdx,
-                                  GrGLInstalledProcessors*) SK_OVERRIDE;
+    virtual void setTransformData(const GrFragmentStage&, GrGLInstalledFragProc*) SK_OVERRIDE;
 
     struct Varying {
         GrGLint     fLocation;
@@ -298,13 +275,10 @@ private:
                           const BuiltinUniformHandles&,
                           GrGLuint programID,
                           const UniformInfoArray&,
-                          GrGLInstalledProcessors* colorProcessors,
-                          GrGLInstalledProcessors* coverageProcessors,
+                          GrGLInstalledFragProcs* fragmentProcessors,
                           int texCoordSetCnt);
     virtual void didSetData(GrGpu::DrawType) SK_OVERRIDE;
-    virtual void setTransformData(const GrProcessorStage&,
-                                  int effectIdx,
-                                  GrGLInstalledProcessors*) SK_OVERRIDE;
+    virtual void setTransformData(const GrFragmentStage&, GrGLInstalledFragProc*) SK_OVERRIDE;
 
     int fTexCoordSetCnt;
 
index 0c85c99a8a4725659760dd60c92eba7ebeb154a9..224411e51c3d32fa882aefc5c660ff4483b59cc1 100644 (file)
@@ -60,10 +60,10 @@ static bool swizzle_requires_alpha_remapping(const GrGLCaps& caps,
     return false;
 }
 
-static uint32_t gen_attrib_key(const GrGeometryProcessor* effect) {
+static uint32_t gen_attrib_key(const GrGeometryProcessor& proc) {
     uint32_t key = 0;
 
-    const GrGeometryProcessor::VertexAttribArray& vars = effect->getVertexAttribs();
+    const GrGeometryProcessor::VertexAttribArray& vars = proc.getVertexAttribs();
     int numAttributes = vars.count();
     SkASSERT(numAttributes <= 2);
     for (int a = 0; a < numAttributes; ++a) {
@@ -73,7 +73,7 @@ static uint32_t gen_attrib_key(const GrGeometryProcessor* effect) {
     return key;
 }
 
-static uint32_t gen_transform_key(const GrProcessorStage& effectStage,
+static uint32_t gen_transform_key(const GrFragmentStage& effectStage,
                                   bool useExplicitLocalCoords) {
     uint32_t totalKey = 0;
     int numTransforms = effectStage.getProcessor()->numTransforms();
@@ -96,11 +96,11 @@ static uint32_t gen_transform_key(const GrProcessorStage& effectStage,
     return totalKey;
 }
 
-static uint32_t gen_texture_key(const GrProcessor* effect, const GrGLCaps& caps) {
+static uint32_t gen_texture_key(const GrProcessor& proc, const GrGLCaps& caps) {
     uint32_t key = 0;
-    int numTextures = effect->numTextures();
+    int numTextures = proc.numTextures();
     for (int t = 0; t < numTextures; ++t) {
-        const GrTextureAccess& access = effect->textureAccess(t);
+        const GrTextureAccess& access = proc.textureAccess(t);
         uint32_t configComponentMask = GrPixelConfigComponentMask(access.getTexture()->config());
         if (swizzle_requires_alpha_remapping(caps, configComponentMask, access.swizzleMask())) {
             key |= 1 << t;
@@ -115,101 +115,61 @@ static uint32_t gen_texture_key(const GrProcessor* effect, const GrGLCaps& caps)
  * in its key (e.g. the pixel format of textures used). So we create a meta-key for
  * every effect using this function. It is also responsible for inserting the effect's class ID
  * which must be different for every GrProcessor subclass. It can fail if an effect uses too many
- * textures, transforms, etc, for the space allotted in the meta-key.
+ * textures, transforms, etc, for the space allotted in the meta-key.  NOTE, both FPs and GPs share
+ * this function because it is hairy, though FPs do not have attribs, and GPs do not have transforms
  */
-
-static uint32_t* get_processor_meta_key(const GrProcessorStage& processorStage,
-                                        bool useExplicitLocalCoords,
-                                        const GrGLCaps& caps,
-                                        GrProcessorKeyBuilder* b) {
-
-    uint32_t textureKey = gen_texture_key(processorStage.getProcessor(), caps);
-    uint32_t transformKey = gen_transform_key(processorStage,useExplicitLocalCoords);
-    uint32_t classID = processorStage.getProcessor()->getFactory().effectClassID();
-
-    // Currently we allow 16 bits for each of the above portions of the meta-key. Fail if they
-    // don't fit.
-    static const uint32_t kMetaKeyInvalidMask = ~((uint32_t) SK_MaxU16);
-    if ((textureKey | transformKey | classID) & kMetaKeyInvalidMask) {
-        return NULL;
-    }
-
-    uint32_t* key = b->add32n(2);
-    key[0] = (textureKey << 16 | transformKey);
-    key[1] = (classID << 16);
-    return key;
-}
-
-static bool get_fp_key(const GrProcessorStage& stage,
-                       const GrGLCaps& caps,
-                       bool useExplicitLocalCoords,
-                       GrProcessorKeyBuilder* b,
-                       uint16_t* processorKeySize) {
-    const GrProcessor& effect = *stage.getProcessor();
-    const GrBackendProcessorFactory& factory = effect.getFactory();
-    factory.getGLProcessorKey(effect, caps, b);
-    size_t size = b->size();
-    if (size > SK_MaxU16) {
-        *processorKeySize = 0; // suppresses a warning.
-        return false;
-    }
-    *processorKeySize = SkToU16(size);
-    if (NULL == get_processor_meta_key(stage, useExplicitLocalCoords, caps, b)) {
-        return false;
-    }
-    return true;
-}
-
-static bool get_gp_key(const GrGeometryStage& stage,
-                       const GrGLCaps& caps,
-                       bool useExplicitLocalCoords,
-                       GrProcessorKeyBuilder* b,
-                       uint16_t* processorKeySize) {
-    const GrProcessor& effect = *stage.getProcessor();
-    const GrBackendProcessorFactory& factory = effect.getFactory();
-    factory.getGLProcessorKey(effect, caps, b);
+static bool get_meta_key(const GrProcessor& proc,
+                         const GrGLCaps& caps,
+                         uint32_t transformKey,
+                         uint32_t attribKey,
+                         GrProcessorKeyBuilder* b,
+                         uint16_t* processorKeySize) {
+    const GrBackendProcessorFactory& factory = proc.getFactory();
+    factory.getGLProcessorKey(proc, caps, b);
     size_t size = b->size();
     if (size > SK_MaxU16) {
         *processorKeySize = 0; // suppresses a warning.
         return false;
     }
     *processorKeySize = SkToU16(size);
-    uint32_t* key = get_processor_meta_key(stage, useExplicitLocalCoords, caps, b);
-    if (NULL == key) {
-        return false;
-    }
-    uint32_t attribKey = gen_attrib_key(stage.getProcessor());
+    uint32_t textureKey = gen_texture_key(proc, caps);
+    uint32_t classID = proc.getFactory().effectClassID();
 
     // Currently we allow 16 bits for each of the above portions of the meta-key. Fail if they
     // don't fit.
     static const uint32_t kMetaKeyInvalidMask = ~((uint32_t) SK_MaxU16);
-    if ((attribKey) & kMetaKeyInvalidMask) {
-       return false;
+    if ((textureKey | transformKey | classID) & kMetaKeyInvalidMask) {
+        return false;
     }
 
-    key[1] |= attribKey;
+    uint32_t* key = b->add32n(2);
+    key[0] = (textureKey << 16 | transformKey);
+    key[1] = (classID << 16);
     return true;
 }
 
 struct GeometryProcessorKeyBuilder {
-    typedef GrGeometryStage StagedProcessor;
-    static bool GetProcessorKey(const GrGeometryStage& gpStage,
+    typedef GrGeometryProcessor StagedProcessor;
+    static bool GetProcessorKey(const GrGeometryProcessor& gp,
                                 const GrGLCaps& caps,
-                                bool requiresLocalCoordAttrib,
+                                bool,
                                 GrProcessorKeyBuilder* b,
-                                uint16_t* processorKeySize) {
-        return get_gp_key(gpStage, caps, requiresLocalCoordAttrib, b, processorKeySize);
+                                uint16_t* keySize) {
+        /* 0 because no transforms on a GP */
+        return get_meta_key(gp, caps, 0, gen_attrib_key(gp), b, keySize);
     }
 };
 
 struct FragmentProcessorKeyBuilder {
     typedef GrFragmentStage StagedProcessor;
-    static bool GetProcessorKey(const GrFragmentStage& fpStage,
+    static bool GetProcessorKey(const GrFragmentStage& fps,
                                 const GrGLCaps& caps,
-                                bool requiresLocalCoordAttrib,
+                                bool useLocalCoords,
                                 GrProcessorKeyBuilder* b,
-                                uint16_t* processorKeySize) {
-        return get_fp_key(fpStage, caps, requiresLocalCoordAttrib, b, processorKeySize);
+                                uint16_t* keySize) {
+        /* 0 because no attribs on a fP */
+        return get_meta_key(*fps.getProcessor(), caps, gen_transform_key(fps, useLocalCoords), 0,
+                            b, keySize);
     }
 };
 
@@ -242,17 +202,9 @@ GrGLProgramDesc::BuildStagedProcessorKey(const typename ProcessorKeyBuilder::Sta
 
 bool GrGLProgramDesc::Build(const GrOptDrawState& optState,
                             GrGpu::DrawType drawType,
-                            GrBlendCoeff srcCoeff,
-                            GrBlendCoeff dstCoeff,
                             GrGpuGL* gpu,
                             const GrDeviceCoordTexture* dstCopy,
-                            const GrGeometryStage** geometryProcessor,
-                            SkTArray<const GrFragmentStage*, true>* colorStages,
-                            SkTArray<const GrFragmentStage*, true>* coverageStages,
                             GrGLProgramDesc* desc) {
-    colorStages->reset();
-    coverageStages->reset();
-
     bool inputColorIsUsed = optState.inputColorIsUsed();
     bool inputCoverageIsUsed = optState.inputCoverageIsUsed();
 
@@ -274,29 +226,17 @@ bool GrGLProgramDesc::Build(const GrOptDrawState& optState,
 
     // We can only have one effect which touches the vertex shader
     if (optState.hasGeometryProcessor()) {
-        const GrGeometryStage& gpStage = *optState.getGeometryProcessor();
-        if (!BuildStagedProcessorKey<GeometryProcessorKeyBuilder>(gpStage,
+        if (!BuildStagedProcessorKey<GeometryProcessorKeyBuilder>(*optState.getGeometryProcessor(),
                                                                   gpu->glCaps(),
-                                                                  requiresLocalCoordAttrib,
+                                                                  false,
                                                                   desc,
                                                                   &offsetAndSizeIndex)) {
             return false;
         }
-        *geometryProcessor = &gpStage;
     }
 
-    for (int s = 0; s < optState.numColorStages(); ++s) {
-        if (!BuildStagedProcessorKey<FragmentProcessorKeyBuilder>(optState.getColorStage(s),
-                                                                  gpu->glCaps(),
-                                                                  requiresLocalCoordAttrib,
-                                                                  desc,
-                                                                  &offsetAndSizeIndex)) {
-            return false;
-        }
-    }
-
-    for (int s = 0; s < optState.numCoverageStages(); ++s) {
-        if (!BuildStagedProcessorKey<FragmentProcessorKeyBuilder>(optState.getCoverageStage(s),
+    for (int s = 0; s < optState.numFragmentStages(); ++s) {
+        if (!BuildStagedProcessorKey<FragmentProcessorKeyBuilder>(optState.getFragmentStage(s),
                                                                   gpu->glCaps(),
                                                                   requiresLocalCoordAttrib,
                                                                   desc,
@@ -399,15 +339,8 @@ bool GrGLProgramDesc::Build(const GrOptDrawState& optState,
     header->fPrimaryOutputType = optState.getPrimaryOutputType();
     header->fSecondaryOutputType = optState.getSecondaryOutputType();
 
-    for (int s = 0; s < optState.numColorStages(); ++s) {
-        colorStages->push_back(&optState.getColorStage(s));
-    }
-    for (int s = 0; s < optState.numCoverageStages(); ++s) {
-        coverageStages->push_back(&optState.getCoverageStage(s));
-    }
-
-    header->fColorEffectCnt = colorStages->count();
-    header->fCoverageEffectCnt = coverageStages->count();
+    header->fColorEffectCnt = optState.numColorStages();
+    header->fCoverageEffectCnt = optState.numCoverageStages();
     desc->finalize();
     return true;
 }
index 9bf7553b61cfede488dd9b15283302a23f2aedd0..4e1be5b2f9c0d1127b62c134bfdc2471a17bb55d 100644 (file)
@@ -43,13 +43,8 @@ public:
      */
     static bool Build(const GrOptDrawState&,
                       GrGpu::DrawType,
-                      GrBlendCoeff srcCoeff,
-                      GrBlendCoeff dstCoeff,
                       GrGpuGL*,
-                      const GrDeviceCoordTexture* dstCopy,
-                      const GrGeometryStage** geometryProcessor,
-                      SkTArray<const GrFragmentStage*, true>* colorStages,
-                      SkTArray<const GrFragmentStage*, true>* coverageStages,
+                      const GrDeviceCoordTexture*,
                       GrGLProgramDesc*);
 
     bool hasGeometryProcessor() const {
@@ -160,26 +155,23 @@ private:
     const KeyHeader& getHeader() const { return *this->atOffset<KeyHeader, kHeaderOffset>(); }
 
     /** Used to provide effects' keys to their emitCode() function. */
-    class EffectKeyProvider {
+    class ProcKeyProvider {
     public:
-        enum EffectType {
-            kGeometryProcessor_EffectType,
-            kColor_EffectType,
-            kCoverage_EffectType,
+        enum ProcessorType {
+            kGeometry_ProcessorType,
+            kFragment_ProcessorType,
         };
 
-        EffectKeyProvider(const GrGLProgramDesc* desc, EffectType type) : fDesc(desc) {
+        ProcKeyProvider(const GrGLProgramDesc* desc, ProcessorType type)
+            : fDesc(desc), fBaseIndex(0) {
             switch (type) {
-                case kGeometryProcessor_EffectType:
+                case kGeometry_ProcessorType:
                     // there can be only one
                     fBaseIndex = 0;
                     break;
-                case kColor_EffectType:
+                case kFragment_ProcessorType:
                     fBaseIndex = desc->hasGeometryProcessor() ? 1 : 0;
                     break;
-                case kCoverage_EffectType:
-                    fBaseIndex = desc->numColorEffects() + (desc->hasGeometryProcessor() ? 1 : 0);
-                    break;
             }
         }
 
index 056f0935eca6a1db4d235827ab076ea391ec8c7d..24ab4ec14d6a941803e84c8e88b035b522151a2c 100644 (file)
@@ -181,10 +181,7 @@ private:
         void abandon();
         GrGLProgram* getProgram(const GrOptDrawState&,
                                 const GrGLProgramDesc&,
-                                DrawType,
-                                const GrGeometryStage* geometryProcessor,
-                                const GrFragmentStage* colorStages[],
-                                const GrFragmentStage* coverageStages[]);
+                                DrawType);
 
     private:
         enum {
index 7dba5316a4e7afee640b9c4402ca2e1b07129148..6a09ebf64e1564d03e0d54cd7cfed199630610d4 100644 (file)
@@ -93,10 +93,7 @@ int GrGpuGL::ProgramCache::search(const GrGLProgramDesc& desc) const {
 
 GrGLProgram* GrGpuGL::ProgramCache::getProgram(const GrOptDrawState& optState,
                                                const GrGLProgramDesc& desc,
-                                               DrawType type,
-                                               const GrGeometryStage* geometryProcessor,
-                                               const GrFragmentStage* colorStages[],
-                                               const GrFragmentStage* coverageStages[]) {
+                                               DrawType type) {
 #ifdef PROGRAM_CACHE_STATS
     ++fTotalRequests;
 #endif
@@ -131,9 +128,7 @@ GrGLProgram* GrGpuGL::ProgramCache::getProgram(const GrOptDrawState& optState,
 #ifdef PROGRAM_CACHE_STATS
         ++fCacheMisses;
 #endif
-        GrGLProgram* program = GrGLProgramBuilder::CreateProgram(optState, desc, type,
-                                                                 geometryProcessor, colorStages,
-                                                                 coverageStages, fGpu);
+        GrGLProgram* program = GrGLProgramBuilder::CreateProgram(optState, desc, type, fGpu);
         if (NULL == program) {
             return NULL;
         }
@@ -237,30 +232,13 @@ bool GrGpuGL::flushGraphicsState(DrawType type, const GrDeviceCoordTexture* dstC
             return false;
         }
 
-        const GrGeometryStage* geometryProcessor = NULL;
-        SkSTArray<8, const GrFragmentStage*, true> colorStages;
-        SkSTArray<8, const GrFragmentStage*, true> coverageStages;
         GrGLProgramDesc desc;
-        if (!GrGLProgramDesc::Build(*optState.get(),
-                                    type,
-                                    srcCoeff,
-                                    dstCoeff,
-                                    this,
-                                    dstCopy,
-                                    &geometryProcessor,
-                                    &colorStages,
-                                    &coverageStages,
-                                    &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,
-                                                        geometryProcessor,
-                                                        colorStages.begin(),
-                                                        coverageStages.begin()));
+        fCurrentProgram.reset(fProgramCache->getProgram(*optState.get(), desc, type));
         if (NULL == fCurrentProgram.get()) {
             SkDEBUGFAIL("Failed to create program!");
             return false;
@@ -276,13 +254,7 @@ bool GrGpuGL::flushGraphicsState(DrawType type, const GrDeviceCoordTexture* dstC
 
         this->flushBlend(*optState.get(), kDrawLines_DrawType == type, srcCoeff, dstCoeff);
 
-        fCurrentProgram->setData(*optState.get(),
-                                 type,
-                                 geometryProcessor,
-                                 colorStages.begin(),
-                                 coverageStages.begin(),
-                                 dstCopy,
-                                 &fSharedGLProgramState);
+        fCurrentProgram->setData(*optState.get(), type, dstCopy, &fSharedGLProgramState);
     }
 
     GrGLRenderTarget* glRT = static_cast<GrGLRenderTarget*>(optState->getRenderTarget());
index acb4af10be10e3dcdcc0ec104eae58b0fd8d1f70..1c1cb421223b366747058be5cd3775d8cd9e0e67 100644 (file)
@@ -24,20 +24,17 @@ int GrGLLegacyNvprProgramBuilder::addTexCoordSets(int count) {
     return firstFreeCoordSet;
 }
 
-void GrGLLegacyNvprProgramBuilder::emitTransforms(const GrProcessorStage& processorStage,
+void GrGLLegacyNvprProgramBuilder::emitTransforms(const GrFragmentStage& processorStage,
                                             GrGLProcessor::TransformedCoordsArray* outCoords,
-                                            GrGLInstalledProcessors* installedProcessors) {
+                                            GrGLInstalledFragProc* ifp) {
     int numTransforms = processorStage.getProcessor()->numTransforms();
     int texCoordIndex = this->addTexCoordSets(numTransforms);
 
-    SkTArray<GrGLInstalledProcessors::Transform, true>& transforms =
-            installedProcessors->addTransforms();
-
     // Use the first uniform location as the texcoord index.  This may seem a bit hacky but it
     // allows us to use one program effects object for all of our programs which really simplifies
     // the code overall
-    transforms.push_back_n(1);
-    transforms[0].fHandle = GrGLInstalledProcessors::ShaderVarHandle(texCoordIndex);
+    ifp->fTransforms.push_back_n(1);
+    ifp->fTransforms[0].fHandle = GrGLInstalledFragProc::ShaderVarHandle(texCoordIndex);
 
     SkString name;
     for (int t = 0; t < numTransforms; ++t) {
@@ -51,5 +48,5 @@ void GrGLLegacyNvprProgramBuilder::emitTransforms(const GrProcessorStage& proces
 
 GrGLProgram* GrGLLegacyNvprProgramBuilder::createProgram(GrGLuint programID) {
     return SkNEW_ARGS(GrGLLegacyNvprProgram, (fGpu, fDesc, fUniformHandles, programID, fUniforms,
-                                        fColorEffects, fCoverageEffects,  fTexCoordSetCnt));
+                                              fFragmentProcessors.get(),  fTexCoordSetCnt));
 }
index 496fbd872643a9dbb6c9357ed2c77905397bd8ce..dabec081b4e914c7a0ef83a1b96d85552864dd9a 100644 (file)
@@ -18,9 +18,9 @@ public:
 
 private:
     int addTexCoordSets(int count);
-    void emitTransforms(const GrProcessorStage&,
+    void emitTransforms(const GrFragmentStage&,
                         GrGLProcessor::TransformedCoordsArray* outCoords,
-                        GrGLInstalledProcessors*);
+                        GrGLInstalledFragProc*);
 
     int fTexCoordSetCnt;
 
index e5eae9d884cd8014cc0406946c1b37d0e20bfb31..a20b0d6b0d87ea7110b2ee0d0e8238dd8d0037d5 100644 (file)
@@ -18,15 +18,13 @@ GrGLNvprProgramBuilder::GrGLNvprProgramBuilder(GrGpuGL* gpu,
         , fSeparableVaryingInfos(kVarsPerBlock) {
 }
 
-void GrGLNvprProgramBuilder::emitTransforms(const GrProcessorStage& processorStage,
+void GrGLNvprProgramBuilder::emitTransforms(const GrFragmentStage& processorStage,
                                             GrGLProcessor::TransformedCoordsArray* outCoords,
-                                            GrGLInstalledProcessors* installedProcessors) {
-    const GrProcessor* effect = processorStage.getProcessor();
+                                            GrGLInstalledFragProc* ifp) {
+    const GrFragmentProcessor* effect = processorStage.getProcessor();
     int numTransforms = effect->numTransforms();
 
-    SkTArray<GrGLInstalledProcessors::Transform, true>& transforms =
-            installedProcessors->addTransforms();
-    transforms.push_back_n(numTransforms);
+    ifp->fTransforms.push_back_n(numTransforms);
 
     for (int t = 0; t < numTransforms; t++) {
         GrSLType varyingType =
@@ -43,24 +41,24 @@ void GrGLNvprProgramBuilder::emitTransforms(const GrProcessorStage& processorSta
         }
         const char* vsVaryingName;
         const char* fsVaryingName;
-        transforms[t].fHandle = this->addSeparableVarying(varyingType, varyingName,
-                                                          &vsVaryingName, &fsVaryingName);
-        transforms[t].fType = varyingType;
+        ifp->fTransforms[t].fHandle = this->addSeparableVarying(varyingType, varyingName,
+                                                                &vsVaryingName, &fsVaryingName);
+        ifp->fTransforms[t].fType = varyingType;
 
         SkNEW_APPEND_TO_TARRAY(outCoords, GrGLProcessor::TransformedCoords,
                                (SkString(fsVaryingName), varyingType));
     }
 }
 
-GrGLInstalledProcessors::ShaderVarHandle
+GrGLInstalledFragProc::ShaderVarHandle
 GrGLNvprProgramBuilder::addSeparableVarying(GrSLType type,
-                                              const char* name,
-                                              const char** vsOutName,
-                                              const char** fsInName) {
+                                            const char* name,
+                                            const char** vsOutName,
+                                            const char** fsInName) {
     addVarying(type, name, vsOutName, fsInName);
     SeparableVaryingInfo& varying = fSeparableVaryingInfos.push_back();
     varying.fVariable = fFS.fInputs.back();
-    return GrGLInstalledProcessors::ShaderVarHandle(fSeparableVaryingInfos.count() - 1);
+    return GrGLInstalledFragProc::ShaderVarHandle(fSeparableVaryingInfos.count() - 1);
 }
 
 void GrGLNvprProgramBuilder::resolveSeparableVaryings(GrGLuint programId) {
@@ -80,5 +78,5 @@ GrGLProgram* GrGLNvprProgramBuilder::createProgram(GrGLuint programID) {
     // building
     this->resolveSeparableVaryings(programID);
     return SkNEW_ARGS(GrGLNvprProgram, (fGpu, fDesc, fUniformHandles, programID, fUniforms,
-                                        fColorEffects, fCoverageEffects, fSeparableVaryingInfos));
+                                        fFragmentProcessors.get(), fSeparableVaryingInfos));
 }
index cb1337521d9a6327b08c61a5abd3e20078ed3322..4bf7e02414ca5bb0d178a2d4992d6c672c4d784e 100644 (file)
@@ -28,11 +28,11 @@ public:
     virtual GrGLProgram* createProgram(GrGLuint programID);
 
 private:
-    virtual void emitTransforms(const GrProcessorStage&,
+    virtual void emitTransforms(const GrFragmentStage&,
                                 GrGLProcessor::TransformedCoordsArray* outCoords,
-                                GrGLInstalledProcessors*) SK_OVERRIDE;
+                                GrGLInstalledFragProc*) SK_OVERRIDE;
 
-    typedef GrGLInstalledProcessors::ShaderVarHandle ShaderVarHandle;
+    typedef GrGLInstalledFragProc::ShaderVarHandle ShaderVarHandle;
 
     /**
      * Add a separable varying input variable to the current program.
index fbf78d763464a3b0175fff9d60474c5db0beaa7f..687c2fd4c927331ff7efb662ed53ae4728a0219b 100644 (file)
@@ -32,16 +32,13 @@ const int GrGLProgramBuilder::kVarsPerBlock = 8;
 GrGLProgram* GrGLProgramBuilder::CreateProgram(const GrOptDrawState& optState,
                                                const GrGLProgramDesc& desc,
                                                GrGpu::DrawType drawType,
-                                               const GrGeometryStage* geometryProcessor,
-                                               const GrFragmentStage* colorStages[],
-                                               const GrFragmentStage* coverageStages[],
                                                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,
                                                                    drawType,
-                                                                   SkToBool(geometryProcessor),
+                                                                   optState.hasGeometryProcessor(),
                                                                    gpu));
 
     GrGLProgramBuilder* pb = builder.get();
@@ -74,8 +71,7 @@ GrGLProgram* GrGLProgramBuilder::CreateProgram(const GrOptDrawState& optState,
         }
     }
 
-    pb->createAndEmitProcessors(geometryProcessor, colorStages, coverageStages, &inputColor,
-                                &inputCoverage);
+    pb->emitAndInstallProcs(optState, &inputColor, &inputCoverage);
 
     if (hasVertexShader) {
         pb->fVS.transformSkiaToGLCoords();
@@ -116,13 +112,15 @@ GrGLProgramBuilder::CreateProgramBuilder(const GrGLProgramDesc& desc,
 
 /////////////////////////////////////////////////////////////////////////////
 
-GrGLProgramBuilder::GrGLProgramBuilder(GrGpuGL* gpu, const GrOptDrawState& optState,
+GrGLProgramBuilder::GrGLProgramBuilder(GrGpuGL* gpu,
+                                       const GrOptDrawState& optState,
                                        const GrGLProgramDesc& desc)
     : fVS(this)
     , fGS(this)
     , fFS(this, desc)
     , fOutOfStage(true)
     , fStageIndex(-1)
+    , fGeometryProcessor(NULL)
     , fOptState(optState)
     , fDesc(desc)
     , fGpu(gpu)
@@ -225,104 +223,106 @@ void GrGLProgramBuilder::setupUniformColorAndCoverageIfNeeded(GrGLSLExpr4* input
     }
 }
 
-void GrGLProgramBuilder::createAndEmitProcessors(const GrGeometryStage* geometryProcessor,
-                                                 const GrFragmentStage* colorStages[],
-                                                 const GrFragmentStage* coverageStages[],
-                                                 GrGLSLExpr4* inputColor,
-                                                 GrGLSLExpr4* inputCoverage) {
-    bool useLocalCoords = fVS.hasExplicitLocalCoords();
-
-    EffectKeyProvider colorKeyProvider(&fDesc, EffectKeyProvider::kColor_EffectType);
-    int numColorEffects = fDesc.numColorEffects();
-    GrGLInstalledProcessors* ip = SkNEW_ARGS(GrGLInstalledProcessors, (numColorEffects,
-                                                                       useLocalCoords));
-    this->createAndEmitProcessors<GrFragmentStage>(colorStages, numColorEffects, colorKeyProvider,
-                                                   inputColor, ip);
-    fColorEffects.reset(ip);
-
-    if (geometryProcessor) {
-        fVS.emitAttributes(*geometryProcessor->getProcessor());
-        EffectKeyProvider gpKeyProvider(&fDesc, EffectKeyProvider::kGeometryProcessor_EffectType);
-        ip = SkNEW_ARGS(GrGLInstalledProcessors, (1, useLocalCoords));
-        this->createAndEmitProcessors<GrGeometryStage>(&geometryProcessor, 1, gpKeyProvider,
-                                                       inputCoverage, ip);
-        fGeometryProcessor.reset(ip);
+void GrGLProgramBuilder::emitAndInstallProcs(const GrOptDrawState& optState,
+                                             GrGLSLExpr4* inputColor,
+                                             GrGLSLExpr4* inputCoverage) {
+    fFragmentProcessors.reset(SkNEW(GrGLInstalledFragProcs));
+    int numProcs = optState.numFragmentStages();
+    this->emitAndInstallFragProcs(0, optState.numColorStages(), inputColor);
+    if (optState.hasGeometryProcessor()) {
+        const GrGeometryProcessor& gp = *optState.getGeometryProcessor();
+        fVS.emitAttributes(gp);
+        ProcKeyProvider keyProvider(&fDesc, ProcKeyProvider::kGeometry_ProcessorType);
+        GrGLSLExpr4 output;
+        this->emitAndInstallProc<GrGeometryProcessor>(gp, 0, keyProvider, *inputCoverage, &output);
+        *inputCoverage = output;
     }
+    this->emitAndInstallFragProcs(optState.numColorStages(), numProcs,  inputCoverage);
+}
 
-    EffectKeyProvider coverageKeyProvider(&fDesc, EffectKeyProvider::kCoverage_EffectType);
-    int numCoverageEffects = fDesc.numCoverageEffects();
-    ip = SkNEW_ARGS(GrGLInstalledProcessors, (numCoverageEffects, useLocalCoords));
-    this->createAndEmitProcessors<GrFragmentStage>(coverageStages, numCoverageEffects,
-                                                   coverageKeyProvider, inputCoverage, ip);
-    fCoverageEffects.reset(ip);
+void GrGLProgramBuilder::emitAndInstallFragProcs(int procOffset, int numProcs, GrGLSLExpr4* inOut) {
+    ProcKeyProvider keyProvider(&fDesc, ProcKeyProvider::kFragment_ProcessorType);
+    for (int e = procOffset; e < numProcs; ++e) {
+        GrGLSLExpr4 output;
+        const GrFragmentStage& stage = fOptState.getFragmentStage(e);
+        this->emitAndInstallProc<GrFragmentStage>(stage, e, keyProvider, *inOut, &output);
+        *inOut = output;
+    }
 }
 
-template <class ProcessorStage>
-void GrGLProgramBuilder::createAndEmitProcessors(const ProcessorStage* processStages[],
-                                                 int effectCnt,
-                                                 const EffectKeyProvider& keyProvider,
-                                                 GrGLSLExpr4* fsInOutColor,
-                                                 GrGLInstalledProcessors* installedProcessors) {
-    bool effectEmitted = false;
-
-    GrGLSLExpr4 inColor = *fsInOutColor;
-    GrGLSLExpr4 outColor;
-
-    for (int e = 0; e < effectCnt; ++e) {
-        // Program builders have a bit of state we need to clear with each effect
-        AutoStageAdvance adv(this);
-        const ProcessorStage& stage = *processStages[e];
-        SkASSERT(stage.getProcessor());
-
-        if (inColor.isZeros()) {
-            SkString inColorName;
-
-            // Effects have no way to communicate zeros, they treat an empty string as ones.
-            this->nameVariable(&inColorName, '\0', "input");
-            fFS.codeAppendf("vec4 %s = %s;", inColorName.c_str(), inColor.c_str());
-            inColor = inColorName;
-        }
+// TODO Processors cannot output zeros because an empty string is all 1s
+// the fix is to allow effects to take the GrGLSLExpr4 directly
+template <class Proc>
+void GrGLProgramBuilder::emitAndInstallProc(const Proc& proc,
+                                            int index,
+                                            const ProcKeyProvider keyProvider,
+                                            const GrGLSLExpr4& input,
+                                            GrGLSLExpr4* output) {
+    // Program builders have a bit of state we need to clear with each effect
+    AutoStageAdvance adv(this);
+
+    // create var to hold stage result
+    SkString outColorName;
+    this->nameVariable(&outColorName, '\0', "output");
+    fFS.codeAppendf("vec4 %s;", outColorName.c_str());
+    *output = outColorName;
+
+    // Enclose custom code in a block to avoid namespace conflicts
+    SkString openBrace;
+    openBrace.printf("{ // Stage %d\n", fStageIndex);
+    fFS.codeAppend(openBrace.c_str());
+
+    this->emitAndInstallProc(proc, keyProvider.get(index), output->c_str(),
+                             input.isOnes() ? NULL : input.c_str());
+
+    fFS.codeAppend("}");
+}
 
-        // create var to hold stage result
-        SkString outColorName;
-        this->nameVariable(&outColorName, '\0', "output");
-        fFS.codeAppendf("vec4 %s;", outColorName.c_str());
-        outColor = outColorName;
-
-        SkASSERT(installedProcessors);
-        const typename ProcessorStage::Processor& processor = *stage.getProcessor();
-        SkSTArray<2, GrGLProcessor::TransformedCoords> coords(processor.numTransforms());
-        SkSTArray<4, GrGLProcessor::TextureSampler> samplers(processor.numTextures());
-
-        this->emitTransforms(stage, &coords, installedProcessors);
-        this->emitSamplers(processor, &samplers, installedProcessors);
-
-        typename ProcessorStage::GLProcessor* glEffect =
-                processor.getFactory().createGLInstance(processor);
-        installedProcessors->addEffect(glEffect);
-
-        // Enclose custom code in a block to avoid namespace conflicts
-        SkString openBrace;
-        openBrace.printf("{ // Stage %d: %s\n", fStageIndex, glEffect->name());
-        fFS.codeAppend(openBrace.c_str());
-        fVS.codeAppend(openBrace.c_str());
-
-        glEffect->emitCode(this, processor, keyProvider.get(e), outColor.c_str(),
-                           inColor.isOnes() ? NULL : inColor.c_str(), coords, samplers);
-
-        // We have to check that effects and the code they emit are consistent, ie if an effect
-        // asks for dst color, then the emit code needs to follow suit
-        verify(processor);
-        fFS.codeAppend("}");
-        fVS.codeAppend("}");
-
-        inColor = outColor;
-        effectEmitted = true;
-    }
+void GrGLProgramBuilder::emitAndInstallProc(const GrFragmentStage& fs,
+                                            const GrProcessorKey& key,
+                                            const char* outColor,
+                                            const char* inColor) {
+    GrGLInstalledFragProc* ifp = SkNEW_ARGS(GrGLInstalledFragProc, (fVS.hasLocalCoords()));
 
-    if (effectEmitted) {
-        *fsInOutColor = outColor;
-    }
+    const GrFragmentProcessor& fp = *fs.getProcessor();
+    ifp->fGLProc = fp.getFactory().createGLInstance(fp);
+
+    SkSTArray<4, GrGLProcessor::TextureSampler> samplers(fp.numTextures());
+    this->emitSamplers(fp, &samplers, ifp);
+
+    // Fragment processors can have coord transforms
+    SkSTArray<2, GrGLProcessor::TransformedCoords> coords(fp.numTransforms());
+    this->emitTransforms(fs, &coords, ifp);
+
+    ifp->fGLProc->emitCode(this, fp, key, outColor, inColor, coords, samplers);
+
+    // We have to check that effects and the code they emit are consistent, ie if an effect
+    // asks for dst color, then the emit code needs to follow suit
+    verify(fp);
+    fFragmentProcessors->fProcs.push_back(ifp);
+}
+
+void GrGLProgramBuilder::emitAndInstallProc(const GrGeometryProcessor& gp,
+                                            const GrProcessorKey& key,
+                                            const char* outColor,
+                                            const char* inColor) {
+    SkASSERT(!fGeometryProcessor);
+    fGeometryProcessor = SkNEW(GrGLInstalledGeoProc);
+
+    fGeometryProcessor->fGLProc = gp.getFactory().createGLInstance(gp);
+
+    SkSTArray<4, GrGLProcessor::TextureSampler> samplers(gp.numTextures());
+    this->emitSamplers(gp, &samplers, fGeometryProcessor);
+
+    SkSTArray<2, GrGLProcessor::TransformedCoords> coords;
+
+    // TODO remove coords from emit code signature, probably best to use a struct here so these
+    // updates are less painful
+    fGeometryProcessor->fGLProc->emitCode(this, gp, key, outColor, inColor, coords, samplers);
+
+    // We have to check that effects and the code they emit are consistent, ie if an effect
+    // asks for dst color, then the emit code needs to follow suit
+    verify(gp);
 }
 
 void GrGLProgramBuilder::verify(const GrGeometryProcessor& gp) {
@@ -334,19 +334,17 @@ void GrGLProgramBuilder::verify(const GrFragmentProcessor& fp) {
     SkASSERT(fFS.hasReadDstColor() == fp.willReadDstColor());
 }
 
-void GrGLProgramBuilder::emitTransforms(const GrProcessorStage& effectStage,
+void GrGLProgramBuilder::emitTransforms(const GrFragmentStage& effectStage,
                                         GrGLProcessor::TransformedCoordsArray* outCoords,
-                                        GrGLInstalledProcessors* installedProcessors) {
-    SkTArray<GrGLInstalledProcessors::Transform, true>& transforms =
-            installedProcessors->addTransforms();
-    const GrProcessor* effect = effectStage.getProcessor();
+                                        GrGLInstalledFragProc* ifp) {
+    const GrFragmentProcessor* effect = effectStage.getProcessor();
     int numTransforms = effect->numTransforms();
-    transforms.push_back_n(numTransforms);
+    ifp->fTransforms.push_back_n(numTransforms);
 
     for (int t = 0; t < numTransforms; t++) {
         const char* uniName = "StageMatrix";
         GrSLType varyingType =
-                effectStage.isPerspectiveCoordTransform(t, fVS.hasExplicitLocalCoords()) ?
+                effectStage.isPerspectiveCoordTransform(t, fVS.hasLocalCoords()) ?
                         kVec3f_GrSLType :
                         kVec2f_GrSLType;
 
@@ -356,10 +354,10 @@ void GrGLProgramBuilder::emitTransforms(const GrProcessorStage& effectStage,
             suffixedUniName.appendf("_%i", t);
             uniName = suffixedUniName.c_str();
         }
-        transforms[t].fHandle = this->addUniform(GrGLProgramBuilder::kVertex_Visibility,
-                                                 kMat33f_GrSLType,
-                                                 uniName,
-                                                 &uniName).toShaderBuilderIndex();
+        ifp->fTransforms[t].fHandle = this->addUniform(GrGLProgramBuilder::kVertex_Visibility,
+                                                       kMat33f_GrSLType,
+                                                       uniName,
+                                                       &uniName).toShaderBuilderIndex();
 
         const char* varyingName = "MatrixCoord";
         SkString suffixedVaryingName;
@@ -393,18 +391,17 @@ void GrGLProgramBuilder::emitTransforms(const GrProcessorStage& effectStage,
 
 void GrGLProgramBuilder::emitSamplers(const GrProcessor& processor,
                                       GrGLProcessor::TextureSamplerArray* outSamplers,
-                                      GrGLInstalledProcessors* installedProcessors) {
-    SkTArray<GrGLInstalledProcessors::Sampler, true>& samplers = installedProcessors->addSamplers();
+                                      GrGLInstalledProc* ip) {
     int numTextures = processor.numTextures();
-    samplers.push_back_n(numTextures);
+    ip->fSamplers.push_back_n(numTextures);
     SkString name;
     for (int t = 0; t < numTextures; ++t) {
         name.printf("Sampler%d", t);
-        samplers[t].fUniform = this->addUniform(GrGLProgramBuilder::kFragment_Visibility,
-                                                kSampler2D_GrSLType,
-                                                name.c_str());
+        ip->fSamplers[t].fUniform = this->addUniform(GrGLProgramBuilder::kFragment_Visibility,
+                                                     kSampler2D_GrSLType,
+                                                     name.c_str());
         SkNEW_APPEND_TO_TARRAY(outSamplers, GrGLProcessor::TextureSampler,
-                               (samplers[t].fUniform, processor.textureAccess(t)));
+                               (ip->fSamplers[t].fUniform, processor.textureAccess(t)));
     }
 }
 
@@ -506,14 +503,14 @@ void GrGLProgramBuilder::cleanupShaders(const SkTDArray<GrGLuint>& shaderIDs) {
 
 GrGLProgram* GrGLProgramBuilder::createProgram(GrGLuint programID) {
     return SkNEW_ARGS(GrGLProgram, (fGpu, fDesc, fUniformHandles, programID, fUniforms,
-                                    fGeometryProcessor, fColorEffects, fCoverageEffects));
+                                    fGeometryProcessor, fFragmentProcessors.get()));
 }
 
-////////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////////////////////////
 
-GrGLInstalledProcessors::~GrGLInstalledProcessors() {
-    int numEffects = fGLProcessors.count();
-    for (int e = 0; e < numEffects; ++e) {
-        SkDELETE(fGLProcessors[e]);
+GrGLInstalledFragProcs::~GrGLInstalledFragProcs() {
+    int numProcs = fProcs.count();
+    for (int e = 0; e < numProcs; ++e) {
+        SkDELETE(fProcs[e]->fGLProc);
     }
 }
index 6141058152b88546f12bb9c2aefc29eb9c151a73..a8293545b20d6cada3a847a950ba5e3fcdc4fb3e 100644 (file)
@@ -14,8 +14,6 @@
 #include "../GrGLProgramDataManager.h"
 #include "../GrGLUniformHandle.h"
 
-class GrGLInstalledProcessors;
-
 /*
  * This is the base class for a series of interfaces.  This base class *MUST* remain abstract with
  * NO data members because it is used in multiple interface inheritance.
@@ -98,6 +96,11 @@ public:
      */
 };
 
+struct GrGLInstalledProc;
+struct GrGLInstalledGeoProc;
+struct GrGLInstalledFragProc;
+struct GrGLInstalledFragProcs;
+
 /*
  * Please note - no diamond problems because of virtual inheritance.  Also, both base classes
  * are pure virtual with no data members.  This is the base class for program building.
@@ -118,9 +121,6 @@ public:
     static GrGLProgram* CreateProgram(const GrOptDrawState&,
                                       const GrGLProgramDesc&,
                                       GrGpu::DrawType,
-                                      const GrGeometryStage* inGeometryProcessor,
-                                      const GrFragmentStage* inColorStages[],
-                                      const GrFragmentStage* inCoverageStages[],
                                       GrGpuGL* gpu);
 
     virtual UniformHandle addUniform(uint32_t visibility,
@@ -150,11 +150,12 @@ public:
     virtual GrGLFPFragmentBuilder* getFragmentShaderBuilder() SK_OVERRIDE { return &fFS; }
     virtual GrGLVertexBuilder* getVertexShaderBuilder() SK_OVERRIDE { return &fVS; }
 
-    virtual void addVarying(GrSLType type,
-                            const char* name,
-                            const char** vsOutName = NULL,
-                            const char** fsInName = NULL,
-                            GrGLShaderVar::Precision fsPrecision=GrGLShaderVar::kDefault_Precision);
+    virtual void addVarying(
+            GrSLType type,
+            const char* name,
+            const char** vsOutName = NULL,
+            const char** fsInName = NULL,
+            GrGLShaderVar::Precision fsPrecision=GrGLShaderVar::kDefault_Precision) SK_OVERRIDE;
 
     // Handles for program uniforms (other than per-effect uniforms)
     struct BuiltinUniformHandles {
@@ -174,6 +175,10 @@ public:
     };
 
 protected:
+    typedef GrGLProgramDesc::ProcKeyProvider ProcKeyProvider;
+    typedef GrGLProgramDataManager::UniformInfo UniformInfo;
+    typedef GrGLProgramDataManager::UniformInfoArray UniformInfoArray;
+
     static GrGLProgramBuilder* CreateProgramBuilder(const GrGLProgramDesc&,
                                                     const GrOptDrawState&,
                                                     GrGpu::DrawType,
@@ -191,32 +196,40 @@ protected:
     // generating stage code.
     void nameVariable(SkString* out, char prefix, const char* name);
     void setupUniformColorAndCoverageIfNeeded(GrGLSLExpr4* inputColor, GrGLSLExpr4* inputCoverage);
-    void createAndEmitProcessors(const GrGeometryStage* geometryProcessor,
-                                 const GrFragmentStage* colorStages[],
-                                 const GrFragmentStage* coverageStages[],
-                                 GrGLSLExpr4* inputColor,
-                                 GrGLSLExpr4* inputCoverage);
-    template <class ProcessorStage>
-    void createAndEmitProcessors(const ProcessorStage*[],
-                                 int effectCnt,
-                                 const GrGLProgramDesc::EffectKeyProvider&,
-                                 GrGLSLExpr4* fsInOutColor,
-                                 GrGLInstalledProcessors*);
+    void emitAndInstallProcs(const GrOptDrawState& optState,
+                             GrGLSLExpr4* inputColor,
+                             GrGLSLExpr4* inputCoverage);
+    void emitAndInstallFragProcs(int procOffset, int numProcs, GrGLSLExpr4* inOut);
+    template <class Proc>
+    void emitAndInstallProc(const Proc&,
+                            int index,
+                            const ProcKeyProvider,
+                            const GrGLSLExpr4& input,
+                            GrGLSLExpr4* output);
+
+    // these emit functions help to keep the createAndEmitProcessors template general
+    void emitAndInstallProc(const GrFragmentStage&,
+                            const GrProcessorKey&,
+                            const char* outColor,
+                            const char* inColor);
+    void emitAndInstallProc(const GrGeometryProcessor&,
+                            const GrProcessorKey&,
+                            const char* outColor,
+                            const char* inColor);
     void verify(const GrGeometryProcessor&);
     void verify(const GrFragmentProcessor&);
     void emitSamplers(const GrProcessor&,
                       GrGLProcessor::TextureSamplerArray* outSamplers,
-                      GrGLInstalledProcessors*);
+                      GrGLInstalledProc*);
 
     // each specific program builder has a distinct transform and must override this function
-    virtual void emitTransforms(const GrProcessorStage&,
+    virtual void emitTransforms(const GrFragmentStage&,
                                 GrGLProcessor::TransformedCoordsArray* outCoords,
-                                GrGLInstalledProcessors*);
+                                GrGLInstalledFragProc*);
     GrGLProgram* finalize();
     void bindUniformLocations(GrGLuint programID);
     bool checkLinkStatus(GrGLuint programID);
     void resolveUniformLocations(GrGLuint programID);
-
     void cleanupProgram(GrGLuint programID, const SkTDArray<GrGLuint>& shaderIDs);
     void cleanupShaders(const SkTDArray<GrGLuint>& shaderIDs);
 
@@ -256,10 +269,6 @@ protected:
     void enterStage() { fOutOfStage = false; }
     int stageIndex() const { return fStageIndex; }
 
-    typedef GrGLProgramDesc::EffectKeyProvider EffectKeyProvider;
-    typedef GrGLProgramDataManager::UniformInfo UniformInfo;
-    typedef GrGLProgramDataManager::UniformInfoArray UniformInfoArray;
-
     // number of each input/output type in a single allocation block, used by many builders
     static const int kVarsPerBlock;
 
@@ -270,9 +279,8 @@ protected:
     bool fOutOfStage;
     int fStageIndex;
 
-    SkAutoTUnref<GrGLInstalledProcessors> fGeometryProcessor;
-    SkAutoTUnref<GrGLInstalledProcessors> fColorEffects;
-    SkAutoTUnref<GrGLInstalledProcessors> fCoverageEffects;
+    GrGLInstalledGeoProc* fGeometryProcessor;
+    SkAutoTUnref<GrGLInstalledFragProcs> fFragmentProcessors;
 
     const GrOptDrawState& fOptState;
     const GrGLProgramDesc& fDesc;
@@ -286,32 +294,26 @@ protected:
 };
 
 /**
- * This class encapsulates an array of GrGLProcessors and their supporting data (coord transforms
- * and textures). It is built by GrGLProgramBuilder, then used to manage the necessary GL
- * state and shader uniforms in GLPrograms.  Its just Plain old data, and as such is entirely public
- *
- * TODO We really don't need this class to have an array of processors.  It makes sense for it
- * to just have one, also break out the transforms
+ * The below structs represent processors installed in programs.  All processors can have texture
+ * samplers, but only frag processors have coord transforms, hence the need for different structs
  */
-class GrGLInstalledProcessors : public SkRefCnt {
-public:
-    GrGLInstalledProcessors(int reserveCount, bool hasExplicitLocalCoords = false)
-        : fGLProcessors(reserveCount)
-        , fSamplers(reserveCount)
-        , fTransforms(reserveCount)
-        , fHasExplicitLocalCoords(hasExplicitLocalCoords) {
-    }
-
-    virtual ~GrGLInstalledProcessors();
-
-    typedef GrGLProgramDataManager::UniformHandle UniformHandle;
+struct GrGLInstalledProc {
+     typedef GrGLProgramDataManager::UniformHandle UniformHandle;
+
+     struct Sampler {
+         SkDEBUGCODE(Sampler() : fTextureUnit(-1) {})
+         UniformHandle  fUniform;
+         int            fTextureUnit;
+     };
+     SkSTArray<4, Sampler, true> fSamplers;
+};
 
-    struct Sampler {
-        SkDEBUGCODE(Sampler() : fTextureUnit(-1) {})
-        UniformHandle  fUniform;
-        int            fTextureUnit;
-    };
+struct GrGLInstalledGeoProc : public GrGLInstalledProc {
+    GrGLGeometryProcessor* fGLProc;
+};
 
+struct GrGLInstalledFragProc : public GrGLInstalledProc {
+    GrGLInstalledFragProc(bool useLocalCoords) : fGLProc(NULL), fLocalCoordAttrib(useLocalCoords) {}
     class ShaderVarHandle {
     public:
         bool isValid() const { return fHandle > -1; }
@@ -334,19 +336,14 @@ public:
         GrSLType       fType;
     };
 
-    void addEffect(GrGLProcessor* effect) { fGLProcessors.push_back(effect); }
-    SkTArray<Sampler, true>& addSamplers() { return fSamplers.push_back(); }
-    SkTArray<Transform, true>& addTransforms() { return fTransforms.push_back(); }
-
-    SkTArray<GrGLProcessor*>                 fGLProcessors;
-    SkTArray<SkSTArray<4, Sampler, true> >   fSamplers;
-    SkTArray<SkSTArray<2, Transform, true> > fTransforms;
-    bool                                     fHasExplicitLocalCoords;
+    GrGLFragmentProcessor*        fGLProc;
+    SkSTArray<2, Transform, true> fTransforms;
+    bool                          fLocalCoordAttrib;
+};
 
-    friend class GrGLShaderBuilder;
-    friend class GrGLVertexShaderBuilder;
-    friend class GrGLFragmentShaderBuilder;
-    friend class GrGLGeometryShaderBuilder;
+struct GrGLInstalledFragProcs : public SkRefCnt {
+    ~GrGLInstalledFragProcs();
+    SkSTArray<8, GrGLInstalledFragProc*, true> fProcs;
 };
 
 #endif
index 0b85b84dfb6994642fff5152cbe42c3ce68b9c12..6e1495a746de37c97ff9ab4570683fd94cd25c87 100644 (file)
@@ -21,7 +21,7 @@ public:
     /**
      * Are explicit local coordinates provided as input to the vertex shader.
      */
-    bool hasExplicitLocalCoords() const { return (fLocalCoordsVar != fPositionVar); }
+    bool hasLocalCoords() const { return (fLocalCoordsVar != fPositionVar); }
 
     /** Returns a vertex attribute that represents the local coords in the VS. This may be the same
         as positionAttribute() or it may not be. It depends upon whether the rendering code
index 5ab35b7d227b9314d80fcd14e9c06e6a481cde8a..75032bdbe6a168b8b0a3daba063b0c9794823711 100644 (file)
@@ -456,9 +456,6 @@ bool GrGpuGL::programUnitTest(int maxStages) {
             ds->reset();
             continue;
         }
-        const GrGeometryStage*                     geometryProcessor = NULL;
-        SkSTArray<8, const GrFragmentStage*, true> colorStages;
-        SkSTArray<8, const GrFragmentStage*, true> coverageStages;
         GrGLProgramDesc desc;
         GrDeviceCoordTexture dstCopy;
 
@@ -468,24 +465,14 @@ bool GrGpuGL::programUnitTest(int maxStages) {
         }
         if (!GrGLProgramDesc::Build(*ods,
                                     drawType,
-                                    ods->getSrcBlendCoeff(),
-                                    ods->getDstBlendCoeff(),
                                     this,
                                     dstCopy.texture() ? &dstCopy : NULL,
-                                    &geometryProcessor,
-                                    &colorStages,
-                                    &coverageStages,
                                     &desc)) {
             SkDebugf("Failed to generate GL program descriptor");
             return false;
         }
-        SkAutoTUnref<GrGLProgram> program(GrGLProgramBuilder::CreateProgram(*ods,
-                                                                            desc,
-                                                                            drawType,
-                                                                            geometryProcessor,
-                                                                            colorStages.begin(),
-                                                                            coverageStages.begin(),
-                                                                            this));
+        SkAutoTUnref<GrGLProgram> program(
+                GrGLProgramBuilder::CreateProgram(*ods, desc, drawType, this));
         if (NULL == program.get()) {
             SkDebugf("Failed to create program!");
             return false;