diff options
author | robertphillips <robertphillips@google.com> | 2015-10-29 12:12:21 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2015-10-29 12:12:21 -0700 |
commit | 687378229aecefc0ab7e639181593774ec8a4290 (patch) | |
tree | 18eef745eb26d302a6bf90bcb2615984b5dfea10 /src/gpu | |
parent | 89fe56bb98de55c7bd2b547c875b74a98bd5a1ca (diff) |
Remove GrPipelineBuilder from getPathRenderer call
Logically this CL:
Moves the PathRendererChain from GrContext to GrDrawManager
- this was needed to untangled the Path-Chain/Renderer header mess
- this entailed adding getDrawingMgr so the CMM could access the PathRenderingChain
- this also entailed re-adding freeGpuResources to the GrDrawingMgr
Moves the CanDrawArgs struct up stack
Removes the GrPipelineBuilder from the CanDrawArgs struct
Review URL: https://codereview.chromium.org/1407883004
Diffstat (limited to 'src/gpu')
-rw-r--r-- | src/gpu/GrClipMaskManager.cpp | 93 | ||||
-rw-r--r-- | src/gpu/GrClipMaskManager.h | 17 | ||||
-rw-r--r-- | src/gpu/GrContext.cpp | 50 | ||||
-rw-r--r-- | src/gpu/GrDrawContext.cpp | 38 | ||||
-rw-r--r-- | src/gpu/GrDrawingManager.cpp | 38 | ||||
-rw-r--r-- | src/gpu/GrDrawingManager.h | 16 | ||||
-rw-r--r-- | src/gpu/GrPathRenderer.h | 24 | ||||
-rw-r--r-- | src/gpu/GrPathRendererChain.cpp | 19 | ||||
-rw-r--r-- | src/gpu/GrPathRendererChain.h | 72 | ||||
-rw-r--r-- | src/gpu/GrPipelineBuilder.h | 5 | ||||
-rw-r--r-- | src/gpu/batches/GrStencilAndCoverPathRenderer.cpp | 4 |
11 files changed, 248 insertions, 128 deletions
diff --git a/src/gpu/GrClipMaskManager.cpp b/src/gpu/GrClipMaskManager.cpp index 445c6dbc78..9617e0dc65 100644 --- a/src/gpu/GrClipMaskManager.cpp +++ b/src/gpu/GrClipMaskManager.cpp @@ -7,6 +7,7 @@ #include "GrClipMaskManager.h" #include "GrCaps.h" +#include "GrDrawingManager.h" #include "GrDrawContext.h" #include "GrDrawTarget.h" #include "GrGpuResourcePriv.h" @@ -49,12 +50,13 @@ static const GrFragmentProcessor* create_fp_for_mask(GrTexture* result, const Sk // Does the path in 'element' require SW rendering? If so, return true (and, // optionally, set 'prOut' to NULL. If not, return false (and, optionally, set // 'prOut' to the non-SW path renderer that will do the job). -static bool path_needs_SW_renderer(GrContext* context, - const GrPipelineBuilder& pipelineBuilder, - const SkMatrix& viewMatrix, - const Element* element, - GrPathRenderer** prOut, - bool needsStencil) { +bool GrClipMaskManager::PathNeedsSWRenderer(GrContext* context, + bool isStencilDisabled, + const GrRenderTarget* rt, + const SkMatrix& viewMatrix, + const Element* element, + GrPathRenderer** prOut, + bool needsStencil) { if (Element::kRect_Type == element->getType()) { // rects can always be drawn directly w/o using the software path // TODO: skip rrects once we're drawing them directly. @@ -86,9 +88,17 @@ static bool path_needs_SW_renderer(GrContext* context, : GrPathRendererChain::kColor_DrawType; } + GrPathRenderer::CanDrawPathArgs canDrawArgs; + canDrawArgs.fShaderCaps = context->caps()->shaderCaps(); + canDrawArgs.fViewMatrix = &viewMatrix; + canDrawArgs.fPath = &path; + canDrawArgs.fStroke = &stroke; + canDrawArgs.fAntiAlias = element->isAA(); + canDrawArgs.fIsStencilDisabled = isStencilDisabled; + canDrawArgs.fIsStencilBufferMSAA = rt->isStencilBufferMultisampled(); + // the 'false' parameter disallows use of the SW path renderer - GrPathRenderer* pr = context->getPathRenderer(pipelineBuilder, viewMatrix, path, - stroke, false, type); + GrPathRenderer* pr = context->drawingManager()->getPathRenderer(canDrawArgs, false, type); if (prOut) { *prOut = pr; } @@ -99,13 +109,20 @@ static bool path_needs_SW_renderer(GrContext* context, // 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. -static GrPathRenderer* get_path_renderer(GrContext* context, - GrPipelineBuilder* pipelineBuilder, - const SkMatrix& viewMatrix, - const SkClipStack::Element* element) { +GrPathRenderer* GrClipMaskManager::GetPathRenderer(GrContext* context, + GrTexture* texture, + const SkMatrix& viewMatrix, + const SkClipStack::Element* element) { GrPathRenderer* pr; static const bool kNeedsStencil = true; - path_needs_SW_renderer(context, *pipelineBuilder, viewMatrix, element, &pr, kNeedsStencil); + static const bool kStencilIsDisabled = true; + PathNeedsSWRenderer(context, + kStencilIsDisabled, + texture->asRenderTarget(), + viewMatrix, + element, + &pr, + kNeedsStencil); return pr; } @@ -131,6 +148,7 @@ GrResourceProvider* GrClipMaskManager::resourceProvider() { * entire clip should be rendered in SW and then uploaded en masse to the gpu. */ bool GrClipMaskManager::useSWOnlyPath(const GrPipelineBuilder& pipelineBuilder, + const GrRenderTarget* rt, const SkVector& clipToMaskOffset, const GrReducedClip::ElementList& elements) { // TODO: generalize this function so that when @@ -149,8 +167,8 @@ bool GrClipMaskManager::useSWOnlyPath(const GrPipelineBuilder& pipelineBuilder, bool needsStencil = invert || SkRegion::kIntersect_Op == op || SkRegion::kReverseDifference_Op == op; - if (path_needs_SW_renderer(this->getContext(), pipelineBuilder, translate, - element, nullptr, needsStencil)) { + if (PathNeedsSWRenderer(this->getContext(), pipelineBuilder.getStencil().isDisabled(), + rt, translate, element, nullptr, needsStencil)) { return true; } } @@ -360,7 +378,7 @@ bool GrClipMaskManager::setupClipping(const GrPipelineBuilder& pipelineBuilder, SkIntToScalar(-clipSpaceIBounds.fTop) }; - if (this->useSWOnlyPath(pipelineBuilder, clipToMaskOffset, elements)) { + if (this->useSWOnlyPath(pipelineBuilder, rt, clipToMaskOffset, elements)) { // The clip geometry is complex enough that it will be more efficient to create it // entirely in software result.reset(this->createSoftwareClipMask(genID, @@ -426,7 +444,8 @@ bool GrClipMaskManager::drawElement(GrPipelineBuilder* pipelineBuilder, const SkClipStack::Element* element, GrPathRenderer* pr) { - pipelineBuilder->setRenderTarget(target->asRenderTarget()); + GrRenderTarget* rt = target->asRenderTarget(); + pipelineBuilder->setRenderTarget(rt); // The color we use to draw does not matter since we will always be using a GrCoverageSetOpXP // which ignores color. @@ -462,8 +481,17 @@ bool GrClipMaskManager::drawElement(GrPipelineBuilder* pipelineBuilder, GrPathRendererChain::DrawType type; type = element->isAA() ? GrPathRendererChain::kColorAntiAlias_DrawType : GrPathRendererChain::kColor_DrawType; - pr = this->getContext()->getPathRenderer(*pipelineBuilder, viewMatrix, - path, stroke, false, type); + + GrPathRenderer::CanDrawPathArgs canDrawArgs; + canDrawArgs.fShaderCaps = this->getContext()->caps()->shaderCaps(); + canDrawArgs.fViewMatrix = &viewMatrix; + canDrawArgs.fPath = &path; + canDrawArgs.fStroke = &stroke; + canDrawArgs.fAntiAlias = element->isAA();; + canDrawArgs.fIsStencilDisabled = pipelineBuilder->getStencil().isDisabled(); + canDrawArgs.fIsStencilBufferMSAA = rt->isStencilBufferMultisampled(); + + pr = this->getContext()->drawingManager()->getPathRenderer(canDrawArgs, false, type); } if (nullptr == pr) { return false; @@ -566,8 +594,9 @@ GrTexture* GrClipMaskManager::createAlphaClipMask(int32_t elementsGenID, pipelineBuilder.setClip(clip); pipelineBuilder.setRenderTarget(texture->asRenderTarget()); - GrPathRenderer* pr = get_path_renderer(this->getContext(), &pipelineBuilder, - translate, element); + SkASSERT(pipelineBuilder.getStencil().isDisabled()); + GrPathRenderer* pr = GetPathRenderer(this->getContext(), + texture, translate, element); if (Element::kRect_Type != element->getType() && !pr) { // useSWOnlyPath should now filter out all cases where gpu-side mask merging would // be performed (i.e., pr would be NULL for a non-rect path). See skbug.com/4519 @@ -701,13 +730,21 @@ bool GrClipMaskManager::createStencilClipMask(GrRenderTarget* rt, if (fillInverted) { clipPath.toggleInverseFillType(); } - pr = this->getContext()->getPathRenderer(pipelineBuilder, - viewMatrix, - clipPath, - stroke, - false, - GrPathRendererChain::kStencilOnly_DrawType, - &stencilSupport); + + SkASSERT(pipelineBuilder.getStencil().isDisabled()); + + GrPathRenderer::CanDrawPathArgs canDrawArgs; + canDrawArgs.fShaderCaps = this->getContext()->caps()->shaderCaps(); + canDrawArgs.fViewMatrix = &viewMatrix; + canDrawArgs.fPath = &clipPath; + canDrawArgs.fStroke = &stroke; + canDrawArgs.fAntiAlias = false; + canDrawArgs.fIsStencilDisabled = pipelineBuilder.getStencil().isDisabled(); + canDrawArgs.fIsStencilBufferMSAA = rt->isStencilBufferMultisampled(); + + pr = this->getContext()->drawingManager()->getPathRenderer(canDrawArgs, false, + GrPathRendererChain::kStencilOnly_DrawType, + &stencilSupport); if (nullptr == pr) { return false; } diff --git a/src/gpu/GrClipMaskManager.h b/src/gpu/GrClipMaskManager.h index 2d9816c84c..98fd3af351 100644 --- a/src/gpu/GrClipMaskManager.h +++ b/src/gpu/GrClipMaskManager.h @@ -76,6 +76,18 @@ private: inline const GrCaps* caps() const; inline GrResourceProvider* resourceProvider(); + static bool PathNeedsSWRenderer(GrContext* context, + bool isStencilDisabled, + const GrRenderTarget* rt, + const SkMatrix& viewMatrix, + const SkClipStack::Element* element, + GrPathRenderer** prOut, + bool needsStencil); + static GrPathRenderer* GetPathRenderer(GrContext* context, + GrTexture* texture, + const SkMatrix& viewMatrix, + const SkClipStack::Element* element); + /** * Informs the helper function adjustStencilParams() about how the stencil * buffer clip is being used. @@ -125,8 +137,9 @@ private: const SkIRect& clipSpaceIBounds); bool useSWOnlyPath(const GrPipelineBuilder&, - const SkVector& clipToMaskOffset, - const GrReducedClip::ElementList& elements); + const GrRenderTarget* rt, + const SkVector& clipToMaskOffset, + const GrReducedClip::ElementList& elements); // Draws a clip element into the target alpha mask. The caller should have already setup the // desired blend operation. Optionally if the caller already selected a path renderer it can diff --git a/src/gpu/GrContext.cpp b/src/gpu/GrContext.cpp index 04e1b8d203..755b0f2ec9 100644 --- a/src/gpu/GrContext.cpp +++ b/src/gpu/GrContext.cpp @@ -60,8 +60,6 @@ GrContext::GrContext() : fUniqueID(next_id()) { fCaps = nullptr; fResourceCache = nullptr; fResourceProvider = nullptr; - fPathRendererChain = nullptr; - fSoftwarePathRenderer = nullptr; fBatchFontCache = nullptr; fFlushToReduceCacheSize = false; } @@ -118,8 +116,6 @@ GrContext::~GrContext() { fGpu->unref(); fCaps->unref(); - SkSafeUnref(fPathRendererChain); - SkSafeUnref(fSoftwarePathRenderer); } void GrContext::abandonContext() { @@ -130,11 +126,6 @@ void GrContext::abandonContext() { fGpu->contextAbandoned(); - // a path renderer may be holding onto resources that - // are now unusable - SkSafeSetNull(fPathRendererChain); - SkSafeSetNull(fSoftwarePathRenderer); - fDrawingManager->abandon(); fBatchFontCache->freeAll(); @@ -151,9 +142,8 @@ void GrContext::freeGpuResources() { fBatchFontCache->freeAll(); fLayerCache->freeAll(); - // a path renderer may be holding onto resources - SkSafeSetNull(fPathRendererChain); - SkSafeSetNull(fSoftwarePathRenderer); + + fDrawingManager->freeGpuResources(); fResourceCache->purgeAllUnlocked(); } @@ -535,42 +525,6 @@ void GrContext::flushSurfaceWrites(GrSurface* surface) { } } -/* - * This method finds a path renderer that can draw the specified path on - * the provided target. - * Due to its expense, the software path renderer has split out so it can - * can be individually allowed/disallowed via the "allowSW" boolean. - */ -GrPathRenderer* GrContext::getPathRenderer(const GrPipelineBuilder& pipelineBuilder, - const SkMatrix& viewMatrix, - const SkPath& path, - const GrStrokeInfo& stroke, - bool allowSW, - GrPathRendererChain::DrawType drawType, - GrPathRendererChain::StencilSupport* stencilSupport) { - - if (!fPathRendererChain) { - fPathRendererChain = new GrPathRendererChain(this); - } - - GrPathRenderer* pr = fPathRendererChain->getPathRenderer(this->caps()->shaderCaps(), - pipelineBuilder, - viewMatrix, - path, - stroke, - drawType, - stencilSupport); - - if (!pr && allowSW) { - if (!fSoftwarePathRenderer) { - fSoftwarePathRenderer = new GrSoftwarePathRenderer(this); - } - pr = fSoftwarePathRenderer; - } - - return pr; -} - //////////////////////////////////////////////////////////////////////////////// int GrContext::getRecommendedSampleCount(GrPixelConfig config, SkScalar dpi) const { diff --git a/src/gpu/GrDrawContext.cpp b/src/gpu/GrDrawContext.cpp index d64273a828..82e1057c6a 100644 --- a/src/gpu/GrDrawContext.cpp +++ b/src/gpu/GrDrawContext.cpp @@ -680,21 +680,28 @@ void GrDrawContext::internalDrawPath(GrPipelineBuilder* pipelineBuilder, // thing WRT to the blend then we'll need some query on the PR. bool useCoverageAA = useAA && !pipelineBuilder->getRenderTarget()->isUnifiedMultisampled(); + bool isStencilDisabled = pipelineBuilder->getStencil().isDisabled(); + bool isStencilBufferMSAA = pipelineBuilder->getRenderTarget()->isStencilBufferMultisampled(); - - GrPathRendererChain::DrawType type = - useCoverageAA ? GrPathRendererChain::kColorAntiAlias_DrawType : - GrPathRendererChain::kColor_DrawType; + const GrPathRendererChain::DrawType type = + useCoverageAA ? GrPathRendererChain::kColorAntiAlias_DrawType + : GrPathRendererChain::kColor_DrawType; const SkPath* pathPtr = &path; SkTLazy<SkPath> tmpPath; const GrStrokeInfo* strokeInfoPtr = &strokeInfo; + GrPathRenderer::CanDrawPathArgs canDrawArgs; + canDrawArgs.fShaderCaps = fDrawingManager->getContext()->caps()->shaderCaps(); + canDrawArgs.fViewMatrix = &viewMatrix; + canDrawArgs.fPath = pathPtr; + canDrawArgs.fStroke = strokeInfoPtr; + canDrawArgs.fAntiAlias = useCoverageAA; + canDrawArgs.fIsStencilDisabled = isStencilDisabled; + canDrawArgs.fIsStencilBufferMSAA = isStencilBufferMSAA; + // Try a 1st time without stroking the path and without allowing the SW renderer - GrPathRenderer* pr = fDrawingManager->getContext()->getPathRenderer(*pipelineBuilder, - viewMatrix, *pathPtr, - *strokeInfoPtr, false, - type); + GrPathRenderer* pr = fDrawingManager->getPathRenderer(canDrawArgs, false, type); GrStrokeInfo dashlessStrokeInfo(strokeInfo, false); if (nullptr == pr && strokeInfo.isDashed()) { @@ -707,9 +714,11 @@ void GrDrawContext::internalDrawPath(GrPipelineBuilder* pipelineBuilder, return; } strokeInfoPtr = &dashlessStrokeInfo; - pr = fDrawingManager->getContext()->getPathRenderer(*pipelineBuilder, viewMatrix, - *pathPtr, *strokeInfoPtr, - false, type); + + canDrawArgs.fPath = pathPtr; + canDrawArgs.fStroke = strokeInfoPtr; + + pr = fDrawingManager->getPathRenderer(canDrawArgs, false, type); } if (nullptr == pr) { @@ -731,10 +740,11 @@ void GrDrawContext::internalDrawPath(GrPipelineBuilder* pipelineBuilder, strokeInfoPtr = &dashlessStrokeInfo; } + canDrawArgs.fPath = pathPtr; + canDrawArgs.fStroke = strokeInfoPtr; + // This time, allow SW renderer - pr = fDrawingManager->getContext()->getPathRenderer(*pipelineBuilder, viewMatrix, - *pathPtr, *strokeInfoPtr, - true, type); + pr = fDrawingManager->getPathRenderer(canDrawArgs, true, type); } if (nullptr == pr) { diff --git a/src/gpu/GrDrawingManager.cpp b/src/gpu/GrDrawingManager.cpp index 0dbd476c79..0a487daf41 100644 --- a/src/gpu/GrDrawingManager.cpp +++ b/src/gpu/GrDrawingManager.cpp @@ -10,6 +10,7 @@ #include "GrDrawingManager.h" #include "GrDrawTarget.h" #include "GrResourceProvider.h" +#include "GrSoftwarePathRenderer.h" #include "GrStencilAndCoverTextContext.h" #include "SkTTopoSort.h" @@ -29,6 +30,9 @@ void GrDrawingManager::cleanup() { delete fTextContexts[i][1]; fTextContexts[i][1] = nullptr; } + + SkSafeSetNull(fPathRendererChain); + SkSafeSetNull(fSoftwarePathRenderer); } GrDrawingManager::~GrDrawingManager() { @@ -40,6 +44,12 @@ void GrDrawingManager::abandon() { this->cleanup(); } +void GrDrawingManager::freeGpuResources() { + // a path renderer may be holding onto resources + SkSafeSetNull(fPathRendererChain); + SkSafeSetNull(fSoftwarePathRenderer); +} + void GrDrawingManager::reset() { for (int i = 0; i < fDrawTargets.count(); ++i) { fDrawTargets[i]->reset(); @@ -114,7 +124,33 @@ GrDrawTarget* GrDrawingManager::newDrawTarget(GrRenderTarget* rt) { return SkRef(dt); } -GrDrawContext* GrDrawingManager::drawContext(GrRenderTarget* rt, +/* + * This method finds a path renderer that can draw the specified path on + * the provided target. + * Due to its expense, the software path renderer has split out so it can + * can be individually allowed/disallowed via the "allowSW" boolean. + */ +GrPathRenderer* GrDrawingManager::getPathRenderer(const GrPathRenderer::CanDrawPathArgs& args, + bool allowSW, + GrPathRendererChain::DrawType drawType, + GrPathRenderer::StencilSupport* stencilSupport) { + + if (!fPathRendererChain) { + fPathRendererChain = new GrPathRendererChain(fContext); + } + + GrPathRenderer* pr = fPathRendererChain->getPathRenderer(args, drawType, stencilSupport); + if (!pr && allowSW) { + if (!fSoftwarePathRenderer) { + fSoftwarePathRenderer = new GrSoftwarePathRenderer(fContext); + } + pr = fSoftwarePathRenderer; + } + + return pr; +} + +GrDrawContext* GrDrawingManager::drawContext(GrRenderTarget* rt, const SkSurfaceProps* surfaceProps) { if (this->abandoned()) { return nullptr; diff --git a/src/gpu/GrDrawingManager.h b/src/gpu/GrDrawingManager.h index be21d68ea8..c8b9a9b471 100644 --- a/src/gpu/GrDrawingManager.h +++ b/src/gpu/GrDrawingManager.h @@ -9,10 +9,13 @@ #define GrDrawingManager_DEFINED #include "GrDrawTarget.h" +#include "GrPathRendererChain.h" +#include "GrPathRenderer.h" #include "SkTDArray.h" class GrContext; class GrDrawContext; +class GrSoftwarePathRenderer; class GrTextContext; // Currently the DrawingManager creates a separate GrTextContext for each @@ -29,6 +32,7 @@ public: ~GrDrawingManager(); bool abandoned() const { return fAbandoned; } + void freeGpuResources(); GrDrawContext* drawContext(GrRenderTarget* rt, const SkSurfaceProps* surfaceProps); @@ -40,12 +44,19 @@ public: GrContext* getContext() { return fContext; } + GrPathRenderer* getPathRenderer(const GrPathRenderer::CanDrawPathArgs& args, + bool allowSW, + GrPathRendererChain::DrawType drawType, + GrPathRenderer::StencilSupport* stencilSupport = NULL); + private: GrDrawingManager(GrContext* context, GrDrawTarget::Options options) : fContext(context) , fAbandoned(false) , fOptions(options) - , fNVPRTextContext(nullptr) { + , fNVPRTextContext(nullptr) + , fPathRendererChain(nullptr) + , fSoftwarePathRenderer(nullptr) { sk_bzero(fTextContexts, sizeof(fTextContexts)); } @@ -67,6 +78,9 @@ private: GrTextContext* fNVPRTextContext; GrTextContext* fTextContexts[kNumPixelGeometries][kNumDFTOptions]; + + GrPathRendererChain* fPathRendererChain; + GrSoftwarePathRenderer* fSoftwarePathRenderer; }; #endif diff --git a/src/gpu/GrPathRenderer.h b/src/gpu/GrPathRenderer.h index 2390ba0f97..25a2a68abb 100644 --- a/src/gpu/GrPathRenderer.h +++ b/src/gpu/GrPathRenderer.h @@ -10,7 +10,6 @@ #define GrPathRenderer_DEFINED #include "GrDrawTarget.h" -#include "GrPathRendererChain.h" #include "GrStencil.h" #include "GrStrokeInfo.h" @@ -51,13 +50,11 @@ public: * covered by the path. * 3) kNoSupport: This path renderer cannot be used to stencil the path. */ - typedef GrPathRendererChain::StencilSupport StencilSupport; - static const StencilSupport kNoSupport_StencilSupport = - GrPathRendererChain::kNoSupport_StencilSupport; - static const StencilSupport kStencilOnly_StencilSupport = - GrPathRendererChain::kStencilOnly_StencilSupport; - static const StencilSupport kNoRestriction_StencilSupport = - GrPathRendererChain::kNoRestriction_StencilSupport; + enum StencilSupport { + kNoSupport_StencilSupport, + kStencilOnly_StencilSupport, + kNoRestriction_StencilSupport, + }; /** * This function is to get the stencil support for a particular path. The path's fill must @@ -82,15 +79,17 @@ public: */ struct CanDrawPathArgs { const GrShaderCaps* fShaderCaps; - const GrPipelineBuilder* fPipelineBuilder;// only used by GrStencilAndCoverPathRenderer const SkMatrix* fViewMatrix; const SkPath* fPath; const GrStrokeInfo* fStroke; bool fAntiAlias; + // These next two are only used by GrStencilAndCoverPathRenderer + bool fIsStencilDisabled; + bool fIsStencilBufferMSAA; + void validate() const { SkASSERT(fShaderCaps); - SkASSERT(fPipelineBuilder); SkASSERT(fViewMatrix); SkASSERT(fPath); SkASSERT(fStroke); @@ -151,11 +150,14 @@ public: #ifdef SK_DEBUG CanDrawPathArgs canArgs; canArgs.fShaderCaps = args.fTarget->caps()->shaderCaps(); - canArgs.fPipelineBuilder = args.fPipelineBuilder; canArgs.fViewMatrix = args.fViewMatrix; canArgs.fPath = args.fPath; canArgs.fStroke = args.fStroke; canArgs.fAntiAlias = args.fAntiAlias; + + canArgs.fIsStencilDisabled = args.fPipelineBuilder->getStencil().isDisabled(); + canArgs.fIsStencilBufferMSAA = + args.fPipelineBuilder->getRenderTarget()->isStencilBufferMultisampled(); SkASSERT(this->canDrawPath(canArgs)); SkASSERT(args.fPipelineBuilder->getStencil().isDisabled() || kNoRestriction_StencilSupport == this->getStencilSupport(*args.fPath, diff --git a/src/gpu/GrPathRendererChain.cpp b/src/gpu/GrPathRendererChain.cpp index c6bc4c08f1..63195c6414 100644 --- a/src/gpu/GrPathRendererChain.cpp +++ b/src/gpu/GrPathRendererChain.cpp @@ -39,18 +39,12 @@ GrPathRenderer* GrPathRendererChain::addPathRenderer(GrPathRenderer* pr) { return pr; } -GrPathRenderer* GrPathRendererChain::getPathRenderer(const GrShaderCaps* shaderCaps, - const GrPipelineBuilder& pipelineBuilder, - const SkMatrix& viewMatrix, - const SkPath& path, - const GrStrokeInfo& stroke, +GrPathRenderer* GrPathRendererChain::getPathRenderer(const GrPathRenderer::CanDrawPathArgs& args, DrawType drawType, - StencilSupport* stencilSupport) { + GrPathRenderer::StencilSupport* stencilSupport) { if (!fInit) { this->init(); } - bool antiAlias = (kColorAntiAlias_DrawType == drawType || - kStencilAndColorAntiAlias_DrawType == drawType); GR_STATIC_ASSERT(GrPathRenderer::kNoSupport_StencilSupport < GrPathRenderer::kStencilOnly_StencilSupport); @@ -68,17 +62,10 @@ GrPathRenderer* GrPathRendererChain::getPathRenderer(const GrShaderCaps* shaderC for (int i = 0; i < fChain.count(); ++i) { - GrPathRenderer::CanDrawPathArgs args; - args.fShaderCaps = shaderCaps; - args.fPipelineBuilder = &pipelineBuilder; - args.fViewMatrix = &viewMatrix; - args.fPath = &path; - args.fStroke = &stroke; - args.fAntiAlias = antiAlias; if (fChain[i]->canDrawPath(args)) { if (GrPathRenderer::kNoSupport_StencilSupport != minStencilSupport) { GrPathRenderer::StencilSupport support = - fChain[i]->getStencilSupport(path, stroke); + fChain[i]->getStencilSupport(*args.fPath, *args.fStroke); if (support < minStencilSupport) { continue; } else if (stencilSupport) { diff --git a/src/gpu/GrPathRendererChain.h b/src/gpu/GrPathRendererChain.h new file mode 100644 index 0000000000..e0e7d46f06 --- /dev/null +++ b/src/gpu/GrPathRendererChain.h @@ -0,0 +1,72 @@ +/* + * Copyright 2011 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#ifndef GrPathRendererChain_DEFINED +#define GrPathRendererChain_DEFINED + +#include "GrPathRenderer.h" + +#include "SkRefCnt.h" +#include "SkTArray.h" + +class GrContext; +class GrPipelineBuilder; +class GrShaderCaps; +class GrStrokeInfo; +class SkMatrix; +class SkPath; + +/** + * Keeps track of an ordered list of path renderers. When a path needs to be + * drawn this list is scanned to find the most preferred renderer. To add your + * path renderer to the list implement the GrPathRenderer::AddPathRenderers + * function. + */ +class GrPathRendererChain : public SkRefCnt { +public: + GrPathRendererChain(GrContext* context); + + ~GrPathRendererChain(); + + /** Documents how the caller plans to use a GrPathRenderer to draw a path. It affects the PR + returned by getPathRenderer */ + enum DrawType { + kColor_DrawType, // draw to the color buffer, no AA + kColorAntiAlias_DrawType, // draw to color buffer, with partial coverage AA + kStencilOnly_DrawType, // draw just to the stencil buffer + kStencilAndColor_DrawType, // draw the stencil and color buffer, no AA + kStencilAndColorAntiAlias_DrawType // draw the stencil and color buffer, with partial + // coverage AA. + }; + + /** Returns a GrPathRenderer compatible with the request if one is available. If the caller + is drawing the path to the stencil buffer then stencilSupport can be used to determine + whether the path can be rendered with arbitrary stencil rules or not. See comments on + StencilSupport in GrPathRenderer.h. */ + GrPathRenderer* getPathRenderer(const GrPathRenderer::CanDrawPathArgs& args, + DrawType drawType, + GrPathRenderer::StencilSupport* stencilSupport); + +private: + GrPathRendererChain(); + + // takes a ref and unrefs in destructor + GrPathRenderer* addPathRenderer(GrPathRenderer* pr); + + void init(); + + enum { + kPreAllocCount = 8, + }; + bool fInit; + GrContext* fOwner; + SkSTArray<kPreAllocCount, GrPathRenderer*, true> fChain; + + typedef SkRefCnt INHERITED; +}; + +#endif diff --git a/src/gpu/GrPipelineBuilder.h b/src/gpu/GrPipelineBuilder.h index e329bc5736..2bafd9aeab 100644 --- a/src/gpu/GrPipelineBuilder.h +++ b/src/gpu/GrPipelineBuilder.h @@ -229,11 +229,6 @@ public: */ void setStencil(const GrStencilSettings& settings) { fStencilSettings = settings; } - /** - * Shortcut to disable stencil testing and ops. - */ - void disableStencil() { fStencilSettings.setDisabled(); } - GrStencilSettings* stencil() { return &fStencilSettings; } /** diff --git a/src/gpu/batches/GrStencilAndCoverPathRenderer.cpp b/src/gpu/batches/GrStencilAndCoverPathRenderer.cpp index 720c1c34f6..c96e2074c5 100644 --- a/src/gpu/batches/GrStencilAndCoverPathRenderer.cpp +++ b/src/gpu/batches/GrStencilAndCoverPathRenderer.cpp @@ -49,11 +49,11 @@ bool GrStencilAndCoverPathRenderer::onCanDrawPath(const CanDrawPathArgs& args) c if (args.fStroke->isHairlineStyle()) { return false; } - if (!args.fPipelineBuilder->getStencil().isDisabled()) { + if (!args.fIsStencilDisabled) { return false; } if (args.fAntiAlias) { - return args.fPipelineBuilder->getRenderTarget()->isStencilBufferMultisampled(); + return args.fIsStencilBufferMSAA; } else { return true; // doesn't do per-path AA, relies on the target having MSAA } |