Only discard for XP dstCopies if we have a coverage value.
authoregdaniel <egdaniel@google.com>
Sun, 10 May 2015 15:45:18 +0000 (08:45 -0700)
committerCommit bot <commit-bot@chromium.org>
Sun, 10 May 2015 15:45:18 +0000 (08:45 -0700)
TBR=bsalomon@google.com

BUG=skia:

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

include/gpu/GrXferProcessor.h
src/effects/SkArithmeticMode_gpu.cpp
src/gpu/GrXferProcessor.cpp
src/gpu/effects/GrCoverageSetOpXP.cpp
src/gpu/effects/GrCustomXfermode.cpp
src/gpu/effects/GrDisableColorXP.cpp
src/gpu/effects/GrPorterDuffXferProcessor.cpp
src/gpu/gl/GrGLXferProcessor.cpp

index 7c07b8027d41593cc4de73e7c37d4afa5e5f6309..812ce5c64cb050372b3bac37a0489a33a23b913c 100644 (file)
@@ -164,11 +164,11 @@ public:
      * A caller who calls this function on a XP is required to honor the returned OptFlags
      * and color values for its draw.
      */
-    virtual OptFlags getOptimizations(const GrProcOptInfo& colorPOI,
-                                      const GrProcOptInfo& coveragePOI,
-                                      bool doesStencilWrite,
-                                      GrColor* overrideColor,
-                                      const GrDrawTargetCaps& caps) = 0;
+    OptFlags getOptimizations(const GrProcOptInfo& colorPOI,
+                              const GrProcOptInfo& coveragePOI,
+                              bool doesStencilWrite,
+                              GrColor* overrideColor,
+                              const GrDrawTargetCaps& caps);
 
     /**
      * Returns whether this XP will require an Xfer barrier on the given rt. If true, outBarrierType
@@ -217,6 +217,11 @@ public:
         return fDstCopyTextureOffset;
     }
 
+    /**
+     * Returns whether or not the XP will look at coverage when doing its blending.
+     */
+    bool readsCoverage() const { return fReadsCoverage; }
+
     /** 
      * Returns whether or not this xferProcossor will set a secondary output to be used with dual
      * source blending.
@@ -237,6 +242,9 @@ public:
         if (this->fWillReadDstColor != that.fWillReadDstColor) {
             return false;
         }
+        if (this->fReadsCoverage != that.fReadsCoverage) {
+            return false;
+        }
         if (this->fDstCopy.getTexture() != that.fDstCopy.getTexture()) {
             return false;
         }
@@ -251,6 +259,12 @@ protected:
     GrXferProcessor(const GrDeviceCoordTexture* dstCopy, bool willReadDstColor);
 
 private:
+    virtual OptFlags onGetOptimizations(const GrProcOptInfo& colorPOI,
+                                        const GrProcOptInfo& coveragePOI,
+                                        bool doesStencilWrite,
+                                        GrColor* overrideColor,
+                                        const GrDrawTargetCaps& caps) = 0;
+
     /**
      * Sets a unique key on the GrProcessorKeyBuilder that is directly associated with this xfer
      * processor's GL backend implementation.
@@ -278,6 +292,7 @@ private:
     virtual bool onIsEqual(const GrXferProcessor&) const = 0;
 
     bool                    fWillReadDstColor;
+    bool                    fReadsCoverage;
     SkIPoint                fDstCopyTextureOffset;
     GrTextureAccess         fDstCopy;
 
index bd87931eb4a43c9865e9fe02dd908d0e25f9f8d7..69c2d7c0fdf25901cc9bd0ec492d268fb83ec5fd 100644 (file)
@@ -175,12 +175,6 @@ public:
 
     bool hasSecondaryOutput() const override { return false; }
 
-    GrXferProcessor::OptFlags getOptimizations(const GrProcOptInfo& colorPOI,
-                                               const GrProcOptInfo& coveragePOI,
-                                               bool doesStencilWrite,
-                                               GrColor* overrideColor,
-                                               const GrDrawTargetCaps& caps) override;
-
     float k1() const { return fK1; }
     float k2() const { return fK2; }
     float k3() const { return fK3; }
@@ -191,6 +185,12 @@ private:
     ArithmeticXP(float k1, float k2, float k3, float k4, bool enforcePMColor,
                    const GrDeviceCoordTexture* dstCopy, bool willReadDstColor);
 
+    GrXferProcessor::OptFlags onGetOptimizations(const GrProcOptInfo& colorPOI,
+                                                 const GrProcOptInfo& coveragePOI,
+                                                 bool doesStencilWrite,
+                                                 GrColor* overrideColor,
+                                                 const GrDrawTargetCaps& caps) override;
+
     void onGetGLProcessorKey(const GrGLSLCaps& caps, GrProcessorKeyBuilder* b) const override;
 
     bool onIsEqual(const GrXferProcessor& xpBase) const override {
@@ -281,11 +281,11 @@ GrGLXferProcessor* ArithmeticXP::createGLInstance() const {
     return SkNEW_ARGS(GLArithmeticXP, (*this));
 }
 
-GrXferProcessor::OptFlags ArithmeticXP::getOptimizations(const GrProcOptInfo& colorPOI,
-                                                         const GrProcOptInfo& coveragePOI,
-                                                         bool doesStencilWrite,
-                                                         GrColor* overrideColor,
-                                                         const GrDrawTargetCaps& caps) {
+GrXferProcessor::OptFlags ArithmeticXP::onGetOptimizations(const GrProcOptInfo& colorPOI,
+                                                           const GrProcOptInfo& coveragePOI,
+                                                           bool doesStencilWrite,
+                                                           GrColor* overrideColor,
+                                                           const GrDrawTargetCaps& caps) {
    return GrXferProcessor::kNone_Opt;
 }
 
index 243b9feb3f32edd6cee2386aaf10d91fb135f89b..bc79b2dbe1a3ea71c895a33a2886d6b91b57c899 100644 (file)
@@ -8,11 +8,13 @@
 #include "GrXferProcessor.h"
 #include "gl/GrGLCaps.h"
 
-GrXferProcessor::GrXferProcessor() : fWillReadDstColor(false), fDstCopyTextureOffset() {
+GrXferProcessor::GrXferProcessor()
+    : fWillReadDstColor(false), fReadsCoverage(true), fDstCopyTextureOffset() {
 }
 
 GrXferProcessor::GrXferProcessor(const GrDeviceCoordTexture* dstCopy, bool willReadDstColor)
     : fWillReadDstColor(willReadDstColor)
+    , fReadsCoverage(true)
     , fDstCopyTextureOffset() {
     if (dstCopy && dstCopy->texture()) {
         fDstCopy.reset(dstCopy->texture());
@@ -22,6 +24,23 @@ GrXferProcessor::GrXferProcessor(const GrDeviceCoordTexture* dstCopy, bool willR
     }
 }
 
+GrXferProcessor::OptFlags GrXferProcessor::getOptimizations(const GrProcOptInfo& colorPOI,
+                                                            const GrProcOptInfo& coveragePOI,
+                                                            bool doesStencilWrite,
+                                                            GrColor* overrideColor,
+                                                            const GrDrawTargetCaps& caps) {
+    GrXferProcessor::OptFlags flags = this->onGetOptimizations(colorPOI,
+                                                               coveragePOI,
+                                                               doesStencilWrite,
+                                                               overrideColor,
+                                                               caps);
+
+    if (flags & GrXferProcessor::kIgnoreCoverage_OptFlag) {
+        fReadsCoverage = false;
+    }
+    return flags;
+}
+
 void GrXferProcessor::getGLProcessorKey(const GrGLSLCaps& caps, GrProcessorKeyBuilder* b) const {
     uint32_t key = this->willReadDstColor() ? 0x1 : 0x0;
     if (this->getDstCopyTexture() &&
index 69b9ea417e23e473e1df4e63acd06db1e1f6f05c..02552b3bae8c7788a6c1b26a6304ee104e7141e5 100644 (file)
@@ -29,17 +29,17 @@ public:
 
     bool hasSecondaryOutput() const override { return false; }
 
-    GrXferProcessor::OptFlags getOptimizations(const GrProcOptInfo& colorPOI,
-                                               const GrProcOptInfo& coveragePOI,
-                                               bool doesStencilWrite,
-                                               GrColor* color,
-                                               const GrDrawTargetCaps& caps) override;
-
     bool invertCoverage() const { return fInvertCoverage; }
 
 private:
     CoverageSetOpXP(SkRegion::Op regionOp, bool fInvertCoverage);
 
+    GrXferProcessor::OptFlags onGetOptimizations(const GrProcOptInfo& colorPOI,
+                                                 const GrProcOptInfo& coveragePOI,
+                                                 bool doesStencilWrite,
+                                                 GrColor* color,
+                                                 const GrDrawTargetCaps& caps) override;
+
     void onGetGLProcessorKey(const GrGLSLCaps& caps, GrProcessorKeyBuilder* b) const override;
 
     void onGetBlendInfo(GrXferProcessor::BlendInfo* blendInfo) const override;
@@ -108,11 +108,11 @@ GrGLXferProcessor* CoverageSetOpXP::createGLInstance() const {
 }
 
 GrXferProcessor::OptFlags
-CoverageSetOpXP::getOptimizations(const GrProcOptInfo& colorPOI,
-                                  const GrProcOptInfo& coveragePOI,
-                                  bool doesStencilWrite,
-                                  GrColor* color,
-                                  const GrDrawTargetCaps& caps) {
+CoverageSetOpXP::onGetOptimizations(const GrProcOptInfo& colorPOI,
+                                    const GrProcOptInfo& coveragePOI,
+                                    bool doesStencilWrite,
+                                    GrColor* color,
+                                    const GrDrawTargetCaps& caps) {
     // We never look at the color input
     return GrXferProcessor::kIgnoreColor_OptFlag; 
 }
index b15e2c2b9a133ad47bae7cd672a65bec36a2fbee..0a525b4d9279933a4334b1fe19c7ac89a5cc020a 100644 (file)
@@ -525,14 +525,7 @@ public:
 
     bool hasSecondaryOutput() const override { return false; }
 
-    GrXferProcessor::OptFlags getOptimizations(const GrProcOptInfo& colorPOI,
-                                               const GrProcOptInfo& coveragePOI,
-                                               bool doesStencilWrite,
-                                               GrColor* overrideColor,
-                                               const GrDrawTargetCaps& caps) override;
-
     SkXfermode::Mode mode() const { return fMode; }
-    bool hasCoverage() const { return fHasCoverage; }
     bool hasHWBlendEquation() const { return kInvalid_GrBlendEquation != fHWBlendEquation; }
 
     GrBlendEquation hwBlendEquation() const {
@@ -543,6 +536,12 @@ public:
 private:
     CustomXP(SkXfermode::Mode mode, const GrDeviceCoordTexture* dstCopy, bool willReadDstColor);
 
+    GrXferProcessor::OptFlags onGetOptimizations(const GrProcOptInfo& colorPOI,
+                                                 const GrProcOptInfo& coveragePOI,
+                                                 bool doesStencilWrite,
+                                                 GrColor* overrideColor,
+                                                 const GrDrawTargetCaps& caps) override;
+
     void onGetGLProcessorKey(const GrGLSLCaps& caps, GrProcessorKeyBuilder* b) const override;
 
     bool onWillNeedXferBarrier(const GrRenderTarget* rt,
@@ -554,7 +553,6 @@ private:
     bool onIsEqual(const GrXferProcessor& xpBase) const override;
 
     SkXfermode::Mode fMode;
-    bool             fHasCoverage;
     GrBlendEquation  fHWBlendEquation;
 
     typedef GrXferProcessor INHERITED;
@@ -581,7 +579,7 @@ public:
         const CustomXP& xp = p.cast<CustomXP>();
         uint32_t key = xp.numTextures();
         SkASSERT(key <= 1);
-        key |= xp.hasCoverage() << 1;
+        key |= xp.readsCoverage() << 1;
         if (xp.hasHWBlendEquation()) {
             SkASSERT(caps.advBlendEqInteraction() > 0);  // 0 will mean !xp.hasHWBlendEquation().
             key |= caps.advBlendEqInteraction() << 2;
@@ -601,7 +599,7 @@ private:
         if (xp.hasHWBlendEquation()) {
             // The blend mode will be implemented in hardware; only output the src color.
             fsBuilder->enableAdvancedBlendEquationIfNeeded(xp.hwBlendEquation());
-            if (xp.hasCoverage()) {
+            if (xp.readsCoverage()) {
                 // Do coverage modulation by multiplying it into the src color before blending.
                 // (See getOptimizations())
                 fsBuilder->codeAppendf("%s = %s * %s;",
@@ -613,7 +611,7 @@ private:
             const char* dstColor = fsBuilder->dstColor();
             emit_custom_xfermode_code(xp.mode(), fsBuilder, args.fOutputPrimary, args.fInputColor,
                                       dstColor);
-            if (xp.hasCoverage()) {
+            if (xp.readsCoverage()) {
                 fsBuilder->codeAppendf("%s = %s * %s + (vec4(1.0) - %s) * %s;",
                                        args.fOutputPrimary, args.fOutputPrimary,
                                        args.fInputCoverage, args.fInputCoverage, dstColor);
@@ -632,7 +630,6 @@ CustomXP::CustomXP(SkXfermode::Mode mode, const GrDeviceCoordTexture* dstCopy,
                    bool willReadDstColor)
     : INHERITED(dstCopy, willReadDstColor),
       fMode(mode),
-      fHasCoverage(true),
       fHWBlendEquation(kInvalid_GrBlendEquation) {
     this->initClassID<CustomXP>();
 }
@@ -648,12 +645,10 @@ GrGLXferProcessor* CustomXP::createGLInstance() const {
 
 bool CustomXP::onIsEqual(const GrXferProcessor& other) const {
     const CustomXP& s = other.cast<CustomXP>();
-    return fMode == s.fMode &&
-           fHasCoverage == s.fHasCoverage &&
-           fHWBlendEquation == s.fHWBlendEquation;
+    return fMode == s.fMode && fHWBlendEquation == s.fHWBlendEquation;
 }
 
-GrXferProcessor::OptFlags CustomXP::getOptimizations(const GrProcOptInfo& colorPOI,
+GrXferProcessor::OptFlags CustomXP::onGetOptimizations(const GrProcOptInfo& colorPOI,
                                                        const GrProcOptInfo& coveragePOI,
                                                        bool doesStencilWrite,
                                                        GrColor* overrideColor,
@@ -760,7 +755,6 @@ GrXferProcessor::OptFlags CustomXP::getOptimizations(const GrProcOptInfo& colorP
     }
     if (coveragePOI.isSolidWhite()) {
         flags = flags | kIgnoreCoverage_OptFlag;
-        fHasCoverage = false;
     }
     if (caps.advancedBlendEquationSupport() && !coveragePOI.isFourChannelOutput()) {
         // This blend mode can be implemented in hardware.
index 261100deb97ca91ab893e1a7469d4c1ff9e26f97..9b513f663eafe6bd390e19e0be7056486c91c4b4 100644 (file)
@@ -29,17 +29,17 @@ public:
 
     bool hasSecondaryOutput() const override { return false; }
 
-    GrXferProcessor::OptFlags getOptimizations(const GrProcOptInfo& colorPOI,
-                                               const GrProcOptInfo& coveragePOI,
-                                               bool doesStencilWrite,
-                                               GrColor* color,
-                                               const GrDrawTargetCaps& caps) override {
-        return GrXferProcessor::kIgnoreColor_OptFlag | GrXferProcessor::kIgnoreCoverage_OptFlag;
-    }
-
 private:
     DisableColorXP();
 
+    GrXferProcessor::OptFlags onGetOptimizations(const GrProcOptInfo& colorPOI,
+                                                 const GrProcOptInfo& coveragePOI,
+                                                 bool doesStencilWrite,
+                                                 GrColor* color,
+                                                 const GrDrawTargetCaps& caps) override {
+        return GrXferProcessor::kIgnoreColor_OptFlag | GrXferProcessor::kIgnoreCoverage_OptFlag;
+    }
+
     void onGetGLProcessorKey(const GrGLSLCaps& caps, GrProcessorKeyBuilder* b) const override;
 
     void onGetBlendInfo(GrXferProcessor::BlendInfo* blendInfo) const override;
index 73d58245c00766ee117c04dd3c97d13cfaa078ab..543a515e909e9ed59d2a64231bfe795ed1df20ce 100644 (file)
@@ -84,12 +84,6 @@ public:
     PrimaryOutputType primaryOutputType() const { return fPrimaryOutputType; }
     SecondaryOutputType secondaryOutputType() const { return fSecondaryOutputType; }
 
-    GrXferProcessor::OptFlags getOptimizations(const GrProcOptInfo& colorPOI,
-                                               const GrProcOptInfo& coveragePOI,
-                                               bool doesStencilWrite,
-                                               GrColor* overrideColor,
-                                               const GrDrawTargetCaps& caps) override;
-
     GrBlendCoeff getSrcBlend() const { return fSrcBlend; }
     GrBlendCoeff getDstBlend() const { return fDstBlend; }
 
@@ -97,6 +91,12 @@ private:
     PorterDuffXferProcessor(GrBlendCoeff srcBlend, GrBlendCoeff dstBlend, GrColor constant,
                             const GrDeviceCoordTexture* dstCopy, bool willReadDstColor);
 
+    GrXferProcessor::OptFlags onGetOptimizations(const GrProcOptInfo& colorPOI,
+                                                 const GrProcOptInfo& coveragePOI,
+                                                 bool doesStencilWrite,
+                                                 GrColor* overrideColor,
+                                                 const GrDrawTargetCaps& caps) override;
+
     void onGetGLProcessorKey(const GrGLSLCaps& caps, GrProcessorKeyBuilder* b) const override;
 
     void onGetBlendInfo(GrXferProcessor::BlendInfo* blendInfo) const override {
@@ -301,11 +301,11 @@ GrGLXferProcessor* PorterDuffXferProcessor::createGLInstance() const {
 }
 
 GrXferProcessor::OptFlags
-PorterDuffXferProcessor::getOptimizations(const GrProcOptInfo& colorPOI,
-                                          const GrProcOptInfo& coveragePOI,
-                                          bool doesStencilWrite,
-                                          GrColor* overrideColor,
-                                          const GrDrawTargetCaps& caps) {
+PorterDuffXferProcessor::onGetOptimizations(const GrProcOptInfo& colorPOI,
+                                            const GrProcOptInfo& coveragePOI,
+                                            bool doesStencilWrite,
+                                            GrColor* overrideColor,
+                                            const GrDrawTargetCaps& caps) {
     GrXferProcessor::OptFlags optFlags;
     // Optimizations when doing RGB Coverage
     if (coveragePOI.isFourChannelOutput()) {
index c517381249ae77735346c5a050d026ab38467e20..657da41274af0d8f3a7e19c559340d79d7afa668 100644 (file)
@@ -17,11 +17,14 @@ void GrGLXferProcessor::emitCode(const EmitArgs& args) {
 
         GrGLXPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder();
 
-        // We don't think any shaders actually output negative coverage, but just as a safety check
-        // for floating point precision errors we compare with <= here
-        fsBuilder->codeAppendf("if (all(lessThanEqual(%s, vec4(0)))) {"
-                               "    discard;"
-                               "}", args.fInputCoverage);
+        if (args.fXP.readsCoverage()) {
+            // We don't think any shaders actually output negative coverage, but just as a safety
+            // check for floating point precision errors we compare with <= here
+            fsBuilder->codeAppendf("if (all(lessThanEqual(%s, vec4(0)))) {"
+                                   "    discard;"
+                                   "}", args.fInputCoverage);
+        }
+
         const char* dstColor = fsBuilder->dstColor();
 
         const char* dstCopyTopLeftName;