Use GrShape in GrPathRenderer.
authorbsalomon <bsalomon@google.com>
Fri, 24 Jun 2016 17:42:16 +0000 (10:42 -0700)
committerCommit bot <commit-bot@chromium.org>
Fri, 24 Jun 2016 17:42:16 +0000 (10:42 -0700)
GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=2081383006

Review-Url: https://codereview.chromium.org/2081383006

26 files changed:
src/gpu/GrClipMaskManager.cpp
src/gpu/GrDrawContext.cpp
src/gpu/GrPathRenderer.h
src/gpu/GrPathRendererChain.cpp
src/gpu/GrSWMaskHelper.cpp
src/gpu/GrSWMaskHelper.h
src/gpu/GrSoftwarePathRenderer.cpp
src/gpu/GrSoftwarePathRenderer.h
src/gpu/GrStyle.h
src/gpu/batches/GrAAConvexPathRenderer.cpp
src/gpu/batches/GrAADistanceFieldPathRenderer.cpp
src/gpu/batches/GrAADistanceFieldPathRenderer.h
src/gpu/batches/GrAAHairLinePathRenderer.cpp
src/gpu/batches/GrAALinearizingConvexPathRenderer.cpp
src/gpu/batches/GrDashLinePathRenderer.cpp
src/gpu/batches/GrDashLinePathRenderer.h
src/gpu/batches/GrDefaultPathRenderer.cpp
src/gpu/batches/GrDefaultPathRenderer.h
src/gpu/batches/GrMSAAPathRenderer.cpp
src/gpu/batches/GrMSAAPathRenderer.h
src/gpu/batches/GrPLSPathRenderer.cpp
src/gpu/batches/GrStencilAndCoverPathRenderer.cpp
src/gpu/batches/GrStencilAndCoverPathRenderer.h
src/gpu/batches/GrTessellatingPathRenderer.cpp
src/gpu/batches/GrTessellatingPathRenderer.h
tests/TessellatingPathRendererTests.cpp

index 2047f6f..e5f1330 100644 (file)
@@ -91,11 +91,11 @@ bool GrClipMaskManager::PathNeedsSWRenderer(GrContext* context,
                             : GrPathRendererChain::kColor_DrawType;
         }
 
+        GrShape shape(path, GrStyle::SimpleFill());
         GrPathRenderer::CanDrawPathArgs canDrawArgs;
         canDrawArgs.fShaderCaps = context->caps()->shaderCaps();
         canDrawArgs.fViewMatrix = &viewMatrix;
-        canDrawArgs.fPath = &path;
-        canDrawArgs.fStyle = &GrStyle::SimpleFill();
+        canDrawArgs.fShape = &shape;
         canDrawArgs.fAntiAlias = element->isAA();
         canDrawArgs.fHasUserStencilSettings = hasUserStencilSettings;
         canDrawArgs.fIsStencilBufferMSAA = drawContext->isStencilBufferMultisampled();
@@ -615,11 +615,11 @@ bool GrClipMaskManager::CreateStencilClipMask(GrContext* context,
                     clipPath.toggleInverseFillType();
                 }
 
+                GrShape shape(clipPath, GrStyle::SimpleFill());
                 GrPathRenderer::CanDrawPathArgs canDrawArgs;
                 canDrawArgs.fShaderCaps = context->caps()->shaderCaps();
                 canDrawArgs.fViewMatrix = &viewMatrix;
-                canDrawArgs.fPath = &clipPath;
-                canDrawArgs.fStyle = &GrStyle::SimpleFill();
+                canDrawArgs.fShape = &shape;
                 canDrawArgs.fAntiAlias = false;
                 canDrawArgs.fHasUserStencilSettings = false;
                 canDrawArgs.fIsStencilBufferMSAA = drawContext->isStencilBufferMultisampled();
@@ -658,6 +658,7 @@ bool GrClipMaskManager::CreateStencilClipMask(GrContext* context,
                                                                viewMatrix, element->getRect());
                 } else {
                     if (!clipPath.isEmpty()) {
+                        GrShape shape(clipPath, GrStyle::SimpleFill());
                         if (canRenderDirectToStencil) {
                             GrPaint paint;
                             paint.setXPFactory(GrDisableColorXPFactory::Make());
@@ -671,8 +672,7 @@ bool GrClipMaskManager::CreateStencilClipMask(GrContext* context,
                             args.fClip = &clip;
                             args.fColor = GrColor_WHITE;
                             args.fViewMatrix = &viewMatrix;
-                            args.fPath = &clipPath;
-                            args.fStyle = &GrStyle::SimpleFill();
+                            args.fShape = &shape;
                             args.fAntiAlias = false;
                             args.fGammaCorrect = false;
                             pr->drawPath(args);
@@ -682,8 +682,8 @@ bool GrClipMaskManager::CreateStencilClipMask(GrContext* context,
                             args.fDrawContext = drawContext;
                             args.fClip = &clip;
                             args.fViewMatrix = &viewMatrix;
-                            args.fPath = &clipPath;
                             args.fIsAA = element->isAA();
+                            args.fShape = &shape;
                             pr->stencilPath(args);
                         }
                     }
@@ -700,10 +700,10 @@ bool GrClipMaskManager::CreateStencilClipMask(GrContext* context,
                         drawContext->drawContextPriv().stencilRect(clip, *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;
@@ -712,8 +712,7 @@ bool GrClipMaskManager::CreateStencilClipMask(GrContext* context,
                         args.fClip = &clip;
                         args.fColor = GrColor_WHITE;
                         args.fViewMatrix = &viewMatrix;
-                        args.fPath = &clipPath;
-                        args.fStyle = &GrStyle::SimpleFill();
+                        args.fShape = &shape;
                         args.fAntiAlias = false;
                         args.fGammaCorrect = false;
                         pr->drawPath(args);
@@ -775,8 +774,8 @@ sk_sp<GrTexture> GrClipMaskManager::CreateSoftwareClipMask(
             SkPath clipPath;
             element->asPath(&clipPath);
             clipPath.toggleInverseFillType();
-            helper.drawPath(clipPath, GrStyle::SimpleFill(), SkRegion::kReplace_Op,
-                            element->isAA(), 0x00);
+            GrShape shape(clipPath, GrStyle::SimpleFill());
+            helper.drawShape(shape, SkRegion::kReplace_Op, element->isAA(), 0x00);
             continue;
         }
 
@@ -787,7 +786,8 @@ sk_sp<GrTexture> GrClipMaskManager::CreateSoftwareClipMask(
         } else {
             SkPath path;
             element->asPath(&path);
-            helper.drawPath(path, GrStyle::SimpleFill(), op, element->isAA(), 0xFF);
+            GrShape shape(path, GrStyle::SimpleFill());
+            helper.drawShape(shape, op, element->isAA(), 0xFF);
         }
     }
 
index b5489f1..7ee4e62 100644 (file)
@@ -925,11 +925,11 @@ bool GrDrawContextPriv::drawAndStencilPath(const GrFixedClip& clip,
         useCoverageAA ? GrPathRendererChain::kColorAntiAlias_DrawType
                       : GrPathRendererChain::kColor_DrawType;
 
+    GrShape shape(path, GrStyle::SimpleFill());
     GrPathRenderer::CanDrawPathArgs canDrawArgs;
     canDrawArgs.fShaderCaps = fDrawContext->fDrawingManager->getContext()->caps()->shaderCaps();
     canDrawArgs.fViewMatrix = &viewMatrix;
-    canDrawArgs.fPath = &path;
-    canDrawArgs.fStyle = &GrStyle::SimpleFill();
+    canDrawArgs.fShape = &shape;
     canDrawArgs.fAntiAlias = useCoverageAA;
     canDrawArgs.fHasUserStencilSettings = hasUserStencilSettings;
     canDrawArgs.fIsStencilBufferMSAA = isStencilBufferMSAA;
@@ -951,8 +951,7 @@ bool GrDrawContextPriv::drawAndStencilPath(const GrFixedClip& clip,
     args.fClip = &clip;
     args.fColor = GrColor_WHITE;
     args.fViewMatrix = &viewMatrix;
-    args.fPath = &path;
-    args.fStyle = &GrStyle::SimpleFill();
+    args.fShape = &shape;
     args.fAntiAlias = useCoverageAA;
     args.fGammaCorrect = fDrawContext->isGammaCorrect();
     pr->drawPath(args);
@@ -962,11 +961,11 @@ bool GrDrawContextPriv::drawAndStencilPath(const GrFixedClip& clip,
 void GrDrawContext::internalDrawPath(const GrClip& clip,
                                      const GrPaint& paint,
                                      const SkMatrix& viewMatrix,
-                                     const SkPath& origPath,
-                                     const GrStyle& origStyle) {
+                                     const SkPath& path,
+                                     const GrStyle& style) {
     ASSERT_SINGLE_OWNER
     RETURN_IF_ABANDONED
-    SkASSERT(!origPath.isEmpty());
+    SkASSERT(!path.isEmpty());
 
     bool useCoverageAA = should_apply_coverage_aa(paint, fRenderTarget.get());
     constexpr bool kHasUserStencilSettings = false;
@@ -976,14 +975,11 @@ void GrDrawContext::internalDrawPath(const GrClip& clip,
         useCoverageAA ? GrPathRendererChain::kColorAntiAlias_DrawType
                       : GrPathRendererChain::kColor_DrawType;
 
-    SkTLazy<SkPath> tmpPath;
-    SkTLazy<GrStyle> tmpStyle;
-
+    GrShape shape(path, style);
     GrPathRenderer::CanDrawPathArgs canDrawArgs;
     canDrawArgs.fShaderCaps = fDrawingManager->getContext()->caps()->shaderCaps();
     canDrawArgs.fViewMatrix = &viewMatrix;
-    canDrawArgs.fPath = &origPath;
-    canDrawArgs.fStyle = &origStyle;
+    canDrawArgs.fShape = &shape;
     canDrawArgs.fAntiAlias = useCoverageAA;
     canDrawArgs.fHasUserStencilSettings = kHasUserStencilSettings;
     canDrawArgs.fIsStencilBufferMSAA = isStencilBufferMSAA;
@@ -992,55 +988,26 @@ void GrDrawContext::internalDrawPath(const GrClip& clip,
     GrPathRenderer* pr = fDrawingManager->getPathRenderer(canDrawArgs, false, type);
     SkScalar styleScale =  GrStyle::MatrixToScaleFactor(viewMatrix);
 
-    if (!pr && canDrawArgs.fStyle->pathEffect()) {
+    if (!pr && shape.style().pathEffect()) {
         // It didn't work above, so try again with the path effect applied.
-        SkStrokeRec rec(SkStrokeRec::kFill_InitStyle);
-        if (!canDrawArgs.fStyle->applyPathEffectToPath(tmpPath.init(), &rec, *canDrawArgs.fPath,
-                                                       styleScale)) {
-            GrStyle noPathEffect(canDrawArgs.fStyle->strokeRec(), nullptr);
-            this->internalDrawPath(clip, paint, viewMatrix, *canDrawArgs.fPath, noPathEffect);
-            return;
-        }
-        tmpStyle.init(rec, nullptr);
-        canDrawArgs.fPath = tmpPath.get();
-        canDrawArgs.fStyle = tmpStyle.get();
-        if (canDrawArgs.fPath->isEmpty()) {
+        shape = shape.applyStyle(GrStyle::Apply::kPathEffectOnly, styleScale);
+        if (shape.isEmpty()) {
             return;
         }
-
         pr = fDrawingManager->getPathRenderer(canDrawArgs, false, type);
     }
     if (!pr) {
-        SkASSERT(!canDrawArgs.fStyle->pathEffect());
-        if (canDrawArgs.fStyle->strokeRec().needToApply()) {
-            if (!tmpPath.isValid()) {
-                tmpPath.init();
-            }
-            // It didn't work above, so try again by applying the stroke to the geometry.
-            SkStrokeRec::InitStyle fillOrHairline;
-            if (!canDrawArgs.fStyle->applyToPath(tmpPath.get(), &fillOrHairline,
-                                                 *canDrawArgs.fPath, styleScale)) {
+        if (shape.style().applies()) {
+            shape = shape.applyStyle(GrStyle::Apply::kPathEffectAndStrokeRec, styleScale);
+            if (shape.isEmpty()) {
                 return;
             }
-            if (!tmpStyle.isValid()) {
-                tmpStyle.init(fillOrHairline);
-            } else {
-                tmpStyle.get()->resetToInitStyle(fillOrHairline);
-            }
-            canDrawArgs.fPath = tmpPath.get();
-            canDrawArgs.fStyle = tmpStyle.get();
-            if (canDrawArgs.fPath->isEmpty()) {
-                return;
-            }
-
-            pr = fDrawingManager->getPathRenderer(canDrawArgs, false, type);
         }
-
         // This time, allow SW renderer
         pr = fDrawingManager->getPathRenderer(canDrawArgs, true, type);
     }
 
-    if (nullptr == pr) {
+    if (!pr) {
 #ifdef SK_DEBUG
         SkDebugf("Unable to find path renderer compatible with path.\n");
 #endif
@@ -1055,8 +1022,7 @@ void GrDrawContext::internalDrawPath(const GrClip& clip,
     args.fClip = &clip;
     args.fColor = paint.getColor();
     args.fViewMatrix = &viewMatrix;
-    args.fPath = canDrawArgs.fPath;
-    args.fStyle = canDrawArgs.fStyle;
+    args.fShape = canDrawArgs.fShape;
     args.fAntiAlias = useCoverageAA;
     args.fGammaCorrect = this->isGammaCorrect();
     pr->drawPath(args);
index 20c6967..96e603f 100644 (file)
@@ -11,7 +11,7 @@
 #include "GrDrawContext.h"
 #include "GrPaint.h"
 #include "GrResourceProvider.h"
-#include "GrStyle.h"
+#include "GrShape.h"
 
 #include "SkDrawProcs.h"
 #include "SkTArray.h"
@@ -60,11 +60,15 @@ public:
      * This function is to get the stencil support for a particular path. The path's fill must
      * not be an inverse type. The path will always be filled and not stroked.
      *
-     * @param path      the path that will be drawn
+     * @param shape   the shape that will be drawn. Must be simple fill styled and non-inverse
+     *                filled.
      */
-    StencilSupport getStencilSupport(const SkPath& path) const {
+    StencilSupport getStencilSupport(const GrShape& shape) const {
+        SkDEBUGCODE(SkPath path;)
+        SkDEBUGCODE(shape.asPath(&path);)
+        SkASSERT(shape.style().isSimpleFill());
         SkASSERT(!path.isInverseFillType());
-        return this->onGetStencilSupport(path);
+        return this->onGetStencilSupport(shape);
     }
 
     /** Args to canDrawPath()
@@ -72,28 +76,26 @@ public:
      * fShaderCaps       The shader caps
      * fPipelineBuilder  The pipelineBuilder
      * fViewMatrix       The viewMatrix
-     * fPath             The path to draw
-     * fStyle            The styling info (path effect, stroking info)
+     * fShape            The shape to draw
      * fAntiAlias        True if anti-aliasing is required.
      */
     struct CanDrawPathArgs {
         const GrShaderCaps*         fShaderCaps;
         const SkMatrix*             fViewMatrix;
-        const SkPath*               fPath;
-        const GrStyle*              fStyle;
+        const GrShape*              fShape;
         bool                        fAntiAlias;
 
         // These next two are only used by GrStencilAndCoverPathRenderer
         bool                        fHasUserStencilSettings;
         bool                        fIsStencilBufferMSAA;
 
+#ifdef SK_DEBUG
         void validate() const {
             SkASSERT(fShaderCaps);
             SkASSERT(fViewMatrix);
-            SkASSERT(fPath);
-            SkASSERT(fStyle);
-            SkASSERT(!fPath->isEmpty());
+            SkASSERT(fShape);
         }
+#endif
     };
 
     /**
@@ -117,8 +119,7 @@ public:
      * fClip                  The clip
      * fColor                 Color to render with
      * fViewMatrix            The viewMatrix
-     * fPath                  the path to draw.
-     * fStyle                 the style information (path effect, stroke info)
+     * fShape                 The shape to draw
      * fAntiAlias             true if anti-aliasing is required.
      * fGammaCorrect          true if gamma-correct rendering is to be used.
      */
@@ -131,11 +132,10 @@ public:
         const GrClip*               fClip;
         GrColor                     fColor;
         const SkMatrix*             fViewMatrix;
-        const SkPath*               fPath;
-        const GrStyle*              fStyle;
+        const GrShape*              fShape;
         bool                        fAntiAlias;
         bool                        fGammaCorrect;
-
+#ifdef SK_DEBUG
         void validate() const {
             SkASSERT(fResourceProvider);
             SkASSERT(fPaint);
@@ -143,10 +143,9 @@ public:
             SkASSERT(fDrawContext);
             SkASSERT(fClip);
             SkASSERT(fViewMatrix);
-            SkASSERT(fPath);
-            SkASSERT(fStyle);
-            SkASSERT(!fPath->isEmpty());
+            SkASSERT(fShape);
         }
+#endif
     };
 
     /**
@@ -159,16 +158,17 @@ public:
         CanDrawPathArgs canArgs;
         canArgs.fShaderCaps = args.fResourceProvider->caps()->shaderCaps();
         canArgs.fViewMatrix = args.fViewMatrix;
-        canArgs.fPath = args.fPath;
-        canArgs.fStyle = args.fStyle;
+        canArgs.fShape = args.fShape;
         canArgs.fAntiAlias = args.fAntiAlias;
 
         canArgs.fHasUserStencilSettings = !args.fUserStencilSettings->isUnused();
         canArgs.fIsStencilBufferMSAA = args.fDrawContext->isStencilBufferMultisampled();
         SkASSERT(this->canDrawPath(canArgs));
         if (!args.fUserStencilSettings->isUnused()) {
-            SkASSERT(kNoRestriction_StencilSupport == this->getStencilSupport(*args.fPath));
-            SkASSERT(args.fStyle->isSimpleFill());
+            SkPath path;
+            args.fShape->asPath(&path);
+            SkASSERT(args.fShape->style().isSimpleFill());
+            SkASSERT(kNoRestriction_StencilSupport == this->getStencilSupport(*args.fShape));
         }
 #endif
         return this->onDrawPath(args);
@@ -187,16 +187,21 @@ public:
         GrDrawContext*      fDrawContext;
         const GrFixedClip*  fClip;
         const SkMatrix*     fViewMatrix;
-        const SkPath*       fPath;
         bool                fIsAA;
+        const GrShape*      fShape;
 
+#ifdef SK_DEBUG
         void validate() const {
             SkASSERT(fResourceProvider);
             SkASSERT(fDrawContext);
             SkASSERT(fViewMatrix);
-            SkASSERT(fPath);
-            SkASSERT(!fPath->isEmpty());
+            SkASSERT(fShape);
+            SkASSERT(fShape->style().isSimpleFill())
+            SkPath path;
+            fShape->asPath(&path);
+            SkASSERT(!path.isInverseFillType());
         }
+#endif
     };
 
     /**
@@ -205,7 +210,7 @@ public:
      */
     void stencilPath(const StencilPathArgs& args) {
         SkDEBUGCODE(args.validate();)
-        SkASSERT(kNoSupport_StencilSupport != this->getStencilSupport(*args.fPath));
+        SkASSERT(kNoSupport_StencilSupport != this->getStencilSupport(*args.fShape));
         this->onStencilPath(args);
     }
 
@@ -240,7 +245,7 @@ private:
     /**
      * Subclass overrides if it has any limitations of stenciling support.
      */
-    virtual StencilSupport onGetStencilSupport(const SkPath&) const {
+    virtual StencilSupport onGetStencilSupport(const GrShape&) const {
         return kNoRestriction_StencilSupport;
     }
 
@@ -278,8 +283,7 @@ private:
         drawArgs.fDrawContext = args.fDrawContext;
         drawArgs.fColor = GrColor_WHITE;
         drawArgs.fViewMatrix = args.fViewMatrix;
-        drawArgs.fPath = args.fPath;
-        drawArgs.fStyle = &GrStyle::SimpleFill();
+        drawArgs.fShape = args.fShape;
         drawArgs.fAntiAlias = false;  // In this case the MSAA handles the AA so we want to draw BW
         drawArgs.fGammaCorrect = false;
         this->drawPath(drawArgs);
index 8994186..bed56f8 100644 (file)
@@ -79,7 +79,7 @@ GrPathRenderer* GrPathRendererChain::getPathRenderer(
     }
     if (minStencilSupport != GrPathRenderer::kNoSupport_StencilSupport) {
         // We don't support (and shouldn't need) stenciling of non-fill paths.
-        if (!args.fStyle->isSimpleFill()) {
+        if (!args.fShape->style().isSimpleFill()) {
             return nullptr;
         }
     }
@@ -87,8 +87,7 @@ GrPathRenderer* GrPathRendererChain::getPathRenderer(
     for (int i = 0; i < fChain.count(); ++i) {
         if (fChain[i]->canDrawPath(args)) {
             if (GrPathRenderer::kNoSupport_StencilSupport != minStencilSupport) {
-                GrPathRenderer::StencilSupport support =
-                                        fChain[i]->getStencilSupport(*args.fPath);
+                GrPathRenderer::StencilSupport support = fChain[i]->getStencilSupport(*args.fShape);
                 if (support < minStencilSupport) {
                     continue;
                 } else if (stencilSupport) {
index 0c42a2b..496dadf 100644 (file)
 #include "GrContext.h"
 #include "batches/GrDrawBatch.h"
 #include "GrDrawContext.h"
-#include "GrGpu.h"
 #include "GrPipelineBuilder.h"
-#include "GrStyle.h"
+#include "GrShape.h"
 
-#include "SkData.h"
 #include "SkDistanceFieldGen.h"
-#include "SkStrokeRec.h"
 
 #include "batches/GrRectBatchFactory.h"
 
@@ -55,13 +52,15 @@ void GrSWMaskHelper::drawRect(const SkRect& rect, SkRegion::Op op,
 /**
  * Draw a single path element of the clip stack into the accumulation bitmap
  */
-void GrSWMaskHelper::drawPath(const SkPath& path, const GrStyle& style, SkRegion::Op op,
-                              bool antiAlias, uint8_t alpha) {
+void GrSWMaskHelper::drawShape(const GrShape& shape, SkRegion::Op op, bool antiAlias,
+                               uint8_t alpha) {
     SkPaint paint;
-    paint.setPathEffect(sk_ref_sp(style.pathEffect()));
-    style.strokeRec().applyToPaint(&paint);
+    paint.setPathEffect(sk_ref_sp(shape.style().pathEffect()));
+    shape.style().strokeRec().applyToPaint(&paint);
     paint.setAntiAlias(antiAlias);
 
+    SkPath path;
+    shape.asPath(&path);
     if (SkRegion::kReplace_Op == op && 0xFF == alpha) {
         SkASSERT(0xFF == paint.getAlpha());
         fDraw.drawPathCoverage(path, paint);
@@ -132,23 +131,21 @@ void GrSWMaskHelper::toSDF(unsigned char* sdf) {
 
 ////////////////////////////////////////////////////////////////////////////////
 /**
- * Software rasterizes path to A8 mask (possibly using the context's matrix)
- * and uploads the result to a scratch texture. Returns the resulting
- * texture on success; nullptr on failure.
+ * Software rasterizes shape to A8 mask and uploads the result to a scratch texture. Returns the
+ * resulting texture on success; nullptr on failure.
  */
-GrTexture* GrSWMaskHelper::DrawPathMaskToTexture(GrTextureProvider* texProvider,
-                                                 const SkPath& path,
-                                                 const GrStyle& style,
-                                                 const SkIRect& resultBounds,
-                                                 bool antiAlias,
-                                                 const SkMatrix* matrix) {
+GrTexture* GrSWMaskHelper::DrawShapeMaskToTexture(GrTextureProvider* texProvider,
+                                                  const GrShape& shape,
+                                                  const SkIRect& resultBounds,
+                                                  bool antiAlias,
+                                                  const SkMatrix* matrix) {
     GrSWMaskHelper helper(texProvider);
 
     if (!helper.init(resultBounds, matrix)) {
         return nullptr;
     }
 
-    helper.drawPath(path, style, SkRegion::kReplace_Op, antiAlias, 0xFF);
+    helper.drawShape(shape, SkRegion::kReplace_Op, antiAlias, 0xFF);
 
     GrTexture* texture(helper.createTexture());
     if (!texture) {
@@ -160,14 +157,14 @@ GrTexture* GrSWMaskHelper::DrawPathMaskToTexture(GrTextureProvider* texProvider,
     return texture;
 }
 
-void GrSWMaskHelper::DrawToTargetWithPathMask(GrTexture* texture,
-                                              GrDrawContext* drawContext,
-                                              const GrPaint* paint,
-                                              const GrUserStencilSettings* userStencilSettings,
-                                              const GrClip& clip,
-                                              GrColor color,
-                                              const SkMatrix& viewMatrix,
-                                              const SkIRect& rect) {
+void GrSWMaskHelper::DrawToTargetWithShapeMask(GrTexture* texture,
+                                               GrDrawContext* drawContext,
+                                               const GrPaint* paint,
+                                               const GrUserStencilSettings* userStencilSettings,
+                                               const GrClip& clip,
+                                               GrColor color,
+                                               const SkMatrix& viewMatrix,
+                                               const SkIRect& rect) {
     SkMatrix invert;
     if (!viewMatrix.invert(&invert)) {
         return;
index 107c77e..b015b15 100644 (file)
 
 class GrClip;
 class GrPaint;
+class GrShape;
 class GrTextureProvider;
 class GrStyle;
 class GrTexture;
-class SkPath;
-class SkStrokeRec;
 struct GrUserStencilSettings;
 
 /**
@@ -54,8 +53,7 @@ public:
     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 drawPath(const SkPath& path, const GrStyle& style, SkRegion::Op op,
-                  bool antiAlias, 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);
@@ -70,14 +68,13 @@ public:
 
     // Canonical usage utility that draws a single path and uploads it
     // to the GPU. The result is returned.
-    static GrTexture* DrawPathMaskToTexture(GrTextureProvider*,
-                                            const SkPath& path,
-                                            const GrStyle& style,
-                                            const SkIRect& resultBounds,
-                                            bool antiAlias,
-                                            const SkMatrix* matrix);
-
-    // This utility routine is used to add a path's mask to some other draw.
+    static GrTexture* DrawShapeMaskToTexture(GrTextureProvider*,
+                                             const GrShape&,
+                                             const SkIRect& resultBounds,
+                                             bool antiAlias,
+                                             const SkMatrix* matrix);
+
+    // This utility routine is used to add a shape's mask to some other draw.
     // The ClipMaskManager uses it to accumulate clip masks while the
     // GrSoftwarePathRenderer uses it to fulfill a drawPath call.
     // It draws with "texture" as a path mask into "target" using "rect" as
@@ -87,14 +84,14 @@ public:
     // the draw state can be used to hold the mask texture stage.
     // This method is really only intended to be used with the
     // output of DrawPathMaskToTexture.
-    static void DrawToTargetWithPathMask(GrTexture* texture,
-                                         GrDrawContext*,
-                                         const GrPaint* paint,
-                                         const GrUserStencilSettings* userStencilSettings,
-                                         const GrClip&,
-                                         GrColor,
-                                         const SkMatrix& viewMatrix,
-                                         const SkIRect& rect);
+    static void DrawToTargetWithShapeMask(GrTexture* texture,
+                                          GrDrawContext*,
+                                          const GrPaint* paint,
+                                          const GrUserStencilSettings* userStencilSettings,
+                                          const GrClip&,
+                                          GrColor,
+                                          const SkMatrix& viewMatrix,
+                                          const SkIRect& rect);
 
 private:
     // Helper function to get a scratch texture suitable for capturing the
index fd25bbb..983bd20 100644 (file)
@@ -14,7 +14,9 @@
 
 ////////////////////////////////////////////////////////////////////////////////
 bool GrSoftwarePathRenderer::onCanDrawPath(const CanDrawPathArgs& args) const {
-    return SkToBool(fTexProvider);
+    // Pass on any style that applies. The caller will apply the style if a suitable renderer is
+    // not found and try again with the new GrShape.
+    return !args.fShape->style().applies() && SkToBool(fTexProvider);
 }
 
 namespace {
@@ -23,33 +25,34 @@ namespace {
 // gets device coord bounds of path (not considering the fill) and clip. The
 // path bounds will be a subset of the clip bounds. returns false if
 // path bounds would be empty.
-bool get_path_and_clip_bounds(int width, int height,
-                              const GrClip& clip,
-                              const SkPath& path,
-                              const SkMatrix& matrix,
-                              SkIRect* devPathBounds,
-                              SkIRect* devClipBounds) {
+bool get_shape_and_clip_bounds(int width, int height,
+                               const GrClip& clip,
+                               const GrShape& shape,
+                               const SkMatrix& matrix,
+                               SkIRect* devShapeBounds,
+                               SkIRect* devClipBounds) {
     // compute bounds as intersection of rt size, clip, and path
     clip.getConservativeBounds(width, height, devClipBounds);
 
     if (devClipBounds->isEmpty()) {
-        *devPathBounds = SkIRect::MakeWH(width, height);
+        *devShapeBounds = SkIRect::MakeWH(width, height);
         return false;
     }
-
-    if (!path.getBounds().isEmpty()) {
-        SkRect pathSBounds;
-        matrix.mapRect(&pathSBounds, path.getBounds());
-        SkIRect pathIBounds;
-        pathSBounds.roundOut(&pathIBounds);
-        *devPathBounds = *devClipBounds;
-        if (!devPathBounds->intersect(pathIBounds)) {
+    SkRect shapeBounds;
+    shape.styledBounds(&shapeBounds);
+    if (!shapeBounds.isEmpty()) {
+        SkRect shapeSBounds;
+        matrix.mapRect(&shapeSBounds, shapeBounds);
+        SkIRect shapeIBounds;
+        shapeSBounds.roundOut(&shapeIBounds);
+        *devShapeBounds = *devClipBounds;
+        if (!devShapeBounds->intersect(shapeIBounds)) {
             // set the correct path bounds, as this would be used later.
-            *devPathBounds = pathIBounds;
+            *devShapeBounds = shapeIBounds;
             return false;
         }
     } else {
-        *devPathBounds = SkIRect::EmptyIRect();
+        *devShapeBounds = SkIRect::EmptyIRect();
         return false;
     }
     return true;
@@ -125,35 +128,41 @@ bool GrSoftwarePathRenderer::onDrawPath(const DrawPathArgs& args) {
         return false;
     }
 
-    SkIRect devPathBounds, devClipBounds;
-    if (!get_path_and_clip_bounds(args.fDrawContext->width(), args.fDrawContext->height(),
-                                  *args.fClip, *args.fPath,
-                                  *args.fViewMatrix, &devPathBounds, &devClipBounds)) {
-        if (args.fPath->isInverseFillType()) {
+    // We really need to know if the shape will be inverse filled or not
+    bool inverseFilled = false;
+    SkTLazy<GrShape> tmpShape;
+    SkASSERT(!args.fShape->style().applies())
+    inverseFilled = args.fShape->inverseFilled();
+
+    SkIRect devShapeBounds, devClipBounds;
+    if (!get_shape_and_clip_bounds(args.fDrawContext->width(), args.fDrawContext->height(),
+                                   *args.fClip, *args.fShape,
+                                   *args.fViewMatrix, &devShapeBounds, &devClipBounds)) {
+        if (inverseFilled) {
             DrawAroundInvPath(args.fDrawContext, args.fPaint, args.fUserStencilSettings,
                               *args.fClip, args.fColor,
-                              *args.fViewMatrix, devClipBounds, devPathBounds);
+                              *args.fViewMatrix, devClipBounds, devShapeBounds);
+
         }
         return true;
     }
 
     SkAutoTUnref<GrTexture> texture(
-            GrSWMaskHelper::DrawPathMaskToTexture(fTexProvider, *args.fPath, *args.fStyle,
-                                                  devPathBounds,
-                                                  args.fAntiAlias, args.fViewMatrix));
+            GrSWMaskHelper::DrawShapeMaskToTexture(fTexProvider, *args.fShape, devShapeBounds,
+                                                   args.fAntiAlias, args.fViewMatrix));
     if (nullptr == texture) {
         return false;
     }
 
-    GrSWMaskHelper::DrawToTargetWithPathMask(texture, args.fDrawContext, args.fPaint,
-                                             args.fUserStencilSettings,
-                                             *args.fClip, args.fColor, *args.fViewMatrix,
-                                             devPathBounds);
+    GrSWMaskHelper::DrawToTargetWithShapeMask(texture, args.fDrawContext, args.fPaint,
+                                              args.fUserStencilSettings,
+                                              *args.fClip, args.fColor, *args.fViewMatrix,
+                                              devShapeBounds);
 
-    if (args.fPath->isInverseFillType()) {
+    if (inverseFilled) {
         DrawAroundInvPath(args.fDrawContext, args.fPaint, args.fUserStencilSettings,
                           *args.fClip, args.fColor,
-                          *args.fViewMatrix, devClipBounds, devPathBounds);
+                          *args.fViewMatrix, devClipBounds, devShapeBounds);
     }
 
     return true;
index 4c756d5..30edfeb 100644 (file)
@@ -37,7 +37,7 @@ private:
                                   const SkIRect& devClipBounds,
                                   const SkIRect& devPathBounds);
 
-    StencilSupport onGetStencilSupport(const SkPath&) const override {
+    StencilSupport onGetStencilSupport(const GrShape&) const override {
         return GrPathRenderer::kNoSupport_StencilSupport;
     }
 
index 326f800..478564f 100644 (file)
@@ -113,6 +113,13 @@ public:
     /** Is this style a hairline with no path effect? */
     bool isSimpleHairline() const { return fStrokeRec.isHairlineStyle() && !fPathEffect; }
 
+    bool couldBeHairline() const {
+        // If the original stroke rec has hairline style then either a null or dash patheffect
+        // would preserve the hairline status. An arbitrary path effect could introduce hairline
+        // style.
+        return this->strokeRec().isHairlineStyle() || this->hasNonDashPathEffect();
+    }
+
     SkPathEffect* pathEffect() const { return fPathEffect.get(); }
 
     bool hasPathEffect() const { return SkToBool(fPathEffect.get()); }
index 390162e..bb097aa 100644 (file)
@@ -681,8 +681,8 @@ sk_sp<GrGeometryProcessor> QuadEdgeEffect::TestCreate(GrProcessorTestData* d) {
 
 bool GrAAConvexPathRenderer::onCanDrawPath(const CanDrawPathArgs& args) const {
     return (args.fShaderCaps->shaderDerivativeSupport() && args.fAntiAlias &&
-            args.fStyle->isSimpleFill() && !args.fPath->isInverseFillType() &&
-            args.fPath->isConvex());
+            args.fShape->style().isSimpleFill() && !args.fShape->inverseFilled() &&
+            args.fShape->knownToBeConvex());
 }
 
 // extract the result vertices and indices from the GrAAConvexTessellator
@@ -998,15 +998,12 @@ bool GrAAConvexPathRenderer::onDrawPath(const DrawPathArgs& args) {
     GR_AUDIT_TRAIL_AUTO_FRAME(args.fDrawContext->auditTrail(),
                               "GrAAConvexPathRenderer::onDrawPath");
     SkASSERT(!args.fDrawContext->isUnifiedMultisampled());
-
-    if (args.fPath->isEmpty()) {
-        return true;
-    }
+    SkASSERT(!args.fShape->isEmpty());
 
     AAConvexPathBatch::Geometry geometry;
     geometry.fColor = args.fColor;
     geometry.fViewMatrix = *args.fViewMatrix;
-    geometry.fPath = *args.fPath;
+    args.fShape->asPath(&geometry.fPath);
 
     SkAutoTUnref<GrDrawBatch> batch(AAConvexPathBatch::Create(geometry));
 
index e6be590..6cf3e4b 100644 (file)
@@ -82,13 +82,13 @@ GrAADistanceFieldPathRenderer::~GrAADistanceFieldPathRenderer() {
 ////////////////////////////////////////////////////////////////////////////////
 bool GrAADistanceFieldPathRenderer::onCanDrawPath(const CanDrawPathArgs& args) const {
     // We don't currently apply the dash or factor it into the DF key. (skbug.com/5082)
-    if (args.fStyle->pathEffect()) {
+    if (args.fShape->style().pathEffect()) {
         return false;
     }
     // TODO: Support inverse fill
     if (!args.fShaderCaps->shaderDerivativeSupport() || !args.fAntiAlias ||
-        args.fStyle->isSimpleHairline() || args.fPath->isInverseFillType() ||
-        args.fPath->isVolatile()) {
+        args.fShape->style().isSimpleHairline() || args.fShape->mayBeInverseFilledAfterStyling() ||
+        !args.fShape->hasUnstyledKey()) {
         return false;
     }
 
@@ -102,7 +102,7 @@ bool GrAADistanceFieldPathRenderer::onCanDrawPath(const CanDrawPathArgs& args) c
     // the goal is to accelerate rendering of lots of small paths that may be scaling
     SkScalar maxScale = args.fViewMatrix->getMaxScale();
     SkRect bounds;
-    args.fStyle->adjustBounds(&bounds, args.fPath->getBounds());
+    args.fShape->styledBounds(&bounds);
     SkScalar maxDim = SkMaxScalar(bounds.width(), bounds.height());
 
     return maxDim <= kMediumMIP && maxDim * maxScale <= 2.0f*kLargeMIP;
@@ -532,9 +532,7 @@ bool GrAADistanceFieldPathRenderer::onDrawPath(const DrawPathArgs& args) {
     SkASSERT(!args.fDrawContext->isUnifiedMultisampled());
 
     // we've already bailed on inverse filled paths, so this is safe
-    if (args.fPath->isEmpty()) {
-        return true;
-    }
+    SkASSERT(!args.fShape->isEmpty());
 
     if (!fAtlas) {
         fAtlas = args.fResourceProvider->createAtlas(kAlpha_8_GrPixelConfig,
@@ -547,19 +545,19 @@ bool GrAADistanceFieldPathRenderer::onDrawPath(const DrawPathArgs& args) {
         }
     }
 
+    const GrStyle& style = args.fShape->style();
     // It's ok to ignore style's path effect because canDrawPath filtered out path effects.
-    AADistanceFieldPathBatch::Geometry geometry(args.fStyle->strokeRec());
-    if (args.fStyle->isSimpleFill()) {
-        geometry.fPath = *args.fPath;
-    } else {
-        args.fStyle->strokeRec().applyToPath(&geometry.fPath, *args.fPath);
-    }
-    geometry.fColor = args.fColor;
-    geometry.fAntiAlias = args.fAntiAlias;
+    AADistanceFieldPathBatch::Geometry geometry(style.strokeRec());
+    args.fShape->asPath(&geometry.fPath);
     // Note: this is the generation ID of the _original_ path. When a new path is
     // generated due to stroking it is important that the original path's id is used
     // for caching.
-    geometry.fGenID = args.fPath->getGenerationID();
+    geometry.fGenID = geometry.fPath.getGenerationID();
+    if (!style.isSimpleFill()) {
+        style.strokeRec().applyToPath(&geometry.fPath, geometry.fPath);
+    }
+    geometry.fColor = args.fColor;
+    geometry.fAntiAlias = args.fAntiAlias;
 
     SkAutoTUnref<GrDrawBatch> batch(AADistanceFieldPathBatch::Create(geometry,
                                                                      *args.fViewMatrix, fAtlas,
index 099d0c7..e5c7dce 100755 (executable)
@@ -23,7 +23,7 @@ public:
     virtual ~GrAADistanceFieldPathRenderer();
 
 private:
-    StencilSupport onGetStencilSupport(const SkPath&) const override {
+    StencilSupport onGetStencilSupport(const GrShape&) const override {
         return GrPathRenderer::kNoSupport_StencilSupport;
     }
 
index f44c454..1f7407c 100644 (file)
@@ -618,19 +618,20 @@ bool GrAAHairLinePathRenderer::onCanDrawPath(const CanDrawPathArgs& args) const
         return false;
     }
 
-    if (!IsStrokeHairlineOrEquivalent(*args.fStyle, *args.fViewMatrix, nullptr)) {
+    if (!IsStrokeHairlineOrEquivalent(args.fShape->style(), *args.fViewMatrix, nullptr)) {
         return false;
     }
 
     // We don't currently handle dashing in this class though perhaps we should.
-    if (args.fStyle->pathEffect()) {
+    if (args.fShape->style().pathEffect()) {
         return false;
     }
 
-    if (SkPath::kLine_SegmentMask == args.fPath->getSegmentMasks() ||
+    if (SkPath::kLine_SegmentMask == args.fShape->segmentMask() ||
         args.fShaderCaps->shaderDerivativeSupport()) {
         return true;
     }
+
     return false;
 }
 
@@ -971,12 +972,13 @@ bool GrAAHairLinePathRenderer::onDrawPath(const DrawPathArgs& args) {
     args.fClip->getConservativeBounds(args.fDrawContext->width(), args.fDrawContext->height(),
                                       &devClipBounds);
 
-    SkAutoTUnref<GrDrawBatch> batch(create_hairline_batch(args.fColor, *args.fViewMatrix, *args.fPath,
-                                                          *args.fStyle, devClipBounds));
+    SkPath path;
+    args.fShape->asPath(&path);
+    SkAutoTUnref<GrDrawBatch> batch(create_hairline_batch(args.fColor, *args.fViewMatrix, path,
+                                                          args.fShape->style(), devClipBounds));
 
     GrPipelineBuilder pipelineBuilder(*args.fPaint);
     pipelineBuilder.setUserStencil(args.fUserStencilSettings);
-
     args.fDrawContext->drawBatch(pipelineBuilder, *args.fClip, batch);
 
     return true;
index 1847a67..9748829 100644 (file)
@@ -40,23 +40,23 @@ bool GrAALinearizingConvexPathRenderer::onCanDrawPath(const CanDrawPathArgs& arg
     if (!args.fAntiAlias) {
         return false;
     }
-    if (args.fPath->isInverseFillType()) {
+    if (!args.fShape->knownToBeConvex()) {
         return false;
     }
-    if (!args.fPath->isConvex()) {
+    if (args.fShape->style().pathEffect()) {
         return false;
     }
-    if (args.fStyle->pathEffect()) {
+    if (args.fShape->inverseFilled()) {
         return false;
     }
-    const SkStrokeRec& stroke = args.fStyle->strokeRec();
+    const SkStrokeRec& stroke = args.fShape->style().strokeRec();
     if (stroke.getStyle() == SkStrokeRec::kStroke_Style) {
         if (!args.fViewMatrix->isSimilarity()) {
             return false;
         }
         SkScalar strokeWidth = args.fViewMatrix->getMaxScale() * stroke.getWidth();
         return strokeWidth >= 1.0f && strokeWidth <= kMaxStrokeWidth &&
-               SkPathPriv::IsClosedSingleContour(*args.fPath) &&
+               args.fShape->knownToBeClosed() &&
                stroke.getJoin() != SkPaint::Join::kRound_Join;
     }
     return stroke.getStyle() == SkStrokeRec::kFill_Style;
@@ -324,18 +324,17 @@ bool GrAALinearizingConvexPathRenderer::onDrawPath(const DrawPathArgs& args) {
     GR_AUDIT_TRAIL_AUTO_FRAME(args.fDrawContext->auditTrail(),
                               "GrAALinearizingConvexPathRenderer::onDrawPath");
     SkASSERT(!args.fDrawContext->isUnifiedMultisampled());
+    SkASSERT(!args.fShape->isEmpty());
 
-    if (args.fPath->isEmpty()) {
-        return true;
-    }
     AAFlatteningConvexPathBatch::Geometry geometry;
     geometry.fColor = args.fColor;
     geometry.fViewMatrix = *args.fViewMatrix;
-    geometry.fPath = *args.fPath;
-    bool fill = args.fStyle->isSimpleFill();
-    geometry.fStrokeWidth = fill ? -1.0f : args.fStyle->strokeRec().getWidth();
-    geometry.fJoin = fill ? SkPaint::Join::kMiter_Join : args.fStyle->strokeRec().getJoin();
-    geometry.fMiterLimit = args.fStyle->strokeRec().getMiter();
+    args.fShape->asPath(&geometry.fPath);
+    bool fill = args.fShape->style().isSimpleFill();
+    const SkStrokeRec& stroke = args.fShape->style().strokeRec();
+    geometry.fStrokeWidth = fill ? -1.0f : stroke.getWidth();
+    geometry.fJoin = fill ? SkPaint::Join::kMiter_Join : stroke.getJoin();
+    geometry.fMiterLimit = stroke.getMiter();
 
     SkAutoTUnref<GrDrawBatch> batch(AAFlatteningConvexPathBatch::Create(geometry));
 
index a442b66..8dba7b9 100644 (file)
@@ -13,8 +13,8 @@
 
 bool GrDashLinePathRenderer::onCanDrawPath(const CanDrawPathArgs& args) const {
     SkPoint pts[2];
-    if (args.fStyle->isDashed() && args.fPath->isLine(pts)) {
-        return GrDashingEffect::CanDrawDashLine(pts, *args.fStyle, *args.fViewMatrix);
+    if (args.fShape->style().isDashed() && args.fShape->asLine(pts)) {
+        return GrDashingEffect::CanDrawDashLine(pts, args.fShape->style(), *args.fViewMatrix);
     }
     return false;
 }
@@ -34,12 +34,12 @@ bool GrDashLinePathRenderer::onDrawPath(const DrawPathArgs& args) {
         aaMode = GrDashingEffect::AAMode::kNone;
     }
     SkPoint pts[2];
-    SkAssertResult(args.fPath->isLine(pts));
+    SkAssertResult(args.fShape->asLine(pts));
     SkAutoTUnref<GrDrawBatch> batch(GrDashingEffect::CreateDashLineBatch(args.fColor,
                                                                          *args.fViewMatrix,
                                                                          pts,
                                                                          aaMode,
-                                                                         *args.fStyle));
+                                                                         args.fShape->style()));
     if (!batch) {
         return false;
     }
index e25f882..d959421 100644 (file)
@@ -14,7 +14,7 @@ class GrDashLinePathRenderer : public GrPathRenderer {
 private:
     bool onCanDrawPath(const CanDrawPathArgs&) const override;
 
-    StencilSupport onGetStencilSupport(const SkPath&) const override {
+    StencilSupport onGetStencilSupport(const GrShape&) const override {
         return kNoSupport_StencilSupport;
     }
 
index 7fd7913..1e807f8 100644 (file)
@@ -34,20 +34,20 @@ GrDefaultPathRenderer::GrDefaultPathRenderer(bool separateStencilSupport,
 
 #define STENCIL_OFF     0   // Always disable stencil (even when needed)
 
-static inline bool single_pass_path(const SkPath& path, const SkStrokeRec& stroke) {
+static inline bool single_pass_shape(const GrShape& shape) {
 #if STENCIL_OFF
     return true;
 #else
-    if (!stroke.isHairlineStyle() && !path.isInverseFillType()) {
-        return path.isConvex();
+    if (!shape.style().couldBeHairline() && !shape.inverseFilled()) {
+        return shape.knownToBeConvex();
     }
     return false;
 #endif
 }
 
 GrPathRenderer::StencilSupport
-GrDefaultPathRenderer::onGetStencilSupport(const SkPath& path) const {
-    if (single_pass_path(path, SkStrokeRec(SkStrokeRec::kFill_InitStyle))) {
+GrDefaultPathRenderer::onGetStencilSupport(const GrShape& shape) const {
+    if (single_pass_shape(shape)) {
         return GrPathRenderer::kNoRestriction_StencilSupport;
     } else {
         return GrPathRenderer::kStencilOnly_StencilSupport;
@@ -422,20 +422,19 @@ bool GrDefaultPathRenderer::internalDrawPath(GrDrawContext* drawContext,
                                              const GrClip& clip,
                                              GrColor color,
                                              const SkMatrix& viewMatrix,
-                                             const SkPath& path,
-                                             const GrStyle& origStyle,
+                                             const GrShape& shape,
                                              bool stencilOnly) {
-    const GrStyle* style = &origStyle;
+    SkPath path;
+    shape.asPath(&path);
 
     SkScalar hairlineCoverage;
     uint8_t newCoverage = 0xff;
     bool isHairline = false;
-    if (IsStrokeHairlineOrEquivalent(*style, viewMatrix, &hairlineCoverage)) {
+    if (IsStrokeHairlineOrEquivalent(shape.style(), viewMatrix, &hairlineCoverage)) {
         newCoverage = SkScalarRoundToInt(hairlineCoverage * 0xff);
-        style = &GrStyle::SimpleHairline();
         isHairline = true;
     } else {
-        SkASSERT(style->isSimpleFill());
+        SkASSERT(shape.style().isSimpleFill());
     }
 
     int                          passCount = 0;
@@ -454,7 +453,7 @@ bool GrDefaultPathRenderer::internalDrawPath(GrDrawContext* drawContext,
         lastPassIsBounds = false;
         drawFace[0] = GrPipelineBuilder::kBoth_DrawFace;
     } else {
-        if (single_pass_path(path, style->strokeRec())) {
+        if (single_pass_shape(shape)) {
             passCount = 1;
             if (stencilOnly) {
                 passes[0] = &gDirectToStencil;
@@ -600,9 +599,8 @@ bool GrDefaultPathRenderer::internalDrawPath(GrDrawContext* drawContext,
 bool GrDefaultPathRenderer::onCanDrawPath(const CanDrawPathArgs& args) const {
     // this class can draw any path with any simple fill style but doesn't do any anti-aliasing.
     return !args.fAntiAlias &&
-           (args.fStyle->isSimpleFill() || IsStrokeHairlineOrEquivalent(*args.fStyle,
-                                                                        *args.fViewMatrix,
-                                                                        nullptr));
+           (args.fShape->style().isSimpleFill() ||
+            IsStrokeHairlineOrEquivalent(args.fShape->style(), *args.fViewMatrix, nullptr));
 }
 
 bool GrDefaultPathRenderer::onDrawPath(const DrawPathArgs& args) {
@@ -614,30 +612,21 @@ bool GrDefaultPathRenderer::onDrawPath(const DrawPathArgs& args) {
                                   *args.fClip,
                                   args.fColor,
                                   *args.fViewMatrix,
-                                  *args.fPath,
-                                  *args.fStyle,
+                                  *args.fShape,
                                   false);
 }
 
 void GrDefaultPathRenderer::onStencilPath(const StencilPathArgs& args) {
     GR_AUDIT_TRAIL_AUTO_FRAME(args.fDrawContext->auditTrail(),
                               "GrDefaultPathRenderer::onStencilPath");
-    SkASSERT(SkPath::kInverseEvenOdd_FillType != args.fPath->getFillType());
-    SkASSERT(SkPath::kInverseWinding_FillType != args.fPath->getFillType());
+    SkASSERT(!args.fShape->inverseFilled());
 
     GrPaint paint;
     paint.setXPFactory(GrDisableColorXPFactory::Make());
     paint.setAntiAlias(args.fIsAA);
 
-    this->internalDrawPath(args.fDrawContext,
-                           paint,
-                           &GrUserStencilSettings::kUnused,
-                           *args.fClip,
-                           GrColor_WHITE,
-                           *args.fViewMatrix,
-                           *args.fPath,
-                           GrStyle::SimpleFill(),
-                           true);
+    this->internalDrawPath(args.fDrawContext, paint, &GrUserStencilSettings::kUnused, *args.fClip,
+                           GrColor_WHITE, *args.fViewMatrix, *args.fShape, true);
 }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
index 277d7a8..04e1013 100644 (file)
@@ -22,7 +22,7 @@ public:
 
 private:
 
-    StencilSupport onGetStencilSupport(const SkPath&) const override;
+    StencilSupport onGetStencilSupport(const GrShape&) const override;
 
     bool onCanDrawPath(const CanDrawPathArgs&) const override;
 
@@ -36,8 +36,7 @@ private:
                           const GrClip&,
                           GrColor,
                           const SkMatrix& viewMatrix,
-                          const SkPath&,
-                          const GrStyle&,
+                          const GrShape&,
                           bool stencilOnly);
 
     bool    fSeparateStencil;
index edc285e..31b9ebf 100644 (file)
@@ -31,16 +31,15 @@ static const float kTolerance = 0.5f;
 ////////////////////////////////////////////////////////////////////////////////
 // Helpers for drawPath
 
-static inline bool single_pass_path(const SkPath& path) {
-    if (!path.isInverseFillType()) {
-        return path.isConvex();
+static inline bool single_pass_shape(const GrShape& shape) {
+    if (!shape.inverseFilled()) {
+        return shape.knownToBeConvex();
     }
     return false;
 }
 
-GrPathRenderer::StencilSupport
-GrMSAAPathRenderer::onGetStencilSupport(const SkPath& path) const {
-    if (single_pass_path(path)) {
+GrPathRenderer::StencilSupport GrMSAAPathRenderer::onGetStencilSupport(const GrShape& shape) const {
+    if (single_pass_shape(shape)) {
         return GrPathRenderer::kNoRestriction_StencilSupport;
     } else {
         return GrPathRenderer::kStencilOnly_StencilSupport;
@@ -574,15 +573,19 @@ bool GrMSAAPathRenderer::internalDrawPath(GrDrawContext* drawContext,
                                           const GrClip& clip,
                                           GrColor color,
                                           const SkMatrix& viewMatrix,
-                                          const SkPath& path,
+                                          const GrShape& shape,
                                           bool stencilOnly) {
+    SkASSERT(shape.style().isSimpleFill());
+    SkPath path;
+    shape.asPath(&path);
+
     int                          passCount = 0;
     const GrUserStencilSettings* passes[3];
     GrPipelineBuilder::DrawFace  drawFace[3];
     bool                         reverse = false;
     bool                         lastPassIsBounds;
 
-    if (single_pass_path(path)) {
+    if (single_pass_shape(shape)) {
         passCount = 1;
         if (stencilOnly) {
             passes[0] = &gDirectToStencil;
@@ -709,28 +712,19 @@ bool GrMSAAPathRenderer::onCanDrawPath(const CanDrawPathArgs& args) const {
     // This path renderer does not support hairlines. We defer on anything that could be handled
     // as a hairline by another path renderer. Also, arbitrary path effects could produce
     // a hairline result.
-    return !IsStrokeHairlineOrEquivalent(*args.fStyle, *args.fViewMatrix, nullptr) &&
-           !args.fStyle->strokeRec().isHairlineStyle() &&
-           !args.fStyle->hasNonDashPathEffect() && !args.fAntiAlias;
+    return !IsStrokeHairlineOrEquivalent(args.fShape->style(), *args.fViewMatrix, nullptr) &&
+           !args.fShape->style().couldBeHairline() && !args.fAntiAlias;
 }
 
 bool GrMSAAPathRenderer::onDrawPath(const DrawPathArgs& args) {
     GR_AUDIT_TRAIL_AUTO_FRAME(args.fDrawContext->auditTrail(),
                               "GrMSAAPathRenderer::onDrawPath");
-    SkPath tmpPath;
-    const SkPath* path;
-    if (args.fStyle->applies()) {
-        SkStrokeRec::InitStyle fill;
+    SkTLazy<GrShape> tmpShape;
+    const GrShape* shape = args.fShape;
+    if (shape->style().applies()) {
         SkScalar styleScale = GrStyle::MatrixToScaleFactor(*args.fViewMatrix);
-        if (!args.fStyle->applyToPath(&tmpPath, &fill, *args.fPath, styleScale)) {
-            return false;
-        }
-        // We don't accept styles that are hairlines or have path effects that could produce
-        // hairlines.
-        SkASSERT(SkStrokeRec::kFill_InitStyle == fill);
-        path = &tmpPath;
-    } else {
-        path = args.fPath;
+        tmpShape.init(args.fShape->applyStyle(GrStyle::Apply::kPathEffectAndStrokeRec, styleScale));
+        shape = tmpShape.get();
     }
     return this->internalDrawPath(args.fDrawContext,
                                   *args.fPaint,
@@ -738,28 +732,22 @@ bool GrMSAAPathRenderer::onDrawPath(const DrawPathArgs& args) {
                                   *args.fClip,
                                   args.fColor,
                                   *args.fViewMatrix,
-                                  *path,
+                                  *shape,
                                   false);
 }
 
 void GrMSAAPathRenderer::onStencilPath(const StencilPathArgs& args) {
     GR_AUDIT_TRAIL_AUTO_FRAME(args.fDrawContext->auditTrail(),
                               "GrMSAAPathRenderer::onStencilPath");
-    SkASSERT(SkPath::kInverseEvenOdd_FillType != args.fPath->getFillType());
-    SkASSERT(SkPath::kInverseWinding_FillType != args.fPath->getFillType());
+    SkASSERT(args.fShape->style().isSimpleFill());
+    SkASSERT(!args.fShape->mayBeInverseFilledAfterStyling());
 
     GrPaint paint;
     paint.setXPFactory(GrDisableColorXPFactory::Make());
     paint.setAntiAlias(args.fIsAA);
 
-    this->internalDrawPath(args.fDrawContext,
-                           paint,
-                           &GrUserStencilSettings::kUnused,
-                           *args.fClip,
-                           GrColor_WHITE,
-                           *args.fViewMatrix,
-                           *args.fPath,
-                           true);
+    this->internalDrawPath(args.fDrawContext, paint, &GrUserStencilSettings::kUnused, *args.fClip,
+                           GrColor_WHITE, *args.fViewMatrix, *args.fShape, true);
 }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
index 0c27e8c..e1cf4a3 100644 (file)
@@ -13,7 +13,7 @@
 
 class SK_API GrMSAAPathRenderer : public GrPathRenderer {
 private:
-    StencilSupport onGetStencilSupport(const SkPath&) const override;
+    StencilSupport onGetStencilSupport(const GrShape&) const override;
 
     bool onCanDrawPath(const CanDrawPathArgs&) const override;
 
@@ -27,7 +27,7 @@ private:
                           const GrClip&,
                           GrColor,
                           const SkMatrix& viewMatrix,
-                          const SkPath&,
+                          const GrShape&,
                           bool stencilOnly);
 
     typedef GrPathRenderer INHERITED;
index a81b883..ba84d73 100644 (file)
@@ -777,9 +777,11 @@ private:
 bool GrPLSPathRenderer::onCanDrawPath(const CanDrawPathArgs& args) const {
     // We have support for even-odd rendering, but are having some troublesome
     // seams. Disable in the presence of even-odd for now.
+    SkPath path;
+    args.fShape->asPath(&path);
     return args.fShaderCaps->shaderDerivativeSupport() && args.fAntiAlias &&
-            args.fStyle->isSimpleFill() && !args.fPath->isInverseFillType() &&
-            args.fPath->getFillType() == SkPath::FillType::kWinding_FillType;
+            args.fShape->style().isSimpleFill() && !path.isInverseFillType() &&
+            path.getFillType() == SkPath::FillType::kWinding_FillType;
 }
 
 class PLSPathBatch : public GrVertexBatch {
@@ -974,15 +976,13 @@ private:
 
 SkDEBUGCODE(bool inPLSDraw = false;)
 bool GrPLSPathRenderer::onDrawPath(const DrawPathArgs& args) {
-    if (args.fPath->isEmpty()) {
-        return true;
-    }
+    SkASSERT(!args.fShape->isEmpty())
     SkASSERT(!inPLSDraw);
     SkDEBUGCODE(inPLSDraw = true;)
     PLSPathBatch::Geometry geometry;
     geometry.fColor = args.fColor;
     geometry.fViewMatrix = *args.fViewMatrix;
-    geometry.fPath = *args.fPath;
+    args.fShape->asPath(&geometry.fPath);
 
     SkAutoTUnref<GrDrawBatch> batch(PLSPathBatch::Create(geometry));
 
index 2a48018..0995310 100644 (file)
@@ -33,9 +33,8 @@ GrStencilAndCoverPathRenderer::GrStencilAndCoverPathRenderer(GrResourceProvider*
 }
 
 bool GrStencilAndCoverPathRenderer::onCanDrawPath(const CanDrawPathArgs& args) const {
-    // GrPath doesn't support hairline paths. Also, an arbitrary path effect could change
-    // the style type to hairline.
-    if (args.fStyle->hasNonDashPathEffect() || args.fStyle->strokeRec().isHairlineStyle()) {
+    // GrPath doesn't support hairline paths.
+    if (args.fShape->style().couldBeHairline()) {
         return false;
     }
     if (args.fHasUserStencilSettings) {
@@ -70,6 +69,8 @@ void GrStencilAndCoverPathRenderer::onStencilPath(const StencilPathArgs& args) {
     GR_AUDIT_TRAIL_AUTO_FRAME(args.fDrawContext->auditTrail(),
                               "GrStencilAndCoverPathRenderer::onStencilPath");
     SkASSERT(!args.fIsAA || args.fDrawContext->isStencilBufferMultisampled());
+    SkPath path;
+    args.fShape->asPath(&path);
 
     GrPaint paint;
     paint.setXPFactory(GrDisableColorXPFactory::Make());
@@ -77,24 +78,23 @@ void GrStencilAndCoverPathRenderer::onStencilPath(const StencilPathArgs& args) {
 
     const GrPipelineBuilder pipelineBuilder(paint, args.fIsAA);
 
-    SkASSERT(!args.fPath->isInverseFillType());
-    SkAutoTUnref<GrPath> path(get_gr_path(fResourceProvider, *args.fPath, GrStyle::SimpleFill()));
-    args.fDrawContext->drawContextPriv().stencilPath(pipelineBuilder,
-                                                     *args.fClip,
-                                                     *args.fViewMatrix,
-                                                     path,
-                                                     path->getFillType());
+    SkAutoTUnref<GrPath> p(get_gr_path(fResourceProvider, path, GrStyle::SimpleFill()));
+    args.fDrawContext->drawContextPriv().stencilPath(pipelineBuilder, *args.fClip,
+                                                     *args.fViewMatrix, p, p->getFillType());
 }
 
 bool GrStencilAndCoverPathRenderer::onDrawPath(const DrawPathArgs& args) {
     GR_AUDIT_TRAIL_AUTO_FRAME(args.fDrawContext->auditTrail(),
                               "GrStencilAndCoverPathRenderer::onDrawPath");
     SkASSERT(!args.fPaint->isAntiAlias() || args.fDrawContext->isStencilBufferMultisampled());
-    SkASSERT(!args.fStyle->strokeRec().isHairlineStyle());
-    const SkPath& path = *args.fPath;
+    SkASSERT(!args.fShape->style().strokeRec().isHairlineStyle());
+
     const SkMatrix& viewMatrix = *args.fViewMatrix;
 
-    SkAutoTUnref<GrPath> p(get_gr_path(fResourceProvider, path, *args.fStyle));
+    SkPath path;
+    args.fShape->asPath(&path);
+
+    SkAutoTUnref<GrPath> p(get_gr_path(fResourceProvider, path, args.fShape->style()));
 
     if (path.isInverseFillType()) {
         static constexpr GrUserStencilSettings kInvertedCoverPass(
index cec8126..c896e61 100644 (file)
@@ -24,7 +24,7 @@ public:
 
 
 private:
-    StencilSupport onGetStencilSupport(const SkPath&) const override {
+    StencilSupport onGetStencilSupport(const GrShape&) const override {
         return GrPathRenderer::kStencilOnly_StencilSupport;
     }
 
index 6bc8549..060e3f0 100644 (file)
@@ -109,9 +109,10 @@ bool GrTessellatingPathRenderer::onCanDrawPath(const CanDrawPathArgs& args) cons
     // not do antialiasing. It can do convex and concave paths, but we'll leave the convex ones to
     // simpler algorithms. Similary, we skip the non-hairlines that can be treated as hairline.
     // An arbitrary path effect could produce a hairline result so we pass on those.
-    return !IsStrokeHairlineOrEquivalent(*args.fStyle, *args.fViewMatrix, nullptr) &&
-           !args.fStyle->strokeRec().isHairlineStyle() &&
-           !args.fStyle->hasNonDashPathEffect() && !args.fAntiAlias && !args.fPath->isConvex();
+    return !IsStrokeHairlineOrEquivalent(args.fShape->style(), *args.fViewMatrix, nullptr) &&
+           !args.fShape->style().strokeRec().isHairlineStyle() &&
+           !args.fShape->style().hasNonDashPathEffect() && !args.fAntiAlias &&
+           !args.fShape->knownToBeConvex();
 }
 
 class TessellatingPathBatch : public GrVertexBatch {
@@ -292,8 +293,11 @@ bool GrTessellatingPathRenderer::onDrawPath(const DrawPathArgs& args) {
         return false;
     }
     vmi.mapRect(&clipBounds);
-    SkAutoTUnref<GrDrawBatch> batch(TessellatingPathBatch::Create(args.fColor, *args.fPath,
-                                                                  *args.fStyle, *args.fViewMatrix,
+    SkPath path;
+    args.fShape->asPath(&path);
+    SkAutoTUnref<GrDrawBatch> batch(TessellatingPathBatch::Create(args.fColor, path,
+                                                                  args.fShape->style(),
+                                                                  *args.fViewMatrix,
                                                                   clipBounds));
 
     GrPipelineBuilder pipelineBuilder(*args.fPaint, args.fDrawContext->mustUseHWAA(*args.fPaint));
index f1faa60..d5f2c7a 100644 (file)
@@ -21,7 +21,7 @@ public:
 private:
     bool onCanDrawPath(const CanDrawPathArgs& ) const override;
 
-    StencilSupport onGetStencilSupport(const SkPath&) const override {
+    StencilSupport onGetStencilSupport(const GrShape&) const override {
         return GrPathRenderer::kNoSupport_StencilSupport;
     }
 
index 51ccef9..16cf7b2 100644 (file)
@@ -248,8 +248,8 @@ static void test_path(GrDrawContext* drawContext, GrResourceProvider* rp, const
     args.fResourceProvider = rp;
     args.fColor = GrColor_WHITE;
     args.fViewMatrix = &SkMatrix::I();
-    args.fPath = &path;
-    args.fStyle = &style;
+    GrShape shape(path, style);
+    args.fShape = &shape;
     args.fAntiAlias = false;
     tess.drawPath(args);
 }