Add XP to handle the cases where we disable color write.

BUG=skia:

Review URL: https://codereview.chromium.org/787233003
diff --git a/src/gpu/GrClipMaskManager.cpp b/src/gpu/GrClipMaskManager.cpp
index 7f85801..797a21a 100644
--- a/src/gpu/GrClipMaskManager.cpp
+++ b/src/gpu/GrClipMaskManager.cpp
@@ -693,7 +693,8 @@
             GrDrawState drawState(matrix);
             drawState.setRenderTarget(rt);
             drawState.enableState(GrDrawState::kClip_StateBit);
-            drawState.enableState(GrDrawState::kNoColorWrites_StateBit);
+
+            drawState.setDisableColorXPFactory();
 
             // if the target is MSAA then we want MSAA enabled when the clip is soft
             if (rt->isMultisampled()) {
diff --git a/src/gpu/GrDefaultPathRenderer.cpp b/src/gpu/GrDefaultPathRenderer.cpp
index d8f723e..7222e62 100644
--- a/src/gpu/GrDefaultPathRenderer.cpp
+++ b/src/gpu/GrDefaultPathRenderer.cpp
@@ -364,8 +364,8 @@
                           tol)) {
         return false;
     }
-
-    bool colorWritesWereDisabled = drawState->isColorWriteDisabled();
+    // Save the current xp on the draw state so we can reset it if needed
+    SkAutoTUnref<const GrXPFactory> backupXPFactory(SkRef(drawState->getXPFactory()));
     // face culling doesn't make sense here
     SkASSERT(GrDrawState::kBoth_DrawFace == drawState->getDrawFace());
 
@@ -471,9 +471,8 @@
         }
 
         if (lastPassIsBounds && (p == passCount-1)) {
-            if (!colorWritesWereDisabled) {
-                drawState->disableState(GrDrawState::kNoColorWrites_StateBit);
-            }
+            // Reset the XP Factory on drawState
+            drawState->setXPFactory(backupXPFactory);
             SkRect bounds;
             GrDrawState::AutoViewMatrixRestore avmr;
             if (reverse) {
@@ -495,7 +494,7 @@
             target->drawSimpleRect(drawState, color, bounds);
         } else {
             if (passCount > 1) {
-                drawState->enableState(GrDrawState::kNoColorWrites_StateBit);
+                drawState->setDisableColorXPFactory();
             }
             GrDrawState::AutoRestoreEffects are(drawState);
             SkAutoTUnref<const GrGeometryProcessor> gp(
diff --git a/src/gpu/GrDrawState.cpp b/src/gpu/GrDrawState.cpp
index 883c74b..68cd01c 100644
--- a/src/gpu/GrDrawState.cpp
+++ b/src/gpu/GrDrawState.cpp
@@ -184,8 +184,7 @@
     // TODO we want to cache the result of this call, but we can probably clean up the interface
     // so we don't have to pass in a seemingly known coverage
     this->calcCoverageInvariantOutput(GrColor_WHITE);
-    return fXPFactory->canApplyCoverage(fColorProcInfo, fCoverageProcInfo,
-                                        this->isColorWriteDisabled());
+    return fXPFactory->canApplyCoverage(fColorProcInfo, fCoverageProcInfo);
 }
 
 //////////////////////////////////////////////////////////////////////////////s
@@ -193,21 +192,8 @@
 bool GrDrawState::willEffectReadDstColor(const GrPrimitiveProcessor* pp) const {
     this->calcColorInvariantOutput(pp);
     this->calcCoverageInvariantOutput(pp);
-    // TODO: Remove need to create the XP here.
-    //       Also once all custom blends are turned into XPs we can remove the need
-    //       to check other stages since only xp's will be able to read dst
-    SkAutoTUnref<GrXferProcessor> xferProcessor(fXPFactory->createXferProcessor(fColorProcInfo,
-                                                                                fCoverageProcInfo));
-    if (xferProcessor && xferProcessor->willReadDstColor()) {
-        return true;
-    }
 
-    if (!this->isColorWriteDisabled()) {
-        if (fColorProcInfo.readsDst()) {
-            return true;
-        }
-    }
-    return fCoverageProcInfo.readsDst();
+    return fXPFactory->willReadDst(fColorProcInfo, fCoverageProcInfo);
 }
 
 void GrDrawState::AutoRestoreEffects::set(GrDrawState* ds) {
@@ -341,8 +327,7 @@
     this->calcCoverageInvariantOutput(pp);
     
     GrXPFactory::InvariantOutput output;
-    fXPFactory->getInvariantOutput(fColorProcInfo, fCoverageProcInfo, this->isColorWriteDisabled(),
-                                   &output);
+    fXPFactory->getInvariantOutput(fColorProcInfo, fCoverageProcInfo, &output);
     return output.fWillBlendWithDst;
 }
 
diff --git a/src/gpu/GrDrawState.h b/src/gpu/GrDrawState.h
index 7d3c1e9..24f987d 100644
--- a/src/gpu/GrDrawState.h
+++ b/src/gpu/GrDrawState.h
@@ -20,6 +20,7 @@
 #include "GrXferProcessor.h"
 #include "SkMatrix.h"
 #include "effects/GrCoverageSetOpXP.h"
+#include "effects/GrDisableColorXP.h"
 #include "effects/GrPorterDuffXferProcessor.h"
 #include "effects/GrSimpleTextureEffect.h"
 
@@ -144,6 +145,10 @@
         fXPFactory.reset(GrCoverageSetOpXPFactory::Create(regionOp, invertCoverage));
     }
 
+    void setDisableColorXPFactory() {
+        fXPFactory.reset(GrDisableColorXPFactory::Create());
+    }
+
     const GrFragmentProcessor* addColorProcessor(const GrFragmentProcessor* effect) {
         SkASSERT(effect);
         SkNEW_APPEND_TO_TARRAY(&fColorStages, GrFragmentStage, (effect));
@@ -410,17 +415,11 @@
          * Draws will respect the clip, otherwise the clip is ignored.
          */
         kClip_StateBit          = 0x04,
-        /**
-         * Disables writing to the color buffer. Useful when performing stencil
-         * operations.
-         */
-        kNoColorWrites_StateBit = 0x08,
 
-        kLast_StateBit = kNoColorWrites_StateBit,
+        kLast_StateBit = kClip_StateBit,
     };
 
     bool isClipState() const { return 0 != (fFlagBits & kClip_StateBit); }
-    bool isColorWriteDisabled() const { return 0 != (fFlagBits & kNoColorWrites_StateBit); }
     bool isDither() const { return 0 != (fFlagBits & kDither_StateBit); }
     bool isHWAntialias() const { return 0 != (fFlagBits & kHWAntialias_StateBit); }
 
diff --git a/src/gpu/GrOptDrawState.cpp b/src/gpu/GrOptDrawState.cpp
index 95d5984..082db32 100644
--- a/src/gpu/GrOptDrawState.cpp
+++ b/src/gpu/GrOptDrawState.cpp
@@ -53,7 +53,6 @@
 
         optFlags = xferProcessor->getOptimizations(colorPOI,
                                                    coveragePOI,
-                                                   drawState.isColorWriteDisabled(),
                                                    drawState.getStencil().doesWrite(),
                                                    &overrideColor,
                                                    caps);
@@ -86,9 +85,6 @@
     if (drawState.isHWAntialias()) {
         fFlags |= kHWAA_Flag;
     }
-    if (drawState.isColorWriteDisabled()) {
-        fFlags |= kDisableColorWrite_Flag;
-    }
     if (drawState.isDither()) {
         fFlags |= kDither_Flag;
     }
diff --git a/src/gpu/GrOptDrawState.h b/src/gpu/GrOptDrawState.h
index 9c42b7c..111f920 100644
--- a/src/gpu/GrOptDrawState.h
+++ b/src/gpu/GrOptDrawState.h
@@ -125,14 +125,12 @@
 
     /// @}
 
-
     ///////////////////////////////////////////////////////////////////////////
     /// @name Boolean Queries
     ////
 
     bool isDitherState() const { return SkToBool(fFlags & kDither_Flag); }
     bool isHWAntialiasState() const { return SkToBool(fFlags & kHWAA_Flag); }
-    bool isColorWriteDisabled() const { return SkToBool(fFlags & kDisableColorWrite_Flag); }
     bool mustSkip() const { return NULL == this->getRenderTarget(); }
 
     /// @}
@@ -179,7 +177,6 @@
     enum Flags {
         kDither_Flag            = 0x1,
         kHWAA_Flag              = 0x2,
-        kDisableColorWrite_Flag = 0x4,
     };
 
     typedef GrPendingIOResource<GrRenderTarget, kWrite_GrIOType> RenderTarget;
diff --git a/src/gpu/GrPaint.cpp b/src/gpu/GrPaint.cpp
index 1997796..da6408c 100644
--- a/src/gpu/GrPaint.cpp
+++ b/src/gpu/GrPaint.cpp
@@ -41,7 +41,7 @@
                                         kRGBA_GrColorComponentFlags, false);
 
     GrXPFactory::InvariantOutput output;
-    fXPFactory->getInvariantOutput(colorProcInfo, coverageProcInfo, true, &output);
+    fXPFactory->getInvariantOutput(colorProcInfo, coverageProcInfo, &output);
 
     if (kRGBA_GrColorComponentFlags == output.fBlendedColorFlags &&
         0xFF == GrColorUnpackA(output.fBlendedColor)) {
diff --git a/src/gpu/GrPathRenderer.h b/src/gpu/GrPathRenderer.h
index f4276b4..4d38aa0 100644
--- a/src/gpu/GrPathRenderer.h
+++ b/src/gpu/GrPathRenderer.h
@@ -197,7 +197,7 @@
                                      0xffff,
                                      0xffff);
         drawState->setStencil(kIncrementStencil);
-        drawState->enableState(GrDrawState::kNoColorWrites_StateBit);
+        drawState->setDisableColorXPFactory();
         this->drawPath(target, drawState, GrColor_WHITE,  path, stroke, false);
     }
 
diff --git a/src/gpu/GrProcessor.cpp b/src/gpu/GrProcessor.cpp
index 6699b52..75245f3 100644
--- a/src/gpu/GrProcessor.cpp
+++ b/src/gpu/GrProcessor.cpp
@@ -52,7 +52,7 @@
  */
 static const int kFPFactoryCount = 37;
 static const int kGPFactoryCount = 14;
-static const int kXPFactoryCount = 2;
+static const int kXPFactoryCount = 3;
 
 template<>
 void GrProcessorTestFactory<GrFragmentProcessor>::VerifyFactoryCount() {
diff --git a/src/gpu/effects/GrCoverageSetOpXP.cpp b/src/gpu/effects/GrCoverageSetOpXP.cpp
index d956cd3..bb87616 100644
--- a/src/gpu/effects/GrCoverageSetOpXP.cpp
+++ b/src/gpu/effects/GrCoverageSetOpXP.cpp
@@ -9,7 +9,6 @@
 #include "effects/GrCoverageSetOpXP.h"
 #include "GrColor.h"
 #include "GrDrawTargetCaps.h"
-#include "GrInvariantOutput.h"
 #include "GrProcessor.h"
 #include "GrProcOptInfo.h"
 #include "gl/GrGLXferProcessor.h"
@@ -68,7 +67,6 @@
 GrXferProcessor::OptFlags
 GrCoverageSetOpXP::getOptimizations(const GrProcOptInfo& colorPOI,
                                     const GrProcOptInfo& coveragePOI,
-                                    bool colorWriteDisabled,
                                     bool doesStencilWrite,
                                     GrColor* color,
                                     const GrDrawTargetCaps& caps) {
@@ -188,7 +186,6 @@
 
 void GrCoverageSetOpXPFactory::getInvariantOutput(const GrProcOptInfo& colorPOI,
                                                   const GrProcOptInfo& coveragePOI,
-                                                  bool colorWriteDisabled,
                                                   GrXPFactory::InvariantOutput* output) const {
     if (SkRegion::kReplace_Op == fRegionOp) {
         if (coveragePOI.isSolidWhite()) {
@@ -209,6 +206,11 @@
     }
 }
 
+bool GrCoverageSetOpXPFactory::willReadDst(const GrProcOptInfo& colorPOI,
+                                           const GrProcOptInfo& coveragePOI) const {
+    return coveragePOI.readsDst();
+}
+
 GR_DEFINE_XP_FACTORY_TEST(GrCoverageSetOpXPFactory);
 
 GrXPFactory* GrCoverageSetOpXPFactory::TestCreate(SkRandom* random,
diff --git a/src/gpu/effects/GrCoverageSetOpXP.h b/src/gpu/effects/GrCoverageSetOpXP.h
index e3ce07c..289b5cf 100644
--- a/src/gpu/effects/GrCoverageSetOpXP.h
+++ b/src/gpu/effects/GrCoverageSetOpXP.h
@@ -12,7 +12,6 @@
 #include "GrXferProcessor.h"
 #include "SkRegion.h"
 
-class GrInvariantOutput;
 class GrProcOptInfo;
 
 /**
@@ -28,7 +27,7 @@
 
     ~GrCoverageSetOpXP() SK_OVERRIDE;
 
-    virtual const char* name() const SK_OVERRIDE { return "Coverage Set Op"; }
+    const char* name() const SK_OVERRIDE { return "Coverage Set Op"; }
 
     void getGLProcessorKey(const GrGLCaps& caps, GrProcessorKeyBuilder* b) const SK_OVERRIDE;
 
@@ -38,7 +37,6 @@
 
     GrXferProcessor::OptFlags getOptimizations(const GrProcOptInfo& colorPOI,
                                                const GrProcOptInfo& coveragePOI,
-                                               bool colorWriteDisabled,
                                                bool doesStencilWrite,
                                                GrColor* color,
                                                const GrDrawTargetCaps& caps) SK_OVERRIDE;
@@ -75,17 +73,19 @@
         return true;
     }
 
-    bool canApplyCoverage(const GrProcOptInfo& colorPOI, const GrProcOptInfo& coveragePOI,
-                          bool colorWriteDisabled) const SK_OVERRIDE {
+    bool canApplyCoverage(const GrProcOptInfo& colorPOI,
+                          const GrProcOptInfo& coveragePOI) const SK_OVERRIDE {
         return true;
     }
 
     bool canTweakAlphaForCoverage() const SK_OVERRIDE { return false; }
 
     void getInvariantOutput(const GrProcOptInfo& colorPOI, const GrProcOptInfo& coveragePOI,
-                            bool colorWriteDisabled,
                             GrXPFactory::InvariantOutput*) const SK_OVERRIDE;
 
+    bool willReadDst(const GrProcOptInfo& colorPOI,
+                     const GrProcOptInfo& coveragePOI) const SK_OVERRIDE;
+
 private:
     GrCoverageSetOpXPFactory(SkRegion::Op regionOp, bool invertCoverage);
 
diff --git a/src/gpu/effects/GrDisableColorXP.cpp b/src/gpu/effects/GrDisableColorXP.cpp
new file mode 100644
index 0000000..ba6a45b
--- /dev/null
+++ b/src/gpu/effects/GrDisableColorXP.cpp
@@ -0,0 +1,65 @@
+/*
+ * Copyright 2014 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "effects/GrDisableColorXP.h"
+#include "GrProcessor.h"
+#include "gl/GrGLXferProcessor.h"
+
+class GrGLDisableColorXP : public GrGLXferProcessor {
+public:
+    GrGLDisableColorXP(const GrProcessor&) {}
+
+    ~GrGLDisableColorXP() SK_OVERRIDE {}
+
+    void emitCode(const EmitArgs& args) SK_OVERRIDE {}
+
+    void setData(const GrGLProgramDataManager&, const GrXferProcessor&) SK_OVERRIDE {}
+
+    static void GenKey(const GrProcessor&, const GrGLCaps&, GrProcessorKeyBuilder*) {}
+
+private:
+    typedef GrGLXferProcessor INHERITED;
+};
+
+///////////////////////////////////////////////////////////////////////////////
+
+GrDisableColorXP::GrDisableColorXP() {
+    this->initClassID<GrDisableColorXP>();
+}
+
+void GrDisableColorXP::getGLProcessorKey(const GrGLCaps& caps, GrProcessorKeyBuilder* b) const {
+    GrGLDisableColorXP::GenKey(*this, caps, b);
+}
+
+GrGLXferProcessor* GrDisableColorXP::createGLInstance() const {
+    return SkNEW_ARGS(GrGLDisableColorXP, (*this));
+}
+
+void GrDisableColorXP::getBlendInfo(GrXferProcessor::BlendInfo* blendInfo) const {
+    blendInfo->fWriteColor = false;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+GrDisableColorXPFactory::GrDisableColorXPFactory() {
+    this->initClassID<GrDisableColorXPFactory>();
+}
+
+GrXferProcessor* GrDisableColorXPFactory::createXferProcessor(const GrProcOptInfo& colorPOI,
+                                                              const GrProcOptInfo& covPOI) const {
+    return GrDisableColorXP::Create();
+}
+
+GR_DEFINE_XP_FACTORY_TEST(GrDisableColorXPFactory);
+
+GrXPFactory* GrDisableColorXPFactory::TestCreate(SkRandom* random,
+                                                  GrContext*,
+                                                  const GrDrawTargetCaps&,
+                                                  GrTexture*[]) {
+    return GrDisableColorXPFactory::Create();
+}
+
diff --git a/src/gpu/effects/GrDisableColorXP.h b/src/gpu/effects/GrDisableColorXP.h
new file mode 100644
index 0000000..b0de66b
--- /dev/null
+++ b/src/gpu/effects/GrDisableColorXP.h
@@ -0,0 +1,102 @@
+/*
+ * 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 GrDisableColorXP_DEFINED
+#define GrDisableColorXP_DEFINED
+
+#include "GrTypes.h"
+#include "GrXferProcessor.h"
+
+class GrProcOptInfo;
+
+/**
+ * This xfer processor disables color writing. Thus color and coverage and ignored and no blending
+ * occurs. This XP is usful for things like stenciling.
+ */
+class GrDisableColorXP : public GrXferProcessor {
+public:
+    static GrXferProcessor* Create() {
+        return SkNEW(GrDisableColorXP);
+    }
+
+    ~GrDisableColorXP() SK_OVERRIDE {};
+
+    const char* name() const SK_OVERRIDE { return "Disable Color"; }
+
+    void getGLProcessorKey(const GrGLCaps& caps, GrProcessorKeyBuilder* b) const SK_OVERRIDE;
+
+    GrGLXferProcessor* createGLInstance() const SK_OVERRIDE;
+
+    bool hasSecondaryOutput() const SK_OVERRIDE { return false; }
+
+    GrXferProcessor::OptFlags getOptimizations(const GrProcOptInfo& colorPOI,
+                                               const GrProcOptInfo& coveragePOI,
+                                               bool doesStencilWrite,
+                                               GrColor* color,
+                                               const GrDrawTargetCaps& caps) SK_OVERRIDE {
+        return GrXferProcessor::kIgnoreColor_OptFlag | GrXferProcessor::kIgnoreCoverage_OptFlag;
+    }
+
+    void getBlendInfo(GrXferProcessor::BlendInfo* blendInfo) const SK_OVERRIDE;
+
+private:
+    GrDisableColorXP();
+
+    bool onIsEqual(const GrXferProcessor& xpBase) const SK_OVERRIDE {
+        return true;
+    }
+
+    typedef GrXferProcessor INHERITED;
+};
+
+///////////////////////////////////////////////////////////////////////////////
+
+class GrDisableColorXPFactory : public GrXPFactory {
+public:
+    static GrXPFactory* Create() {
+        return SkNEW(GrDisableColorXPFactory);
+    }
+
+    GrXferProcessor* createXferProcessor(const GrProcOptInfo& colorPOI,
+                                         const GrProcOptInfo& coveragePOI) const SK_OVERRIDE;
+
+    bool supportsRGBCoverage(GrColor knownColor, uint32_t knownColorFlags) const SK_OVERRIDE {
+        return true;
+    }
+
+    bool canApplyCoverage(const GrProcOptInfo& colorPOI,
+                          const GrProcOptInfo& coveragePOI) const SK_OVERRIDE {
+        return true;
+    }
+
+    bool canTweakAlphaForCoverage() const SK_OVERRIDE { return true; }
+
+    void getInvariantOutput(const GrProcOptInfo& colorPOI, const GrProcOptInfo& coveragePOI,
+                            GrXPFactory::InvariantOutput* output) const SK_OVERRIDE {
+        output->fBlendedColorFlags = 0;
+        output->fWillBlendWithDst = 0;
+    }
+
+    bool willReadDst(const GrProcOptInfo& colorPOI,
+                     const GrProcOptInfo& coveragePOI) const SK_OVERRIDE {
+        return false;
+    }
+
+private:
+    GrDisableColorXPFactory();
+
+    bool onIsEqual(const GrXPFactory& xpfBase) const SK_OVERRIDE {
+        return true;
+    }
+
+    GR_DECLARE_XP_FACTORY_TEST;
+
+    typedef GrXPFactory INHERITED;
+};
+
+#endif
+
diff --git a/src/gpu/effects/GrPorterDuffXferProcessor.cpp b/src/gpu/effects/GrPorterDuffXferProcessor.cpp
index 2dd3d53..2b10cad 100644
--- a/src/gpu/effects/GrPorterDuffXferProcessor.cpp
+++ b/src/gpu/effects/GrPorterDuffXferProcessor.cpp
@@ -9,7 +9,6 @@
 
 #include "GrBlend.h"
 #include "GrDrawTargetCaps.h"
-#include "GrInvariantOutput.h"
 #include "GrProcessor.h"
 #include "GrProcOptInfo.h"
 #include "GrTypes.h"
@@ -127,7 +126,6 @@
 GrXferProcessor::OptFlags
 GrPorterDuffXferProcessor::getOptimizations(const GrProcOptInfo& colorPOI,
                                             const GrProcOptInfo& coveragePOI,
-                                            bool colorWriteDisabled,
                                             bool doesStencilWrite,
                                             GrColor* overrideColor,
                                             const GrDrawTargetCaps& caps) {
@@ -144,7 +142,6 @@
     } else {
         optFlags = this->internalGetOptimizations(colorPOI,
                                                   coveragePOI,
-                                                  colorWriteDisabled,
                                                   doesStencilWrite);
     }
     this->calcOutputTypes(optFlags, caps, coveragePOI.isSolidWhite(),
@@ -198,13 +195,7 @@
 GrXferProcessor::OptFlags
 GrPorterDuffXferProcessor::internalGetOptimizations(const GrProcOptInfo& colorPOI,
                                                     const GrProcOptInfo& coveragePOI,
-                                                    bool colorWriteDisabled,
                                                     bool doesStencilWrite) {
-    if (colorWriteDisabled) {
-        fSrcBlend = kZero_GrBlendCoeff;
-        fDstBlend = kOne_GrBlendCoeff;
-    }
-
     bool srcAIsOne;
     bool hasCoverage;
 
@@ -399,14 +390,9 @@
 }
 
 bool GrPorterDuffXPFactory::canApplyCoverage(const GrProcOptInfo& colorPOI,
-                                             const GrProcOptInfo& coveragePOI,
-                                             bool colorWriteDisabled) const {
+                                             const GrProcOptInfo& coveragePOI) const {
     bool srcAIsOne = colorPOI.isOpaque();
 
-    if (colorWriteDisabled) {
-        return true;
-    }
-
     bool dstCoeffIsOne = kOne_GrBlendCoeff == fDstCoeff ||
                          (kSA_GrBlendCoeff == fDstCoeff && srcAIsOne);
     bool dstCoeffIsZero = kZero_GrBlendCoeff == fDstCoeff ||
@@ -449,7 +435,6 @@
 
 void GrPorterDuffXPFactory::getInvariantOutput(const GrProcOptInfo& colorPOI,
                                                const GrProcOptInfo& coveragePOI,
-                                               bool colorWriteDisabled,
                                                GrXPFactory::InvariantOutput* output) const {
     if (!coveragePOI.isSolidWhite()) {
         output->fWillBlendWithDst = true;
@@ -516,13 +501,18 @@
 
     // TODO: once all SkXferEffects are XP's then we will never reads dst here since only XP's
     // will readDst and PD XP's don't read dst.
-    if ((!colorWriteDisabled && colorPOI.readsDst()) || coveragePOI.readsDst()) {
+    if (colorPOI.readsDst() || coveragePOI.readsDst()) {
         output->fWillBlendWithDst = true;
         return;
     }
     output->fWillBlendWithDst = false;
 }
 
+bool GrPorterDuffXPFactory::willReadDst(const GrProcOptInfo& colorPOI,
+                                        const GrProcOptInfo& coveragePOI) const {
+    return colorPOI.readsDst() || coveragePOI.readsDst();
+}
+
 GR_DEFINE_XP_FACTORY_TEST(GrPorterDuffXPFactory);
 
 GrXPFactory* GrPorterDuffXPFactory::TestCreate(SkRandom* random,
diff --git a/src/gpu/gl/GrGpuGL.cpp b/src/gpu/gl/GrGpuGL.cpp
index 53d3ac2..b36e887 100644
--- a/src/gpu/gl/GrGpuGL.cpp
+++ b/src/gpu/gl/GrGpuGL.cpp
@@ -1345,8 +1345,11 @@
 }
 
 bool GrGLGpu::flushGLState(const GrOptDrawState& optState) {
+    GrXferProcessor::BlendInfo blendInfo;
+    optState.getXferProcessor()->getBlendInfo(&blendInfo);
+
     this->flushDither(optState.isDitherState());
-    this->flushColorWriteDisable(optState.isColorWriteDisabled());
+    this->flushColorWrite(blendInfo.fWriteColor);
     this->flushDrawFace(optState.getDrawFace());
 
     fCurrentProgram.reset(fProgramCache->getProgram(optState));
@@ -1363,7 +1366,9 @@
         fHWProgramID = programID;
     }
 
-    this->flushBlend(optState);
+    if (blendInfo.fWriteColor) {
+        this->flushBlend(blendInfo);
+    }
 
     fCurrentProgram->setData(optState);
 
@@ -1865,7 +1870,7 @@
 }
 
 void GrGLGpu::onStencilPath(const GrPath* path, const StencilPathState& state) {
-    this->flushColorWriteDisable(true);
+    this->flushColorWrite(false);
     this->flushDrawFace(GrDrawState::kBoth_DrawFace);
 
     GrGLRenderTarget* rt = static_cast<GrGLRenderTarget*>(state.fRenderTarget);
@@ -2056,12 +2061,10 @@
     }
 }
 
-void GrGLGpu::flushBlend(const GrOptDrawState& optState) {
+void GrGLGpu::flushBlend(const GrXferProcessor::BlendInfo& blendInfo) {
     // Any optimization to disable blending should have already been applied and
     // tweaked the coeffs to (1, 0).
     
-    GrXferProcessor::BlendInfo blendInfo;
-    optState.getXferProcessor()->getBlendInfo(&blendInfo);
     GrBlendCoeff srcCoeff = blendInfo.fSrcBlend;
     GrBlendCoeff dstCoeff = blendInfo.fDstBlend;
     bool blendOff = kOne_GrBlendCoeff == srcCoeff && kZero_GrBlendCoeff == dstCoeff;
@@ -2223,8 +2226,8 @@
     }
 }
 
-void GrGLGpu::flushColorWriteDisable(bool disableColorWrites) {
-    if (disableColorWrites) {
+void GrGLGpu::flushColorWrite(bool writeColor) {
+    if (!writeColor) {
         if (kNo_TriState != fHWWriteToColor) {
             GL_CALL(ColorMask(GR_GL_FALSE, GR_GL_FALSE,
                               GR_GL_FALSE, GR_GL_FALSE));
diff --git a/src/gpu/gl/GrGpuGL.h b/src/gpu/gl/GrGpuGL.h
index 93564fc..d2a0d9a 100644
--- a/src/gpu/gl/GrGpuGL.h
+++ b/src/gpu/gl/GrGpuGL.h
@@ -21,6 +21,7 @@
 #include "GrGLVertexBuffer.h"
 #include "GrGpu.h"
 #include "GrOptDrawState.h"
+#include "GrXferProcessor.h"
 #include "SkTypes.h"
 
 #ifdef SK_DEVELOPER
@@ -177,7 +178,7 @@
                        size_t* indexOffsetInBytes);
 
     // Subclasses should call this to flush the blend state.
-    void flushBlend(const GrOptDrawState& optState);
+    void flushBlend(const GrXferProcessor::BlendInfo& blendInfo);
 
     bool hasExtension(const char* ext) const { return fGLContext.hasExtension(ext); }
 
@@ -224,7 +225,7 @@
     };
 
     void flushDither(bool dither);
-    void flushColorWriteDisable(bool disableColorWrites);
+    void flushColorWrite(bool writeColor);
     void flushDrawFace(GrDrawState::DrawFace face);
 
     // flushes the scissor. see the note on flushBoundTextureAndParams about