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); |
@@ -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()); |
bungeman-skia
2016/06/03 23:57:03
leak
|
+ 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()); |
bungeman-skia
2016/06/03 23:57:03
leak
|
+ 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); |
} |
} |
} |