aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorGravatar bsalomon@google.com <bsalomon@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2012-06-05 20:24:20 +0000
committerGravatar bsalomon@google.com <bsalomon@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2012-06-05 20:24:20 +0000
commit411dad0630913fc07f2412b4be17acfbfd914fbc (patch)
tree36d28ba722c1c33cd2ca60f341ef60ef1d5e5a03 /src
parent57288857cd7992eaa44753c7b9f987e318a0e8c3 (diff)
Move stencil param adjustment to GrClipMaskManager, attempt to make GrGpuGL::flushStencil readable
Review URL: http://codereview.appspot.com/6295046/ git-svn-id: http://skia.googlecode.com/svn/trunk@4173 2bbb7eff-a529-9590-31e7-b0007b416f81
Diffstat (limited to 'src')
-rw-r--r--src/gpu/GrClipMaskManager.cpp95
-rw-r--r--src/gpu/GrClipMaskManager.h41
-rw-r--r--src/gpu/GrGpu.cpp81
-rw-r--r--src/gpu/gl/GrGpuGL.cpp275
-rw-r--r--src/gpu/gl/GrGpuGL.h18
5 files changed, 271 insertions, 239 deletions
diff --git a/src/gpu/GrClipMaskManager.cpp b/src/gpu/GrClipMaskManager.cpp
index 6e84724e8f..e31b5f3466 100644
--- a/src/gpu/GrClipMaskManager.cpp
+++ b/src/gpu/GrClipMaskManager.cpp
@@ -862,6 +862,100 @@ bool GrClipMaskManager::createStencilClipMask(GrGpu* gpu,
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][kClipStencilFuncCount] = {
+ {// 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..
+ }
+};
+
+GrStencilFunc GrClipMaskManager::adjustStencilParams(GrStencilFunc func,
+ StencilClipMode mode,
+ unsigned int stencilBitCnt,
+ unsigned int* ref,
+ unsigned int* mask,
+ unsigned int* writeMask) {
+ GrAssert(stencilBitCnt > 0);
+ GrAssert((unsigned) func < kStencilFuncCount);
+
+ if (kModifyClip_StencilClipMode == mode) {
+ // We assume that this class is the client/draw-caller of the GrGpu and
+ // has already setup the correct values
+ return func;
+ }
+ unsigned int clipBit = (1 << (stencilBitCnt - 1));
+ unsigned int userBits = clipBit - 1;
+
+ *writeMask &= userBits;
+
+ if (func >= kBasicStencilFuncCount) {
+ int respectClip = kRespectClip_StencilClipMode == mode;
+ if (respectClip) {
+ // The GrGpu class should have checked this
+ GrAssert(this->isClipInStencil());
+ switch (func) {
+ case kAlwaysIfInClip_StencilFunc:
+ *mask = clipBit;
+ *ref = clipBit;
+ break;
+ case kEqualIfInClip_StencilFunc:
+ case kLessIfInClip_StencilFunc:
+ case kLEqualIfInClip_StencilFunc:
+ *mask = (*mask & userBits) | clipBit;
+ *ref = (*ref & userBits) | clipBit;
+ break;
+ case kNonZeroIfInClip_StencilFunc:
+ *mask = (*mask & userBits) | clipBit;
+ *ref = clipBit;
+ break;
+ default:
+ GrCrash("Unknown stencil func");
+ }
+ } else {
+ *mask &= userBits;
+ *ref &= userBits;
+ }
+ const GrStencilFunc* table = gSpecialToBasicStencilFunc[respectClip];
+ func = table[func - kBasicStencilFuncCount];
+ GrAssert(func >= 0 && func < kBasicStencilFuncCount);
+ } else {
+ *mask &= userBits;
+ *ref &= userBits;
+ }
+ return func;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
namespace {
GrPathFill invert_fill(GrPathFill fill) {
@@ -883,7 +977,6 @@ GrPathFill invert_fill(GrPathFill fill) {
}
-////////////////////////////////////////////////////////////////////////////////
bool GrClipMaskManager::createSoftwareClipMask(GrGpu* gpu,
const GrClip& clipIn,
GrTexture** result,
diff --git a/src/gpu/GrClipMaskManager.h b/src/gpu/GrClipMaskManager.h
index cc80cdb503..2f4d8c7aa7 100644
--- a/src/gpu/GrClipMaskManager.h
+++ b/src/gpu/GrClipMaskManager.h
@@ -9,14 +9,16 @@
#ifndef GrClipMaskManager_DEFINED
#define GrClipMaskManager_DEFINED
-#include "GrRect.h"
-#include "SkPath.h"
-#include "GrNoncopyable.h"
#include "GrClip.h"
-#include "SkRefCnt.h"
+#include "GrContext.h"
+#include "GrNoncopyable.h"
+#include "GrRect.h"
+#include "GrStencil.h"
#include "GrTexture.h"
+
#include "SkDeque.h"
-#include "GrContext.h"
+#include "SkPath.h"
+#include "SkRefCnt.h"
class GrGpu;
class GrPathRenderer;
@@ -319,7 +321,34 @@ public:
return fAACache.getContext();
}
-protected:
+ /**
+ * Informs the helper function adjustStencilParams() about how the stencil
+ * buffer clip is being used.
+ */
+ enum StencilClipMode {
+ // Draw to the clip bit of the stencil buffer
+ kModifyClip_StencilClipMode,
+ // Clip against the existing representation of the clip in the high bit
+ // of the stencil buffer.
+ kRespectClip_StencilClipMode,
+ // Neither writing to nor clipping against the clip bit.
+ kIgnoreClip_StencilClipMode,
+ };
+
+ /**
+ * The stencil func, mask, and reference value are specified by GrGpu's
+ * caller but the actual values passed to the API may have to be adjusted
+ * due to the stencil buffer simultaneously being used for clipping. This
+ * function should be called even when clipping is disabled in order to
+ * prevent the clip from being accidentally overwritten.
+ */
+ GrStencilFunc adjustStencilParams(GrStencilFunc,
+ StencilClipMode mode,
+ unsigned int stencilBitCnt,
+ unsigned int* ref,
+ unsigned int* mask,
+ unsigned int* writeMask);
+
private:
bool fClipMaskInStencil; // is the clip mask in the stencil buffer?
bool fClipMaskInAlpha; // is the clip mask in an alpha texture?
diff --git a/src/gpu/GrGpu.cpp b/src/gpu/GrGpu.cpp
index 4839e4f045..a873fe7ef5 100644
--- a/src/gpu/GrGpu.cpp
+++ b/src/gpu/GrGpu.cpp
@@ -357,87 +357,6 @@ const GrStencilSettings* GrGpu::GetClipStencilSettings(void) {
return GR_CONST_STENCIL_SETTINGS_PTR_FROM_STRUCT_PTR(&sClipStencilSettings);
}
-// mapping of clip-respecting stencil funcs to normal stencil funcs
-// mapping depends on whether stencil-clipping is in effect.
-static const GrStencilFunc gGrClipToNormalStencilFunc[2][kClipStencilFuncCount] = {
- {// Stencil-Clipping is DISABLED, 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..
- }
-};
-
-GrStencilFunc GrGpu::ConvertStencilFunc(bool stencilInClip, GrStencilFunc func) {
- GrAssert(func >= 0);
- if (func >= kBasicStencilFuncCount) {
- GrAssert(func < kStencilFuncCount);
- func = gGrClipToNormalStencilFunc[stencilInClip ? 1 : 0][func - kBasicStencilFuncCount];
- GrAssert(func >= 0 && func < kBasicStencilFuncCount);
- }
- return func;
-}
-
-void GrGpu::ConvertStencilFuncAndMask(GrStencilFunc func,
- bool clipInStencil,
- unsigned int clipBit,
- unsigned int userBits,
- unsigned int* ref,
- unsigned int* mask) {
- if (func < kBasicStencilFuncCount) {
- *mask &= userBits;
- *ref &= userBits;
- } else {
- if (clipInStencil) {
- switch (func) {
- case kAlwaysIfInClip_StencilFunc:
- *mask = clipBit;
- *ref = clipBit;
- break;
- case kEqualIfInClip_StencilFunc:
- case kLessIfInClip_StencilFunc:
- case kLEqualIfInClip_StencilFunc:
- *mask = (*mask & userBits) | clipBit;
- *ref = (*ref & userBits) | clipBit;
- break;
- case kNonZeroIfInClip_StencilFunc:
- *mask = (*mask & userBits) | clipBit;
- *ref = clipBit;
- break;
- default:
- GrCrash("Unknown stencil func");
- }
- } else {
- *mask &= userBits;
- *ref &= userBits;
- }
- }
-}
-
////////////////////////////////////////////////////////////////////////////////
bool GrGpu::setupClipAndFlushState(GrPrimitiveType type) {
diff --git a/src/gpu/gl/GrGpuGL.cpp b/src/gpu/gl/GrGpuGL.cpp
index bf526c9a0f..3d40eb3c3f 100644
--- a/src/gpu/gl/GrGpuGL.cpp
+++ b/src/gpu/gl/GrGpuGL.cpp
@@ -497,7 +497,9 @@ void GrGpuGL::onResetContext() {
fHWBounds.fViewportRect.invalidate();
fHWStencilSettings.invalidate();
- fHWStencilClipMode = kInvalid_StencilClipMode;
+ // This is arbitrary. The above invalidate ensures a full setup of the
+ // stencil on the next draw.
+ fHWStencilClipMode = GrClipMaskManager::kRespectClip_StencilClipMode;
// TODO: I believe this should actually go in GrGpu::onResetContext
// rather than here
@@ -1411,7 +1413,6 @@ void GrGpuGL::clearStencil() {
GL_CALL(ClearStencil(0));
GL_CALL(Clear(GR_GL_STENCIL_BUFFER_BIT));
fHWStencilSettings.invalidate();
- fHWStencilClipMode = kInvalid_StencilClipMode;
}
void GrGpuGL::clearStencilClip(const GrIRect& rect, bool insideClip) {
@@ -1446,7 +1447,6 @@ void GrGpuGL::clearStencilClip(const GrIRect& rect, bool insideClip) {
GL_CALL(ClearStencil(value));
GL_CALL(Clear(GR_GL_STENCIL_BUFFER_BIT));
fHWStencilSettings.invalidate();
- fHWStencilClipMode = kInvalid_StencilClipMode;
}
void GrGpuGL::onForceRenderTargetFlush() {
@@ -1776,75 +1776,121 @@ void GrGpuGL::onResolveRenderTarget(GrRenderTarget* target) {
}
}
-static const GrGLenum grToGLStencilFunc[] = {
- GR_GL_ALWAYS, // kAlways_StencilFunc
- GR_GL_NEVER, // kNever_StencilFunc
- GR_GL_GREATER, // kGreater_StencilFunc
- GR_GL_GEQUAL, // kGEqual_StencilFunc
- GR_GL_LESS, // kLess_StencilFunc
- GR_GL_LEQUAL, // kLEqual_StencilFunc,
- GR_GL_EQUAL, // kEqual_StencilFunc,
- GR_GL_NOTEQUAL, // kNotEqual_StencilFunc,
-};
-GR_STATIC_ASSERT(GR_ARRAY_COUNT(grToGLStencilFunc) == kBasicStencilFuncCount);
-GR_STATIC_ASSERT(0 == kAlways_StencilFunc);
-GR_STATIC_ASSERT(1 == kNever_StencilFunc);
-GR_STATIC_ASSERT(2 == kGreater_StencilFunc);
-GR_STATIC_ASSERT(3 == kGEqual_StencilFunc);
-GR_STATIC_ASSERT(4 == kLess_StencilFunc);
-GR_STATIC_ASSERT(5 == kLEqual_StencilFunc);
-GR_STATIC_ASSERT(6 == kEqual_StencilFunc);
-GR_STATIC_ASSERT(7 == kNotEqual_StencilFunc);
-
-static const GrGLenum grToGLStencilOp[] = {
- GR_GL_KEEP, // kKeep_StencilOp
- GR_GL_REPLACE, // kReplace_StencilOp
- GR_GL_INCR_WRAP, // kIncWrap_StencilOp
- GR_GL_INCR, // kIncClamp_StencilOp
- GR_GL_DECR_WRAP, // kDecWrap_StencilOp
- GR_GL_DECR, // kDecClamp_StencilOp
- GR_GL_ZERO, // kZero_StencilOp
- GR_GL_INVERT, // kInvert_StencilOp
-};
-GR_STATIC_ASSERT(GR_ARRAY_COUNT(grToGLStencilOp) == kStencilOpCount);
-GR_STATIC_ASSERT(0 == kKeep_StencilOp);
-GR_STATIC_ASSERT(1 == kReplace_StencilOp);
-GR_STATIC_ASSERT(2 == kIncWrap_StencilOp);
-GR_STATIC_ASSERT(3 == kIncClamp_StencilOp);
-GR_STATIC_ASSERT(4 == kDecWrap_StencilOp);
-GR_STATIC_ASSERT(5 == kDecClamp_StencilOp);
-GR_STATIC_ASSERT(6 == kZero_StencilOp);
-GR_STATIC_ASSERT(7 == kInvert_StencilOp);
+namespace {
+
+GrGLenum gr_to_gl_stencil_func(GrStencilFunc basicFunc) {
+ static const GrGLenum gTable[] = {
+ GR_GL_ALWAYS, // kAlways_StencilFunc
+ GR_GL_NEVER, // kNever_StencilFunc
+ GR_GL_GREATER, // kGreater_StencilFunc
+ GR_GL_GEQUAL, // kGEqual_StencilFunc
+ GR_GL_LESS, // kLess_StencilFunc
+ GR_GL_LEQUAL, // kLEqual_StencilFunc,
+ GR_GL_EQUAL, // kEqual_StencilFunc,
+ GR_GL_NOTEQUAL, // kNotEqual_StencilFunc,
+ };
+ GR_STATIC_ASSERT(GR_ARRAY_COUNT(gTable) == kBasicStencilFuncCount);
+ GR_STATIC_ASSERT(0 == kAlways_StencilFunc);
+ GR_STATIC_ASSERT(1 == kNever_StencilFunc);
+ GR_STATIC_ASSERT(2 == kGreater_StencilFunc);
+ GR_STATIC_ASSERT(3 == kGEqual_StencilFunc);
+ GR_STATIC_ASSERT(4 == kLess_StencilFunc);
+ GR_STATIC_ASSERT(5 == kLEqual_StencilFunc);
+ GR_STATIC_ASSERT(6 == kEqual_StencilFunc);
+ GR_STATIC_ASSERT(7 == kNotEqual_StencilFunc);
+ GrAssert((unsigned) basicFunc < kBasicStencilFuncCount);
+
+ return gTable[basicFunc];
+}
+
+GrGLenum gr_to_gl_stencil_op(GrStencilOp op) {
+ static const GrGLenum gTable[] = {
+ GR_GL_KEEP, // kKeep_StencilOp
+ GR_GL_REPLACE, // kReplace_StencilOp
+ GR_GL_INCR_WRAP, // kIncWrap_StencilOp
+ GR_GL_INCR, // kIncClamp_StencilOp
+ GR_GL_DECR_WRAP, // kDecWrap_StencilOp
+ GR_GL_DECR, // kDecClamp_StencilOp
+ GR_GL_ZERO, // kZero_StencilOp
+ GR_GL_INVERT, // kInvert_StencilOp
+ };
+ GR_STATIC_ASSERT(GR_ARRAY_COUNT(gTable) == kStencilOpCount);
+ GR_STATIC_ASSERT(0 == kKeep_StencilOp);
+ GR_STATIC_ASSERT(1 == kReplace_StencilOp);
+ GR_STATIC_ASSERT(2 == kIncWrap_StencilOp);
+ GR_STATIC_ASSERT(3 == kIncClamp_StencilOp);
+ GR_STATIC_ASSERT(4 == kDecWrap_StencilOp);
+ GR_STATIC_ASSERT(5 == kDecClamp_StencilOp);
+ GR_STATIC_ASSERT(6 == kZero_StencilOp);
+ GR_STATIC_ASSERT(7 == kInvert_StencilOp);
+ GrAssert((unsigned) op < kStencilOpCount);
+ return gTable[op];
+}
+
+void set_gl_stencil(const GrGLInterface* gl,
+ GrGLenum glFace,
+ GrStencilFunc func,
+ GrStencilOp failOp,
+ GrStencilOp passOp,
+ unsigned int ref,
+ unsigned int mask,
+ unsigned int writeMask) {
+ GrGLenum glFunc = gr_to_gl_stencil_func(func);
+ GrGLenum glFailOp = gr_to_gl_stencil_op(failOp);
+ GrGLenum glPassOp = gr_to_gl_stencil_op(passOp);
+
+ if (GR_GL_FRONT_AND_BACK == glFace) {
+ // we call the combined func just in case separate stencil is not
+ // supported.
+ GR_GL_CALL(gl, StencilFunc(glFunc, ref, mask));
+ GR_GL_CALL(gl, StencilMask(writeMask));
+ GR_GL_CALL(gl, StencilOp(glFailOp, glPassOp, glPassOp));
+ } else {
+ GR_GL_CALL(gl, StencilFuncSeparate(glFace, glFunc, ref, mask));
+ GR_GL_CALL(gl, StencilMaskSeparate(glFace, writeMask));
+ GR_GL_CALL(gl, StencilOpSeparate(glFace, glFailOp, glPassOp, glPassOp));
+ }
+}
+}
void GrGpuGL::flushStencil() {
const GrDrawState& drawState = this->getDrawState();
- const GrStencilSettings* settings = &drawState.getStencil();
-
// use stencil for clipping if clipping is enabled and the clip
// has been written into the stencil.
- StencilClipMode clipMode;
+ GrClipMaskManager::StencilClipMode clipMode;
if (fClipMaskManager.isClipInStencil() &&
drawState.isClipState()) {
- clipMode = kUseClip_StencilClipMode;
+ clipMode = GrClipMaskManager::kRespectClip_StencilClipMode;
// We can't be modifying the clip and respecting it at the same time.
GrAssert(!drawState.isStateFlagEnabled(kModifyStencilClip_StateBit));
} else if (drawState.isStateFlagEnabled(kModifyStencilClip_StateBit)) {
- clipMode = kModifyClip_StencilClipMode;
+ clipMode = GrClipMaskManager::kModifyClip_StencilClipMode;
} else {
- clipMode = kIgnoreClip_StencilClipMode;
+ clipMode = GrClipMaskManager::kIgnoreClip_StencilClipMode;
}
- bool stencilChange = (fHWStencilSettings != *settings) ||
- (fHWStencilClipMode != clipMode);
- if (stencilChange) {
+ // The caller may not be using the stencil buffer but we may need to enable
+ // it in order to respect a stencil clip.
+ const GrStencilSettings* settings = &drawState.getStencil();
+ if (settings->isDisabled() &&
+ GrClipMaskManager::kRespectClip_StencilClipMode == clipMode) {
+ settings = GetClipStencilSettings();
+ }
- if (settings->isDisabled()) {
- if (kUseClip_StencilClipMode == clipMode) {
- settings = GetClipStencilSettings();
- }
- }
+ // TODO: dynamically attach a stencil buffer
+ int stencilBits = 0;
+ GrStencilBuffer* stencilBuffer =
+ drawState.getRenderTarget()->getStencilBuffer();
+ if (NULL != stencilBuffer) {
+ stencilBits = stencilBuffer->bits();
+ }
+ GrAssert(stencilBits || settings->isDisabled());
+ bool updateStencilSettings = stencilBits > 0 &&
+ ((fHWStencilSettings != *settings) ||
+ (fHWStencilClipMode != clipMode));
+ if (updateStencilSettings) {
if (settings->isDisabled()) {
GL_CALL(Disable(GR_GL_STENCIL_TEST));
} else {
@@ -1861,96 +1907,55 @@ void GrGpuGL::flushStencil() {
GrAssert(settings->frontFailOp() != kDecWrap_StencilOp);
}
#endif
- int stencilBits = 0;
- GrStencilBuffer* stencilBuffer =
- drawState.getRenderTarget()->getStencilBuffer();
- if (NULL != stencilBuffer) {
- stencilBits = stencilBuffer->bits();
- }
- // TODO: dynamically attach a stencil buffer
- GrAssert(stencilBits || settings->isDisabled());
-
- GrGLuint clipStencilMask = 0;
- GrGLuint userStencilMask = ~0;
- if (stencilBits > 0) {
- clipStencilMask = 1 << (stencilBits - 1);
- userStencilMask = clipStencilMask - 1;
- }
unsigned int frontRef = settings->frontFuncRef();
unsigned int frontMask = settings->frontFuncMask();
unsigned int frontWriteMask = settings->frontWriteMask();
- GrGLenum frontFunc;
- if (kModifyClip_StencilClipMode == clipMode) {
- GrAssert(settings->frontFunc() < kBasicStencilFuncCount);
- frontFunc = grToGLStencilFunc[settings->frontFunc()];
- } else {
- bool useClip = kUseClip_StencilClipMode == clipMode;
- frontFunc = grToGLStencilFunc[ConvertStencilFunc(useClip,
- settings->frontFunc())];
-
- ConvertStencilFuncAndMask(settings->frontFunc(),
- useClip,
- clipStencilMask,
- userStencilMask,
- &frontRef,
- &frontMask);
- frontWriteMask &= userStencilMask;
- }
- GrAssert((size_t)
- settings->frontFailOp() < GR_ARRAY_COUNT(grToGLStencilOp));
- GrAssert((size_t)
- settings->frontPassOp() < GR_ARRAY_COUNT(grToGLStencilOp));
- GrAssert((size_t)
- settings->backFailOp() < GR_ARRAY_COUNT(grToGLStencilOp));
- GrAssert((size_t)
- settings->backPassOp() < GR_ARRAY_COUNT(grToGLStencilOp));
+ GrStencilFunc frontFunc =
+ fClipMaskManager.adjustStencilParams(settings->frontFunc(),
+ clipMode,
+ stencilBits,
+ &frontRef,
+ &frontMask,
+ &frontWriteMask);
if (this->getCaps().fTwoSidedStencilSupport) {
- GrGLenum backFunc;
-
unsigned int backRef = settings->backFuncRef();
unsigned int backMask = settings->backFuncMask();
unsigned int backWriteMask = settings->backWriteMask();
-
- if (kModifyClip_StencilClipMode == clipMode) {
- GrAssert(settings->backFunc() < kBasicStencilFuncCount);
- backFunc = grToGLStencilFunc[settings->backFunc()];
- } else {
- bool useClip = kUseClip_StencilClipMode == clipMode;
- backFunc = grToGLStencilFunc[ConvertStencilFunc(useClip,
- settings->backFunc())];
- ConvertStencilFuncAndMask(settings->backFunc(),
- useClip,
- clipStencilMask,
- userStencilMask,
- &backRef,
- &backMask);
- backWriteMask &= userStencilMask;
- }
-
- GL_CALL(StencilFuncSeparate(GR_GL_FRONT, frontFunc,
- frontRef, frontMask));
- GL_CALL(StencilMaskSeparate(GR_GL_FRONT, frontWriteMask));
- GL_CALL(StencilFuncSeparate(GR_GL_BACK, backFunc,
- backRef, backMask));
- GL_CALL(StencilMaskSeparate(GR_GL_BACK, backWriteMask));
- GL_CALL(StencilOpSeparate(GR_GL_FRONT,
- grToGLStencilOp[settings->frontFailOp()],
- grToGLStencilOp[settings->frontPassOp()],
- grToGLStencilOp[settings->frontPassOp()]));
-
- GL_CALL(StencilOpSeparate(GR_GL_BACK,
- grToGLStencilOp[settings->backFailOp()],
- grToGLStencilOp[settings->backPassOp()],
- grToGLStencilOp[settings->backPassOp()]));
+ GrStencilFunc backFunc =
+ fClipMaskManager.adjustStencilParams(settings->frontFunc(),
+ clipMode,
+ stencilBits,
+ &backRef,
+ &backMask,
+ &backWriteMask);
+ set_gl_stencil(this->glInterface(),
+ GR_GL_FRONT,
+ frontFunc,
+ settings->frontFailOp(),
+ settings->frontPassOp(),
+ frontRef,
+ frontMask,
+ frontWriteMask);
+ set_gl_stencil(this->glInterface(),
+ GR_GL_BACK,
+ backFunc,
+ settings->backFailOp(),
+ settings->backPassOp(),
+ backRef,
+ backMask,
+ backWriteMask);
} else {
- GL_CALL(StencilFunc(frontFunc, frontRef, frontMask));
- GL_CALL(StencilMask(frontWriteMask));
- GL_CALL(StencilOp(grToGLStencilOp[settings->frontFailOp()],
- grToGLStencilOp[settings->frontPassOp()],
- grToGLStencilOp[settings->frontPassOp()]));
+ set_gl_stencil(this->glInterface(),
+ GR_GL_FRONT_AND_BACK,
+ frontFunc,
+ settings->frontFailOp(),
+ settings->frontPassOp(),
+ frontRef,
+ frontMask,
+ frontWriteMask);
}
}
fHWStencilSettings = *settings;
diff --git a/src/gpu/gl/GrGpuGL.h b/src/gpu/gl/GrGpuGL.h
index 5830348b6c..df729a74ff 100644
--- a/src/gpu/gl/GrGpuGL.h
+++ b/src/gpu/gl/GrGpuGL.h
@@ -347,22 +347,8 @@ private:
}
} fHWAAState;
- // The high bit of the stencil buffer is used for clipping. This enum is
- // used to track whether the clip bit of the stencil buffer is being used,
- // manipulated, or neither.
- enum StencilClipMode {
- // Draw to the clip bit of the stencil buffer
- kModifyClip_StencilClipMode,
- // Clip against the existing representation of the clip in the high bit
- // of the stencil buffer.
- kUseClip_StencilClipMode,
- // Neither writing to nor clipping against the clip bit.
- kIgnoreClip_StencilClipMode,
- // Unknown state of HW
- kInvalid_StencilClipMode,
- };
- StencilClipMode fHWStencilClipMode;
- GrStencilSettings fHWStencilSettings;
+ GrClipMaskManager::StencilClipMode fHWStencilClipMode;
+ GrStencilSettings fHWStencilSettings;
GrDrawState::DrawFace fHWDrawFace;
TriState fHWWriteToColor;