Revert of Create xfer processor backend. (patchset #6 id:100001 of https://codereview...
authorjoshualitt <joshualitt@google.com>
Wed, 10 Dec 2014 23:03:00 +0000 (15:03 -0800)
committerCommit bot <commit-bot@chromium.org>
Wed, 10 Dec 2014 23:03:01 +0000 (15:03 -0800)
Reason for revert:
CL breaks windows DM

Original issue's description:
> Create xfer processor backend.
>
> This includes:
> -Having an actual XP stage at the end of the gl pipeline.
> -All Blending work is handled by XP until actually setting GL blend states
> -GLPrograms test to test XP
>
> BUG=skia:
>
> Committed: https://skia.googlesource.com/skia/+/4dffc940c430eec66d4707490eace19c9b3f7904

TBR=bsalomon@google.com,joshualitt@chromium.org,egdaniel@google.com
NOTREECHECKS=true
NOTRY=true
BUG=skia:

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

22 files changed:
expectations/gm/ignored-tests.txt
include/gpu/GrProcessorUnitTest.h
include/gpu/GrXferProcessor.h
include/gpu/effects/GrPorterDuffXferProcessor.h
src/gpu/GrGeometryProcessor.h
src/gpu/GrOptDrawState.cpp
src/gpu/GrOptDrawState.h
src/gpu/GrProcessor.cpp
src/gpu/GrProgramDesc.h
src/gpu/effects/GrPorterDuffXferProcessor.cpp
src/gpu/gl/GrGLProcessor.h
src/gpu/gl/GrGLProgram.cpp
src/gpu/gl/GrGLProgram.h
src/gpu/gl/GrGLProgramDesc.cpp
src/gpu/gl/GrGLXferProcessor.h [deleted file]
src/gpu/gl/builders/GrGLFragmentShaderBuilder.cpp
src/gpu/gl/builders/GrGLFragmentShaderBuilder.h
src/gpu/gl/builders/GrGLLegacyNvprProgramBuilder.cpp
src/gpu/gl/builders/GrGLNvprProgramBuilder.cpp
src/gpu/gl/builders/GrGLProgramBuilder.cpp
src/gpu/gl/builders/GrGLProgramBuilder.h
tests/GLProgramsTest.cpp

index 396ca20424955975cbb8dc0498f9dc200c2bf3b1..31b71225fa78847a1ccbcce402d54357540b1ca4 100644 (file)
@@ -51,10 +51,6 @@ imagemagnifier
 #reed
 modecolorfilters
 
-#egdaniel
-xfermodes3
-mixed_xfermodes
-
 #humper skia:2049
 dashcubics
 
index 4b97483c0fa438f017c2c6728ed04c2b5084bd44..fbf4382d69533011541581d6548db4741e36cb66 100644 (file)
@@ -149,14 +149,6 @@ private:
                                            const GrDrawTargetCaps&,                                \
                                            GrTexture* dummyTextures[2])
 
-#define GR_DECLARE_XP_FACTORY_TEST                                                                 \
-    static GrProcessorTestFactory<GrXPFactory> gTestFactory SK_UNUSED;                             \
-    static GrXPFactory* TestCreate(SkRandom*,                                                      \
-                                   GrContext*,                                                     \
-                                   const GrDrawTargetCaps&,                                        \
-                                   GrTexture* dummyTextures[2])
-
-
 /** GrProcessor subclasses should insert this macro in their implementation file. They must then
  *  also implement this static function:
  *      GrProcessor* TestCreate(SkRandom*,
@@ -171,9 +163,6 @@ private:
 #define GR_DEFINE_FRAGMENT_PROCESSOR_TEST(Effect)                                                  \
     GrProcessorTestFactory<GrFragmentProcessor> Effect :: gTestFactory(Effect :: TestCreate)
 
-#define GR_DEFINE_XP_FACTORY_TEST(Factory)                                                         \
-    GrProcessorTestFactory<GrXPFactory> Factory :: gTestFactory(Factory :: TestCreate)
-
 #define GR_DEFINE_GEOMETRY_PROCESSOR_TEST(Effect)                                                  \
     GrProcessorTestFactory<GrGeometryProcessor> Effect :: gTestFactory(Effect :: TestCreate)
 
@@ -183,27 +172,18 @@ private:
 // its definitions will compile.
 #define GR_DECLARE_FRAGMENT_PROCESSOR_TEST                                                         \
     static GrFragmentProcessor* TestCreate(SkRandom*,                                              \
-                                           GrContext*,                                             \
-                                           const GrDrawTargetCaps&,                                \
-                                           GrTexture* dummyTextures[2])
+                                GrContext*,                                                        \
+                                const GrDrawTargetCaps&,                                           \
+                                GrTexture* dummyTextures[2])
 #define GR_DEFINE_FRAGMENT_PROCESSOR_TEST(X)
 
-// The unit test relies on static initializers. Just declare the TestCreate function so that
-// its definitions will compile.
-#define GR_DECLARE_XP_FACTORY_TEST                                                                 \
-    static GrXPFactory* TestCreate(SkRandom*,                                                      \
-                                   GrContext*,                                                     \
-                                   const GrDrawTargetCaps&,                                        \
-                                   GrTexture* dummyTextures[2])
-#define GR_DEFINE_XP_FACTORY_TEST(X)
-
 // The unit test relies on static initializers. Just declare the TestCreate function so that
 // its definitions will compile.
 #define GR_DECLARE_GEOMETRY_PROCESSOR_TEST                                                         \
     static GrGeometryProcessor* TestCreate(SkRandom*,                                              \
-                                           GrContext*,                                             \
-                                           const GrDrawTargetCaps&,                                \
-                                           GrTexture* dummyTextures[2])
+                                GrContext*,                                                        \
+                                const GrDrawTargetCaps&,                                           \
+                                GrTexture* dummyTextures[2])
 #define GR_DEFINE_GEOMETRY_PROCESSOR_TEST(X)
 
 #endif // !SK_ALLOW_STATIC_GLOBAL_INITIALIZERS
index 696359b8b3fb351438c3d0b816e802a23422725f..b7d0bdd9fa9ef7717471a3857b9e788e95793378 100644 (file)
@@ -9,13 +9,10 @@
 #define GrXferProcessor_DEFINED
 
 #include "GrColor.h"
-#include "GrProcessor.h"
+#include "GrFragmentProcessor.h"
 #include "GrTypes.h"
 #include "SkXfermode.h"
 
-class GrDrawTargetCaps;
-class GrGLCaps;
-class GrGLXferProcessor;
 class GrProcOptInfo;
 
 /**
@@ -31,20 +28,8 @@ class GrProcOptInfo;
  * A GrXferProcessor is never installed directly into our draw state, but instead is created from a
  * GrXPFactory once we have finalized the state of our draw.
  */
-class GrXferProcessor : public GrProcessor {
+class GrXferProcessor : public GrFragmentProcessor {
 public:
-    /**
-     * Sets a unique key on the GrProcessorKeyBuilder that is directly associated with this xfer
-     * processor's GL backend implementation.
-     */
-    virtual void getGLProcessorKey(const GrGLCaps& caps,
-                                   GrProcessorKeyBuilder* b) const = 0;
-
-    /** Returns a new instance of the appropriate *GL* implementation class
-        for the given GrXferProcessor; caller is responsible for deleting
-        the object. */
-    virtual GrGLXferProcessor* createGLInstance() const = 0;
-
     /**
      * Optimizations for blending / coverage that an OptDrawState should apply to itself.
      */
@@ -89,8 +74,7 @@ public:
                                       bool colorWriteDisabled,
                                       bool doesStencilWrite,
                                       GrColor* color,
-                                      uint8_t* coverage,
-                                      const GrDrawTargetCaps& caps) = 0;
+                                      uint8_t* coverage) = 0;
 
     struct BlendInfo {
         GrBlendCoeff fSrcBlend;
@@ -103,27 +87,6 @@ public:
     /** Will this prceossor read the destination pixel value? */
     bool willReadDstColor() const { return fWillReadDstColor; }
 
-    /** 
-     * Returns whether or not this xferProcossor will set a secondary output to be used with dual
-     * source blending.
-     */
-    virtual bool hasSecondaryOutput() const { return false; }
-
-    /** Returns true if this and other processor conservatively draw identically. It can only return
-        true when the two processor are of the same subclass (i.e. they return the same object from
-        from getFactory()).
-
-        A return value of true from isEqual() should not be used to test whether the processor would
-        generate the same shader code. To test for identical code generation use getGLProcessorKey*/
-    
-    bool isEqual(const GrXferProcessor& that) const {
-        if (this->classID() != that.classID()) {
-            return false;
-        }
-        return this->onIsEqual(that);
-    }
-   
-
 protected:
     GrXferProcessor() : fWillReadDstColor(false) {}
 
@@ -135,7 +98,6 @@ protected:
     void setWillReadDstColor() { fWillReadDstColor = true; }
 
 private:
-    virtual bool onIsEqual(const GrXferProcessor&) const = 0;
 
     bool         fWillReadDstColor;
 
index 26800c7f8f9387957234323f35a5b14229fc6e10..0ddfcdcd2a9594056bb12d469d5e85b5e0ca84bb 100644 (file)
@@ -26,44 +26,20 @@ public:
 
     virtual const char* name() const { return "Porter Duff"; }
 
-    void getGLProcessorKey(const GrGLCaps& caps, GrProcessorKeyBuilder* b) const SK_OVERRIDE;
-
-    GrGLXferProcessor* createGLInstance() const SK_OVERRIDE;
-
-    virtual bool hasSecondaryOutput() const SK_OVERRIDE;
-
-    ///////////////////////////////////////////////////////////////////////////
-    /// @name Stage Output Types
-    ////
-
-    enum SecondaryOutputType {
-        // There is no secondary output
-        kNone_SecondaryOutputType,
-        // Writes coverage as the secondary output. Only set if dual source blending is supported
-        // and primary output is kModulate.
-        kCoverage_SecondaryOutputType,
-        // Writes coverage * (1 - colorA) as the secondary output. Only set if dual source blending
-        // is supported and primary output is kModulate.
-        kCoverageISA_SecondaryOutputType,
-        // Writes coverage * (1 - colorRGBA) as the secondary output. Only set if dual source
-        // blending is supported and primary output is kModulate.
-        kCoverageISC_SecondaryOutputType,
-
-        kSecondaryOutputTypeCnt,
-    };
-
-    SecondaryOutputType secondaryOutputType() const { return fSecondaryOutputType; }
-
-    GrXferProcessor::OptFlags getOptimizations(const GrProcOptInfo& colorPOI,
-                                               const GrProcOptInfo& coveragePOI,
-                                               bool isCoverageDrawing,
-                                               bool colorWriteDisabled,
-                                               bool doesStencilWrite,
-                                               GrColor* color,
-                                               uint8_t* coverage,
-                                               const GrDrawTargetCaps& caps) SK_OVERRIDE;
-
-    void getBlendInfo(GrXferProcessor::BlendInfo* blendInfo) const SK_OVERRIDE {
+    virtual void getGLProcessorKey(const GrGLCaps& caps,
+                                   GrProcessorKeyBuilder* b) const SK_OVERRIDE;
+
+    virtual GrGLFragmentProcessor* createGLInstance() const SK_OVERRIDE;
+
+    virtual GrXferProcessor::OptFlags getOptimizations(const GrProcOptInfo& colorPOI,
+                                                       const GrProcOptInfo& coveragePOI,
+                                                       bool isCoverageDrawing,
+                                                       bool colorWriteDisabled,
+                                                       bool doesStencilWrite,
+                                                       GrColor* color,
+                                                       uint8_t* coverage) SK_OVERRIDE;
+
+    virtual void getBlendInfo(GrXferProcessor::BlendInfo* blendInfo) const SK_OVERRIDE {
         blendInfo->fSrcBlend = fSrcBlend;
         blendInfo->fDstBlend = fDstBlend;
         blendInfo->fBlendConstant = fBlendConstant;
@@ -72,34 +48,21 @@ public:
 private:
     GrPorterDuffXferProcessor(GrBlendCoeff srcBlend, GrBlendCoeff dstBlend, GrColor constant);
 
-    bool onIsEqual(const GrXferProcessor& xpBase) const SK_OVERRIDE {
-        const GrPorterDuffXferProcessor& xp = xpBase.cast<GrPorterDuffXferProcessor>();
+    virtual bool onIsEqual(const GrFragmentProcessor& fpBase) const SK_OVERRIDE {
+        const GrPorterDuffXferProcessor& xp = fpBase.cast<GrPorterDuffXferProcessor>();
         if (fSrcBlend != xp.fSrcBlend ||
             fDstBlend != xp.fDstBlend ||
-            fBlendConstant != xp.fBlendConstant ||
-            fSecondaryOutputType != xp.fSecondaryOutputType) {
+            fBlendConstant != xp.fBlendConstant) {
             return false;
         }
         return true;
     }
 
-    void onComputeInvariantOutput(GrInvariantOutput* inout) const SK_OVERRIDE;
-
-    GrXferProcessor::OptFlags internalGetOptimizations(const GrProcOptInfo& colorPOI,
-                                                       const GrProcOptInfo& coveragePOI,
-                                                       bool isCoverageDrawing,
-                                                       bool colorWriteDisabled,
-                                                       bool doesStencilWrite,
-                                                       GrColor* color,
-                                                       uint8_t* coverage);
-
-    void calcOutputTypes(GrXferProcessor::OptFlags blendOpts, const GrDrawTargetCaps& caps,
-                         bool isCoverageDrawing, bool readDst);
+    virtual void onComputeInvariantOutput(GrInvariantOutput* inout) const SK_OVERRIDE;
 
     GrBlendCoeff fSrcBlend;
     GrBlendCoeff fDstBlend;
     GrColor      fBlendConstant;
-    SecondaryOutputType fSecondaryOutputType;
 
     typedef GrXferProcessor INHERITED;
 };
@@ -144,8 +107,6 @@ private:
         return (fSrcCoeff == xpf.fSrcCoeff && fDstCoeff == xpf.fDstCoeff);
     }
 
-    GR_DECLARE_XP_FACTORY_TEST;
-
     GrBlendCoeff fSrcCoeff;
     GrBlendCoeff fDstCoeff;
 
index a0cfc09d4536d7cfef2e5e101ef8eb1d9784f34f..4801069005fdd21ccc4a9103e1f8b9fac4905059 100644 (file)
@@ -62,10 +62,7 @@ public:
 
     virtual const char* name() const = 0;
 
-    /**
-     * Sets a unique key on the GrProcessorKeyBuilder that is directly associated with this geometry
-     * processor's GL backend implementation.
-     */
+    /** Implemented using GLProcessor::GenKey as described in this class's comment. */
     virtual void getGLProcessorKey(const GrBatchTracker& bt,
                                    const GrGLCaps& caps,
                                    GrProcessorKeyBuilder* b) const = 0;
index 9ebe551d6bc5d5fa141f94854ca75e17ebf17daf..409305ce33fae912d79acbd2f3964ed589d4464a 100644 (file)
@@ -44,8 +44,7 @@ GrOptDrawState::GrOptDrawState(const GrDrawState& drawState,
                                                    drawState.isColorWriteDisabled(),
                                                    drawState.getStencil().doesWrite(),
                                                    &fColor,
-                                                   &fCoverage,
-                                                   caps);
+                                                   &fCoverage);
     }
 
     // When path rendering the stencil settings are not always set on the draw state
@@ -147,6 +146,42 @@ GrOptDrawState::GrOptDrawState(const GrDrawState& drawState,
         init.fCoverage = this->getCoverage();
         fGeometryProcessor->initBatchTracker(&fBatchTracker, init);
     }
+
+    this->setOutputStateInfo(drawState, coverageColor, optFlags, caps);
+}
+
+void GrOptDrawState::setOutputStateInfo(const GrDrawState& ds,
+                                        GrColor coverage,
+                                        GrXferProcessor::OptFlags optFlags,
+                                        const GrDrawTargetCaps& caps) {
+    // Set this default and then possibly change our mind if there is coverage.
+    fDescInfo.fPrimaryOutputType = GrProgramDesc::kModulate_PrimaryOutputType;
+    fDescInfo.fSecondaryOutputType = GrProgramDesc::kNone_SecondaryOutputType;
+
+    // Determine whether we should use dual source blending or shader code to keep coverage
+    // separate from color.
+    bool keepCoverageSeparate = !(optFlags & GrXferProcessor::kSetCoverageDrawing_OptFlag);
+    if (keepCoverageSeparate && !ds.hasSolidCoverage(coverage)) {
+        if (caps.dualSourceBlendingSupport()) {
+            if (kZero_GrBlendCoeff == fDstBlend) {
+                // write the coverage value to second color
+                fDescInfo.fSecondaryOutputType = GrProgramDesc::kCoverage_SecondaryOutputType;
+                fDstBlend = (GrBlendCoeff)GrGpu::kIS2C_GrBlendCoeff;
+            } else if (kSA_GrBlendCoeff == fDstBlend) {
+                // SA dst coeff becomes 1-(1-SA)*coverage when dst is partially covered.
+                fDescInfo.fSecondaryOutputType = GrProgramDesc::kCoverageISA_SecondaryOutputType;
+                fDstBlend = (GrBlendCoeff)GrGpu::kIS2C_GrBlendCoeff;
+            } else if (kSC_GrBlendCoeff == fDstBlend) {
+                // SA dst coeff becomes 1-(1-SA)*coverage when dst is partially covered.
+                fDescInfo.fSecondaryOutputType = GrProgramDesc::kCoverageISC_SecondaryOutputType;
+                fDstBlend = (GrBlendCoeff)GrGpu::kIS2C_GrBlendCoeff;
+            }
+        } else if (fDescInfo.fReadsDst &&
+                   kOne_GrBlendCoeff == fSrcBlend &&
+                   kZero_GrBlendCoeff == fDstBlend) {
+            fDescInfo.fPrimaryOutputType = GrProgramDesc::kCombineWithDst_PrimaryOutputType;
+        }
+    }
 }
 
 void GrOptDrawState::adjustProgramFromOptimizations(const GrDrawState& ds,
@@ -227,10 +262,6 @@ bool GrOptDrawState::operator== (const GrOptDrawState& that) const {
         return false;
     }
 
-    if (!this->getXferProcessor()->isEqual(*that.getXferProcessor())) {
-        return false;
-    }
-
     // The program desc comparison should have already assured that the stage counts match.
     SkASSERT(this->numFragmentStages() == that.numFragmentStages());
     for (int i = 0; i < this->numFragmentStages(); i++) {
index 55a5071d4179414af49eca990ec7166d934fe678..cf5737373caa44ba3134f6a7d9efb56bc52ecef4 100644 (file)
@@ -79,8 +79,7 @@ public:
     int numCoverageStages() const { return fFragmentStages.count() - fNumColorStages; }
     int numFragmentStages() const { return fFragmentStages.count(); }
     int numTotalStages() const {
-        // the + 1 at the end is for the xferProcessor which will always be present
-        return this->numFragmentStages() + (this->hasGeometryProcessor() ? 1 : 0) + 1;
+         return this->numFragmentStages() + (this->hasGeometryProcessor() ? 1 : 0);
     }
 
     bool hasGeometryProcessor() const { return SkToBool(fGeometryProcessor.get()); }
index 2bcd9b46a29feaac6857fde67cfa6f2cec853071..ccd4d7f7e86bae2bb64350f8839991ae24000cc8 100644 (file)
@@ -32,9 +32,9 @@ GrProcessorTestFactory<GrFragmentProcessor>::GetFactories() {
 }
 
 template<>
-SkTArray<GrProcessorTestFactory<GrXPFactory>*, true>*
-GrProcessorTestFactory<GrXPFactory>::GetFactories() {
-    static SkTArray<GrProcessorTestFactory<GrXPFactory>*, true> gFactories;
+SkTArray<GrProcessorTestFactory<GrXferProcessor>*, true>*
+GrProcessorTestFactory<GrXferProcessor>::GetFactories() {
+    static SkTArray<GrProcessorTestFactory<GrXferProcessor>*, true> gFactories;
     return &gFactories;
 }
 
@@ -52,7 +52,7 @@ GrProcessorTestFactory<GrGeometryProcessor>::GetFactories() {
  */
 static const int kFPFactoryCount = 37;
 static const int kGPFactoryCount = 14;
-static const int kXPFactoryCount = 1;
+static const int kXPFactoryCount = 0;
 
 template<>
 void GrProcessorTestFactory<GrFragmentProcessor>::VerifyFactoryCount() {
@@ -69,9 +69,9 @@ void GrProcessorTestFactory<GrGeometryProcessor>::VerifyFactoryCount() {
 }
 
 template<>
-void GrProcessorTestFactory<GrXPFactory>::VerifyFactoryCount() {
+void GrProcessorTestFactory<GrXferProcessor>::VerifyFactoryCount() {
     if (kXPFactoryCount != GetFactories()->count()) {
-        SkFAIL("Wrong number of xp factory factories!");
+        SkFAIL("Wrong number of xfer processor factories!");
     }
 }
 
index 3d53842e43ae2cab3a9ddaee0062c353c25593db..a20b99f74948c91377c7127ef12a17ff683b019b 100644 (file)
@@ -55,6 +55,36 @@ public:
     }
 
 
+    ///////////////////////////////////////////////////////////////////////////
+    /// @name Stage Output Types
+    ////
+
+    enum PrimaryOutputType {
+        // Modulate color and coverage, write result as the color output.
+        kModulate_PrimaryOutputType,
+        // Combines the coverage, dst, and color as coverage * color + (1 - coverage) * dst. This
+        // can only be set if fDstReadKey is non-zero.
+        kCombineWithDst_PrimaryOutputType,
+
+        kPrimaryOutputTypeCnt,
+    };
+
+    enum SecondaryOutputType {
+        // There is no secondary output
+        kNone_SecondaryOutputType,
+        // Writes coverage as the secondary output. Only set if dual source blending is supported
+        // and primary output is kModulate.
+        kCoverage_SecondaryOutputType,
+        // Writes coverage * (1 - colorA) as the secondary output. Only set if dual source blending
+        // is supported and primary output is kModulate.
+        kCoverageISA_SecondaryOutputType,
+        // Writes coverage * (1 - colorRGBA) as the secondary output. Only set if dual source
+        // blending is supported and primary output is kModulate.
+        kCoverageISC_SecondaryOutputType,
+
+        kSecondaryOutputTypeCnt,
+    };
+
     // Specifies where the initial color comes from before the stages are applied.
     enum ColorInput {
         kAllOnes_ColorInput,
@@ -75,6 +105,9 @@ public:
         ColorInput                  fColorInput : 8;
         ColorInput                  fCoverageInput : 8;
 
+        PrimaryOutputType           fPrimaryOutputType : 8;
+        SecondaryOutputType         fSecondaryOutputType : 8;
+
         SkBool8                     fHasGeometryProcessor;
         int8_t                      fColorEffectCnt;
         int8_t                      fCoverageEffectCnt;
@@ -107,7 +140,10 @@ public:
                    fInputCoverageIsUsed == that.fInputCoverageIsUsed &&
                    fReadsDst == that.fReadsDst &&
                    fReadsFragPosition == that.fReadsFragPosition &&
-                   fRequiresLocalCoordAttrib == that.fRequiresLocalCoordAttrib;
+                   fRequiresLocalCoordAttrib == that.fRequiresLocalCoordAttrib &&
+                   fPrimaryOutputType == that.fPrimaryOutputType &&
+                   fSecondaryOutputType == that.fSecondaryOutputType;
+
         }
         bool operator!=(const DescInfo& that) const { return !(*this == that); };
         // TODO when GPs control uniform / attribute handling of color / coverage, then we can
@@ -126,6 +162,9 @@ public:
         bool            fReadsFragPosition;
         bool            fRequiresLocalCoordAttrib;
 
+        // Fragment shader color outputs
+        GrProgramDesc::PrimaryOutputType  fPrimaryOutputType : 8;
+        GrProgramDesc::SecondaryOutputType  fSecondaryOutputType : 8;
     };
 
 private:
index 097854622d67d9538eebe959dfe73080eb20abf3..2b4b1334f89828b96cc142a688f8492437f7dcfa 100644 (file)
@@ -9,12 +9,11 @@
 
 #include "GrBlend.h"
 #include "GrDrawState.h"
-#include "GrDrawTargetCaps.h"
 #include "GrInvariantOutput.h"
 #include "GrProcessor.h"
 #include "GrTypes.h"
 #include "GrXferProcessor.h"
-#include "gl/GrGLXferProcessor.h"
+#include "gl/GrGLProcessor.h"
 #include "gl/builders/GrGLFragmentShaderBuilder.h"
 #include "gl/builders/GrGLProgramBuilder.h"
 
@@ -43,40 +42,19 @@ public:
 
     virtual ~GrGLPorterDuffXferProcessor() {}
 
-    virtual void emitCode(const EmitArgs& args) SK_OVERRIDE {
-        const GrPorterDuffXferProcessor& xp = args.fXP.cast<GrPorterDuffXferProcessor>();
-        GrGLFPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder();
-        if (xp.hasSecondaryOutput()) {
-            switch(xp.secondaryOutputType()) {
-                case GrPorterDuffXferProcessor::kCoverage_SecondaryOutputType:
-                    fsBuilder->codeAppendf("%s = %s;", args.fOutputSecondary, args.fInputCoverage);
-                    break;
-                case GrPorterDuffXferProcessor::kCoverageISA_SecondaryOutputType:
-                    fsBuilder->codeAppendf("%s = (1.0 - %s.a) * %s;",
-                                           args.fOutputSecondary, args.fInputColor,
-                                           args.fInputCoverage);
-                    break;
-                case GrPorterDuffXferProcessor::kCoverageISC_SecondaryOutputType:
-                    fsBuilder->codeAppendf("%s = (vec4(1.0) - %s) * %s;",
-                                           args.fOutputSecondary, args.fInputColor,
-                                           args.fInputCoverage);
-                    break;
-                default:
-                    SkFAIL("Unexpected Secondary Output");
-            }
-        }
-        
-        fsBuilder->codeAppendf("%s = %s * %s;", args.fOutputPrimary, args.fInputColor,
-                               args.fInputCoverage);
+    virtual void emitCode(GrGLFPBuilder* builder,
+                          const GrFragmentProcessor& fp,
+                          const char* outputColor,
+                          const char* inputColor,
+                          const TransformedCoordsArray& coords,
+                          const TextureSamplerArray& samplers) SK_OVERRIDE {
+        GrGLFPFragmentBuilder* fsBuilder = builder->getFragmentShaderBuilder();
+        fsBuilder->codeAppendf("%s = %s;", outputColor, inputColor);
     }
 
-    virtual void setData(const GrGLProgramDataManager&, const GrXferProcessor&) SK_OVERRIDE {};
+    virtual void setData(const GrGLProgramDataManager&, const GrProcessor&) SK_OVERRIDE {};
 
-    static void GenKey(const GrProcessor& processor, const GrGLCaps& caps,
-                       GrProcessorKeyBuilder* b) {
-        const GrPorterDuffXferProcessor& xp = processor.cast<GrPorterDuffXferProcessor>();
-        b->add32(xp.secondaryOutputType());
-    };
+    static void GenKey(const GrProcessor&, const GrGLCaps& caps, GrProcessorKeyBuilder* b) {};
 
 private:
     typedef GrGLXferProcessor INHERITED;
@@ -86,10 +64,7 @@ private:
 
 GrPorterDuffXferProcessor::GrPorterDuffXferProcessor(GrBlendCoeff srcBlend, GrBlendCoeff dstBlend,
                                                      GrColor constant)
-    : fSrcBlend(srcBlend)
-    , fDstBlend(dstBlend)
-    , fBlendConstant(constant)
-    , fSecondaryOutputType(kNone_SecondaryOutputType) {
+    : fSrcBlend(srcBlend), fDstBlend(dstBlend), fBlendConstant(constant) {
     this->initClassID<GrPorterDuffXferProcessor>();
 }
 
@@ -101,7 +76,7 @@ void GrPorterDuffXferProcessor::getGLProcessorKey(const GrGLCaps& caps,
     GrGLPorterDuffXferProcessor::GenKey(*this, caps, b);
 }
 
-GrGLXferProcessor* GrPorterDuffXferProcessor::createGLInstance() const {
+GrGLFragmentProcessor* GrPorterDuffXferProcessor::createGLInstance() const {
     return SkNEW_ARGS(GrGLPorterDuffXferProcessor, (*this));
 }
 
@@ -115,54 +90,7 @@ GrPorterDuffXferProcessor::getOptimizations(const GrProcOptInfo& colorPOI,
                                             bool isCoverageDrawing,
                                             bool colorWriteDisabled,
                                             bool doesStencilWrite,
-                                            GrColor* color, uint8_t* coverage,
-                                            const GrDrawTargetCaps& caps) {
-    GrXferProcessor::OptFlags optFlags = this->internalGetOptimizations(colorPOI,
-                                                                        coveragePOI,
-                                                                        isCoverageDrawing,
-                                                                        colorWriteDisabled,
-                                                                        doesStencilWrite,
-                                                                        color,
-                                                                        coverage);
-
-    this->calcOutputTypes(optFlags, caps, isCoverageDrawing,
-                          colorPOI.readsDst() || coveragePOI.readsDst());
-    return optFlags;
-}
-
-void GrPorterDuffXferProcessor::calcOutputTypes(GrXferProcessor::OptFlags optFlags,
-                                                const GrDrawTargetCaps& caps,
-                                                bool isCoverageDrawing, bool readsDst) {
-    // If we do have coverage determine whether it matters.  Dual source blending is expensive so
-    // we don't do it if we are doing coverage drawing.  If we aren't then We always do dual source
-    // blending if we have any effective coverage stages OR the geometry processor doesn't emits
-    // solid coverage.
-    if (!(optFlags & kSetCoverageDrawing_OptFlag) && !isCoverageDrawing) {
-        if (caps.dualSourceBlendingSupport()) {
-            if (kZero_GrBlendCoeff == fDstBlend) {
-                // write the coverage value to second color
-                fSecondaryOutputType = kCoverage_SecondaryOutputType;
-                fDstBlend = (GrBlendCoeff)GrGpu::kIS2C_GrBlendCoeff;
-            } else if (kSA_GrBlendCoeff == fDstBlend) {
-                // SA dst coeff becomes 1-(1-SA)*coverage when dst is partially covered.
-                fSecondaryOutputType = kCoverageISA_SecondaryOutputType;
-                fDstBlend = (GrBlendCoeff)GrGpu::kIS2C_GrBlendCoeff;
-            } else if (kSC_GrBlendCoeff == fDstBlend) {
-                // SA dst coeff becomes 1-(1-SA)*coverage when dst is partially covered.
-                fSecondaryOutputType = kCoverageISC_SecondaryOutputType;
-                fDstBlend = (GrBlendCoeff)GrGpu::kIS2C_GrBlendCoeff;
-            }
-        }
-    }
-}
-
-GrXferProcessor::OptFlags
-GrPorterDuffXferProcessor::internalGetOptimizations(const GrProcOptInfo& colorPOI,
-                                                    const GrProcOptInfo& coveragePOI,
-                                                    bool isCoverageDrawing,
-                                                    bool colorWriteDisabled,
-                                                    bool doesStencilWrite,
-                                                    GrColor* color, uint8_t* coverage) {
+                                            GrColor* color, uint8_t* coverage) {
     if (colorWriteDisabled) {
         fSrcBlend = kZero_GrBlendCoeff;
         fDstBlend = kOne_GrBlendCoeff;
@@ -264,11 +192,6 @@ GrPorterDuffXferProcessor::internalGetOptimizations(const GrProcOptInfo& colorPO
 
     return GrXferProcessor::kNone_Opt;
 }
-
-bool GrPorterDuffXferProcessor::hasSecondaryOutput() const {
-    return kNone_SecondaryOutputType != fSecondaryOutputType;
-}
-
 ///////////////////////////////////////////////////////////////////////////////
 
 GrPorterDuffXPFactory::GrPorterDuffXPFactory(GrBlendCoeff src, GrBlendCoeff dst)
@@ -527,22 +450,4 @@ bool GrPorterDuffXPFactory::getOpaqueAndKnownColor(const GrProcOptInfo& colorPOI
     return opaque;
 }
 
-GR_DEFINE_XP_FACTORY_TEST(GrPorterDuffXPFactory);
-
-GrXPFactory* GrPorterDuffXPFactory::TestCreate(SkRandom* random,
-                                               GrContext*,
-                                               const GrDrawTargetCaps&,
-                                               GrTexture*[]) {
-    GrBlendCoeff src;
-    do {
-        src = GrBlendCoeff(random->nextRangeU(kFirstPublicGrBlendCoeff, kLastPublicGrBlendCoeff));
-    } while (GrBlendCoeffRefsSrc(src));
-
-    GrBlendCoeff dst;
-    do {
-        dst = GrBlendCoeff(random->nextRangeU(kFirstPublicGrBlendCoeff, kLastPublicGrBlendCoeff));
-    } while (GrBlendCoeffRefsDst(dst));
-
-    return GrPorterDuffXPFactory::Create(src, dst);
-}
 
index a4fad753ec668ae276f6c0e725f3d41b83d4c9b9..6dccd33bac40764f5adba2b7762ccdabd3a53e0a 100644 (file)
@@ -117,4 +117,14 @@ private:
     typedef GrGLProcessor INHERITED;
 };
 
+class GrGLXferProcessor : public GrGLFragmentProcessor {
+public:
+    GrGLXferProcessor() {}
+    
+    virtual ~GrGLXferProcessor() {}
+
+private:
+    typedef GrGLFragmentProcessor INHERITED;
+};
+
 #endif
index da687c1eb6e5c84db74832be88e00b105d9d702e..29c44ac56ccb9e92181b4b254c999857f325dadb 100644 (file)
 #include "GrCoordTransform.h"
 #include "GrGLGeometryProcessor.h"
 #include "GrGLProcessor.h"
-#include "GrGLXferProcessor.h"
 #include "GrGpuGL.h"
 #include "GrGLPathRendering.h"
 #include "GrGLShaderVar.h"
 #include "GrGLSL.h"
 #include "GrOptDrawState.h"
-#include "GrXferProcessor.h"
 #include "SkXfermode.h"
 
 #define GL_CALL(X) GR_GL_CALL(fGpu->glInterface(), X)
@@ -59,7 +57,6 @@ GrGLProgram::GrGLProgram(GrGpuGL* gpu,
                          GrGLuint programID,
                          const UniformInfoArray& uniforms,
                          GrGLInstalledGeoProc* geometryProcessor,
-                         GrGLInstalledXferProc* xferProcessor,
                          GrGLInstalledFragProcs* fragmentProcessors)
     : fColor(GrColor_ILLEGAL)
     , fCoverage(0)
@@ -67,7 +64,6 @@ GrGLProgram::GrGLProgram(GrGpuGL* gpu,
     , fBuiltinUniformHandles(builtinUniforms)
     , fProgramID(programID)
     , fGeometryProcessor(geometryProcessor)
-    , fXferProcessor(xferProcessor)
     , fFragmentProcessors(SkRef(fragmentProcessors))
     , fDesc(desc)
     , fGpu(gpu)
@@ -95,9 +91,6 @@ void GrGLProgram::initSamplerUniforms() {
     if (fGeometryProcessor.get()) {
         this->initSamplers(fGeometryProcessor.get(), &texUnitIdx);
     }
-    if (fXferProcessor.get()) {
-        this->initSamplers(fXferProcessor.get(), &texUnitIdx);
-    }
     int numProcs = fFragmentProcessors->fProcs.count();
     for (int i = 0; i < numProcs; i++) {
         this->initSamplers(fFragmentProcessors->fProcs[i], &texUnitIdx);
@@ -169,11 +162,6 @@ void GrGLProgram::setData(const GrOptDrawState& optState) {
         fGeometryProcessor->fGLProc->setData(fProgramDataManager, gp, bt);
         this->bindTextures(fGeometryProcessor, gp);
     }
-    if (fXferProcessor.get()) {
-        const GrXferProcessor& xp = *optState.getXferProcessor();
-        fXferProcessor->fGLProc->setData(fProgramDataManager, xp);
-        this->bindTextures(fXferProcessor, xp);
-    }
     this->setFragmentData(optState);
 
     // Some of GrGLProgram subclasses need to update state here
@@ -296,10 +284,8 @@ GrGLNvprProgramBase::GrGLNvprProgramBase(GrGpuGL* gpu,
                                          const BuiltinUniformHandles& builtinUniforms,
                                          GrGLuint programID,
                                          const UniformInfoArray& uniforms,
-                                         GrGLInstalledXferProc* xferProcessor,
                                          GrGLInstalledFragProcs* fragmentProcessors)
-    : INHERITED(gpu, desc, builtinUniforms, programID, uniforms, NULL,
-                xferProcessor, fragmentProcessors) {
+    : INHERITED(gpu, desc, builtinUniforms, programID, uniforms, NULL, fragmentProcessors) {
 }
 
 void GrGLNvprProgramBase::onSetMatrixAndRenderTargetHeight(const GrOptDrawState& optState) {
@@ -317,11 +303,9 @@ GrGLNvprProgram::GrGLNvprProgram(GrGpuGL* gpu,
                                  const BuiltinUniformHandles& builtinUniforms,
                                  GrGLuint programID,
                                  const UniformInfoArray& uniforms,
-                                 GrGLInstalledXferProc* xferProcessor,
                                  GrGLInstalledFragProcs* fragmentProcessors,
                                  const SeparableVaryingInfoArray& separableVaryings)
-    : INHERITED(gpu, desc, builtinUniforms, programID, uniforms,
-                xferProcessor, fragmentProcessors) {
+    : INHERITED(gpu, desc, builtinUniforms, programID, uniforms, fragmentProcessors) {
     int count = separableVaryings.count();
     fVaryings.push_back_n(count);
     for (int i = 0; i < count; i++) {
@@ -369,10 +353,9 @@ GrGLLegacyNvprProgram::GrGLLegacyNvprProgram(GrGpuGL* gpu,
                                              const BuiltinUniformHandles& builtinUniforms,
                                              GrGLuint programID,
                                              const UniformInfoArray& uniforms,
-                                             GrGLInstalledXferProc* xp,
                                              GrGLInstalledFragProcs* fps,
                                              int texCoordSetCnt)
-    : INHERITED(gpu, desc, builtinUniforms, programID, uniforms, xp, fps)
+    : INHERITED(gpu, desc, builtinUniforms, programID, uniforms, fps)
     , fTexCoordSetCnt(texCoordSetCnt) {
 }
 
index ea8be85251c6bcfaf3e98218a80cb981fee41117..36bf8602330e55c9a1fe9f5e12c8aec0fafd29f9 100644 (file)
@@ -141,7 +141,6 @@ protected:
                 GrGLuint programID,
                 const UniformInfoArray&,
                 GrGLInstalledGeoProc* geometryProcessor,
-                GrGLInstalledXferProc* xferProcessor,
                 GrGLInstalledFragProcs* fragmentProcessors);
 
     // Sets the texture units for samplers.
@@ -181,7 +180,6 @@ protected:
 
     // the installed effects
     SkAutoTDelete<GrGLInstalledGeoProc> fGeometryProcessor;
-    SkAutoTDelete<GrGLInstalledXferProc> fXferProcessor;
     SkAutoTUnref<GrGLInstalledFragProcs> fFragmentProcessors;
 
     GrProgramDesc fDesc;
@@ -207,7 +205,6 @@ protected:
                         const BuiltinUniformHandles&,
                         GrGLuint programID,
                         const UniformInfoArray&,
-                        GrGLInstalledXferProc* xferProcessor,
                         GrGLInstalledFragProcs* fragmentProcessors);
     virtual void onSetMatrixAndRenderTargetHeight(const GrOptDrawState&);
 
@@ -226,7 +223,6 @@ private:
                     const BuiltinUniformHandles&,
                     GrGLuint programID,
                     const UniformInfoArray&,
-                    GrGLInstalledXferProc* xferProcessor,
                     GrGLInstalledFragProcs* fragmentProcessors,
                     const SeparableVaryingInfoArray& separableVaryings);
     virtual void didSetData(GrGpu::DrawType) SK_OVERRIDE;
@@ -256,8 +252,7 @@ private:
                           const BuiltinUniformHandles&,
                           GrGLuint programID,
                           const UniformInfoArray&,
-                          GrGLInstalledXferProc* xp,
-                          GrGLInstalledFragProcs* fps,
+                          GrGLInstalledFragProcs* fragmentProcessors,
                           int texCoordSetCnt);
     virtual void didSetData(GrGpu::DrawType) SK_OVERRIDE;
     virtual void setTransformData(const GrPendingFragmentStage&,
index 2476c5532cc3cd89cc14af1c7ccdf4e53ccc6112..068386c3aa94a5e761da2620714967de81b6d842 100644 (file)
@@ -189,21 +189,13 @@ bool GrGLProgramDescBuilder::Build(const GrOptDrawState& optState,
         const GrFragmentProcessor& fp = *fps.getProcessor();
         GrProcessorKeyBuilder b(&desc->fKey);
         fp.getGLProcessorKey(gpu->glCaps(), &b);
-        if (!get_meta_key(fp, gpu->glCaps(),
-                          gen_transform_key(fps, requiresLocalCoordAttrib), 0, &b)) {
+        if (!get_meta_key(*fps.getProcessor(), gpu->glCaps(),
+                         gen_transform_key(fps, requiresLocalCoordAttrib), 0, &b)) {
             desc->fKey.reset();
             return false;
         }
     }
 
-    const GrXferProcessor& xp = *optState.getXferProcessor();
-    GrProcessorKeyBuilder b(&desc->fKey);
-    xp.getGLProcessorKey(gpu->glCaps(), &b);
-    if (!get_meta_key(xp, gpu->glCaps(), 0, 0, &b)) {
-        desc->fKey.reset();
-        return false;
-    }
-
     // --------DO NOT MOVE HEADER ABOVE THIS LINE--------------------------------------------------
     // Because header is a pointer into the dynamic array, we can't push any new data into the key
     // below here.
@@ -268,6 +260,9 @@ bool GrGLProgramDescBuilder::Build(const GrOptDrawState& optState,
         header->fFragPosKey = 0;
     }
 
+    header->fPrimaryOutputType = descInfo.fPrimaryOutputType;
+    header->fSecondaryOutputType = descInfo.fSecondaryOutputType;
+
     header->fColorEffectCnt = optState.numColorStages();
     header->fCoverageEffectCnt = optState.numCoverageStages();
     desc->finalize();
diff --git a/src/gpu/gl/GrGLXferProcessor.h b/src/gpu/gl/GrGLXferProcessor.h
deleted file mode 100644 (file)
index 5c92559..0000000
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Copyright 2014 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#ifndef GrGLXferProcessor_DEFINED
-#define GrGLXferProcessor_DEFINED
-
-#include "GrGLProcessor.h"
-
-class GrGLXPBuilder;
-
-class GrGLXferProcessor {
-public:
-    GrGLXferProcessor() {}
-    virtual ~GrGLXferProcessor() {}
-
-    typedef GrGLProcessor::TextureSamplerArray TextureSamplerArray;
-    struct EmitArgs {
-        EmitArgs(GrGLXPBuilder* pb,
-                 const GrXferProcessor& xp,
-                 const char* inputColor,
-                 const char* inputCoverage,
-                 const char* outputPrimary,
-                 const char* outputSecondary,
-                 const TextureSamplerArray& samplers)
-            : fPB(pb)
-            , fXP(xp)
-            , fInputColor(inputColor)
-            , fInputCoverage(inputCoverage)
-            , fOutputPrimary(outputPrimary)
-            , fOutputSecondary(outputSecondary)
-            , fSamplers(samplers) {}
-
-        GrGLXPBuilder* fPB;
-        const GrXferProcessor& fXP;
-        const char* fInputColor;
-        const char* fInputCoverage;
-        const char* fOutputPrimary;
-        const char* fOutputSecondary;
-        const TextureSamplerArray& fSamplers;
-    };
-    /**
-     * This is similar to emitCode() in the base class, except it takes a full shader builder.
-     * This allows the effect subclass to emit vertex code.
-     */
-    virtual void emitCode(const EmitArgs&) = 0;
-
-    /** A GrGLXferProcessor instance can be reused with any GrGLXferProcessor that produces
-        the same stage key; this function reads data from a GrGLXferProcessor and uploads any
-        uniform variables required  by the shaders created in emitCode(). The GrXferProcessor
-        parameter is guaranteed to be of the same type that created this GrGLXferProcessor and
-        to have an identical processor key as the one that created this GrGLXferProcessor.  */
-    virtual void setData(const GrGLProgramDataManager&,
-                         const GrXferProcessor&) = 0;
-private:
-    typedef GrGLProcessor INHERITED;
-};
-#endif
index b6daca797865e7055561ebeb11a494a094682176..49be12d8badf82f2aa910b9fd00f1c449568c1fc 100644 (file)
@@ -256,6 +256,55 @@ const char* GrGLFragmentShaderBuilder::getSecondaryColorOutputName() const {
     return dual_source_output_name();
 }
 
+void GrGLFragmentShaderBuilder::enableSecondaryOutput(const GrGLSLExpr4& inputColor,
+                                                      const GrGLSLExpr4& inputCoverage) {
+    this->enableSecondaryOutput();
+    const char* secondaryOutputName = this->getSecondaryColorOutputName();
+    GrGLSLExpr4 coeff(1);
+    switch (fProgramBuilder->header().fSecondaryOutputType) {
+        case GrProgramDesc::kCoverage_SecondaryOutputType:
+            break;
+        case GrProgramDesc::kCoverageISA_SecondaryOutputType:
+            // Get (1-A) into coeff
+            coeff = GrGLSLExpr4::VectorCast(GrGLSLExpr1(1) - inputColor.a());
+            break;
+        case GrProgramDesc::kCoverageISC_SecondaryOutputType:
+            // Get (1-RGBA) into coeff
+            coeff = GrGLSLExpr4(1) - inputColor;
+            break;
+        default:
+            SkFAIL("Unexpected Secondary Output");
+    }
+    // Get coeff * coverage into modulate and then write that to the dual source output.
+    this->codeAppendf("\t%s = %s;\n", secondaryOutputName, (coeff * inputCoverage).c_str());
+}
+
+void GrGLFragmentShaderBuilder::combineColorAndCoverage(const GrGLSLExpr4& inputColor,
+                                                        const GrGLSLExpr4& inputCoverage) {
+    GrGLSLExpr4 fragColor = inputColor * inputCoverage;
+    switch (fProgramBuilder->header().fPrimaryOutputType) {
+        case GrProgramDesc::kModulate_PrimaryOutputType:
+            break;
+        case GrProgramDesc::kCombineWithDst_PrimaryOutputType:
+            {
+                // Tack on "+(1-coverage)dst onto the frag color.
+                GrGLSLExpr4 dstCoeff = GrGLSLExpr4(1) - inputCoverage;
+                GrGLSLExpr4 dstContribution = dstCoeff * GrGLSLExpr4(this->dstColor());
+                fragColor = fragColor + dstContribution;
+            }
+            break;
+        default:
+            SkFAIL("Unknown Primary Output");
+    }
+
+    // On any post 1.10 GLSL supporting GPU, we declare custom output
+    if (k110_GrGLSLGeneration != fProgramBuilder->gpu()->glslGeneration()) {
+        this->enableCustomOutput();
+    }
+
+    this->codeAppendf("\t%s = %s;\n", this->getPrimaryColorOutputName(), fragColor.c_str());
+}
+
 bool GrGLFragmentShaderBuilder::compileAndAttachShaders(GrGLuint programId,
                                                         SkTDArray<GrGLuint>* shaderIds) const {
     GrGpuGL* gpu = fProgramBuilder->gpu();
index 456ec4f27cddb7eec0253444bf97bcc33f78a30b..03f0e7f7a673d5e3f85be2123e0c0b17dfe2057a 100644 (file)
@@ -100,6 +100,8 @@ private:
     void enableSecondaryOutput();
     const char* getPrimaryColorOutputName() const;
     const char* getSecondaryColorOutputName() const;
+    void enableSecondaryOutput(const GrGLSLExpr4& inputColor, const GrGLSLExpr4& inputCoverage);
+    void combineColorAndCoverage(const GrGLSLExpr4& inputColor, const GrGLSLExpr4& inputCoverage);
     bool compileAndAttachShaders(GrGLuint programId, SkTDArray<GrGLuint>* shaderIds) const;
     void bindFragmentShaderLocations(GrGLuint programID);
 
index b90bab2c1d8dec6f25878dfbf956ea1f1e98db0e..b251593bfeb22185acddd7e557dc64378d27cdbf 100644 (file)
@@ -45,6 +45,5 @@ void GrGLLegacyNvprProgramBuilder::emitTransforms(const GrPendingFragmentStage&
 
 GrGLProgram* GrGLLegacyNvprProgramBuilder::createProgram(GrGLuint programID) {
     return SkNEW_ARGS(GrGLLegacyNvprProgram, (fGpu, fDesc, fUniformHandles, programID, fUniforms,
-                                              fXferProcessor, fFragmentProcessors.get(),
-                                              fTexCoordSetCnt));
+                                              fFragmentProcessors.get(),  fTexCoordSetCnt));
 }
index ba19275f6facca6abd021218db5956eee2a059fe..f5a55866eecb15b3d1e5ff4af90d6e334d36f76b 100644 (file)
@@ -72,6 +72,5 @@ GrGLProgram* GrGLNvprProgramBuilder::createProgram(GrGLuint programID) {
     // building
     this->resolveSeparableVaryings(programID);
     return SkNEW_ARGS(GrGLNvprProgram, (fGpu, fDesc, fUniformHandles, programID, fUniforms,
-                                        fXferProcessor, fFragmentProcessors.get(),
-                                        fSeparableVaryingInfos));
+                                        fFragmentProcessors.get(), fSeparableVaryingInfos));
 }
index daa0b6ba064205fccc2f89605d07f35bb6828841..7929801bbf29699285eab5110db5b8602f7b8897 100644 (file)
@@ -9,7 +9,6 @@
 #include "gl/GrGLProgram.h"
 #include "gl/GrGLSLPrettyPrint.h"
 #include "gl/GrGLUniformHandle.h"
-#include "../GrGLXferProcessor.h"
 #include "../GrGpuGL.h"
 #include "GrCoordTransform.h"
 #include "GrGLLegacyNvprProgramBuilder.h"
@@ -56,12 +55,20 @@ GrGLProgram* GrGLProgramBuilder::CreateProgram(const GrOptDrawState& optState, G
 
     pb->emitAndInstallProcs(&inputColor, &inputCoverageVec4);
 
+    // write the secondary color output if necessary
+    if (GrProgramDesc::kNone_SecondaryOutputType != header.fSecondaryOutputType) {
+        pb->fFS.enableSecondaryOutput(inputColor, inputCoverageVec4);
+    }
+
+    pb->fFS.combineColorAndCoverage(inputColor, inputCoverageVec4);
+
     return pb->finalize();
 }
 
-GrGLProgramBuilder* GrGLProgramBuilder::CreateProgramBuilder(const GrOptDrawState& optState,
-                                                             bool hasGeometryProcessor,
-                                                             GrGpuGL* gpu) {
+GrGLProgramBuilder*
+GrGLProgramBuilder::CreateProgramBuilder(const GrOptDrawState& optState,
+                                         bool hasGeometryProcessor,
+                                         GrGpuGL* gpu) {
     const GrProgramDesc& desc = optState.programDesc();
     if (GrGLProgramDescBuilder::GetHeader(desc).fUseNvpr) {
         SkASSERT(gpu->glCaps().pathRenderingSupport());
@@ -88,7 +95,6 @@ GrGLProgramBuilder::GrGLProgramBuilder(GrGpuGL* gpu, const GrOptDrawState& optSt
     , fOutOfStage(true)
     , fStageIndex(-1)
     , fGeometryProcessor(NULL)
-    , fXferProcessor(NULL)
     , fOptState(optState)
     , fDesc(optState.programDesc())
     , fGpu(gpu)
@@ -254,8 +260,6 @@ void GrGLProgramBuilder::emitAndInstallProcs(GrGLSLExpr4* inputColor, GrGLSLExpr
     if (fOptState.hasGeometryProcessor()) {
         fVS.transformToNormalizedDeviceSpace();
     }
-
-    this->emitAndInstallXferProc(*fOptState.getXferProcessor(), *inputColor, *inputCoverage);
 }
 
 void GrGLProgramBuilder::emitAndInstallFragProcs(int procOffset,
@@ -364,55 +368,10 @@ void GrGLProgramBuilder::emitAndInstallProc(const GrGeometryProcessor& gp,
     verify(gp);
 }
 
-void GrGLProgramBuilder::emitAndInstallXferProc(const GrXferProcessor& xp,
-                                                const GrGLSLExpr4& colorIn,
-                                                const GrGLSLExpr4& coverageIn) {
-    // Program builders have a bit of state we need to clear with each effect
-    AutoStageAdvance adv(this);
-
-    SkASSERT(!fXferProcessor);
-    fXferProcessor = SkNEW(GrGLInstalledXferProc);
-
-    fXferProcessor->fGLProc.reset(xp.createGLInstance());
-
-    // Enable dual source secondary output if we have one
-    if (xp.hasSecondaryOutput()) {
-        fFS.enableSecondaryOutput();
-    }
-
-    // On any post 1.10 GLSL supporting GPU, we declare custom output
-    if (k110_GrGLSLGeneration != fFS.fProgramBuilder->gpu()->glslGeneration()) {
-        fFS.enableCustomOutput();
-    }
-
-    SkString openBrace;
-    openBrace.printf("{ // Xfer Processor: %s\n", xp.name());
-    fFS.codeAppend(openBrace.c_str());
-
-    SkSTArray<4, GrGLProcessor::TextureSampler> samplers(xp.numTextures());
-    this->emitSamplers(xp, &samplers, fXferProcessor);
-
-    GrGLXferProcessor::EmitArgs args(this, xp, colorIn.c_str(), coverageIn.c_str(),
-                                     fFS.getPrimaryColorOutputName(),
-                                     fFS.getSecondaryColorOutputName(), samplers);
-    fXferProcessor->fGLProc->emitCode(args);
-
-    // 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(xp);
-    fFS.codeAppend("}");
-}
-
 void GrGLProgramBuilder::verify(const GrGeometryProcessor& gp) {
     SkASSERT(fFS.hasReadFragmentPosition() == gp.willReadFragmentPosition());
 }
 
-void GrGLProgramBuilder::verify(const GrXferProcessor& xp) {
-    // TODO: Once will readDst is only xp enable this assert and remove it from the
-    // FragmentProcessor verify()
-    //SkASSERT(fFS.hasReadDstColor() == xp.willReadDstColor());
-}
-
 void GrGLProgramBuilder::verify(const GrFragmentProcessor& fp) {
     SkASSERT(fFS.hasReadFragmentPosition() == fp.willReadFragmentPosition());
     SkASSERT(fFS.hasReadDstColor() == fp.willReadDstColor());
@@ -584,7 +543,7 @@ void GrGLProgramBuilder::cleanupShaders(const SkTDArray<GrGLuint>& shaderIDs) {
 
 GrGLProgram* GrGLProgramBuilder::createProgram(GrGLuint programID) {
     return SkNEW_ARGS(GrGLProgram, (fGpu, fDesc, fUniformHandles, programID, fUniforms,
-                                    fGeometryProcessor, fXferProcessor, fFragmentProcessors.get()));
+                                    fGeometryProcessor, fFragmentProcessors.get()));
 }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
index 69eed27252f9c37cad2588988d6a688659e0d878..1798e604db121bda747bace1d4923b89beb1e28c 100644 (file)
@@ -14,7 +14,6 @@
 #include "../GrGLProgramDataManager.h"
 #include "../GrGLUniformHandle.h"
 #include "../GrGLGeometryProcessor.h"
-#include "../GrGLXferProcessor.h"
 #include "../../GrOptDrawState.h"
 #include "../../GrPendingFragmentStage.h"
 
@@ -112,7 +111,6 @@ private:
 
     friend class GrGLVertexBuilder;
     friend class GrGLGeometryBuilder;
-    friend class GrGLXferBuilder;
     friend class GrGLFragmentShaderBuilder;
 };
 
@@ -172,18 +170,8 @@ public:
      */
 };
 
-/* a specializations for XPs. Lets the user add uniforms and FS code */
-class GrGLXPBuilder : public virtual GrGLUniformBuilder {
-public:
-    virtual GrGLFPFragmentBuilder* getFragmentShaderBuilder() = 0;
-
-    /*
-     * *NOTE* NO MEMBERS ALLOWED, MULTIPLE INHERITANCE
-     */
-};
 struct GrGLInstalledProc;
 struct GrGLInstalledGeoProc;
-struct GrGLInstalledXferProc;
 struct GrGLInstalledFragProc;
 struct GrGLInstalledFragProcs;
 
@@ -195,8 +183,7 @@ struct GrGLInstalledFragProcs;
  * respective builders
 */
 class GrGLProgramBuilder : public GrGLGPBuilder,
-                           public GrGLFPBuilder,
-                           public GrGLXPBuilder {
+                           public GrGLFPBuilder {
 public:
     /** Generates a shader program.
      *
@@ -296,12 +283,8 @@ protected:
     void emitAndInstallProc(const GrGeometryProcessor&,
                             const char* outColor,
                             const char* outCoverage);
-    void emitAndInstallXferProc(const GrXferProcessor&,
-                                const GrGLSLExpr4& colorIn,
-                                const GrGLSLExpr4& coverageIn);
 
     void verify(const GrGeometryProcessor&);
-    void verify(const GrXferProcessor&);
     void verify(const GrFragmentProcessor&);
     void emitSamplers(const GrProcessor&,
                       GrGLProcessor::TextureSamplerArray* outSamplers,
@@ -375,7 +358,6 @@ protected:
     int fStageIndex;
 
     GrGLInstalledGeoProc* fGeometryProcessor;
-    GrGLInstalledXferProc* fXferProcessor;
     SkAutoTUnref<GrGLInstalledFragProcs> fFragmentProcessors;
 
     const GrOptDrawState& fOptState;
@@ -409,10 +391,6 @@ struct GrGLInstalledGeoProc : public GrGLInstalledProc {
     SkAutoTDelete<GrGLGeometryProcessor> fGLProc;
 };
 
-struct GrGLInstalledXferProc : public GrGLInstalledProc {
-    SkAutoTDelete<GrGLXferProcessor> fGLProc;
-};
-
 struct GrGLInstalledFragProc : public GrGLInstalledProc {
     GrGLInstalledFragProc() : fGLProc(NULL) {}
     class ShaderVarHandle {
index 953b5e07cbcc45e05dd07a25871f4bf316a3fcdc..253e4aeccc265ceff7c58582a261c8cbc0f6abdf 100644 (file)
@@ -121,14 +121,6 @@ static GrRenderTarget* random_render_target(GrContext* context,
     return SkRef(texture->asRenderTarget());
 }
 
-static void set_random_xpf(GrContext* context, const GrDrawTargetCaps& caps, GrDrawState* ds,
-                           SkRandom* random, GrTexture* dummyTextures[]) {
-    SkAutoTUnref<const GrXPFactory> xpf(
-        GrProcessorTestFactory<GrXPFactory>::CreateStage(random, context, caps, dummyTextures));
-    SkASSERT(xpf);
-    ds->setXPFactory(xpf.get());
-}
-
 static void set_random_gp(GrContext* context,
                           const GrDrawTargetCaps& caps,
                           GrDrawState* ds,
@@ -203,6 +195,22 @@ static void set_random_state(GrDrawState* ds, SkRandom* random) {
     ds->enableState(state);
 }
 
+// this function will randomly pick non-self referencing blend modes
+static void set_random_blend_func(GrDrawState* ds, SkRandom* random) {
+    GrBlendCoeff src;
+    do {
+        src = GrBlendCoeff(random->nextRangeU(kFirstPublicGrBlendCoeff, kLastPublicGrBlendCoeff));
+    } while (GrBlendCoeffRefsSrc(src));
+
+    GrBlendCoeff dst;
+    do {
+        dst = GrBlendCoeff(random->nextRangeU(kFirstPublicGrBlendCoeff, kLastPublicGrBlendCoeff));
+    } while (GrBlendCoeffRefsDst(dst));
+
+    GrXPFactory* xpFactory = GrPorterDuffXPFactory::Create(src, dst);
+    ds->setXPFactory(xpFactory)->unref();
+}
+
 // right now, the only thing we seem to care about in drawState's stencil is 'doesWrite()'
 static void set_random_stencil(GrDrawState* ds, SkRandom* random) {
     GR_STATIC_CONST_SAME_STENCIL(kDoesWriteStencil,
@@ -302,12 +310,9 @@ bool GrDrawTarget::programUnitTest(int maxStages) {
                                          usePathRendering,
                                          &random,
                                          dummyTextures);
-
-        // creates a random xfer processor factory on the draw state 
-        set_random_xpf(fContext, gpu->glCaps(), &ds, &random, dummyTextures);
-
         set_random_hints(&ds, &random);
         set_random_state(&ds, &random);
+        set_random_blend_func(&ds, &random);
         set_random_stencil(&ds, &random);
 
         GrDeviceCoordTexture dstCopy;