diff options
-rw-r--r-- | include/gpu/GrContext.h | 3 | ||||
-rw-r--r-- | include/gpu/GrPathRendererChain.h | 2 | ||||
-rw-r--r-- | src/gpu/GrAAConvexPathRenderer.cpp | 12 | ||||
-rw-r--r-- | src/gpu/GrAAConvexPathRenderer.h | 9 | ||||
-rw-r--r-- | src/gpu/GrAAHairLinePathRenderer.cpp | 14 | ||||
-rw-r--r-- | src/gpu/GrAAHairLinePathRenderer.h | 6 | ||||
-rw-r--r-- | src/gpu/GrClipMaskManager.cpp | 123 | ||||
-rw-r--r-- | src/gpu/GrClipMaskManager.h | 12 | ||||
-rw-r--r-- | src/gpu/GrContext.cpp | 18 | ||||
-rw-r--r-- | src/gpu/GrDefaultPathRenderer.cpp | 38 | ||||
-rw-r--r-- | src/gpu/GrDefaultPathRenderer.h | 15 | ||||
-rw-r--r-- | src/gpu/GrPathRenderer.h | 111 | ||||
-rw-r--r-- | src/gpu/GrPathRendererChain.cpp | 9 | ||||
-rw-r--r-- | src/gpu/GrSoftwarePathRenderer.cpp | 15 | ||||
-rw-r--r-- | src/gpu/GrSoftwarePathRenderer.h | 9 | ||||
-rw-r--r-- | src/gpu/GrStencilAndCoverPathRenderer.cpp | 22 | ||||
-rw-r--r-- | src/gpu/GrStencilAndCoverPathRenderer.h | 12 |
17 files changed, 201 insertions, 229 deletions
diff --git a/include/gpu/GrContext.h b/include/gpu/GrContext.h index 8feea812dc..ad3789b1a8 100644 --- a/include/gpu/GrContext.h +++ b/include/gpu/GrContext.h @@ -854,8 +854,7 @@ public: const SkStrokeRec& stroke, const GrDrawTarget* target, bool allowSW, - GrPathRendererChain::DrawType drawType, - SkPath::FillType fillType, + GrPathRendererChain::DrawType drawType = GrPathRendererChain::kColor_DrawType, GrPathRendererChain::StencilSupport* stencilSupport = NULL); diff --git a/include/gpu/GrPathRendererChain.h b/include/gpu/GrPathRendererChain.h index 76fd1da70a..ca8c35bdeb 100644 --- a/include/gpu/GrPathRendererChain.h +++ b/include/gpu/GrPathRendererChain.h @@ -8,7 +8,6 @@ #ifndef GrPathRendererChain_DEFINED #define GrPathRendererChain_DEFINED -#include "SkPath.h" #include "SkRefCnt.h" #include "SkTArray.h" @@ -60,7 +59,6 @@ public: const SkStrokeRec& rec, const GrDrawTarget* target, DrawType drawType, - SkPath::FillType fillType, StencilSupport* stencilSupport); private: diff --git a/src/gpu/GrAAConvexPathRenderer.cpp b/src/gpu/GrAAConvexPathRenderer.cpp index 0a11661eba..a8af559991 100644 --- a/src/gpu/GrAAConvexPathRenderer.cpp +++ b/src/gpu/GrAAConvexPathRenderer.cpp @@ -605,11 +605,12 @@ GrEffectRef* QuadEdgeEffect::TestCreate(SkRandom* random, /////////////////////////////////////////////////////////////////////////////// -bool GrAAConvexPathRenderer::canDrawPath(const SkStrokeRec& stroke, +bool GrAAConvexPathRenderer::canDrawPath(const SkPath& path, + const SkStrokeRec& stroke, const GrDrawTarget* target, bool antiAlias) const { return (target->caps()->shaderDerivativeSupport() && antiAlias && - stroke.isFillStyle() && !this->path().isInverseFillType() && this->path().isConvex()); + stroke.isFillStyle() && !path.isInverseFillType() && path.isConvex()); } namespace { @@ -622,11 +623,12 @@ extern const GrVertexAttrib gPathAttribs[] = { }; -bool GrAAConvexPathRenderer::onDrawPath(const SkStrokeRec&, +bool GrAAConvexPathRenderer::onDrawPath(const SkPath& origPath, + const SkStrokeRec&, GrDrawTarget* target, bool antiAlias) { - const SkPath* path = &this->path(); + const SkPath* path = &origPath; if (path->isEmpty()) { return true; } @@ -643,7 +645,7 @@ bool GrAAConvexPathRenderer::onDrawPath(const SkStrokeRec&, // segment representation. SkPath tmpPath; if (viewMatrix.hasPerspective()) { - this->path().transform(viewMatrix, &tmpPath); + origPath.transform(viewMatrix, &tmpPath); path = &tmpPath; viewMatrix = SkMatrix::I(); } diff --git a/src/gpu/GrAAConvexPathRenderer.h b/src/gpu/GrAAConvexPathRenderer.h index 61e5472ca7..62394a3a74 100644 --- a/src/gpu/GrAAConvexPathRenderer.h +++ b/src/gpu/GrAAConvexPathRenderer.h @@ -13,15 +13,14 @@ class GrAAConvexPathRenderer : public GrPathRenderer { public: GrAAConvexPathRenderer(); - virtual bool canDrawPath(const SkStrokeRec& stroke, + virtual bool canDrawPath(const SkPath& path, + const SkStrokeRec& stroke, const GrDrawTarget* target, bool antiAlias) const SK_OVERRIDE; protected: - virtual bool onDrawPath(const SkStrokeRec& stroke, + virtual bool onDrawPath(const SkPath& path, + const SkStrokeRec& stroke, GrDrawTarget* target, bool antiAlias) SK_OVERRIDE; - -private: - typedef GrPathRenderer INHERITED; }; diff --git a/src/gpu/GrAAHairLinePathRenderer.cpp b/src/gpu/GrAAHairLinePathRenderer.cpp index 7f152661f1..830f513e6c 100644 --- a/src/gpu/GrAAHairLinePathRenderer.cpp +++ b/src/gpu/GrAAHairLinePathRenderer.cpp @@ -826,7 +826,8 @@ bool GrAAHairLinePathRenderer::createBezierGeom( return true; } -bool GrAAHairLinePathRenderer::canDrawPath(const SkStrokeRec& stroke, +bool GrAAHairLinePathRenderer::canDrawPath(const SkPath& path, + const SkStrokeRec& stroke, const GrDrawTarget* target, bool antiAlias) const { if (!antiAlias) { @@ -839,7 +840,7 @@ bool GrAAHairLinePathRenderer::canDrawPath(const SkStrokeRec& stroke, return false; } - if (SkPath::kLine_SegmentMask == this->path().getSegmentMasks() || + if (SkPath::kLine_SegmentMask == path.getSegmentMasks() || target->caps()->shaderDerivativeSupport()) { return true; } @@ -883,7 +884,8 @@ bool check_bounds(GrDrawState* drawState, const SkRect& devBounds, void* vertice return true; } -bool GrAAHairLinePathRenderer::onDrawPath(const SkStrokeRec& stroke, +bool GrAAHairLinePathRenderer::onDrawPath(const SkPath& path, + const SkStrokeRec& stroke, GrDrawTarget* target, bool antiAlias) { GrDrawState* drawState = target->drawState(); @@ -908,7 +910,7 @@ bool GrAAHairLinePathRenderer::onDrawPath(const SkStrokeRec& stroke, PREALLOC_PTARRAY(128) conics; IntArray qSubdivs; FloatArray cWeights; - quadCnt = generate_lines_and_quads(this->path(), drawState->getViewMatrix(), devClipBounds, + quadCnt = generate_lines_and_quads(path, drawState->getViewMatrix(), devClipBounds, &lines, &quads, &conics, &qSubdivs, &cWeights); lineCnt = lines.count() / 2; conicCnt = conics.count() / 3; @@ -918,7 +920,7 @@ bool GrAAHairLinePathRenderer::onDrawPath(const SkStrokeRec& stroke, GrDrawTarget::AutoReleaseGeometry arg; SkRect devBounds; - if (!this->createLineGeom(this->path(), + if (!this->createLineGeom(path, target, lines, lineCnt, @@ -964,7 +966,7 @@ bool GrAAHairLinePathRenderer::onDrawPath(const SkStrokeRec& stroke, GrDrawTarget::AutoReleaseGeometry arg; SkRect devBounds; - if (!this->createBezierGeom(this->path(), + if (!this->createBezierGeom(path, target, quads, quadCnt, diff --git a/src/gpu/GrAAHairLinePathRenderer.h b/src/gpu/GrAAHairLinePathRenderer.h index 627474abdb..22cc876eab 100644 --- a/src/gpu/GrAAHairLinePathRenderer.h +++ b/src/gpu/GrAAHairLinePathRenderer.h @@ -17,7 +17,8 @@ public: static GrPathRenderer* Create(GrContext* context); - virtual bool canDrawPath(const SkStrokeRec& stroke, + virtual bool canDrawPath(const SkPath& path, + const SkStrokeRec& stroke, const GrDrawTarget* target, bool antiAlias) const SK_OVERRIDE; @@ -26,7 +27,8 @@ public: typedef SkTArray<float, true> FloatArray; protected: - virtual bool onDrawPath(const SkStrokeRec& stroke, + virtual bool onDrawPath(const SkPath& path, + const SkStrokeRec& stroke, GrDrawTarget* target, bool antiAlias) SK_OVERRIDE; diff --git a/src/gpu/GrClipMaskManager.cpp b/src/gpu/GrClipMaskManager.cpp index 35e0818dd0..caee6eb033 100644 --- a/src/gpu/GrClipMaskManager.cpp +++ b/src/gpu/GrClipMaskManager.cpp @@ -30,11 +30,12 @@ typedef SkClipStack::Element Element; using namespace GrReducedClip; //////////////////////////////////////////////////////////////////////////////// +namespace { // set up the draw state to enable the aa clipping mask. Besides setting up the // stage matrix this also alters the vertex layout -static void setup_drawstate_aaclip(GrGpu* gpu, - GrTexture* result, - const SkIRect &devBound) { +void setup_drawstate_aaclip(GrGpu* gpu, + GrTexture* result, + const SkIRect &devBound) { GrDrawState* drawState = gpu->drawState(); SkASSERT(drawState); @@ -58,21 +59,24 @@ static void setup_drawstate_aaclip(GrGpu* gpu, kPosition_GrCoordSet))->unref(); } -static bool path_needs_SW_renderer(GrContext* context, - GrGpu* gpu, - const SkPath& origPath, - const SkStrokeRec& stroke, - bool doAA) { +bool path_needs_SW_renderer(GrContext* context, + GrGpu* gpu, + const SkPath& origPath, + const SkStrokeRec& stroke, + bool doAA) { + // the gpu alpha mask will draw the inverse paths as non-inverse to a temp buffer + SkTCopyOnFirstWrite<SkPath> path(origPath); + if (path->isInverseFillType()) { + path.writable()->toggleInverseFillType(); + } + // last (false) parameter disallows use of the SW path renderer GrPathRendererChain::DrawType type = doAA ? GrPathRendererChain::kColorAntiAlias_DrawType : GrPathRendererChain::kColor_DrawType; - // the gpu alpha mask will draw the inverse paths as non-inverse to a temp buffer - SkPath::FillType fillType = SkPath::ConvertToNonInverseFillType(origPath.getFillType()); - // the 'false' parameter disallows use of the SW path renderer - GrPathRenderer::AutoClearPath acp(context->getPathRenderer(origPath, stroke, gpu, - false, type, fillType)); - return NULL == acp.renderer(); + return NULL == context->getPathRenderer(*path, stroke, gpu, false, type); +} + } /* @@ -309,20 +313,9 @@ void setup_boolean_blendcoeffs(GrDrawState* drawState, SkRegion::Op op) { } //////////////////////////////////////////////////////////////////////////////// -bool GrClipMaskManager::drawFilledPath(GrTexture* target, - GrPathRenderer* pathRenderer, - bool isAA) { - GrDrawState* drawState = fGpu->drawState(); - - drawState->setRenderTarget(target->asRenderTarget()); - - SkStrokeRec stroke(SkStrokeRec::kFill_InitStyle); - pathRenderer->drawPath(stroke, fGpu, isAA); - return true; -} - bool GrClipMaskManager::drawElement(GrTexture* target, - const SkClipStack::Element* element) { + const SkClipStack::Element* element, + GrPathRenderer* pr) { GrDrawState* drawState = fGpu->drawState(); drawState->setRenderTarget(target->asRenderTarget()); @@ -343,19 +336,21 @@ bool GrClipMaskManager::drawElement(GrTexture* target, } return true; case Element::kPath_Type: { + SkTCopyOnFirstWrite<SkPath> path(element->getPath()); + if (path->isInverseFillType()) { + path.writable()->toggleInverseFillType(); + } SkStrokeRec stroke(SkStrokeRec::kFill_InitStyle); - GrPathRendererChain::DrawType type; - type = element->isAA() ? GrPathRendererChain::kColorAntiAlias_DrawType : - GrPathRendererChain::kColor_DrawType; - SkPath::FillType fillType = element->getPath().getFillType(); - GrPathRenderer::AutoClearPath acp(this->getContext()->getPathRenderer( - element->getPath(), - stroke, fGpu, false, type, - SkPath::ConvertToNonInverseFillType(fillType))); - if (NULL == acp.renderer()) { + if (NULL == pr) { + GrPathRendererChain::DrawType type; + type = element->isAA() ? GrPathRendererChain::kColorAntiAlias_DrawType : + GrPathRendererChain::kColor_DrawType; + pr = this->getContext()->getPathRenderer(*path, stroke, fGpu, false, type); + } + if (NULL == pr) { return false; } - acp->drawPath(stroke, fGpu, element->isAA()); + pr->drawPath(element->getPath(), stroke, fGpu, element->isAA()); break; } default: @@ -368,7 +363,7 @@ bool GrClipMaskManager::drawElement(GrTexture* target, bool GrClipMaskManager::canStencilAndDrawElement(GrTexture* target, const SkClipStack::Element* element, - GrPathRenderer::AutoClearPath* acp) { + GrPathRenderer** pr) { GrDrawState* drawState = fGpu->drawState(); drawState->setRenderTarget(target->asRenderTarget()); @@ -376,15 +371,16 @@ bool GrClipMaskManager::canStencilAndDrawElement(GrTexture* target, case Element::kRect_Type: return true; case Element::kPath_Type: { + SkTCopyOnFirstWrite<SkPath> path(element->getPath()); + if (path->isInverseFillType()) { + path.writable()->toggleInverseFillType(); + } SkStrokeRec stroke(SkStrokeRec::kFill_InitStyle); GrPathRendererChain::DrawType type = element->isAA() ? GrPathRendererChain::kStencilAndColorAntiAlias_DrawType : GrPathRendererChain::kStencilAndColor_DrawType; - SkPath::FillType fillType = element->getPath().getFillType(); - acp->set(this->getContext()->getPathRenderer(element->getPath(), - stroke, fGpu, false, type, - SkPath::ConvertToNonInverseFillType(fillType))); - return NULL != acp->renderer(); + *pr = this->getContext()->getPathRenderer(*path, stroke, fGpu, false, type); + return NULL != *pr; } default: // something is wrong if we're trying to draw an empty element. @@ -529,8 +525,8 @@ GrTexture* GrClipMaskManager::createAlphaClipMask(int32_t elementsGenID, bool invert = element->isInverseFilled(); if (invert || SkRegion::kIntersect_Op == op || SkRegion::kReverseDifference_Op == op) { - GrPathRenderer::AutoClearPath acp; - bool useTemp = !this->canStencilAndDrawElement(result, element, &acp); + GrPathRenderer* pr = NULL; + bool useTemp = !this->canStencilAndDrawElement(result, element, &pr); GrTexture* dst; // This is the bounds of the clip element in the space of the alpha-mask. The temporary // mask buffer can be substantially larger than the actually clip stack element. We @@ -577,13 +573,9 @@ GrTexture* GrClipMaskManager::createAlphaClipMask(int32_t elementsGenID, drawState->setAlpha(invert ? 0x00 : 0xff); - if (NULL != acp.renderer()) { - this->drawFilledPath(dst, acp.renderer(), element->isAA()); - } else { - if (!this->drawElement(dst, element)) { - fAACache.reset(); - return NULL; - } + if (!this->drawElement(dst, element, pr)) { + fAACache.reset(); + return NULL; } if (useTemp) { @@ -609,7 +601,7 @@ GrTexture* GrClipMaskManager::createAlphaClipMask(int32_t elementsGenID, drawState->disableStencil(); } } else { - // all the remaining ops can just be directly drawn into the accumulation buffer + // all the remaining ops can just be directly draw into the accumulation buffer drawState->setAlpha(0xff); setup_boolean_blendcoeffs(drawState, op); this->drawElement(result, element); @@ -695,22 +687,25 @@ bool GrClipMaskManager::createStencilClipMask(int32_t elementsGenID, SkRegion::Op op = element->getOp(); - GrPathRenderer::AutoClearPath acp; + GrPathRenderer* pr = NULL; + SkTCopyOnFirstWrite<SkPath> clipPath; if (Element::kRect_Type == element->getType()) { stencilSupport = GrPathRenderer::kNoRestriction_StencilSupport; fillInverted = false; } else { SkASSERT(Element::kPath_Type == element->getType()); - fillInverted = element->getPath().isInverseFillType(); - SkPath::FillType fill = element->getPath().getFillType(); - acp.set(this->getContext()->getPathRenderer(element->getPath(), + clipPath.init(element->getPath()); + fillInverted = clipPath->isInverseFillType(); + if (fillInverted) { + clipPath.writable()->toggleInverseFillType(); + } + pr = this->getContext()->getPathRenderer(*clipPath, stroke, fGpu, false, GrPathRendererChain::kStencilOnly_DrawType, - SkPath::ConvertToNonInverseFillType(fill), - &stencilSupport)); - if (NULL == acp.renderer()) { + &stencilSupport); + if (NULL == pr) { return false; } } @@ -746,12 +741,12 @@ bool GrClipMaskManager::createStencilClipMask(int32_t elementsGenID, fGpu->drawSimpleRect(element->getRect(), NULL); } else { SkASSERT(Element::kPath_Type == element->getType()); - if (NULL != acp.renderer()) { + if (!clipPath->isEmpty()) { if (canRenderDirectToStencil) { *drawState->stencil() = gDrawToStencil; - acp->drawPath(stroke, fGpu, false); + pr->drawPath(*clipPath, stroke, fGpu, false); } else { - acp->stencilPath(stroke, fGpu); + pr->stencilPath(*clipPath, stroke, fGpu); } } } @@ -769,7 +764,7 @@ bool GrClipMaskManager::createStencilClipMask(int32_t elementsGenID, } else { SkASSERT(Element::kPath_Type == element->getType()); SET_RANDOM_COLOR - acp->drawPath(stroke, fGpu, false); + pr->drawPath(*clipPath, stroke, fGpu, false); } } else { SET_RANDOM_COLOR diff --git a/src/gpu/GrClipMaskManager.h b/src/gpu/GrClipMaskManager.h index fa54f3ce0e..f44a8e7b22 100644 --- a/src/gpu/GrClipMaskManager.h +++ b/src/gpu/GrClipMaskManager.h @@ -11,7 +11,6 @@ #include "GrClipMaskCache.h" #include "GrContext.h" #include "GrDrawState.h" -#include "GrPathRenderer.h" #include "GrReducedClip.h" #include "GrStencil.h" #include "GrTexture.h" @@ -131,18 +130,15 @@ private: bool useSWOnlyPath(const GrReducedClip::ElementList& elements); - // Draws a filled clip path into the target alpha mask - bool drawFilledPath(GrTexture* target, GrPathRenderer* pathRenderer, bool isAA); - // Draws a clip element into the target alpha mask. The caller should have already setup the - // desired blend operation. - bool drawElement(GrTexture* target, const SkClipStack::Element* element); + // desired blend operation. Optionally if the caller already selected a path renderer it can + // be passed. Otherwise the function will select one if the element is a path. + bool drawElement(GrTexture* target, const SkClipStack::Element*, GrPathRenderer* = NULL); // Determines whether it is possible to draw the element to both the stencil buffer and the // alpha mask simultaneously. If so and the element is a path a compatible path renderer is // also returned. - bool canStencilAndDrawElement(GrTexture* target, const SkClipStack::Element*, - GrPathRenderer::AutoClearPath* pr); + bool canStencilAndDrawElement(GrTexture* target, const SkClipStack::Element*, GrPathRenderer**); void mergeMask(GrTexture* dstMask, GrTexture* srcMask, diff --git a/src/gpu/GrContext.cpp b/src/gpu/GrContext.cpp index ab20dc3902..bb0f4fa9fa 100644 --- a/src/gpu/GrContext.cpp +++ b/src/gpu/GrContext.cpp @@ -1148,18 +1148,16 @@ void GrContext::internalDrawPath(GrDrawTarget* target, bool useAA, const SkPath& GrPathRendererChain::DrawType type = useCoverageAA ? GrPathRendererChain::kColorAntiAlias_DrawType : - GrPathRendererChain::kColor_DrawType; + GrPathRendererChain::kColor_DrawType; const SkPath* pathPtr = &path; SkTLazy<SkPath> tmpPath; SkTCopyOnFirstWrite<SkStrokeRec> stroke(origStroke); // Try a 1st time without stroking the path and without allowing the SW renderer - GrPathRenderer::AutoClearPath acp(this->getPathRenderer(*pathPtr, *stroke, - target, false, type, - pathPtr->getFillType())); + GrPathRenderer* pr = this->getPathRenderer(*pathPtr, *stroke, target, false, type); - if (NULL == acp.renderer()) { + if (NULL == pr) { if (!GrPathRenderer::IsStrokeHairlineOrEquivalent(*stroke, this->getMatrix(), NULL)) { // It didn't work the 1st time, so try again with the stroked path if (stroke->applyToPath(tmpPath.init(), *pathPtr)) { @@ -1172,18 +1170,17 @@ void GrContext::internalDrawPath(GrDrawTarget* target, bool useAA, const SkPath& } // This time, allow SW renderer - acp.set(this->getPathRenderer(*pathPtr, *stroke, target, true, type, - pathPtr->getFillType())); + pr = this->getPathRenderer(*pathPtr, *stroke, target, true, type); } - if (NULL == acp.renderer()) { + if (NULL == pr) { #ifdef SK_DEBUG GrPrintf("Unable to find path renderer compatible with path.\n"); #endif return; } - acp->drawPath(*stroke, target, useCoverageAA); + pr->drawPath(*pathPtr, *stroke, target, useCoverageAA); } //////////////////////////////////////////////////////////////////////////////// @@ -1679,7 +1676,6 @@ GrPathRenderer* GrContext::getPathRenderer(const SkPath& path, const GrDrawTarget* target, bool allowSW, GrPathRendererChain::DrawType drawType, - SkPath::FillType fillType, GrPathRendererChain::StencilSupport* stencilSupport) { if (NULL == fPathRendererChain) { @@ -1690,7 +1686,6 @@ GrPathRenderer* GrContext::getPathRenderer(const SkPath& path, stroke, target, drawType, - fillType, stencilSupport); if (NULL == pr && allowSW) { @@ -1698,7 +1693,6 @@ GrPathRenderer* GrContext::getPathRenderer(const SkPath& path, fSoftwarePathRenderer = SkNEW_ARGS(GrSoftwarePathRenderer, (this)); } pr = fSoftwarePathRenderer; - pr->setPath(path, fillType); } return pr; diff --git a/src/gpu/GrDefaultPathRenderer.cpp b/src/gpu/GrDefaultPathRenderer.cpp index 69da9d9bf2..1f20ac2724 100644 --- a/src/gpu/GrDefaultPathRenderer.cpp +++ b/src/gpu/GrDefaultPathRenderer.cpp @@ -163,9 +163,10 @@ static inline bool single_pass_path(const SkPath& path, const SkStrokeRec& strok } GrPathRenderer::StencilSupport GrDefaultPathRenderer::onGetStencilSupport( + const SkPath& path, const SkStrokeRec& stroke, const GrDrawTarget*) const { - if (single_pass_path(this->path(), stroke)) { + if (single_pass_path(path, stroke)) { return GrPathRenderer::kNoRestriction_StencilSupport; } else { return GrPathRenderer::kStencilOnly_StencilSupport; @@ -324,7 +325,8 @@ FINISHED: return true; } -bool GrDefaultPathRenderer::internalDrawPath(const SkStrokeRec& origStroke, +bool GrDefaultPathRenderer::internalDrawPath(const SkPath& path, + const SkStrokeRec& origStroke, GrDrawTarget* target, bool stencilOnly) { @@ -344,13 +346,13 @@ bool GrDefaultPathRenderer::internalDrawPath(const SkStrokeRec& origStroke, } SkScalar tol = SK_Scalar1; - tol = GrPathUtils::scaleToleranceToSrc(tol, viewM, this->path().getBounds()); + tol = GrPathUtils::scaleToleranceToSrc(tol, viewM, path.getBounds()); int vertexCnt; int indexCnt; GrPrimitiveType primType; GrDrawTarget::AutoReleaseGeometry arg; - if (!this->createGeom(this->path(), + if (!this->createGeom(path, *stroke, tol, target, @@ -384,7 +386,7 @@ bool GrDefaultPathRenderer::internalDrawPath(const SkStrokeRec& origStroke, lastPassIsBounds = false; drawFace[0] = GrDrawState::kBoth_DrawFace; } else { - if (single_pass_path(this->path(), *stroke)) { + if (single_pass_path(path, *stroke)) { passCount = 1; if (stencilOnly) { passes[0] = &gDirectToStencil; @@ -394,7 +396,7 @@ bool GrDefaultPathRenderer::internalDrawPath(const SkStrokeRec& origStroke, drawFace[0] = GrDrawState::kBoth_DrawFace; lastPassIsBounds = false; } else { - switch (this->path().getFillType()) { + switch (path.getFillType()) { case SkPath::kInverseEvenOdd_FillType: reverse = true; // fallthrough @@ -461,7 +463,7 @@ bool GrDefaultPathRenderer::internalDrawPath(const SkStrokeRec& origStroke, } SkRect devBounds; - GetPathDevBounds(this->path(), drawState->getRenderTarget(), viewM, &devBounds); + GetPathDevBounds(path, drawState->getRenderTarget(), viewM, &devBounds); for (int p = 0; p < passCount; ++p) { drawState->setDrawFace(drawFace[p]); @@ -488,7 +490,7 @@ bool GrDefaultPathRenderer::internalDrawPath(const SkStrokeRec& origStroke, avmr.setIdentity(drawState); } } else { - bounds = this->path().getBounds(); + bounds = path.getBounds(); } GrDrawTarget::AutoGeometryAndStatePush agasp(target, GrDrawTarget::kPreserve_ASRInit); target->drawSimpleRect(bounds, NULL); @@ -507,7 +509,8 @@ bool GrDefaultPathRenderer::internalDrawPath(const SkStrokeRec& origStroke, return true; } -bool GrDefaultPathRenderer::canDrawPath(const SkStrokeRec& stroke, +bool GrDefaultPathRenderer::canDrawPath(const SkPath& path, + const SkStrokeRec& stroke, const GrDrawTarget* target, bool antiAlias) const { // this class can draw any path with any fill but doesn't do any anti-aliasing. @@ -517,15 +520,20 @@ bool GrDefaultPathRenderer::canDrawPath(const SkStrokeRec& stroke, IsStrokeHairlineOrEquivalent(stroke, target->getDrawState().getViewMatrix(), NULL)); } -bool GrDefaultPathRenderer::onDrawPath(const SkStrokeRec& stroke, +bool GrDefaultPathRenderer::onDrawPath(const SkPath& path, + const SkStrokeRec& stroke, GrDrawTarget* target, bool antiAlias) { - return this->internalDrawPath(stroke, target, false); + return this->internalDrawPath(path, + stroke, + target, + false); } -void GrDefaultPathRenderer::onStencilPath(const SkStrokeRec& stroke, +void GrDefaultPathRenderer::onStencilPath(const SkPath& path, + const SkStrokeRec& stroke, GrDrawTarget* target) { - SkASSERT(SkPath::kInverseEvenOdd_FillType != this->path().getFillType()); - SkASSERT(SkPath::kInverseWinding_FillType != this->path().getFillType()); - this->internalDrawPath(stroke, target, true); + SkASSERT(SkPath::kInverseEvenOdd_FillType != path.getFillType()); + SkASSERT(SkPath::kInverseWinding_FillType != path.getFillType()); + this->internalDrawPath(path, stroke, target, true); } diff --git a/src/gpu/GrDefaultPathRenderer.h b/src/gpu/GrDefaultPathRenderer.h index 56d4370718..c60afccbfb 100644 --- a/src/gpu/GrDefaultPathRenderer.h +++ b/src/gpu/GrDefaultPathRenderer.h @@ -19,23 +19,28 @@ class SK_API GrDefaultPathRenderer : public GrPathRenderer { public: GrDefaultPathRenderer(bool separateStencilSupport, bool stencilWrapOpsSupport); - virtual bool canDrawPath(const SkStrokeRec&, + virtual bool canDrawPath(const SkPath&, + const SkStrokeRec&, const GrDrawTarget*, bool antiAlias) const SK_OVERRIDE; private: - virtual StencilSupport onGetStencilSupport(const SkStrokeRec&, + virtual StencilSupport onGetStencilSupport(const SkPath&, + const SkStrokeRec&, const GrDrawTarget*) const SK_OVERRIDE; - virtual bool onDrawPath(const SkStrokeRec&, + virtual bool onDrawPath(const SkPath&, + const SkStrokeRec&, GrDrawTarget*, bool antiAlias) SK_OVERRIDE; - virtual void onStencilPath(const SkStrokeRec&, + virtual void onStencilPath(const SkPath&, + const SkStrokeRec&, GrDrawTarget*) SK_OVERRIDE; - bool internalDrawPath(const SkStrokeRec&, + bool internalDrawPath(const SkPath&, + const SkStrokeRec&, GrDrawTarget*, bool stencilOnly); diff --git a/src/gpu/GrPathRenderer.h b/src/gpu/GrPathRenderer.h index 692cefc7f1..88665c1d42 100644 --- a/src/gpu/GrPathRenderer.h +++ b/src/gpu/GrPathRenderer.h @@ -74,108 +74,70 @@ public: GrPathRendererChain::kNoRestriction_StencilSupport; /** - * This function is to get the stencil support for the current path. The path's fill must + * This function is to get the stencil support for a particular path. The path's fill must * not be an inverse type. * - * @param stroke the stroke information (width, join, cap). * @param target target that the path will be rendered to + * @param path the path that will be drawn + * @param stroke the stroke information (width, join, cap). */ - StencilSupport getStencilSupport(const SkStrokeRec& stroke, + StencilSupport getStencilSupport(const SkPath& path, + const SkStrokeRec& stroke, const GrDrawTarget* target) const { - SkASSERT(!fPath.isInverseFillType()); - return this->onGetStencilSupport(stroke, target); - } - - // Set the path and fill type the path renderer is to use. - // 'fillType' is included as a parameter b.c. we often want to draw - // inverse filled paths normally filled. - void setPath(const SkPath& path, SkPath::FillType fillType) { - SkASSERT(fPath.isEmpty()); - fPath = path; - fPath.setFillType(fillType); - } - - void resetPath() { - fPath.reset(); + SkASSERT(!path.isInverseFillType()); + return this->onGetStencilSupport(path, stroke, target); } /** - * Returns true if this path renderer is able to render the current 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. + * 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. * + * @param path The path to draw * @param stroke The stroke information (width, join, cap) * @param target The target that the path will be rendered to * @param antiAlias True if anti-aliasing is required. * * @return true if the path can be drawn by this object, false otherwise. */ - virtual bool canDrawPath(const SkStrokeRec& stroke, + virtual bool canDrawPath(const SkPath& path, + const SkStrokeRec& rec, const GrDrawTarget* target, bool antiAlias) const = 0; /** - * Draws the current path into the draw target. If getStencilSupport() would return - * kNoRestriction then the subclass must respect the stencil settings of the - * target's draw state. + * Draws the path into the draw target. If getStencilSupport() would return kNoRestriction then + * the subclass must respect the stencil settings of the target's draw state. * + * @param path the path to draw. * @param stroke the stroke information (width, join, cap) * @param target target that the path will be rendered to * @param antiAlias true if anti-aliasing is required. */ - bool drawPath(const SkStrokeRec& stroke, + bool drawPath(const SkPath& path, + const SkStrokeRec& stroke, GrDrawTarget* target, bool antiAlias) { - SkASSERT(!fPath.isEmpty()); - SkASSERT(this->canDrawPath(stroke, target, antiAlias)); + SkASSERT(!path.isEmpty()); + SkASSERT(this->canDrawPath(path, stroke, target, antiAlias)); SkASSERT(target->drawState()->getStencil().isDisabled() || - kNoRestriction_StencilSupport == this->getStencilSupport(stroke, target)); - return this->onDrawPath(stroke, target, antiAlias); + kNoRestriction_StencilSupport == this->getStencilSupport(path, stroke, target)); + return this->onDrawPath(path, stroke, target, antiAlias); } /** - * Draws the current path to the stencil buffer. Assume the writable stencil bits are already - * initialized to zero. The pixels inside the path will have non-zero stencil values - * afterwards. + * Draws the path to the stencil buffer. Assume the writable stencil bits are already + * initialized to zero. The pixels inside the path will have non-zero stencil values afterwards. * + * @param path the path to draw. * @param stroke the stroke information (width, join, cap) * @param target target that the path will be rendered to */ - void stencilPath(const SkStrokeRec& stroke, GrDrawTarget* target) { - SkASSERT(!fPath.isEmpty()); - SkASSERT(kNoSupport_StencilSupport != this->getStencilSupport(stroke, target)); - this->onStencilPath(stroke, target); + void stencilPath(const SkPath& path, const SkStrokeRec& stroke, GrDrawTarget* target) { + SkASSERT(!path.isEmpty()); + SkASSERT(kNoSupport_StencilSupport != this->getStencilSupport(path, stroke, target)); + this->onStencilPath(path, stroke, target); } - class AutoClearPath : ::SkNoncopyable { - public: - AutoClearPath(GrPathRenderer* renderer) : fRenderer(renderer) {} - AutoClearPath() : fRenderer(NULL) {} - ~AutoClearPath() { - this->reset(); - } - - GrPathRenderer* renderer() { - return fRenderer; - } - - void set(GrPathRenderer* renderer) { - this->reset(); - fRenderer = renderer; - } - - GrPathRenderer* operator->() { return fRenderer; } - - private: - void reset() { - if (NULL != fRenderer) { - fRenderer->resetPath(); - } - fRenderer = NULL; - } - - GrPathRenderer* fRenderer; - }; - // Helper for determining if we can treat a thin stroke as a hairline w/ coverage. // If we can, we draw lots faster (raster device does this same test). static bool IsStrokeHairlineOrEquivalent(const SkStrokeRec& stroke, const SkMatrix& matrix, @@ -191,14 +153,11 @@ public: } protected: - const SkPath& path() const { - return fPath; - } - /** * Subclass overrides if it has any limitations of stenciling support. */ - virtual StencilSupport onGetStencilSupport(const SkStrokeRec&, + virtual StencilSupport onGetStencilSupport(const SkPath&, + const SkStrokeRec&, const GrDrawTarget*) const { return kNoRestriction_StencilSupport; } @@ -206,7 +165,8 @@ protected: /** * Subclass implementation of drawPath() */ - virtual bool onDrawPath(const SkStrokeRec& stroke, + virtual bool onDrawPath(const SkPath& path, + const SkStrokeRec& stroke, GrDrawTarget* target, bool antiAlias) = 0; @@ -214,7 +174,7 @@ protected: * Subclass implementation of stencilPath(). Subclass must override iff it ever returns * kStencilOnly in onGetStencilSupport(). */ - virtual void onStencilPath(const SkStrokeRec& stroke, GrDrawTarget* target) { + virtual void onStencilPath(const SkPath& path, const SkStrokeRec& stroke, GrDrawTarget* target) { GrDrawTarget::AutoStateRestore asr(target, GrDrawTarget::kPreserve_ASRInit); GrDrawState* drawState = target->drawState(); GR_STATIC_CONST_SAME_STENCIL(kIncrementStencil, @@ -226,7 +186,7 @@ protected: 0xffff); drawState->setStencil(kIncrementStencil); drawState->enableState(GrDrawState::kNoColorWrites_StateBit); - this->drawPath(stroke, target, false); + this->drawPath(path, stroke, target, false); } // Helper for getting the device bounds of a path. Inverse filled paths will have bounds set @@ -246,7 +206,6 @@ protected: } private: - SkPath fPath; typedef SkRefCnt INHERITED; }; diff --git a/src/gpu/GrPathRendererChain.cpp b/src/gpu/GrPathRendererChain.cpp index 89112884d3..cac0475bbf 100644 --- a/src/gpu/GrPathRendererChain.cpp +++ b/src/gpu/GrPathRendererChain.cpp @@ -35,7 +35,6 @@ GrPathRenderer* GrPathRendererChain::getPathRenderer(const SkPath& path, const SkStrokeRec& stroke, const GrDrawTarget* target, DrawType drawType, - SkPath::FillType fillType, StencilSupport* stencilSupport) { if (!fInit) { this->init(); @@ -57,11 +56,12 @@ GrPathRenderer* GrPathRendererChain::getPathRenderer(const SkPath& path, minStencilSupport = GrPathRenderer::kNoSupport_StencilSupport; } + for (int i = 0; i < fChain.count(); ++i) { - fChain[i]->setPath(path, fillType); - if (fChain[i]->canDrawPath(stroke, target, antiAlias)) { + if (fChain[i]->canDrawPath(path, stroke, target, antiAlias)) { if (GrPathRenderer::kNoSupport_StencilSupport != minStencilSupport) { - GrPathRenderer::StencilSupport support = fChain[i]->getStencilSupport(stroke, + GrPathRenderer::StencilSupport support = fChain[i]->getStencilSupport(path, + stroke, target); if (support < minStencilSupport) { continue; @@ -71,7 +71,6 @@ GrPathRenderer* GrPathRendererChain::getPathRenderer(const SkPath& path, } return fChain[i]; } - fChain[i]->resetPath(); } return NULL; } diff --git a/src/gpu/GrSoftwarePathRenderer.cpp b/src/gpu/GrSoftwarePathRenderer.cpp index 61711c07ce..d0936d6b28 100644 --- a/src/gpu/GrSoftwarePathRenderer.cpp +++ b/src/gpu/GrSoftwarePathRenderer.cpp @@ -11,7 +11,8 @@ #include "GrSWMaskHelper.h" //////////////////////////////////////////////////////////////////////////////// -bool GrSoftwarePathRenderer::canDrawPath(const SkStrokeRec&, +bool GrSoftwarePathRenderer::canDrawPath(const SkPath&, + const SkStrokeRec&, const GrDrawTarget*, bool antiAlias) const { if (!antiAlias || NULL == fContext) { @@ -28,6 +29,7 @@ bool GrSoftwarePathRenderer::canDrawPath(const SkStrokeRec&, } GrPathRenderer::StencilSupport GrSoftwarePathRenderer::onGetStencilSupport( + const SkPath&, const SkStrokeRec&, const GrDrawTarget*) const { return GrPathRenderer::kNoSupport_StencilSupport; @@ -111,7 +113,8 @@ void draw_around_inv_path(GrDrawTarget* target, //////////////////////////////////////////////////////////////////////////////// // return true on success; false on failure -bool GrSoftwarePathRenderer::onDrawPath(const SkStrokeRec& stroke, +bool GrSoftwarePathRenderer::onDrawPath(const SkPath& path, + const SkStrokeRec& stroke, GrDrawTarget* target, bool antiAlias) { @@ -124,16 +127,16 @@ bool GrSoftwarePathRenderer::onDrawPath(const SkStrokeRec& stroke, SkMatrix vm = drawState->getViewMatrix(); SkIRect devPathBounds, devClipBounds; - if (!get_path_and_clip_bounds(target, this->path(), vm, + if (!get_path_and_clip_bounds(target, path, vm, &devPathBounds, &devClipBounds)) { - if (this->path().isInverseFillType()) { + if (path.isInverseFillType()) { draw_around_inv_path(target, devClipBounds, devPathBounds); } return true; } SkAutoTUnref<GrTexture> texture( - GrSWMaskHelper::DrawPathMaskToTexture(fContext, this->path(), stroke, + GrSWMaskHelper::DrawPathMaskToTexture(fContext, path, stroke, devPathBounds, antiAlias, &vm)); if (NULL == texture) { @@ -142,7 +145,7 @@ bool GrSoftwarePathRenderer::onDrawPath(const SkStrokeRec& stroke, GrSWMaskHelper::DrawToTargetWithPathMask(texture, target, devPathBounds); - if (this->path().isInverseFillType()) { + if (path.isInverseFillType()) { draw_around_inv_path(target, devClipBounds, devPathBounds); } diff --git a/src/gpu/GrSoftwarePathRenderer.h b/src/gpu/GrSoftwarePathRenderer.h index 6e8cec4e13..f8c5620f49 100644 --- a/src/gpu/GrSoftwarePathRenderer.h +++ b/src/gpu/GrSoftwarePathRenderer.h @@ -24,14 +24,17 @@ public: : fContext(context) { } - virtual bool canDrawPath(const SkStrokeRec&, + virtual bool canDrawPath(const SkPath&, + const SkStrokeRec&, const GrDrawTarget*, bool antiAlias) const SK_OVERRIDE; protected: - virtual StencilSupport onGetStencilSupport(const SkStrokeRec&, + virtual StencilSupport onGetStencilSupport(const SkPath&, + const SkStrokeRec&, const GrDrawTarget*) const SK_OVERRIDE; - virtual bool onDrawPath(const SkStrokeRec&, + virtual bool onDrawPath(const SkPath&, + const SkStrokeRec&, GrDrawTarget*, bool antiAlias) SK_OVERRIDE; diff --git a/src/gpu/GrStencilAndCoverPathRenderer.cpp b/src/gpu/GrStencilAndCoverPathRenderer.cpp index ff287b7735..273c01b861 100644 --- a/src/gpu/GrStencilAndCoverPathRenderer.cpp +++ b/src/gpu/GrStencilAndCoverPathRenderer.cpp @@ -34,7 +34,8 @@ GrStencilAndCoverPathRenderer::~GrStencilAndCoverPathRenderer() { fGpu->unref(); } -bool GrStencilAndCoverPathRenderer::canDrawPath(const SkStrokeRec& stroke, +bool GrStencilAndCoverPathRenderer::canDrawPath(const SkPath& path, + const SkStrokeRec& stroke, const GrDrawTarget* target, bool antiAlias) const { return !stroke.isHairlineStyle() && @@ -44,19 +45,22 @@ bool GrStencilAndCoverPathRenderer::canDrawPath(const SkStrokeRec& stroke, } GrPathRenderer::StencilSupport GrStencilAndCoverPathRenderer::onGetStencilSupport( + const SkPath&, const SkStrokeRec& , const GrDrawTarget*) const { return GrPathRenderer::kStencilOnly_StencilSupport; } -void GrStencilAndCoverPathRenderer::onStencilPath(const SkStrokeRec& stroke, +void GrStencilAndCoverPathRenderer::onStencilPath(const SkPath& path, + const SkStrokeRec& stroke, GrDrawTarget* target) { - SkASSERT(!this->path().isInverseFillType()); - SkAutoTUnref<GrPath> p(fGpu->getContext()->createPath(this->path(), stroke)); - target->stencilPath(p, this->path().getFillType()); + SkASSERT(!path.isInverseFillType()); + SkAutoTUnref<GrPath> p(fGpu->getContext()->createPath(path, stroke)); + target->stencilPath(p, path.getFillType()); } -bool GrStencilAndCoverPathRenderer::onDrawPath(const SkStrokeRec& stroke, +bool GrStencilAndCoverPathRenderer::onDrawPath(const SkPath& path, + const SkStrokeRec& stroke, GrDrawTarget* target, bool antiAlias) { SkASSERT(!antiAlias); @@ -65,9 +69,9 @@ bool GrStencilAndCoverPathRenderer::onDrawPath(const SkStrokeRec& stroke, GrDrawState* drawState = target->drawState(); SkASSERT(drawState->getStencil().isDisabled()); - SkAutoTUnref<GrPath> p(fGpu->getContext()->createPath(this->path(), stroke)); + SkAutoTUnref<GrPath> p(fGpu->getContext()->createPath(path, stroke)); - if (this->path().isInverseFillType()) { + if (path.isInverseFillType()) { GR_STATIC_CONST_SAME_STENCIL(kInvertedStencilPass, kZero_StencilOp, kZero_StencilOp, @@ -92,7 +96,7 @@ bool GrStencilAndCoverPathRenderer::onDrawPath(const SkStrokeRec& stroke, *drawState->stencil() = kStencilPass; } - target->drawPath(p, this->path().getFillType()); + target->drawPath(p, path.getFillType()); target->drawState()->stencil()->setDisabled(); return true; diff --git a/src/gpu/GrStencilAndCoverPathRenderer.h b/src/gpu/GrStencilAndCoverPathRenderer.h index 4cd6581503..9ebcec9858 100644 --- a/src/gpu/GrStencilAndCoverPathRenderer.h +++ b/src/gpu/GrStencilAndCoverPathRenderer.h @@ -25,19 +25,23 @@ public: virtual ~GrStencilAndCoverPathRenderer(); - virtual bool canDrawPath(const SkStrokeRec&, + virtual bool canDrawPath(const SkPath&, + const SkStrokeRec&, const GrDrawTarget*, bool antiAlias) const SK_OVERRIDE; protected: - virtual StencilSupport onGetStencilSupport(const SkStrokeRec&, + virtual StencilSupport onGetStencilSupport(const SkPath&, + const SkStrokeRec&, const GrDrawTarget*) const SK_OVERRIDE; - virtual bool onDrawPath(const SkStrokeRec&, + virtual bool onDrawPath(const SkPath&, + const SkStrokeRec&, GrDrawTarget*, bool antiAlias) SK_OVERRIDE; - virtual void onStencilPath(const SkStrokeRec&, + virtual void onStencilPath(const SkPath&, + const SkStrokeRec&, GrDrawTarget*) SK_OVERRIDE; private: |