From 6b2445eb154d71517b1ed6811f3f77eec592963a Mon Sep 17 00:00:00 2001 From: "bsalomon@google.com" Date: Thu, 15 Dec 2011 19:47:46 +0000 Subject: 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 --- src/gpu/GrStencil.h | 74 +++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 69 insertions(+), 5 deletions(-) (limited to 'src/gpu/GrStencil.h') 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(&(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)) -- cgit v1.2.3