Only discard for XP dstCopies if we have a coverage value.

TBR=bsalomon@google.com

BUG=skia:

Review URL: https://codereview.chromium.org/1125283005
diff --git a/include/gpu/GrXferProcessor.h b/include/gpu/GrXferProcessor.h
index 7c07b80..812ce5c 100644
--- a/include/gpu/GrXferProcessor.h
+++ b/include/gpu/GrXferProcessor.h
@@ -164,11 +164,11 @@
      * 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 @@
         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 @@
         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 @@
     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 @@
     virtual bool onIsEqual(const GrXferProcessor&) const = 0;
 
     bool                    fWillReadDstColor;
+    bool                    fReadsCoverage;
     SkIPoint                fDstCopyTextureOffset;
     GrTextureAccess         fDstCopy;
 
diff --git a/src/effects/SkArithmeticMode_gpu.cpp b/src/effects/SkArithmeticMode_gpu.cpp
index bd87931..69c2d7c 100644
--- a/src/effects/SkArithmeticMode_gpu.cpp
+++ b/src/effects/SkArithmeticMode_gpu.cpp
@@ -175,12 +175,6 @@
 
     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 @@
     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 @@
     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;
 }
 
diff --git a/src/gpu/GrXferProcessor.cpp b/src/gpu/GrXferProcessor.cpp
index 243b9fe..bc79b2d 100644
--- a/src/gpu/GrXferProcessor.cpp
+++ b/src/gpu/GrXferProcessor.cpp
@@ -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::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() &&
diff --git a/src/gpu/effects/GrCoverageSetOpXP.cpp b/src/gpu/effects/GrCoverageSetOpXP.cpp
index 69b9ea4..02552b3 100644
--- a/src/gpu/effects/GrCoverageSetOpXP.cpp
+++ b/src/gpu/effects/GrCoverageSetOpXP.cpp
@@ -29,17 +29,17 @@
 
     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 @@
 }
 
 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; 
 }
diff --git a/src/gpu/effects/GrCustomXfermode.cpp b/src/gpu/effects/GrCustomXfermode.cpp
index b15e2c2..0a525b4 100644
--- a/src/gpu/effects/GrCustomXfermode.cpp
+++ b/src/gpu/effects/GrCustomXfermode.cpp
@@ -525,14 +525,7 @@
 
     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 @@
 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 @@
     bool onIsEqual(const GrXferProcessor& xpBase) const override;
 
     SkXfermode::Mode fMode;
-    bool             fHasCoverage;
     GrBlendEquation  fHWBlendEquation;
 
     typedef GrXferProcessor INHERITED;
@@ -581,7 +579,7 @@
         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 @@
         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 @@
             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 @@
                    bool willReadDstColor)
     : INHERITED(dstCopy, willReadDstColor),
       fMode(mode),
-      fHasCoverage(true),
       fHWBlendEquation(kInvalid_GrBlendEquation) {
     this->initClassID<CustomXP>();
 }
@@ -648,12 +645,10 @@
 
 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 @@
     }
     if (coveragePOI.isSolidWhite()) {
         flags = flags | kIgnoreCoverage_OptFlag;
-        fHasCoverage = false;
     }
     if (caps.advancedBlendEquationSupport() && !coveragePOI.isFourChannelOutput()) {
         // This blend mode can be implemented in hardware.
diff --git a/src/gpu/effects/GrDisableColorXP.cpp b/src/gpu/effects/GrDisableColorXP.cpp
index 261100d..9b513f6 100644
--- a/src/gpu/effects/GrDisableColorXP.cpp
+++ b/src/gpu/effects/GrDisableColorXP.cpp
@@ -29,17 +29,17 @@
 
     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;
diff --git a/src/gpu/effects/GrPorterDuffXferProcessor.cpp b/src/gpu/effects/GrPorterDuffXferProcessor.cpp
index 73d5824..543a515 100644
--- a/src/gpu/effects/GrPorterDuffXferProcessor.cpp
+++ b/src/gpu/effects/GrPorterDuffXferProcessor.cpp
@@ -84,12 +84,6 @@
     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 @@
     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 @@
 }
 
 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()) {
diff --git a/src/gpu/gl/GrGLXferProcessor.cpp b/src/gpu/gl/GrGLXferProcessor.cpp
index c517381..657da41 100644
--- a/src/gpu/gl/GrGLXferProcessor.cpp
+++ b/src/gpu/gl/GrGLXferProcessor.cpp
@@ -17,11 +17,14 @@
 
         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;