diff options
Diffstat (limited to 'src/gpu/GrClipMaskManager.cpp')
-rw-r--r-- | src/gpu/GrClipMaskManager.cpp | 194 |
1 files changed, 79 insertions, 115 deletions
diff --git a/src/gpu/GrClipMaskManager.cpp b/src/gpu/GrClipMaskManager.cpp index df58a9251f..ff95eeaac3 100644 --- a/src/gpu/GrClipMaskManager.cpp +++ b/src/gpu/GrClipMaskManager.cpp @@ -9,7 +9,6 @@ #include "GrCaps.h" #include "GrDrawingManager.h" #include "GrDrawContextPriv.h" -#include "GrDrawTarget.h" #include "GrGpuResourcePriv.h" #include "GrPaint.h" #include "GrPathRenderer.h" @@ -28,6 +27,8 @@ typedef SkClipStack::Element Element; +static const int kMaxAnalyticElements = 4; + //////////////////////////////////////////////////////////////////////////////// // set up the draw state to enable the aa clipping mask. Besides setting up the // stage matrix this also alters the vertex layout @@ -50,15 +51,13 @@ static sk_sp<const GrFragmentProcessor> create_fp_for_mask(GrTexture* result, kDevice_GrCoordSet)); } -static void draw_non_aa_rect(GrDrawTarget* drawTarget, - const GrPipelineBuilder& pipelineBuilder, - const GrClip& clip, - GrColor color, - const SkMatrix& viewMatrix, - const SkRect& rect) { - SkAutoTUnref<GrDrawBatch> batch(GrRectBatchFactory::CreateNonAAFill(color, viewMatrix, rect, - nullptr, nullptr)); - drawTarget->drawBatch(pipelineBuilder, clip, batch); +void GrClipMaskManager::DrawNonAARect(GrDrawContext* drawContext, + const GrFixedClip& clip, + const SkMatrix& viewMatrix, + const SkRect& rect, + bool doAA, + const GrUserStencilSettings* stencilSettings) { + drawContext->drawContextPriv().stencilRect(clip, stencilSettings, doAA, viewMatrix, rect); } // Does the path in 'element' require SW rendering? If so, return true (and, @@ -66,7 +65,7 @@ static void draw_non_aa_rect(GrDrawTarget* drawTarget, // 'prOut' to the non-SW path renderer that will do the job). bool GrClipMaskManager::PathNeedsSWRenderer(GrContext* context, bool hasUserStencilSettings, - const GrRenderTarget* rt, + const GrDrawContext* drawContext, const SkMatrix& viewMatrix, const Element* element, GrPathRenderer** prOut, @@ -108,7 +107,7 @@ bool GrClipMaskManager::PathNeedsSWRenderer(GrContext* context, canDrawArgs.fStyle = &GrStyle::SimpleFill(); canDrawArgs.fAntiAlias = element->isAA(); canDrawArgs.fHasUserStencilSettings = hasUserStencilSettings; - canDrawArgs.fIsStencilBufferMSAA = rt->isStencilBufferMultisampled(); + canDrawArgs.fIsStencilBufferMSAA = drawContext->isStencilBufferMultisampled(); // the 'false' parameter disallows use of the SW path renderer GrPathRenderer* pr = context->drawingManager()->getPathRenderer(canDrawArgs, false, type); @@ -119,37 +118,6 @@ bool GrClipMaskManager::PathNeedsSWRenderer(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. -GrPathRenderer* GrClipMaskManager::GetPathRenderer(GrContext* context, - GrTexture* texture, - const SkMatrix& viewMatrix, - const SkClipStack::Element* element) { - GrPathRenderer* pr; - constexpr bool kNeedsStencil = true; - constexpr bool kHasUserStencilSettings = false; - PathNeedsSWRenderer(context, - kHasUserStencilSettings, - texture->asRenderTarget(), - viewMatrix, - element, - &pr, - kNeedsStencil); - return pr; -} - -GrContext* GrClipMaskManager::getContext() { - return fDrawTarget->cmmAccess().context(); -} - -const GrCaps* GrClipMaskManager::caps() const { - return fDrawTarget->caps(); -} - -GrResourceProvider* GrClipMaskManager::resourceProvider() { - return fDrawTarget->cmmAccess().resourceProvider(); -} /* * This method traverses the clip stack to see if the GrSoftwarePathRenderer * will be used on any element. If so, it returns true to indicate that the @@ -157,7 +125,7 @@ GrResourceProvider* GrClipMaskManager::resourceProvider() { */ bool GrClipMaskManager::UseSWOnlyPath(GrContext* context, const GrPipelineBuilder& pipelineBuilder, - const GrRenderTarget* rt, + const GrDrawContext* drawContext, const SkVector& clipToMaskOffset, const GrReducedClip::ElementList& elements) { // TODO: generalize this function so that when @@ -177,18 +145,18 @@ bool GrClipMaskManager::UseSWOnlyPath(GrContext* context, SkRegion::kIntersect_Op == op || SkRegion::kReverseDifference_Op == op; if (PathNeedsSWRenderer(context, pipelineBuilder.hasUserStencilSettings(), - rt, translate, element, nullptr, needsStencil)) { + drawContext, translate, element, nullptr, needsStencil)) { return true; } } return false; } -bool GrClipMaskManager::getAnalyticClipProcessor(const GrReducedClip::ElementList& elements, - bool abortIfAA, - SkVector& clipToRTOffset, - const SkRect* drawBounds, - sk_sp<const GrFragmentProcessor>* resultFP) { +static bool get_analytic_clip_processor(const GrReducedClip::ElementList& elements, + bool abortIfAA, + SkVector& clipToRTOffset, + const SkRect* drawBounds, + sk_sp<const GrFragmentProcessor>* resultFP) { SkRect boundsInClipSpace; if (drawBounds) { boundsInClipSpace = *drawBounds; @@ -284,7 +252,9 @@ bool GrClipMaskManager::getAnalyticClipProcessor(const GrReducedClip::ElementLis //////////////////////////////////////////////////////////////////////////////// // sort out what kind of clip mask needs to be created: alpha, stencil, // scissor, or entirely software -bool GrClipMaskManager::setupClipping(const GrPipelineBuilder& pipelineBuilder, +bool GrClipMaskManager::SetupClipping(GrContext* context, + const GrPipelineBuilder& pipelineBuilder, + GrDrawContext* drawContext, const GrClipStackClip& clip, const SkRect* devBounds, GrAppliedClip* out) { @@ -297,12 +267,8 @@ bool GrClipMaskManager::setupClipping(const GrPipelineBuilder& pipelineBuilder, GrReducedClip::InitialState initialState = GrReducedClip::kAllIn_InitialState; SkIRect clipSpaceIBounds; bool requiresAA = false; - GrRenderTarget* rt = pipelineBuilder.getRenderTarget(); - // GrDrawTarget should have filtered this for us - SkASSERT(rt); - - SkIRect clipSpaceRTIBounds = SkIRect::MakeWH(rt->width(), rt->height()); + SkIRect clipSpaceRTIBounds = SkIRect::MakeWH(drawContext->width(), drawContext->height()); clipSpaceRTIBounds.offset(clip.origin()); SkIRect clipSpaceReduceQueryBounds; @@ -346,8 +312,8 @@ bool GrClipMaskManager::setupClipping(const GrPipelineBuilder& pipelineBuilder, SkIntToScalar(-clip.origin().fY) }; // When there are multiple samples we want to do per-sample clipping, not compute a // fractional pixel coverage. - bool disallowAnalyticAA = rt->isStencilBufferMultisampled(); - if (disallowAnalyticAA && !rt->numColorSamples()) { + bool disallowAnalyticAA = drawContext->isStencilBufferMultisampled(); + if (disallowAnalyticAA && !drawContext->numColorSamples()) { // With a single color sample, any coverage info is lost from color once it hits the // color buffer anyway, so we may as well use coverage AA if nothing else in the pipe // is multisampled. @@ -357,12 +323,11 @@ bool GrClipMaskManager::setupClipping(const GrPipelineBuilder& pipelineBuilder, sk_sp<const GrFragmentProcessor> clipFP; if (elements.isEmpty() || (requiresAA && - this->getAnalyticClipProcessor(elements, disallowAnalyticAA, clipToRTOffset, devBounds, - &clipFP))) { + get_analytic_clip_processor(elements, disallowAnalyticAA, clipToRTOffset, devBounds, + &clipFP))) { SkIRect scissorSpaceIBounds(clipSpaceIBounds); scissorSpaceIBounds.offset(-clip.origin()); - if (nullptr == devBounds || - !SkRect::Make(scissorSpaceIBounds).contains(*devBounds)) { + if (!devBounds || !SkRect::Make(scissorSpaceIBounds).contains(*devBounds)) { out->makeScissoredFPBased(clipFP, scissorSpaceIBounds); return true; } @@ -372,7 +337,7 @@ bool GrClipMaskManager::setupClipping(const GrPipelineBuilder& pipelineBuilder, } // If the stencil buffer is multisampled we can use it to do everything. - if (!rt->isStencilBufferMultisampled() && requiresAA) { + if (!drawContext->isStencilBufferMultisampled() && requiresAA) { sk_sp<GrTexture> result; // The top-left of the mask corresponds to the top-left corner of the bounds. @@ -381,17 +346,18 @@ bool GrClipMaskManager::setupClipping(const GrPipelineBuilder& pipelineBuilder, SkIntToScalar(-clipSpaceIBounds.fTop) }; - if (UseSWOnlyPath(this->getContext(), pipelineBuilder, rt, clipToMaskOffset, elements)) { + if (UseSWOnlyPath(context, pipelineBuilder, drawContext, + clipToMaskOffset, elements)) { // The clip geometry is complex enough that it will be more efficient to create it // entirely in software - result = CreateSoftwareClipMask(this->getContext()->textureProvider(), + result = CreateSoftwareClipMask(context->textureProvider(), genID, initialState, elements, clipToMaskOffset, clipSpaceIBounds); } else { - result = CreateAlphaClipMask(this->getContext(), + result = CreateAlphaClipMask(context, genID, initialState, elements, @@ -414,12 +380,13 @@ bool GrClipMaskManager::setupClipping(const GrPipelineBuilder& pipelineBuilder, // use the stencil clip if we can't represent the clip as a rectangle. SkIPoint clipSpaceToStencilSpaceOffset = -clip.origin(); - this->createStencilClipMask(rt, - genID, - initialState, - elements, - clipSpaceIBounds, - clipSpaceToStencilSpaceOffset); + CreateStencilClipMask(context, + drawContext, + genID, + initialState, + elements, + clipSpaceIBounds, + clipSpaceToStencilSpaceOffset); // This must occur after createStencilClipMask. That function may change the scissor. Also, it // only guarantees that the stencil mask is correct within the bounds it was passed, so we must @@ -609,19 +576,22 @@ sk_sp<GrTexture> GrClipMaskManager::CreateAlphaClipMask(GrContext* context, //////////////////////////////////////////////////////////////////////////////// // Create a 1-bit clip mask in the stencil buffer. 'devClipBounds' are in device // (as opposed to canvas) coordinates -bool GrClipMaskManager::createStencilClipMask(GrRenderTarget* rt, +bool GrClipMaskManager::CreateStencilClipMask(GrContext* context, + GrDrawContext* drawContext, int32_t elementsGenID, GrReducedClip::InitialState initialState, const GrReducedClip::ElementList& elements, const SkIRect& clipSpaceIBounds, const SkIPoint& clipSpaceToStencilOffset) { - SkASSERT(rt); + SkASSERT(drawContext); - GrStencilAttachment* stencilAttachment = this->resourceProvider()->attachStencilAttachment(rt); + GrStencilAttachment* stencilAttachment = context->resourceProvider()->attachStencilAttachment( + drawContext->accessRenderTarget()); if (nullptr == stencilAttachment) { return false; } + // TODO: these need to be swapped over to using a StencilAttachmentProxy if (stencilAttachment->mustRenderClip(elementsGenID, clipSpaceIBounds, clipSpaceToStencilOffset)) { stencilAttachment->setLastClip(elementsGenID, clipSpaceIBounds, clipSpaceToStencilOffset); // Set the matrix so that rendered clip elements are transformed from clip to stencil space. @@ -637,24 +607,15 @@ bool GrClipMaskManager::createStencilClipMask(GrRenderTarget* rt, stencilSpaceIBounds.offset(clipSpaceToStencilOffset); GrFixedClip clip(stencilSpaceIBounds); - fDrawTarget->cmmAccess().clearStencilClip(stencilSpaceIBounds, - GrReducedClip::kAllIn_InitialState == initialState, rt); + drawContext->drawContextPriv().clearStencilClip( + stencilSpaceIBounds, + GrReducedClip::kAllIn_InitialState == initialState); // walk through each clip element and perform its set op // with the existing clip. for (GrReducedClip::ElementList::Iter iter(elements.headIter()); iter.get(); iter.next()) { const Element* element = iter.get(); - GrPipelineBuilder pipelineBuilder; - pipelineBuilder.setRenderTarget(rt); - - pipelineBuilder.setDisableColorXPFactory(); - - // if the target is MSAA then we want MSAA enabled when the clip is soft - if (rt->isStencilBufferMultisampled()) { - pipelineBuilder.setState(GrPipelineBuilder::kHWAntialias_Flag, element->isAA()); - } - bool fillInverted = false; // enabled at bottom of loop clip.enableStencilClip(false); @@ -677,21 +638,19 @@ bool GrClipMaskManager::createStencilClipMask(GrRenderTarget* rt, clipPath.toggleInverseFillType(); } - SkASSERT(!pipelineBuilder.hasUserStencilSettings()); - GrPathRenderer::CanDrawPathArgs canDrawArgs; - canDrawArgs.fShaderCaps = this->getContext()->caps()->shaderCaps(); + canDrawArgs.fShaderCaps = context->caps()->shaderCaps(); canDrawArgs.fViewMatrix = &viewMatrix; canDrawArgs.fPath = &clipPath; canDrawArgs.fStyle = &GrStyle::SimpleFill(); canDrawArgs.fAntiAlias = false; - canDrawArgs.fHasUserStencilSettings = pipelineBuilder.hasUserStencilSettings(); - canDrawArgs.fIsStencilBufferMSAA = rt->isStencilBufferMultisampled(); + canDrawArgs.fHasUserStencilSettings = false; + canDrawArgs.fIsStencilBufferMSAA = drawContext->isStencilBufferMultisampled(); - pr = this->getContext()->drawingManager()->getPathRenderer(canDrawArgs, false, - GrPathRendererChain::kStencilOnly_DrawType, - &stencilSupport); - if (nullptr == pr) { + pr = context->drawingManager()->getPathRenderer(canDrawArgs, false, + GrPathRendererChain::kStencilOnly_DrawType, + &stencilSupport); + if (!pr) { return false; } } @@ -718,19 +677,20 @@ bool GrClipMaskManager::createStencilClipMask(GrRenderTarget* rt, 0xffff>() ); if (Element::kRect_Type == element->getType()) { - pipelineBuilder.setUserStencil(&kDrawToStencil); - - draw_non_aa_rect(fDrawTarget, pipelineBuilder, clip, GrColor_WHITE, viewMatrix, - element->getRect()); + DrawNonAARect(drawContext, clip, viewMatrix, + element->getRect(), element->isAA(), &kDrawToStencil); } else { if (!clipPath.isEmpty()) { if (canRenderDirectToStencil) { - pipelineBuilder.setUserStencil(&kDrawToStencil); + GrPaint paint; + paint.setXPFactory(GrDisableColorXPFactory::Create()); + paint.setAntiAlias(element->isAA()); GrPathRenderer::DrawPathArgs args; - args.fTarget = fDrawTarget; - args.fResourceProvider = this->getContext()->resourceProvider(); - args.fPipelineBuilder = &pipelineBuilder; + args.fResourceProvider = context->resourceProvider(); + args.fPaint = &paint; + args.fUserStencilSettings = &kDrawToStencil; + args.fDrawContext = drawContext; args.fClip = &clip; args.fColor = GrColor_WHITE; args.fViewMatrix = &viewMatrix; @@ -741,12 +701,12 @@ bool GrClipMaskManager::createStencilClipMask(GrRenderTarget* rt, pr->drawPath(args); } else { GrPathRenderer::StencilPathArgs args; - args.fTarget = fDrawTarget; - args.fResourceProvider = this->getContext()->resourceProvider(); - args.fPipelineBuilder = &pipelineBuilder; + args.fResourceProvider = context->resourceProvider(); + args.fDrawContext = drawContext; args.fClip = &clip; args.fViewMatrix = &viewMatrix; args.fPath = &clipPath; + args.fIsAA = element->isAA(); pr->stencilPath(args); } } @@ -757,17 +717,21 @@ bool GrClipMaskManager::createStencilClipMask(GrRenderTarget* rt, // element directly or a bounding rect of the entire clip. clip.enableStencilClip(true); for (GrUserStencilSettings const* const* pass = stencilPasses; *pass; ++pass) { - pipelineBuilder.setUserStencil(*pass); if (drawDirectToClip) { if (Element::kRect_Type == element->getType()) { - draw_non_aa_rect(fDrawTarget, pipelineBuilder, clip, GrColor_WHITE, - viewMatrix, element->getRect()); + DrawNonAARect(drawContext, clip, + viewMatrix, element->getRect(), element->isAA(), *pass); } else { + GrPaint paint; + paint.setXPFactory(GrDisableColorXPFactory::Create()); + paint.setAntiAlias(element->isAA()); + GrPathRenderer::DrawPathArgs args; - args.fTarget = fDrawTarget; - args.fResourceProvider = this->getContext()->resourceProvider(); - args.fPipelineBuilder = &pipelineBuilder; + args.fResourceProvider = context->resourceProvider(); + args.fPaint = &paint; + args.fUserStencilSettings = *pass; + args.fDrawContext = drawContext; args.fClip = &clip; args.fColor = GrColor_WHITE; args.fViewMatrix = &viewMatrix; @@ -780,8 +744,8 @@ bool GrClipMaskManager::createStencilClipMask(GrRenderTarget* rt, } else { // The view matrix is setup to do clip space -> stencil space translation, so // draw rect in clip space. - draw_non_aa_rect(fDrawTarget, pipelineBuilder, clip, GrColor_WHITE, viewMatrix, - SkRect::Make(clipSpaceIBounds)); + DrawNonAARect(drawContext, clip, viewMatrix, + SkRect::Make(clipSpaceIBounds), false, *pass); } } } |