aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar bsalomon@google.com <bsalomon@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2011-12-15 19:47:46 +0000
committerGravatar bsalomon@google.com <bsalomon@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2011-12-15 19:47:46 +0000
commit6b2445eb154d71517b1ed6811f3f77eec592963a (patch)
tree2fd8b08e454b82069cf19aa5469b79485b9f1887
parent8c0aab14438651de3c20e2008bae404da3fd4f70 (diff)
Make GrStencilState a class to enable future optimizations
Review URL: http://codereview.appspot.com/5492047/ git-svn-id: http://skia.googlecode.com/svn/trunk@2881 2bbb7eff-a529-9590-31e7-b0007b416f81
-rw-r--r--src/gpu/GrDefaultPathRenderer.cpp169
-rw-r--r--src/gpu/GrGpu.cpp31
-rw-r--r--src/gpu/GrGpu.h3
-rw-r--r--src/gpu/GrGpuGL.cpp73
-rw-r--r--src/gpu/GrStencil.cpp352
-rw-r--r--src/gpu/GrStencil.h74
6 files changed, 367 insertions, 335 deletions
diff --git a/src/gpu/GrDefaultPathRenderer.cpp b/src/gpu/GrDefaultPathRenderer.cpp
index ebd0cc142d..6ea04591cd 100644
--- a/src/gpu/GrDefaultPathRenderer.cpp
+++ b/src/gpu/GrDefaultPathRenderer.cpp
@@ -41,34 +41,31 @@ bool GrDefaultPathRenderer::canDrawPath(const GrDrawTarget::Caps& targetCaps,
////// Even/Odd
-static const GrStencilSettings gEOStencilPass = {
- kInvert_StencilOp, kInvert_StencilOp,
- kKeep_StencilOp, kKeep_StencilOp,
- kAlwaysIfInClip_StencilFunc, kAlwaysIfInClip_StencilFunc,
- 0xffff, 0xffff,
- 0xffff, 0xffff,
- 0xffff, 0xffff
-};
+GR_STATIC_CONST_SAME_STENCIL(gEOStencilPass,
+ kInvert_StencilOp,
+ kKeep_StencilOp,
+ kAlwaysIfInClip_StencilFunc,
+ 0xffff,
+ 0xffff,
+ 0xffff);
// ok not to check clip b/c stencil pass only wrote inside clip
-static const GrStencilSettings gEOColorPass = {
- kZero_StencilOp, kZero_StencilOp,
- kZero_StencilOp, kZero_StencilOp,
- kNotEqual_StencilFunc, kNotEqual_StencilFunc,
- 0xffff, 0xffff,
- 0x0000, 0x0000,
- 0xffff, 0xffff
-};
+GR_STATIC_CONST_SAME_STENCIL(gEOColorPass,
+ kZero_StencilOp,
+ kZero_StencilOp,
+ kNotEqual_StencilFunc,
+ 0xffff,
+ 0x0000,
+ 0xffff);
// have to check clip b/c outside clip will always be zero.
-static const GrStencilSettings gInvEOColorPass = {
- kZero_StencilOp, kZero_StencilOp,
- kZero_StencilOp, kZero_StencilOp,
- kEqualIfInClip_StencilFunc, kEqualIfInClip_StencilFunc,
- 0xffff, 0xffff,
- 0x0000, 0x0000,
- 0xffff, 0xffff
-};
+GR_STATIC_CONST_SAME_STENCIL(gInvEOColorPass,
+ kZero_StencilOp,
+ kZero_StencilOp,
+ kEqualIfInClip_StencilFunc,
+ 0xffff,
+ 0x0000,
+ 0xffff);
////// Winding
@@ -76,95 +73,91 @@ static const GrStencilSettings gInvEOColorPass = {
// when we don't have wrap incr and decr we use the stencil test to simulate
// them.
-static const GrStencilSettings gWindStencilSeparateWithWrap = {
+GR_STATIC_CONST_STENCIL(gWindStencilSeparateWithWrap,
kIncWrap_StencilOp, kDecWrap_StencilOp,
kKeep_StencilOp, kKeep_StencilOp,
kAlwaysIfInClip_StencilFunc, kAlwaysIfInClip_StencilFunc,
0xffff, 0xffff,
0xffff, 0xffff,
- 0xffff, 0xffff
-};
+ 0xffff, 0xffff);
// if inc'ing the max value, invert to make 0
// if dec'ing zero invert to make all ones.
// we can't avoid touching the stencil on both passing and
// failing, so we can't resctrict ourselves to the clip.
-static const GrStencilSettings gWindStencilSeparateNoWrap = {
+GR_STATIC_CONST_STENCIL(gWindStencilSeparateNoWrap,
kInvert_StencilOp, kInvert_StencilOp,
kIncClamp_StencilOp, kDecClamp_StencilOp,
kEqual_StencilFunc, kEqual_StencilFunc,
0xffff, 0xffff,
0xffff, 0x0000,
- 0xffff, 0xffff
-};
+ 0xffff, 0xffff);
// When there are no separate faces we do two passes to setup the winding rule
// stencil. First we draw the front faces and inc, then we draw the back faces
// and dec. These are same as the above two split into the incrementing and
// decrementing passes.
-static const GrStencilSettings gWindSingleStencilWithWrapInc = {
- kIncWrap_StencilOp, kIncWrap_StencilOp,
- kKeep_StencilOp, kKeep_StencilOp,
- kAlwaysIfInClip_StencilFunc, kAlwaysIfInClip_StencilFunc,
- 0xffff, 0xffff,
- 0xffff, 0xffff,
- 0xffff, 0xffff
-};
-static const GrStencilSettings gWindSingleStencilWithWrapDec = {
- kDecWrap_StencilOp, kDecWrap_StencilOp,
- kKeep_StencilOp, kKeep_StencilOp,
- kAlwaysIfInClip_StencilFunc, kAlwaysIfInClip_StencilFunc,
- 0xffff, 0xffff,
- 0xffff, 0xffff,
- 0xffff, 0xffff
-};
-static const GrStencilSettings gWindSingleStencilNoWrapInc = {
- kInvert_StencilOp, kInvert_StencilOp,
- kIncClamp_StencilOp, kIncClamp_StencilOp,
- kEqual_StencilFunc, kEqual_StencilFunc,
- 0xffff, 0xffff,
- 0xffff, 0xffff,
- 0xffff, 0xffff
-};
-static const GrStencilSettings gWindSingleStencilNoWrapDec = {
- kInvert_StencilOp, kInvert_StencilOp,
- kDecClamp_StencilOp, kDecClamp_StencilOp,
- kEqual_StencilFunc, kEqual_StencilFunc,
- 0xffff, 0xffff,
- 0x0000, 0x0000,
- 0xffff, 0xffff
-};
-
-static const GrStencilSettings gWindColorPass = {
- kZero_StencilOp, kZero_StencilOp,
- kZero_StencilOp, kZero_StencilOp,
- kNonZeroIfInClip_StencilFunc, kNonZeroIfInClip_StencilFunc,
- 0xffff, 0xffff,
- 0x0000, 0x0000,
- 0xffff, 0xffff
-};
-
-static const GrStencilSettings gInvWindColorPass = {
- kZero_StencilOp, kZero_StencilOp,
- kZero_StencilOp, kZero_StencilOp,
- kEqualIfInClip_StencilFunc, kEqualIfInClip_StencilFunc,
- 0xffff, 0xffff,
- 0x0000, 0x0000,
- 0xffff, 0xffff
-};
+GR_STATIC_CONST_SAME_STENCIL(gWindSingleStencilWithWrapInc,
+ kIncWrap_StencilOp,
+ kKeep_StencilOp,
+ kAlwaysIfInClip_StencilFunc,
+ 0xffff,
+ 0xffff,
+ 0xffff);
+
+GR_STATIC_CONST_SAME_STENCIL(gWindSingleStencilWithWrapDec,
+ kDecWrap_StencilOp,
+ kKeep_StencilOp,
+ kAlwaysIfInClip_StencilFunc,
+ 0xffff,
+ 0xffff,
+ 0xffff);
+
+GR_STATIC_CONST_SAME_STENCIL(gWindSingleStencilNoWrapInc,
+ kInvert_StencilOp,
+ kIncClamp_StencilOp,
+ kEqual_StencilFunc,
+ 0xffff,
+ 0xffff,
+ 0xffff);
+
+GR_STATIC_CONST_SAME_STENCIL(gWindSingleStencilNoWrapDec,
+ kInvert_StencilOp,
+ kDecClamp_StencilOp,
+ kEqual_StencilFunc,
+ 0xffff,
+ 0x0000,
+ 0xffff);
+
+// Color passes are the same whether we use the two-sided stencil or two passes
+
+GR_STATIC_CONST_SAME_STENCIL(gWindColorPass,
+ kZero_StencilOp,
+ kZero_StencilOp,
+ kNonZeroIfInClip_StencilFunc,
+ 0xffff,
+ 0x0000,
+ 0xffff);
+
+GR_STATIC_CONST_SAME_STENCIL(gInvWindColorPass,
+ kZero_StencilOp,
+ kZero_StencilOp,
+ kEqualIfInClip_StencilFunc,
+ 0xffff,
+ 0x0000,
+ 0xffff);
////// Normal render to stencil
// Sometimes the default path renderer can draw a path directly to the stencil
// buffer without having to first resolve the interior / exterior.
-static const GrStencilSettings gDirectToStencil = {
- kZero_StencilOp, kZero_StencilOp,
- kIncClamp_StencilOp, kIncClamp_StencilOp,
- kAlwaysIfInClip_StencilFunc, kAlwaysIfInClip_StencilFunc,
- 0xffff, 0xffff,
- 0x0000, 0x0000,
- 0xffff, 0xffff
-};
+GR_STATIC_CONST_SAME_STENCIL(gDirectToStencil,
+ kZero_StencilOp,
+ kIncClamp_StencilOp,
+ kAlwaysIfInClip_StencilFunc,
+ 0xffff,
+ 0x0000,
+ 0xffff);
////////////////////////////////////////////////////////////////////////////////
// Helpers for drawPath
diff --git a/src/gpu/GrGpu.cpp b/src/gpu/GrGpu.cpp
index 4a2e5d71a9..176134528f 100644
--- a/src/gpu/GrGpu.cpp
+++ b/src/gpu/GrGpu.cpp
@@ -339,14 +339,14 @@ const GrVertexBuffer* GrGpu::getUnitSquareVertexBuffer() const {
////////////////////////////////////////////////////////////////////////////////
// stencil settings to use when clip is in stencil
-const GrStencilSettings GrGpu::gClipStencilSettings = {
- kKeep_StencilOp, kKeep_StencilOp,
- kKeep_StencilOp, kKeep_StencilOp,
- kAlwaysIfInClip_StencilFunc, kAlwaysIfInClip_StencilFunc,
- 0x0000, 0x0000,
- 0x0000, 0x0000,
- 0x0000, 0x0000
-};
+GR_STATIC_CONST_SAME_STENCIL(gClipStencilSettings,
+ kKeep_StencilOp,
+ kKeep_StencilOp,
+ kAlwaysIfInClip_StencilFunc,
+ 0x0000,
+ 0x0000,
+ 0x0000);
+const GrStencilSettings& GrGpu::gClipStencilSettings = ::gClipStencilSettings;
// mapping of clip-respecting stencil funcs to normal stencil funcs
// mapping depends on whether stencil-clipping is in effect.
@@ -669,14 +669,13 @@ bool GrGpu::setupClipAndFlushState(GrPrimitiveType type) {
// draw the element to the client stencil bits if necessary
if (!canDrawDirectToClip) {
- static const GrStencilSettings gDrawToStencil = {
- kIncClamp_StencilOp, kIncClamp_StencilOp,
- kIncClamp_StencilOp, kIncClamp_StencilOp,
- kAlways_StencilFunc, kAlways_StencilFunc,
- 0xffff, 0xffff,
- 0x0000, 0x0000,
- 0xffff, 0xffff,
- };
+ GR_STATIC_CONST_SAME_STENCIL(gDrawToStencil,
+ kIncClamp_StencilOp,
+ kIncClamp_StencilOp,
+ kAlways_StencilFunc,
+ 0xffff,
+ 0x0000,
+ 0xffff);
SET_RANDOM_COLOR
if (kRect_ClipType == clip.getElementType(c)) {
*drawState->stencil() = gDrawToStencil;
diff --git a/src/gpu/GrGpu.h b/src/gpu/GrGpu.h
index 11f50831ca..0836ec87cc 100644
--- a/src/gpu/GrGpu.h
+++ b/src/gpu/GrGpu.h
@@ -355,8 +355,7 @@ protected:
// stencil settings to clip drawing when stencil clipping is in effect
// and the client isn't using the stencil test.
- static const GrStencilSettings gClipStencilSettings;
-
+ static const GrStencilSettings& gClipStencilSettings;
GrGpuStats fStats;
diff --git a/src/gpu/GrGpuGL.cpp b/src/gpu/GrGpuGL.cpp
index f2663689e1..339133fa8e 100644
--- a/src/gpu/GrGpuGL.cpp
+++ b/src/gpu/GrGpuGL.cpp
@@ -1826,14 +1826,14 @@ void GrGpuGL::flushStencil() {
GL_CALL(Enable(GR_GL_STENCIL_TEST));
#if GR_DEBUG
if (!this->getCaps().fStencilWrapOpsSupport) {
- GrAssert(settings->fFrontPassOp != kIncWrap_StencilOp);
- GrAssert(settings->fFrontPassOp != kDecWrap_StencilOp);
- GrAssert(settings->fFrontFailOp != kIncWrap_StencilOp);
- GrAssert(settings->fBackFailOp != kDecWrap_StencilOp);
- GrAssert(settings->fBackPassOp != kIncWrap_StencilOp);
- GrAssert(settings->fBackPassOp != kDecWrap_StencilOp);
- GrAssert(settings->fBackFailOp != kIncWrap_StencilOp);
- GrAssert(settings->fFrontFailOp != kDecWrap_StencilOp);
+ GrAssert(settings->frontPassOp() != kIncWrap_StencilOp);
+ GrAssert(settings->frontPassOp() != kDecWrap_StencilOp);
+ GrAssert(settings->frontFailOp() != kIncWrap_StencilOp);
+ GrAssert(settings->backFailOp() != kDecWrap_StencilOp);
+ GrAssert(settings->backPassOp() != kIncWrap_StencilOp);
+ GrAssert(settings->backPassOp() != kDecWrap_StencilOp);
+ GrAssert(settings->backFailOp() != kIncWrap_StencilOp);
+ GrAssert(settings->frontFailOp() != kDecWrap_StencilOp);
}
#endif
int stencilBits = 0;
@@ -1843,8 +1843,7 @@ void GrGpuGL::flushStencil() {
stencilBits = stencilBuffer->bits();
}
// TODO: dynamically attach a stencil buffer
- GrAssert(stencilBits ||
- (GrStencilSettings::gDisabled == *settings));
+ GrAssert(stencilBits || settings->isDisabled());
GrGLuint clipStencilMask = 0;
GrGLuint userStencilMask = ~0;
@@ -1853,19 +1852,19 @@ void GrGpuGL::flushStencil() {
userStencilMask = clipStencilMask - 1;
}
- unsigned int frontRef = settings->fFrontFuncRef;
- unsigned int frontMask = settings->fFrontFuncMask;
- unsigned int frontWriteMask = settings->fFrontWriteMask;
+ unsigned int frontRef = settings->frontFuncRef();
+ unsigned int frontMask = settings->frontFuncMask();
+ unsigned int frontWriteMask = settings->frontWriteMask();
GrGLenum frontFunc;
if (drawClipToStencil) {
- GrAssert(settings->fFrontFunc < kBasicStencilFuncCount);
- frontFunc = grToGLStencilFunc[settings->fFrontFunc];
+ GrAssert(settings->frontFunc() < kBasicStencilFuncCount);
+ frontFunc = grToGLStencilFunc[settings->frontFunc()];
} else {
frontFunc = grToGLStencilFunc[ConvertStencilFunc(
- stencilClip, settings->fFrontFunc)];
+ stencilClip, settings->frontFunc())];
- ConvertStencilFuncAndMask(settings->fFrontFunc,
+ ConvertStencilFuncAndMask(settings->frontFunc(),
stencilClip,
clipStencilMask,
userStencilMask,
@@ -1874,28 +1873,28 @@ void GrGpuGL::flushStencil() {
frontWriteMask &= userStencilMask;
}
GrAssert((size_t)
- settings->fFrontFailOp < GR_ARRAY_COUNT(grToGLStencilOp));
+ settings->frontFailOp() < GR_ARRAY_COUNT(grToGLStencilOp));
GrAssert((size_t)
- settings->fFrontPassOp < GR_ARRAY_COUNT(grToGLStencilOp));
+ settings->frontPassOp() < GR_ARRAY_COUNT(grToGLStencilOp));
GrAssert((size_t)
- settings->fBackFailOp < GR_ARRAY_COUNT(grToGLStencilOp));
+ settings->backFailOp() < GR_ARRAY_COUNT(grToGLStencilOp));
GrAssert((size_t)
- settings->fBackPassOp < GR_ARRAY_COUNT(grToGLStencilOp));
+ settings->backPassOp() < GR_ARRAY_COUNT(grToGLStencilOp));
if (this->getCaps().fTwoSidedStencilSupport) {
GrGLenum backFunc;
- unsigned int backRef = settings->fBackFuncRef;
- unsigned int backMask = settings->fBackFuncMask;
- unsigned int backWriteMask = settings->fBackWriteMask;
+ unsigned int backRef = settings->backFuncRef();
+ unsigned int backMask = settings->backFuncMask();
+ unsigned int backWriteMask = settings->backWriteMask();
if (drawClipToStencil) {
- GrAssert(settings->fBackFunc < kBasicStencilFuncCount);
- backFunc = grToGLStencilFunc[settings->fBackFunc];
+ GrAssert(settings->backFunc() < kBasicStencilFuncCount);
+ backFunc = grToGLStencilFunc[settings->backFunc()];
} else {
backFunc = grToGLStencilFunc[ConvertStencilFunc(
- stencilClip, settings->fBackFunc)];
- ConvertStencilFuncAndMask(settings->fBackFunc,
+ stencilClip, settings->backFunc())];
+ ConvertStencilFuncAndMask(settings->backFunc(),
stencilClip,
clipStencilMask,
userStencilMask,
@@ -1911,20 +1910,20 @@ void GrGpuGL::flushStencil() {
backRef, backMask));
GL_CALL(StencilMaskSeparate(GR_GL_BACK, backWriteMask));
GL_CALL(StencilOpSeparate(GR_GL_FRONT,
- grToGLStencilOp[settings->fFrontFailOp],
- grToGLStencilOp[settings->fFrontPassOp],
- grToGLStencilOp[settings->fFrontPassOp]));
+ grToGLStencilOp[settings->frontFailOp()],
+ grToGLStencilOp[settings->frontPassOp()],
+ grToGLStencilOp[settings->frontPassOp()]));
GL_CALL(StencilOpSeparate(GR_GL_BACK,
- grToGLStencilOp[settings->fBackFailOp],
- grToGLStencilOp[settings->fBackPassOp],
- grToGLStencilOp[settings->fBackPassOp]));
+ grToGLStencilOp[settings->backFailOp()],
+ grToGLStencilOp[settings->backPassOp()],
+ grToGLStencilOp[settings->backPassOp()]));
} else {
GL_CALL(StencilFunc(frontFunc, frontRef, frontMask));
GL_CALL(StencilMask(frontWriteMask));
- GL_CALL(StencilOp(grToGLStencilOp[settings->fFrontFailOp],
- grToGLStencilOp[settings->fFrontPassOp],
- grToGLStencilOp[settings->fFrontPassOp]));
+ GL_CALL(StencilOp(grToGLStencilOp[settings->frontFailOp()],
+ grToGLStencilOp[settings->frontPassOp()],
+ grToGLStencilOp[settings->frontPassOp()]));
}
}
*fHWDrawState.stencil() = *settings;
diff --git a/src/gpu/GrStencil.cpp b/src/gpu/GrStencil.cpp
index 81b3b8d144..66249429d2 100644
--- a/src/gpu/GrStencil.cpp
+++ b/src/gpu/GrStencil.cpp
@@ -9,17 +9,6 @@
#include "GrStencil.h"
-const GrStencilSettings GrStencilSettings::gDisabled = {
- kKeep_StencilOp, kKeep_StencilOp,
- kKeep_StencilOp, kKeep_StencilOp,
- kAlways_StencilFunc, kAlways_StencilFunc,
- 0x0000, 0x0000,
- 0x0000, 0x0000,
- 0x0000, 0x0000
-};
-GR_STATIC_ASSERT(0 == kKeep_StencilOp);
-GR_STATIC_ASSERT(0 == kAlways_StencilFunc);
-
////////////////////////////////////////////////////////////////////////////////
// Stencil Rules for Merging user stencil space into clip
@@ -32,171 +21,160 @@ GR_STATIC_ASSERT(0 == kAlways_StencilFunc);
// Replace
// set the ref to be the clip bit, but mask it out for the test
-static const GrStencilSettings gUserToClipReplace = {
- kReplace_StencilOp, kReplace_StencilOp,
- kZero_StencilOp, kZero_StencilOp,
- kLess_StencilFunc, kLess_StencilFunc,
- 0xffff, 0xffff, // unset clip bit
- 0x0000, 0x0000, // set clip bit
- 0xffff, 0xffff
-};
-static const GrStencilSettings gInvUserToClipReplace = {
- kReplace_StencilOp, kReplace_StencilOp,
- kZero_StencilOp, kZero_StencilOp,
- kEqual_StencilFunc, kEqual_StencilFunc,
- 0xffff, 0xffff, // unset clip bit
- 0x0000, 0x0000, // set clip bit
- 0xffff, 0xffff
-};
+GR_STATIC_CONST_SAME_STENCIL(gUserToClipReplace,
+ kReplace_StencilOp,
+ kZero_StencilOp,
+ kLess_StencilFunc,
+ 0xffff, // unset clip bit
+ 0x0000, // set clip bit
+ 0xffff);
+
+GR_STATIC_CONST_SAME_STENCIL(gInvUserToClipReplace,
+ kReplace_StencilOp,
+ kZero_StencilOp,
+ kEqual_StencilFunc,
+ 0xffff, // unset clip bit
+ 0x0000, // set clip bit
+ 0xffff);
///////
// Intersect
-static const GrStencilSettings gUserToClipIsect = {
- kReplace_StencilOp, kReplace_StencilOp,
- kZero_StencilOp, kZero_StencilOp,
- kLess_StencilFunc, kLess_StencilFunc,
- 0xffff, 0xffff,
- 0x0000, 0x0000, // set clip bit
- 0xffff, 0xffff
-};
-static const GrStencilSettings gInvUserToClipIsect = {
- kReplace_StencilOp, kReplace_StencilOp,
- kZero_StencilOp, kZero_StencilOp,
- kEqual_StencilFunc, kEqual_StencilFunc,
- 0xffff, 0xffff,
- 0x0000, 0x0000, // set clip bit
- 0xffff, 0xffff
-};
+GR_STATIC_CONST_SAME_STENCIL(gUserToClipIsect,
+ kReplace_StencilOp,
+ kZero_StencilOp,
+ kLess_StencilFunc,
+ 0xffff,
+ 0x0000, // set clip bit
+ 0xffff);
+
+GR_STATIC_CONST_SAME_STENCIL(gInvUserToClipIsect,
+ kReplace_StencilOp,
+ kZero_StencilOp,
+ kEqual_StencilFunc,
+ 0xffff,
+ 0x0000, // set clip bit
+ 0xffff);
///////
// Difference
-static const GrStencilSettings gUserToClipDiff = {
- kReplace_StencilOp, kReplace_StencilOp,
- kZero_StencilOp, kZero_StencilOp,
- kEqual_StencilFunc, kEqual_StencilFunc,
- 0xffff, 0xffff,
- 0x0000, 0x0000, // set clip bit
- 0xffff, 0xffff
-};
-static const GrStencilSettings gInvUserToClipDiff = {
- kReplace_StencilOp, kReplace_StencilOp,
- kZero_StencilOp, kZero_StencilOp,
- kLess_StencilFunc, kLess_StencilFunc,
- 0xffff, 0xffff,
- 0x0000, 0x0000, // set clip bit
- 0xffff, 0xffff
-};
+GR_STATIC_CONST_SAME_STENCIL(gUserToClipDiff,
+ kReplace_StencilOp,
+ kZero_StencilOp,
+ kEqual_StencilFunc,
+ 0xffff,
+ 0x0000, // set clip bit
+ 0xffff);
+
+GR_STATIC_CONST_SAME_STENCIL(gInvUserToClipDiff,
+ kReplace_StencilOp,
+ kZero_StencilOp,
+ kLess_StencilFunc,
+ 0xffff,
+ 0x0000, // set clip bit
+ 0xffff);
///////
// Union
// first pass makes all the passing cases >= just clip bit set.
-static const GrStencilSettings gUserToClipUnionPass0 = {
- kReplace_StencilOp, kReplace_StencilOp,
- kKeep_StencilOp, kKeep_StencilOp,
- kLEqual_StencilFunc, kLEqual_StencilFunc,
- 0xffff, 0xffff, // unset clip bit
- 0x0001, 0x0001, // set clip bit
- 0xffff, 0xffff
-};
+GR_STATIC_CONST_SAME_STENCIL(gUserToClipUnionPass0,
+ kReplace_StencilOp,
+ kKeep_StencilOp,
+ kLEqual_StencilFunc,
+ 0xffff,
+ 0x0001, // set clip bit
+ 0xffff);
// second pass allows anything greater than just clip bit set to pass
-static const GrStencilSettings gUserToClipUnionPass1 = {
- kReplace_StencilOp, kReplace_StencilOp,
- kZero_StencilOp, kZero_StencilOp,
- kLEqual_StencilFunc, kLEqual_StencilFunc,
- 0xffff, 0xffff,
- 0x0000, 0x0000, // set clip bit
- 0xffff, 0xffff
-};
+GR_STATIC_CONST_SAME_STENCIL(gUserToClipUnionPass1,
+ kReplace_StencilOp,
+ kZero_StencilOp,
+ kLEqual_StencilFunc,
+ 0xffff,
+ 0x0000, // set clip bit
+ 0xffff);
// first pass finds zeros in the user bits and if found sets
// the clip bit to 1
-static const GrStencilSettings gInvUserToClipUnionPass0 = {
- kReplace_StencilOp, kReplace_StencilOp,
- kKeep_StencilOp, kKeep_StencilOp,
- kEqual_StencilFunc, kEqual_StencilFunc,
- 0xffff, 0xffff, // unset clip bit
- 0x0000, 0x0000, // set clip bit
- 0x0000, 0x0000 // set clip bit
-};
+GR_STATIC_CONST_SAME_STENCIL(gInvUserToClipUnionPass0,
+ kReplace_StencilOp,
+ kKeep_StencilOp,
+ kEqual_StencilFunc,
+ 0xffff,
+ 0x0000, // set clip bit
+ 0x0000 // set clip bit
+);
// second pass zeros the user bits
-static const GrStencilSettings gInvUserToClipUnionPass1 = {
- kZero_StencilOp, kZero_StencilOp,
- kZero_StencilOp, kZero_StencilOp,
- kLess_StencilFunc, kLess_StencilFunc,
- 0xffff, 0xffff,
- 0x0000, 0x0000,
- 0xffff, 0xffff // unset clip bit
-};
+GR_STATIC_CONST_SAME_STENCIL(gInvUserToClipUnionPass1,
+ kZero_StencilOp,
+ kZero_StencilOp,
+ kLess_StencilFunc,
+ 0xffff,
+ 0x0000,
+ 0xffff // unset clip bit
+);
///////
// Xor
-static const GrStencilSettings gUserToClipXorPass0 = {
- kInvert_StencilOp, kInvert_StencilOp,
- kKeep_StencilOp, kKeep_StencilOp,
- kEqual_StencilFunc, kEqual_StencilFunc,
- 0xffff, 0xffff, // unset clip bit
- 0x0000, 0x0000,
- 0xffff, 0xffff
-};
-
-static const GrStencilSettings gUserToClipXorPass1 = {
- kReplace_StencilOp, kReplace_StencilOp,
- kZero_StencilOp, kZero_StencilOp,
- kGreater_StencilFunc, kGreater_StencilFunc,
- 0xffff, 0xffff,
- 0x0000, 0x0000, // set clip bit
- 0xffff, 0xffff
-};
-
-static const GrStencilSettings gInvUserToClipXorPass0 = {
- kInvert_StencilOp, kInvert_StencilOp,
- kKeep_StencilOp, kKeep_StencilOp,
- kEqual_StencilFunc, kEqual_StencilFunc,
- 0xffff, 0xffff, // unset clip bit
- 0x0000, 0x0000,
- 0xffff, 0xffff
-};
-
-static const GrStencilSettings gInvUserToClipXorPass1 = {
- kReplace_StencilOp, kReplace_StencilOp,
- kZero_StencilOp, kZero_StencilOp,
- kLess_StencilFunc, kLess_StencilFunc,
- 0xffff, 0xffff,
- 0x0000, 0x0000, // set clip bit
- 0xffff, 0xffff
-};
+GR_STATIC_CONST_SAME_STENCIL(gUserToClipXorPass0,
+ kInvert_StencilOp,
+ kKeep_StencilOp,
+ kEqual_StencilFunc,
+ 0xffff, // unset clip bit
+ 0x0000,
+ 0xffff);
+
+GR_STATIC_CONST_SAME_STENCIL(gUserToClipXorPass1,
+ kReplace_StencilOp,
+ kZero_StencilOp,
+ kGreater_StencilFunc,
+ 0xffff,
+ 0x0000, // set clip bit
+ 0xffff);
+
+GR_STATIC_CONST_SAME_STENCIL(gInvUserToClipXorPass0,
+ kInvert_StencilOp,
+ kKeep_StencilOp,
+ kEqual_StencilFunc,
+ 0xffff, // unset clip bit
+ 0x0000,
+ 0xffff);
+
+GR_STATIC_CONST_SAME_STENCIL(gInvUserToClipXorPass1,
+ kReplace_StencilOp,
+ kZero_StencilOp,
+ kLess_StencilFunc,
+ 0xffff,
+ 0x0000, // set clip bit
+ 0xffff);
///////
// Reverse Diff
-static const GrStencilSettings gUserToClipRDiffPass0 = {
- kInvert_StencilOp, kInvert_StencilOp,
- kZero_StencilOp, kZero_StencilOp,
- kLess_StencilFunc, kLess_StencilFunc,
- 0xffff, 0xffff, // unset clip bit
- 0x0000, 0x0000, // set clip bit
- 0xffff, 0xffff
-};
-
-static const GrStencilSettings gUserToClipRDiffPass1 = {
- kReplace_StencilOp, kReplace_StencilOp,
- kZero_StencilOp, kZero_StencilOp,
- kEqual_StencilFunc, kEqual_StencilFunc,
- 0x0000, 0x0000, // set clip bit
- 0x0000, 0x0000, // set clip bit
- 0xffff, 0xffff
-};
-
-static const GrStencilSettings gInvUserToClipRDiff = {
- kInvert_StencilOp, kInvert_StencilOp,
- kZero_StencilOp, kZero_StencilOp,
- kEqual_StencilFunc, kEqual_StencilFunc,
- 0xffff, 0xffff,
- 0x0000, 0x0000,
- 0x0000, 0x0000 // set clip bit
-};
+GR_STATIC_CONST_SAME_STENCIL(gUserToClipRDiffPass0,
+ kInvert_StencilOp,
+ kZero_StencilOp,
+ kLess_StencilFunc,
+ 0xffff, // unset clip bit
+ 0x0000, // set clip bit
+ 0xffff);
+
+GR_STATIC_CONST_SAME_STENCIL(gUserToClipRDiffPass1,
+ kReplace_StencilOp,
+ kZero_StencilOp,
+ kEqual_StencilFunc,
+ 0x0000, // set clip bit
+ 0x0000, // set clip bit
+ 0xffff);
+
+GR_STATIC_CONST_SAME_STENCIL(gInvUserToClipRDiff,
+ kInvert_StencilOp,
+ kZero_StencilOp,
+ kEqual_StencilFunc,
+ 0xffff,
+ 0x0000,
+ 0x0000 // set clip bit
+);
///////
// Direct to Stencil
@@ -206,41 +184,41 @@ static const GrStencilSettings gInvUserToClipRDiff = {
// this one only works if used right after stencil clip was cleared.
// Our GrClip doesn't allow midstream replace ops.
-static const GrStencilSettings gReplaceClip = {
- kReplace_StencilOp, kReplace_StencilOp,
- kReplace_StencilOp, kReplace_StencilOp,
- kAlways_StencilFunc, kAlways_StencilFunc,
- 0xffff, 0xffff,
- 0x0000, 0x0000, // set clip bit
- 0x0000, 0x0000 // set clipBit
-};
-
-static const GrStencilSettings gUnionClip = {
- kReplace_StencilOp, kReplace_StencilOp,
- kReplace_StencilOp, kReplace_StencilOp,
- kAlways_StencilFunc, kAlways_StencilFunc,
- 0xffff, 0xffff,
- 0x0000, 0x0000, // set clip bit
- 0x0000, 0x0000 // set clip bit
-};
-
-static const GrStencilSettings gXorClip = {
- kInvert_StencilOp, kInvert_StencilOp,
- kInvert_StencilOp, kInvert_StencilOp,
- kAlways_StencilFunc, kAlways_StencilFunc,
- 0xffff, 0xffff,
- 0x0000, 0x0000,
- 0x0000, 0x0000 // set clip bit
-};
-
-static const GrStencilSettings gDiffClip = {
- kZero_StencilOp, kZero_StencilOp,
- kZero_StencilOp, kZero_StencilOp,
- kAlways_StencilFunc, kAlways_StencilFunc,
- 0xffff, 0xffff,
- 0x0000, 0x0000,
- 0x0000, 0x0000 // set clip bit
-};
+GR_STATIC_CONST_SAME_STENCIL(gReplaceClip,
+ kReplace_StencilOp,
+ kReplace_StencilOp,
+ kAlways_StencilFunc,
+ 0xffff,
+ 0x0000, // set clip bit
+ 0x0000 // set clipBit
+);
+
+GR_STATIC_CONST_SAME_STENCIL(gUnionClip,
+ kReplace_StencilOp,
+ kReplace_StencilOp,
+ kAlways_StencilFunc,
+ 0xffff,
+ 0x0000, // set clip bit
+ 0x0000 // set clip bit
+);
+
+GR_STATIC_CONST_SAME_STENCIL(gXorClip,
+ kInvert_StencilOp,
+ kInvert_StencilOp,
+ kAlways_StencilFunc,
+ 0xffff,
+ 0x0000,
+ 0x0000 // set clip bit
+);
+
+GR_STATIC_CONST_SAME_STENCIL(gDiffClip,
+ kZero_StencilOp,
+ kZero_StencilOp,
+ kAlways_StencilFunc,
+ 0xffff,
+ 0x0000,
+ 0x0000 // set clip bit
+);
bool GrStencilSettings::GetClipPasses(GrSetOp op,
bool canBeDirect,
diff --git a/src/gpu/GrStencil.h b/src/gpu/GrStencil.h
index 207a8316e8..78a156f9ea 100644
--- a/src/gpu/GrStencil.h
+++ b/src/gpu/GrStencil.h
@@ -85,9 +85,15 @@ enum GrStencilOp {
};
/**
- * Struct representing stencil state.
+ * GrStencilState needs to be a class with accessors and setters so that it
+ * can maintain flags related to its current state. However, we also want to
+ * be able to declare pre-made stencil settings at compile time (without
+ * inserting static initializer code). So all the data members are in this
+ * struct. A macro defined after the class can be used to jam an instance of
+ * this struct that is created from an initializer list into a
+ * GrStencilSettings. (We hang our heads in shame.)
*/
-struct GrStencilSettings {
+struct GrStencilSettingsStruct {
GrStencilOp fFrontPassOp : 8; // op to perform when front faces pass
GrStencilOp fBackPassOp : 8; // op to perform when back faces pass
GrStencilOp fFrontFailOp : 8; // op to perform when front faces fail
@@ -100,7 +106,14 @@ struct GrStencilSettings {
unsigned short fBackFuncRef; // reference value for back face test
unsigned short fFrontWriteMask; // stencil write mask for front faces
unsigned short fBackWriteMask; // stencil write mask for back faces
+};
+
+/**
+ * Class representing stencil state.
+ */
+class GrStencilSettings : private GrStencilSettingsStruct {
+public:
bool operator == (const GrStencilSettings& s) const {
// make sure this is tightly packed (< 4B padding).
GR_STATIC_ASSERT(sizeof(GrStencilSettings) / 4 ==
@@ -119,6 +132,32 @@ struct GrStencilSettings {
return *this;
}
+ GrStencilOp frontPassOp() const { return fFrontPassOp; }
+ GrStencilOp backPassOp() const { return fBackPassOp; }
+ GrStencilOp frontFailOp() const { return fFrontFailOp; }
+ GrStencilOp backFailOp() const { return fBackFailOp; }
+ GrStencilFunc frontFunc() const { return fFrontFunc; }
+ GrStencilFunc backFunc() const { return fBackFunc; }
+ unsigned short frontFuncMask() const { return fFrontFuncMask; }
+ unsigned short backFuncMask() const { return fBackFuncMask; }
+ unsigned short frontFuncRef() const { return fFrontFuncRef; }
+ unsigned short backFuncRef() const { return fBackFuncRef; }
+ unsigned short frontWriteMask() const {return fFrontWriteMask; }
+ unsigned short backWriteMask() const { return fBackWriteMask; }
+
+ void setFrontPassOp(GrStencilOp op) { fFrontPassOp = op; }
+ void setBackPassOp(GrStencilOp op) { fBackPassOp = op; }
+ void setFrontFailOp(GrStencilOp op) {fFrontFailOp = op; }
+ void setBackFailOp(GrStencilOp op) { fBackFailOp = op; }
+ void setFrontFunc(GrStencilFunc func) { fFrontFunc = func; }
+ void setBackFunc(GrStencilFunc func) { fBackFunc = func; }
+ void setFrontFuncMask(unsigned short mask) { fFrontFuncMask = mask; }
+ void setBackFuncMask(unsigned short mask) { fBackFuncMask = mask; }
+ void setFrontFuncRef(unsigned short ref) { fFrontFuncRef = ref; }
+ void setBackFuncRef(unsigned short ref) { fBackFuncRef = ref; }
+ void setFrontWriteMask(unsigned short writeMask) { fFrontWriteMask = writeMask; }
+ void setBackWriteMask(unsigned short writeMask) { fBackWriteMask = writeMask; }
+
void setSame(GrStencilOp passOp,
GrStencilOp failOp,
GrStencilFunc func,
@@ -139,10 +178,10 @@ struct GrStencilSettings {
fBackWriteMask = writeMask;
}
- // canonical value for disabled stenciling
- static const GrStencilSettings gDisabled;
void setDisabled() {
- *this = gDisabled;
+ memset(this, 0, sizeof(*this));
+ GR_STATIC_ASSERT(0 == kKeep_StencilOp);
+ GR_STATIC_ASSERT(0 == kAlways_StencilFunc);
}
bool isDisabled() const {
return kKeep_StencilOp == fFrontPassOp &&
@@ -206,4 +245,29 @@ private:
GrStencilSettings settings[kMaxStencilClipPasses]);
};
+GR_STATIC_ASSERT(sizeof(GrStencilSettingsStruct) == sizeof(GrStencilSettings));
+
+#define GR_STATIC_CONST_STENCIL(NAME, \
+ FRONT_PASS_OP, BACK_PASS_OP, \
+ FRONT_FAIL_OP, BACK_FAIL_OP, \
+ FRONT_FUNC, BACK_FUNC, \
+ FRONT_MASK, BACK_MASK, \
+ FRONT_REF, BACK_REF, \
+ FRONT_WRITE_MASK, BACK_WRITE_MASK) \
+ static const GrStencilSettingsStruct NAME ## _STRUCT = { \
+ (FRONT_PASS_OP), (BACK_PASS_OP), \
+ (FRONT_FAIL_OP), (BACK_FAIL_OP), \
+ (FRONT_FUNC), (BACK_FUNC), \
+ (FRONT_MASK), (BACK_MASK), \
+ (FRONT_REF), (BACK_REF), \
+ (FRONT_WRITE_MASK), (BACK_WRITE_MASK) \
+ }; \
+ static const GrStencilSettings& NAME = \
+ *static_cast<const GrStencilSettings*>(&(NAME ## _STRUCT))
#endif
+
+#define GR_STATIC_CONST_SAME_STENCIL(NAME, \
+ PASS_OP, FAIL_OP, FUNC, MASK, REF, WRITE_MASK) \
+ GR_STATIC_CONST_STENCIL(NAME, (PASS_OP), (PASS_OP), (FAIL_OP), \
+ (FAIL_OP), (FUNC), (FUNC), (MASK), (MASK), (REF), (REF), (WRITE_MASK), \
+ (WRITE_MASK))