Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(15)

Unified Diff: src/gpu/GrClipMaskManager.cpp

Issue 732693002: Drawstate on stack (Closed) Base URL: https://skia.googlesource.com/skia.git@real_def_gp
Patch Set: tiny fix Created 6 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/gpu/GrClipMaskManager.h ('k') | src/gpu/GrContext.cpp » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/gpu/GrClipMaskManager.cpp
diff --git a/src/gpu/GrClipMaskManager.cpp b/src/gpu/GrClipMaskManager.cpp
index e04d444a545e4789954f62f76b88a57f83696d4b..f86aa9de29f7e1eb649972d4b88179505ab1c614 100644
--- a/src/gpu/GrClipMaskManager.cpp
+++ b/src/gpu/GrClipMaskManager.cpp
@@ -1,4 +1,3 @@
-
/*
* Copyright 2012 Google Inc.
*
@@ -24,17 +23,15 @@
#include "effects/GrRRectEffect.h"
#define GR_AA_CLIP 1
-
typedef SkClipStack::Element Element;
////////////////////////////////////////////////////////////////////////////////
namespace {
// set up the draw state to enable the aa clipping mask. Besides setting up the
// stage matrix this also alters the vertex layout
-void setup_drawstate_aaclip(GrDrawTarget* gpu,
- GrTexture* result,
- const SkIRect &devBound) {
- GrDrawState* drawState = gpu->drawState();
+void setup_drawstate_aaclip(const SkIRect &devBound,
+ GrDrawState* drawState,
+ GrTexture* result) {
SkASSERT(drawState);
SkMatrix mat;
@@ -58,7 +55,8 @@ void setup_drawstate_aaclip(GrDrawTarget* gpu,
}
bool path_needs_SW_renderer(GrContext* context,
- GrDrawTarget* gpu,
+ const GrDrawTarget* gpu,
+ const GrDrawState* drawState,
const SkPath& origPath,
const SkStrokeRec& stroke,
bool doAA) {
@@ -72,9 +70,8 @@ bool path_needs_SW_renderer(GrContext* context,
GrPathRendererChain::kColorAntiAlias_DrawType :
GrPathRendererChain::kColor_DrawType;
- return NULL == context->getPathRenderer(*path, stroke, gpu, false, type);
+ return NULL == context->getPathRenderer(gpu, drawState, *path, stroke, false, type);
}
-
}
/*
@@ -82,8 +79,8 @@ bool path_needs_SW_renderer(GrContext* context,
* will be used on any element. If so, it returns true to indicate that the
* entire clip should be rendered in SW and then uploaded en masse to the gpu.
*/
-bool GrClipMaskManager::useSWOnlyPath(const GrReducedClip::ElementList& elements) {
-
+bool GrClipMaskManager::useSWOnlyPath(const GrDrawState* drawState,
+ const GrReducedClip::ElementList& elements) {
// TODO: generalize this function so that when
// a clip gets complex enough it can just be done in SW regardless
// of whether it would invoke the GrSoftwarePathRenderer.
@@ -96,7 +93,7 @@ bool GrClipMaskManager::useSWOnlyPath(const GrReducedClip::ElementList& elements
if (Element::kRect_Type != element->getType()) {
SkPath path;
element->asPath(&path);
- if (path_needs_SW_renderer(this->getContext(), fClipTarget, path, stroke,
+ if (path_needs_SW_renderer(this->getContext(), fClipTarget, drawState, path, stroke,
element->isAA())) {
return true;
}
@@ -105,12 +102,11 @@ bool GrClipMaskManager::useSWOnlyPath(const GrReducedClip::ElementList& elements
return false;
}
-bool GrClipMaskManager::installClipEffects(const GrReducedClip::ElementList& elements,
+bool GrClipMaskManager::installClipEffects(GrDrawState* drawState,
GrDrawState::AutoRestoreEffects* are,
+ const GrReducedClip::ElementList& elements,
const SkVector& clipToRTOffset,
const SkRect* drawBounds) {
-
- GrDrawState* drawState = fClipTarget->drawState();
SkRect boundsInClipSpace;
if (drawBounds) {
boundsInClipSpace = *drawBounds;
@@ -120,10 +116,7 @@ bool GrClipMaskManager::installClipEffects(const GrReducedClip::ElementList& ele
are->set(drawState);
GrRenderTarget* rt = drawState->getRenderTarget();
GrReducedClip::ElementList::Iter iter(elements);
-
- bool setARE = false;
bool failed = false;
-
while (iter.get()) {
SkRegion::Op op = iter.get()->getOp();
bool invert;
@@ -187,11 +180,7 @@ bool GrClipMaskManager::installClipEffects(const GrReducedClip::ElementList& ele
break;
}
if (fp) {
- if (!setARE) {
- are->set(fClipTarget->drawState());
- setARE = true;
- }
- fClipTarget->drawState()->addCoverageProcessor(fp);
+ drawState->addCoverageProcessor(fp);
} else {
failed = true;
break;
@@ -203,18 +192,18 @@ bool GrClipMaskManager::installClipEffects(const GrReducedClip::ElementList& ele
if (failed) {
are->set(NULL);
}
-
return !failed;
}
////////////////////////////////////////////////////////////////////////////////
// sort out what kind of clip mask needs to be created: alpha, stencil,
// scissor, or entirely software
-bool GrClipMaskManager::setupClipping(const GrClipData* clipDataIn,
- const SkRect* devBounds,
+bool GrClipMaskManager::setupClipping(GrDrawState* drawState,
GrDrawState::AutoRestoreEffects* are,
GrDrawState::AutoRestoreStencil* ars,
- ScissorState* scissorState) {
+ ScissorState* scissorState,
+ const GrClipData* clipDataIn,
+ const SkRect* devBounds) {
fCurrClipMaskType = kNone_ClipMaskType;
if (kRespectClip_StencilClipMode == fClipMode) {
fClipMode = kIgnoreClip_StencilClipMode;
@@ -225,10 +214,8 @@ bool GrClipMaskManager::setupClipping(const GrClipData* clipDataIn,
GrReducedClip::InitialState initialState;
SkIRect clipSpaceIBounds;
bool requiresAA;
+ GrRenderTarget* rt = drawState->getRenderTarget();
- GrDrawState* drawState = fClipTarget->drawState();
-
- const GrRenderTarget* rt = drawState->getRenderTarget();
// GrDrawTarget should have filtered this for us
SkASSERT(rt);
@@ -253,7 +240,7 @@ bool GrClipMaskManager::setupClipping(const GrClipData* clipDataIn,
}
if (ignoreClip) {
- this->setDrawStateStencil(ars);
+ this->setDrawStateStencil(drawState, ars);
return true;
}
@@ -269,14 +256,15 @@ bool GrClipMaskManager::setupClipping(const GrClipData* clipDataIn,
SkVector clipToRTOffset = { SkIntToScalar(-clipDataIn->fOrigin.fX),
SkIntToScalar(-clipDataIn->fOrigin.fY) };
if (elements.isEmpty() ||
- (requiresAA && this->installClipEffects(elements, are, clipToRTOffset, devBounds))) {
+ (requiresAA && this->installClipEffects(drawState, are, elements, clipToRTOffset,
+ devBounds))) {
SkIRect scissorSpaceIBounds(clipSpaceIBounds);
scissorSpaceIBounds.offset(-clipDataIn->fOrigin);
if (NULL == devBounds ||
!SkRect::Make(scissorSpaceIBounds).contains(*devBounds)) {
scissorState->set(scissorSpaceIBounds);
}
- this->setDrawStateStencil(ars);
+ this->setDrawStateStencil(drawState, ars);
return true;
}
}
@@ -286,7 +274,7 @@ bool GrClipMaskManager::setupClipping(const GrClipData* clipDataIn,
if (0 == rt->numSamples() && requiresAA) {
GrTexture* result = NULL;
- if (this->useSWOnlyPath(elements)) {
+ if (this->useSWOnlyPath(drawState, elements)) {
// The clip geometry is complex enough that it will be more efficient to create it
// entirely in software
result = this->createSoftwareClipMask(genID,
@@ -305,9 +293,8 @@ bool GrClipMaskManager::setupClipping(const GrClipData* clipDataIn,
// clipSpace bounds. We determine the mask's position WRT to the render target here.
SkIRect rtSpaceMaskBounds = clipSpaceIBounds;
rtSpaceMaskBounds.offset(-clipDataIn->fOrigin);
- are->set(fClipTarget->drawState());
- setup_drawstate_aaclip(fClipTarget, result, rtSpaceMaskBounds);
- this->setDrawStateStencil(ars);
+ setup_drawstate_aaclip(rtSpaceMaskBounds, drawState, result);
+ this->setDrawStateStencil(drawState, ars);
return true;
}
// if alpha clip mask creation fails fall through to the non-AA code paths
@@ -323,7 +310,8 @@ bool GrClipMaskManager::setupClipping(const GrClipData* clipDataIn,
// use the stencil clip if we can't represent the clip as a rectangle.
SkIPoint clipSpaceToStencilSpaceOffset = -clipDataIn->fOrigin;
- this->createStencilClipMask(genID,
+ this->createStencilClipMask(rt,
+ genID,
initialState,
elements,
clipSpaceIBounds,
@@ -335,27 +323,15 @@ bool GrClipMaskManager::setupClipping(const GrClipData* clipDataIn,
SkIRect scissorSpaceIBounds(clipSpaceIBounds);
scissorSpaceIBounds.offset(clipSpaceToStencilSpaceOffset);
scissorState->set(scissorSpaceIBounds);
- this->setDrawStateStencil(ars);
+ this->setDrawStateStencil(drawState, ars);
return true;
}
-#define VISUALIZE_COMPLEX_CLIP 0
-
-#if VISUALIZE_COMPLEX_CLIP
- #include "SkRandom.h"
- SkRandom gRandom;
- #define SET_RANDOM_COLOR drawState->setColor(0xff000000 | gRandom.nextU());
-#else
- #define SET_RANDOM_COLOR
-#endif
-
namespace {
-
////////////////////////////////////////////////////////////////////////////////
// set up the OpenGL blend function to perform the specified
// boolean operation for alpha clip mask creation
-void setup_boolean_blendcoeffs(GrDrawState* drawState, SkRegion::Op op) {
-
+void setup_boolean_blendcoeffs(SkRegion::Op op, GrDrawState* drawState) {
switch (op) {
case SkRegion::kReplace_Op:
drawState->setBlendFunc(kOne_GrBlendCoeff, kZero_GrBlendCoeff);
@@ -380,14 +356,14 @@ void setup_boolean_blendcoeffs(GrDrawState* drawState, SkRegion::Op op) {
break;
}
}
-
}
////////////////////////////////////////////////////////////////////////////////
-bool GrClipMaskManager::drawElement(GrTexture* target,
+bool GrClipMaskManager::drawElement(GrDrawState* drawState,
+ GrTexture* target,
const SkClipStack::Element* element,
GrPathRenderer* pr) {
- GrDrawState* drawState = fClipTarget->drawState();
+ GrDrawTarget::AutoGeometryPush agp(fClipTarget);
drawState->setRenderTarget(target->asRenderTarget());
@@ -401,11 +377,12 @@ bool GrClipMaskManager::drawElement(GrTexture* target,
// the entire mask bounds and writes 0 outside the rect.
if (element->isAA()) {
this->getContext()->getAARectRenderer()->fillAARect(fClipTarget,
+ drawState,
element->getRect(),
SkMatrix::I(),
element->getRect());
} else {
- fClipTarget->drawSimpleRect(element->getRect());
+ fClipTarget->drawSimpleRect(drawState, element->getRect());
}
return true;
default: {
@@ -420,22 +397,24 @@ bool GrClipMaskManager::drawElement(GrTexture* target,
GrPathRendererChain::DrawType type;
type = element->isAA() ? GrPathRendererChain::kColorAntiAlias_DrawType :
GrPathRendererChain::kColor_DrawType;
- pr = this->getContext()->getPathRenderer(path, stroke, fClipTarget, false, type);
+ pr = this->getContext()->getPathRenderer(fClipTarget, drawState, path, stroke,
+ false, type);
}
if (NULL == pr) {
return false;
}
- pr->drawPath(path, stroke, fClipTarget, element->isAA());
+
+ pr->drawPath(fClipTarget, drawState, path, stroke, element->isAA());
break;
}
}
return true;
}
-bool GrClipMaskManager::canStencilAndDrawElement(GrTexture* target,
- const SkClipStack::Element* element,
- GrPathRenderer** pr) {
- GrDrawState* drawState = fClipTarget->drawState();
+bool GrClipMaskManager::canStencilAndDrawElement(GrDrawState* drawState,
+ GrTexture* target,
+ GrPathRenderer** pr,
+ const SkClipStack::Element* element) {
drawState->setRenderTarget(target->asRenderTarget());
if (Element::kRect_Type == element->getType()) {
@@ -452,24 +431,23 @@ bool GrClipMaskManager::canStencilAndDrawElement(GrTexture* target,
GrPathRendererChain::DrawType type = element->isAA() ?
GrPathRendererChain::kStencilAndColorAntiAlias_DrawType :
GrPathRendererChain::kStencilAndColor_DrawType;
- *pr = this->getContext()->getPathRenderer(path, stroke, fClipTarget, false, type);
+ *pr = this->getContext()->getPathRenderer(fClipTarget, drawState, path, stroke, false,
+ type);
return SkToBool(*pr);
}
}
-void GrClipMaskManager::mergeMask(GrTexture* dstMask,
+void GrClipMaskManager::mergeMask(GrDrawState* drawState,
+ GrTexture* dstMask,
GrTexture* srcMask,
SkRegion::Op op,
const SkIRect& dstBound,
const SkIRect& srcBound) {
- GrDrawState::AutoViewMatrixRestore avmr;
- GrDrawState* drawState = fClipTarget->drawState();
- SkAssertResult(avmr.setIdentity(drawState));
- GrDrawState::AutoRestoreEffects are(drawState);
+ SkAssertResult(drawState->setIdentityViewMatrix());
drawState->setRenderTarget(dstMask->asRenderTarget());
- setup_boolean_blendcoeffs(drawState, op);
+ setup_boolean_blendcoeffs(op, drawState);
SkMatrix sampleM;
sampleM.setIDiv(srcMask->width(), srcMask->height());
@@ -480,7 +458,7 @@ void GrClipMaskManager::mergeMask(GrTexture* dstMask,
GrTextureDomain::MakeTexelDomain(srcMask, srcBound),
GrTextureDomain::kDecal_Mode,
GrTextureParams::kNone_FilterMode))->unref();
- fClipTarget->drawSimpleRect(SkRect::Make(dstBound));
+ fClipTarget->drawSimpleRect(drawState, SkRect::Make(dstBound));
}
GrTexture* GrClipMaskManager::createTempMask(int width, int height) {
@@ -563,13 +541,6 @@ GrTexture* GrClipMaskManager::createAlphaClipMask(int32_t elementsGenID,
// Set the matrix so that rendered clip elements are transformed to mask space from clip space.
SkMatrix translate;
translate.setTranslate(clipToMaskOffset);
- GrDrawTarget::AutoGeometryAndStatePush agasp(fClipTarget, GrDrawTarget::kReset_ASRInit,
- &translate);
-
- GrDrawState* drawState = fClipTarget->drawState();
-
- // We're drawing a coverage mask and want coverage to be run through the blend function.
- drawState->enableState(GrDrawState::kCoverageDrawing_StateBit);
// The scratch texture that we are drawing into can be substantially larger than the mask. Only
// clear the part that we care about.
@@ -583,18 +554,21 @@ GrTexture* GrClipMaskManager::createAlphaClipMask(int32_t elementsGenID,
// pass must not set values outside of this bounds or stencil values outside the rect won't be
// cleared.
GrDrawTarget::AutoClipRestore acr(fClipTarget, maskSpaceIBounds);
- drawState->enableState(GrDrawState::kClip_StateBit);
-
SkAutoTUnref<GrTexture> temp;
+
// walk through each clip element and perform its set op
for (GrReducedClip::ElementList::Iter iter = elements.headIter(); iter.get(); iter.next()) {
const Element* element = iter.get();
SkRegion::Op op = element->getOp();
bool invert = element->isInverseFilled();
-
if (invert || SkRegion::kIntersect_Op == op || SkRegion::kReverseDifference_Op == op) {
+ GrDrawState drawState(translate);
+ // We're drawing a coverage mask and want coverage to be run through the blend function.
+ drawState.enableState(GrDrawState::kCoverageDrawing_StateBit |
+ GrDrawState::kClip_StateBit);
+
GrPathRenderer* pr = NULL;
- bool useTemp = !this->canStencilAndDrawElement(result, element, &pr);
+ bool useTemp = !this->canStencilAndDrawElement(&drawState, result, &pr, element);
GrTexture* dst;
// This is the bounds of the clip element in the space of the alpha-mask. The temporary
// mask buffer can be substantially larger than the actually clip stack element. We
@@ -622,11 +596,10 @@ GrTexture* GrClipMaskManager::createAlphaClipMask(int32_t elementsGenID,
dst = temp;
// clear the temp target and set blend to replace
fClipTarget->clear(&maskSpaceElementIBounds,
- invert ? 0xffffffff : 0x00000000,
- true,
- dst->asRenderTarget());
- setup_boolean_blendcoeffs(drawState, SkRegion::kReplace_Op);
-
+ invert ? 0xffffffff : 0x00000000,
+ true,
+ dst->asRenderTarget());
+ setup_boolean_blendcoeffs(SkRegion::kReplace_Op, &drawState);
} else {
// draw directly into the result with the stencil set to make the pixels affected
// by the clip shape be non-zero.
@@ -638,13 +611,17 @@ GrTexture* GrClipMaskManager::createAlphaClipMask(int32_t elementsGenID,
0xffff,
0xffff,
0xffff);
- drawState->setStencil(kStencilInElement);
- setup_boolean_blendcoeffs(drawState, op);
+ drawState.setStencil(kStencilInElement);
+ setup_boolean_blendcoeffs(op, &drawState);
}
- drawState->setAlpha(invert ? 0x00 : 0xff);
+ drawState.setAlpha(invert ? 0x00 : 0xff);
- if (!this->drawElement(dst, element, pr)) {
+ // We have to backup the drawstate because the drawElement call may call into
+ // renderers which consume it.
+ GrDrawState backupDrawState(drawState);
+
+ if (!this->drawElement(&drawState, dst, element, pr)) {
fAACache.reset();
return NULL;
}
@@ -652,14 +629,15 @@ GrTexture* GrClipMaskManager::createAlphaClipMask(int32_t elementsGenID,
if (useTemp) {
// Now draw into the accumulator using the real operation and the temp buffer as a
// texture
- this->mergeMask(result,
+ this->mergeMask(&backupDrawState,
+ result,
temp,
op,
maskSpaceIBounds,
maskSpaceElementIBounds);
} else {
// Draw to the exterior pixels (those with a zero stencil value).
- drawState->setAlpha(invert ? 0xff : 0x00);
+ backupDrawState.setAlpha(invert ? 0xff : 0x00);
GR_STATIC_CONST_SAME_STENCIL(kDrawOutsideElement,
kZero_StencilOp,
kZero_StencilOp,
@@ -667,15 +645,18 @@ GrTexture* GrClipMaskManager::createAlphaClipMask(int32_t elementsGenID,
0xffff,
0x0000,
0xffff);
- drawState->setStencil(kDrawOutsideElement);
- fClipTarget->drawSimpleRect(clipSpaceIBounds);
- drawState->disableStencil();
+ backupDrawState.setStencil(kDrawOutsideElement);
+ fClipTarget->drawSimpleRect(&backupDrawState, clipSpaceIBounds);
}
} else {
+ GrDrawState drawState(translate);
+ drawState.enableState(GrDrawState::kCoverageDrawing_StateBit |
+ GrDrawState::kClip_StateBit);
+
// all the remaining ops can just be directly draw into the accumulation buffer
- drawState->setAlpha(0xff);
- setup_boolean_blendcoeffs(drawState, op);
- this->drawElement(result, element);
+ drawState.setAlpha(0xff);
+ setup_boolean_blendcoeffs(op, &drawState);
+ this->drawElement(&drawState, result, element);
}
}
@@ -686,18 +667,13 @@ GrTexture* GrClipMaskManager::createAlphaClipMask(int32_t elementsGenID,
////////////////////////////////////////////////////////////////////////////////
// Create a 1-bit clip mask in the stencil buffer. 'devClipBounds' are in device
// (as opposed to canvas) coordinates
-bool GrClipMaskManager::createStencilClipMask(int32_t elementsGenID,
+bool GrClipMaskManager::createStencilClipMask(GrRenderTarget* rt,
+ int32_t elementsGenID,
GrReducedClip::InitialState initialState,
const GrReducedClip::ElementList& elements,
const SkIRect& clipSpaceIBounds,
const SkIPoint& clipSpaceToStencilOffset) {
-
SkASSERT(kNone_ClipMaskType == fCurrClipMaskType);
-
- GrDrawState* drawState = fClipTarget->drawState();
- SkASSERT(drawState->isClipState());
-
- GrRenderTarget* rt = drawState->getRenderTarget();
SkASSERT(rt);
// TODO: dynamically attach a SB when needed.
@@ -708,7 +684,6 @@ bool GrClipMaskManager::createStencilClipMask(int32_t elementsGenID,
if (stencilBuffer->mustRenderClip(elementsGenID, clipSpaceIBounds, clipSpaceToStencilOffset)) {
stencilBuffer->setLastClip(elementsGenID, clipSpaceIBounds, clipSpaceToStencilOffset);
-
// Set the matrix so that rendered clip elements are transformed from clip to stencil space.
SkVector translate = {
SkIntToScalar(clipSpaceToStencilOffset.fX),
@@ -716,21 +691,11 @@ bool GrClipMaskManager::createStencilClipMask(int32_t elementsGenID,
};
SkMatrix matrix;
matrix.setTranslate(translate);
- GrDrawTarget::AutoGeometryAndStatePush agasp(fClipTarget, GrDrawTarget::kReset_ASRInit,
- &matrix);
- drawState = fClipTarget->drawState();
-
- drawState->setRenderTarget(rt);
// We set the current clip to the bounds so that our recursive draws are scissored to them.
SkIRect stencilSpaceIBounds(clipSpaceIBounds);
stencilSpaceIBounds.offset(clipSpaceToStencilOffset);
GrDrawTarget::AutoClipRestore acr(fClipTarget, stencilSpaceIBounds);
- drawState->enableState(GrDrawState::kClip_StateBit);
-
-#if !VISUALIZE_COMPLEX_CLIP
- drawState->enableState(GrDrawState::kNoColorWrites_StateBit);
-#endif
int clipBit = stencilBuffer->bits();
SkASSERT((clipBit <= 16) && "Ganesh only handles 16b or smaller stencil buffers");
@@ -744,20 +709,26 @@ bool GrClipMaskManager::createStencilClipMask(int32_t elementsGenID,
// with the existing clip.
for (GrReducedClip::ElementList::Iter iter(elements.headIter()); iter.get(); iter.next()) {
const Element* element = iter.get();
- bool fillInverted = false;
- // enabled at bottom of loop
- fClipMode = kIgnoreClip_StencilClipMode;
+
+ GrDrawState drawState(matrix);
+ drawState.setRenderTarget(rt);
+ drawState.enableState(GrDrawState::kClip_StateBit);
+ drawState.enableState(GrDrawState::kNoColorWrites_StateBit);
+
// if the target is MSAA then we want MSAA enabled when the clip is soft
if (rt->isMultisampled()) {
- drawState->setState(GrDrawState::kHWAntialias_StateBit, element->isAA());
+ drawState.setState(GrDrawState::kHWAntialias_StateBit, element->isAA());
}
+ bool fillInverted = false;
+ // enabled at bottom of loop
+ fClipMode = kIgnoreClip_StencilClipMode;
+
// This will be used to determine whether the clip shape can be rendered into the
// stencil with arbitrary stencil settings.
GrPathRenderer::StencilSupport stencilSupport;
SkStrokeRec stroke(SkStrokeRec::kFill_InitStyle);
-
SkRegion::Op op = element->getOp();
GrPathRenderer* pr = NULL;
@@ -771,9 +742,10 @@ bool GrClipMaskManager::createStencilClipMask(int32_t elementsGenID,
if (fillInverted) {
clipPath.toggleInverseFillType();
}
- pr = this->getContext()->getPathRenderer(clipPath,
+ pr = this->getContext()->getPathRenderer(fClipTarget,
+ &drawState,
+ clipPath,
stroke,
- fClipTarget,
false,
GrPathRendererChain::kStencilOnly_DrawType,
&stencilSupport);
@@ -807,17 +779,17 @@ bool GrClipMaskManager::createStencilClipMask(int32_t elementsGenID,
0xffff,
0x0000,
0xffff);
- SET_RANDOM_COLOR
if (Element::kRect_Type == element->getType()) {
- *drawState->stencil() = gDrawToStencil;
- fClipTarget->drawSimpleRect(element->getRect());
+ *drawState.stencil() = gDrawToStencil;
+ fClipTarget->drawSimpleRect(&drawState, element->getRect());
} else {
if (!clipPath.isEmpty()) {
+ GrDrawTarget::AutoGeometryPush agp(fClipTarget);
if (canRenderDirectToStencil) {
- *drawState->stencil() = gDrawToStencil;
- pr->drawPath(clipPath, stroke, fClipTarget, false);
+ *drawState.stencil() = gDrawToStencil;
+ pr->drawPath(fClipTarget, &drawState, clipPath, stroke, false);
} else {
- pr->stencilPath(clipPath, stroke, fClipTarget);
+ pr->stencilPath(fClipTarget, &drawState, clipPath, stroke);
}
}
}
@@ -827,20 +799,20 @@ bool GrClipMaskManager::createStencilClipMask(int32_t elementsGenID,
// element directly or a bounding rect of the entire clip.
fClipMode = kModifyClip_StencilClipMode;
for (int p = 0; p < passes; ++p) {
- *drawState->stencil() = stencilSettings[p];
+ GrDrawState drawStateCopy(drawState);
+ *drawStateCopy.stencil() = stencilSettings[p];
+
if (canDrawDirectToClip) {
if (Element::kRect_Type == element->getType()) {
- SET_RANDOM_COLOR
- fClipTarget->drawSimpleRect(element->getRect());
+ fClipTarget->drawSimpleRect(&drawStateCopy, element->getRect());
} else {
- SET_RANDOM_COLOR
- pr->drawPath(clipPath, stroke, fClipTarget, false);
+ GrDrawTarget::AutoGeometryPush agp(fClipTarget);
+ pr->drawPath(fClipTarget, &drawStateCopy, clipPath, stroke, false);
}
} else {
- SET_RANDOM_COLOR
// The view matrix is setup to do clip space -> stencil space translation, so
// draw rect in clip space.
- fClipTarget->drawSimpleRect(SkRect::Make(clipSpaceIBounds));
+ fClipTarget->drawSimpleRect(&drawStateCopy, SkRect::Make(clipSpaceIBounds));
}
}
}
@@ -852,7 +824,6 @@ bool GrClipMaskManager::createStencilClipMask(int32_t elementsGenID,
return true;
}
-
// mapping of clip-respecting stencil funcs to normal stencil funcs
// mapping depends on whether stencil-clipping is in effect.
static const GrStencilFunc
@@ -905,33 +876,32 @@ const GrStencilSettings& basic_apply_stencil_clip_settings() {
}
}
-void GrClipMaskManager::setDrawStateStencil(GrDrawState::AutoRestoreStencil* ars) {
+void GrClipMaskManager::setDrawStateStencil(GrDrawState* drawState,
+ GrDrawState::AutoRestoreStencil* ars) {
// We make two copies of the StencilSettings here (except in the early
// exit scenario. One copy from draw state to the stack var. Then another
// from the stack var to the gpu. We could make this class hold a ptr to
// GrGpu's fStencilSettings and eliminate the stack copy here.
- const GrDrawState& drawState = fClipTarget->getDrawState();
-
// use stencil for clipping if clipping is enabled and the clip
// has been written into the stencil.
-
GrStencilSettings settings;
+
// The GrGpu client may not be using the stencil buffer but we may need to
// enable it in order to respect a stencil clip.
- if (drawState.getStencil().isDisabled()) {
+ if (drawState->getStencil().isDisabled()) {
if (GrClipMaskManager::kRespectClip_StencilClipMode == fClipMode) {
settings = basic_apply_stencil_clip_settings();
} else {
return;
}
} else {
- settings = drawState.getStencil();
+ settings = drawState->getStencil();
}
// TODO: dynamically attach a stencil buffer
int stencilBits = 0;
- GrStencilBuffer* stencilBuffer = drawState.getRenderTarget()->getStencilBuffer();
+ GrStencilBuffer* stencilBuffer = drawState->getRenderTarget()->getStencilBuffer();
if (stencilBuffer) {
stencilBits = stencilBuffer->bits();
}
@@ -939,8 +909,8 @@ void GrClipMaskManager::setDrawStateStencil(GrDrawState::AutoRestoreStencil* ars
SkASSERT(fClipTarget->caps()->stencilWrapOpsSupport() || !settings.usesWrapOp());
SkASSERT(fClipTarget->caps()->twoSidedStencilSupport() || !settings.isTwoSided());
this->adjustStencilParams(&settings, fClipMode, stencilBits);
- ars->set(fClipTarget->drawState());
- fClipTarget->drawState()->setStencil(settings);
+ ars->set(drawState);
+ drawState->setStencil(settings);
}
void GrClipMaskManager::adjustStencilParams(GrStencilSettings* settings,
@@ -1045,14 +1015,12 @@ GrTexture* GrClipMaskManager::createSoftwareClipMask(int32_t elementsGenID,
SkMatrix matrix;
matrix.setTranslate(SkIntToScalar(-clipSpaceIBounds.fLeft),
SkIntToScalar(-clipSpaceIBounds.fTop));
- helper.init(maskSpaceIBounds, &matrix, false);
+ helper.init(maskSpaceIBounds, &matrix, false);
helper.clear(GrReducedClip::kAllIn_InitialState == initialState ? 0xFF : 0x00);
-
SkStrokeRec stroke(SkStrokeRec::kFill_InitStyle);
for (GrReducedClip::ElementList::Iter iter(elements.headIter()) ; iter.get(); iter.next()) {
-
const Element* element = iter.get();
SkRegion::Op op = element->getOp();
@@ -1066,12 +1034,10 @@ GrTexture* GrClipMaskManager::createSoftwareClipMask(int32_t elementsGenID,
// invert the entire scene
helper.draw(temp, SkRegion::kXOR_Op, false, 0xFF);
}
-
SkPath clipPath;
element->asPath(&clipPath);
clipPath.toggleInverseFillType();
helper.draw(clipPath, stroke, SkRegion::kReplace_Op, element->isAA(), 0x00);
-
continue;
}
@@ -1108,14 +1074,11 @@ void GrClipMaskManager::setClipTarget(GrClipTarget* clipTarget) {
fAACache.setContext(clipTarget->getContext());
}
-void GrClipMaskManager::adjustPathStencilParams(GrStencilSettings* settings) {
- const GrDrawState& drawState = fClipTarget->getDrawState();
-
+void GrClipMaskManager::adjustPathStencilParams(const GrStencilBuffer* stencilBuffer,
+ GrStencilSettings* settings) {
// TODO: dynamically attach a stencil buffer
- int stencilBits = 0;
- GrStencilBuffer* stencilBuffer = drawState.getRenderTarget()->getStencilBuffer();
if (stencilBuffer) {
- stencilBits = stencilBuffer->bits();
+ int stencilBits = stencilBuffer->bits();
this->adjustStencilParams(settings, fClipMode, stencilBits);
}
}
« no previous file with comments | « src/gpu/GrClipMaskManager.h ('k') | src/gpu/GrContext.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698