From 8acedde5970ce70de6d9791ffeda87a65af4ed07 Mon Sep 17 00:00:00 2001 From: bsalomon Date: Fri, 24 Jun 2016 10:42:16 -0700 Subject: [PATCH] Use GrShape in GrPathRenderer. GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=2081383006 Review-Url: https://codereview.chromium.org/2081383006 --- src/gpu/GrClipMaskManager.cpp | 26 ++++---- src/gpu/GrDrawContext.cpp | 66 +++++-------------- src/gpu/GrPathRenderer.h | 64 +++++++++--------- src/gpu/GrPathRendererChain.cpp | 5 +- src/gpu/GrSWMaskHelper.cpp | 49 +++++++------- src/gpu/GrSWMaskHelper.h | 37 +++++------ src/gpu/GrSoftwarePathRenderer.cpp | 75 ++++++++++++---------- src/gpu/GrSoftwarePathRenderer.h | 2 +- src/gpu/GrStyle.h | 7 ++ src/gpu/batches/GrAAConvexPathRenderer.cpp | 11 ++-- src/gpu/batches/GrAADistanceFieldPathRenderer.cpp | 30 ++++----- src/gpu/batches/GrAADistanceFieldPathRenderer.h | 2 +- src/gpu/batches/GrAAHairLinePathRenderer.cpp | 14 ++-- .../batches/GrAALinearizingConvexPathRenderer.cpp | 25 ++++---- src/gpu/batches/GrDashLinePathRenderer.cpp | 8 +-- src/gpu/batches/GrDashLinePathRenderer.h | 2 +- src/gpu/batches/GrDefaultPathRenderer.cpp | 45 +++++-------- src/gpu/batches/GrDefaultPathRenderer.h | 5 +- src/gpu/batches/GrMSAAPathRenderer.cpp | 58 +++++++---------- src/gpu/batches/GrMSAAPathRenderer.h | 4 +- src/gpu/batches/GrPLSPathRenderer.cpp | 12 ++-- src/gpu/batches/GrStencilAndCoverPathRenderer.cpp | 26 ++++---- src/gpu/batches/GrStencilAndCoverPathRenderer.h | 2 +- src/gpu/batches/GrTessellatingPathRenderer.cpp | 14 ++-- src/gpu/batches/GrTessellatingPathRenderer.h | 2 +- tests/TessellatingPathRendererTests.cpp | 4 +- 26 files changed, 275 insertions(+), 320 deletions(-) diff --git a/src/gpu/GrClipMaskManager.cpp b/src/gpu/GrClipMaskManager.cpp index 2047f6f..e5f1330 100644 --- a/src/gpu/GrClipMaskManager.cpp +++ b/src/gpu/GrClipMaskManager.cpp @@ -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 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 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); } } diff --git a/src/gpu/GrDrawContext.cpp b/src/gpu/GrDrawContext.cpp index b5489f1..7ee4e62 100644 --- a/src/gpu/GrDrawContext.cpp +++ b/src/gpu/GrDrawContext.cpp @@ -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 tmpPath; - SkTLazy 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); diff --git a/src/gpu/GrPathRenderer.h b/src/gpu/GrPathRenderer.h index 20c6967..96e603f 100644 --- a/src/gpu/GrPathRenderer.h +++ b/src/gpu/GrPathRenderer.h @@ -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); diff --git a/src/gpu/GrPathRendererChain.cpp b/src/gpu/GrPathRendererChain.cpp index 8994186..bed56f8 100644 --- a/src/gpu/GrPathRendererChain.cpp +++ b/src/gpu/GrPathRendererChain.cpp @@ -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) { diff --git a/src/gpu/GrSWMaskHelper.cpp b/src/gpu/GrSWMaskHelper.cpp index 0c42a2b..496dadf 100644 --- a/src/gpu/GrSWMaskHelper.cpp +++ b/src/gpu/GrSWMaskHelper.cpp @@ -11,13 +11,10 @@ #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; diff --git a/src/gpu/GrSWMaskHelper.h b/src/gpu/GrSWMaskHelper.h index 107c77e..b015b15 100644 --- a/src/gpu/GrSWMaskHelper.h +++ b/src/gpu/GrSWMaskHelper.h @@ -19,11 +19,10 @@ 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 diff --git a/src/gpu/GrSoftwarePathRenderer.cpp b/src/gpu/GrSoftwarePathRenderer.cpp index fd25bbb..983bd20 100644 --- a/src/gpu/GrSoftwarePathRenderer.cpp +++ b/src/gpu/GrSoftwarePathRenderer.cpp @@ -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 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 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; diff --git a/src/gpu/GrSoftwarePathRenderer.h b/src/gpu/GrSoftwarePathRenderer.h index 4c756d5..30edfeb 100644 --- a/src/gpu/GrSoftwarePathRenderer.h +++ b/src/gpu/GrSoftwarePathRenderer.h @@ -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; } diff --git a/src/gpu/GrStyle.h b/src/gpu/GrStyle.h index 326f800..478564f 100644 --- a/src/gpu/GrStyle.h +++ b/src/gpu/GrStyle.h @@ -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()); } diff --git a/src/gpu/batches/GrAAConvexPathRenderer.cpp b/src/gpu/batches/GrAAConvexPathRenderer.cpp index 390162e..bb097aa 100644 --- a/src/gpu/batches/GrAAConvexPathRenderer.cpp +++ b/src/gpu/batches/GrAAConvexPathRenderer.cpp @@ -681,8 +681,8 @@ sk_sp 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 batch(AAConvexPathBatch::Create(geometry)); diff --git a/src/gpu/batches/GrAADistanceFieldPathRenderer.cpp b/src/gpu/batches/GrAADistanceFieldPathRenderer.cpp index e6be590..6cf3e4b 100644 --- a/src/gpu/batches/GrAADistanceFieldPathRenderer.cpp +++ b/src/gpu/batches/GrAADistanceFieldPathRenderer.cpp @@ -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 batch(AADistanceFieldPathBatch::Create(geometry, *args.fViewMatrix, fAtlas, diff --git a/src/gpu/batches/GrAADistanceFieldPathRenderer.h b/src/gpu/batches/GrAADistanceFieldPathRenderer.h index 099d0c7..e5c7dce 100755 --- a/src/gpu/batches/GrAADistanceFieldPathRenderer.h +++ b/src/gpu/batches/GrAADistanceFieldPathRenderer.h @@ -23,7 +23,7 @@ public: virtual ~GrAADistanceFieldPathRenderer(); private: - StencilSupport onGetStencilSupport(const SkPath&) const override { + StencilSupport onGetStencilSupport(const GrShape&) const override { return GrPathRenderer::kNoSupport_StencilSupport; } diff --git a/src/gpu/batches/GrAAHairLinePathRenderer.cpp b/src/gpu/batches/GrAAHairLinePathRenderer.cpp index f44c454..1f7407c 100644 --- a/src/gpu/batches/GrAAHairLinePathRenderer.cpp +++ b/src/gpu/batches/GrAAHairLinePathRenderer.cpp @@ -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 batch(create_hairline_batch(args.fColor, *args.fViewMatrix, *args.fPath, - *args.fStyle, devClipBounds)); + SkPath path; + args.fShape->asPath(&path); + SkAutoTUnref 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; diff --git a/src/gpu/batches/GrAALinearizingConvexPathRenderer.cpp b/src/gpu/batches/GrAALinearizingConvexPathRenderer.cpp index 1847a67..9748829 100644 --- a/src/gpu/batches/GrAALinearizingConvexPathRenderer.cpp +++ b/src/gpu/batches/GrAALinearizingConvexPathRenderer.cpp @@ -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 batch(AAFlatteningConvexPathBatch::Create(geometry)); diff --git a/src/gpu/batches/GrDashLinePathRenderer.cpp b/src/gpu/batches/GrDashLinePathRenderer.cpp index a442b66..8dba7b9 100644 --- a/src/gpu/batches/GrDashLinePathRenderer.cpp +++ b/src/gpu/batches/GrDashLinePathRenderer.cpp @@ -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 batch(GrDashingEffect::CreateDashLineBatch(args.fColor, *args.fViewMatrix, pts, aaMode, - *args.fStyle)); + args.fShape->style())); if (!batch) { return false; } diff --git a/src/gpu/batches/GrDashLinePathRenderer.h b/src/gpu/batches/GrDashLinePathRenderer.h index e25f882..d959421 100644 --- a/src/gpu/batches/GrDashLinePathRenderer.h +++ b/src/gpu/batches/GrDashLinePathRenderer.h @@ -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; } diff --git a/src/gpu/batches/GrDefaultPathRenderer.cpp b/src/gpu/batches/GrDefaultPathRenderer.cpp index 7fd7913..1e807f8 100644 --- a/src/gpu/batches/GrDefaultPathRenderer.cpp +++ b/src/gpu/batches/GrDefaultPathRenderer.cpp @@ -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); } /////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/gpu/batches/GrDefaultPathRenderer.h b/src/gpu/batches/GrDefaultPathRenderer.h index 277d7a8..04e1013 100644 --- a/src/gpu/batches/GrDefaultPathRenderer.h +++ b/src/gpu/batches/GrDefaultPathRenderer.h @@ -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; diff --git a/src/gpu/batches/GrMSAAPathRenderer.cpp b/src/gpu/batches/GrMSAAPathRenderer.cpp index edc285e..31b9ebf 100644 --- a/src/gpu/batches/GrMSAAPathRenderer.cpp +++ b/src/gpu/batches/GrMSAAPathRenderer.cpp @@ -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 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); } /////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/gpu/batches/GrMSAAPathRenderer.h b/src/gpu/batches/GrMSAAPathRenderer.h index 0c27e8c..e1cf4a3 100644 --- a/src/gpu/batches/GrMSAAPathRenderer.h +++ b/src/gpu/batches/GrMSAAPathRenderer.h @@ -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; diff --git a/src/gpu/batches/GrPLSPathRenderer.cpp b/src/gpu/batches/GrPLSPathRenderer.cpp index a81b883..ba84d73 100644 --- a/src/gpu/batches/GrPLSPathRenderer.cpp +++ b/src/gpu/batches/GrPLSPathRenderer.cpp @@ -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 batch(PLSPathBatch::Create(geometry)); diff --git a/src/gpu/batches/GrStencilAndCoverPathRenderer.cpp b/src/gpu/batches/GrStencilAndCoverPathRenderer.cpp index 2a48018..0995310 100644 --- a/src/gpu/batches/GrStencilAndCoverPathRenderer.cpp +++ b/src/gpu/batches/GrStencilAndCoverPathRenderer.cpp @@ -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 path(get_gr_path(fResourceProvider, *args.fPath, GrStyle::SimpleFill())); - args.fDrawContext->drawContextPriv().stencilPath(pipelineBuilder, - *args.fClip, - *args.fViewMatrix, - path, - path->getFillType()); + SkAutoTUnref 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 p(get_gr_path(fResourceProvider, path, *args.fStyle)); + SkPath path; + args.fShape->asPath(&path); + + SkAutoTUnref p(get_gr_path(fResourceProvider, path, args.fShape->style())); if (path.isInverseFillType()) { static constexpr GrUserStencilSettings kInvertedCoverPass( diff --git a/src/gpu/batches/GrStencilAndCoverPathRenderer.h b/src/gpu/batches/GrStencilAndCoverPathRenderer.h index cec8126..c896e61 100644 --- a/src/gpu/batches/GrStencilAndCoverPathRenderer.h +++ b/src/gpu/batches/GrStencilAndCoverPathRenderer.h @@ -24,7 +24,7 @@ public: private: - StencilSupport onGetStencilSupport(const SkPath&) const override { + StencilSupport onGetStencilSupport(const GrShape&) const override { return GrPathRenderer::kStencilOnly_StencilSupport; } diff --git a/src/gpu/batches/GrTessellatingPathRenderer.cpp b/src/gpu/batches/GrTessellatingPathRenderer.cpp index 6bc8549..060e3f0 100644 --- a/src/gpu/batches/GrTessellatingPathRenderer.cpp +++ b/src/gpu/batches/GrTessellatingPathRenderer.cpp @@ -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 batch(TessellatingPathBatch::Create(args.fColor, *args.fPath, - *args.fStyle, *args.fViewMatrix, + SkPath path; + args.fShape->asPath(&path); + SkAutoTUnref batch(TessellatingPathBatch::Create(args.fColor, path, + args.fShape->style(), + *args.fViewMatrix, clipBounds)); GrPipelineBuilder pipelineBuilder(*args.fPaint, args.fDrawContext->mustUseHWAA(*args.fPaint)); diff --git a/src/gpu/batches/GrTessellatingPathRenderer.h b/src/gpu/batches/GrTessellatingPathRenderer.h index f1faa60..d5f2c7a 100644 --- a/src/gpu/batches/GrTessellatingPathRenderer.h +++ b/src/gpu/batches/GrTessellatingPathRenderer.h @@ -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; } diff --git a/tests/TessellatingPathRendererTests.cpp b/tests/TessellatingPathRendererTests.cpp index 51ccef9..16cf7b2 100644 --- a/tests/TessellatingPathRendererTests.cpp +++ b/tests/TessellatingPathRendererTests.cpp @@ -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); } -- 2.7.4