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

Unified Diff: src/gpu/GrClipMaskManager.cpp

Issue 1962243002: Separate user and raw stencil settings (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Created 4 years, 7 months 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/GrDrawContext.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 56c0ee641b6613d1946cf32ebfff91b2c8e381f7..c7b88caa244cef3abf9ae59abab5097f919af3a3 100644
--- a/src/gpu/GrClipMaskManager.cpp
+++ b/src/gpu/GrClipMaskManager.cpp
@@ -62,7 +62,7 @@ static void draw_non_aa_rect(GrDrawTarget* drawTarget,
// optionally, set 'prOut' to NULL. If not, return false (and, optionally, set
// 'prOut' to the non-SW path renderer that will do the job).
bool GrClipMaskManager::PathNeedsSWRenderer(GrContext* context,
- bool isStencilDisabled,
+ bool hasUserStencilSettings,
const GrRenderTarget* rt,
const SkMatrix& viewMatrix,
const Element* element,
@@ -104,7 +104,7 @@ bool GrClipMaskManager::PathNeedsSWRenderer(GrContext* context,
canDrawArgs.fPath = &path;
canDrawArgs.fStyle = &GrStyle::SimpleFill();
canDrawArgs.fAntiAlias = element->isAA();
- canDrawArgs.fIsStencilDisabled = isStencilDisabled;
+ canDrawArgs.fHasUserStencilSettings = hasUserStencilSettings;
canDrawArgs.fIsStencilBufferMSAA = rt->isStencilBufferMultisampled();
// the 'false' parameter disallows use of the SW path renderer
@@ -124,10 +124,10 @@ GrPathRenderer* GrClipMaskManager::GetPathRenderer(GrContext* context,
const SkMatrix& viewMatrix,
const SkClipStack::Element* element) {
GrPathRenderer* pr;
- static const bool kNeedsStencil = true;
- static const bool kStencilIsDisabled = true;
+ constexpr bool kNeedsStencil = true;
+ constexpr bool kHasUserStencilSettings = false;
PathNeedsSWRenderer(context,
- kStencilIsDisabled,
+ kHasUserStencilSettings,
texture->asRenderTarget(),
viewMatrix,
element,
@@ -179,7 +179,7 @@ bool GrClipMaskManager::UseSWOnlyPath(GrContext* context,
bool needsStencil = invert ||
SkRegion::kIntersect_Op == op || SkRegion::kReverseDifference_Op == op;
- if (PathNeedsSWRenderer(context, pipelineBuilder.getStencil().isDisabled(),
+ if (PathNeedsSWRenderer(context, pipelineBuilder.hasUserStencilSettings(),
rt, translate, element, nullptr, needsStencil)) {
return true;
}
@@ -317,13 +317,11 @@ static void add_rect_to_clip(const GrClip& clip, const SkRect& devRect, GrClip*
}
bool GrClipMaskManager::setupScissorClip(const GrPipelineBuilder& pipelineBuilder,
- GrPipelineBuilder::AutoRestoreStencil* ars,
const SkIRect& clipScissor,
const SkRect* devBounds,
GrAppliedClip* out) {
- if (kRespectClip_StencilClipMode == fClipMode) {
- fClipMode = kIgnoreClip_StencilClipMode;
- }
+ SkASSERT(kModifyClip_StencilClipMode != fClipMode); // TODO: Remove fClipMode.
+ fClipMode = kIgnoreClip_StencilClipMode;
GrRenderTarget* rt = pipelineBuilder.getRenderTarget();
@@ -340,13 +338,11 @@ bool GrClipMaskManager::setupScissorClip(const GrPipelineBuilder& pipelineBuilde
if (scissor->contains(clipSpaceRTIBounds)) {
// This counts as wide open
- this->setPipelineBuilderStencil(pipelineBuilder, ars);
return true;
}
if (clipSpaceRTIBounds.intersect(*scissor)) {
out->fScissorState.set(clipSpaceRTIBounds);
- this->setPipelineBuilderStencil(pipelineBuilder, ars);
return true;
}
return false;
@@ -356,7 +352,6 @@ bool GrClipMaskManager::setupScissorClip(const GrPipelineBuilder& pipelineBuilde
// sort out what kind of clip mask needs to be created: alpha, stencil,
// scissor, or entirely software
bool GrClipMaskManager::setupClipping(const GrPipelineBuilder& pipelineBuilder,
- GrPipelineBuilder::AutoRestoreStencil* ars,
const SkRect* devBounds,
GrAppliedClip* out) {
if (kRespectClip_StencilClipMode == fClipMode) {
@@ -382,7 +377,6 @@ bool GrClipMaskManager::setupClipping(const GrPipelineBuilder& pipelineBuilder,
const GrClip& clip = doDevBoundsClip ? devBoundsClip : pipelineBuilder.clip();
if (clip.isWideOpen(clipSpaceRTIBounds)) {
- this->setPipelineBuilderStencil(pipelineBuilder, ars);
return true;
}
@@ -396,7 +390,7 @@ bool GrClipMaskManager::setupClipping(const GrPipelineBuilder& pipelineBuilder,
SkIRect scissor = clip.irect();
if (scissor.intersect(clipSpaceRTIBounds)) {
out->fScissorState.set(scissor);
- this->setPipelineBuilderStencil(pipelineBuilder, ars);
+ out->fHasStencilClip = kIgnoreClip_StencilClipMode != fClipMode;
return true;
}
return false;
@@ -424,7 +418,6 @@ bool GrClipMaskManager::setupClipping(const GrPipelineBuilder& pipelineBuilder,
if (elements.isEmpty()) {
if (GrReducedClip::kAllIn_InitialState == initialState) {
if (clipSpaceIBounds == clipSpaceRTIBounds) {
- this->setPipelineBuilderStencil(pipelineBuilder, ars);
return true;
}
} else {
@@ -434,6 +427,8 @@ bool GrClipMaskManager::setupClipping(const GrPipelineBuilder& pipelineBuilder,
} break;
}
+ SkASSERT(kIgnoreClip_StencilClipMode == fClipMode); // TODO: Remove fClipMode.
+
// An element count of 4 was chosen because of the common pattern in Blink of:
// isect RR
// diff RR
@@ -453,7 +448,7 @@ bool GrClipMaskManager::setupClipping(const GrPipelineBuilder& pipelineBuilder,
// color buffer anyway, so we may as well use coverage AA if nothing else in the pipe
// is multisampled.
disallowAnalyticAA = pipelineBuilder.isHWAntialias() ||
- !pipelineBuilder.getStencil().isDisabled();
+ pipelineBuilder.hasUserStencilSettings();
}
const GrFragmentProcessor* clipFP = nullptr;
if (elements.isEmpty() ||
@@ -466,7 +461,6 @@ bool GrClipMaskManager::setupClipping(const GrPipelineBuilder& pipelineBuilder,
!SkRect::Make(scissorSpaceIBounds).contains(*devBounds)) {
out->fScissorState.set(scissorSpaceIBounds);
}
- this->setPipelineBuilderStencil(pipelineBuilder, ars);
out->fClipCoverageFP.reset(clipFP);
return true;
}
@@ -508,7 +502,6 @@ bool GrClipMaskManager::setupClipping(const GrPipelineBuilder& pipelineBuilder,
SkIRect rtSpaceMaskBounds = clipSpaceIBounds;
rtSpaceMaskBounds.offset(-clip.origin());
out->fClipCoverageFP.reset(create_fp_for_mask(result, rtSpaceMaskBounds));
- this->setPipelineBuilderStencil(pipelineBuilder, ars);
return true;
}
// if alpha clip mask creation fails fall through to the non-AA code paths
@@ -529,13 +522,14 @@ bool GrClipMaskManager::setupClipping(const GrPipelineBuilder& pipelineBuilder,
SkIRect scissorSpaceIBounds(clipSpaceIBounds);
scissorSpaceIBounds.offset(clipSpaceToStencilSpaceOffset);
out->fScissorState.set(scissorSpaceIBounds);
- this->setPipelineBuilderStencil(pipelineBuilder, ars);
+ SkASSERT(kRespectClip_StencilClipMode == fClipMode); // TODO: Remove fClipMode.
+ out->fHasStencilClip = true;
return true;
}
static bool stencil_element(GrDrawContext* dc,
const SkIRect* scissorRect,
- const GrStencilSettings& ss,
+ const GrUserStencilSettings* ss,
const SkMatrix& viewMatrix,
const SkClipStack::Element* element) {
@@ -681,28 +675,32 @@ GrTexture* GrClipMaskManager::CreateAlphaClipMask(GrContext* context,
// draw directly into the result with the stencil set to make the pixels affected
// by the clip shape be non-zero.
- static constexpr GrStencilSettings kStencilInElement(
- kReplace_StencilOp,
- kReplace_StencilOp,
- kAlways_StencilFunc,
- 0xffff,
- 0xffff,
- 0xffff);
- if (!stencil_element(dc.get(), &maskSpaceIBounds, kStencilInElement,
+ static constexpr GrUserStencilSettings kStencilInElement(
+ GrUserStencilSettings::StaticInit<
+ 0xffff,
+ GrUserStencilTest::kAlways,
+ 0xffff,
+ GrUserStencilOp::kReplace,
+ GrUserStencilOp::kReplace,
+ 0xffff>()
+ );
+ if (!stencil_element(dc.get(), &maskSpaceIBounds, &kStencilInElement,
translate, element)) {
texture->resourcePriv().removeUniqueKey();
return nullptr;
}
// Draw to the exterior pixels (those with a zero stencil value).
- static constexpr GrStencilSettings kDrawOutsideElement(
- kZero_StencilOp,
- kZero_StencilOp,
- kEqual_StencilFunc,
- 0xffff,
- 0x0000,
- 0xffff);
- if (!dc->drawContextPriv().drawAndStencilRect(&maskSpaceIBounds, kDrawOutsideElement,
+ static constexpr GrUserStencilSettings kDrawOutsideElement(
+ GrUserStencilSettings::StaticInit<
+ 0x0000,
+ GrUserStencilTest::kEqual,
+ 0xffff,
+ GrUserStencilOp::kZero,
+ GrUserStencilOp::kZero,
+ 0xffff>()
+ );
+ if (!dc->drawContextPriv().drawAndStencilRect(&maskSpaceIBounds, &kDrawOutsideElement,
op, !invert, false,
translate,
SkRect::Make(clipSpaceIBounds))) {
@@ -753,10 +751,6 @@ bool GrClipMaskManager::createStencilClipMask(GrRenderTarget* rt,
stencilSpaceIBounds.offset(clipSpaceToStencilOffset);
GrClip clip(stencilSpaceIBounds);
- int clipBit = stencilAttachment->bits();
- SkASSERT((clipBit <= 16) && "Ganesh only handles 16b or smaller stencil buffers");
- clipBit = (1 << (clipBit-1));
-
fDrawTarget->cmmAccess().clearStencilClip(stencilSpaceIBounds,
GrReducedClip::kAllIn_InitialState == initialState, rt);
@@ -798,7 +792,7 @@ bool GrClipMaskManager::createStencilClipMask(GrRenderTarget* rt,
clipPath.toggleInverseFillType();
}
- SkASSERT(pipelineBuilder.getStencil().isDisabled());
+ SkASSERT(!pipelineBuilder.hasUserStencilSettings());
GrPathRenderer::CanDrawPathArgs canDrawArgs;
canDrawArgs.fShaderCaps = this->getContext()->caps()->shaderCaps();
@@ -806,7 +800,7 @@ bool GrClipMaskManager::createStencilClipMask(GrRenderTarget* rt,
canDrawArgs.fPath = &clipPath;
canDrawArgs.fStyle = &GrStyle::SimpleFill();
canDrawArgs.fAntiAlias = false;
- canDrawArgs.fIsStencilDisabled = pipelineBuilder.getStencil().isDisabled();
+ canDrawArgs.fHasUserStencilSettings = pipelineBuilder.hasUserStencilSettings();
canDrawArgs.fIsStencilBufferMSAA = rt->isStencilBufferMultisampled();
pr = this->getContext()->drawingManager()->getPathRenderer(canDrawArgs, false,
@@ -817,40 +811,36 @@ bool GrClipMaskManager::createStencilClipMask(GrRenderTarget* rt,
}
}
- int passes;
- GrStencilSettings stencilSettings[GrStencilSettings::kMaxStencilClipPasses];
-
bool canRenderDirectToStencil =
GrPathRenderer::kNoRestriction_StencilSupport == stencilSupport;
- bool canDrawDirectToClip; // Given the renderer, the element,
- // fill rule, and set operation can
- // we render the element directly to
- // stencil bit used for clipping.
- canDrawDirectToClip = GrStencilSettings::GetClipPasses(op,
- canRenderDirectToStencil,
- clipBit,
- fillInverted,
- &passes,
- stencilSettings);
+ bool drawDirectToClip; // Given the renderer, the element,
+ // fill rule, and set operation should
+ // we render the element directly to
+ // stencil bit used for clipping.
+ GrUserStencilSettings const* const* stencilPasses =
+ GrStencilSettings::GetClipPasses(op, canRenderDirectToStencil, fillInverted,
+ &drawDirectToClip);
// draw the element to the client stencil bits if necessary
- if (!canDrawDirectToClip) {
- static constexpr GrStencilSettings kDrawToStencil(
- kIncClamp_StencilOp,
- kIncClamp_StencilOp,
- kAlways_StencilFunc,
- 0xffff,
- 0x0000,
- 0xffff);
+ if (!drawDirectToClip) {
+ static constexpr GrUserStencilSettings kDrawToStencil(
+ GrUserStencilSettings::StaticInit<
+ 0x0000,
+ GrUserStencilTest::kAlways,
+ 0xffff,
+ GrUserStencilOp::kIncMaybeClamp,
+ GrUserStencilOp::kIncMaybeClamp,
+ 0xffff>()
+ );
if (Element::kRect_Type == element->getType()) {
- *pipelineBuilder.stencil() = kDrawToStencil;
+ pipelineBuilder.setUserStencil(&kDrawToStencil);
draw_non_aa_rect(fDrawTarget, pipelineBuilder, GrColor_WHITE, viewMatrix,
element->getRect());
} else {
if (!clipPath.isEmpty()) {
if (canRenderDirectToStencil) {
- *pipelineBuilder.stencil() = kDrawToStencil;
+ pipelineBuilder.setUserStencil(&kDrawToStencil);
GrPathRenderer::DrawPathArgs args;
args.fTarget = fDrawTarget;
@@ -879,10 +869,10 @@ bool GrClipMaskManager::createStencilClipMask(GrRenderTarget* rt,
// now we modify the clip bit by rendering either the clip
// element directly or a bounding rect of the entire clip.
fClipMode = kModifyClip_StencilClipMode;
- for (int p = 0; p < passes; ++p) {
- *pipelineBuilder.stencil() = stencilSettings[p];
+ for (GrUserStencilSettings const* const* pass = stencilPasses; *pass; ++pass) {
+ pipelineBuilder.setUserStencil(*pass);
- if (canDrawDirectToClip) {
+ if (drawDirectToClip) {
if (Element::kRect_Type == element->getType()) {
draw_non_aa_rect(fDrawTarget, pipelineBuilder, GrColor_WHITE, viewMatrix,
element->getRect());
@@ -912,165 +902,6 @@ bool GrClipMaskManager::createStencilClipMask(GrRenderTarget* rt,
return true;
}
-// mapping of clip-respecting stencil funcs to normal stencil funcs
-// mapping depends on whether stencil-clipping is in effect.
-static const GrStencilFunc
- gSpecialToBasicStencilFunc[2][kClipStencilFuncCnt] = {
- {// Stencil-Clipping is DISABLED, we are effectively always inside the clip
- // In the Clip Funcs
- kAlways_StencilFunc, // kAlwaysIfInClip_StencilFunc
- kEqual_StencilFunc, // kEqualIfInClip_StencilFunc
- kLess_StencilFunc, // kLessIfInClip_StencilFunc
- kLEqual_StencilFunc, // kLEqualIfInClip_StencilFunc
- // Special in the clip func that forces user's ref to be 0.
- kNotEqual_StencilFunc, // kNonZeroIfInClip_StencilFunc
- // make ref 0 and do normal nequal.
- },
- {// Stencil-Clipping is ENABLED
- // In the Clip Funcs
- kEqual_StencilFunc, // kAlwaysIfInClip_StencilFunc
- // eq stencil clip bit, mask
- // out user bits.
-
- kEqual_StencilFunc, // kEqualIfInClip_StencilFunc
- // add stencil bit to mask and ref
-
- kLess_StencilFunc, // kLessIfInClip_StencilFunc
- kLEqual_StencilFunc, // kLEqualIfInClip_StencilFunc
- // for both of these we can add
- // the clip bit to the mask and
- // ref and compare as normal
- // Special in the clip func that forces user's ref to be 0.
- kLess_StencilFunc, // kNonZeroIfInClip_StencilFunc
- // make ref have only the clip bit set
- // and make comparison be less
- // 10..0 < 1..user_bits..
- }
-};
-
-void GrClipMaskManager::setPipelineBuilderStencil(const GrPipelineBuilder& pipelineBuilder,
- GrPipelineBuilder::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.
-
- // 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 (pipelineBuilder.getStencil().isDisabled()) {
- if (GrClipMaskManager::kRespectClip_StencilClipMode == fClipMode) {
- static constexpr GrStencilSettings kBasicApplyClipSettings(
- kKeep_StencilOp,
- kKeep_StencilOp,
- kAlwaysIfInClip_StencilFunc,
- 0x0000,
- 0x0000,
- 0x0000);
- settings = kBasicApplyClipSettings;
- } else {
- return;
- }
- } else {
- settings = pipelineBuilder.getStencil();
- }
-
- int stencilBits = 0;
- GrRenderTarget* rt = pipelineBuilder.getRenderTarget();
- GrStencilAttachment* stencilAttachment = this->resourceProvider()->attachStencilAttachment(rt);
- if (stencilAttachment) {
- stencilBits = stencilAttachment->bits();
- }
-
- SkASSERT(this->caps()->stencilWrapOpsSupport() || !settings.usesWrapOp());
- SkASSERT(this->caps()->twoSidedStencilSupport() || !settings.isTwoSided());
- this->adjustStencilParams(&settings, fClipMode, stencilBits);
- ars->set(&pipelineBuilder);
- ars->setStencil(settings);
-}
-
-void GrClipMaskManager::adjustStencilParams(GrStencilSettings* settings,
- StencilClipMode mode,
- int stencilBitCnt) {
- SkASSERT(stencilBitCnt > 0);
-
- if (kModifyClip_StencilClipMode == mode) {
- // We assume that this clip manager itself is drawing to the GrGpu and
- // has already setup the correct values.
- return;
- }
-
- unsigned int clipBit = (1 << (stencilBitCnt - 1));
- unsigned int userBits = clipBit - 1;
-
- GrStencilSettings::Face face = GrStencilSettings::kFront_Face;
- bool twoSided = this->caps()->twoSidedStencilSupport();
-
- bool finished = false;
- while (!finished) {
- GrStencilFunc func = settings->func(face);
- uint16_t writeMask = settings->writeMask(face);
- uint16_t funcMask = settings->funcMask(face);
- uint16_t funcRef = settings->funcRef(face);
-
- SkASSERT((unsigned) func < kStencilFuncCnt);
-
- writeMask &= userBits;
-
- if (func >= kBasicStencilFuncCnt) {
- int respectClip = kRespectClip_StencilClipMode == mode;
- if (respectClip) {
- switch (func) {
- case kAlwaysIfInClip_StencilFunc:
- funcMask = clipBit;
- funcRef = clipBit;
- break;
- case kEqualIfInClip_StencilFunc:
- case kLessIfInClip_StencilFunc:
- case kLEqualIfInClip_StencilFunc:
- funcMask = (funcMask & userBits) | clipBit;
- funcRef = (funcRef & userBits) | clipBit;
- break;
- case kNonZeroIfInClip_StencilFunc:
- funcMask = (funcMask & userBits) | clipBit;
- funcRef = clipBit;
- break;
- default:
- SkFAIL("Unknown stencil func");
- }
- } else {
- funcMask &= userBits;
- funcRef &= userBits;
- }
- const GrStencilFunc* table =
- gSpecialToBasicStencilFunc[respectClip];
- func = table[func - kBasicStencilFuncCnt];
- SkASSERT(func >= 0 && func < kBasicStencilFuncCnt);
- } else {
- funcMask &= userBits;
- funcRef &= userBits;
- }
-
- settings->setFunc(face, func);
- settings->setWriteMask(face, writeMask);
- settings->setFuncMask(face, funcMask);
- settings->setFuncRef(face, funcRef);
-
- if (GrStencilSettings::kFront_Face == face) {
- face = GrStencilSettings::kBack_Face;
- finished = !twoSided;
- } else {
- finished = true;
- }
- }
- if (!twoSided) {
- settings->copyFrontSettingsToBack();
- }
-}
-
////////////////////////////////////////////////////////////////////////////////
GrTexture* GrClipMaskManager::CreateSoftwareClipMask(GrContext* context,
int32_t elementsGenID,
@@ -1148,13 +979,3 @@ GrTexture* GrClipMaskManager::CreateSoftwareClipMask(GrContext* context,
return result;
}
-
-////////////////////////////////////////////////////////////////////////////////
-
-void GrClipMaskManager::adjustPathStencilParams(const GrStencilAttachment* stencilAttachment,
- GrStencilSettings* settings) {
- if (stencilAttachment) {
- int stencilBits = stencilAttachment->bits();
- this->adjustStencilParams(settings, fClipMode, stencilBits);
- }
-}
« no previous file with comments | « src/gpu/GrClipMaskManager.h ('k') | src/gpu/GrDrawContext.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698