aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/gpu/GrClipMaskManager.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/gpu/GrClipMaskManager.cpp')
-rw-r--r--src/gpu/GrClipMaskManager.cpp194
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);
}
}
}