Revert "Remove antialiasing control from GrPaint."

This reverts commit 9f549358b3ac9f61e78b194e39d6ac6eb322e35e.

Reason for revert: hitting asserts

Change-Id: I542d34edc05ecf72b7646263f25736a0950c78e7
Reviewed-on: https://skia-review.googlesource.com/5707
Commit-Queue: Brian Salomon <bsalomon@google.com>
Reviewed-by: Brian Salomon <bsalomon@google.com>
diff --git a/gm/beziereffects.cpp b/gm/beziereffects.cpp
index 9a1990b..f924ee0 100644
--- a/gm/beziereffects.cpp
+++ b/gm/beziereffects.cpp
@@ -195,8 +195,7 @@
                     sk_sp<GrDrawOp> batch = sk_make_sp<BezierCubicOrConicTestBatch>(
                             gp, bounds, color, klmEqs, klmSigns[c]);
 
-                    renderTargetContext->priv().testingOnly_drawBatch(grPaint, GrAAType::kNone,
-                                                                      batch.get());
+                    renderTargetContext->priv().testingOnly_drawBatch(grPaint, batch.get());
                 }
                 ++col;
                 if (numCols == col) {
@@ -328,8 +327,7 @@
                     sk_sp<GrDrawOp> batch(
                         new BezierCubicOrConicTestBatch(gp, bounds, color, klmEqs, 1.f));
 
-                    renderTargetContext->priv().testingOnly_drawBatch(grPaint, GrAAType::kNone,
-                                                                      batch.get());
+                    renderTargetContext->priv().testingOnly_drawBatch(grPaint, batch.get());
                 }
                 ++col;
                 if (numCols == col) {
@@ -540,8 +538,7 @@
 
                     sk_sp<GrDrawOp> batch(new BezierQuadTestBatch(gp, bounds, color, DevToUV));
 
-                    renderTargetContext->priv().testingOnly_drawBatch(grPaint, GrAAType::kNone,
-                                                                      batch.get());
+                    renderTargetContext->priv().testingOnly_drawBatch(grPaint, batch.get());
                 }
                 ++col;
                 if (numCols == col) {
diff --git a/gm/bigrrectaaeffect.cpp b/gm/bigrrectaaeffect.cpp
index 9750d90..b114f49 100644
--- a/gm/bigrrectaaeffect.cpp
+++ b/gm/bigrrectaaeffect.cpp
@@ -90,8 +90,7 @@
                     sk_sp<GrDrawOp> batch(
                             GrRectBatchFactory::CreateNonAAFill(0xff000000, SkMatrix::I(), bounds,
                                                                 nullptr, nullptr));
-                    renderTargetContext->priv().testingOnly_drawBatch(grPaint, GrAAType::kNone,
-                                                                      batch.get());
+                    renderTargetContext->priv().testingOnly_drawBatch(grPaint, batch.get());
                 }
             canvas->restore();
             x = x + fTestOffsetX;
diff --git a/gm/constcolorprocessor.cpp b/gm/constcolorprocessor.cpp
index 67b2b33..d706742 100644
--- a/gm/constcolorprocessor.cpp
+++ b/gm/constcolorprocessor.cpp
@@ -112,8 +112,7 @@
                     sk_sp<GrDrawOp> batch(
                             GrRectBatchFactory::CreateNonAAFill(grPaint.getColor(), viewMatrix,
                                                                 renderRect, nullptr, nullptr));
-                    renderTargetContext->priv().testingOnly_drawBatch(grPaint, GrAAType::kNone,
-                                                                      batch.get());
+                    renderTargetContext->priv().testingOnly_drawBatch(grPaint, batch.get());
 
                     // Draw labels for the input to the processor and the processor to the right of
                     // the test rect. The input label appears above the processor label.
diff --git a/gm/convexpolyeffect.cpp b/gm/convexpolyeffect.cpp
index c7a5d0c..7a8c5b2 100644
--- a/gm/convexpolyeffect.cpp
+++ b/gm/convexpolyeffect.cpp
@@ -185,8 +185,7 @@
 
                 sk_sp<GrDrawOp> batch(new PolyBoundsBatch(p.getBounds(), 0xff000000));
 
-                renderTargetContext->priv().testingOnly_drawBatch(grPaint, GrAAType::kNone,
-                                                                  batch.get());
+                renderTargetContext->priv().testingOnly_drawBatch(grPaint, batch.get());
 
                 x += SkScalarCeilToScalar(path->getBounds().width() + kDX);
             }
@@ -225,8 +224,7 @@
 
                 sk_sp<GrDrawOp> batch(new PolyBoundsBatch(rect, 0xff000000));
 
-                renderTargetContext->priv().testingOnly_drawBatch(grPaint, GrAAType::kNone,
-                                                                  batch.get());
+                renderTargetContext->priv().testingOnly_drawBatch(grPaint, batch.get());
 
                 x += SkScalarCeilToScalar(rect.width() + kDX);
             }
diff --git a/gm/rrects.cpp b/gm/rrects.cpp
index a3b31d5..268e449 100644
--- a/gm/rrects.cpp
+++ b/gm/rrects.cpp
@@ -118,9 +118,7 @@
                             sk_sp<GrDrawOp> batch(
                                     GrRectBatchFactory::CreateNonAAFill(0xff000000, SkMatrix::I(),
                                                                         bounds, nullptr, nullptr));
-                            renderTargetContext->priv().testingOnly_drawBatch(grPaint,
-                                                                              GrAAType::kNone,
-                                                                              batch.get());
+                            renderTargetContext->priv().testingOnly_drawBatch(grPaint, batch.get());
                         } else {
                             drew = false;
                         }
diff --git a/gm/texdata.cpp b/gm/texdata.cpp
index 574dfad..4a74468 100644
--- a/gm/texdata.cpp
+++ b/gm/texdata.cpp
@@ -102,7 +102,7 @@
         tm.postIDiv(2*S, 2*S);
         paint.addColorTextureProcessor(texture, nullptr, tm);
 
-        renderTargetContext->drawRect(clip, paint, GrAA::kNo, vm, SkRect::MakeWH(2*S, 2*S));
+        renderTargetContext->drawRect(clip, paint, vm, SkRect::MakeWH(2*S, 2*S));
 
         // now update the lower right of the texture in first pass
         // or upper right in second pass
@@ -116,7 +116,7 @@
         texture->writePixels(S, (i ? 0 : S), S, S,
                                 texture->config(), gTextureData.get(),
                                 4 * stride);
-        renderTargetContext->drawRect(clip, paint, GrAA::kNo, vm, SkRect::MakeWH(2*S, 2*S));
+        renderTargetContext->drawRect(clip, paint, vm, SkRect::MakeWH(2*S, 2*S));
     }
 }
 #endif
diff --git a/gm/texturedomaineffect.cpp b/gm/texturedomaineffect.cpp
index 5ce6017..e51a906 100644
--- a/gm/texturedomaineffect.cpp
+++ b/gm/texturedomaineffect.cpp
@@ -130,8 +130,7 @@
                     sk_sp<GrDrawOp> batch(
                             GrRectBatchFactory::CreateNonAAFill(GrColor_WHITE, viewMatrix,
                                                                 renderRect, nullptr, nullptr));
-                    renderTargetContext->priv().testingOnly_drawBatch(grPaint, GrAAType::kNone,
-                                                                      batch.get());
+                    renderTargetContext->priv().testingOnly_drawBatch(grPaint, batch.get());
                     x += renderRect.width() + kTestPad;
                 }
                 y += renderRect.height() + kTestPad;
diff --git a/gm/windowrectangles.cpp b/gm/windowrectangles.cpp
index 94da20b..3949b3f 100644
--- a/gm/windowrectangles.cpp
+++ b/gm/windowrectangles.cpp
@@ -141,7 +141,7 @@
 class MaskOnlyClipBase : public GrClip {
 private:
     bool quickContains(const SkRect&) const final { return false; }
-    bool isRRect(const SkRect& rtBounds, SkRRect* rr, GrAA*) const final { return false; }
+    bool isRRect(const SkRect& rtBounds, SkRRect* rr, bool* aa) const final { return false; }
     void getConservativeBounds(int width, int height, SkIRect* rect, bool* iior) const final {
         rect->set(0, 0, width, height);
         if (iior) {
@@ -190,6 +190,7 @@
     const GrReducedClip reducedClip(stack, SkRect::Make(kCoverRect), kNumWindows);
 
     GrPaint paint;
+    paint.setAntiAlias(true);
     if (!rtc->isStencilBufferMultisampled()) {
         paint.setColor4f(GrColor4f(0, 0.25f, 1, 1));
         this->visualizeAlphaMask(ctx, rtc, reducedClip, paint);
@@ -216,7 +217,7 @@
     this->stencilCheckerboard(maskRTC.get(), true);
     maskRTC->clear(nullptr, GrColorPackA4(0xff), true);
     maskRTC->priv().drawAndStencilRect(StencilOnlyClip(), &GrUserStencilSettings::kUnused,
-                                       SkRegion::kDifference_Op, false, GrAA::kNo, SkMatrix::I(),
+                                       SkRegion::kDifference_Op, false, false, SkMatrix::I(),
                                        SkRect::MakeIWH(maskRTC->width(), maskRTC->height()));
     reducedClip.drawAlphaClipMask(maskRTC.get());
     sk_sp<GrTexture> mask(maskRTC->asTexture());
@@ -228,7 +229,7 @@
     // inside window rectangles or outside the scissor should still have the initial checkerboard
     // intact. (This verifies we didn't spend any time modifying those pixels in the mask.)
     AlphaOnlyClip clip(mask.get(), x, y);
-    rtc->drawRect(clip, paint, GrAA::kYes, SkMatrix::I(),
+    rtc->drawRect(clip, paint, SkMatrix::I(),
                  SkRect::Make(SkIRect::MakeXYWH(x, y, mask->width(), mask->height())));
 }
 
@@ -267,7 +268,7 @@
         for (int x = (y & 1) == flip ? 0 : kMaskCheckerSize;
              x < kLayerRect.width(); x += 2 * kMaskCheckerSize) {
             SkIRect checker = SkIRect::MakeXYWH(x, y, kMaskCheckerSize, kMaskCheckerSize);
-            rtc->priv().stencilRect(GrNoClip(), &kSetClip, GrAAType::kNone, SkMatrix::I(),
+            rtc->priv().stencilRect(GrNoClip(), &kSetClip, false, SkMatrix::I(),
                                     SkRect::Make(checker));
         }
     }
diff --git a/gm/yuvtorgbeffect.cpp b/gm/yuvtorgbeffect.cpp
index fb0bcf3..6b90dad 100644
--- a/gm/yuvtorgbeffect.cpp
+++ b/gm/yuvtorgbeffect.cpp
@@ -129,8 +129,7 @@
                     sk_sp<GrDrawOp> batch(
                             GrRectBatchFactory::CreateNonAAFill(GrColor_WHITE, viewMatrix,
                                                                 renderRect, nullptr, nullptr));
-                    renderTargetContext->priv().testingOnly_drawBatch(grPaint, GrAAType::kNone,
-                                                                      batch.get());
+                    renderTargetContext->priv().testingOnly_drawBatch(grPaint, batch.get());
                 }
                 x += renderRect.width() + kTestPad;
             }
@@ -245,8 +244,7 @@
                 grPaint.addColorFragmentProcessor(fp);
                 sk_sp<GrDrawOp> batch(GrRectBatchFactory::CreateNonAAFill(
                     GrColor_WHITE, viewMatrix, renderRect, nullptr, nullptr));
-                renderTargetContext->priv().testingOnly_drawBatch(grPaint, GrAAType::kNone,
-                                                                  batch.get());
+                renderTargetContext->priv().testingOnly_drawBatch(grPaint, batch.get());
             }
         }
     }
diff --git a/include/gpu/GrClip.h b/include/gpu/GrClip.h
index 9bf2da2..2d4c1f2 100644
--- a/include/gpu/GrClip.h
+++ b/include/gpu/GrClip.h
@@ -8,7 +8,6 @@
 #ifndef GrClip_DEFINED
 #define GrClip_DEFINED
 
-#include "GrTypes.h"
 #include "SkRect.h"
 #include "SkRRect.h"
 
@@ -46,7 +45,7 @@
      * @return true if the clip is equivalent to a single rrect, false otherwise.
      *
      */
-    virtual bool isRRect(const SkRect& rtBounds, SkRRect* rrect, GrAA* aa) const = 0;
+    virtual bool isRRect(const SkRect& rtBounds, SkRRect* rrect, bool* aa) const = 0;
 
     /**
      * This is the maximum distance that a draw may extend beyond a clip's boundary and still count
@@ -141,7 +140,7 @@
     bool apply(GrContext*, GrRenderTargetContext*, bool, bool, GrAppliedClip*) const final {
         return true;
     }
-    bool isRRect(const SkRect&, SkRRect*, GrAA*) const override { return false; }
+    bool isRRect(const SkRect&, SkRRect*, bool*) const override { return false; }
 };
 
 #endif
diff --git a/include/gpu/GrPaint.h b/include/gpu/GrPaint.h
index 6cdc2de..9390d02 100644
--- a/include/gpu/GrPaint.h
+++ b/include/gpu/GrPaint.h
@@ -30,9 +30,10 @@
  * The primitive color computation starts with the color specified by setColor(). This color is the
  * input to the first color stage. Each color stage feeds its output to the next color stage.
  *
- * Fractional pixel coverage follows a similar flow. The GrGeometryProcessor (specified elsewhere)
- * provides the initial coverage which is passed to the first coverage fragment processor, which
- * feeds its output to next coverage fragment processor.
+ * Fractional pixel coverage follows a similar flow. The coverage is initially the value specified
+ * by setCoverage(). This is input to the first coverage stage. Coverage stages are chained
+ * together in the same manner as color stages. The output of the last stage is modulated by any
+ * fractional coverage produced by anti-aliasing. This last step produces the final coverage, C.
  *
  * setXPFactory is used to control blending between the output color and dest. It also implements
  * the application of fractional coverage from the coverage pipeline.
@@ -57,6 +58,12 @@
     GrColor getColor() const { return fColor.toGrColor(); }
 
     /**
+     * Should primitives be anti-aliased or not. Defaults to false.
+     */
+    void setAntiAlias(bool aa) { fAntiAlias = aa; }
+    bool isAntiAlias() const { return fAntiAlias; }
+
+    /**
      * Should shader output conversion from linear to sRGB be disabled.
      * Only relevant if the destination is sRGB. Defaults to false.
      */
@@ -139,6 +146,7 @@
     }
 
     GrPaint& operator=(const GrPaint& paint) {
+        fAntiAlias = paint.fAntiAlias;
         fDisableOutputConversionToSRGB = paint.fDisableOutputConversionToSRGB;
         fAllowSRGBInputs = paint.fAllowSRGBInputs;
         fUsesDistanceVectorField = paint.fUsesDistanceVectorField;
@@ -177,6 +185,7 @@
     SkSTArray<4, sk_sp<GrFragmentProcessor>>  fColorFragmentProcessors;
     SkSTArray<2, sk_sp<GrFragmentProcessor>>  fCoverageFragmentProcessors;
 
+    bool                                      fAntiAlias;
     bool                                      fDisableOutputConversionToSRGB;
     bool                                      fAllowSRGBInputs;
     bool                                      fUsesDistanceVectorField;
diff --git a/include/gpu/GrRenderTargetContext.h b/include/gpu/GrRenderTargetContext.h
index f4894fa..93a3282 100644
--- a/include/gpu/GrRenderTargetContext.h
+++ b/include/gpu/GrRenderTargetContext.h
@@ -88,17 +88,15 @@
     void drawPaint(const GrClip&, const GrPaint&, const SkMatrix& viewMatrix);
 
     /**
-     * Draw the rect using a paint.
-     * @param paint        describes how to color pixels.
-     * @param GrAA         Controls whether rect is antialiased
-     * @param viewMatrix   transformation matrix
-     * @param style        The style to apply. Null means fill. Currently path effects are not
-     *                     allowed.
-     * The rects coords are used to access the paint (through texture matrix)
+     *  Draw the rect using a paint.
+     *  @param paint        describes how to color pixels.
+     *  @param viewMatrix   transformation matrix
+     *  @param style        The style to apply. Null means fill. Currently path effects are not
+     *                      allowed.
+     *  The rects coords are used to access the paint (through texture matrix)
      */
     void drawRect(const GrClip&,
                   const GrPaint& paint,
-                  GrAA,
                   const SkMatrix& viewMatrix,
                   const SkRect&,
                   const GrStyle* style  = nullptr);
@@ -106,15 +104,13 @@
     /**
      * Maps a rectangle of shader coordinates to a rectangle and fills that rectangle.
      *
-     * @param paint        describes how to color pixels.
-     * @param GrAA         Controls whether rect is antialiased
-     * @param viewMatrix   transformation matrix which applies to rectToDraw
-     * @param rectToDraw   the rectangle to draw
-     * @param localRect    the rectangle of shader coordinates applied to rectToDraw
+     * @param paint         describes how to color pixels.
+     * @param viewMatrix    transformation matrix which applies to rectToDraw
+     * @param rectToDraw    the rectangle to draw
+     * @param localRect     the rectangle of shader coordinates applied to rectToDraw
      */
     void fillRectToRect(const GrClip&,
                         const GrPaint& paint,
-                        GrAA,
                         const SkMatrix& viewMatrix,
                         const SkRect& rectToDraw,
                         const SkRect& localRect);
@@ -124,36 +120,33 @@
      */
     void fillRectWithLocalMatrix(const GrClip& clip,
                                  const GrPaint& paint,
-                                 GrAA,
                                  const SkMatrix& viewMatrix,
                                  const SkRect& rect,
                                  const SkMatrix& localMatrix);
 
     /**
-     * Draw a roundrect using a paint.
+     *  Draw a roundrect using a paint.
      *
-     * @param paint       describes how to color pixels.
-     * @param GrAA        Controls whether rrect is antialiased.
-     * @param viewMatrix  transformation matrix
-     * @param rrect       the roundrect to draw
-     * @param style       style to apply to the rrect. Currently path effects are not allowed.
+     *  @param paint        describes how to color pixels.
+     *  @param viewMatrix   transformation matrix
+     *  @param rrect        the roundrect to draw
+     *  @param style        style to apply to the rrect. Currently path effects are not allowed.
      */
     void drawRRect(const GrClip&,
                    const GrPaint&,
-                   GrAA,
                    const SkMatrix& viewMatrix,
                    const SkRRect& rrect,
                    const GrStyle& style);
 
     /**
-     * Draw a roundrect using a paint and a shadow shader. This is separate from drawRRect
-     * because it uses different underlying geometry and GeometryProcessor
+     *  Draw a roundrect using a paint and a shadow shader. This is separate from drawRRect
+     *  because it uses different underlying geometry and GeometryProcessor
      *
-     * @param paint        describes how to color pixels.
-     * @param viewMatrix   transformation matrix
-     * @param rrect        the roundrect to draw
-     * @param blurRadius   amount of shadow blur to apply (in device space)
-     * @param style        style to apply to the rrect. Currently path effects are not allowed.
+     *  @param paint        describes how to color pixels.
+     *  @param viewMatrix   transformation matrix
+     *  @param rrect        the roundrect to draw
+     *  @param blurRadius   amount of shadow blur to apply (in device space)
+     *  @param style        style to apply to the rrect. Currently path effects are not allowed.
      */
     void drawShadowRRect(const GrClip&,
                          const GrPaint&,
@@ -163,18 +156,17 @@
                          const GrStyle& style);
 
     /**
-     * Shortcut for filling a SkPath consisting of nested rrects using a paint. The result is
-     * undefined if outer does not contain inner.
+     *  Shortcut for drawing an SkPath consisting of nested rrects using a paint.
+     *  Does not support stroking. The result is undefined if outer does not contain
+     *  inner.
      *
-     * @param paint        describes how to color pixels.
-     * @param GrAA         Controls whether rrects edges are antialiased
-     * @param viewMatrix   transformation matrix
-     * @param outer        the outer roundrect
-     * @param inner        the inner roundrect
+     *  @param paint        describes how to color pixels.
+     *  @param viewMatrix   transformation matrix
+     *  @param outer        the outer roundrect
+     *  @param inner        the inner roundrect
      */
     void drawDRRect(const GrClip&,
                     const GrPaint&,
-                    GrAA,
                     const SkMatrix& viewMatrix,
                     const SkRRect& outer,
                     const SkRRect& inner);
@@ -183,14 +175,12 @@
      * Draws a path.
      *
      * @param paint         describes how to color pixels.
-     * @param GrAA          Controls whether the path is antialiased.
      * @param viewMatrix    transformation matrix
      * @param path          the path to draw
      * @param style         style to apply to the path.
      */
     void drawPath(const GrClip&,
                   const GrPaint&,
-                  GrAA,
                   const SkMatrix& viewMatrix,
                   const SkPath&,
                   const GrStyle& style);
@@ -224,8 +214,7 @@
                       int indexCount);
 
     /**
-     * Draws textured sprites from an atlas with a paint. This currently does not support AA for the
-     * sprite rectangle edges.
+     * Draws textured sprites from an atlas with a paint.
      *
      * @param   paint           describes how to color pixels.
      * @param   viewMatrix      transformation matrix
@@ -248,13 +237,11 @@
      *
      * @param paint         describes how to color pixels
      * @param viewMatrix    transformation matrix
-     * @param aa            should the rects of the region be antialiased.
      * @param region        the region to be drawn
      * @param style         style to apply to the region
      */
     void drawRegion(const GrClip&,
                     const GrPaint& paint,
-                    GrAA aa,
                     const SkMatrix& viewMatrix,
                     const SkRegion& region,
                     const GrStyle& style);
@@ -263,35 +250,31 @@
      * Draws an oval.
      *
      * @param paint         describes how to color pixels.
-     * @param GrAA          Controls whether the oval is antialiased.
      * @param viewMatrix    transformation matrix
      * @param oval          the bounding rect of the oval.
      * @param style         style to apply to the oval. Currently path effects are not allowed.
      */
     void drawOval(const GrClip&,
                   const GrPaint& paint,
-                  GrAA,
                   const SkMatrix& viewMatrix,
                   const SkRect& oval,
                   const GrStyle& style);
-    /**
-     * Draws a partial arc of an oval.
-     *
-     * @param paint         describes how to color pixels.
-     * @param GrGrAA          Controls whether the arc is antialiased.
-     * @param viewMatrix    transformation matrix.
-     * @param oval          the bounding rect of the oval.
-     * @param startAngle    starting angle in degrees.
-     * @param sweepAngle    angle to sweep in degrees. Must be in (-360, 360)
-     * @param useCenter     true means that the implied path begins at the oval center, connects as
-     *                      a line to the point indicated by the start contains the arc indicated by
-     *                      the sweep angle. If false the line beginning at the center point is
-     *                      omitted.
-     * @param style         style to apply to the oval.
-     */
+   /**
+    * Draws a partial arc of an oval.
+    *
+    * @param paint         describes how to color pixels.
+    * @param viewMatrix    transformation matrix.
+    * @param oval          the bounding rect of the oval.
+    * @param startAngle    starting angle in degrees.
+    * @param sweepAngle    angle to sweep in degrees. Must be in (-360, 360)
+    * @param useCenter     true means that the implied path begins at the oval center, connects as a
+    *                      line to the point indicated by the start contains the arc indicated by
+    *                      the sweep angle. If false the line beginning at the center point is
+    *                      omitted.
+    * @param style         style to apply to the oval.
+    */
     void drawArc(const GrClip&,
                  const GrPaint& paint,
-                 GrAA,
                  const SkMatrix& viewMatrix,
                  const SkRect& oval,
                  SkScalar startAngle,
@@ -350,6 +333,10 @@
     bool isUnifiedMultisampled() const { return fRenderTargetProxy->isUnifiedMultisampled(); }
     bool hasMixedSamples() const { return fRenderTargetProxy->isMixedSampled(); }
 
+    bool mustUseHWAA(const GrPaint& paint) const {
+        return paint.isAntiAlias() && fRenderTargetProxy->isUnifiedMultisampled();
+    }
+
     const GrCaps* caps() const { return fContext->caps(); }
     const GrSurfaceDesc& desc() const { return fRenderTargetProxy->desc(); }
     int width() const { return fRenderTargetProxy->width(); }
@@ -412,16 +399,6 @@
     SkDEBUGCODE(void validate() const;)
 
 private:
-    inline GrAAType decideAAType(GrAA aa) {
-        if (GrAA::kNo == aa) {
-            return GrAAType::kNone;
-        }
-        if (this->isUnifiedMultisampled()) {
-            return GrAAType::kHW;
-        }
-        return GrAAType::kCoverage;
-    }
-
     friend class GrAtlasTextBlob; // for access to addDrawOp
     friend class GrStencilAndCoverTextContext; // for access to addDrawOp
 
@@ -447,14 +424,12 @@
 
     bool drawFilledDRRect(const GrClip& clip,
                           const GrPaint& paint,
-                          GrAA,
                           const SkMatrix& viewMatrix,
                           const SkRRect& origOuter,
                           const SkRRect& origInner);
 
     bool drawFilledRect(const GrClip& clip,
                         const GrPaint& paint,
-                        GrAA,
                         const SkMatrix& viewMatrix,
                         const SkRect& rect,
                         const GrUserStencilSettings* ss);
@@ -466,23 +441,13 @@
                              const SkRect* localRect,
                              const SkMatrix* localMatrix,
                              const GrUserStencilSettings* ss,
-                             GrAAType hwOrNoneAAType);
+                             bool useHWAA);
 
     void internalDrawPath(const GrClip& clip,
                           const GrPaint& paint,
-                          GrAA aa,
                           const SkMatrix& viewMatrix,
                           const SkPath& path,
-                          const GrStyle& style) {
-        this->internalDrawPath(clip, paint, this->decideAAType(aa), viewMatrix, path, style);
-    }
-
-    void internalDrawPath(const GrClip&,
-                          const GrPaint&,
-                          GrAAType,
-                          const SkMatrix&,
-                          const SkPath&,
-                          const GrStyle&);
+                          const GrStyle& style);
 
     // This entry point allows the GrTextContext-derived classes to add their ops to the GrOpList.
     void addDrawOp(const GrPipelineBuilder&, const GrClip&, GrDrawOp*);
diff --git a/include/gpu/GrTypes.h b/include/gpu/GrTypes.h
index 86e83f9..846537a 100644
--- a/include/gpu/GrTypes.h
+++ b/include/gpu/GrTypes.h
@@ -149,18 +149,6 @@
 ///////////////////////////////////////////////////////////////////////////////
 
 /**
- * Used to control antialiasing in draw calls.
- */
-enum class GrAA {
-    kYes,
-    kNo
-};
-
-static inline GrAA GrBoolToAA(bool aa) { return aa ? GrAA::kYes : GrAA::kNo; }
-
-///////////////////////////////////////////////////////////////////////////////
-
-/**
 * Geometric primitives used for drawing.
 */
 enum GrPrimitiveType {
diff --git a/include/gpu/GrTypesPriv.h b/include/gpu/GrTypesPriv.h
index edf3ab9..51dccc5 100644
--- a/include/gpu/GrTypesPriv.h
+++ b/include/gpu/GrTypesPriv.h
@@ -11,16 +11,6 @@
 #include "GrTypes.h"
 #include "SkRefCnt.h"
 
-/** This enum indicates the type of antialiasing to be performed. */
-enum class GrAAType {
-    /** No antialiasing */
-    kNone,
-    /** Use fragment shader code to compute a fractional pixel coverage. */
-    kCoverage,
-    /** Use HW AA (MSAA). */
-    kHW
-};
-
  /**
   * Types of shader-language-specific boxed variables we can create. (Currently only GrGLShaderVars,
   * but should be applicable to other shader languages.)
diff --git a/src/core/SkGpuBlurUtils.cpp b/src/core/SkGpuBlurUtils.cpp
index 0c01f6c..f210178 100644
--- a/src/core/SkGpuBlurUtils.cpp
+++ b/src/core/SkGpuBlurUtils.cpp
@@ -83,7 +83,7 @@
     paint.setPorterDuffXPFactory(SkBlendMode::kSrc);
     SkMatrix localMatrix = SkMatrix::MakeTrans(-SkIntToScalar(srcOffset.x()),
                                                -SkIntToScalar(srcOffset.y()));
-    renderTargetContext->fillRectWithLocalMatrix(clip, paint, GrAA::kNo, SkMatrix::I(),
+    renderTargetContext->fillRectWithLocalMatrix(clip, paint, SkMatrix::I(),
                                                  SkRect::Make(dstRect), localMatrix);
 }
 
@@ -111,7 +111,7 @@
             true, sigmaX, sigmaY));
     paint.addColorFragmentProcessor(std::move(conv));
     paint.setPorterDuffXPFactory(SkBlendMode::kSrc);
-    renderTargetContext->fillRectWithLocalMatrix(clip, paint, GrAA::kNo, SkMatrix::I(),
+    renderTargetContext->fillRectWithLocalMatrix(clip, paint, SkMatrix::I(),
                                                  SkRect::Make(dstRect), localMatrix);
 }
 
@@ -288,7 +288,7 @@
         paint.setPorterDuffXPFactory(SkBlendMode::kSrc);
         shrink_irect_by_2(&dstRect, i < scaleFactorX, i < scaleFactorY);
 
-        dstRenderTargetContext->fillRectToRect(clip, paint, GrAA::kNo, SkMatrix::I(),
+        dstRenderTargetContext->fillRectToRect(clip, paint, SkMatrix::I(),
                                                SkRect::Make(dstRect), SkRect::Make(srcRect));
 
         srcRenderTargetContext = dstRenderTargetContext;
@@ -378,7 +378,7 @@
         SkIRect dstRect(srcRect);
         scale_irect(&dstRect, scaleFactorX, scaleFactorY);
 
-        dstRenderTargetContext->fillRectToRect(clip, paint, GrAA::kNo, SkMatrix::I(),
+        dstRenderTargetContext->fillRectToRect(clip, paint, SkMatrix::I(),
                                                SkRect::Make(dstRect), SkRect::Make(srcRect));
 
         srcRenderTargetContext = dstRenderTargetContext;
diff --git a/src/core/SkImageFilter.cpp b/src/core/SkImageFilter.cpp
index 2ec441f..df46a13 100644
--- a/src/core/SkImageFilter.cpp
+++ b/src/core/SkImageFilter.cpp
@@ -297,7 +297,7 @@
     SkRect srcRect = SkRect::Make(bounds);
     SkRect dstRect = SkRect::MakeWH(srcRect.width(), srcRect.height());
     GrFixedClip clip(dstIRect);
-    renderTargetContext->fillRectToRect(clip, paint, GrAA::kNo, SkMatrix::I(), dstRect, srcRect);
+    renderTargetContext->fillRectToRect(clip, paint, SkMatrix::I(), dstRect, srcRect);
 
     return SkSpecialImage::MakeDeferredFromGpu(context, dstIRect,
                                                kNeedNewImageUniqueID_SpecialImage,
diff --git a/src/effects/SkAlphaThresholdFilter.cpp b/src/effects/SkAlphaThresholdFilter.cpp
index 6cf1ce6..43751e1 100644
--- a/src/effects/SkAlphaThresholdFilter.cpp
+++ b/src/effects/SkAlphaThresholdFilter.cpp
@@ -114,7 +114,7 @@
     GrFixedClip clip(SkIRect::MakeWH(bounds.width(), bounds.height()));
     while (!iter.done()) {
         SkRect rect = SkRect::Make(iter.rect());
-        rtContext->drawRect(clip, grPaint, GrAA::kNo, inMatrix, rect);
+        rtContext->drawRect(clip, grPaint, inMatrix, rect);
         iter.next();
     }
 
diff --git a/src/effects/SkBlurMaskFilter.cpp b/src/effects/SkBlurMaskFilter.cpp
index 0b1d1db..e8867ea 100644
--- a/src/effects/SkBlurMaskFilter.cpp
+++ b/src/effects/SkBlurMaskFilter.cpp
@@ -1060,8 +1060,7 @@
         return false;
     }
 
-    renderTargetContext->fillRectWithLocalMatrix(clip, *grp, GrAA::kNo, SkMatrix::I(), rect,
-                                                 inverse);
+    renderTargetContext->fillRectWithLocalMatrix(clip, *grp, SkMatrix::I(), rect, inverse);
     return true;
 }
 
@@ -1104,7 +1103,8 @@
 static sk_sp<GrTexture> find_or_create_rrect_blur_mask(GrContext* context,
                                                        const SkRRect& rrectToDraw,
                                                        const SkISize& size,
-                                                       float xformedSigma) {
+                                                       float xformedSigma,
+                                                       bool doAA) {
     static const GrUniqueKey::Domain kDomain = GrUniqueKey::GenerateDomain();
     GrUniqueKey key;
     GrUniqueKey::Builder builder(&key, kDomain, 9);
@@ -1129,10 +1129,10 @@
         }
 
         GrPaint grPaint;
+        grPaint.setAntiAlias(doAA);
 
         rtc->clear(nullptr, 0x0, true);
-        rtc->drawRRect(GrNoClip(), grPaint, GrAA::kYes, SkMatrix::I(), rrectToDraw,
-                       GrStyle::SimpleFill());
+        rtc->drawRRect(GrNoClip(), grPaint, SkMatrix::I(), rrectToDraw, GrStyle::SimpleFill());
 
         sk_sp<GrTexture> srcTexture(rtc->asTexture());
         if (!srcTexture) {
@@ -1192,7 +1192,8 @@
         return nullptr;
     }
 
-    sk_sp<GrTexture> mask(find_or_create_rrect_blur_mask(context, rrectToDraw, size, xformedSigma));
+    sk_sp<GrTexture> mask(find_or_create_rrect_blur_mask(context, rrectToDraw, size,
+                                                         xformedSigma, true));
     if (!mask) {
         return nullptr;
     }
@@ -1379,11 +1380,12 @@
 
         GrPaint newPaint(*grp);
         newPaint.addCoverageFragmentProcessor(std::move(fp));
+        newPaint.setAntiAlias(false);
 
         SkRect srcProxyRect = srcRRect.rect();
         srcProxyRect.outset(3.0f*fSigma, 3.0f*fSigma);
 
-        renderTargetContext->drawRect(clip, newPaint, GrAA::kNo, viewMatrix, srcProxyRect);
+        renderTargetContext->drawRect(clip, newPaint, viewMatrix, srcProxyRect);
         return true;
     }
 
@@ -1395,6 +1397,7 @@
 
     GrPaint newPaint(*grp);
     newPaint.addCoverageFragmentProcessor(std::move(fp));
+    newPaint.setAntiAlias(false);
 
     if (!this->ignoreXform()) {
         SkRect srcProxyRect = srcRRect.rect();
@@ -1441,8 +1444,8 @@
         proxyRect.outset(extra, extra);
 
 
-        renderTargetContext->fillRectWithLocalMatrix(clip, newPaint, GrAA::kNo, SkMatrix::I(),
-                                                     proxyRect, inverse);
+        renderTargetContext->fillRectWithLocalMatrix(clip, newPaint, SkMatrix::I(), proxyRect,
+                                                     inverse);
     }
 
     return true;
@@ -1535,8 +1538,7 @@
             paint.setCoverageSetOpXPFactory(SkRegion::kReplace_Op);
         }
 
-        renderTargetContext->drawRect(GrNoClip(), paint, GrAA::kNo, SkMatrix::I(),
-                                      SkRect::Make(clipRect));
+        renderTargetContext->drawRect(GrNoClip(), paint, SkMatrix::I(), SkRect::Make(clipRect));
     }
 
     *result = renderTargetContext->asTexture().release();
diff --git a/src/effects/SkDisplacementMapEffect.cpp b/src/effects/SkDisplacementMapEffect.cpp
index 661dacd..2d79f9a 100644
--- a/src/effects/SkDisplacementMapEffect.cpp
+++ b/src/effects/SkDisplacementMapEffect.cpp
@@ -360,8 +360,7 @@
         }
         paint.setGammaCorrect(renderTargetContext->isGammaCorrect());
 
-        renderTargetContext->drawRect(GrNoClip(), paint, GrAA::kNo, matrix,
-                                      SkRect::Make(colorBounds));
+        renderTargetContext->drawRect(GrNoClip(), paint, matrix, SkRect::Make(colorBounds));
 
         offset->fX = bounds.left();
         offset->fY = bounds.top();
diff --git a/src/effects/SkLightingImageFilter.cpp b/src/effects/SkLightingImageFilter.cpp
index 52c8947..75947e8 100644
--- a/src/effects/SkLightingImageFilter.cpp
+++ b/src/effects/SkLightingImageFilter.cpp
@@ -400,7 +400,7 @@
                                                               boundaryMode));
     paint.addColorFragmentProcessor(std::move(fp));
     paint.setPorterDuffXPFactory(SkBlendMode::kSrc);
-    renderTargetContext->fillRectToRect(clip, paint, GrAA::kNo, SkMatrix::I(), dstRect, srcRect);
+    renderTargetContext->fillRectToRect(clip, paint, SkMatrix::I(), dstRect, srcRect);
 }
 
 sk_sp<SkSpecialImage> SkLightingImageFilterInternal::filterImageGPU(
diff --git a/src/effects/SkMorphologyImageFilter.cpp b/src/effects/SkMorphologyImageFilter.cpp
index 130f099..2fa67a4 100644
--- a/src/effects/SkMorphologyImageFilter.cpp
+++ b/src/effects/SkMorphologyImageFilter.cpp
@@ -407,8 +407,7 @@
     paint.addColorFragmentProcessor(GrMorphologyEffect::Make(tex, direction, radius, morphType,
                                                              bounds));
     paint.setPorterDuffXPFactory(SkBlendMode::kSrc);
-    renderTargetContext->fillRectToRect(clip, paint, GrAA::kNo,
-                                        SkMatrix::I(), SkRect::Make(dstRect),
+    renderTargetContext->fillRectToRect(clip, paint, SkMatrix::I(), SkRect::Make(dstRect),
                                         SkRect::Make(srcRect));
 }
 
@@ -429,8 +428,8 @@
     }
     paint.addColorFragmentProcessor(GrMorphologyEffect::Make(tex, direction, radius, morphType));
     paint.setPorterDuffXPFactory(SkBlendMode::kSrc);
-    renderTargetContext->fillRectToRect(clip, paint, GrAA::kNo, SkMatrix::I(),
-                                        SkRect::Make(dstRect), SkRect::Make(srcRect));
+    renderTargetContext->fillRectToRect(clip, paint, SkMatrix::I(), SkRect::Make(dstRect),
+                                        SkRect::Make(srcRect));
 }
 
 static void apply_morphology_pass(GrTextureProvider* provider,
diff --git a/src/effects/SkShadowMaskFilter.cpp b/src/effects/SkShadowMaskFilter.cpp
index 5c54072..958ab17 100755
--- a/src/effects/SkShadowMaskFilter.cpp
+++ b/src/effects/SkShadowMaskFilter.cpp
@@ -252,6 +252,7 @@
         const SkScalar devSpaceAmbientRadius = srcSpaceAmbientRadius * scaleFactor;
 
         GrPaint newPaint(*grp);
+        newPaint.setAntiAlias(true);
         GrColor4f color = newPaint.getColor4f();
         color.fRGBA[3] *= fAmbientAlpha;
         newPaint.setColor4f(color);
@@ -310,6 +311,7 @@
                               (spotShadowRRect.width() + srcSpaceSpotRadius);
 
         GrPaint newPaint(*grp);
+        newPaint.setAntiAlias(true);
         GrColor4f color = newPaint.getColor4f();
         color.fRGBA[3] *= fSpotAlpha;
         newPaint.setColor4f(color);
diff --git a/src/effects/SkXfermodeImageFilter.cpp b/src/effects/SkXfermodeImageFilter.cpp
index d7a0b5d..0987266 100644
--- a/src/effects/SkXfermodeImageFilter.cpp
+++ b/src/effects/SkXfermodeImageFilter.cpp
@@ -303,7 +303,7 @@
 
     SkMatrix matrix;
     matrix.setTranslate(SkIntToScalar(-bounds.left()), SkIntToScalar(-bounds.top()));
-    renderTargetContext->drawRect(GrNoClip(), paint, GrAA::kNo, matrix, SkRect::Make(bounds));
+    renderTargetContext->drawRect(GrNoClip(), paint, matrix, SkRect::Make(bounds));
 
     return SkSpecialImage::MakeDeferredFromGpu(context,
                                                SkIRect::MakeWH(bounds.width(), bounds.height()),
diff --git a/src/gpu/GrBlurUtils.cpp b/src/gpu/GrBlurUtils.cpp
index 04a0022..8f14bf7 100644
--- a/src/gpu/GrBlurUtils.cpp
+++ b/src/gpu/GrBlurUtils.cpp
@@ -44,8 +44,8 @@
     if (!viewMatrix.invert(&inverse)) {
         return false;
     }
-    renderTargetContext->fillRectWithLocalMatrix(clip, *grp, GrAA::kNo, SkMatrix::I(),
-                                                 SkRect::Make(maskRect), inverse);
+    renderTargetContext->fillRectWithLocalMatrix(clip, *grp, SkMatrix::I(), SkRect::Make(maskRect),
+                                                 inverse);
     return true;
 }
 
@@ -97,9 +97,9 @@
                                              const SkIRect& maskRect,
                                              const SkPath& devPath,
                                              SkStrokeRec::InitStyle fillOrHairline,
-                                             GrAA aa,
+                                             bool doAA,
                                              int sampleCnt) {
-    if (GrAA::kNo == aa) {
+    if (!doAA) {
         // Don't need MSAA if mask isn't AA
         sampleCnt = 0;
     }
@@ -114,6 +114,7 @@
     rtContext->clear(nullptr, 0x0, true);
 
     GrPaint tempPaint;
+    tempPaint.setAntiAlias(doAA);
     tempPaint.setCoverageSetOpXPFactory(SkRegion::kReplace_Op);
 
     // setup new clip
@@ -124,7 +125,7 @@
     // the origin using tempPaint.
     SkMatrix translate;
     translate.setTranslate(-SkIntToScalar(maskRect.fLeft), -SkIntToScalar(maskRect.fTop));
-    rtContext->drawPath(clip, tempPaint, aa, translate, devPath, GrStyle(fillOrHairline));
+    rtContext->drawPath(clip, tempPaint, translate, devPath, GrStyle(fillOrHairline));
     return sk_ref_sp(rtContext->asDeferredTexture());
 }
 
@@ -132,7 +133,6 @@
                                        GrRenderTargetContext* renderTargetContext,
                                        const GrClip& clip,
                                        GrPaint* paint,
-                                       GrAA aa,
                                        const SkMatrix& viewMatrix,
                                        const SkMaskFilter* maskFilter,
                                        const GrStyle& style,
@@ -210,7 +210,7 @@
                                                         finalIRect,
                                                         *path,
                                                         fillOrHairline,
-                                                        aa,
+                                                        paint->isAntiAlias(),
                                                         renderTargetContext->numColorSamples()));
         if (maskProxy) {
             GrTexture* filtered;
@@ -241,12 +241,11 @@
                                          const GrClip& clip,
                                          const SkPath& path,
                                          GrPaint* paint,
-                                         GrAA aa,
                                          const SkMatrix& viewMatrix,
                                          const SkMaskFilter* mf,
                                          const GrStyle& style,
                                          bool pathIsMutable) {
-    draw_path_with_mask_filter(context, renderTargetContext, clip, paint, aa, viewMatrix, mf,
+    draw_path_with_mask_filter(context, renderTargetContext, clip, paint, viewMatrix, mf,
                                style, &path, pathIsMutable);
 }
 
@@ -290,14 +289,14 @@
     if (!SkPaintToGrPaint(context, renderTargetContext, paint, viewMatrix, &grPaint)) {
         return;
     }
-    GrAA aa = GrBoolToAA(paint.isAntiAlias());
+
     SkMaskFilter* mf = paint.getMaskFilter();
     if (mf && !mf->asFragmentProcessor(nullptr, nullptr, viewMatrix)) {
         // The MaskFilter wasn't already handled in SkPaintToGrPaint
-        draw_path_with_mask_filter(context, renderTargetContext, clip, &grPaint, aa, viewMatrix,
+        draw_path_with_mask_filter(context, renderTargetContext, clip, &grPaint, viewMatrix,
                                    mf, style,
                                    path, pathIsMutable);
     } else {
-        renderTargetContext->drawPath(clip, grPaint, aa, viewMatrix, *path, style);
+        renderTargetContext->drawPath(clip, grPaint, viewMatrix, *path, style);
     }
 }
diff --git a/src/gpu/GrBlurUtils.h b/src/gpu/GrBlurUtils.h
index be0d2fb..090448f 100644
--- a/src/gpu/GrBlurUtils.h
+++ b/src/gpu/GrBlurUtils.h
@@ -8,13 +8,11 @@
 #ifndef GrBlurUtils_DEFINED
 #define GrBlurUtils_DEFINED
 
-#include "GrTypes.h"
-
 class GrClip;
 class GrContext;
+class GrRenderTargetContext;
 class GrPaint;
 class GrRenderTarget;
-class GrRenderTargetContext;
 class GrStyle;
 struct SkIRect;
 class SkMaskFilter;
@@ -50,7 +48,6 @@
                                 const GrClip&,
                                 const SkPath& path,
                                 GrPaint*,
-                                GrAA,
                                 const SkMatrix& viewMatrix,
                                 const SkMaskFilter*,
                                 const GrStyle&,
diff --git a/src/gpu/GrClipStackClip.cpp b/src/gpu/GrClipStackClip.cpp
index 01cfdbf..548f5b7 100644
--- a/src/gpu/GrClipStackClip.cpp
+++ b/src/gpu/GrClipStackClip.cpp
@@ -42,7 +42,7 @@
                                                   SkIntToScalar(fOrigin.fY)));
 }
 
-bool GrClipStackClip::isRRect(const SkRect& origRTBounds, SkRRect* rr, GrAA* aa) const {
+bool GrClipStackClip::isRRect(const SkRect& origRTBounds, SkRRect* rr, bool* aa) const {
     if (!fStack) {
         return false;
     }
@@ -54,9 +54,7 @@
         tempRTBounds.offset(SkIntToScalar(fOrigin.fX), SkIntToScalar(fOrigin.fY));
         rtBounds = &tempRTBounds;
     }
-    bool isAA;
-    if (fStack->isRRect(*rtBounds, rr, &isAA)) {
-        *aa = GrBoolToAA(isAA);
+    if (fStack->isRRect(*rtBounds, rr, aa)) {
         if (origin) {
             rr->offset(-SkIntToScalar(fOrigin.fX), -SkIntToScalar(fOrigin.fY));
         }
@@ -134,14 +132,9 @@
         canDrawArgs.fShaderCaps = context->caps()->shaderCaps();
         canDrawArgs.fViewMatrix = &viewMatrix;
         canDrawArgs.fShape = &shape;
-        if (!element->isAA()) {
-            canDrawArgs.fAAType = GrAAType::kNone;
-        } else if (renderTargetContext->isStencilBufferMultisampled()){
-            canDrawArgs.fAAType = GrAAType::kHW;
-        } else {
-            canDrawArgs.fAAType = GrAAType::kCoverage;
-        }
+        canDrawArgs.fAntiAlias = element->isAA();
         canDrawArgs.fHasUserStencilSettings = hasUserStencilSettings;
+        canDrawArgs.fIsStencilBufferMSAA = renderTargetContext->isStencilBufferMultisampled();
 
         // the 'false' parameter disallows use of the SW path renderer
         GrPathRenderer* pr =
@@ -457,7 +450,6 @@
     for (ElementList::Iter iter(reducedClip.elements()); iter.get(); iter.next()) {
         const Element* element = iter.get();
         SkCanvas::ClipOp op = element->getOp();
-        GrAA aa = GrBoolToAA(element->isAA());
 
         if (SkCanvas::kIntersect_Op == op || SkCanvas::kReverseDifference_Op == op) {
             // Intersect and reverse difference require modifying pixels outside of the geometry
@@ -467,25 +459,25 @@
             if (SkCanvas::kReverseDifference_Op == op) {
                 SkRect temp = SkRect::Make(reducedClip.ibounds());
                 // invert the entire scene
-                helper.drawRect(temp, SkRegion::kXOR_Op, GrAA::kNo, 0xFF);
+                helper.drawRect(temp, SkRegion::kXOR_Op, false, 0xFF);
             }
             SkPath clipPath;
             element->asPath(&clipPath);
             clipPath.toggleInverseFillType();
             GrShape shape(clipPath, GrStyle::SimpleFill());
-            helper.drawShape(shape, SkRegion::kReplace_Op, aa, 0x00);
+            helper.drawShape(shape, SkRegion::kReplace_Op, element->isAA(), 0x00);
             continue;
         }
 
         // The other ops (union, xor, diff) only affect pixels inside
         // the geometry so they can just be drawn normally
         if (Element::kRect_Type == element->getType()) {
-            helper.drawRect(element->getRect(), (SkRegion::Op)op, aa, 0xFF);
+            helper.drawRect(element->getRect(), (SkRegion::Op)op, element->isAA(), 0xFF);
         } else {
             SkPath path;
             element->asPath(&path);
             GrShape shape(path, GrStyle::SimpleFill());
-            helper.drawShape(shape, (SkRegion::Op)op, aa, 0xFF);
+            helper.drawShape(shape, (SkRegion::Op)op, element->isAA(), 0xFF);
         }
     }
 
diff --git a/src/gpu/GrClipStackClip.h b/src/gpu/GrClipStackClip.h
index 42bd373..afda3eb 100644
--- a/src/gpu/GrClipStackClip.h
+++ b/src/gpu/GrClipStackClip.h
@@ -38,7 +38,7 @@
     bool apply(GrContext*, GrRenderTargetContext*, bool useHWAA, bool hasUserStencilSettings,
                GrAppliedClip* out) const final;
 
-    bool isRRect(const SkRect& rtBounds, SkRRect* rr, GrAA* aa) const override;
+    bool isRRect(const SkRect& rtBounds, SkRRect* rr, bool* aa) const override;
 
 private:
     static bool PathNeedsSWRenderer(GrContext* context,
diff --git a/src/gpu/GrContext.cpp b/src/gpu/GrContext.cpp
index ff5b026..34b9abf 100644
--- a/src/gpu/GrContext.cpp
+++ b/src/gpu/GrContext.cpp
@@ -366,7 +366,7 @@
             paint.setPorterDuffXPFactory(SkBlendMode::kSrc);
             paint.setAllowSRGBInputs(true);
             SkRect rect = SkRect::MakeWH(SkIntToScalar(width), SkIntToScalar(height));
-            renderTargetContext->drawRect(GrNoClip(), paint, GrAA::kNo, matrix, rect, nullptr);
+            renderTargetContext->drawRect(GrNoClip(), paint, matrix, rect, nullptr);
 
             if (kFlushWrites_PixelOp & pixelOpsFlags) {
                 this->flushSurfaceWrites(surface);
@@ -486,7 +486,7 @@
                 paint.setPorterDuffXPFactory(SkBlendMode::kSrc);
                 paint.setAllowSRGBInputs(true);
                 SkRect rect = SkRect::MakeWH(SkIntToScalar(width), SkIntToScalar(height));
-                tempRTC->drawRect(GrNoClip(), paint, GrAA::kNo, SkMatrix::I(), rect, nullptr);
+                tempRTC->drawRect(GrNoClip(), paint, SkMatrix::I(), rect, nullptr);
                 surfaceToRead.reset(tempRTC->asTexture().release());
                 left = 0;
                 top = 0;
diff --git a/src/gpu/GrFixedClip.cpp b/src/gpu/GrFixedClip.cpp
index f664a54..9e87588 100644
--- a/src/gpu/GrFixedClip.cpp
+++ b/src/gpu/GrFixedClip.cpp
@@ -29,7 +29,7 @@
     }
 }
 
-bool GrFixedClip::isRRect(const SkRect& rtBounds, SkRRect* rr, GrAA* aa) const {
+bool GrFixedClip::isRRect(const SkRect& rtBounds, SkRRect* rr, bool* aa) const {
     if (fWindowRectsState.enabled()) {
         return false;
     }
@@ -39,7 +39,7 @@
             return false;
         }
         rr->setRect(rect);
-        *aa = GrAA::kNo;
+        *aa = false;
         return true;
     }
     return false;
diff --git a/src/gpu/GrFixedClip.h b/src/gpu/GrFixedClip.h
index 7f18c26..6c350d5 100644
--- a/src/gpu/GrFixedClip.h
+++ b/src/gpu/GrFixedClip.h
@@ -42,7 +42,7 @@
 
     bool quickContains(const SkRect&) const override;
     void getConservativeBounds(int w, int h, SkIRect* devResult, bool* iior) const override;
-    bool isRRect(const SkRect& rtBounds, SkRRect* rr, GrAA*) const override;
+    bool isRRect(const SkRect& rtBounds, SkRRect* rr, bool* aa) const override;
     bool apply(GrContext*, GrRenderTargetContext*, bool, bool, GrAppliedClip* out) const override;
 
     static const GrFixedClip& Disabled();
diff --git a/src/gpu/GrPaint.cpp b/src/gpu/GrPaint.cpp
index 0954505..d5f8d3d 100644
--- a/src/gpu/GrPaint.cpp
+++ b/src/gpu/GrPaint.cpp
@@ -13,7 +13,8 @@
 #include "effects/GrSimpleTextureEffect.h"
 
 GrPaint::GrPaint()
-    : fDisableOutputConversionToSRGB(false)
+    : fAntiAlias(false)
+    , fDisableOutputConversionToSRGB(false)
     , fAllowSRGBInputs(false)
     , fUsesDistanceVectorField(false)
     , fColor(GrColor4f::OpaqueWhite()) {}
diff --git a/src/gpu/GrPathRenderer.h b/src/gpu/GrPathRenderer.h
index 4e1a966..2b5ccdc 100644
--- a/src/gpu/GrPathRenderer.h
+++ b/src/gpu/GrPathRenderer.h
@@ -78,16 +78,17 @@
      * fPipelineBuilder  The pipelineBuilder
      * fViewMatrix       The viewMatrix
      * fShape            The shape to draw
-     * fAntiAlias        The type of anti aliasing required.
+     * fAntiAlias        True if anti-aliasing is required.
      */
     struct CanDrawPathArgs {
         const GrShaderCaps*         fShaderCaps;
         const SkMatrix*             fViewMatrix;
         const GrShape*              fShape;
-        GrAAType                    fAAType;
+        bool                        fAntiAlias;
 
         // These next two are only used by GrStencilAndCoverPathRenderer
         bool                        fHasUserStencilSettings;
+        bool                        fIsStencilBufferMSAA;
 
 #ifdef SK_DEBUG
         void validate() const {
@@ -120,7 +121,7 @@
      * fColor                 Color to render with
      * fViewMatrix            The viewMatrix
      * fShape                 The shape to draw
-     * fAAtype                true if anti-aliasing is required.
+     * fAntiAlias             true if anti-aliasing is required.
      * fGammaCorrect          true if gamma-correct rendering is to be used.
      */
     struct DrawPathArgs {
@@ -132,7 +133,7 @@
         const GrClip*               fClip;
         const SkMatrix*             fViewMatrix;
         const GrShape*              fShape;
-        GrAAType                    fAAType;
+        bool                        fAntiAlias;
         bool                        fGammaCorrect;
 #ifdef SK_DEBUG
         void validate() const {
@@ -158,13 +159,10 @@
         canArgs.fShaderCaps = args.fResourceProvider->caps()->shaderCaps();
         canArgs.fViewMatrix = args.fViewMatrix;
         canArgs.fShape = args.fShape;
-        canArgs.fAAType = args.fAAType;
+        canArgs.fAntiAlias = args.fAntiAlias;
 
         canArgs.fHasUserStencilSettings = !args.fUserStencilSettings->isUnused();
-        SkASSERT(!(canArgs.fAAType == GrAAType::kHW &&
-                   !args.fRenderTargetContext->isStencilBufferMultisampled()));
-        SkASSERT(!(canArgs.fAAType == GrAAType::kCoverage &&
-                   args.fRenderTargetContext->isStencilBufferMultisampled()));
+        canArgs.fIsStencilBufferMSAA = args.fRenderTargetContext->isStencilBufferMultisampled();
         SkASSERT(this->canDrawPath(canArgs));
         if (!args.fUserStencilSettings->isUnused()) {
             SkPath path;
@@ -182,14 +180,14 @@
      * fRenderTargetContext   The target of the draws
      * fViewMatrix            Matrix applied to the path.
      * fPath                  The path to draw.
-     * fAAType                The type of AA, cannot be kCoverage.
+     * fIsAA                  Is the path to be drawn AA (only set when MSAA is available)
      */
     struct StencilPathArgs {
         GrResourceProvider*    fResourceProvider;
         GrRenderTargetContext* fRenderTargetContext;
         const GrClip*          fClip;
         const SkMatrix*        fViewMatrix;
-        GrAAType               fAAType;
+        bool                   fIsAA;
         const GrShape*         fShape;
 
 #ifdef SK_DEBUG
@@ -199,7 +197,6 @@
             SkASSERT(fViewMatrix);
             SkASSERT(fShape);
             SkASSERT(fShape->style().isSimpleFill());
-            SkASSERT(GrAAType::kCoverage != fAAType);
             SkPath path;
             fShape->asPath(&path);
             SkASSERT(!path.isInverseFillType());
@@ -286,7 +283,7 @@
         drawArgs.fRenderTargetContext = args.fRenderTargetContext;
         drawArgs.fViewMatrix = args.fViewMatrix;
         drawArgs.fShape = args.fShape;
-        drawArgs.fAAType = args.fAAType;
+        drawArgs.fAntiAlias = false;  // In this case the MSAA handles the AA so we want to draw BW
         drawArgs.fGammaCorrect = false;
         this->drawPath(drawArgs);
     }
diff --git a/src/gpu/GrPipelineBuilder.cpp b/src/gpu/GrPipelineBuilder.cpp
index 8315c01..fac5752 100644
--- a/src/gpu/GrPipelineBuilder.cpp
+++ b/src/gpu/GrPipelineBuilder.cpp
@@ -15,10 +15,15 @@
 #include "batches/GrOp.h"
 #include "effects/GrPorterDuffXferProcessor.h"
 
-GrPipelineBuilder::GrPipelineBuilder(const GrPaint& paint, GrAAType aaType)
-        : fFlags(0x0)
-        , fUserStencilSettings(&GrUserStencilSettings::kUnused)
-        , fDrawFace(GrDrawFace::kBoth) {
+GrPipelineBuilder::GrPipelineBuilder()
+    : fFlags(0x0)
+    , fUserStencilSettings(&GrUserStencilSettings::kUnused)
+    , fDrawFace(GrDrawFace::kBoth) {
+    SkDEBUGCODE(fBlockEffectRemovalCnt = 0;)
+}
+
+GrPipelineBuilder::GrPipelineBuilder(const GrPaint& paint, bool useHWAA)
+    : GrPipelineBuilder() {
     SkDEBUGCODE(fBlockEffectRemovalCnt = 0;)
 
     for (int i = 0; i < paint.numColorFragmentProcessors(); ++i) {
@@ -31,7 +36,7 @@
 
     fXPFactory.reset(SkSafeRef(paint.getXPFactory()));
 
-    this->setState(GrPipelineBuilder::kHWAntialias_Flag, GrAAType::kHW == aaType);
+    this->setState(GrPipelineBuilder::kHWAntialias_Flag, useHWAA);
     this->setState(GrPipelineBuilder::kDisableOutputConversionToSRGB_Flag,
                    paint.getDisableOutputConversionToSRGB());
     this->setState(GrPipelineBuilder::kAllowSRGBInputs_Flag,
diff --git a/src/gpu/GrPipelineBuilder.h b/src/gpu/GrPipelineBuilder.h
index 69aa454..fcff2ad 100644
--- a/src/gpu/GrPipelineBuilder.h
+++ b/src/gpu/GrPipelineBuilder.h
@@ -29,14 +29,15 @@
 
 class GrPipelineBuilder : public SkNoncopyable {
 public:
-//    GrPipelineBuilder();
+    GrPipelineBuilder();
+
     /**
      * Initializes the GrPipelineBuilder based on a GrPaint and MSAA availability. Note
      * that GrPipelineBuilder encompasses more than GrPaint. Aspects of GrPipelineBuilder that have
      * no GrPaint equivalents are set to default values with the exception of vertex attribute state
      * which is unmodified by this function and clipping which will be enabled.
      */
-    GrPipelineBuilder(const GrPaint& paint, GrAAType aaType);
+    GrPipelineBuilder(const GrPaint&, bool useHWAA = false);
 
     virtual ~GrPipelineBuilder();
 
diff --git a/src/gpu/GrReducedClip.cpp b/src/gpu/GrReducedClip.cpp
index 0c15a96..a82048b 100644
--- a/src/gpu/GrReducedClip.cpp
+++ b/src/gpu/GrReducedClip.cpp
@@ -529,7 +529,8 @@
                             const GrUserStencilSettings* ss,
                             const SkMatrix& viewMatrix,
                             const SkClipStack::Element* element) {
-    GrAA aa = GrBoolToAA(element->isAA());
+
+    // TODO: Draw rrects directly here.
     switch (element->getType()) {
         case Element::kEmpty_Type:
             SkDEBUGFAIL("Should never get here with an empty element.");
@@ -537,7 +538,9 @@
         case Element::kRect_Type:
             return rtc->priv().drawAndStencilRect(clip, ss,
                                                   (SkRegion::Op)element->getOp(),
-                                                  element->isInverseFilled(), aa, viewMatrix,
+                                                  element->isInverseFilled(),
+                                                  element->isAA(),
+                                                  viewMatrix,
                                                   element->getRect());
             break;
         default: {
@@ -547,8 +550,11 @@
                 path.toggleInverseFillType();
             }
 
-            return rtc->priv().drawAndStencilPath(clip, ss, (SkRegion::Op)element->getOp(),
-                                                  element->isInverseFilled(), aa, viewMatrix, path);
+            return rtc->priv().drawAndStencilPath(clip, ss,
+                                                  (SkRegion::Op)element->getOp(),
+                                                  element->isInverseFilled(),
+                                                  element->isAA(), viewMatrix,
+                                                  path);
             break;
         }
     }
@@ -559,7 +565,6 @@
 static void draw_element(GrRenderTargetContext* rtc,
                          const GrClip& clip, // TODO: can this just always be WideOpen?
                          const GrPaint &paint,
-                         GrAA aa,
                          const SkMatrix& viewMatrix,
                          const SkClipStack::Element* element) {
 
@@ -569,7 +574,7 @@
             SkDEBUGFAIL("Should never get here with an empty element.");
             break;
         case Element::kRect_Type:
-            rtc->drawRect(clip, paint, aa, viewMatrix, element->getRect());
+            rtc->drawRect(clip, paint, viewMatrix, element->getRect());
             break;
         default: {
             SkPath path;
@@ -578,7 +583,7 @@
                 path.toggleInverseFillType();
             }
 
-            rtc->drawPath(clip, paint, aa, viewMatrix, path, GrStyle::SimpleFill());
+            rtc->drawPath(clip, paint, viewMatrix, path, GrStyle::SimpleFill());
             break;
         }
     }
@@ -607,7 +612,6 @@
     for (ElementList::Iter iter(fElements); iter.get(); iter.next()) {
         const Element* element = iter.get();
         SkRegion::Op op = (SkRegion::Op)element->getOp();
-        GrAA aa = GrBoolToAA(element->isAA());
         bool invert = element->isInverseFilled();
         if (invert || SkRegion::kIntersect_Op == op || SkRegion::kReverseDifference_Op == op) {
             // draw directly into the result with the stencil set to make the pixels affected
@@ -635,16 +639,17 @@
                      GrUserStencilOp::kZero,
                      0xffff>()
             );
-            if (!rtc->priv().drawAndStencilRect(clip, &kDrawOutsideElement, op, !invert, GrAA::kNo,
+            if (!rtc->priv().drawAndStencilRect(clip, &kDrawOutsideElement, op, !invert, false,
                                                 translate, SkRect::Make(fIBounds))) {
                 return false;
             }
         } else {
             // all the remaining ops can just be directly draw into the accumulation buffer
             GrPaint paint;
+            paint.setAntiAlias(element->isAA());
             paint.setCoverageSetOpXPFactory(op, false);
 
-            draw_element(rtc, clip, paint, aa, translate, element);
+            draw_element(rtc, clip, paint, translate, element);
         }
     }
 
@@ -671,7 +676,7 @@
     void getConservativeBounds(int width, int height, SkIRect* bounds, bool* iior) const override {
         fFixedClip.getConservativeBounds(width, height, bounds, iior);
     }
-    bool isRRect(const SkRect& rtBounds, SkRRect* rr, GrAA*) const override {
+    bool isRRect(const SkRect& rtBounds, SkRRect* rr, bool* aa) const override {
         return false;
     }
     bool apply(GrContext* context, GrRenderTargetContext* renderTargetContext, bool useHWAA,
@@ -706,13 +711,11 @@
     SkMatrix viewMatrix;
     viewMatrix.setTranslate(SkIntToScalar(-clipOrigin.x()), SkIntToScalar(-clipOrigin.y()));
 
-    // walk through each clip element and perform its set op with the existing clip.
+    // walk through each clip element and perform its set op
+    // with the existing clip.
     for (ElementList::Iter iter(fElements); iter.get(); iter.next()) {
         const Element* element = iter.get();
-        GrAAType aaType = GrAAType::kNone;
-        if (element->isAA() && renderTargetContext->isStencilBufferMultisampled()) {
-            aaType = GrAAType::kHW;
-        }
+        bool useHWAA = element->isAA() && renderTargetContext->isStencilBufferMultisampled();
 
         bool fillInverted = false;
 
@@ -739,8 +742,9 @@
             canDrawArgs.fShaderCaps = context->caps()->shaderCaps();
             canDrawArgs.fViewMatrix = &viewMatrix;
             canDrawArgs.fShape = &shape;
-            canDrawArgs.fAAType = aaType;
+            canDrawArgs.fAntiAlias = false;
             canDrawArgs.fHasUserStencilSettings = false;
+            canDrawArgs.fIsStencilBufferMSAA = renderTargetContext->isStencilBufferMultisampled();
 
             GrDrawingManager* dm = context->contextPriv().drawingManager();
             pr = dm->getPathRenderer(canDrawArgs, false,
@@ -774,13 +778,14 @@
             );
             if (Element::kRect_Type == element->getType()) {
                 renderTargetContext->priv().stencilRect(stencilClip.fixedClip(), &kDrawToStencil,
-                                                        aaType, viewMatrix, element->getRect());
+                                                        useHWAA, viewMatrix, element->getRect());
             } else {
                 if (!clipPath.isEmpty()) {
                     GrShape shape(clipPath, GrStyle::SimpleFill());
                     if (canRenderDirectToStencil) {
                         GrPaint paint;
                         paint.setXPFactory(GrDisableColorXPFactory::Make());
+                        paint.setAntiAlias(element->isAA());
 
                         GrPathRenderer::DrawPathArgs args;
                         args.fResourceProvider = context->resourceProvider();
@@ -790,7 +795,7 @@
                         args.fClip = &stencilClip.fixedClip();
                         args.fViewMatrix = &viewMatrix;
                         args.fShape = &shape;
-                        args.fAAType = aaType;
+                        args.fAntiAlias = false;
                         args.fGammaCorrect = false;
                         pr->drawPath(args);
                     } else {
@@ -799,7 +804,7 @@
                         args.fRenderTargetContext = renderTargetContext;
                         args.fClip = &stencilClip.fixedClip();
                         args.fViewMatrix = &viewMatrix;
-                        args.fAAType = aaType;
+                        args.fIsAA = element->isAA();
                         args.fShape = &shape;
                         pr->stencilPath(args);
                     }
@@ -812,12 +817,13 @@
         for (GrUserStencilSettings const* const* pass = stencilPasses; *pass; ++pass) {
             if (drawDirectToClip) {
                 if (Element::kRect_Type == element->getType()) {
-                    renderTargetContext->priv().stencilRect(stencilClip, *pass, aaType, viewMatrix,
+                    renderTargetContext->priv().stencilRect(stencilClip, *pass, useHWAA, viewMatrix,
                                                             element->getRect());
                 } else {
                     GrShape shape(clipPath, GrStyle::SimpleFill());
                     GrPaint paint;
                     paint.setXPFactory(GrDisableColorXPFactory::Make());
+                    paint.setAntiAlias(element->isAA());
                     GrPathRenderer::DrawPathArgs args;
                     args.fResourceProvider = context->resourceProvider();
                     args.fPaint = &paint;
@@ -826,14 +832,14 @@
                     args.fClip = &stencilClip;
                     args.fViewMatrix = &viewMatrix;
                     args.fShape = &shape;
-                    args.fAAType = aaType;
+                    args.fAntiAlias = false;
                     args.fGammaCorrect = false;
                     pr->drawPath(args);
                 }
             } else {
                 // The view matrix is setup to do clip space -> stencil space translation, so
                 // draw rect in clip space.
-                renderTargetContext->priv().stencilRect(stencilClip, *pass, aaType, viewMatrix,
+                renderTargetContext->priv().stencilRect(stencilClip, *pass, false, viewMatrix,
                                                         SkRect::Make(fIBounds));
             }
         }
diff --git a/src/gpu/GrRenderTargetContext.cpp b/src/gpu/GrRenderTargetContext.cpp
index d14e550..bc29a70 100644
--- a/src/gpu/GrRenderTargetContext.cpp
+++ b/src/gpu/GrRenderTargetContext.cpp
@@ -265,7 +265,7 @@
         paint.setColor4f(GrColor4f::FromGrColor(color));
         paint.setXPFactory(GrPorterDuffXPFactory::Make(SkBlendMode::kSrc));
 
-        this->drawRect(clip, paint, GrAA::kNo, SkMatrix::I(), SkRect::Make(clearRect));
+        this->drawRect(clip, paint, SkMatrix::I(), SkRect::Make(clearRect));
     } else if (isFull) {
         if (this->accessRenderTarget()) {
             this->getOpList()->fullClear(this->accessRenderTarget(), color);
@@ -283,7 +283,7 @@
 }
 
 void GrRenderTargetContext::drawPaint(const GrClip& clip,
-                                      const GrPaint& paint,
+                                      const GrPaint& origPaint,
                                       const SkMatrix& viewMatrix) {
     ASSERT_SINGLE_OWNER
     RETURN_IF_ABANDONED
@@ -294,19 +294,26 @@
     // don't overflow fixed-point implementations
 
     SkRect r = fRenderTargetProxy->getBoundsRect();
+    SkTCopyOnFirstWrite<GrPaint> paint(origPaint);
 
     SkRRect rrect;
-    GrAA aa;
+    bool aaRRect;
     // Check if we can replace a clipRRect()/drawPaint() with a drawRRect(). We only do the
     // transformation for non-rect rrects. Rects caused a performance regression on an Android
     // test that needs investigation. We also skip cases where there are fragment processors
     // because they may depend on having correct local coords and this path draws in device space
     // without a local matrix.
-    if (!paint.numTotalFragmentProcessors() && clip.isRRect(r, &rrect, &aa) && !rrect.isRect()) {
-        this->drawRRect(GrNoClip(), paint, aa, SkMatrix::I(), rrect, GrStyle::SimpleFill());
+    if (!paint->numTotalFragmentProcessors() &&
+        clip.isRRect(r, &rrect, &aaRRect) && !rrect.isRect()) {
+        paint.writable()->setAntiAlias(aaRRect);
+        this->drawRRect(GrNoClip(), *paint, SkMatrix::I(), rrect, GrStyle::SimpleFill());
         return;
     }
 
+    // by definition this fills the entire clip, no need for AA
+    if (paint->isAntiAlias()) {
+        paint.writable()->setAntiAlias(false);
+    }
 
     bool isPerspective = viewMatrix.hasPerspective();
 
@@ -318,7 +325,7 @@
             SkDebugf("Could not invert matrix\n");
             return;
         }
-        this->drawRect(clip, paint, GrAA::kNo, viewMatrix, r);
+        this->drawRect(clip, *paint, viewMatrix, r);
     } else {
         SkMatrix localMatrix;
         if (!viewMatrix.invert(&localMatrix)) {
@@ -328,8 +335,8 @@
 
         AutoCheckFlush acf(fDrawingManager);
 
-        this->drawNonAAFilledRect(clip, paint, SkMatrix::I(), r, nullptr, &localMatrix,
-                                  nullptr, GrAAType::kNone);
+        this->drawNonAAFilledRect(clip, *paint, SkMatrix::I(), r, nullptr, &localMatrix, nullptr,
+                                  false /* useHWAA */);
     }
 }
 
@@ -342,6 +349,21 @@
     return viewMatrix.preservesRightAngles();
 }
 
+static bool should_apply_coverage_aa(const GrPaint& paint, GrRenderTargetProxy* rtp,
+                                     bool* useHWAA = nullptr) {
+    if (!paint.isAntiAlias()) {
+        if (useHWAA) {
+            *useHWAA = false;
+        }
+        return false;
+    } else {
+        if (useHWAA) {
+            *useHWAA = rtp->isUnifiedMultisampled();
+        }
+        return !rtp->isUnifiedMultisampled();
+    }
+}
+
 // Attempts to crop a rect and optional local rect to the clip boundaries.
 // Returns false if the draw can be skipped entirely.
 static bool crop_filled_rect(int width, int height, const GrClip& clip,
@@ -389,7 +411,6 @@
 
 bool GrRenderTargetContext::drawFilledRect(const GrClip& clip,
                                            const GrPaint& paint,
-                                           GrAA aa,
                                            const SkMatrix& viewMatrix,
                                            const SkRect& rect,
                                            const GrUserStencilSettings* ss) {
@@ -400,14 +421,14 @@
     }
 
     sk_sp<GrDrawOp> op;
-    GrAAType aaType;
+    bool useHWAA;
 
     if (GrCaps::InstancedSupport::kNone != fContext->caps()->instancedSupport()) {
         InstancedRendering* ir = this->getOpList()->instancedRendering();
-        op.reset(ir->recordRect(croppedRect, viewMatrix, paint.getColor(), aa,
-                                fInstancedPipelineInfo, &aaType));
+        op.reset(ir->recordRect(croppedRect, viewMatrix, paint.getColor(), paint.isAntiAlias(),
+                                fInstancedPipelineInfo, &useHWAA));
         if (op) {
-            GrPipelineBuilder pipelineBuilder(paint, aaType);
+            GrPipelineBuilder pipelineBuilder(paint, useHWAA);
             if (ss) {
                 pipelineBuilder.setUserStencil(ss);
             }
@@ -415,8 +436,8 @@
             return true;
         }
     }
-    aaType = this->decideAAType(aa);
-    if (GrAAType::kCoverage == aaType) {
+
+    if (should_apply_coverage_aa(paint, fRenderTargetProxy.get(), &useHWAA)) {
         // The fill path can handle rotation but not skew.
         if (view_matrix_ok_for_aa_fill_rect(viewMatrix)) {
             SkRect devBoundRect;
@@ -425,7 +446,7 @@
             op.reset(GrRectBatchFactory::CreateAAFill(paint, viewMatrix, rect, croppedRect,
                                                       devBoundRect));
             if (op) {
-                GrPipelineBuilder pipelineBuilder(paint, aaType);
+                GrPipelineBuilder pipelineBuilder(paint, useHWAA);
                 if (ss) {
                     pipelineBuilder.setUserStencil(ss);
                 }
@@ -435,7 +456,7 @@
         }
     } else {
         this->drawNonAAFilledRect(clip, paint, viewMatrix, croppedRect, nullptr, nullptr, ss,
-                                  aaType);
+                                  useHWAA);
         return true;
     }
 
@@ -444,7 +465,6 @@
 
 void GrRenderTargetContext::drawRect(const GrClip& clip,
                                      const GrPaint& paint,
-                                     GrAA aa,
                                      const SkMatrix& viewMatrix,
                                      const SkRect& rect,
                                      const GrStyle* style) {
@@ -491,7 +511,7 @@
             }
         }
 
-        if (this->drawFilledRect(clip, paint, aa, viewMatrix, rect, nullptr)) {
+        if (this->drawFilledRect(clip, paint, viewMatrix, rect, nullptr)) {
             return;
         }
     } else if (stroke.getStyle() == SkStrokeRec::kStroke_Style ||
@@ -502,7 +522,7 @@
             // TODO: Move these stroke->fill fallbacks to GrShape?
             switch (stroke.getJoin()) {
                 case SkPaint::kMiter_Join:
-                    this->drawRect(clip, paint, aa, viewMatrix,
+                    this->drawRect(clip, paint, viewMatrix,
                                    {rect.fLeft - r, rect.fTop - r,
                                     rect.fRight + r, rect.fBottom + r},
                                    &GrStyle::SimpleFill());
@@ -511,16 +531,16 @@
                     // Raster draws nothing when both dimensions are empty.
                     if (rect.width() || rect.height()){
                         SkRRect rrect = SkRRect::MakeRectXY(rect.makeOutset(r, r), r, r);
-                        this->drawRRect(clip, paint, aa, viewMatrix, rrect, GrStyle::SimpleFill());
+                        this->drawRRect(clip, paint, viewMatrix, rrect, GrStyle::SimpleFill());
                         return;
                     }
                 case SkPaint::kBevel_Join:
                     if (!rect.width()) {
-                        this->drawRect(clip, paint, aa, viewMatrix,
+                        this->drawRect(clip, paint, viewMatrix,
                                        {rect.fLeft - r, rect.fTop, rect.fRight + r, rect.fBottom},
                                        &GrStyle::SimpleFill());
                     } else {
-                        this->drawRect(clip, paint, aa, viewMatrix,
+                        this->drawRect(clip, paint, viewMatrix,
                                        {rect.fLeft, rect.fTop - r, rect.fRight, rect.fBottom + r},
                                        &GrStyle::SimpleFill());
                     }
@@ -528,12 +548,12 @@
                 }
         }
 
+        bool useHWAA;
         bool snapToPixelCenters = false;
         sk_sp<GrDrawOp> op;
 
         GrColor color = paint.getColor();
-        GrAAType aaType = this->decideAAType(aa);
-        if (GrAAType::kCoverage == aaType) {
+        if (should_apply_coverage_aa(paint, fRenderTargetProxy.get(), &useHWAA)) {
             // The stroke path needs the rect to remain axis aligned (no rotation or skew).
             if (viewMatrix.rectStaysRect()) {
                 op.reset(GrRectBatchFactory::CreateAAStroke(color, viewMatrix, rect, stroke));
@@ -549,7 +569,7 @@
         }
 
         if (op) {
-            GrPipelineBuilder pipelineBuilder(paint, aaType);
+            GrPipelineBuilder pipelineBuilder(paint, useHWAA);
 
             if (snapToPixelCenters) {
                 pipelineBuilder.setState(GrPipelineBuilder::kSnapVerticesToPixelCenters_Flag,
@@ -564,7 +584,7 @@
     SkPath path;
     path.setIsVolatile(true);
     path.addRect(rect);
-    this->internalDrawPath(clip, paint, aa, viewMatrix, path, *style);
+    this->internalDrawPath(clip, paint, viewMatrix, path, *style);
 }
 
 int GrRenderTargetContextPriv::maxWindowRectangles() const {
@@ -588,17 +608,16 @@
 }
 
 void GrRenderTargetContextPriv::stencilPath(const GrClip& clip,
-                                            GrAAType aaType,
+                                            bool useHWAA,
                                             const SkMatrix& viewMatrix,
                                             const GrPath* path) {
-    SkASSERT(aaType != GrAAType::kCoverage);
-    fRenderTargetContext->getOpList()->stencilPath(fRenderTargetContext, clip, aaType, viewMatrix,
+    fRenderTargetContext->getOpList()->stencilPath(fRenderTargetContext, clip, useHWAA, viewMatrix,
                                                    path);
 }
 
 void GrRenderTargetContextPriv::stencilRect(const GrClip& clip,
                                             const GrUserStencilSettings* ss,
-                                            GrAAType aaType,
+                                            bool useHWAA,
                                             const SkMatrix& viewMatrix,
                                             const SkRect& rect) {
     ASSERT_SINGLE_OWNER_PRIV
@@ -606,21 +625,22 @@
     SkDEBUGCODE(fRenderTargetContext->validate();)
     GR_AUDIT_TRAIL_AUTO_FRAME(fRenderTargetContext->fAuditTrail,
                               "GrRenderTargetContext::stencilRect");
-    SkASSERT(GrAAType::kCoverage != aaType);
+
     AutoCheckFlush acf(fRenderTargetContext->fDrawingManager);
 
     GrPaint paint;
+    paint.setAntiAlias(useHWAA);
     paint.setXPFactory(GrDisableColorXPFactory::Make());
 
     fRenderTargetContext->drawNonAAFilledRect(clip, paint, viewMatrix, rect, nullptr, nullptr, ss,
-                                              aaType);
+                                              useHWAA);
 }
 
 bool GrRenderTargetContextPriv::drawAndStencilRect(const GrClip& clip,
                                                    const GrUserStencilSettings* ss,
                                                    SkRegion::Op op,
                                                    bool invert,
-                                                   GrAA aa,
+                                                   bool doAA,
                                                    const SkMatrix& viewMatrix,
                                                    const SkRect& rect) {
     ASSERT_SINGLE_OWNER_PRIV
@@ -632,20 +652,21 @@
     AutoCheckFlush acf(fRenderTargetContext->fDrawingManager);
 
     GrPaint paint;
+    paint.setAntiAlias(doAA);
     paint.setCoverageSetOpXPFactory(op, invert);
 
-    if (fRenderTargetContext->drawFilledRect(clip, paint, aa, viewMatrix, rect, ss)) {
+    if (fRenderTargetContext->drawFilledRect(clip, paint, viewMatrix, rect, ss)) {
         return true;
     }
+
     SkPath path;
     path.setIsVolatile(true);
     path.addRect(rect);
-    return this->drawAndStencilPath(clip, ss, op, invert, aa, viewMatrix, path);
+    return this->drawAndStencilPath(clip, ss, op, invert, doAA, viewMatrix, path);
 }
 
 void GrRenderTargetContext::fillRectToRect(const GrClip& clip,
                                            const GrPaint& paint,
-                                           GrAA aa,
                                            const SkMatrix& viewMatrix,
                                            const SkRect& rectToDraw,
                                            const SkRect& localRect) {
@@ -662,30 +683,30 @@
     }
 
     AutoCheckFlush acf(fDrawingManager);
-    GrAAType aaType;
+    bool useHWAA;
 
     if (GrCaps::InstancedSupport::kNone != fContext->caps()->instancedSupport()) {
         InstancedRendering* ir = this->getOpList()->instancedRendering();
         sk_sp<GrDrawOp> op(ir->recordRect(croppedRect, viewMatrix, paint.getColor(),
-                                          croppedLocalRect, aa, fInstancedPipelineInfo, &aaType));
+                                          croppedLocalRect, paint.isAntiAlias(),
+                                          fInstancedPipelineInfo, &useHWAA));
         if (op) {
-            GrPipelineBuilder pipelineBuilder(paint, aaType);
+            GrPipelineBuilder pipelineBuilder(paint, useHWAA);
             this->getOpList()->addDrawOp(pipelineBuilder, this, clip, op.get());
             return;
         }
     }
 
-    aaType = this->decideAAType(aa);
-    if (GrAAType::kCoverage != aaType) {
-        this->drawNonAAFilledRect(clip, paint, viewMatrix, croppedRect, &croppedLocalRect, nullptr,
-                                  nullptr, aaType);
+    if (!should_apply_coverage_aa(paint, fRenderTargetProxy.get(), &useHWAA)) {
+        this->drawNonAAFilledRect(clip, paint, viewMatrix, croppedRect, &croppedLocalRect,
+                                  nullptr, nullptr, useHWAA);
         return;
     }
 
     if (view_matrix_ok_for_aa_fill_rect(viewMatrix)) {
         sk_sp<GrDrawOp> op(GrAAFillRectBatch::CreateWithLocalRect(paint.getColor(), viewMatrix,
                                                                   croppedRect, croppedLocalRect));
-        GrPipelineBuilder pipelineBuilder(paint, aaType);
+        GrPipelineBuilder pipelineBuilder(paint, useHWAA);
         this->addDrawOp(pipelineBuilder, clip, op.get());
         return;
     }
@@ -700,12 +721,11 @@
     SkPath path;
     path.setIsVolatile(true);
     path.addRect(localRect);
-    this->internalDrawPath(clip, paint, aaType, viewAndUnLocalMatrix, path, GrStyle());
+    this->internalDrawPath(clip, paint, viewAndUnLocalMatrix, path, GrStyle());
 }
 
 void GrRenderTargetContext::fillRectWithLocalMatrix(const GrClip& clip,
                                                     const GrPaint& paint,
-                                                    GrAA aa,
                                                     const SkMatrix& viewMatrix,
                                                     const SkRect& rectToDraw,
                                                     const SkMatrix& localMatrix) {
@@ -720,30 +740,29 @@
     }
 
     AutoCheckFlush acf(fDrawingManager);
-    GrAAType aaType;
+    bool useHWAA;
 
     if (GrCaps::InstancedSupport::kNone != fContext->caps()->instancedSupport()) {
         InstancedRendering* ir = this->getOpList()->instancedRendering();
         sk_sp<GrDrawOp> op(ir->recordRect(croppedRect, viewMatrix, paint.getColor(), localMatrix,
-                                          aa, fInstancedPipelineInfo, &aaType));
+                                          paint.isAntiAlias(), fInstancedPipelineInfo, &useHWAA));
         if (op) {
-            GrPipelineBuilder pipelineBuilder(paint, aaType);
+            GrPipelineBuilder pipelineBuilder(paint, useHWAA);
             this->getOpList()->addDrawOp(pipelineBuilder, this, clip, op.get());
             return;
         }
     }
 
-    aaType = this->decideAAType(aa);
-    if (GrAAType::kCoverage != aaType) {
-        this->drawNonAAFilledRect(clip, paint, viewMatrix, croppedRect, nullptr, &localMatrix,
-                                  nullptr, aaType);
+    if (!should_apply_coverage_aa(paint, fRenderTargetProxy.get(), &useHWAA)) {
+        this->drawNonAAFilledRect(clip, paint, viewMatrix, croppedRect, nullptr,
+                                  &localMatrix, nullptr, useHWAA);
         return;
     }
 
     if (view_matrix_ok_for_aa_fill_rect(viewMatrix)) {
         sk_sp<GrDrawOp> op(GrAAFillRectBatch::Create(paint.getColor(), viewMatrix, localMatrix,
                                                      croppedRect));
-        GrPipelineBuilder pipelineBuilder(paint, aaType);
+        GrPipelineBuilder pipelineBuilder(paint, useHWAA);
         this->getOpList()->addDrawOp(pipelineBuilder, this, clip, op.get());
         return;
     }
@@ -759,7 +778,7 @@
     path.setIsVolatile(true);
     path.addRect(rectToDraw);
     path.transform(localMatrix);
-    this->internalDrawPath(clip, paint, aaType, viewAndUnLocalMatrix, path, GrStyle());
+    this->internalDrawPath(clip, paint, viewAndUnLocalMatrix, path, GrStyle());
 }
 
 void GrRenderTargetContext::drawVertices(const GrClip& clip,
@@ -792,7 +811,7 @@
                                                positions, vertexCount, indices, indexCount, colors,
                                                texCoords, bounds));
 
-    GrPipelineBuilder pipelineBuilder(paint, GrAAType::kNone);
+    GrPipelineBuilder pipelineBuilder(paint, this->mustUseHWAA(paint));
     this->getOpList()->addDrawOp(pipelineBuilder, this, clip, op.get());
 }
 
@@ -815,7 +834,7 @@
     sk_sp<GrDrawOp> op(new GrDrawAtlasBatch(paint.getColor(), viewMatrix, spriteCount, xform,
                                             texRect, colors));
 
-    GrPipelineBuilder pipelineBuilder(paint, GrAAType::kNone);
+    GrPipelineBuilder pipelineBuilder(paint, this->mustUseHWAA(paint));
     this->getOpList()->addDrawOp(pipelineBuilder, this, clip, op.get());
 }
 
@@ -823,7 +842,6 @@
 
 void GrRenderTargetContext::drawRRect(const GrClip& origClip,
                                       const GrPaint& paint,
-                                      GrAA aa,
                                       const SkMatrix& viewMatrix,
                                       const SkRRect& rrect,
                                       const GrStyle& style) {
@@ -852,22 +870,21 @@
 
     AutoCheckFlush acf(fDrawingManager);
     const SkStrokeRec stroke = style.strokeRec();
-    GrAAType aaType;
+    bool useHWAA;
 
     if (GrCaps::InstancedSupport::kNone != fContext->caps()->instancedSupport() &&
         stroke.isFillStyle()) {
         InstancedRendering* ir = this->getOpList()->instancedRendering();
-        sk_sp<GrDrawOp> op(ir->recordRRect(rrect, viewMatrix, paint.getColor(), aa,
-                                           fInstancedPipelineInfo, &aaType));
+        sk_sp<GrDrawOp> op(ir->recordRRect(rrect, viewMatrix, paint.getColor(), paint.isAntiAlias(),
+                                           fInstancedPipelineInfo, &useHWAA));
         if (op) {
-            GrPipelineBuilder pipelineBuilder(paint, aaType);
+            GrPipelineBuilder pipelineBuilder(paint, useHWAA);
             this->getOpList()->addDrawOp(pipelineBuilder, this, *clip, op.get());
             return;
         }
     }
 
-    aaType = this->decideAAType(aa);
-    if (GrAAType::kCoverage == aaType) {
+    if (should_apply_coverage_aa(paint, fRenderTargetProxy.get(), &useHWAA)) {
         const GrShaderCaps* shaderCaps = fContext->caps()->shaderCaps();
         sk_sp<GrDrawOp> op(GrOvalRenderer::CreateRRectBatch(paint.getColor(),
                                                             paint.usesDistanceVectorField(),
@@ -876,7 +893,7 @@
                                                             stroke,
                                                             shaderCaps));
         if (op) {
-            GrPipelineBuilder pipelineBuilder(paint, aaType);
+            GrPipelineBuilder pipelineBuilder(paint, useHWAA);
             this->getOpList()->addDrawOp(pipelineBuilder, this, *clip, op.get());
             return;
         }
@@ -885,7 +902,7 @@
     SkPath path;
     path.setIsVolatile(true);
     path.addRRect(rrect);
-    this->internalDrawPath(*clip, paint, aaType, viewMatrix, path, style);
+    this->internalDrawPath(*clip, paint, viewMatrix, path, style);
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -908,55 +925,72 @@
 
     AutoCheckFlush acf(fDrawingManager);
     const SkStrokeRec stroke = style.strokeRec();
-    // TODO: add instancing support?
+    bool useHWAA;
 
-    const GrShaderCaps* shaderCaps = fContext->caps()->shaderCaps();
-    sk_sp<GrDrawOp> op(CreateShadowRRectBatch(paint.getColor(),
-                                              viewMatrix,
-                                              rrect,
-                                              blurRadius,
-                                              stroke,
-                                              shaderCaps));
-    if (op) {
-        GrPipelineBuilder pipelineBuilder(paint, GrAAType::kNone);
-        this->getOpList()->addDrawOp(pipelineBuilder, this, clip, op.get());
-        return;
+    // TODO: add instancing support
+    //if (GrCaps::InstancedSupport::kNone != fContext->caps()->instancedSupport() &&
+    //    stroke.isFillStyle()) {
+    //    InstancedRendering* ir = this->getOpList()->instancedRendering();
+    //    SkAutoTUnref<GrDrawOp> op(ir->recordRRect(rrect, viewMatrix, paint.getColor(),
+    //                                              paint.isAntiAlias(), fInstancedPipelineInfo,
+    //                                              &useHWAA));
+    //    if (op) {
+    //        GrPipelineBuilder pipelineBuilder(paint, useHWAA);
+    //        this->getOpList()->addDrawOp(pipelineBuilder, this, *clip, op);
+    //        return;
+    //    }
+    //}
+
+    if (should_apply_coverage_aa(paint, fRenderTargetProxy.get(), &useHWAA)) {
+        const GrShaderCaps* shaderCaps = fContext->caps()->shaderCaps();
+        sk_sp<GrDrawOp> op(CreateShadowRRectBatch(paint.getColor(),
+                                                  viewMatrix,
+                                                  rrect,
+                                                  blurRadius,
+                                                  stroke,
+                                                  shaderCaps));
+        if (op) {
+            GrPipelineBuilder pipelineBuilder(paint, useHWAA);
+            this->getOpList()->addDrawOp(pipelineBuilder, this, clip, op.get());
+            return;
+        }
     }
+
+    SkPath path;
+    path.setIsVolatile(true);
+    path.addRRect(rrect);
+    this->internalDrawPath(clip, paint, viewMatrix, path, style);
 }
 
 ///////////////////////////////////////////////////////////////////////////////
 
 bool GrRenderTargetContext::drawFilledDRRect(const GrClip& clip,
                                              const GrPaint& paintIn,
-                                             GrAA aa,
                                              const SkMatrix& viewMatrix,
                                              const SkRRect& origOuter,
                                              const SkRRect& origInner) {
     SkASSERT(!origInner.isEmpty());
     SkASSERT(!origOuter.isEmpty());
-    GrAAType aaType;
 
     if (GrCaps::InstancedSupport::kNone != fContext->caps()->instancedSupport()) {
+        bool useHWAA;
         InstancedRendering* ir = this->getOpList()->instancedRendering();
         sk_sp<GrDrawOp> op(ir->recordDRRect(origOuter, origInner, viewMatrix, paintIn.getColor(),
-                                            aa, fInstancedPipelineInfo, &aaType));
+                                            paintIn.isAntiAlias(), fInstancedPipelineInfo,
+                                            &useHWAA));
         if (op) {
-            GrPipelineBuilder pipelineBuilder(paintIn, aaType);
+            GrPipelineBuilder pipelineBuilder(paintIn, useHWAA);
             this->getOpList()->addDrawOp(pipelineBuilder, this, clip, op.get());
             return true;
         }
     }
 
-    aaType = this->decideAAType(aa);
+    bool applyAA = paintIn.isAntiAlias() && !fRenderTargetProxy->isUnifiedMultisampled();
 
-    GrPrimitiveEdgeType innerEdgeType, outerEdgeType;
-    if (GrAAType::kCoverage == aaType) {
-        innerEdgeType = kInverseFillAA_GrProcessorEdgeType;
-        outerEdgeType = kFillAA_GrProcessorEdgeType;
-    } else {
-        innerEdgeType = kInverseFillBW_GrProcessorEdgeType;
-        outerEdgeType = kFillBW_GrProcessorEdgeType;
-    }
+    GrPrimitiveEdgeType innerEdgeType = applyAA ? kInverseFillAA_GrProcessorEdgeType :
+                                                  kInverseFillBW_GrProcessorEdgeType;
+    GrPrimitiveEdgeType outerEdgeType = applyAA ? kFillAA_GrProcessorEdgeType :
+                                                  kFillBW_GrProcessorEdgeType;
 
     SkTCopyOnFirstWrite<SkRRect> inner(origInner), outer(origOuter);
     SkMatrix inverseVM;
@@ -975,6 +1009,7 @@
     }
 
     GrPaint grPaint(paintIn);
+    grPaint.setAntiAlias(false);
 
     // TODO these need to be a geometry processors
     sk_sp<GrFragmentProcessor> innerEffect(GrRRectEffect::Make(innerEdgeType, *inner));
@@ -991,17 +1026,16 @@
     grPaint.addCoverageFragmentProcessor(std::move(outerEffect));
 
     SkRect bounds = outer->getBounds();
-    if (GrAAType::kCoverage == aaType) {
+    if (applyAA) {
         bounds.outset(SK_ScalarHalf, SK_ScalarHalf);
     }
 
-    this->fillRectWithLocalMatrix(clip, grPaint, GrAA::kNo, SkMatrix::I(), bounds, inverseVM);
+    this->fillRectWithLocalMatrix(clip, grPaint, SkMatrix::I(), bounds, inverseVM);
     return true;
 }
 
 void GrRenderTargetContext::drawDRRect(const GrClip& clip,
                                        const GrPaint& paint,
-                                       GrAA aa,
                                        const SkMatrix& viewMatrix,
                                        const SkRRect& outer,
                                        const SkRRect& inner) {
@@ -1015,7 +1049,7 @@
 
     AutoCheckFlush acf(fDrawingManager);
 
-    if (this->drawFilledDRRect(clip, paint, aa, viewMatrix, outer, inner)) {
+    if (this->drawFilledDRRect(clip, paint, viewMatrix, outer, inner)) {
         return;
     }
 
@@ -1025,7 +1059,7 @@
     path.addRRect(outer);
     path.setFillType(SkPath::kEvenOdd_FillType);
 
-    this->internalDrawPath(clip, paint, aa, viewMatrix, path, GrStyle::SimpleFill());
+    this->internalDrawPath(clip, paint, viewMatrix, path, GrStyle::SimpleFill());
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -1036,7 +1070,6 @@
 
 void GrRenderTargetContext::drawRegion(const GrClip& clip,
                                        const GrPaint& paint,
-                                       GrAA aa,
                                        const SkMatrix& viewMatrix,
                                        const SkRegion& region,
                                        const GrStyle& style) {
@@ -1045,30 +1078,28 @@
     SkDEBUGCODE(this->validate();)
     GR_AUDIT_TRAIL_AUTO_FRAME(fAuditTrail, "GrRenderTargetContext::drawRegion");
 
-    if (GrAA::kYes == aa) {
+    bool needsAA = false;
+    if (paint.isAntiAlias()) {
         // GrRegionBatch performs no antialiasing but is much faster, so here we check the matrix
         // to see whether aa is really required.
-        if (!SkToBool(viewMatrix.getType() & ~(SkMatrix::kTranslate_Mask)) &&
-            is_int(viewMatrix.getTranslateX()) &&
-            is_int(viewMatrix.getTranslateY())) {
-            aa = GrAA::kNo;
-        }
+        needsAA = SkToBool(viewMatrix.getType() & ~(SkMatrix::kTranslate_Mask)) ||
+                  !is_int(viewMatrix.getTranslateX()) ||
+                  !is_int(viewMatrix.getTranslateY());
     }
     bool complexStyle = !style.isSimpleFill();
-    if (complexStyle || GrAA::kYes == aa) {
+    if (complexStyle || needsAA) {
         SkPath path;
         region.getBoundaryPath(&path);
-        return this->drawPath(clip, paint, aa, viewMatrix, path, style);
+        return this->drawPath(clip, paint, viewMatrix, path, style);
     }
 
     sk_sp<GrDrawOp> op(GrRegionBatch::Create(paint.getColor(), viewMatrix, region));
-    GrPipelineBuilder pipelineBuilder(paint, GrAAType::kNone);
+    GrPipelineBuilder pipelineBuilder(paint, false);
     this->getOpList()->addDrawOp(pipelineBuilder, this, clip, op.get());
 }
 
 void GrRenderTargetContext::drawOval(const GrClip& clip,
                                      const GrPaint& paint,
-                                     GrAA aa,
                                      const SkMatrix& viewMatrix,
                                      const SkRect& oval,
                                      const GrStyle& style) {
@@ -1085,22 +1116,21 @@
 
     AutoCheckFlush acf(fDrawingManager);
     const SkStrokeRec& stroke = style.strokeRec();
-    GrAAType aaType;
+    bool useHWAA;
 
     if (GrCaps::InstancedSupport::kNone != fContext->caps()->instancedSupport() &&
         stroke.isFillStyle()) {
         InstancedRendering* ir = this->getOpList()->instancedRendering();
-        sk_sp<GrDrawOp> op(ir->recordOval(oval, viewMatrix, paint.getColor(), aa,
-                                          fInstancedPipelineInfo, &aaType));
+        sk_sp<GrDrawOp> op(ir->recordOval(oval, viewMatrix, paint.getColor(), paint.isAntiAlias(),
+                                          fInstancedPipelineInfo, &useHWAA));
         if (op) {
-            GrPipelineBuilder pipelineBuilder(paint, aaType);
+            GrPipelineBuilder pipelineBuilder(paint, useHWAA);
             this->getOpList()->addDrawOp(pipelineBuilder, this, clip, op.get());
             return;
         }
     }
 
-    aaType = this->decideAAType(aa);
-    if (GrAAType::kCoverage == aaType) {
+    if (should_apply_coverage_aa(paint, fRenderTargetProxy.get(), &useHWAA)) {
         const GrShaderCaps* shaderCaps = fContext->caps()->shaderCaps();
         sk_sp<GrDrawOp> op(GrOvalRenderer::CreateOvalBatch(paint.getColor(),
                                                            viewMatrix,
@@ -1108,7 +1138,7 @@
                                                            stroke,
                                                            shaderCaps));
         if (op) {
-            GrPipelineBuilder pipelineBuilder(paint, aaType);
+            GrPipelineBuilder pipelineBuilder(paint, useHWAA);
             this->getOpList()->addDrawOp(pipelineBuilder, this, clip, op.get());
             return;
         }
@@ -1117,20 +1147,19 @@
     SkPath path;
     path.setIsVolatile(true);
     path.addOval(oval);
-    this->internalDrawPath(clip, paint, aaType, viewMatrix, path, style);
+    this->internalDrawPath(clip, paint, viewMatrix, path, style);
 }
 
 void GrRenderTargetContext::drawArc(const GrClip& clip,
                                     const GrPaint& paint,
-                                    GrAA aa,
                                     const SkMatrix& viewMatrix,
                                     const SkRect& oval,
                                     SkScalar startAngle,
                                     SkScalar sweepAngle,
                                     bool useCenter,
                                     const GrStyle& style) {
-    GrAAType aaType = this->decideAAType(aa);
-    if (GrAAType::kCoverage == aaType) {
+    bool useHWAA;
+    if (should_apply_coverage_aa(paint, fRenderTargetProxy.get(), &useHWAA)) {
         const GrShaderCaps* shaderCaps = fContext->caps()->shaderCaps();
         sk_sp<GrDrawOp> op(GrOvalRenderer::CreateArcBatch(paint.getColor(),
                                                           viewMatrix,
@@ -1141,7 +1170,7 @@
                                                           style,
                                                           shaderCaps));
         if (op) {
-            GrPipelineBuilder pipelineBuilder(paint, aaType);
+            GrPipelineBuilder pipelineBuilder(paint, useHWAA);
             this->getOpList()->addDrawOp(pipelineBuilder, this, clip, op.get());
             return;
         }
@@ -1149,7 +1178,8 @@
     SkPath path;
     SkPathPriv::CreateDrawArcPath(&path, oval, startAngle, sweepAngle, useCenter,
                                   style.isSimpleFill());
-    this->internalDrawPath(clip, paint, aaType, viewMatrix, path, style);
+    this->internalDrawPath(clip, paint, viewMatrix, path, style);
+    return;
 }
 
 void GrRenderTargetContext::drawImageLattice(const GrClip& clip,
@@ -1169,7 +1199,7 @@
     sk_sp<GrDrawOp> op(GrNinePatch::CreateNonAA(paint.getColor(), viewMatrix, imageWidth,
                                                 imageHeight, std::move(iter), dst));
 
-    GrPipelineBuilder pipelineBuilder(paint, GrAAType::kNone);
+    GrPipelineBuilder pipelineBuilder(paint, this->mustUseHWAA(paint));
     this->getOpList()->addDrawOp(pipelineBuilder, this, clip, op.get());
 }
 
@@ -1198,12 +1228,11 @@
                                                 const SkRect* localRect,
                                                 const SkMatrix* localMatrix,
                                                 const GrUserStencilSettings* ss,
-                                                GrAAType hwOrNoneAAType) {
-    SkASSERT(GrAAType::kCoverage != hwOrNoneAAType);
-    SkASSERT(hwOrNoneAAType == GrAAType::kNone || this->isStencilBufferMultisampled());
+                                                bool useHWAA) {
+    SkASSERT(!useHWAA || this->isStencilBufferMultisampled());
     sk_sp<GrDrawOp> op( GrRectBatchFactory::CreateNonAAFill(paint.getColor(), viewMatrix, rect,
                                                             localRect, localMatrix));
-    GrPipelineBuilder pipelineBuilder(paint, hwOrNoneAAType);
+    GrPipelineBuilder pipelineBuilder(paint, useHWAA);
     if (ss) {
         pipelineBuilder.setUserStencil(ss);
     }
@@ -1305,7 +1334,6 @@
 
 void GrRenderTargetContext::drawPath(const GrClip& clip,
                                      const GrPaint& paint,
-                                     GrAA aa,
                                      const SkMatrix& viewMatrix,
                                      const SkPath& path,
                                      const GrStyle& style) {
@@ -1323,8 +1351,9 @@
 
     AutoCheckFlush acf(fDrawingManager);
 
-    GrAAType aaType = this->decideAAType(aa);
-    if (GrAAType::kCoverage == aaType && !style.pathEffect()) {
+    bool useHWAA;
+    if (should_apply_coverage_aa(paint, fRenderTargetProxy.get(), &useHWAA) &&
+                                                                            !style.pathEffect()) {
         if (style.isSimpleFill() && !path.isConvex()) {
             // Concave AA paths are expensive - try to avoid them for special cases
             SkRect rects[2];
@@ -1332,8 +1361,8 @@
             if (fills_as_nested_rects(viewMatrix, path, rects)) {
                 sk_sp<GrDrawOp> op(GrRectBatchFactory::CreateAAFillNestedRects(
                     paint.getColor(), viewMatrix, rects));
-              if (op) {
-                    GrPipelineBuilder pipelineBuilder(paint, aaType);
+                if (op) {
+                    GrPipelineBuilder pipelineBuilder(paint, useHWAA);
                     this->getOpList()->addDrawOp(pipelineBuilder, this, clip, op.get());
                 }
                 return;
@@ -1350,7 +1379,7 @@
                                                                style.strokeRec(),
                                                                shaderCaps));
             if (op) {
-                GrPipelineBuilder pipelineBuilder(paint, aaType);
+                GrPipelineBuilder pipelineBuilder(paint, useHWAA);
                 this->getOpList()->addDrawOp(pipelineBuilder, this, clip, op.get());
                 return;
             }
@@ -1362,24 +1391,23 @@
     // cache. This presents a potential hazard for buffered drawing. However,
     // the writePixels that uploads to the scratch will perform a flush so we're
     // OK.
-    this->internalDrawPath(clip, paint, aaType, viewMatrix, path, style);
+    this->internalDrawPath(clip, paint, viewMatrix, path, style);
 }
 
 bool GrRenderTargetContextPriv::drawAndStencilPath(const GrClip& clip,
                                                    const GrUserStencilSettings* ss,
                                                    SkRegion::Op op,
                                                    bool invert,
-                                                   GrAA aa,
+                                                   bool doAA,
                                                    const SkMatrix& viewMatrix,
                                                    const SkPath& path) {
     ASSERT_SINGLE_OWNER_PRIV
     RETURN_FALSE_IF_ABANDONED_PRIV
     SkDEBUGCODE(fRenderTargetContext->validate();)
-    GR_AUDIT_TRAIL_AUTO_FRAME(fRenderTargetContext->fAuditTrail,
-                              "GrRenderTargetContextPriv::drawAndStencilPath");
+    GR_AUDIT_TRAIL_AUTO_FRAME(fRenderTargetContext->fAuditTrail, "GrRenderTargetContext::drawPath");
 
     if (path.isEmpty() && path.isInverseFillType()) {
-        this->drawAndStencilRect(clip, ss, op, invert, GrAA::kNo, SkMatrix::I(),
+        this->drawAndStencilRect(clip, ss, op, invert, false, SkMatrix::I(),
                                  SkRect::MakeIWH(fRenderTargetContext->width(),
                                                  fRenderTargetContext->height()));
         return true;
@@ -1391,12 +1419,13 @@
     // 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.
-    GrAAType aaType = fRenderTargetContext->decideAAType(aa);
+    bool useCoverageAA = doAA && !fRenderTargetContext->isUnifiedMultisampled();
     bool hasUserStencilSettings = !ss->isUnused();
+    bool isStencilBufferMSAA = fRenderTargetContext->isStencilBufferMultisampled();
 
-    const GrPathRendererChain::DrawType type = (GrAAType::kCoverage == aaType)
-                                               ? GrPathRendererChain::kColorAntiAlias_DrawType
-                                               : GrPathRendererChain::kColor_DrawType;
+    const GrPathRendererChain::DrawType type =
+        useCoverageAA ? GrPathRendererChain::kColorAntiAlias_DrawType
+                      : GrPathRendererChain::kColor_DrawType;
 
     GrShape shape(path, GrStyle::SimpleFill());
     GrPathRenderer::CanDrawPathArgs canDrawArgs;
@@ -1404,8 +1433,9 @@
         fRenderTargetContext->fDrawingManager->getContext()->caps()->shaderCaps();
     canDrawArgs.fViewMatrix = &viewMatrix;
     canDrawArgs.fShape = &shape;
-    canDrawArgs.fAAType = aaType;
+    canDrawArgs.fAntiAlias = useCoverageAA;
     canDrawArgs.fHasUserStencilSettings = hasUserStencilSettings;
+    canDrawArgs.fIsStencilBufferMSAA = isStencilBufferMSAA;
 
     // Don't allow the SW renderer
     GrPathRenderer* pr = fRenderTargetContext->fDrawingManager->getPathRenderer(canDrawArgs, false,
@@ -1426,7 +1456,7 @@
     args.fClip = &clip;
     args.fViewMatrix = &viewMatrix;
     args.fShape = &shape;
-    args.fAAType = aaType;
+    args.fAntiAlias = useCoverageAA;
     args.fGammaCorrect = fRenderTargetContext->isGammaCorrect();
     pr->drawPath(args);
     return true;
@@ -1446,7 +1476,6 @@
 
 void GrRenderTargetContext::internalDrawPath(const GrClip& clip,
                                              const GrPaint& paint,
-                                             GrAAType aaType,
                                              const SkMatrix& viewMatrix,
                                              const SkPath& path,
                                              const GrStyle& style) {
@@ -1454,11 +1483,13 @@
     RETURN_IF_ABANDONED
     SkASSERT(!path.isEmpty());
 
+    bool useCoverageAA = should_apply_coverage_aa(paint, fRenderTargetProxy.get());
     constexpr bool kHasUserStencilSettings = false;
+    bool isStencilBufferMSAA = this->isStencilBufferMultisampled();
 
-    const GrPathRendererChain::DrawType type = GrAAType::kCoverage == aaType
-            ? GrPathRendererChain::kColorAntiAlias_DrawType
-            : GrPathRendererChain::kColor_DrawType;
+    const GrPathRendererChain::DrawType type =
+        useCoverageAA ? GrPathRendererChain::kColorAntiAlias_DrawType
+                      : GrPathRendererChain::kColor_DrawType;
 
     GrShape shape(path, style);
     if (shape.isEmpty()) {
@@ -1468,8 +1499,9 @@
     canDrawArgs.fShaderCaps = fDrawingManager->getContext()->caps()->shaderCaps();
     canDrawArgs.fViewMatrix = &viewMatrix;
     canDrawArgs.fShape = &shape;
-    canDrawArgs.fAAType = aaType;
+    canDrawArgs.fAntiAlias = useCoverageAA;
     canDrawArgs.fHasUserStencilSettings = kHasUserStencilSettings;
+    canDrawArgs.fIsStencilBufferMSAA = isStencilBufferMSAA;
 
     // Try a 1st time without applying any of the style to the geometry (and barring sw)
     GrPathRenderer* pr = fDrawingManager->getPathRenderer(canDrawArgs, false, type);
@@ -1509,7 +1541,7 @@
     args.fClip = &clip;
     args.fViewMatrix = &viewMatrix;
     args.fShape = canDrawArgs.fShape;
-    args.fAAType = aaType;
+    args.fAntiAlias = useCoverageAA;
     args.fGammaCorrect = this->isGammaCorrect();
     pr->drawPath(args);
 }
diff --git a/src/gpu/GrRenderTargetContextPriv.h b/src/gpu/GrRenderTargetContextPriv.h
index b232ed1..ff17505 100644
--- a/src/gpu/GrRenderTargetContextPriv.h
+++ b/src/gpu/GrRenderTargetContextPriv.h
@@ -53,33 +53,28 @@
 
     void stencilRect(const GrClip& clip,
                      const GrUserStencilSettings* ss,
-                     GrAAType,
+                     bool useHWAA,
                      const SkMatrix& viewMatrix,
                      const SkRect& rect);
 
-    void stencilPath(const GrClip&, GrAAType, const SkMatrix& viewMatrix, const GrPath*);
+    void stencilPath(const GrClip&,
+                     bool useHWAA,
+                     const SkMatrix& viewMatrix,
+                     const GrPath*);
 
-    /**
-     * Draws a rect, either AA or not, and touches the stencil buffer with the user stencil settings
-     * for each color sample written.
-     */
     bool drawAndStencilRect(const GrClip&,
                             const GrUserStencilSettings*,
                             SkRegion::Op op,
                             bool invert,
-                            GrAA,
+                            bool doAA,
                             const SkMatrix& viewMatrix,
                             const SkRect&);
 
-    /**
-     * Draws a path, either AA or not, and touches the stencil buffer with the user stencil settings
-     * for each color sample written.
-     */
     bool drawAndStencilPath(const GrClip&,
                             const GrUserStencilSettings*,
                             SkRegion::Op op,
                             bool invert,
-                            GrAA,
+                            bool doAA,
                             const SkMatrix& viewMatrix,
                             const SkPath&);
 
@@ -96,7 +91,6 @@
     }
 
     void testingOnly_drawBatch(const GrPaint&,
-                               GrAAType,
                                GrDrawOp* batch,
                                const GrUserStencilSettings* = nullptr,
                                bool snapToCenters = false);
diff --git a/src/gpu/GrRenderTargetOpList.cpp b/src/gpu/GrRenderTargetOpList.cpp
index 28da819..41c0d4f 100644
--- a/src/gpu/GrRenderTargetOpList.cpp
+++ b/src/gpu/GrRenderTargetOpList.cpp
@@ -351,10 +351,9 @@
 
 void GrRenderTargetOpList::stencilPath(GrRenderTargetContext* renderTargetContext,
                                        const GrClip& clip,
-                                       GrAAType aaType,
+                                       bool useHWAA,
                                        const SkMatrix& viewMatrix,
                                        const GrPath* path) {
-    bool useHWAA = aaType == GrAAType::kHW;
     // TODO: extract portions of checkDraw that are relevant to path stenciling.
     SkASSERT(path);
     SkASSERT(this->caps()->shaderCaps()->pathRenderingSupport());
diff --git a/src/gpu/GrRenderTargetOpList.h b/src/gpu/GrRenderTargetOpList.h
index 7ee4470..d7f8ba1 100644
--- a/src/gpu/GrRenderTargetOpList.h
+++ b/src/gpu/GrRenderTargetOpList.h
@@ -95,7 +95,7 @@
      */
     void stencilPath(GrRenderTargetContext*,
                      const GrClip&,
-                     GrAAType aa,
+                     bool useHWAA,
                      const SkMatrix& viewMatrix,
                      const GrPath*);
 
diff --git a/src/gpu/GrSWMaskHelper.cpp b/src/gpu/GrSWMaskHelper.cpp
index 7351ecd..ec76c48 100644
--- a/src/gpu/GrSWMaskHelper.cpp
+++ b/src/gpu/GrSWMaskHelper.cpp
@@ -38,11 +38,12 @@
 /**
  * Draw a single rect element of the clip stack into the accumulation bitmap
  */
-void GrSWMaskHelper::drawRect(const SkRect& rect, SkRegion::Op op, GrAA aa, uint8_t alpha) {
+void GrSWMaskHelper::drawRect(const SkRect& rect, SkRegion::Op op,
+                              bool antiAlias, uint8_t alpha) {
     SkPaint paint;
 
     paint.setBlendMode(op_to_mode(op));
-    paint.setAntiAlias(GrAA::kYes == aa);
+    paint.setAntiAlias(antiAlias);
     paint.setColor(SkColorSetARGB(alpha, alpha, alpha, alpha));
 
     fDraw.drawRect(rect, paint);
@@ -51,11 +52,12 @@
 /**
  * Draw a single path element of the clip stack into the accumulation bitmap
  */
-void GrSWMaskHelper::drawShape(const GrShape& shape, SkRegion::Op op, GrAA aa, uint8_t alpha) {
+void GrSWMaskHelper::drawShape(const GrShape& shape, SkRegion::Op op, bool antiAlias,
+                               uint8_t alpha) {
     SkPaint paint;
     paint.setPathEffect(sk_ref_sp(shape.style().pathEffect()));
     shape.style().strokeRec().applyToPaint(&paint);
-    paint.setAntiAlias(GrAA::kYes == aa);
+    paint.setAntiAlias(antiAlias);
 
     SkPath path;
     shape.asPath(&path);
@@ -139,7 +141,7 @@
 GrTexture* GrSWMaskHelper::DrawShapeMaskToTexture(GrTextureProvider* texProvider,
                                                   const GrShape& shape,
                                                   const SkIRect& resultBounds,
-                                                  GrAA aa,
+                                                  bool antiAlias,
                                                   TextureType textureType,
                                                   const SkMatrix* matrix) {
     GrSWMaskHelper helper(texProvider);
@@ -148,7 +150,7 @@
         return nullptr;
     }
 
-    helper.drawShape(shape, SkRegion::kReplace_Op, aa, 0xFF);
+    helper.drawShape(shape, SkRegion::kReplace_Op, antiAlias, 0xFF);
 
     GrTexture* texture(helper.createTexture(textureType));
     if (!texture) {
@@ -183,7 +185,7 @@
     maskMatrix.preTranslate(SkIntToScalar(-textureOriginInDeviceSpace.fX),
                             SkIntToScalar(-textureOriginInDeviceSpace.fY));
     maskMatrix.preConcat(viewMatrix);
-    GrPipelineBuilder pipelineBuilder(paint, GrAAType::kNone);
+    GrPipelineBuilder pipelineBuilder(paint, renderTargetContext->mustUseHWAA(paint));
     pipelineBuilder.setUserStencil(&userStencilSettings);
 
     pipelineBuilder.addCoverageFragmentProcessor(
diff --git a/src/gpu/GrSWMaskHelper.h b/src/gpu/GrSWMaskHelper.h
index 0669db9..1846733 100644
--- a/src/gpu/GrSWMaskHelper.h
+++ b/src/gpu/GrSWMaskHelper.h
@@ -9,7 +9,6 @@
 #define GrSWMaskHelper_DEFINED
 
 #include "GrColor.h"
-#include "GrRenderTargetContext.h"
 #include "GrTextureProvider.h"
 #include "SkAutoPixmapStorage.h"
 #include "SkBitmap.h"
@@ -52,10 +51,10 @@
     bool init(const SkIRect& resultBounds, const SkMatrix* matrix);
 
     // Draw a single rect into the accumulation bitmap using the specified op
-    void drawRect(const SkRect& rect, SkRegion::Op op, GrAA, uint8_t alpha);
+    void drawRect(const SkRect& rect, SkRegion::Op op, bool antiAlias, uint8_t alpha);
 
     // Draw a single path into the accumuation bitmap using the specified op
-    void drawShape(const GrShape&, SkRegion::Op op, GrAA, uint8_t alpha);
+    void drawShape(const GrShape&, SkRegion::Op op, bool antiAlias, uint8_t alpha);
 
     // Move the mask generation results from the internal bitmap to the gpu.
     void toTexture(GrTexture* texture);
@@ -68,6 +67,7 @@
         fPixels.erase(SkColorSetARGB(alpha, 0xFF, 0xFF, 0xFF));
     }
 
+
     enum class TextureType {
         kExactFit,
         kApproximateFit
@@ -78,7 +78,7 @@
     static GrTexture* DrawShapeMaskToTexture(GrTextureProvider*,
                                              const GrShape&,
                                              const SkIRect& resultBounds,
-                                             GrAA,
+                                             bool antiAlias,
                                              TextureType,
                                              const SkMatrix* matrix);
 
diff --git a/src/gpu/GrSoftwarePathRenderer.cpp b/src/gpu/GrSoftwarePathRenderer.cpp
index a5f18d6..8b941eb 100644
--- a/src/gpu/GrSoftwarePathRenderer.cpp
+++ b/src/gpu/GrSoftwarePathRenderer.cpp
@@ -71,8 +71,9 @@
                                                               viewMatrix, rect,
                                                               nullptr, &localMatrix));
 
-    GrPipelineBuilder pipelineBuilder(paint, GrAAType::kNone);
+    GrPipelineBuilder pipelineBuilder(paint, renderTargetContext->mustUseHWAA(paint));
     pipelineBuilder.setUserStencil(&userStencilSettings);
+
     renderTargetContext->addDrawOp(pipelineBuilder, clip, batch.get());
 }
 
@@ -134,7 +135,7 @@
     // To prevent overloading the cache with entries during animations we limit the cache of masks
     // to cases where the matrix preserves axis alignment.
     bool useCache = fAllowCaching && !inverseFilled && args.fViewMatrix->preservesAxisAlignment() &&
-                    args.fShape->hasUnstyledKey() && GrAAType::kCoverage == args.fAAType;
+                    args.fShape->hasUnstyledKey() && args.fAntiAlias;
 
     if (!get_shape_and_clip_bounds(args.fRenderTargetContext->width(),
                                    args.fRenderTargetContext->height(),
@@ -192,8 +193,6 @@
         builder[3] = SkFloat2Bits(ky);
         builder[4] = fracX | (fracY >> 8);
         args.fShape->writeUnstyledKey(&builder[5]);
-        // FIXME: Doesn't the key need to consider whether we're using AA or not? In practice that
-        // should always be true, though.
     }
 
     sk_sp<GrTexture> texture;
@@ -201,24 +200,25 @@
         texture.reset(args.fResourceProvider->findAndRefTextureByUniqueKey(maskKey));
     }
     if (!texture) {
-        GrSWMaskHelper::TextureType type = useCache ? GrSWMaskHelper::TextureType::kExactFit
-                                                    : GrSWMaskHelper::TextureType::kApproximateFit;
-        GrAA aa = GrAAType::kCoverage == args.fAAType ? GrAA::kYes : GrAA::kNo;
-        texture.reset(GrSWMaskHelper::DrawShapeMaskToTexture(fTexProvider, *args.fShape,
-                                                             *boundsForMask, aa,
-                                                             type, args.fViewMatrix));
-        if (!texture) {
-            return false;
-        }
-        if (useCache) {
-            texture->resourcePriv().setUniqueKey(maskKey);
-        }
+         GrSWMaskHelper::TextureType type = useCache ? GrSWMaskHelper::TextureType::kExactFit
+                                                     : GrSWMaskHelper::TextureType::kApproximateFit;
+         texture.reset(GrSWMaskHelper::DrawShapeMaskToTexture(fTexProvider, *args.fShape,
+                                                              *boundsForMask, args.fAntiAlias,
+                                                              type, args.fViewMatrix));
+         if (!texture) {
+             return false;
+         }
+         if (useCache) {
+             texture->resourcePriv().setUniqueKey(maskKey);
+         }
     }
+
     GrSWMaskHelper::DrawToTargetWithShapeMask(texture.get(), args.fRenderTargetContext,
                                               *args.fPaint, *args.fUserStencilSettings,
                                               *args.fClip, *args.fViewMatrix,
                                               SkIPoint {boundsForMask->fLeft, boundsForMask->fTop},
                                               *boundsForMask);
+
     if (inverseFilled) {
         DrawAroundInvPath(args.fRenderTargetContext, *args.fPaint, *args.fUserStencilSettings,
                           *args.fClip,
diff --git a/src/gpu/GrTextureProducer.cpp b/src/gpu/GrTextureProducer.cpp
index 8b64fea..14e2c29 100644
--- a/src/gpu/GrTextureProducer.cpp
+++ b/src/gpu/GrTextureProducer.cpp
@@ -69,7 +69,7 @@
     }
 
     SkRect dstRect = SkRect::MakeIWH(copyParams.fWidth, copyParams.fHeight);
-    copyRTC->fillRectToRect(GrNoClip(), paint, GrAA::kNo, SkMatrix::I(), dstRect, localRect);
+    copyRTC->fillRectToRect(GrNoClip(), paint, SkMatrix::I(), dstRect, localRect);
     return copyRTC->asTexture().release();
 }
 
diff --git a/src/gpu/GrTextureToYUVPlanes.cpp b/src/gpu/GrTextureToYUVPlanes.cpp
index 6268bef..ff6c707 100644
--- a/src/gpu/GrTextureToYUVPlanes.cpp
+++ b/src/gpu/GrTextureToYUVPlanes.cpp
@@ -43,7 +43,7 @@
     GrPaint paint;
     paint.setPorterDuffXPFactory(SkBlendMode::kSrc);
     paint.addColorFragmentProcessor(std::move(fp));
-    dst->drawRect(GrNoClip(), paint, GrAA::kNo, SkMatrix::I(), SkRect::MakeIWH(dstW, dstH));
+    dst->drawRect(GrNoClip(), paint, SkMatrix::I(), SkRect::MakeIWH(dstW, dstH));
     return true;
 }
 
diff --git a/src/gpu/GrYUVProvider.cpp b/src/gpu/GrYUVProvider.cpp
index 6fbad18..13e84da 100644
--- a/src/gpu/GrYUVProvider.cpp
+++ b/src/gpu/GrYUVProvider.cpp
@@ -147,7 +147,7 @@
     const SkRect r = SkRect::MakeIWH(yuvInfo.fSizeInfo.fSizes[SkYUVSizeInfo::kY].fWidth,
             yuvInfo.fSizeInfo.fSizes[SkYUVSizeInfo::kY].fHeight);
 
-    renderTargetContext->drawRect(GrNoClip(), paint, GrAA::kNo, SkMatrix::I(), r);
+    renderTargetContext->drawRect(GrNoClip(), paint, SkMatrix::I(), r);
 
     return renderTargetContext->asTexture();
 }
diff --git a/src/gpu/SkGpuDevice.cpp b/src/gpu/SkGpuDevice.cpp
index 39e2c5b..ff66177 100644
--- a/src/gpu/SkGpuDevice.cpp
+++ b/src/gpu/SkGpuDevice.cpp
@@ -342,8 +342,7 @@
         path.setIsVolatile(true);
         path.moveTo(pts[0]);
         path.lineTo(pts[1]);
-        fRenderTargetContext->drawPath(fClip, grPaint, GrBoolToAA(paint.isAntiAlias()),
-                                       *draw.fMatrix, path, style);
+        fRenderTargetContext->drawPath(fClip, grPaint, *draw.fMatrix, path, style);
         return;
     }
 
@@ -419,13 +418,13 @@
     }
 
     GrStyle style(paint);
-    fRenderTargetContext->drawRect(fClip, grPaint, GrBoolToAA(paint.isAntiAlias()), *draw.fMatrix,
-                                   rect, &style);
+    fRenderTargetContext->drawRect(fClip, grPaint, *draw.fMatrix, rect, &style);
 }
 
 ///////////////////////////////////////////////////////////////////////////////
 
-void SkGpuDevice::drawRRect(const SkDraw& draw, const SkRRect& rrect, const SkPaint& paint) {
+void SkGpuDevice::drawRRect(const SkDraw& draw, const SkRRect& rrect,
+                            const SkPaint& paint) {
     ASSERT_SINGLE_OWNER
     GR_CREATE_TRACE_MARKER_CONTEXT("SkGpuDevice", "drawRRect", fContext.get());
     CHECK_SHOULD_DRAW(draw);
@@ -484,8 +483,7 @@
 
     SkASSERT(!style.pathEffect());
 
-    fRenderTargetContext->drawRRect(fClip, grPaint, GrBoolToAA(paint.isAntiAlias()), *draw.fMatrix,
-                                    rrect, style);
+    fRenderTargetContext->drawRRect(fClip, grPaint, *draw.fMatrix, rrect, style);
 }
 
 
@@ -512,8 +510,7 @@
             return;
         }
 
-        fRenderTargetContext->drawDRRect(fClip, grPaint, GrBoolToAA(paint.isAntiAlias()),
-                                         *draw.fMatrix, outer, inner);
+        fRenderTargetContext->drawDRRect(fClip, grPaint, *draw.fMatrix, outer, inner);
         return;
     }
 
@@ -545,8 +542,7 @@
         return;
     }
 
-    fRenderTargetContext->drawRegion(fClip, grPaint, GrBoolToAA(paint.isAntiAlias()), *draw.fMatrix,
-                                     region, GrStyle(paint));
+    fRenderTargetContext->drawRegion(fClip, grPaint, *draw.fMatrix, region, GrStyle(paint));
 }
 
 void SkGpuDevice::drawOval(const SkDraw& draw, const SkRect& oval, const SkPaint& paint) {
@@ -575,8 +571,7 @@
         return;
     }
 
-    fRenderTargetContext->drawOval(fClip, grPaint, GrBoolToAA(paint.isAntiAlias()), *draw.fMatrix,
-                                   oval, GrStyle(paint));
+    fRenderTargetContext->drawOval(fClip, grPaint, *draw.fMatrix, oval, GrStyle(paint));
 }
 
 void SkGpuDevice::drawArc(const SkDraw& draw, const SkRect& oval, SkScalar startAngle,
@@ -595,8 +590,8 @@
         return;
     }
 
-    fRenderTargetContext->drawArc(fClip, grPaint, GrBoolToAA(paint.isAntiAlias()), *draw.fMatrix,
-                                  oval, startAngle, sweepAngle, useCenter, GrStyle(paint));
+    fRenderTargetContext->drawArc(fClip, grPaint, *draw.fMatrix, oval, startAngle, sweepAngle,
+                                  useCenter, GrStyle(paint));
 }
 
 #include "SkMaskFilter.h"
@@ -652,9 +647,7 @@
         return;
     }
 
-    fRenderTargetContext->fillRectWithLocalMatrix(fClip, grPaint,
-                                                  GrBoolToAA(newPaint.isAntiAlias()), m, rect,
-                                                  local);
+    fRenderTargetContext->fillRectWithLocalMatrix(fClip, grPaint, m, rect, local);
 }
 
 void SkGpuDevice::drawPath(const SkDraw& draw, const SkPath& origSrcPath,
@@ -1104,10 +1097,7 @@
         return;
     }
 
-    // Coverage-based AA would cause seams between tiles.
-    GrAA aa = GrBoolToAA(paint.isAntiAlias() &&
-                         fRenderTargetContext->isStencilBufferMultisampled());
-    fRenderTargetContext->drawRect(fClip, grPaint, aa, viewMatrix, dstRect);
+    fRenderTargetContext->drawRect(fClip, grPaint, viewMatrix, dstRect);
 }
 
 void SkGpuDevice::drawSprite(const SkDraw& draw, const SkBitmap& bitmap,
@@ -1202,7 +1192,6 @@
 
     fRenderTargetContext->fillRectToRect(fClip,
                                          grPaint,
-                                         GrBoolToAA(paint.isAntiAlias()),
                                          SkMatrix::I(),
                                          SkRect::Make(SkIRect::MakeXYWH(left + offset.fX,
                                                                         top + offset.fY,
diff --git a/src/gpu/SkGpuDevice_drawTexture.cpp b/src/gpu/SkGpuDevice_drawTexture.cpp
index fe14f8a..93c9f18 100644
--- a/src/gpu/SkGpuDevice_drawTexture.cpp
+++ b/src/gpu/SkGpuDevice_drawTexture.cpp
@@ -213,15 +213,15 @@
                                      fp, producer->isAlphaOnly(), &grPaint)) {
         return;
     }
-    GrAA aa = GrBoolToAA(paint.isAntiAlias());
+
     if (canUseTextureCoordsAsLocalCoords) {
-        fRenderTargetContext->fillRectToRect(clip, grPaint, aa, viewMatrix, clippedDstRect,
+        fRenderTargetContext->fillRectToRect(clip, grPaint, viewMatrix, clippedDstRect,
                                              clippedSrcRect);
         return;
     }
 
     if (!mf) {
-        fRenderTargetContext->drawRect(clip, grPaint, aa, viewMatrix, clippedDstRect);
+        fRenderTargetContext->drawRect(clip, grPaint, viewMatrix, clippedDstRect);
         return;
     }
 
@@ -247,6 +247,6 @@
     rectPath.addRect(clippedDstRect);
     rectPath.setIsVolatile(true);
     GrBlurUtils::drawPathWithMaskFilter(this->context(), fRenderTargetContext.get(), fClip,
-                                        rectPath, &grPaint, aa, viewMatrix, mf,
-                                        GrStyle::SimpleFill(), true);
+                                        rectPath, &grPaint, viewMatrix, mf, GrStyle::SimpleFill(),
+                                        true);
 }
diff --git a/src/gpu/SkGr.cpp b/src/gpu/SkGr.cpp
index 4d62e6f..6ce9cae 100644
--- a/src/gpu/SkGr.cpp
+++ b/src/gpu/SkGr.cpp
@@ -558,6 +558,7 @@
                                            SkBlendMode* primColorMode,
                                            bool primitiveIsSrc,
                                            GrPaint* grPaint) {
+    grPaint->setAntiAlias(skPaint.isAntiAlias());
     grPaint->setAllowSRGBInputs(rtc->isGammaCorrect());
 
     // Convert SkPaint color to 4f format, including optional linearizing and gamut conversion.
diff --git a/src/gpu/batches/GrAAConvexPathRenderer.cpp b/src/gpu/batches/GrAAConvexPathRenderer.cpp
index cc31f49..56a5e7a 100644
--- a/src/gpu/batches/GrAAConvexPathRenderer.cpp
+++ b/src/gpu/batches/GrAAConvexPathRenderer.cpp
@@ -672,7 +672,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 
 bool GrAAConvexPathRenderer::onCanDrawPath(const CanDrawPathArgs& args) const {
-    return (args.fShaderCaps->shaderDerivativeSupport() && (GrAAType::kCoverage == args.fAAType) &&
+    return (args.fShaderCaps->shaderDerivativeSupport() && args.fAntiAlias &&
             args.fShape->style().isSimpleFill() && !args.fShape->inverseFilled() &&
             args.fShape->knownToBeConvex());
 }
@@ -1002,7 +1002,7 @@
 
     sk_sp<GrDrawOp> batch(new AAConvexPathBatch(args.fPaint->getColor(), *args.fViewMatrix, path));
 
-    GrPipelineBuilder pipelineBuilder(*args.fPaint, args.fAAType);
+    GrPipelineBuilder pipelineBuilder(*args.fPaint);
     pipelineBuilder.setUserStencil(args.fUserStencilSettings);
 
     args.fRenderTargetContext->addDrawOp(pipelineBuilder, *args.fClip, batch.get());
diff --git a/src/gpu/batches/GrAADistanceFieldPathRenderer.cpp b/src/gpu/batches/GrAADistanceFieldPathRenderer.cpp
index 71b9000..0aa451d 100644
--- a/src/gpu/batches/GrAADistanceFieldPathRenderer.cpp
+++ b/src/gpu/batches/GrAADistanceFieldPathRenderer.cpp
@@ -90,8 +90,8 @@
     if (!args.fShape->style().isSimpleFill()) {
         return false;
     }
-    // This does non-inverse coverage-based antialiased fills.
-    if (GrAAType::kCoverage != args.fAAType) {
+    // This does non-inverse antialiased fills.
+    if (!args.fAntiAlias) {
         return false;
     }
     // TODO: Support inverse fill
@@ -128,6 +128,7 @@
 
     AADistanceFieldPathBatch(GrColor color,
                              const GrShape& shape,
+                             bool antiAlias,
                              const SkMatrix& viewMatrix,
                              GrBatchAtlas* atlas,
                              ShapeCache* shapeCache, ShapeDataList* shapeList,
@@ -135,7 +136,7 @@
             : INHERITED(ClassID()) {
         SkASSERT(shape.hasUnstyledKey());
         fBatch.fViewMatrix = viewMatrix;
-        fGeoData.emplace_back(Geometry{color, shape});
+        fGeoData.emplace_back(Geometry{color, shape, antiAlias});
 
         fAtlas = atlas;
         fShapeCache = shapeCache;
@@ -156,7 +157,7 @@
     SkString dumpInfo() const override {
         SkString string;
         for (const auto& geo : fGeoData) {
-            string.appendf("Color: 0x%08x\n", geo.fColor);
+            string.appendf("Color: 0x%08x AA:%d\n", geo.fColor, geo.fAntiAlias);
         }
         string.append(DumpPipelineInfo(*this->pipeline()));
         string.append(INHERITED::dumpInfo());
@@ -273,6 +274,7 @@
                                           atlas,
                                           shapeData,
                                           args.fShape,
+                                          args.fAntiAlias,
                                           desiredDimension,
                                           scale)) {
                     delete shapeData;
@@ -298,8 +300,8 @@
     }
 
     bool addPathToAtlas(GrMeshDrawOp::Target* target, FlushInfo* flushInfo, GrBatchAtlas* atlas,
-                        ShapeData* shapeData, const GrShape& shape, uint32_t dimension,
-                        SkScalar scale) const {
+                        ShapeData* shapeData, const GrShape& shape, bool antiAlias,
+                        uint32_t dimension, SkScalar scale) const {
         const SkRect& bounds = shape.bounds();
 
         // generate bounding rect for bitmap draw
@@ -346,7 +348,7 @@
         // rasterize path
         SkPaint paint;
         paint.setStyle(SkPaint::kFill_Style);
-        paint.setAntiAlias(true);
+        paint.setAntiAlias(antiAlias);
 
         SkDraw draw;
         sk_bzero(&draw, sizeof(draw));
@@ -500,6 +502,7 @@
     struct Geometry {
         GrColor fColor;
         GrShape fShape;
+        bool fAntiAlias;
     };
 
     BatchTracker fBatch;
@@ -515,6 +518,8 @@
 bool GrAADistanceFieldPathRenderer::onDrawPath(const DrawPathArgs& args) {
     GR_AUDIT_TRAIL_AUTO_FRAME(args.fRenderTargetContext->auditTrail(),
                               "GrAADistanceFieldPathRenderer::onDrawPath");
+    SkASSERT(!args.fRenderTargetContext->isUnifiedMultisampled());
+    SkASSERT(args.fShape->style().isSimpleFill());
 
     // we've already bailed on inverse filled paths, so this is safe
     SkASSERT(!args.fShape->isEmpty());
@@ -531,10 +536,11 @@
     }
 
     sk_sp<GrDrawOp> batch(new AADistanceFieldPathBatch(args.fPaint->getColor(),
-                                                       *args.fShape, *args.fViewMatrix,
+                                                       *args.fShape,
+                                                       args.fAntiAlias, *args.fViewMatrix,
                                                        fAtlas.get(), &fShapeCache, &fShapeList,
                                                        args.fGammaCorrect));
-    GrPipelineBuilder pipelineBuilder(*args.fPaint, args.fAAType);
+    GrPipelineBuilder pipelineBuilder(*args.fPaint);
     pipelineBuilder.setUserStencil(args.fUserStencilSettings);
 
     args.fRenderTargetContext->addDrawOp(pipelineBuilder, *args.fClip, batch.get());
@@ -608,9 +614,11 @@
 
     // This path renderer only allows fill styles.
     GrShape shape(GrTest::TestPath(random), GrStyle::SimpleFill());
+    bool antiAlias = random->nextBool();
 
     return new AADistanceFieldPathBatch(color,
                                         shape,
+                                        antiAlias,
                                         viewMatrix,
                                         gTestStruct.fAtlas.get(),
                                         &gTestStruct.fShapeCache,
diff --git a/src/gpu/batches/GrAAHairLinePathRenderer.cpp b/src/gpu/batches/GrAAHairLinePathRenderer.cpp
index c299be6..70d0d4c 100644
--- a/src/gpu/batches/GrAAHairLinePathRenderer.cpp
+++ b/src/gpu/batches/GrAAHairLinePathRenderer.cpp
@@ -617,7 +617,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 
 bool GrAAHairLinePathRenderer::onCanDrawPath(const CanDrawPathArgs& args) const {
-    if (GrAAType::kCoverage != args.fAAType) {
+    if (!args.fAntiAlias) {
         return false;
     }
 
@@ -981,7 +981,7 @@
                                                 *args.fViewMatrix, path,
                                                 args.fShape->style(), devClipBounds));
 
-    GrPipelineBuilder pipelineBuilder(*args.fPaint, args.fAAType);
+    GrPipelineBuilder pipelineBuilder(*args.fPaint);
     pipelineBuilder.setUserStencil(args.fUserStencilSettings);
     args.fRenderTargetContext->addDrawOp(pipelineBuilder, *args.fClip, batch.get());
 
diff --git a/src/gpu/batches/GrAALinearizingConvexPathRenderer.cpp b/src/gpu/batches/GrAALinearizingConvexPathRenderer.cpp
index cbf526c..f961c5e 100644
--- a/src/gpu/batches/GrAALinearizingConvexPathRenderer.cpp
+++ b/src/gpu/batches/GrAALinearizingConvexPathRenderer.cpp
@@ -37,7 +37,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 
 bool GrAALinearizingConvexPathRenderer::onCanDrawPath(const CanDrawPathArgs& args) const {
-    if (GrAAType::kCoverage != args.fAAType) {
+    if (!args.fAntiAlias) {
         return false;
     }
     if (!args.fShape->knownToBeConvex()) {
@@ -361,7 +361,7 @@
                                                           stroke.getStyle(),
                                                           join, miterLimit));
 
-    GrPipelineBuilder pipelineBuilder(*args.fPaint, args.fAAType);
+    GrPipelineBuilder pipelineBuilder(*args.fPaint);
     pipelineBuilder.setUserStencil(args.fUserStencilSettings);
 
     args.fRenderTargetContext->addDrawOp(pipelineBuilder, *args.fClip, batch.get());
diff --git a/src/gpu/batches/GrDashLinePathRenderer.cpp b/src/gpu/batches/GrDashLinePathRenderer.cpp
index 0c00f18..d2a420d 100644
--- a/src/gpu/batches/GrDashLinePathRenderer.cpp
+++ b/src/gpu/batches/GrDashLinePathRenderer.cpp
@@ -26,18 +26,16 @@
 bool GrDashLinePathRenderer::onDrawPath(const DrawPathArgs& args) {
     GR_AUDIT_TRAIL_AUTO_FRAME(args.fRenderTargetContext->auditTrail(),
                               "GrDashLinePathRenderer::onDrawPath");
-    GrDashingEffect::AAMode aaMode = GrDashingEffect::AAMode::kNone;
-    switch (args.fAAType) {
-        case GrAAType::kNone:
-            break;
-        case GrAAType::kCoverage:
-            aaMode = GrDashingEffect::AAMode::kCoverage;
-            break;
-        case GrAAType::kHW:
-            // In this mode we will use aa between dashes but the outer border uses MSAA. Otherwise,
-            // we can wind up with external edges antialiased and internal edges unantialiased.
-            aaMode = GrDashingEffect::AAMode::kCoverageWithMSAA;
-            break;
+    bool useHWAA = args.fRenderTargetContext->isUnifiedMultisampled();
+    GrDashingEffect::AAMode aaMode;
+    if (useHWAA) {
+        // We ignore args.fAntiAlias here and force anti aliasing when using MSAA. Otherwise,
+        // we can wind up with external edges antialiased and internal edges unantialiased.
+        aaMode = GrDashingEffect::AAMode::kCoverageWithMSAA;
+    } else if (args.fAntiAlias) {
+        aaMode = GrDashingEffect::AAMode::kCoverage;
+    } else {
+        aaMode = GrDashingEffect::AAMode::kNone;
     }
     SkPoint pts[2];
     SkAssertResult(args.fShape->asLine(pts, nullptr));
@@ -50,7 +48,7 @@
         return false;
     }
 
-    GrPipelineBuilder pipelineBuilder(*args.fPaint, args.fAAType);
+    GrPipelineBuilder pipelineBuilder(*args.fPaint, useHWAA);
     pipelineBuilder.setUserStencil(args.fUserStencilSettings);
 
     args.fRenderTargetContext->addDrawOp(pipelineBuilder, *args.fClip, batch.get());
diff --git a/src/gpu/batches/GrDefaultPathRenderer.cpp b/src/gpu/batches/GrDefaultPathRenderer.cpp
index 0b688c5..f3f9e73 100644
--- a/src/gpu/batches/GrDefaultPathRenderer.cpp
+++ b/src/gpu/batches/GrDefaultPathRenderer.cpp
@@ -424,13 +424,11 @@
 
 bool GrDefaultPathRenderer::internalDrawPath(GrRenderTargetContext* renderTargetContext,
                                              const GrPaint& paint,
-                                             GrAAType aaType,
                                              const GrUserStencilSettings& userStencilSettings,
                                              const GrClip& clip,
                                              const SkMatrix& viewMatrix,
                                              const GrShape& shape,
                                              bool stencilOnly) {
-    SkASSERT(GrAAType::kCoverage != aaType);
     SkPath path;
     shape.asPath(&path);
 
@@ -569,20 +567,23 @@
                                                         &localMatrix));
 
             SkASSERT(GrDrawFace::kBoth == drawFace[p]);
-            GrPipelineBuilder pipelineBuilder(paint, aaType);
+            GrPipelineBuilder pipelineBuilder(paint, renderTargetContext->mustUseHWAA(paint));
             pipelineBuilder.setDrawFace(drawFace[p]);
             pipelineBuilder.setUserStencil(passes[p]);
+
             renderTargetContext->addDrawOp(pipelineBuilder, clip, batch.get());
         } else {
             sk_sp<GrDrawOp> batch(new DefaultPathBatch(paint.getColor(), path, srcSpaceTol,
                                                        newCoverage, viewMatrix, isHairline,
                                                        devBounds));
-            GrPipelineBuilder pipelineBuilder(paint, aaType);
+
+            GrPipelineBuilder pipelineBuilder(paint, renderTargetContext->mustUseHWAA(paint));
             pipelineBuilder.setDrawFace(drawFace[p]);
             pipelineBuilder.setUserStencil(passes[p]);
             if (passCount > 1) {
                 pipelineBuilder.setDisableColorXPFactory();
             }
+
             renderTargetContext->addDrawOp(pipelineBuilder, clip, batch.get());
         }
     }
@@ -590,8 +591,8 @@
 }
 
 bool GrDefaultPathRenderer::onCanDrawPath(const CanDrawPathArgs& args) const {
-    // This can draw any path with any simple fill style but doesn't do coverage-based antialiasing.
-    return GrAAType::kCoverage != args.fAAType &&
+    // this class can draw any path with any simple fill style but doesn't do any anti-aliasing.
+    return !args.fAntiAlias &&
            (args.fShape->style().isSimpleFill() ||
             IsStrokeHairlineOrEquivalent(args.fShape->style(), *args.fViewMatrix, nullptr));
 }
@@ -601,7 +602,6 @@
                               "GrDefaultPathRenderer::onDrawPath");
     return this->internalDrawPath(args.fRenderTargetContext,
                                   *args.fPaint,
-                                  args.fAAType,
                                   *args.fUserStencilSettings,
                                   *args.fClip,
                                   *args.fViewMatrix,
@@ -616,10 +616,10 @@
 
     GrPaint paint;
     paint.setXPFactory(GrDisableColorXPFactory::Make());
+    paint.setAntiAlias(args.fIsAA);
 
-    this->internalDrawPath(args.fRenderTargetContext, paint, args.fAAType,
-                           GrUserStencilSettings::kUnused, *args.fClip, *args.fViewMatrix,
-                           *args.fShape, true);
+    this->internalDrawPath(args.fRenderTargetContext, paint, GrUserStencilSettings::kUnused,
+                           *args.fClip, *args.fViewMatrix, *args.fShape, true);
 }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/src/gpu/batches/GrDefaultPathRenderer.h b/src/gpu/batches/GrDefaultPathRenderer.h
index 8e19247..243d4e7 100644
--- a/src/gpu/batches/GrDefaultPathRenderer.h
+++ b/src/gpu/batches/GrDefaultPathRenderer.h
@@ -32,7 +32,6 @@
 
     bool internalDrawPath(GrRenderTargetContext*,
                           const GrPaint&,
-                          GrAAType,
                           const GrUserStencilSettings&,
                           const GrClip&,
                           const SkMatrix& viewMatrix,
diff --git a/src/gpu/batches/GrMSAAPathRenderer.cpp b/src/gpu/batches/GrMSAAPathRenderer.cpp
index 930f7f9..f073db0 100644
--- a/src/gpu/batches/GrMSAAPathRenderer.cpp
+++ b/src/gpu/batches/GrMSAAPathRenderer.cpp
@@ -562,7 +562,6 @@
 
 bool GrMSAAPathRenderer::internalDrawPath(GrRenderTargetContext* renderTargetContext,
                                           const GrPaint& paint,
-                                          GrAAType aaType,
                                           const GrUserStencilSettings& userStencilSettings,
                                           const GrClip& clip,
                                           const SkMatrix& viewMatrix,
@@ -663,7 +662,7 @@
                     GrRectBatchFactory::CreateNonAAFill(paint.getColor(), viewM, bounds, nullptr,
                                                         &localMatrix));
 
-            GrPipelineBuilder pipelineBuilder(paint, aaType);
+            GrPipelineBuilder pipelineBuilder(paint, renderTargetContext->mustUseHWAA(paint));
             pipelineBuilder.setUserStencil(passes[p]);
 
             renderTargetContext->addDrawOp(pipelineBuilder, clip, batch.get());
@@ -674,11 +673,12 @@
                 return false;
             }
 
-            GrPipelineBuilder pipelineBuilder(paint, aaType);
+            GrPipelineBuilder pipelineBuilder(paint, renderTargetContext->mustUseHWAA(paint));
             pipelineBuilder.setUserStencil(passes[p]);
             if (passCount > 1) {
                 pipelineBuilder.setDisableColorXPFactory();
             }
+
             renderTargetContext->addDrawOp(pipelineBuilder, clip, batch.get());
         }
     }
@@ -689,7 +689,7 @@
     // This path renderer only fills and relies on MSAA for antialiasing. Stroked shapes are
     // handled by passing on the original shape and letting the caller compute the stroked shape
     // which will have a fill style.
-    return args.fShape->style().isSimpleFill() && (GrAAType::kCoverage != args.fAAType);
+    return args.fShape->style().isSimpleFill() && !args.fAntiAlias;
 }
 
 bool GrMSAAPathRenderer::onDrawPath(const DrawPathArgs& args) {
@@ -704,7 +704,6 @@
     }
     return this->internalDrawPath(args.fRenderTargetContext,
                                   *args.fPaint,
-                                  args.fAAType,
                                   *args.fUserStencilSettings,
                                   *args.fClip,
                                   *args.fViewMatrix,
@@ -720,10 +719,10 @@
 
     GrPaint paint;
     paint.setXPFactory(GrDisableColorXPFactory::Make());
+    paint.setAntiAlias(args.fIsAA);
 
-    this->internalDrawPath(args.fRenderTargetContext, paint, args.fAAType,
-                           GrUserStencilSettings::kUnused, *args.fClip, *args.fViewMatrix,
-                           *args.fShape, true);
+    this->internalDrawPath(args.fRenderTargetContext, paint, GrUserStencilSettings::kUnused,
+                           *args.fClip, *args.fViewMatrix, *args.fShape, true);
 }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/src/gpu/batches/GrMSAAPathRenderer.h b/src/gpu/batches/GrMSAAPathRenderer.h
index a112c62..3a70bcb 100644
--- a/src/gpu/batches/GrMSAAPathRenderer.h
+++ b/src/gpu/batches/GrMSAAPathRenderer.h
@@ -23,7 +23,6 @@
 
     bool internalDrawPath(GrRenderTargetContext*,
                           const GrPaint&,
-                          GrAAType,
                           const GrUserStencilSettings&,
                           const GrClip&,
                           const SkMatrix& viewMatrix,
diff --git a/src/gpu/batches/GrPLSPathRenderer.cpp b/src/gpu/batches/GrPLSPathRenderer.cpp
index 269fde1..6dd2199 100644
--- a/src/gpu/batches/GrPLSPathRenderer.cpp
+++ b/src/gpu/batches/GrPLSPathRenderer.cpp
@@ -758,7 +758,7 @@
     // seams. Disable in the presence of even-odd for now.
     SkPath path;
     args.fShape->asPath(&path);
-    return args.fShaderCaps->shaderDerivativeSupport() && GrAAType::kCoverage == args.fAAType &&
+    return args.fShaderCaps->shaderDerivativeSupport() && args.fAntiAlias &&
             args.fShape->style().isSimpleFill() && !path.isInverseFillType() &&
             path.getFillType() == SkPath::FillType::kWinding_FillType;
 }
@@ -936,10 +936,13 @@
     args.fShape->asPath(&path);
 
     sk_sp<GrDrawOp> batch(new PLSPathBatch(args.fPaint->getColor(), path, *args.fViewMatrix));
-    GrPipelineBuilder pipelineBuilder(*args.fPaint, args.fAAType);
+
+    GrPipelineBuilder pipelineBuilder(*args.fPaint,
+                                      args.fRenderTargetContext->mustUseHWAA(*args.fPaint));
     pipelineBuilder.setUserStencil(args.fUserStencilSettings);
 
     args.fRenderTargetContext->addDrawOp(pipelineBuilder, *args.fClip, batch.get());
+
     SkDEBUGCODE(inPLSDraw = false;)
     return true;
 
diff --git a/src/gpu/batches/GrStencilAndCoverPathRenderer.cpp b/src/gpu/batches/GrStencilAndCoverPathRenderer.cpp
index 9cc74ad..97287d2 100644
--- a/src/gpu/batches/GrStencilAndCoverPathRenderer.cpp
+++ b/src/gpu/batches/GrStencilAndCoverPathRenderer.cpp
@@ -44,8 +44,11 @@
     if (args.fHasUserStencilSettings) {
         return false;
     }
-    // doesn't do per-path AA, relies on the target having MSAA.
-    return (GrAAType::kCoverage != args.fAAType);
+    if (args.fAntiAlias) {
+        return args.fIsStencilBufferMSAA;
+    } else {
+        return true; // doesn't do per-path AA, relies on the target having MSAA
+    }
 }
 
 static GrPath* get_gr_path(GrResourceProvider* resourceProvider, const GrShape& shape) {
@@ -77,14 +80,18 @@
 void GrStencilAndCoverPathRenderer::onStencilPath(const StencilPathArgs& args) {
     GR_AUDIT_TRAIL_AUTO_FRAME(args.fRenderTargetContext->auditTrail(),
                               "GrStencilAndCoverPathRenderer::onStencilPath");
+    SkASSERT(!args.fIsAA || args.fRenderTargetContext->isStencilBufferMultisampled());
+
     sk_sp<GrPath> p(get_gr_path(fResourceProvider, *args.fShape));
-    args.fRenderTargetContext->priv().stencilPath(*args.fClip, args.fAAType,
+    args.fRenderTargetContext->priv().stencilPath(*args.fClip, args.fIsAA,
                                                   *args.fViewMatrix, p.get());
 }
 
 bool GrStencilAndCoverPathRenderer::onDrawPath(const DrawPathArgs& args) {
     GR_AUDIT_TRAIL_AUTO_FRAME(args.fRenderTargetContext->auditTrail(),
                               "GrStencilAndCoverPathRenderer::onDrawPath");
+    SkASSERT(!args.fPaint->isAntiAlias() ||
+             args.fRenderTargetContext->isStencilBufferMultisampled());
     SkASSERT(!args.fShape->style().strokeRec().isHairlineStyle());
 
     const SkMatrix& viewMatrix = *args.fViewMatrix;
@@ -118,8 +125,8 @@
                                                     nullptr, &invert));
 
         // fake inverse with a stencil and cover
-        args.fRenderTargetContext->priv().stencilPath(*args.fClip, args.fAAType, viewMatrix,
-                                                      path.get());
+        args.fRenderTargetContext->priv().stencilPath(*args.fClip, args.fPaint->isAntiAlias(),
+                                                      viewMatrix, path.get());
 
         {
             static constexpr GrUserStencilSettings kInvertedCoverPass(
@@ -135,11 +142,9 @@
                     0xffff>()
             );
 
-            GrAAType aaType = args.fAAType;
-            if (args.fRenderTargetContext->hasMixedSamples()) {
-                aaType = GrAAType::kNone;
-            }
-            GrPipelineBuilder pipelineBuilder(*args.fPaint, aaType);
+            GrPipelineBuilder pipelineBuilder(*args.fPaint,
+                                              args.fPaint->isAntiAlias() &&
+                                              !args.fRenderTargetContext->hasMixedSamples());
             pipelineBuilder.setUserStencil(&kInvertedCoverPass);
 
             args.fRenderTargetContext->addDrawOp(pipelineBuilder, *args.fClip, coverBatch.get());
@@ -158,8 +163,13 @@
         sk_sp<GrDrawOp> batch(GrDrawPathBatch::Create(viewMatrix, args.fPaint->getColor(),
                                                       path.get()));
 
-        GrPipelineBuilder pipelineBuilder(*args.fPaint, args.fAAType);
+        GrPipelineBuilder pipelineBuilder(*args.fPaint, args.fPaint->isAntiAlias());
         pipelineBuilder.setUserStencil(&kCoverPass);
+        if (args.fAntiAlias) {
+            SkASSERT(args.fRenderTargetContext->isStencilBufferMultisampled());
+            pipelineBuilder.enableState(GrPipelineBuilder::kHWAntialias_Flag);
+        }
+
         args.fRenderTargetContext->addDrawOp(pipelineBuilder, *args.fClip, batch.get());
     }
 
diff --git a/src/gpu/batches/GrTessellatingPathRenderer.cpp b/src/gpu/batches/GrTessellatingPathRenderer.cpp
index 3fa92c6..86cf883 100644
--- a/src/gpu/batches/GrTessellatingPathRenderer.cpp
+++ b/src/gpu/batches/GrTessellatingPathRenderer.cpp
@@ -140,7 +140,7 @@
     if (!args.fShape->style().isSimpleFill() || args.fShape->knownToBeConvex()) {
         return false;
     }
-    if (GrAAType::kCoverage == args.fAAType) {
+    if (args.fAntiAlias) {
 #ifdef SK_DISABLE_SCREENSPACE_TESS_AA_PATH_RENDERER
         return false;
 #else
@@ -364,10 +364,14 @@
                                                         *args.fShape,
                                                         *args.fViewMatrix,
                                                         clipBoundsI,
-                                                        GrAAType::kCoverage == args.fAAType));
-    GrPipelineBuilder pipelineBuilder(*args.fPaint, args.fAAType);
+                                                        args.fAntiAlias));
+
+    GrPipelineBuilder pipelineBuilder(*args.fPaint,
+                                      args.fRenderTargetContext->mustUseHWAA(*args.fPaint));
     pipelineBuilder.setUserStencil(args.fUserStencilSettings);
+
     args.fRenderTargetContext->addDrawOp(pipelineBuilder, *args.fClip, batch.get());
+
     return true;
 }
 
diff --git a/src/gpu/effects/GrConfigConversionEffect.cpp b/src/gpu/effects/GrConfigConversionEffect.cpp
index f6f8334..f700312 100644
--- a/src/gpu/effects/GrConfigConversionEffect.cpp
+++ b/src/gpu/effects/GrConfigConversionEffect.cpp
@@ -237,19 +237,19 @@
         paint1.addColorFragmentProcessor(std::move(pmToUPM1));
         paint1.setPorterDuffXPFactory(SkBlendMode::kSrc);
 
-        readRTC->fillRectToRect(GrNoClip(), paint1, GrAA::kNo, SkMatrix::I(), kDstRect, kSrcRect);
+        readRTC->fillRectToRect(GrNoClip(), paint1, SkMatrix::I(), kDstRect, kSrcRect);
 
         readRTC->asTexture()->readPixels(0, 0, kSize, kSize, kConfig, firstRead);
 
         paint2.addColorFragmentProcessor(std::move(upmToPM));
         paint2.setPorterDuffXPFactory(SkBlendMode::kSrc);
 
-        tempRTC->fillRectToRect(GrNoClip(), paint2, GrAA::kNo, SkMatrix::I(), kDstRect, kSrcRect);
+        tempRTC->fillRectToRect(GrNoClip(), paint2, SkMatrix::I(), kDstRect, kSrcRect);
 
         paint3.addColorFragmentProcessor(std::move(pmToUPM2));
         paint3.setPorterDuffXPFactory(SkBlendMode::kSrc);
 
-        readRTC->fillRectToRect(GrNoClip(), paint3, GrAA::kNo, SkMatrix::I(), kDstRect, kSrcRect);
+        readRTC->fillRectToRect(GrNoClip(), paint3, SkMatrix::I(), kDstRect, kSrcRect);
 
         readRTC->asTexture()->readPixels(0, 0, kSize, kSize, kConfig, secondRead);
 
diff --git a/src/gpu/instanced/InstancedRendering.cpp b/src/gpu/instanced/InstancedRendering.cpp
index 2c46d15..135a061 100644
--- a/src/gpu/instanced/InstancedRendering.cpp
+++ b/src/gpu/instanced/InstancedRendering.cpp
@@ -22,27 +22,28 @@
 }
 
 GrDrawOp* InstancedRendering::recordRect(const SkRect& rect, const SkMatrix& viewMatrix,
-                                         GrColor color, GrAA aa,
-                                         const GrInstancedPipelineInfo& info, GrAAType* aaType) {
-    return this->recordShape(ShapeType::kRect, rect, viewMatrix, color, rect, aa, info, aaType);
+                                         GrColor color, bool antialias,
+                                         const GrInstancedPipelineInfo& info, bool* useHWAA) {
+    return this->recordShape(ShapeType::kRect, rect, viewMatrix, color, rect, antialias, info,
+                             useHWAA);
 }
 
 GrDrawOp* InstancedRendering::recordRect(const SkRect& rect, const SkMatrix& viewMatrix,
-                                         GrColor color, const SkRect& localRect, GrAA aa,
-                                         const GrInstancedPipelineInfo& info, GrAAType* aaType) {
-    return this->recordShape(ShapeType::kRect, rect, viewMatrix, color, localRect, aa, info,
-                             aaType);
+                                         GrColor color, const SkRect& localRect, bool antialias,
+                                         const GrInstancedPipelineInfo& info, bool* useHWAA) {
+    return this->recordShape(ShapeType::kRect, rect, viewMatrix, color, localRect, antialias, info,
+                             useHWAA);
 }
 
 GrDrawOp* InstancedRendering::recordRect(const SkRect& rect, const SkMatrix& viewMatrix,
                                          GrColor color, const SkMatrix& localMatrix,
-                                         GrAA aa, const GrInstancedPipelineInfo& info,
-                                         GrAAType* aaType) {
+                                         bool antialias, const GrInstancedPipelineInfo& info,
+                                         bool* useHWAA) {
     if (localMatrix.hasPerspective()) {
         return nullptr; // Perspective is not yet supported in the local matrix.
     }
-    if (Batch* batch = this->recordShape(ShapeType::kRect, rect, viewMatrix, color, rect, aa,
-                                         info, aaType)) {
+    if (Batch* batch = this->recordShape(ShapeType::kRect, rect, viewMatrix, color, rect, antialias,
+                                         info, useHWAA)) {
         batch->getSingleInstance().fInfo |= kLocalMatrix_InfoFlag;
         batch->appendParamsTexel(localMatrix.getScaleX(), localMatrix.getSkewX(),
                                  localMatrix.getTranslateX());
@@ -55,16 +56,17 @@
 }
 
 GrDrawOp* InstancedRendering::recordOval(const SkRect& oval, const SkMatrix& viewMatrix,
-                                         GrColor color, GrAA aa,
-                                         const GrInstancedPipelineInfo& info, GrAAType* aaType) {
-    return this->recordShape(ShapeType::kOval, oval, viewMatrix, color, oval, aa, info, aaType);
+                                         GrColor color, bool antialias,
+                                         const GrInstancedPipelineInfo& info, bool* useHWAA) {
+    return this->recordShape(ShapeType::kOval, oval, viewMatrix, color, oval, antialias, info,
+                             useHWAA);
 }
 
 GrDrawOp* InstancedRendering::recordRRect(const SkRRect& rrect, const SkMatrix& viewMatrix,
-                                          GrColor color, GrAA aa,
-                                          const GrInstancedPipelineInfo& info, GrAAType* aaType) {
+                                          GrColor color, bool antialias,
+                                          const GrInstancedPipelineInfo& info, bool* useHWAA) {
     if (Batch* batch = this->recordShape(GetRRectShapeType(rrect), rrect.rect(), viewMatrix, color,
-                                         rrect.rect(), aa, info, aaType)) {
+                                         rrect.rect(), antialias, info, useHWAA)) {
         batch->appendRRectParams(rrect);
         return batch;
     }
@@ -73,16 +75,16 @@
 
 GrDrawOp* InstancedRendering::recordDRRect(const SkRRect& outer, const SkRRect& inner,
                                            const SkMatrix& viewMatrix, GrColor color,
-                                           GrAA aa, const GrInstancedPipelineInfo& info,
-                                           GrAAType* aaType) {
+                                           bool antialias, const GrInstancedPipelineInfo& info,
+                                           bool* useHWAA) {
     if (inner.getType() > SkRRect::kSimple_Type) {
        return nullptr; // Complex inner round rects are not yet supported.
     }
     if (SkRRect::kEmpty_Type == inner.getType()) {
-        return this->recordRRect(outer, viewMatrix, color, aa, info, aaType);
+        return this->recordRRect(outer, viewMatrix, color, antialias, info, useHWAA);
     }
     if (Batch* batch = this->recordShape(GetRRectShapeType(outer), outer.rect(), viewMatrix, color,
-                                         outer.rect(), aa, info, aaType)) {
+                                         outer.rect(), antialias, info, useHWAA)) {
         batch->appendRRectParams(outer);
         ShapeType innerShapeType = GetRRectShapeType(inner);
         batch->fInfo.fInnerShapeTypes |= GetShapeFlag(innerShapeType);
@@ -97,9 +99,9 @@
 InstancedRendering::Batch* InstancedRendering::recordShape(ShapeType type, const SkRect& bounds,
                                                            const SkMatrix& viewMatrix,
                                                            GrColor color, const SkRect& localRect,
-                                                           GrAA aa,
+                                                           bool antialias,
                                                            const GrInstancedPipelineInfo& info,
-                                                           GrAAType* aaType) {
+                                                           bool* useHWAA) {
     SkASSERT(State::kRecordingDraws == fState);
 
     if (info.fIsRenderingToFloat && fGpu->caps()->avoidInstancedDrawsToFPTargets()) {
@@ -107,7 +109,7 @@
     }
 
     AntialiasMode antialiasMode;
-    if (!this->selectAntialiasMode(viewMatrix, aa, info, aaType, &antialiasMode)) {
+    if (!this->selectAntialiasMode(viewMatrix, antialias, info, useHWAA, &antialiasMode)) {
         return nullptr;
     }
 
@@ -191,28 +193,27 @@
     return batch;
 }
 
-inline bool InstancedRendering::selectAntialiasMode(const SkMatrix& viewMatrix, GrAA aa,
+inline bool InstancedRendering::selectAntialiasMode(const SkMatrix& viewMatrix, bool antialias,
                                                     const GrInstancedPipelineInfo& info,
-                                                    GrAAType* aaType,
-                                                    AntialiasMode* antialiasMode) {
+                                                    bool* useHWAA, AntialiasMode* antialiasMode) {
     SkASSERT(!info.fColorDisabled || info.fDrawingShapeToStencil);
     SkASSERT(!info.fIsMixedSampled || info.fIsMultisampled);
     SkASSERT(GrCaps::InstancedSupport::kNone != fGpu->caps()->instancedSupport());
 
     if (!info.fIsMultisampled || fGpu->caps()->multisampleDisableSupport()) {
-        if (GrAA::kNo == aa) {
+        if (!antialias) {
             if (info.fDrawingShapeToStencil && !info.fCanDiscard) {
                 // We can't draw to the stencil buffer without discard (or sample mask if MSAA).
                 return false;
             }
             *antialiasMode = AntialiasMode::kNone;
-            *aaType = GrAAType::kNone;
+            *useHWAA = false;
             return true;
         }
 
         if (info.canUseCoverageAA() && viewMatrix.preservesRightAngles()) {
             *antialiasMode = AntialiasMode::kCoverage;
-            *aaType = GrAAType::kCoverage;
+            *useHWAA = false;
             return true;
         }
     }
@@ -221,12 +222,12 @@
         fGpu->caps()->instancedSupport() >= GrCaps::InstancedSupport::kMultisampled) {
         if (!info.fIsMixedSampled || info.fColorDisabled) {
             *antialiasMode = AntialiasMode::kMSAA;
-            *aaType = GrAAType::kHW;
+            *useHWAA = true;
             return true;
         }
         if (fGpu->caps()->instancedSupport() >= GrCaps::InstancedSupport::kMixedSampled) {
             *antialiasMode = AntialiasMode::kMixedSamples;
-            *aaType = GrAAType::kHW;
+            *useHWAA = true;
             return true;
         }
     }
diff --git a/src/gpu/instanced/InstancedRendering.h b/src/gpu/instanced/InstancedRendering.h
index 9036974..d3a0152 100644
--- a/src/gpu/instanced/InstancedRendering.h
+++ b/src/gpu/instanced/InstancedRendering.h
@@ -46,25 +46,28 @@
      * draws between beginFlush() and endFlush().
      */
     GrDrawOp* SK_WARN_UNUSED_RESULT recordRect(const SkRect&, const SkMatrix&, GrColor,
-                                               GrAA, const GrInstancedPipelineInfo&, GrAAType*);
+                                               bool antialias, const GrInstancedPipelineInfo&,
+                                               bool* useHWAA);
 
     GrDrawOp* SK_WARN_UNUSED_RESULT recordRect(const SkRect&, const SkMatrix&, GrColor,
-                                               const SkRect& localRect, GrAA,
-                                               const GrInstancedPipelineInfo&, GrAAType*);
+                                               const SkRect& localRect, bool antialias,
+                                               const GrInstancedPipelineInfo&, bool* useHWAA);
 
     GrDrawOp* SK_WARN_UNUSED_RESULT recordRect(const SkRect&, const SkMatrix&, GrColor,
-                                               const SkMatrix& localMatrix, GrAA,
-                                               const GrInstancedPipelineInfo&, GrAAType*);
+                                               const SkMatrix& localMatrix, bool antialias,
+                                               const GrInstancedPipelineInfo&, bool* useHWAA);
 
     GrDrawOp* SK_WARN_UNUSED_RESULT recordOval(const SkRect&, const SkMatrix&, GrColor,
-                                               GrAA, const GrInstancedPipelineInfo&, GrAAType*);
+                                               bool antialias, const GrInstancedPipelineInfo&,
+                                               bool* useHWAA);
 
     GrDrawOp* SK_WARN_UNUSED_RESULT recordRRect(const SkRRect&, const SkMatrix&, GrColor,
-                                                GrAA, const GrInstancedPipelineInfo&, GrAAType*);
+                                                bool antialias, const GrInstancedPipelineInfo&,
+                                                bool* useHWAA);
 
     GrDrawOp* SK_WARN_UNUSED_RESULT recordDRRect(const SkRRect& outer, const SkRRect& inner,
-                                                 const SkMatrix&, GrColor, GrAA,
-                                                 const GrInstancedPipelineInfo&, GrAAType*);
+                                                 const SkMatrix&, GrColor, bool antialias,
+                                                 const GrInstancedPipelineInfo&, bool* useHWAA);
 
     /**
      * Compiles all recorded draws into GPU buffers and allows the client to begin flushing the
@@ -179,11 +182,11 @@
 
     Batch* SK_WARN_UNUSED_RESULT recordShape(ShapeType, const SkRect& bounds,
                                              const SkMatrix& viewMatrix, GrColor,
-                                             const SkRect& localRect, GrAA aa,
-                                             const GrInstancedPipelineInfo&, GrAAType*);
+                                             const SkRect& localRect, bool antialias,
+                                             const GrInstancedPipelineInfo&, bool* requireHWAA);
 
-    bool selectAntialiasMode(const SkMatrix& viewMatrix, GrAA aa, const GrInstancedPipelineInfo&,
-                             GrAAType*, AntialiasMode*);
+    bool selectAntialiasMode(const SkMatrix& viewMatrix, bool antialias,
+                             const GrInstancedPipelineInfo&, bool* useHWAA, AntialiasMode*);
 
     virtual Batch* createBatch() = 0;
 
diff --git a/src/gpu/text/GrAtlasTextBlob.cpp b/src/gpu/text/GrAtlasTextBlob.cpp
index 10f563a..5b35f84 100644
--- a/src/gpu/text/GrAtlasTextBlob.cpp
+++ b/src/gpu/text/GrAtlasTextBlob.cpp
@@ -323,9 +323,8 @@
                                                 distanceAdjustTable,
                                                 rtc->isGammaCorrect(),
                                                 cache));
-        GrAAType aaType = skPaint.isAntiAlias() && rtc->isUnifiedMultisampled() ? GrAAType::kHW
-                                                                                : GrAAType::kNone;
-        GrPipelineBuilder pipelineBuilder(grPaint, aaType);
+
+        GrPipelineBuilder pipelineBuilder(grPaint, rtc->mustUseHWAA(grPaint));
 
         rtc->addDrawOp(pipelineBuilder, clip, batch.get());
     }
diff --git a/src/gpu/text/GrStencilAndCoverTextContext.cpp b/src/gpu/text/GrStencilAndCoverTextContext.cpp
index b4e087f..ba98784 100644
--- a/src/gpu/text/GrStencilAndCoverTextContext.cpp
+++ b/src/gpu/text/GrStencilAndCoverTextContext.cpp
@@ -224,8 +224,10 @@
 
     TextBlob::Iter iter(blob);
     for (TextRun* run = iter.get(); run; run = iter.next()) {
-        run->draw(context, rtc, paint, clip, viewMatrix, props,  x, y, clipBounds,
-                  fFallbackTextContext, skPaint);
+        // The run's "font" overrides the anti-aliasing of the passed in paint!
+        paint.setAntiAlias(run->isAntiAlias());
+        run->draw(context, rtc, paint, clip, viewMatrix, props,  x, y,
+                  clipBounds, fFallbackTextContext, skPaint);
         run->releaseGlyphCache();
     }
 }
@@ -603,9 +605,8 @@
                                                  const SkIRect& clipBounds,
                                                  GrAtlasTextContext* fallbackTextContext,
                                                  const SkPaint& originalSkPaint) const {
-    GrAA runAA = this->isAntiAlias();
     SkASSERT(fInstanceData);
-    SkASSERT(renderTargetContext->isStencilBufferMultisampled() || GrAA::kNo == runAA);
+    SkASSERT(renderTargetContext->isStencilBufferMultisampled() || !grPaint.isAntiAlias());
 
     if (fInstanceData->count()) {
         static constexpr GrUserStencilSettings kCoverPass(
@@ -639,11 +640,8 @@
                                          GrPathRendering::kWinding_FillType, glyphs.get(),
                                          fInstanceData.get(), bounds));
 
-        // The run's "font" overrides the anti-aliasing of the passed in SkPaint!
-        GrAAType aaType = renderTargetContext->isStencilBufferMultisampled() && GrAA::kYes == runAA
-                ? GrAAType::kHW
-                : GrAAType::kNone;
-        GrPipelineBuilder pipelineBuilder(grPaint, aaType);
+        GrPipelineBuilder pipelineBuilder(grPaint);
+        pipelineBuilder.setState(GrPipelineBuilder::kHWAntialias_Flag, grPaint.isAntiAlias());
         pipelineBuilder.setUserStencil(&kCoverPass);
 
         renderTargetContext->addDrawOp(pipelineBuilder, clip, batch.get());
diff --git a/src/gpu/text/GrStencilAndCoverTextContext.h b/src/gpu/text/GrStencilAndCoverTextContext.h
index 1ba113b..f4773ff 100644
--- a/src/gpu/text/GrStencilAndCoverTextContext.h
+++ b/src/gpu/text/GrStencilAndCoverTextContext.h
@@ -88,7 +88,7 @@
 
         size_t computeSizeInCache() const;
 
-        GrAA isAntiAlias() const { return fFont.isAntiAlias() ? GrAA::kYes : GrAA::kNo; }
+        bool isAntiAlias() const { return fFont.isAntiAlias(); }
 
     private:
         typedef GrDrawPathRangeBatch::InstanceData InstanceData;
diff --git a/src/image/SkImage_Gpu.cpp b/src/image/SkImage_Gpu.cpp
index de13dab..07d352a 100644
--- a/src/image/SkImage_Gpu.cpp
+++ b/src/image/SkImage_Gpu.cpp
@@ -277,7 +277,7 @@
 
     const SkRect rect = SkRect::MakeWH(SkIntToScalar(width), SkIntToScalar(height));
 
-    renderTargetContext->drawRect(GrNoClip(), paint, GrAA::kNo, SkMatrix::I(), rect);
+    renderTargetContext->drawRect(GrNoClip(), paint, SkMatrix::I(), rect);
 
     if (!renderTargetContext->accessRenderTarget()) {
         return nullptr;
diff --git a/tests/DFPathRendererTest.cpp b/tests/DFPathRendererTest.cpp
index e473434..327640c 100644
--- a/tests/DFPathRendererTest.cpp
+++ b/tests/DFPathRendererTest.cpp
@@ -53,7 +53,7 @@
     args.fResourceProvider = rp;
     args.fViewMatrix = &matrix;
     args.fShape = &shape;
-    args.fAAType = GrAAType::kCoverage;
+    args.fAntiAlias = true;
     args.fGammaCorrect = false;
     pr->drawPath(args);
 }
diff --git a/tests/GLProgramsTest.cpp b/tests/GLProgramsTest.cpp
index 0905505..cf4095a 100644
--- a/tests/GLProgramsTest.cpp
+++ b/tests/GLProgramsTest.cpp
@@ -255,6 +255,9 @@
     if (random->nextBool()) {
         paint->setAllowSRGBInputs(true);
     }
+    if (random->nextBool()) {
+        paint->setAntiAlias(true);
+    }
     return random->nextBool();
 }
 
@@ -336,12 +339,8 @@
         set_random_xpf(&grPaint, &ptd);
         bool snapToCenters = set_random_state(&grPaint, &random);
         const GrUserStencilSettings* uss = get_random_stencil(&random);
-        static constexpr GrAAType kAATypes[] = {GrAAType::kNone, GrAAType::kCoverage,
-                                                GrAAType::kHW};
-        GrAAType aaType = kAATypes[random.nextULessThan(SK_ARRAY_COUNT(kAATypes))];
 
-        renderTargetContext->priv().testingOnly_drawBatch(grPaint, aaType, batch.get(), uss,
-                                                          snapToCenters);
+        renderTargetContext->priv().testingOnly_drawBatch(grPaint, batch.get(), uss, snapToCenters);
     }
     // Flush everything, test passes if flush is successful(ie, no asserts are hit, no crashes)
     drawingManager->flush();
@@ -375,8 +374,7 @@
                 BlockInputFragmentProcessor::Make(std::move(fp)));
             grPaint.addColorFragmentProcessor(std::move(blockFP));
 
-            renderTargetContext->priv().testingOnly_drawBatch(grPaint, GrAAType::kNone,
-                                                              batch.get());
+            renderTargetContext->priv().testingOnly_drawBatch(grPaint, batch.get());
             drawingManager->flush();
         }
     }
diff --git a/tests/GpuSampleLocationsTest.cpp b/tests/GpuSampleLocationsTest.cpp
index 3a59e9d..31ada9d 100644
--- a/tests/GpuSampleLocationsTest.cpp
+++ b/tests/GpuSampleLocationsTest.cpp
@@ -14,7 +14,6 @@
 
 #include "GrRenderTargetContext.h"
 #include "GrRenderTargetPriv.h"
-#include "GrTypesPriv.h"
 #include "GrPipelineBuilder.h"
 #include "gl/GrGLGpu.h"
 #include "gl/debug/DebugGLTestContext.h"
@@ -91,7 +90,7 @@
 };
 
 static GrPipeline* construct_dummy_pipeline(GrRenderTargetContext* dc, void* storage) {
-    GrPipelineBuilder dummyBuilder(GrPaint(), GrAAType::kNone);
+    GrPipelineBuilder dummyBuilder;
     GrScissorState dummyScissor;
     GrWindowRectsState dummyWindows;
     GrXPOverridesForBatch dummyOverrides;
diff --git a/tests/PrimitiveProcessorTest.cpp b/tests/PrimitiveProcessorTest.cpp
index 17ce369..816b4e4 100644
--- a/tests/PrimitiveProcessorTest.cpp
+++ b/tests/PrimitiveProcessorTest.cpp
@@ -127,7 +127,7 @@
     GrPaint grPaint;
     // This one should succeed.
     batch.reset(new Batch(attribCnt));
-    renderTargetContext->priv().testingOnly_drawBatch(grPaint, GrAAType::kNone, batch.get());
+    renderTargetContext->priv().testingOnly_drawBatch(grPaint, batch.get());
     context->flush();
 #if GR_GPU_STATS
     REPORTER_ASSERT(reporter, context->getGpu()->stats()->numDraws() == 1);
@@ -136,7 +136,7 @@
     context->resetGpuStats();
     // This one should fail.
     batch.reset(new Batch(attribCnt+1));
-    renderTargetContext->priv().testingOnly_drawBatch(grPaint, GrAAType::kNone, batch.get());
+    renderTargetContext->priv().testingOnly_drawBatch(grPaint, batch.get());
     context->flush();
 #if GR_GPU_STATS
     REPORTER_ASSERT(reporter, context->getGpu()->stats()->numDraws() == 0);
diff --git a/tests/SRGBMipMapTest.cpp b/tests/SRGBMipMapTest.cpp
index afe8167..b963aaf 100644
--- a/tests/SRGBMipMapTest.cpp
+++ b/tests/SRGBMipMapTest.cpp
@@ -136,13 +136,13 @@
 
     // 1) Draw texture to S32 surface (should generate/use sRGB mips)
     paint.setGammaCorrect(true);
-    s32RenderTargetContext->drawRect(noClip, paint, GrAA::kNo, SkMatrix::I(), rect);
+    s32RenderTargetContext->drawRect(noClip, paint, SkMatrix::I(), rect);
     read_and_check_pixels(reporter, s32RenderTargetContext->asTexture().get(), expectedSRGB, error,
                           "first render of sRGB");
 
     // 2) Draw texture to L32 surface (should generate/use linear mips)
     paint.setGammaCorrect(false);
-    l32RenderTargetContext->drawRect(noClip, paint, GrAA::kNo, SkMatrix::I(), rect);
+    l32RenderTargetContext->drawRect(noClip, paint, SkMatrix::I(), rect);
 
     // Right now, this test only runs on GL (because Vulkan doesn't support legacy mip-mapping
     // skbug.com/5048). On GL, we may not have sRGB decode support. In that case, rendering sRGB
@@ -162,7 +162,7 @@
 
     // 3) Go back to sRGB
     paint.setGammaCorrect(true);
-    s32RenderTargetContext->drawRect(noClip, paint, GrAA::kNo, SkMatrix::I(), rect);
+    s32RenderTargetContext->drawRect(noClip, paint, SkMatrix::I(), rect);
     read_and_check_pixels(reporter, s32RenderTargetContext->asTexture().get(), expectedSRGB, error,
                           "re-render as sRGB");
 }
diff --git a/tests/TessellatingPathRendererTests.cpp b/tests/TessellatingPathRendererTests.cpp
index 51b8c5e..db3b5ea 100644
--- a/tests/TessellatingPathRendererTests.cpp
+++ b/tests/TessellatingPathRendererTests.cpp
@@ -267,7 +267,7 @@
     args.fViewMatrix = &SkMatrix::I();
     GrShape shape(path, style);
     args.fShape = &shape;
-    args.fAAType = GrAAType::kNone;
+    args.fAntiAlias = false;
     tess.drawPath(args);
 }
 
diff --git a/tools/gpu/GrTest.cpp b/tools/gpu/GrTest.cpp
index 4327773..8ab4c9b 100644
--- a/tools/gpu/GrTest.cpp
+++ b/tools/gpu/GrTest.cpp
@@ -160,7 +160,7 @@
 
     grPaint.addColorTextureProcessor(tex, nullptr, textureMat);
 
-    fRenderTargetContext->drawRect(GrNoClip(), grPaint, GrAA::kNo, mat, dst);
+    fRenderTargetContext->drawRect(GrNoClip(), grPaint, mat, dst);
 }
 
 
@@ -244,7 +244,6 @@
 #define RETURN_IF_ABANDONED        if (fRenderTargetContext->fDrawingManager->wasAbandoned()) { return; }
 
 void GrRenderTargetContextPriv::testingOnly_drawBatch(const GrPaint& paint,
-                                                      GrAAType aaType,
                                                       GrDrawOp* batch,
                                                       const GrUserStencilSettings* uss,
                                                       bool snapToCenters) {
@@ -254,7 +253,7 @@
     GR_AUDIT_TRAIL_AUTO_FRAME(fRenderTargetContext->fAuditTrail,
                               "GrRenderTargetContext::testingOnly_drawBatch");
 
-    GrPipelineBuilder pipelineBuilder(paint, aaType);
+    GrPipelineBuilder pipelineBuilder(paint, fRenderTargetContext->mustUseHWAA(paint));
     if (uss) {
         pipelineBuilder.setUserStencil(uss);
     }