Do not apply hairline optimization for paths if nv_path_rendering is used

Do not convert thin, non-hairline paths to hairline paths if
nv_path_rendering is used.

The current nv_path_rendering implementation does not render
hairlines. Rendering the hairlines with normal renderers cause
unneccessary gl program changes, which is quite slow.

Changes the behavior of non-nv_path_rendering paths to always perform
the optimization if the shape ends up being painted by the
path-drawing code (GrContext::drawPathInternal). Previously the
optimization was applied only when callgraph started with
SkCanvas::drawPath. This changes drawlooper_msaa4, dashing3_msaa4 and
dashing3_gpu

R=bsalomon@google.com

Author: kkinnunen@nvidia.com

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

git-svn-id: http://skia.googlecode.com/svn/trunk/src@12185 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/core/SkDraw.cpp b/core/SkDraw.cpp
index af4f1ca..826c4ba 100644
--- a/core/SkDraw.cpp
+++ b/core/SkDraw.cpp
@@ -987,24 +987,12 @@
     }
 }
 
-bool SkDrawTreatAsHairline(const SkPaint& paint, const SkMatrix& matrix,
-                           SkScalar* coverage) {
+bool SkDrawTreatAAStrokeAsHairline(SkScalar strokeWidth, const SkMatrix& matrix,
+                                   SkScalar* coverage) {
     SkASSERT(coverage);
-    if (SkPaint::kStroke_Style != paint.getStyle()) {
-        return false;
-    }
-    SkScalar strokeWidth = paint.getStrokeWidth();
-    if (0 == strokeWidth) {
-        *coverage = SK_Scalar1;
-        return true;
-    }
+    SkASSERT(strokeWidth > 0);
+    // We need to try to fake a thick-stroke with a modulated hairline.
 
-    // if we get here, we need to try to fake a thick-stroke with a modulated
-    // hairline
-
-    if (!paint.isAntiAlias()) {
-        return false;
-    }
     if (matrix.hasPerspective()) {
         return false;
     }
diff --git a/core/SkDrawProcs.h b/core/SkDrawProcs.h
index 8b8c382..4453229 100644
--- a/core/SkDrawProcs.h
+++ b/core/SkDrawProcs.h
@@ -59,12 +59,32 @@
     SkDraw1Glyph::Proc  fD1GProc;
 };
 
+bool SkDrawTreatAAStrokeAsHairline(SkScalar strokeWidth, const SkMatrix&,
+                                   SkScalar* coverage);
+
 /**
  *  If the current paint is set to stroke and the stroke-width when applied to
  *  the matrix is <= 1.0, then this returns true, and sets coverage (simulating
  *  a stroke by drawing a hairline with partial coverage). If any of these
  *  conditions are false, then this returns false and coverage is ignored.
  */
-bool SkDrawTreatAsHairline(const SkPaint&, const SkMatrix&, SkScalar* coverage);
+inline bool SkDrawTreatAsHairline(const SkPaint& paint, const SkMatrix& matrix,
+                                  SkScalar* coverage) {
+    if (SkPaint::kStroke_Style != paint.getStyle()) {
+        return false;
+    }
+
+    SkScalar strokeWidth = paint.getStrokeWidth();
+    if (0 == strokeWidth) {
+        *coverage = SK_Scalar1;
+        return true;
+    }
+
+    if (!paint.isAntiAlias()) {
+        return false;
+    }
+
+    return SkDrawTreatAAStrokeAsHairline(strokeWidth, matrix, coverage);
+}
 
 #endif
diff --git a/gpu/GrAAHairLinePathRenderer.cpp b/gpu/GrAAHairLinePathRenderer.cpp
index 02c4419..50d7764 100644
--- a/gpu/GrAAHairLinePathRenderer.cpp
+++ b/gpu/GrAAHairLinePathRenderer.cpp
@@ -759,7 +759,7 @@
     }
     devBounds->set(lines.begin(), lines.count());
     for (int i = 0; i < lineCnt; ++i) {
-        add_line(&lines[2*i], toSrc, drawState->getCoverage(), &verts);
+        add_line(&lines[2*i], toSrc, drawState->getCoverageColor(), &verts);
     }
     // All the verts computed by add_line are within sqrt(1^2 + 0.5^2) of the end points.
     static const SkScalar kSqrtOfOneAndAQuarter = SkFloatToScalar(1.118f);
diff --git a/gpu/GrContext.cpp b/gpu/GrContext.cpp
index b0d34fd..5eee243 100644
--- a/gpu/GrContext.cpp
+++ b/gpu/GrContext.cpp
@@ -25,6 +25,7 @@
 #include "GrSoftwarePathRenderer.h"
 #include "GrStencilBuffer.h"
 #include "GrTextStrike.h"
+#include "SkDrawProcs.h"
 #include "SkRTConf.h"
 #include "SkRRect.h"
 #include "SkStrokeRec.h"
@@ -43,10 +44,6 @@
 
 #define BUFFERED_DRAW (c_Defer ? kYes_BufferedDraw : kNo_BufferedDraw)
 
-// When we're using coverage AA but the blend is incompatible (given gpu
-// limitations) should we disable AA or draw wrong?
-#define DISABLE_COVERAGE_AA_FOR_BLEND 1
-
 #ifdef SK_DEBUG
     // change this to a 1 to see notifications when partial coverage fails
     #define GR_DEBUG_PARTIAL_COVERAGE_CHECK 0
@@ -695,14 +692,6 @@
 
 ////////////////////////////////////////////////////////////////////////////////
 
-namespace {
-inline bool disable_coverage_aa_for_blend(GrDrawTarget* target) {
-    return DISABLE_COVERAGE_AA_FOR_BLEND && !target->canApplyCoverage();
-}
-}
-
-////////////////////////////////////////////////////////////////////////////////
-
 /*  create a triangle strip that strokes the specified triangle. There are 8
  unique vertices, but we repreat the last 2 to close up. Alternatively we
  could use an indices array, and then only send 8 verts, but not sure that
@@ -746,7 +735,7 @@
     // TODO: remove this ugliness when we drop the fixed-pipe impl
     *useVertexCoverage = false;
     if (!target->getDrawState().canTweakAlphaForCoverage()) {
-        if (disable_coverage_aa_for_blend(target)) {
+        if (target->shouldDisableCoverageAAForBlend()) {
 #ifdef SK_DEBUG
             //GrPrintf("Turning off AA to correctly apply blend.\n");
 #endif
@@ -1034,14 +1023,10 @@
     AutoCheckFlush acf(this);
     GrDrawTarget* target = this->prepareToDraw(&paint, BUFFERED_DRAW, &are, &acf);
 
-    bool useAA = paint.isAntiAlias() &&
-                 !target->getDrawState().getRenderTarget()->isMultisampled() &&
-                 !disable_coverage_aa_for_blend(target);
-
-    if (!fOvalRenderer->drawSimpleRRect(target, this, useAA, rect, stroke)) {
+    if (!fOvalRenderer->drawSimpleRRect(target, this, paint.isAntiAlias(), rect, stroke)) {
         SkPath path;
         path.addRRect(rect);
-        this->internalDrawPath(target, useAA, path, stroke);
+        this->internalDrawPath(target, paint.isAntiAlias(), path, stroke);
     }
 }
 
@@ -1058,14 +1043,10 @@
     AutoCheckFlush acf(this);
     GrDrawTarget* target = this->prepareToDraw(&paint, BUFFERED_DRAW, &are, &acf);
 
-    bool useAA = paint.isAntiAlias() &&
-                 !target->getDrawState().getRenderTarget()->isMultisampled() &&
-                 !disable_coverage_aa_for_blend(target);
-
-    if (!fOvalRenderer->drawOval(target, this, useAA, oval, stroke)) {
+    if (!fOvalRenderer->drawOval(target, this, paint.isAntiAlias(), oval, stroke)) {
         SkPath path;
         path.addOval(oval);
-        this->internalDrawPath(target, useAA, path, stroke);
+        this->internalDrawPath(target, paint.isAntiAlias(), path, stroke);
     }
 }
 
@@ -1091,7 +1072,7 @@
 
     *useVertexCoverage = false;
     if (!target->getDrawState().canTweakAlphaForCoverage()) {
-        if (disable_coverage_aa_for_blend(target)) {
+        if (target->shouldDisableCoverageAAForBlend()) {
             return false;
         } else {
             *useVertexCoverage = true;
@@ -1141,15 +1122,17 @@
     AutoRestoreEffects are;
     AutoCheckFlush acf(this);
     GrDrawTarget* target = this->prepareToDraw(&paint, BUFFERED_DRAW, &are, &acf);
+    GrDrawState* drawState = target->drawState();
 
-    bool useAA = paint.isAntiAlias() && !target->getDrawState().getRenderTarget()->isMultisampled();
-    if (useAA && stroke.getWidth() < 0 && !path.isConvex()) {
+    bool useCoverageAA = paint.isAntiAlias() && !drawState->getRenderTarget()->isMultisampled();
+
+    if (useCoverageAA && stroke.getWidth() < 0 && !path.isConvex()) {
         // Concave AA paths are expensive - try to avoid them for special cases
         bool useVertexCoverage;
         SkRect rects[2];
 
         if (is_nested_rects(target, path, stroke, rects, &useVertexCoverage)) {
-            SkMatrix origViewMatrix = target->getDrawState().getViewMatrix();
+            SkMatrix origViewMatrix = drawState->getViewMatrix();
             GrDrawState::AutoViewMatrixRestore avmr;
             if (!avmr.setIdentity(target->drawState())) {
                 return;
@@ -1167,42 +1150,73 @@
     bool isOval = path.isOval(&ovalRect);
 
     if (!isOval || path.isInverseFillType()
-        || !fOvalRenderer->drawOval(target, this, useAA, ovalRect, stroke)) {
-        this->internalDrawPath(target, useAA, path, stroke);
+        || !fOvalRenderer->drawOval(target, this, paint.isAntiAlias(), ovalRect, stroke)) {
+        this->internalDrawPath(target, paint.isAntiAlias(), path, stroke);
     }
 }
 
-void GrContext::internalDrawPath(GrDrawTarget* target, bool useAA, const SkPath& path,
-                                 const SkStrokeRec& stroke) {
+namespace {
+// See also: SkDrawTreatAsHairline.
+static inline bool should_convert_to_hairline(bool useAA, const SkStrokeRec& stroke,
+                                              const SkMatrix& matrix, SkScalar* coverage) {
+
+    if (stroke.getStyle() != SkStrokeRec::kStroke_Style) {
+        return false;
+    }
+
+    SkASSERT(0 != stroke.getWidth());
+
+    if (!useAA) {
+        return false;
+    }
+
+    return SkDrawTreatAAStrokeAsHairline(stroke.getWidth(), matrix, coverage);
+}
+}
+
+
+void GrContext::internalDrawPath(GrDrawTarget* target, bool useAA,
+                                 const SkPath& path, const SkStrokeRec& origStroke) {
     SkASSERT(!path.isEmpty());
 
     // An Assumption here is that path renderer would use some form of tweaking
     // the src color (either the input alpha or in the frag shader) to implement
     // aa. If we have some future driver-mojo path AA that can do the right
     // thing WRT to the blend then we'll need some query on the PR.
-    if (disable_coverage_aa_for_blend(target)) {
-#ifdef SK_DEBUG
-        //GrPrintf("Turning off AA to correctly apply blend.\n");
-#endif
-        useAA = false;
+    bool useCoverageAA = useAA &&
+        !target->getDrawState().getRenderTarget()->isMultisampled() &&
+        !target->shouldDisableCoverageAAForBlend();
+
+    SkTCopyOnFirstWrite<SkStrokeRec> stroke(origStroke);
+    // Can we treat a thin stroke as a hairline w/ coverage? If we can, we draw lots faster (raster
+    // device does this same test).
+
+    // Do not do this if gpu supports path rendering natively and we might be using the support
+    // (useCoverageAA == false). Hairline renderer is likely to be slow due to program switches.
+    if (!useCoverageAA || !fGpu->caps()->pathRenderingSupport()) {
+        SkScalar hairlineCoverage;
+        if (should_convert_to_hairline(useAA, *stroke, this->getMatrix(), &hairlineCoverage)) {
+            target->drawState()->setCoverage(SkScalarRoundToInt(hairlineCoverage * target->getDrawState().getCoverage()));
+            stroke.writable()->setHairlineStyle();
+        }
     }
 
-    GrPathRendererChain::DrawType type = useAA ? GrPathRendererChain::kColorAntiAlias_DrawType :
-                                                 GrPathRendererChain::kColor_DrawType;
+    GrPathRendererChain::DrawType type =
+        useCoverageAA ? GrPathRendererChain::kColorAntiAlias_DrawType :
+                           GrPathRendererChain::kColor_DrawType;
 
     const SkPath* pathPtr = &path;
     SkPath tmpPath;
-    SkStrokeRec strokeRec(stroke);
 
     // Try a 1st time without stroking the path and without allowing the SW renderer
-    GrPathRenderer* pr = this->getPathRenderer(*pathPtr, strokeRec, target, false, type);
+    GrPathRenderer* pr = this->getPathRenderer(*pathPtr, *stroke, target, false, type);
 
     if (NULL == pr) {
-        if (!strokeRec.isHairlineStyle()) {
+        if (!stroke->isHairlineStyle()) {
             // It didn't work the 1st time, so try again with the stroked path
-            if (strokeRec.applyToPath(&tmpPath, *pathPtr)) {
+            if (stroke->applyToPath(&tmpPath, *pathPtr)) {
                 pathPtr = &tmpPath;
-                strokeRec.setFillStyle();
+                stroke.writable()->setFillStyle();
             }
         }
         if (pathPtr->isEmpty()) {
@@ -1210,7 +1224,7 @@
         }
 
         // This time, allow SW renderer
-        pr = this->getPathRenderer(*pathPtr, strokeRec, target, true, type);
+        pr = this->getPathRenderer(*pathPtr, *stroke, target, true, type);
     }
 
     if (NULL == pr) {
@@ -1220,7 +1234,7 @@
         return;
     }
 
-    pr->drawPath(*pathPtr, strokeRec, target, useAA);
+    pr->drawPath(*pathPtr, *stroke, target, useCoverageAA);
 }
 
 ////////////////////////////////////////////////////////////////////////////////
diff --git a/gpu/GrDrawState.cpp b/gpu/GrDrawState.cpp
index 1743604..1bbcc26 100644
--- a/gpu/GrDrawState.cpp
+++ b/gpu/GrDrawState.cpp
@@ -54,7 +54,6 @@
     this->enableState(GrDrawState::kClip_StateBit);
 
     this->setColor(paint.getColor());
-    this->setCoverage4(paint.getCoverage());
     this->setState(GrDrawState::kDither_StateBit, paint.isDither());
     this->setState(GrDrawState::kHWAntialias_StateBit, paint.isAntiAlias());
 
@@ -220,7 +219,7 @@
 
     // Check whether coverage is treated as color. If so we run through the coverage computation.
     if (this->isCoverageDrawing()) {
-        GrColor coverageColor = this->getCoverage();
+        GrColor coverageColor = this->getCoverageColor();
         GrColor oldColor = color;
         color = 0;
         for (int c = 0; c < 4; ++c) {
@@ -312,7 +311,7 @@
 
     bool covIsZero = !this->isCoverageDrawing() &&
                      !this->hasCoverageVertexAttribute() &&
-                     0 == this->getCoverage();
+                     0 == this->getCoverageColor();
     // 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.
@@ -327,7 +326,7 @@
 
     // check for coverage due to constant coverage, per-vertex coverage, or coverage stage
     bool hasCoverage = forceCoverage ||
-                       0xffffffff != this->getCoverage() ||
+                       0xffffffff != this->getCoverageColor() ||
                        this->hasCoverageVertexAttribute() ||
                        fCoverageStages.count() > 0;
 
diff --git a/gpu/GrDrawState.h b/gpu/GrDrawState.h
index 2e4d7f8..3de0b12 100644
--- a/gpu/GrDrawState.h
+++ b/gpu/GrDrawState.h
@@ -311,15 +311,11 @@
         fCommon.fCoverage = GrColorPackRGBA(coverage, coverage, coverage, coverage);
     }
 
-    /**
-     * Version of above that specifies 4 channel per-vertex color. The value
-     * should be premultiplied.
-     */
-    void setCoverage4(GrColor coverage) {
-        fCommon.fCoverage = coverage;
+    uint8_t getCoverage() const {
+        return GrColorUnpackR(fCommon.fCoverage);
     }
 
-    GrColor getCoverage() const {
+    GrColor getCoverageColor() const {
         return fCommon.fCoverage;
     }
 
diff --git a/gpu/GrDrawTarget.h b/gpu/GrDrawTarget.h
index 266dc07..c505869 100644
--- a/gpu/GrDrawTarget.h
+++ b/gpu/GrDrawTarget.h
@@ -100,6 +100,15 @@
      */
     bool canApplyCoverage() const;
 
+    /** When we're using coverage AA but the blend is incompatible (given gpu
+     * limitations) we should disable AA. */
+    bool shouldDisableCoverageAAForBlend() {
+        // Enable below if we should draw with AA even when it produces
+        // incorrect blending.
+        // return false;
+        return !this->canApplyCoverage();
+    }
+
     /**
      * Given the current draw state and hw support, will HW AA lines be used (if
      * a line primitive type is drawn)?
diff --git a/gpu/GrOvalRenderer.cpp b/gpu/GrOvalRenderer.cpp
index aeeb85d..8f078db 100644
--- a/gpu/GrOvalRenderer.cpp
+++ b/gpu/GrOvalRenderer.cpp
@@ -460,7 +460,11 @@
 bool GrOvalRenderer::drawOval(GrDrawTarget* target, const GrContext* context, bool useAA,
                               const SkRect& oval, const SkStrokeRec& stroke)
 {
-    if (!useAA) {
+    bool useCoverageAA = useAA &&
+        !target->getDrawState().getRenderTarget()->isMultisampled() &&
+        !target->shouldDisableCoverageAAForBlend();
+
+    if (!useCoverageAA) {
         return false;
     }
 
@@ -469,13 +473,13 @@
     // we can draw circles
     if (SkScalarNearlyEqual(oval.width(), oval.height())
         && circle_stays_circle(vm)) {
-        this->drawCircle(target, useAA, oval, stroke);
+        this->drawCircle(target, useCoverageAA, oval, stroke);
     // if we have shader derivative support, render as device-independent
     } else if (target->caps()->shaderDerivativeSupport()) {
-        return this->drawDIEllipse(target, useAA, oval, stroke);
+        return this->drawDIEllipse(target, useCoverageAA, oval, stroke);
     // otherwise axis-aligned ellipses only
     } else if (vm.rectStaysRect()) {
-        return this->drawEllipse(target, useAA, oval, stroke);
+        return this->drawEllipse(target, useCoverageAA, oval, stroke);
     } else {
         return false;
     }
@@ -492,7 +496,7 @@
 };
 
 void GrOvalRenderer::drawCircle(GrDrawTarget* target,
-                                bool useAA,
+                                bool useCoverageAA,
                                 const SkRect& circle,
                                 const SkStrokeRec& stroke)
 {
@@ -597,7 +601,7 @@
 };
 
 bool GrOvalRenderer::drawEllipse(GrDrawTarget* target,
-                                 bool useAA,
+                                 bool useCoverageAA,
                                  const SkRect& ellipse,
                                  const SkStrokeRec& stroke)
 {
@@ -606,7 +610,7 @@
     {
         // we should have checked for this previously
         bool isAxisAlignedEllipse = drawState->getViewMatrix().rectStaysRect();
-        SkASSERT(useAA && isAxisAlignedEllipse);
+        SkASSERT(useCoverageAA && isAxisAlignedEllipse);
     }
 #endif
 
@@ -729,7 +733,7 @@
 }
 
 bool GrOvalRenderer::drawDIEllipse(GrDrawTarget* target,
-                                   bool useAA,
+                                   bool useCoverageAA,
                                    const SkRect& ellipse,
                                    const SkStrokeRec& stroke)
 {
@@ -882,8 +886,12 @@
 bool GrOvalRenderer::drawSimpleRRect(GrDrawTarget* target, GrContext* context, bool useAA,
                                      const SkRRect& rrect, const SkStrokeRec& stroke)
 {
+    bool useCoverageAA = useAA &&
+        !target->getDrawState().getRenderTarget()->isMultisampled() &&
+        !target->shouldDisableCoverageAAForBlend();
+
     // only anti-aliased rrects for now
-    if (!useAA) {
+    if (!useCoverageAA) {
         return false;
     }
 
@@ -891,7 +899,7 @@
 #ifdef SK_DEBUG
     {
         // we should have checked for this previously
-        SkASSERT(useAA && vm.rectStaysRect() && rrect.isSimple());
+        SkASSERT(useCoverageAA && vm.rectStaysRect() && rrect.isSimple());
     }
 #endif
 
diff --git a/gpu/GrOvalRenderer.h b/gpu/GrOvalRenderer.h
index b58abb7..9653fcc 100644
--- a/gpu/GrOvalRenderer.h
+++ b/gpu/GrOvalRenderer.h
@@ -37,13 +37,13 @@
                          const SkRRect& rrect, const SkStrokeRec& stroke);
 
 private:
-    bool drawEllipse(GrDrawTarget* target, bool useAA,
+    bool drawEllipse(GrDrawTarget* target, bool useCoverageAA,
                      const SkRect& ellipse,
                      const SkStrokeRec& stroke);
-    bool drawDIEllipse(GrDrawTarget* target, bool useAA,
+    bool drawDIEllipse(GrDrawTarget* target, bool useCoverageAA,
                        const SkRect& ellipse,
                        const SkStrokeRec& stroke);
-    void drawCircle(GrDrawTarget* target, bool useAA,
+    void drawCircle(GrDrawTarget* target, bool useCoverageAA,
                     const SkRect& circle,
                     const SkStrokeRec& stroke);
 
diff --git a/gpu/SkGpuDevice.cpp b/gpu/SkGpuDevice.cpp
index ca86b84..52dc5a7 100644
--- a/gpu/SkGpuDevice.cpp
+++ b/gpu/SkGpuDevice.cpp
@@ -12,7 +12,8 @@
 
 #include "GrContext.h"
 #include "GrBitmapTextContext.h"
-
+#include "GrGpu.h"
+#include "GrDrawTargetCaps.h"
 #include "SkGrTexturePixelRef.h"
 
 #include "SkColorFilter.h"
@@ -850,14 +851,6 @@
         return;
     }
 
-    // can we cheat, and treat a thin stroke as a hairline w/ coverage
-    // if we can, we draw lots faster (raster device does this same test)
-    SkScalar hairlineCoverage;
-    bool doHairLine = SkDrawTreatAsHairline(paint, fContext->getMatrix(), &hairlineCoverage);
-    if (doHairLine) {
-        grPaint.setCoverage(SkScalarRoundToInt(hairlineCoverage * grPaint.getCoverage()));
-    }
-
     // If we have a prematrix, apply it to the path, optimizing for the case
     // where the original path can in fact be modified in place (even though
     // its parameter type is const).
@@ -887,10 +880,6 @@
         pathPtr = &effectPath;
     }
 
-    if (!pathEffect && doHairLine) {
-        stroke.setHairlineStyle();
-    }
-
     if (paint.getMaskFilter()) {
         if (!stroke.isHairlineStyle()) {
             if (stroke.applyToPath(&tmpPath, *pathPtr)) {
diff --git a/gpu/gl/GrGLProgram.cpp b/gpu/gl/GrGLProgram.cpp
index accaf88..5b030fa 100644
--- a/gpu/gl/GrGLProgram.cpp
+++ b/gpu/gl/GrGLProgram.cpp
@@ -207,10 +207,10 @@
         coverage = 0;
     } else if (blendOpts & GrDrawState::kEmitCoverage_BlendOptFlag) {
         color = 0xffffffff;
-        coverage = drawState.getCoverage();
+        coverage = drawState.getCoverageColor();
     } else {
         color = drawState.getColor();
-        coverage = drawState.getCoverage();
+        coverage = drawState.getCoverageColor();
     }
 
     this->setColor(drawState, color, sharedState);
diff --git a/gpu/gl/GrGLProgramDesc.cpp b/gpu/gl/GrGLProgramDesc.cpp
index d958742..6e9d8a4 100644
--- a/gpu/gl/GrGLProgramDesc.cpp
+++ b/gpu/gl/GrGLProgramDesc.cpp
@@ -156,7 +156,7 @@
         header->fHasVertexCode = true;
     }
 
-    bool covIsSolidWhite = !requiresCoverageAttrib && 0xffffffff == drawState.getCoverage();
+    bool covIsSolidWhite = !requiresCoverageAttrib && 0xffffffff == drawState.getCoverageColor();
 
     if (skipCoverage) {
         header->fCoverageInput = kTransBlack_ColorInput;