aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/gpu/gl/GrGpuGL.cpp
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/gpu/gl/GrGpuGL.cpp
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/gpu/gl/GrGpuGL.cpp')
-rw-r--r--src/gpu/gl/GrGpuGL.cpp275
1 files changed, 140 insertions, 135 deletions
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;