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
diff --git a/src/gpu/GrDefaultPathRenderer.cpp b/src/gpu/GrDefaultPathRenderer.cpp
index ebd0cc1..6ea0459 100644
--- a/src/gpu/GrDefaultPathRenderer.cpp
+++ b/src/gpu/GrDefaultPathRenderer.cpp
@@ -41,34 +41,31 @@
 
 ////// 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 @@
 // 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
-};
+GR_STATIC_CONST_SAME_STENCIL(gWindSingleStencilWithWrapInc,
+    kIncWrap_StencilOp,
+    kKeep_StencilOp,
+    kAlwaysIfInClip_StencilFunc,
+    0xffff,
+    0xffff,
+    0xffff);
 
-static const GrStencilSettings gWindColorPass = {
-    kZero_StencilOp,                kZero_StencilOp,
-    kZero_StencilOp,                kZero_StencilOp,
-    kNonZeroIfInClip_StencilFunc,   kNonZeroIfInClip_StencilFunc,
-    0xffff,                         0xffff,
-    0x0000,                         0x0000,
-    0xffff,                         0xffff
-};
+GR_STATIC_CONST_SAME_STENCIL(gWindSingleStencilWithWrapDec,
+    kDecWrap_StencilOp,
+    kKeep_StencilOp,
+    kAlwaysIfInClip_StencilFunc,
+    0xffff,
+    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(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 4a2e5d7..1761345 100644
--- a/src/gpu/GrGpu.cpp
+++ b/src/gpu/GrGpu.cpp
@@ -339,14 +339,14 @@
 ////////////////////////////////////////////////////////////////////////////////
 
 // 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 @@
 
                 // 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 11f5083..0836ec8 100644
--- a/src/gpu/GrGpu.h
+++ b/src/gpu/GrGpu.h
@@ -355,8 +355,7 @@
 
     // 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 f266368..339133fa 100644
--- a/src/gpu/GrGpuGL.cpp
+++ b/src/gpu/GrGpuGL.cpp
@@ -1826,14 +1826,14 @@
             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 @@
                 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 @@
                 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 @@
                 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 @@
                                             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 81b3b8d..6624942 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 @@
 // 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
-};
+GR_STATIC_CONST_SAME_STENCIL(gUserToClipXorPass0,
+    kInvert_StencilOp,
+    kKeep_StencilOp,
+    kEqual_StencilFunc,
+    0xffff,           // unset clip bit
+    0x0000,
+    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
-};
+GR_STATIC_CONST_SAME_STENCIL(gUserToClipXorPass1,
+    kReplace_StencilOp,
+    kZero_StencilOp,
+    kGreater_StencilFunc,
+    0xffff,
+    0x0000,          // set clip bit
+    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
-};
+GR_STATIC_CONST_SAME_STENCIL(gInvUserToClipXorPass0,
+    kInvert_StencilOp,
+    kKeep_StencilOp,
+    kEqual_StencilFunc,
+    0xffff,           // unset clip bit
+    0x0000,
+    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(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
-};
+GR_STATIC_CONST_SAME_STENCIL(gUserToClipRDiffPass0,
+    kInvert_StencilOp,
+    kZero_StencilOp,
+    kLess_StencilFunc,
+    0xffff,         // unset clip bit
+    0x0000,         // set clip bit
+    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
-};
+GR_STATIC_CONST_SAME_STENCIL(gUserToClipRDiffPass1,
+    kReplace_StencilOp,
+    kZero_StencilOp,
+    kEqual_StencilFunc,
+    0x0000,          // set clip bit
+    0x0000,          // set clip bit
+    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(gInvUserToClipRDiff,
+    kInvert_StencilOp,
+    kZero_StencilOp,
+    kEqual_StencilFunc,
+    0xffff,
+    0x0000,
+    0x0000           // set clip bit
+);
 ///////
 // Direct to Stencil
 
@@ -206,41 +184,41 @@
 
 // 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
-};
+GR_STATIC_CONST_SAME_STENCIL(gReplaceClip,
+    kReplace_StencilOp,
+    kReplace_StencilOp,
+    kAlways_StencilFunc,
+    0xffff,
+    0x0000,           // set clip bit
+    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
-};
+GR_STATIC_CONST_SAME_STENCIL(gUnionClip,
+    kReplace_StencilOp,
+    kReplace_StencilOp,
+    kAlways_StencilFunc,
+    0xffff,
+    0x0000,           // set clip bit
+    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
-};
+GR_STATIC_CONST_SAME_STENCIL(gXorClip,
+    kInvert_StencilOp,
+    kInvert_StencilOp,
+    kAlways_StencilFunc,
+    0xffff,
+    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(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 207a831..78a156f 100644
--- a/src/gpu/GrStencil.h
+++ b/src/gpu/GrStencil.h
@@ -85,9 +85,15 @@
 };
 
 /**
- * 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 @@
     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 @@
         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 @@
         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 @@
                               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))