Chromium Code Reviews| Index: src/gpu/GrClipMaskManager.cpp |
| diff --git a/src/gpu/GrClipMaskManager.cpp b/src/gpu/GrClipMaskManager.cpp |
| index df58a9251f6e9b54c7d3a696d6268d18d6061fb7..ff95eeaac33439b7eef438e6caef5e6a7167e544 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); |
|
bsalomon
2016/06/03 14:27:15
It seems like this function's reliance on GrContex
robertphillips
2016/06/03 15:46:16
The getPathRenderer call should actually be limite
|
| @@ -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); |
| } |
| } |
| } |