Move blend optimization functions to GrDrawState.
Review URL: https://codereview.appspot.com/7300089

git-svn-id: http://skia.googlecode.com/svn/trunk@7703 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/src/gpu/GrContext.cpp b/src/gpu/GrContext.cpp
index ef3fd6d..70db256 100644
--- a/src/gpu/GrContext.cpp
+++ b/src/gpu/GrContext.cpp
@@ -647,7 +647,7 @@
     // In a shader implementation we can give a separate coverage input
     // TODO: remove this ugliness when we drop the fixed-pipe impl
     *useVertexCoverage = false;
-    if (!target->canTweakAlphaForCoverage()) {
+    if (!target->getDrawState().canTweakAlphaForCoverage()) {
         if (disable_coverage_aa_for_blend(target)) {
 #if GR_DEBUG
             //GrPrintf("Turning off AA to correctly apply blend.\n");
diff --git a/src/gpu/GrDrawState.cpp b/src/gpu/GrDrawState.cpp
index 5b434c3..f2c6977 100644
--- a/src/gpu/GrDrawState.cpp
+++ b/src/gpu/GrDrawState.cpp
@@ -538,6 +538,134 @@
 
 ////////////////////////////////////////////////////////////////////////////////
 
+// Some blend modes allow folding a fractional coverage value into the color's alpha channel, while
+// others will blend incorrectly.
+bool GrDrawState::canTweakAlphaForCoverage() const {
+    /*
+     The fractional coverage is f.
+     The src and dst coeffs are Cs and Cd.
+     The dst and src colors are S and D.
+     We want the blend to compute: f*Cs*S + (f*Cd + (1-f))D. By tweaking the source color's alpha
+     we're replacing S with S'=fS. It's obvious that that first term will always be ok. The second
+     term can be rearranged as [1-(1-Cd)f]D. By substituting in the various possibilities for Cd we
+     find that only 1, ISA, and ISC produce the correct destination when applied to S' and D.
+     Also, if we're directly rendering coverage (isCoverageDrawing) then coverage is treated as
+     color by definition.
+     */
+    return kOne_GrBlendCoeff == fCommon.fDstBlend ||
+           kISA_GrBlendCoeff == fCommon.fDstBlend ||
+           kISC_GrBlendCoeff == fCommon.fDstBlend ||
+           this->isCoverageDrawing();
+}
+
+GrDrawState::BlendOptFlags GrDrawState::getBlendOpts(bool forceCoverage,
+                                                     GrBlendCoeff* srcCoeff,
+                                                     GrBlendCoeff* dstCoeff) const {
+    GrVertexLayout layout = this->getVertexLayout();
+
+    GrBlendCoeff bogusSrcCoeff, bogusDstCoeff;
+    if (NULL == srcCoeff) {
+        srcCoeff = &bogusSrcCoeff;
+    }
+    *srcCoeff = this->getSrcBlendCoeff();
+
+    if (NULL == dstCoeff) {
+        dstCoeff = &bogusDstCoeff;
+    }
+    *dstCoeff = this->getDstBlendCoeff();
+
+    if (this->isColorWriteDisabled()) {
+        *srcCoeff = kZero_GrBlendCoeff;
+        *dstCoeff = kOne_GrBlendCoeff;
+    }
+
+    bool srcAIsOne = this->srcAlphaWillBeOne(layout);
+    bool dstCoeffIsOne = kOne_GrBlendCoeff == *dstCoeff ||
+                         (kSA_GrBlendCoeff == *dstCoeff && srcAIsOne);
+    bool dstCoeffIsZero = kZero_GrBlendCoeff == *dstCoeff ||
+                         (kISA_GrBlendCoeff == *dstCoeff && srcAIsOne);
+
+    bool covIsZero = !this->isCoverageDrawing() &&
+                     !(layout & GrDrawState::kCoverage_VertexLayoutBit) &&
+                     0 == this->getCoverage();
+    // When coeffs are (0,1) there is no reason to draw at all, unless
+    // stenciling is enabled. Having color writes disabled is effectively
+    // (0,1). The same applies when coverage is known to be 0.
+    if ((kZero_GrBlendCoeff == *srcCoeff && dstCoeffIsOne) || covIsZero) {
+        if (this->getStencil().doesWrite()) {
+            return kDisableBlend_BlendOptFlag |
+                   kEmitTransBlack_BlendOptFlag;
+        } else {
+            return kSkipDraw_BlendOptFlag;
+        }
+    }
+
+    // check for coverage due to constant coverage, per-vertex coverage,
+    // edge aa or coverage stage
+    bool hasCoverage = forceCoverage ||
+                       0xffffffff != this->getCoverage() ||
+                       (layout & GrDrawState::kCoverage_VertexLayoutBit) ||
+                       (layout & GrDrawState::kEdge_VertexLayoutBit);
+    for (int s = this->getFirstCoverageStage();
+         !hasCoverage && s < GrDrawState::kNumStages;
+         ++s) {
+        if (this->isStageEnabled(s)) {
+            hasCoverage = true;
+        }
+    }
+
+    // if we don't have coverage we can check whether the dst
+    // has to read at all. If not, we'll disable blending.
+    if (!hasCoverage) {
+        if (dstCoeffIsZero) {
+            if (kOne_GrBlendCoeff == *srcCoeff) {
+                // if there is no coverage and coeffs are (1,0) then we
+                // won't need to read the dst at all, it gets replaced by src
+                return kDisableBlend_BlendOptFlag;
+            } else if (kZero_GrBlendCoeff == *srcCoeff) {
+                // if the op is "clear" then we don't need to emit a color
+                // or blend, just write transparent black into the dst.
+                *srcCoeff = kOne_GrBlendCoeff;
+                *dstCoeff = kZero_GrBlendCoeff;
+                return kDisableBlend_BlendOptFlag | kEmitTransBlack_BlendOptFlag;
+            }
+        }
+    } else if (this->isCoverageDrawing()) {
+        // we have coverage but we aren't distinguishing it from alpha by request.
+        return kCoverageAsAlpha_BlendOptFlag;
+    } else {
+        // check whether coverage can be safely rolled into alpha
+        // of if we can skip color computation and just emit coverage
+        if (this->canTweakAlphaForCoverage()) {
+            return kCoverageAsAlpha_BlendOptFlag;
+        }
+        if (dstCoeffIsZero) {
+            if (kZero_GrBlendCoeff == *srcCoeff) {
+                // the source color is not included in the blend
+                // the dst coeff is effectively zero so blend works out to:
+                // (c)(0)D + (1-c)D = (1-c)D.
+                *dstCoeff = kISA_GrBlendCoeff;
+                return  kEmitCoverage_BlendOptFlag;
+            } else if (srcAIsOne) {
+                // the dst coeff is effectively zero so blend works out to:
+                // cS + (c)(0)D + (1-c)D = cS + (1-c)D.
+                // If Sa is 1 then we can replace Sa with c
+                // and set dst coeff to 1-Sa.
+                *dstCoeff = kISA_GrBlendCoeff;
+                return  kCoverageAsAlpha_BlendOptFlag;
+            }
+        } else if (dstCoeffIsOne) {
+            // the dst coeff is effectively one so blend works out to:
+            // cS + (c)(1)D + (1-c)D = cS + D.
+            *dstCoeff = kOne_GrBlendCoeff;
+            return  kCoverageAsAlpha_BlendOptFlag;
+        }
+    }
+    return kNone_BlendOpt;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
 void GrDrawState::AutoViewMatrixRestore::restore() {
     if (NULL != fDrawState) {
         fDrawState->setViewMatrix(fViewMatrix);
diff --git a/src/gpu/GrDrawState.h b/src/gpu/GrDrawState.h
index 2245e05..1124ebb 100644
--- a/src/gpu/GrDrawState.h
+++ b/src/gpu/GrDrawState.h
@@ -690,6 +690,60 @@
      */
     GrColor getBlendConstant() const { return fCommon.fBlendConstant; }
 
+    /**
+     * Determines whether multiplying the computed per-pixel color by the pixel's fractional
+     * coverage before the blend will give the correct final destination color. In general it
+     * will not as coverage is applied after blending.
+     */
+    bool canTweakAlphaForCoverage() const;
+
+    /**
+     * Optimizations for blending / coverage to that can be applied based on the current state.
+     */
+    enum BlendOptFlags {
+        /**
+         * No optimization
+         */
+        kNone_BlendOpt                  = 0,
+        /**
+         * Don't draw at all
+         */
+        kSkipDraw_BlendOptFlag          = 0x1,
+        /**
+         * Emit the src color, disable HW blending (replace dst with src)
+         */
+        kDisableBlend_BlendOptFlag      = 0x2,
+        /**
+         * The coverage value does not have to be computed separately from alpha, the the output
+         * color can be the modulation of the two.
+         */
+        kCoverageAsAlpha_BlendOptFlag   = 0x4,
+        /**
+         * Instead of emitting a src color, emit coverage in the alpha channel and r,g,b are
+         * "don't cares".
+         */
+        kEmitCoverage_BlendOptFlag      = 0x8,
+        /**
+         * Emit transparent black instead of the src color, no need to compute coverage.
+         */
+        kEmitTransBlack_BlendOptFlag    = 0x10,
+    };
+    GR_DECL_BITFIELD_OPS_FRIENDS(BlendOptFlags);
+
+    /**
+     * Determines what optimizations can be applied based on the blend. The coefficients may have
+     * to be tweaked in order for the optimization to work. srcCoeff and dstCoeff are optional
+     * params that receive the tweaked coefficients. Normally the function looks at the current
+     * state to see if coverage is enabled. By setting forceCoverage the caller can speculatively
+     * determine the blend optimizations that would be used if there was partial pixel coverage.
+     *
+     * Subclasses of GrDrawTarget that actually draw (as opposed to those that just buffer for
+     * playback) must call this function and respect the flags that replace the output color.
+     */
+    BlendOptFlags getBlendOpts(bool forceCoverage = false,
+                               GrBlendCoeff* srcCoeff = NULL,
+                               GrBlendCoeff* dstCoeff = NULL) const;
+
     /// @}
 
     ///////////////////////////////////////////////////////////////////////////
@@ -1278,4 +1332,6 @@
     typedef GrRefCnt INHERITED;
 };
 
+GR_MAKE_BITFIELD_OPS(GrDrawState::BlendOptFlags);
+
 #endif
diff --git a/src/gpu/GrDrawTarget.cpp b/src/gpu/GrDrawTarget.cpp
index 3282f13..c00a5ce 100644
--- a/src/gpu/GrDrawTarget.cpp
+++ b/src/gpu/GrDrawTarget.cpp
@@ -454,168 +454,24 @@
 
 ////////////////////////////////////////////////////////////////////////////////
 
-// Some blend modes allow folding a partial coverage value into the color's
-// alpha channel, while others will blend incorrectly.
-bool GrDrawTarget::canTweakAlphaForCoverage() const {
-    /**
-     * The fractional coverage is f
-     * The src and dst coeffs are Cs and Cd
-     * The dst and src colors are S and D
-     * We want the blend to compute: f*Cs*S + (f*Cd + (1-f))D
-     * By tweaking the source color's alpha we're replacing S with S'=fS. It's
-     * obvious that that first term will always be ok. The second term can be
-     * rearranged as [1-(1-Cd)f]D. By substituting in the various possibilities
-     * for Cd we find that only 1, ISA, and ISC produce the correct depth
-     * coefficient in terms of S' and D.
-     */
-    GrBlendCoeff dstCoeff = this->getDrawState().getDstBlendCoeff();
-    return kOne_GrBlendCoeff == dstCoeff ||
-           kISA_GrBlendCoeff == dstCoeff ||
-           kISC_GrBlendCoeff == dstCoeff ||
-           this->getDrawState().isCoverageDrawing();
-}
-
-namespace {
-GrVertexLayout default_blend_opts_vertex_layout() {
-    GrVertexLayout layout = 0;
-    return layout;
-}
-}
-
-GrDrawTarget::BlendOptFlags
-GrDrawTarget::getBlendOpts(bool forceCoverage,
-                           GrBlendCoeff* srcCoeff,
-                           GrBlendCoeff* dstCoeff) const {
-
-    const GrDrawState& drawState = this->getDrawState();
-
-    GrVertexLayout layout;
-    if (kNone_GeometrySrcType == this->getGeomSrc().fVertexSrc) {
-        layout = default_blend_opts_vertex_layout();
-    } else {
-        layout = drawState.getVertexLayout();
-    }
-
-    GrBlendCoeff bogusSrcCoeff, bogusDstCoeff;
-    if (NULL == srcCoeff) {
-        srcCoeff = &bogusSrcCoeff;
-    }
-    *srcCoeff = drawState.getSrcBlendCoeff();
-
-    if (NULL == dstCoeff) {
-        dstCoeff = &bogusDstCoeff;
-    }
-    *dstCoeff = drawState.getDstBlendCoeff();
-
-    if (drawState.isColorWriteDisabled()) {
-        *srcCoeff = kZero_GrBlendCoeff;
-        *dstCoeff = kOne_GrBlendCoeff;
-    }
-
-    bool srcAIsOne = drawState.srcAlphaWillBeOne(layout);
-    bool dstCoeffIsOne = kOne_GrBlendCoeff == *dstCoeff ||
-                         (kSA_GrBlendCoeff == *dstCoeff && srcAIsOne);
-    bool dstCoeffIsZero = kZero_GrBlendCoeff == *dstCoeff ||
-                         (kISA_GrBlendCoeff == *dstCoeff && srcAIsOne);
-
-    bool covIsZero = !drawState.isCoverageDrawing() &&
-                     !(layout & GrDrawState::kCoverage_VertexLayoutBit) &&
-                     0 == drawState.getCoverage();
-    // When coeffs are (0,1) there is no reason to draw at all, unless
-    // stenciling is enabled. Having color writes disabled is effectively
-    // (0,1). The same applies when coverage is known to be 0.
-    if ((kZero_GrBlendCoeff == *srcCoeff && dstCoeffIsOne) || covIsZero) {
-        if (drawState.getStencil().doesWrite()) {
-            return kDisableBlend_BlendOptFlag |
-                   kEmitTransBlack_BlendOptFlag;
-        } else {
-            return kSkipDraw_BlendOptFlag;
-        }
-    }
-
-    // check for coverage due to constant coverage, per-vertex coverage,
-    // edge aa or coverage stage
-    bool hasCoverage = forceCoverage ||
-                       0xffffffff != drawState.getCoverage() ||
-                       (layout & GrDrawState::kCoverage_VertexLayoutBit) ||
-                       (layout & GrDrawState::kEdge_VertexLayoutBit);
-    for (int s = drawState.getFirstCoverageStage();
-         !hasCoverage && s < GrDrawState::kNumStages;
-         ++s) {
-        if (drawState.isStageEnabled(s)) {
-            hasCoverage = true;
-        }
-    }
-
-    // if we don't have coverage we can check whether the dst
-    // has to read at all. If not, we'll disable blending.
-    if (!hasCoverage) {
-        if (dstCoeffIsZero) {
-            if (kOne_GrBlendCoeff == *srcCoeff) {
-                // if there is no coverage and coeffs are (1,0) then we
-                // won't need to read the dst at all, it gets replaced by src
-                return kDisableBlend_BlendOptFlag;
-            } else if (kZero_GrBlendCoeff == *srcCoeff) {
-                // if the op is "clear" then we don't need to emit a color
-                // or blend, just write transparent black into the dst.
-                *srcCoeff = kOne_GrBlendCoeff;
-                *dstCoeff = kZero_GrBlendCoeff;
-                return kDisableBlend_BlendOptFlag | kEmitTransBlack_BlendOptFlag;
-            }
-        }
-    } else if (drawState.isCoverageDrawing()) {
-        // we have coverage but we aren't distinguishing it from alpha by request.
-        return kCoverageAsAlpha_BlendOptFlag;
-    } else {
-        // check whether coverage can be safely rolled into alpha
-        // of if we can skip color computation and just emit coverage
-        if (this->canTweakAlphaForCoverage()) {
-            return kCoverageAsAlpha_BlendOptFlag;
-        }
-        if (dstCoeffIsZero) {
-            if (kZero_GrBlendCoeff == *srcCoeff) {
-                // the source color is not included in the blend
-                // the dst coeff is effectively zero so blend works out to:
-                // (c)(0)D + (1-c)D = (1-c)D.
-                *dstCoeff = kISA_GrBlendCoeff;
-                return  kEmitCoverage_BlendOptFlag;
-            } else if (srcAIsOne) {
-                // the dst coeff is effectively zero so blend works out to:
-                // cS + (c)(0)D + (1-c)D = cS + (1-c)D.
-                // If Sa is 1 then we can replace Sa with c
-                // and set dst coeff to 1-Sa.
-                *dstCoeff = kISA_GrBlendCoeff;
-                return  kCoverageAsAlpha_BlendOptFlag;
-            }
-        } else if (dstCoeffIsOne) {
-            // the dst coeff is effectively one so blend works out to:
-            // cS + (c)(1)D + (1-c)D = cS + D.
-            *dstCoeff = kOne_GrBlendCoeff;
-            return  kCoverageAsAlpha_BlendOptFlag;
-        }
-    }
-    return kNone_BlendOpt;
-}
-
 bool GrDrawTarget::willUseHWAALines() const {
-    // there is a conflict between using smooth lines and our use of
-    // premultiplied alpha. Smooth lines tweak the incoming alpha value
-    // but not in a premul-alpha way. So we only use them when our alpha
-    // is 0xff and tweaking the color for partial coverage is OK
+    // There is a conflict between using smooth lines and our use of premultiplied alpha. Smooth
+    // lines tweak the incoming alpha value but not in a premul-alpha way. So we only use them when
+    // our alpha is 0xff and tweaking the color for partial coverage is OK
     if (!fCaps.hwAALineSupport() ||
         !this->getDrawState().isHWAntialiasState()) {
         return false;
     }
-    BlendOptFlags opts = this->getBlendOpts();
-    return (kDisableBlend_BlendOptFlag & opts) &&
-           (kCoverageAsAlpha_BlendOptFlag & opts);
+    GrDrawState::BlendOptFlags opts = this->getDrawState().getBlendOpts();
+    return (GrDrawState::kDisableBlend_BlendOptFlag & opts) &&
+           (GrDrawState::kCoverageAsAlpha_BlendOptFlag & opts);
 }
 
 bool GrDrawTarget::canApplyCoverage() const {
     // we can correctly apply coverage if a) we have dual source blending
     // or b) one of our blend optimizations applies.
     return this->getCaps().dualSourceBlendingSupport() ||
-           kNone_BlendOpt != this->getBlendOpts(true);
+           GrDrawState::kNone_BlendOpt != this->getDrawState().getBlendOpts(true);
 }
 
 ////////////////////////////////////////////////////////////////////////////////
diff --git a/src/gpu/GrDrawTarget.h b/src/gpu/GrDrawTarget.h
index 5a558ed..1f41891 100644
--- a/src/gpu/GrDrawTarget.h
+++ b/src/gpu/GrDrawTarget.h
@@ -145,27 +145,15 @@
      *    1. The caller intends to somehow specify coverage. This can be
      *       specified either by enabling a coverage stage on the GrDrawState or
      *       via the vertex layout.
-     *    2. Other than enabling coverage stages, the current configuration of
-     *       the target's GrDrawState is as it will be at draw time.
-     *    3. If a vertex source has not yet been specified then all stages with
-     *       non-NULL textures will be referenced by the vertex layout.
+     *    2. Other than enabling coverage stages or enabling coverage in the
+     *       layout, the current configuration of the target's GrDrawState is as
+     *       it will be at draw time.
      */
     bool canApplyCoverage() const;
 
     /**
-     * Determines whether incorporating partial pixel coverage into the constant
-     * color specified by setColor or per-vertex colors will give the right
-     * blending result. If a vertex source has not yet been specified then
-     * the function assumes that all stages with non-NULL textures will be
-     * referenced by the vertex layout.
-     */
-    bool canTweakAlphaForCoverage() const;
-
-    /**
-     * Given the current draw state and hw support, will HW AA lines be used
-     * (if line primitive type is drawn)? If a vertex source has not yet been
-     * specified then  the function assumes that all stages with non-NULL
-     * textures will be referenced by the vertex layout.
+     * Given the current draw state and hw support, will HW AA lines be used (if
+     * a line primitive type is drawn)?
      */
     bool willUseHWAALines() const;
 
@@ -616,54 +604,6 @@
 
 protected:
 
-    /**
-     * Optimizations for blending / coverage to be applied based on the current
-     * state.
-     * Subclasses that actually draw (as opposed to those that just buffer for
-     * playback) must implement the flags that replace the output color.
-     */
-    enum BlendOptFlags {
-        /**
-         * No optimization
-         */
-        kNone_BlendOpt = 0,
-        /**
-         * Don't draw at all
-         */
-        kSkipDraw_BlendOptFlag = 0x2,
-        /**
-         * Emit the src color, disable HW blending (replace dst with src)
-         */
-        kDisableBlend_BlendOptFlag = 0x4,
-        /**
-         * The coverage value does not have to be computed separately from
-         * alpha, the the output color can be the modulation of the two.
-         */
-        kCoverageAsAlpha_BlendOptFlag = 0x1,
-        /**
-         * Instead of emitting a src color, emit coverage in the alpha channel
-         * and r,g,b are "don't cares".
-         */
-        kEmitCoverage_BlendOptFlag = 0x10,
-        /**
-         * Emit transparent black instead of the src color, no need to compute
-         * coverage.
-         */
-        kEmitTransBlack_BlendOptFlag = 0x8,
-    };
-    GR_DECL_BITFIELD_OPS_FRIENDS(BlendOptFlags);
-
-    /**
-     * Determines what optimizations can be applied based on the blend. The coefficients may have
-     * to be tweaked in order for the optimization to work. srcCoeff and dstCoeff are optional
-     * params that receive the tweaked coefficients. Normally the function looks at the current
-     * state to see if coverage is enabled. By setting forceCoverage the caller can speculatively
-     * determine the blend optimizations that would be used if there was partial pixel coverage.
-     */
-    BlendOptFlags getBlendOpts(bool forceCoverage = false,
-                               GrBlendCoeff* srcCoeff = NULL,
-                               GrBlendCoeff* dstCoeff = NULL) const;
-
     enum GeometrySrcType {
         kNone_GeometrySrcType,     //<! src has not been specified
         kReserved_GeometrySrcType, //<! src was set using reserve*Space
@@ -837,6 +777,4 @@
     typedef GrRefCnt INHERITED;
 };
 
-GR_MAKE_BITFIELD_OPS(GrDrawTarget::BlendOptFlags);
-
 #endif
diff --git a/src/gpu/gl/GrGpuGL.h b/src/gpu/gl/GrGpuGL.h
index d9ad1f4..7bb458d 100644
--- a/src/gpu/gl/GrGpuGL.h
+++ b/src/gpu/gl/GrGpuGL.h
@@ -202,7 +202,7 @@
     void flushScissor();
 
     void buildProgram(bool isPoints,
-                      BlendOptFlags blendOpts,
+                      GrDrawState::BlendOptFlags blendOpts,
                       GrBlendCoeff dstCoeff,
                       ProgramDesc* desc);
 
diff --git a/src/gpu/gl/GrGpuGL_program.cpp b/src/gpu/gl/GrGpuGL_program.cpp
index a566f3f..570ca19 100644
--- a/src/gpu/gl/GrGpuGL_program.cpp
+++ b/src/gpu/gl/GrGpuGL_program.cpp
@@ -281,8 +281,8 @@
 
         GrBlendCoeff srcCoeff;
         GrBlendCoeff dstCoeff;
-        BlendOptFlags blendOpts = this->getBlendOpts(false, &srcCoeff, &dstCoeff);
-        if (kSkipDraw_BlendOptFlag & blendOpts) {
+        GrDrawState::BlendOptFlags blendOpts = drawState.getBlendOpts(false, &srcCoeff, &dstCoeff);
+        if (GrDrawState::kSkipDraw_BlendOptFlag & blendOpts) {
             return false;
         }
 
@@ -309,10 +309,10 @@
 
         GrColor color;
         GrColor coverage;
-        if (blendOpts & kEmitTransBlack_BlendOptFlag) {
+        if (blendOpts & GrDrawState::kEmitTransBlack_BlendOptFlag) {
             color = 0;
             coverage = 0;
-        } else if (blendOpts & kEmitCoverage_BlendOptFlag) {
+        } else if (blendOpts & GrDrawState::kEmitCoverage_BlendOptFlag) {
             color = 0xffffffff;
             coverage = drawState.getCoverage();
         } else {
@@ -444,18 +444,18 @@
 }
 
 void GrGpuGL::buildProgram(bool isPoints,
-                           BlendOptFlags blendOpts,
+                           GrDrawState::BlendOptFlags blendOpts,
                            GrBlendCoeff dstCoeff,
                            ProgramDesc* desc) {
     const GrDrawState& drawState = this->getDrawState();
 
     // This should already have been caught
-    GrAssert(!(kSkipDraw_BlendOptFlag & blendOpts));
+    GrAssert(!(GrDrawState::kSkipDraw_BlendOptFlag & blendOpts));
 
-    bool skipCoverage = SkToBool(blendOpts & kEmitTransBlack_BlendOptFlag);
+    bool skipCoverage = SkToBool(blendOpts & GrDrawState::kEmitTransBlack_BlendOptFlag);
 
-    bool skipColor = SkToBool(blendOpts & (kEmitTransBlack_BlendOptFlag |
-                                           kEmitCoverage_BlendOptFlag));
+    bool skipColor = SkToBool(blendOpts & (GrDrawState::kEmitTransBlack_BlendOptFlag |
+                                           GrDrawState::kEmitCoverage_BlendOptFlag));
 
     // The descriptor is used as a cache key. Thus when a field of the
     // descriptor will not affect program generation (because of the vertex
@@ -487,8 +487,8 @@
         desc->fVertexLayout &= ~(GrDrawState::kEdge_VertexLayoutBit | GrDrawState::kCoverage_VertexLayoutBit);
     }
 
-    bool colorIsTransBlack = SkToBool(blendOpts & kEmitTransBlack_BlendOptFlag);
-    bool colorIsSolidWhite = (blendOpts & kEmitCoverage_BlendOptFlag) ||
+    bool colorIsTransBlack = SkToBool(blendOpts & GrDrawState::kEmitTransBlack_BlendOptFlag);
+    bool colorIsSolidWhite = (blendOpts & GrDrawState::kEmitCoverage_BlendOptFlag) ||
                              (!requiresAttributeColors && 0xffffffff == drawState.getColor());
     if (colorIsTransBlack) {
         desc->fColorInput = ProgramDesc::kTransBlack_ColorInput;
@@ -567,7 +567,8 @@
         }
 
         if (this->getCaps().dualSourceBlendingSupport() &&
-            !(blendOpts & (kEmitCoverage_BlendOptFlag | kCoverageAsAlpha_BlendOptFlag))) {
+            !(blendOpts & (GrDrawState::kEmitCoverage_BlendOptFlag |
+                           GrDrawState::kCoverageAsAlpha_BlendOptFlag))) {
             if (kZero_GrBlendCoeff == dstCoeff) {
                 // write the coverage value to second color
                 desc->fDualSrcOutput =  ProgramDesc::kCoverage_DualSrcOutput;