diff options
author | Chris Dalton <csmartdalton@google.com> | 2017-09-04 01:47:11 -0600 |
---|---|---|
committer | Skia Commit-Bot <skia-commit-bot@chromium.org> | 2017-09-07 17:04:51 +0000 |
commit | 60f42494f5d45c38e260ce089cdddfb600f799b2 (patch) | |
tree | f7c6235077d40c2cee2b703eb37cbe48b8350493 /src | |
parent | 2bbdcc44c63974f29f3743bb58d929601a3f65c6 (diff) |
Improve GrPathRendererChain heuristics
Changes GrPathRenderer::canDrawPath to return a 'CanDrawPath' enum,
which contains a new kAsBackup value that means "I'm better than SW,
but give the path renderers below me a chance first."
Bug: skia:
Change-Id: I45aac5462ca1bc0bc839eb1c315db9493901a07e
Reviewed-on: https://skia-review.googlesource.com/42222
Reviewed-by: Brian Osman <brianosman@google.com>
Reviewed-by: Brian Salomon <bsalomon@google.com>
Commit-Queue: Chris Dalton <csmartdalton@google.com>
Diffstat (limited to 'src')
25 files changed, 154 insertions, 94 deletions
diff --git a/src/gpu/GrDrawingManager.cpp b/src/gpu/GrDrawingManager.cpp index 31da84e7e6..bbcd8a85d9 100644 --- a/src/gpu/GrDrawingManager.cpp +++ b/src/gpu/GrDrawingManager.cpp @@ -312,7 +312,7 @@ GrPathRenderer* GrDrawingManager::getPathRenderer(const GrPathRenderer::CanDrawP new GrSoftwarePathRenderer(fContext->resourceProvider(), fOptionsForPathRendererChain.fAllowPathMaskCaching); } - if (fSoftwarePathRenderer->canDrawPath(args)) { + if (GrPathRenderer::CanDrawPath::kNo != fSoftwarePathRenderer->canDrawPath(args)) { pr = fSoftwarePathRenderer; } } diff --git a/src/gpu/GrPathRenderer.h b/src/gpu/GrPathRenderer.h index a3cf8c6151..cf0ef6effc 100644 --- a/src/gpu/GrPathRenderer.h +++ b/src/gpu/GrPathRenderer.h @@ -67,6 +67,12 @@ public: return this->onGetStencilSupport(shape); } + enum class CanDrawPath { + kNo, + kAsBackup, // i.e. This renderer is better than SW fallback if no others can draw the path. + kYes + }; + /** Args to canDrawPath() * * fCaps The context caps @@ -94,13 +100,11 @@ public: }; /** - * Returns true if this path renderer is able to render the path. Returning false allows the - * caller to fallback to another path renderer This function is called when searching for a path - * renderer capable of rendering a path. - * - * @return true if the path can be drawn by this object, false otherwise. + * Returns how well this path renderer is able to render the given path. Returning kNo or + * kAsBackup allows the caller to keep searching for a better path renderer. This function is + * called when searching for the best path renderer to draw a path. */ - bool canDrawPath(const CanDrawPathArgs& args) const { + CanDrawPath canDrawPath(const CanDrawPathArgs& args) const { SkDEBUGCODE(args.validate();) return this->onCanDrawPath(args); } @@ -158,7 +162,7 @@ public: GrFSAAType::kUnifiedMSAA != args.fRenderTargetContext->fsaaType())); SkASSERT(!(canArgs.fAAType == GrAAType::kMixedSamples && GrFSAAType::kMixedSamples != args.fRenderTargetContext->fsaaType())); - SkASSERT(this->canDrawPath(canArgs)); + SkASSERT(CanDrawPath::kNo != this->canDrawPath(canArgs)); if (!args.fUserStencilSettings->isUnused()) { SkPath path; args.fShape->asPath(&path); @@ -253,7 +257,7 @@ private: /** * Subclass implementation of canDrawPath() */ - virtual bool onCanDrawPath(const CanDrawPathArgs& args) const = 0; + virtual CanDrawPath onCanDrawPath(const CanDrawPathArgs& args) const = 0; /** * Subclass implementation of stencilPath(). Subclass must override iff it ever returns diff --git a/src/gpu/GrPathRendererChain.cpp b/src/gpu/GrPathRendererChain.cpp index 354d086a22..4a39f256fe 100644 --- a/src/gpu/GrPathRendererChain.cpp +++ b/src/gpu/GrPathRendererChain.cpp @@ -96,18 +96,29 @@ 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.fShape); - if (support < minStencilSupport) { - continue; - } else if (stencilSupport) { - *stencilSupport = support; - } + GrPathRenderer* bestPathRenderer = nullptr; + for (const sk_sp<GrPathRenderer>& pr : fChain) { + GrPathRenderer::StencilSupport support = GrPathRenderer::kNoSupport_StencilSupport; + if (GrPathRenderer::kNoSupport_StencilSupport != minStencilSupport) { + support = pr->getStencilSupport(*args.fShape); + if (support < minStencilSupport) { + continue; } - return fChain[i].get(); + } + GrPathRenderer::CanDrawPath canDrawPath = pr->canDrawPath(args); + if (GrPathRenderer::CanDrawPath::kNo == canDrawPath) { + continue; + } + if (GrPathRenderer::CanDrawPath::kAsBackup == canDrawPath && bestPathRenderer) { + continue; + } + if (stencilSupport) { + *stencilSupport = support; + } + bestPathRenderer = pr.get(); + if (GrPathRenderer::CanDrawPath::kYes == canDrawPath) { + break; } } - return nullptr; + return bestPathRenderer; } diff --git a/src/gpu/GrSoftwarePathRenderer.cpp b/src/gpu/GrSoftwarePathRenderer.cpp index 5780cee4e8..37433ff0c4 100644 --- a/src/gpu/GrSoftwarePathRenderer.cpp +++ b/src/gpu/GrSoftwarePathRenderer.cpp @@ -22,11 +22,16 @@ #include "ops/GrRectOpFactory.h" //////////////////////////////////////////////////////////////////////////////// -bool GrSoftwarePathRenderer::onCanDrawPath(const CanDrawPathArgs& args) const { +GrPathRenderer::CanDrawPath +GrSoftwarePathRenderer::onCanDrawPath(const CanDrawPathArgs& args) const { // 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(fResourceProvider) && - (args.fAAType == GrAAType::kCoverage || args.fAAType == GrAAType::kNone); + if (!args.fShape->style().applies() && SkToBool(fResourceProvider) && + (args.fAAType == GrAAType::kCoverage || args.fAAType == GrAAType::kNone)) { + // This is the fallback renderer for when a path is too complicated for the GPU ones. + return CanDrawPath::kAsBackup; + } + return CanDrawPath::kNo; } //////////////////////////////////////////////////////////////////////////////// diff --git a/src/gpu/GrSoftwarePathRenderer.h b/src/gpu/GrSoftwarePathRenderer.h index 2421fa4d70..d36b2f6486 100644 --- a/src/gpu/GrSoftwarePathRenderer.h +++ b/src/gpu/GrSoftwarePathRenderer.h @@ -53,7 +53,7 @@ private: return GrPathRenderer::kNoSupport_StencilSupport; } - bool onCanDrawPath(const CanDrawPathArgs&) const override; + CanDrawPath onCanDrawPath(const CanDrawPathArgs&) const override; bool onDrawPath(const DrawPathArgs&) override; diff --git a/src/gpu/ccpr/GrCoverageCountingPathRenderer.cpp b/src/gpu/ccpr/GrCoverageCountingPathRenderer.cpp index 2bec4ffeb1..4aff0a918c 100644 --- a/src/gpu/ccpr/GrCoverageCountingPathRenderer.cpp +++ b/src/gpu/ccpr/GrCoverageCountingPathRenderer.cpp @@ -39,17 +39,22 @@ GrCoverageCountingPathRenderer::CreateIfSupported(const GrCaps& caps) { new GrCoverageCountingPathRenderer : nullptr); } -bool GrCoverageCountingPathRenderer::onCanDrawPath(const CanDrawPathArgs& args) const { +GrPathRenderer::CanDrawPath +GrCoverageCountingPathRenderer::onCanDrawPath(const CanDrawPathArgs& args) const { if (!args.fShape->style().isSimpleFill() || args.fShape->inverseFilled() || args.fViewMatrix->hasPerspective() || GrAAType::kCoverage != args.fAAType) { - return false; + return CanDrawPath::kNo; } SkPath path; args.fShape->asPath(&path); - return !SkPathPriv::ConicWeightCnt(path); + if (SkPathPriv::ConicWeightCnt(path)) { + return CanDrawPath::kNo; + } + + return CanDrawPath::kYes; } bool GrCoverageCountingPathRenderer::onDrawPath(const DrawPathArgs& args) { diff --git a/src/gpu/ccpr/GrCoverageCountingPathRenderer.h b/src/gpu/ccpr/GrCoverageCountingPathRenderer.h index e1e28a40bc..d7617281a2 100644 --- a/src/gpu/ccpr/GrCoverageCountingPathRenderer.h +++ b/src/gpu/ccpr/GrCoverageCountingPathRenderer.h @@ -38,7 +38,7 @@ public: StencilSupport onGetStencilSupport(const GrShape&) const override { return GrPathRenderer::kNoSupport_StencilSupport; } - bool onCanDrawPath(const CanDrawPathArgs& args) const override; + CanDrawPath onCanDrawPath(const CanDrawPathArgs& args) const override; bool onDrawPath(const DrawPathArgs&) final; // GrOnFlushCallbackObject overrides. diff --git a/src/gpu/ops/GrAAConvexPathRenderer.cpp b/src/gpu/ops/GrAAConvexPathRenderer.cpp index 425dbae148..0fe74433ff 100644 --- a/src/gpu/ops/GrAAConvexPathRenderer.cpp +++ b/src/gpu/ops/GrAAConvexPathRenderer.cpp @@ -665,10 +665,14 @@ sk_sp<GrGeometryProcessor> QuadEdgeEffect::TestCreate(GrProcessorTestData* d) { /////////////////////////////////////////////////////////////////////////////// -bool GrAAConvexPathRenderer::onCanDrawPath(const CanDrawPathArgs& args) const { - return (args.fCaps->shaderCaps()->shaderDerivativeSupport() && - (GrAAType::kCoverage == args.fAAType) && args.fShape->style().isSimpleFill() && - !args.fShape->inverseFilled() && args.fShape->knownToBeConvex()); +GrPathRenderer::CanDrawPath +GrAAConvexPathRenderer::onCanDrawPath(const CanDrawPathArgs& args) const { + if (args.fCaps->shaderCaps()->shaderDerivativeSupport() && + (GrAAType::kCoverage == args.fAAType) && args.fShape->style().isSimpleFill() && + !args.fShape->inverseFilled() && args.fShape->knownToBeConvex()) { + return CanDrawPath::kYes; + } + return CanDrawPath::kNo; } // extract the result vertices and indices from the GrAAConvexTessellator diff --git a/src/gpu/ops/GrAAConvexPathRenderer.h b/src/gpu/ops/GrAAConvexPathRenderer.h index 420ca60139..a31d6b9593 100644 --- a/src/gpu/ops/GrAAConvexPathRenderer.h +++ b/src/gpu/ops/GrAAConvexPathRenderer.h @@ -15,7 +15,7 @@ public: GrAAConvexPathRenderer(); private: - bool onCanDrawPath(const CanDrawPathArgs&) const override; + CanDrawPath onCanDrawPath(const CanDrawPathArgs&) const override; bool onDrawPath(const DrawPathArgs&) override; }; diff --git a/src/gpu/ops/GrAAHairLinePathRenderer.cpp b/src/gpu/ops/GrAAHairLinePathRenderer.cpp index e00ca3fd5d..ba72eacd7e 100644 --- a/src/gpu/ops/GrAAHairLinePathRenderer.cpp +++ b/src/gpu/ops/GrAAHairLinePathRenderer.cpp @@ -677,26 +677,27 @@ static void add_line(const SkPoint p[2], /////////////////////////////////////////////////////////////////////////////// -bool GrAAHairLinePathRenderer::onCanDrawPath(const CanDrawPathArgs& args) const { +GrPathRenderer::CanDrawPath +GrAAHairLinePathRenderer::onCanDrawPath(const CanDrawPathArgs& args) const { if (GrAAType::kCoverage != args.fAAType) { - return false; + return CanDrawPath::kNo; } if (!IsStrokeHairlineOrEquivalent(args.fShape->style(), *args.fViewMatrix, nullptr)) { - return false; + return CanDrawPath::kNo; } // We don't currently handle dashing in this class though perhaps we should. if (args.fShape->style().pathEffect()) { - return false; + return CanDrawPath::kNo; } if (SkPath::kLine_SegmentMask == args.fShape->segmentMask() || args.fCaps->shaderCaps()->shaderDerivativeSupport()) { - return true; + return CanDrawPath::kYes; } - return false; + return CanDrawPath::kNo; } template <class VertexType> diff --git a/src/gpu/ops/GrAAHairLinePathRenderer.h b/src/gpu/ops/GrAAHairLinePathRenderer.h index e2406a5c01..b52d5e9959 100644 --- a/src/gpu/ops/GrAAHairLinePathRenderer.h +++ b/src/gpu/ops/GrAAHairLinePathRenderer.h @@ -19,7 +19,7 @@ public: typedef SkTArray<float, true> FloatArray; private: - bool onCanDrawPath(const CanDrawPathArgs&) const override; + CanDrawPath onCanDrawPath(const CanDrawPathArgs&) const override; bool onDrawPath(const DrawPathArgs&) override; diff --git a/src/gpu/ops/GrAALinearizingConvexPathRenderer.cpp b/src/gpu/ops/GrAALinearizingConvexPathRenderer.cpp index c1fd4f7e65..d206951ce4 100644 --- a/src/gpu/ops/GrAALinearizingConvexPathRenderer.cpp +++ b/src/gpu/ops/GrAALinearizingConvexPathRenderer.cpp @@ -34,39 +34,46 @@ GrAALinearizingConvexPathRenderer::GrAALinearizingConvexPathRenderer() { /////////////////////////////////////////////////////////////////////////////// -bool GrAALinearizingConvexPathRenderer::onCanDrawPath(const CanDrawPathArgs& args) const { +GrPathRenderer::CanDrawPath +GrAALinearizingConvexPathRenderer::onCanDrawPath(const CanDrawPathArgs& args) const { if (GrAAType::kCoverage != args.fAAType) { - return false; + return CanDrawPath::kNo; } if (!args.fShape->knownToBeConvex()) { - return false; + return CanDrawPath::kNo; } if (args.fShape->style().pathEffect()) { - return false; + return CanDrawPath::kNo; } if (args.fShape->inverseFilled()) { - return false; + return CanDrawPath::kNo; } if (args.fShape->bounds().width() <= 0 && args.fShape->bounds().height() <= 0) { // Stroked zero length lines should draw, but this PR doesn't handle that case - return false; + return CanDrawPath::kNo; } const SkStrokeRec& stroke = args.fShape->style().strokeRec(); if (stroke.getStyle() == SkStrokeRec::kStroke_Style || stroke.getStyle() == SkStrokeRec::kStrokeAndFill_Style) { if (!args.fViewMatrix->isSimilarity()) { - return false; + return CanDrawPath::kNo; } SkScalar strokeWidth = args.fViewMatrix->getMaxScale() * stroke.getWidth(); if (strokeWidth < 1.0f && stroke.getStyle() == SkStrokeRec::kStroke_Style) { - return false; + return CanDrawPath::kNo; } - return strokeWidth <= kMaxStrokeWidth && - args.fShape->knownToBeClosed() && - stroke.getJoin() != SkPaint::Join::kRound_Join; + if (strokeWidth > kMaxStrokeWidth || + !args.fShape->knownToBeClosed() || + stroke.getJoin() == SkPaint::Join::kRound_Join) { + return CanDrawPath::kNo; + } + return CanDrawPath::kYes; + } + if (stroke.getStyle() != SkStrokeRec::kFill_Style) { + return CanDrawPath::kNo; } - return stroke.getStyle() == SkStrokeRec::kFill_Style; + return CanDrawPath::kYes; } // extract the result vertices and indices from the GrAAConvexTessellator diff --git a/src/gpu/ops/GrAALinearizingConvexPathRenderer.h b/src/gpu/ops/GrAALinearizingConvexPathRenderer.h index afee5db4d4..4fdcb12a26 100644 --- a/src/gpu/ops/GrAALinearizingConvexPathRenderer.h +++ b/src/gpu/ops/GrAALinearizingConvexPathRenderer.h @@ -15,7 +15,7 @@ public: GrAALinearizingConvexPathRenderer(); private: - bool onCanDrawPath(const CanDrawPathArgs&) const override; + CanDrawPath onCanDrawPath(const CanDrawPathArgs&) const override; bool onDrawPath(const DrawPathArgs&) override; }; diff --git a/src/gpu/ops/GrDashLinePathRenderer.cpp b/src/gpu/ops/GrDashLinePathRenderer.cpp index 38d486c79f..73c2b3e8f2 100644 --- a/src/gpu/ops/GrDashLinePathRenderer.cpp +++ b/src/gpu/ops/GrDashLinePathRenderer.cpp @@ -12,18 +12,22 @@ #include "ops/GrDashOp.h" #include "ops/GrMeshDrawOp.h" -bool GrDashLinePathRenderer::onCanDrawPath(const CanDrawPathArgs& args) const { +GrPathRenderer::CanDrawPath +GrDashLinePathRenderer::onCanDrawPath(const CanDrawPathArgs& args) const { SkPoint pts[2]; bool inverted; if (args.fShape->style().isDashed() && args.fShape->asLine(pts, &inverted)) { if (args.fAAType == GrAAType::kMixedSamples) { - return false; + return CanDrawPath::kNo; } // We should never have an inverse dashed case. SkASSERT(!inverted); - return GrDashOp::CanDrawDashLine(pts, args.fShape->style(), *args.fViewMatrix); + if (!GrDashOp::CanDrawDashLine(pts, args.fShape->style(), *args.fViewMatrix)) { + return CanDrawPath::kNo; + } + return CanDrawPath::kYes; } - return false; + return CanDrawPath::kNo; } bool GrDashLinePathRenderer::onDrawPath(const DrawPathArgs& args) { diff --git a/src/gpu/ops/GrDashLinePathRenderer.h b/src/gpu/ops/GrDashLinePathRenderer.h index 11abf99396..23227bc824 100644 --- a/src/gpu/ops/GrDashLinePathRenderer.h +++ b/src/gpu/ops/GrDashLinePathRenderer.h @@ -14,7 +14,7 @@ class GrGpu; class GrDashLinePathRenderer : public GrPathRenderer { private: - bool onCanDrawPath(const CanDrawPathArgs&) const override; + CanDrawPath onCanDrawPath(const CanDrawPathArgs&) const override; StencilSupport onGetStencilSupport(const GrShape&) const override { return kNoSupport_StencilSupport; diff --git a/src/gpu/ops/GrDefaultPathRenderer.cpp b/src/gpu/ops/GrDefaultPathRenderer.cpp index e3b48a8db9..9741781013 100644 --- a/src/gpu/ops/GrDefaultPathRenderer.cpp +++ b/src/gpu/ops/GrDefaultPathRenderer.cpp @@ -609,15 +609,20 @@ bool GrDefaultPathRenderer::internalDrawPath(GrRenderTargetContext* renderTarget return true; } -bool GrDefaultPathRenderer::onCanDrawPath(const CanDrawPathArgs& args) const { +GrPathRenderer::CanDrawPath +GrDefaultPathRenderer::onCanDrawPath(const CanDrawPathArgs& args) const { bool isHairline = IsStrokeHairlineOrEquivalent(args.fShape->style(), *args.fViewMatrix, nullptr); // If we aren't a single_pass_shape or hairline, we require stencil buffers. if (!(single_pass_shape(*args.fShape) || isHairline) && args.fCaps->avoidStencilBuffers()) { - return false; + return CanDrawPath::kNo; } // This can draw any path with any simple fill style but doesn't do coverage-based antialiasing. - return GrAAType::kCoverage != args.fAAType && - (args.fShape->style().isSimpleFill() || isHairline); + if (GrAAType::kCoverage == args.fAAType || + (!args.fShape->style().isSimpleFill() && !isHairline)) { + return CanDrawPath::kNo; + } + // This is the fallback renderer for when a path is too complicated for the others to draw. + return CanDrawPath::kAsBackup; } bool GrDefaultPathRenderer::onDrawPath(const DrawPathArgs& args) { diff --git a/src/gpu/ops/GrDefaultPathRenderer.h b/src/gpu/ops/GrDefaultPathRenderer.h index 7f7ab2a5e0..f7d98190c2 100644 --- a/src/gpu/ops/GrDefaultPathRenderer.h +++ b/src/gpu/ops/GrDefaultPathRenderer.h @@ -23,7 +23,7 @@ public: private: StencilSupport onGetStencilSupport(const GrShape&) const override; - bool onCanDrawPath(const CanDrawPathArgs&) const override; + CanDrawPath onCanDrawPath(const CanDrawPathArgs&) const override; bool onDrawPath(const DrawPathArgs&) override; diff --git a/src/gpu/ops/GrMSAAPathRenderer.cpp b/src/gpu/ops/GrMSAAPathRenderer.cpp index ef19367f61..b80a811430 100644 --- a/src/gpu/ops/GrMSAAPathRenderer.cpp +++ b/src/gpu/ops/GrMSAAPathRenderer.cpp @@ -682,15 +682,18 @@ bool GrMSAAPathRenderer::internalDrawPath(GrRenderTargetContext* renderTargetCon return true; } -bool GrMSAAPathRenderer::onCanDrawPath(const CanDrawPathArgs& args) const { +GrPathRenderer::CanDrawPath GrMSAAPathRenderer::onCanDrawPath(const CanDrawPathArgs& args) const { // If we aren't a single_pass_shape, we require stencil buffers. if (!single_pass_shape(*args.fShape) && args.fCaps->avoidStencilBuffers()) { - return false; + return CanDrawPath::kNo; } // This path renderer only fills and relies on MSAA for antialiasing. Stroked shapes are // handled by passing on the original shape and letting the caller compute the stroked shape // which will have a fill style. - return args.fShape->style().isSimpleFill() && (GrAAType::kCoverage != args.fAAType); + if (!args.fShape->style().isSimpleFill() || GrAAType::kCoverage == args.fAAType) { + return CanDrawPath::kNo; + } + return CanDrawPath::kYes; } bool GrMSAAPathRenderer::onDrawPath(const DrawPathArgs& args) { diff --git a/src/gpu/ops/GrMSAAPathRenderer.h b/src/gpu/ops/GrMSAAPathRenderer.h index 13d3e15a7e..1353867f16 100644 --- a/src/gpu/ops/GrMSAAPathRenderer.h +++ b/src/gpu/ops/GrMSAAPathRenderer.h @@ -15,7 +15,7 @@ class SK_API GrMSAAPathRenderer : public GrPathRenderer { private: StencilSupport onGetStencilSupport(const GrShape&) const override; - bool onCanDrawPath(const CanDrawPathArgs&) const override; + CanDrawPath onCanDrawPath(const CanDrawPathArgs&) const override; bool onDrawPath(const DrawPathArgs&) override; diff --git a/src/gpu/ops/GrSmallPathRenderer.cpp b/src/gpu/ops/GrSmallPathRenderer.cpp index cfdf8734c9..1b0648615d 100644 --- a/src/gpu/ops/GrSmallPathRenderer.cpp +++ b/src/gpu/ops/GrSmallPathRenderer.cpp @@ -81,30 +81,30 @@ GrSmallPathRenderer::~GrSmallPathRenderer() { } //////////////////////////////////////////////////////////////////////////////// -bool GrSmallPathRenderer::onCanDrawPath(const CanDrawPathArgs& args) const { +GrPathRenderer::CanDrawPath GrSmallPathRenderer::onCanDrawPath(const CanDrawPathArgs& args) const { if (!args.fCaps->shaderCaps()->shaderDerivativeSupport()) { - return false; + return CanDrawPath::kNo; } // If the shape has no key then we won't get any reuse. if (!args.fShape->hasUnstyledKey()) { - return false; + return CanDrawPath::kNo; } // This only supports filled paths, however, the caller may apply the style to make a filled // path and try again. if (!args.fShape->style().isSimpleFill()) { - return false; + return CanDrawPath::kNo; } // This does non-inverse coverage-based antialiased fills. if (GrAAType::kCoverage != args.fAAType) { - return false; + return CanDrawPath::kNo; } // TODO: Support inverse fill if (args.fShape->inverseFilled()) { - return false; + return CanDrawPath::kNo; } // currently don't support perspective if (args.fViewMatrix->hasPerspective()) { - return false; + return CanDrawPath::kNo; } // Only support paths with bounds within kMaxDim by kMaxDim, @@ -112,15 +112,18 @@ bool GrSmallPathRenderer::onCanDrawPath(const CanDrawPathArgs& args) const { // The goal is to accelerate rendering of lots of small paths that may be scaling. SkScalar scaleFactors[2]; if (!args.fViewMatrix->getMinMaxScales(scaleFactors)) { - return false; + return CanDrawPath::kNo; } SkRect bounds = args.fShape->styledBounds(); SkScalar minDim = SkMinScalar(bounds.width(), bounds.height()); SkScalar maxDim = SkMaxScalar(bounds.width(), bounds.height()); SkScalar minSize = minDim * SkScalarAbs(scaleFactors[0]); SkScalar maxSize = maxDim * SkScalarAbs(scaleFactors[1]); + if (maxDim > kMaxDim || kMinSize > minSize || maxSize > kMaxSize) { + return CanDrawPath::kNo; + } - return maxDim <= kMaxDim && kMinSize <= minSize && maxSize <= kMaxSize; + return CanDrawPath::kYes; } //////////////////////////////////////////////////////////////////////////////// diff --git a/src/gpu/ops/GrSmallPathRenderer.h b/src/gpu/ops/GrSmallPathRenderer.h index d10c4baa86..b958baa843 100644 --- a/src/gpu/ops/GrSmallPathRenderer.h +++ b/src/gpu/ops/GrSmallPathRenderer.h @@ -31,7 +31,7 @@ private: return GrPathRenderer::kNoSupport_StencilSupport; } - bool onCanDrawPath(const CanDrawPathArgs&) const override; + CanDrawPath onCanDrawPath(const CanDrawPathArgs&) const override; bool onDrawPath(const DrawPathArgs&) override; diff --git a/src/gpu/ops/GrStencilAndCoverPathRenderer.cpp b/src/gpu/ops/GrStencilAndCoverPathRenderer.cpp index 4d86efdc0e..3179ebacc8 100644 --- a/src/gpu/ops/GrStencilAndCoverPathRenderer.cpp +++ b/src/gpu/ops/GrStencilAndCoverPathRenderer.cpp @@ -31,18 +31,22 @@ GrStencilAndCoverPathRenderer::GrStencilAndCoverPathRenderer(GrResourceProvider* : fResourceProvider(resourceProvider) { } -bool GrStencilAndCoverPathRenderer::onCanDrawPath(const CanDrawPathArgs& args) const { +GrPathRenderer::CanDrawPath +GrStencilAndCoverPathRenderer::onCanDrawPath(const CanDrawPathArgs& args) const { // GrPath doesn't support hairline paths. An arbitrary path effect could produce a hairline // path. if (args.fShape->style().strokeRec().isHairlineStyle() || args.fShape->style().hasNonDashPathEffect()) { - return false; + return CanDrawPath::kNo; } if (args.fHasUserStencilSettings) { - return false; + return CanDrawPath::kNo; } // doesn't do per-path AA, relies on the target having MSAA. - return (GrAAType::kCoverage != args.fAAType); + if (GrAAType::kCoverage == args.fAAType) { + return CanDrawPath::kNo; + } + return CanDrawPath::kYes; } static GrPath* get_gr_path(GrResourceProvider* resourceProvider, const GrShape& shape) { diff --git a/src/gpu/ops/GrStencilAndCoverPathRenderer.h b/src/gpu/ops/GrStencilAndCoverPathRenderer.h index c896e61545..dda0157a5c 100644 --- a/src/gpu/ops/GrStencilAndCoverPathRenderer.h +++ b/src/gpu/ops/GrStencilAndCoverPathRenderer.h @@ -28,7 +28,7 @@ private: return GrPathRenderer::kStencilOnly_StencilSupport; } - bool onCanDrawPath(const CanDrawPathArgs&) const override; + CanDrawPath onCanDrawPath(const CanDrawPathArgs&) const override; bool onDrawPath(const DrawPathArgs&) override; diff --git a/src/gpu/ops/GrTessellatingPathRenderer.cpp b/src/gpu/ops/GrTessellatingPathRenderer.cpp index 641a037bbe..2db4ffcd0d 100644 --- a/src/gpu/ops/GrTessellatingPathRenderer.cpp +++ b/src/gpu/ops/GrTessellatingPathRenderer.cpp @@ -132,27 +132,31 @@ private: GrTessellatingPathRenderer::GrTessellatingPathRenderer() { } -bool GrTessellatingPathRenderer::onCanDrawPath(const CanDrawPathArgs& args) const { - // This path renderer can draw fill styles, and can do screenspace antialiasing via a - // one-pixel coverage ramp. It can do convex and concave paths, but we'll leave the convex - // ones to simpler algorithms. We pass on paths that have styles, though they may come back - // around after applying the styling information to the geometry to create a filled path. In - // the non-AA case, We skip paths thta don't have a key since the real advantage of this path +GrPathRenderer::CanDrawPath +GrTessellatingPathRenderer::onCanDrawPath(const CanDrawPathArgs& args) const { + // This path renderer can draw fill styles, and can do screenspace antialiasing via a one-pixel + // coverage ramp. It can do convex and concave paths, but we'll give simpler algorithms a chance + // to draw the convex ones first. We pass on paths that have styles, though they may come back + // around after applying the styling information to the geometry to create a filled path. In the + // non-AA case, We skip paths that don't have a key since the real advantage of this path // renderer comes from caching the tessellated geometry. In the AA case, we do not cache, so we // accept paths without keys. - if (!args.fShape->style().isSimpleFill() || args.fShape->knownToBeConvex()) { - return false; + if (!args.fShape->style().isSimpleFill()) { + return CanDrawPath::kNo; } if (GrAAType::kCoverage == args.fAAType) { SkPath path; args.fShape->asPath(&path); if (path.countVerbs() > 10) { - return false; + return CanDrawPath::kNo; } } else if (!args.fShape->hasUnstyledKey()) { - return false; + return CanDrawPath::kNo; } - return true; + if (args.fShape->knownToBeConvex()) { + return CanDrawPath::kAsBackup; + } + return CanDrawPath::kYes; } namespace { diff --git a/src/gpu/ops/GrTessellatingPathRenderer.h b/src/gpu/ops/GrTessellatingPathRenderer.h index d5f2c7af9b..7dd50fc6eb 100644 --- a/src/gpu/ops/GrTessellatingPathRenderer.h +++ b/src/gpu/ops/GrTessellatingPathRenderer.h @@ -19,7 +19,7 @@ public: GrTessellatingPathRenderer(); private: - bool onCanDrawPath(const CanDrawPathArgs& ) const override; + CanDrawPath onCanDrawPath(const CanDrawPathArgs&) const override; StencilSupport onGetStencilSupport(const GrShape&) const override { return GrPathRenderer::kNoSupport_StencilSupport; |