diff options
author | 2012-02-16 22:03:26 +0000 | |
---|---|---|
committer | 2012-02-16 22:03:26 +0000 | |
commit | 9b482c4d3312e33f852407889bbb86980936824c (patch) | |
tree | 4f7a3750efc25504f930ea0a5f8e9711d747fc67 /src/gpu/GrStencil.h | |
parent | 128cd221b1d4fc55d0a05362a22cc7a7cc74995d (diff) |
Remove on static initializer in GrGpu.cpp
This is another go for the patch that was initially
submitted at http://codereview.appspot.com/5504073/ but
crashed the 'gm' unit test.
A problem with the previous implementation is that the
GrStencilSettings ::isDisabled() and ::doesWrite() methods can
modify the object's fFlags member if it is 0, and this will
crash at runtime when doing this for a static constant
object/structure.
I'm not sure why this wasn't triggered previously.
We solve the issue by modifying the implementation of
GR_STATIC_CONST_STENCIL and GR_STATIC_CONST_STENCIL macros to
compute the correct default values for fFlags (which prevents
any member modifications in the above methods).
This requires moving the definition of the disabled/write flags
out of the GrStencilSettings class definition's private section.
Note that the flags are renamed to avoid any confusion and
conflicts, i.e.:
SkIsDisabled_Flag -> SkIsDisabled_StencilFlag
SkNotDisabled_Flag -> SkNotDisabled_StencilFlag
...
Review URL: https://codereview.appspot.com/5616051
git-svn-id: http://skia.googlecode.com/svn/trunk@3214 2bbb7eff-a529-9590-31e7-b0007b416f81
Diffstat (limited to 'src/gpu/GrStencil.h')
-rw-r--r-- | src/gpu/GrStencil.h | 126 |
1 files changed, 92 insertions, 34 deletions
diff --git a/src/gpu/GrStencil.h b/src/gpu/GrStencil.h index ae8184029f..143e52509a 100644 --- a/src/gpu/GrStencil.h +++ b/src/gpu/GrStencil.h @@ -84,6 +84,13 @@ enum GrStencilOp { kStencilOpCount }; +enum GrStencilFlags { + kIsDisabled_StencilFlag = 0x1, + kNotDisabled_StencilFlag = 0x2, + kDoesWrite_StencilFlag = 0x4, + kDoesNotWrite_StencilFlag = 0x8, +}; + /** * 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 @@ -121,6 +128,45 @@ GR_STATIC_ASSERT(sizeof(GrStencilSettingsStruct) == 2*sizeof(unsigned short) + // write masks sizeof(uint32_t)); // flags +// This macro is used to compute the GrStencilSettingsStructs flags +// associated to disabling. It is used both to define constant structure +// initializers and inside GrStencilSettings::isDisabled() +// +#define GR_STENCIL_SETTINGS_IS_DISABLED( \ + FRONT_PASS_OP, BACK_PASS_OP, \ + FRONT_FAIL_OP, BACK_FAIL_OP, \ + FRONT_FUNC, BACK_FUNC) \ + ((FRONT_PASS_OP) == kKeep_StencilOp && \ + (BACK_PASS_OP) == kKeep_StencilOp && \ + (FRONT_FAIL_OP) == kKeep_StencilOp && \ + (BACK_FAIL_OP) == kKeep_StencilOp && \ + (FRONT_FUNC) == kAlways_StencilFunc && \ + (BACK_FUNC) == kAlways_StencilFunc) + +#define GR_STENCIL_SETTINGS_DOES_WRITE( \ + FRONT_PASS_OP, BACK_PASS_OP, \ + FRONT_FAIL_OP, BACK_FAIL_OP, \ + FRONT_FUNC, BACK_FUNC) \ + (!(((FRONT_FUNC) == kNever_StencilFunc || \ + (FRONT_PASS_OP) == kKeep_StencilOp) && \ + ((BACK_FUNC) == kNever_StencilFunc || \ + (BACK_PASS_OP) == kKeep_StencilOp) && \ + ((FRONT_FUNC) == kAlways_StencilFunc || \ + (FRONT_FAIL_OP) == kKeep_StencilOp) && \ + ((BACK_FUNC) == kAlways_StencilFunc || \ + (BACK_FAIL_OP) == kKeep_StencilOp))) + +#define GR_STENCIL_SETTINGS_DEFAULT_FLAGS( \ + FRONT_PASS_OP, BACK_PASS_OP, \ + FRONT_FAIL_OP, BACK_FAIL_OP, \ + FRONT_FUNC, BACK_FUNC) \ + ((GR_STENCIL_SETTINGS_IS_DISABLED(FRONT_PASS_OP,BACK_PASS_OP, \ + FRONT_FAIL_OP,BACK_FAIL_OP,FRONT_FUNC,BACK_FUNC) ? \ + kIsDisabled_StencilFlag : kNotDisabled_StencilFlag) | \ + (GR_STENCIL_SETTINGS_DOES_WRITE(FRONT_PASS_OP,BACK_PASS_OP, \ + FRONT_FAIL_OP,BACK_FAIL_OP,FRONT_FUNC,BACK_FUNC) ? \ + kDoesWrite_StencilFlag : kDoesNotWrite_StencilFlag)) + /** * Class representing stencil state. */ @@ -183,42 +229,36 @@ public: memset(this, 0, sizeof(*this)); GR_STATIC_ASSERT(0 == kKeep_StencilOp); GR_STATIC_ASSERT(0 == kAlways_StencilFunc); - fFlags = kIsDisabled_Flag | kDoesNotWrite_Flag; + fFlags = kIsDisabled_StencilFlag | kDoesNotWrite_StencilFlag; } bool isDisabled() const { - if (fFlags & kIsDisabled_Flag) { + if (fFlags & kIsDisabled_StencilFlag) { return true; } - if (fFlags & kNotDisabled_Flag) { + if (fFlags & kNotDisabled_StencilFlag) { return false; } - bool disabled = kKeep_StencilOp == fFrontPassOp && - kKeep_StencilOp == fBackPassOp && - kKeep_StencilOp == fFrontFailOp && - kKeep_StencilOp == fBackFailOp && - kAlways_StencilFunc == fFrontFunc && - kAlways_StencilFunc == fBackFunc; - fFlags |= disabled ? kIsDisabled_Flag : kNotDisabled_Flag; + bool disabled = GR_STENCIL_SETTINGS_IS_DISABLED( + fFrontPassOp, fBackPassOp, + fFrontFailOp, fBackFailOp, + fFrontFunc ,fBackFunc); + fFlags |= disabled ? kIsDisabled_StencilFlag : kNotDisabled_StencilFlag; return disabled; } bool doesWrite() const { - if (fFlags & kDoesWrite_Flag) { + if (fFlags & kDoesWrite_StencilFlag) { return true; } - if (fFlags & kDoesNotWrite_Flag) { + if (fFlags & kDoesNotWrite_StencilFlag) { return false; } - bool writes = !((kNever_StencilFunc == fFrontFunc || - kKeep_StencilOp == fFrontPassOp) && - (kNever_StencilFunc == fBackFunc || - kKeep_StencilOp == fBackPassOp) && - (kAlways_StencilFunc == fFrontFunc || - kKeep_StencilOp == fFrontFailOp) && - (kAlways_StencilFunc == fBackFunc || - kKeep_StencilOp == fBackFailOp)); - fFlags |= writes ? kDoesWrite_Flag : kDoesNotWrite_Flag; + bool writes = GR_STENCIL_SETTINGS_DOES_WRITE( + fFrontPassOp, fBackPassOp, + fFrontFailOp, fBackFailOp, + fFrontFunc, fBackFunc); + fFlags |= writes ? kDoesWrite_StencilFlag : kDoesNotWrite_StencilFlag; return writes; } @@ -251,13 +291,6 @@ public: private: friend class GrGpu; enum { - kIsDisabled_Flag = 0x1, - kNotDisabled_Flag = 0x2, - kDoesWrite_Flag = 0x4, - kDoesNotWrite_Flag = 0x8, - }; - - enum { kMaxStencilClipPasses = 2 // maximum number of passes to add a clip // element to the stencil buffer. }; @@ -295,14 +328,14 @@ private: GR_STATIC_ASSERT(sizeof(GrStencilSettingsStruct) == sizeof(GrStencilSettings)); -#define GR_STATIC_CONST_STENCIL(NAME, \ +#define GR_STATIC_CONST_STENCIL_STRUCT(STRUCT_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 = { \ + static const GrStencilSettingsStruct STRUCT_NAME = { \ (FRONT_PASS_OP), (BACK_PASS_OP), \ (FRONT_FAIL_OP), (BACK_FAIL_OP), \ (FRONT_FUNC), (BACK_FUNC), \ @@ -310,14 +343,39 @@ GR_STATIC_ASSERT(sizeof(GrStencilSettingsStruct) == sizeof(GrStencilSettings)); (FRONT_MASK), (BACK_MASK), \ (FRONT_REF), (BACK_REF), \ (FRONT_WRITE_MASK), (BACK_WRITE_MASK), \ - 0 \ - }; \ + GR_STENCIL_SETTINGS_DEFAULT_FLAGS( \ + FRONT_PASS_OP, BACK_PASS_OP, FRONT_FAIL_OP, BACK_FAIL_OP, \ + FRONT_FUNC, BACK_FUNC) \ + }; + +#define GR_CONST_STENCIL_SETTINGS_PTR_FROM_STRUCT_PTR(STRUCT_PTR) \ + reinterpret_cast<const GrStencilSettings*>(STRUCT_PTR) + +#define GR_STATIC_CONST_SAME_STENCIL_STRUCT(STRUCT_NAME, \ + PASS_OP, FAIL_OP, FUNC, MASK, REF, WRITE_MASK) \ + GR_STATIC_CONST_STENCIL_STRUCT(STRUCT_NAME, (PASS_OP), (PASS_OP), \ + (FAIL_OP),(FAIL_OP), (FUNC), (FUNC), (MASK), (MASK), (REF), (REF), \ + (WRITE_MASK),(WRITE_MASK)) + +#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) \ + GR_STATIC_CONST_STENCIL_STRUCT(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 = \ - *reinterpret_cast<const GrStencilSettings*>(&(NAME ## _STRUCT)) -#endif + *GR_CONST_STENCIL_SETTINGS_PTR_FROM_STRUCT_PTR(&(NAME ## _STRUCT)); + #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)) + +#endif |