aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/gpu/GrStencil.h
diff options
context:
space:
mode:
authorGravatar digit@google.com <digit@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2012-02-16 22:03:26 +0000
committerGravatar digit@google.com <digit@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2012-02-16 22:03:26 +0000
commit9b482c4d3312e33f852407889bbb86980936824c (patch)
tree4f7a3750efc25504f930ea0a5f8e9711d747fc67 /src/gpu/GrStencil.h
parent128cd221b1d4fc55d0a05362a22cc7a7cc74995d (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.h126
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