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

Unified Diff: src/gpu/GrClipMaskManager.cpp

Issue 1969693003: Revert of 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 c7b88caa244cef3abf9ae59abab5097f919af3a3..56c0ee641b6613d1946cf32ebfff91b2c8e381f7 100644
--- a/src/gpu/GrClipMaskManager.cpp
+++ b/src/gpu/GrClipMaskManager.cpp
@@ -62,7 +62,7 @@
// 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 hasUserStencilSettings,
+ bool isStencilDisabled,
const GrRenderTarget* rt,
const SkMatrix& viewMatrix,
const Element* element,
@@ -104,7 +104,7 @@
canDrawArgs.fPath = &path;
canDrawArgs.fStyle = &GrStyle::SimpleFill();
canDrawArgs.fAntiAlias = element->isAA();
- canDrawArgs.fHasUserStencilSettings = hasUserStencilSettings;
+ canDrawArgs.fIsStencilDisabled = isStencilDisabled;
canDrawArgs.fIsStencilBufferMSAA = rt->isStencilBufferMultisampled();
// the 'false' parameter disallows use of the SW path renderer
@@ -124,10 +124,10 @@
const SkMatrix& viewMatrix,
const SkClipStack::Element* element) {
GrPathRenderer* pr;
- constexpr bool kNeedsStencil = true;
- constexpr bool kHasUserStencilSettings = false;
+ static const bool kNeedsStencil = true;
+ static const bool kStencilIsDisabled = true;
PathNeedsSWRenderer(context,
- kHasUserStencilSettings,
+ kStencilIsDisabled,
texture->asRenderTarget(),
viewMatrix,
element,
@@ -179,7 +179,7 @@
bool needsStencil = invert ||
SkRegion::kIntersect_Op == op || SkRegion::kReverseDifference_Op == op;
- if (PathNeedsSWRenderer(context, pipelineBuilder.hasUserStencilSettings(),
+ if (PathNeedsSWRenderer(context, pipelineBuilder.getStencil().isDisabled(),
rt, translate, element, nullptr, needsStencil)) {
return true;
}
@@ -317,11 +317,13 @@
}
bool GrClipMaskManager::setupScissorClip(const GrPipelineBuilder& pipelineBuilder,
+ GrPipelineBuilder::AutoRestoreStencil* ars,
const SkIRect& clipScissor,
const SkRect* devBounds,
GrAppliedClip* out) {
- SkASSERT(kModifyClip_StencilClipMode != fClipMode); // TODO: Remove fClipMode.
- fClipMode = kIgnoreClip_StencilClipMode;
+ if (kRespectClip_StencilClipMode == fClipMode) {
+ fClipMode = kIgnoreClip_StencilClipMode;
+ }
GrRenderTarget* rt = pipelineBuilder.getRenderTarget();
@@ -338,11 +340,13 @@
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;
@@ -352,6 +356,7 @@
// 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) {
@@ -377,6 +382,7 @@
const GrClip& clip = doDevBoundsClip ? devBoundsClip : pipelineBuilder.clip();
if (clip.isWideOpen(clipSpaceRTIBounds)) {
+ this->setPipelineBuilderStencil(pipelineBuilder, ars);
return true;
}
@@ -390,7 +396,7 @@
SkIRect scissor = clip.irect();
if (scissor.intersect(clipSpaceRTIBounds)) {
out->fScissorState.set(scissor);
- out->fHasStencilClip = kIgnoreClip_StencilClipMode != fClipMode;
+ this->setPipelineBuilderStencil(pipelineBuilder, ars);
return true;
}
return false;
@@ -418,6 +424,7 @@
if (elements.isEmpty()) {
if (GrReducedClip::kAllIn_InitialState == initialState) {
if (clipSpaceIBounds == clipSpaceRTIBounds) {
+ this->setPipelineBuilderStencil(pipelineBuilder, ars);
return true;
}
} else {
@@ -426,8 +433,6 @@
}
} 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
@@ -448,7 +453,7 @@
// color buffer anyway, so we may as well use coverage AA if nothing else in the pipe
// is multisampled.
disallowAnalyticAA = pipelineBuilder.isHWAntialias() ||
- pipelineBuilder.hasUserStencilSettings();
+ !pipelineBuilder.getStencil().isDisabled();
}
const GrFragmentProcessor* clipFP = nullptr;
if (elements.isEmpty() ||
@@ -461,6 +466,7 @@
!SkRect::Make(scissorSpaceIBounds).contains(*devBounds)) {
out->fScissorState.set(scissorSpaceIBounds);
}
+ this->setPipelineBuilderStencil(pipelineBuilder, ars);
out->fClipCoverageFP.reset(clipFP);
return true;
}
@@ -502,6 +508,7 @@
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
@@ -522,14 +529,13 @@
SkIRect scissorSpaceIBounds(clipSpaceIBounds);
scissorSpaceIBounds.offset(clipSpaceToStencilSpaceOffset);
out->fScissorState.set(scissorSpaceIBounds);
- SkASSERT(kRespectClip_StencilClipMode == fClipMode); // TODO: Remove fClipMode.
- out->fHasStencilClip = true;
+ this->setPipelineBuilderStencil(pipelineBuilder, ars);
return true;
}
static bool stencil_element(GrDrawContext* dc,
const SkIRect* scissorRect,
- const GrUserStencilSettings* ss,
+ const GrStencilSettings& ss,
const SkMatrix& viewMatrix,
const SkClipStack::Element* element) {
@@ -675,32 +681,28 @@
// draw directly into the result with the stencil set to make the pixels affected
// by the clip shape be non-zero.
- static constexpr GrUserStencilSettings kStencilInElement(
- GrUserStencilSettings::StaticInit<
- 0xffff,
- GrUserStencilTest::kAlways,
- 0xffff,
- GrUserStencilOp::kReplace,
- GrUserStencilOp::kReplace,
- 0xffff>()
- );
- if (!stencil_element(dc.get(), &maskSpaceIBounds, &kStencilInElement,
+ static constexpr GrStencilSettings kStencilInElement(
+ kReplace_StencilOp,
+ kReplace_StencilOp,
+ kAlways_StencilFunc,
+ 0xffff,
+ 0xffff,
+ 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 GrUserStencilSettings kDrawOutsideElement(
- GrUserStencilSettings::StaticInit<
- 0x0000,
- GrUserStencilTest::kEqual,
- 0xffff,
- GrUserStencilOp::kZero,
- GrUserStencilOp::kZero,
- 0xffff>()
- );
- if (!dc->drawContextPriv().drawAndStencilRect(&maskSpaceIBounds, &kDrawOutsideElement,
+ static constexpr GrStencilSettings kDrawOutsideElement(
+ kZero_StencilOp,
+ kZero_StencilOp,
+ kEqual_StencilFunc,
+ 0xffff,
+ 0x0000,
+ 0xffff);
+ if (!dc->drawContextPriv().drawAndStencilRect(&maskSpaceIBounds, kDrawOutsideElement,
op, !invert, false,
translate,
SkRect::Make(clipSpaceIBounds))) {
@@ -750,6 +752,10 @@
SkIRect stencilSpaceIBounds(clipSpaceIBounds);
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);
@@ -792,7 +798,7 @@
clipPath.toggleInverseFillType();
}
- SkASSERT(!pipelineBuilder.hasUserStencilSettings());
+ SkASSERT(pipelineBuilder.getStencil().isDisabled());
GrPathRenderer::CanDrawPathArgs canDrawArgs;
canDrawArgs.fShaderCaps = this->getContext()->caps()->shaderCaps();
@@ -800,7 +806,7 @@
canDrawArgs.fPath = &clipPath;
canDrawArgs.fStyle = &GrStyle::SimpleFill();
canDrawArgs.fAntiAlias = false;
- canDrawArgs.fHasUserStencilSettings = pipelineBuilder.hasUserStencilSettings();
+ canDrawArgs.fIsStencilDisabled = pipelineBuilder.getStencil().isDisabled();
canDrawArgs.fIsStencilBufferMSAA = rt->isStencilBufferMultisampled();
pr = this->getContext()->drawingManager()->getPathRenderer(canDrawArgs, false,
@@ -811,36 +817,40 @@
}
}
+ int passes;
+ GrStencilSettings stencilSettings[GrStencilSettings::kMaxStencilClipPasses];
+
bool canRenderDirectToStencil =
GrPathRenderer::kNoRestriction_StencilSupport == stencilSupport;
- 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);
+ 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);
// draw the element to the client stencil bits if necessary
- if (!drawDirectToClip) {
- static constexpr GrUserStencilSettings kDrawToStencil(
- GrUserStencilSettings::StaticInit<
- 0x0000,
- GrUserStencilTest::kAlways,
- 0xffff,
- GrUserStencilOp::kIncMaybeClamp,
- GrUserStencilOp::kIncMaybeClamp,
- 0xffff>()
- );
+ if (!canDrawDirectToClip) {
+ static constexpr GrStencilSettings kDrawToStencil(
+ kIncClamp_StencilOp,
+ kIncClamp_StencilOp,
+ kAlways_StencilFunc,
+ 0xffff,
+ 0x0000,
+ 0xffff);
if (Element::kRect_Type == element->getType()) {
- pipelineBuilder.setUserStencil(&kDrawToStencil);
+ *pipelineBuilder.stencil() = kDrawToStencil;
draw_non_aa_rect(fDrawTarget, pipelineBuilder, GrColor_WHITE, viewMatrix,
element->getRect());
} else {
if (!clipPath.isEmpty()) {
if (canRenderDirectToStencil) {
- pipelineBuilder.setUserStencil(&kDrawToStencil);
+ *pipelineBuilder.stencil() = kDrawToStencil;
GrPathRenderer::DrawPathArgs args;
args.fTarget = fDrawTarget;
@@ -869,10 +879,10 @@
// 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 (GrUserStencilSettings const* const* pass = stencilPasses; *pass; ++pass) {
- pipelineBuilder.setUserStencil(*pass);
-
- if (drawDirectToClip) {
+ for (int p = 0; p < passes; ++p) {
+ *pipelineBuilder.stencil() = stencilSettings[p];
+
+ if (canDrawDirectToClip) {
if (Element::kRect_Type == element->getType()) {
draw_non_aa_rect(fDrawTarget, pipelineBuilder, GrColor_WHITE, viewMatrix,
element->getRect());
@@ -902,6 +912,165 @@
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,
@@ -979,3 +1148,13 @@
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