diff options
author | bsalomon@google.com <bsalomon@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2012-06-05 20:24:20 +0000 |
---|---|---|
committer | bsalomon@google.com <bsalomon@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2012-06-05 20:24:20 +0000 |
commit | 411dad0630913fc07f2412b4be17acfbfd914fbc (patch) | |
tree | 36d28ba722c1c33cd2ca60f341ef60ef1d5e5a03 /src | |
parent | 57288857cd7992eaa44753c7b9f987e318a0e8c3 (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.cpp | 95 | ||||
-rw-r--r-- | src/gpu/GrClipMaskManager.h | 41 | ||||
-rw-r--r-- | src/gpu/GrGpu.cpp | 81 | ||||
-rw-r--r-- | src/gpu/gl/GrGpuGL.cpp | 275 | ||||
-rw-r--r-- | src/gpu/gl/GrGpuGL.h | 18 |
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; |