Index: src/gpu/GrStencil.h |
diff --git a/src/gpu/GrStencil.h b/src/gpu/GrStencil.h |
index fc452dab1d60d8ba59efa6fe40398b18bcbbb606..075eb1ef1d2af44e092ae5b48a987fd92d3993f2 100644 |
--- a/src/gpu/GrStencil.h |
+++ b/src/gpu/GrStencil.h |
@@ -64,13 +64,14 @@ enum GrStencilFunc { |
kLEqualIfInClip_StencilFunc, |
kNonZeroIfInClip_StencilFunc, // this one forces the ref to be 0 |
- // counts |
- kStencilFuncCount, |
- kClipStencilFuncCount = kNonZeroIfInClip_StencilFunc - |
- kAlwaysIfInClip_StencilFunc + 1, |
- kBasicStencilFuncCount = kStencilFuncCount - kClipStencilFuncCount |
+ kLast_StencilFunc = kNonZeroIfInClip_StencilFunc |
}; |
+static const int kStencilFuncCnt = kLast_StencilFunc + 1; |
+static const int kClipStencilFuncCnt = |
+ kNonZeroIfInClip_StencilFunc - kAlwaysIfInClip_StencilFunc + 1; |
+static const int kBasicStencilFuncCnt = kStencilFuncCnt - kClipStencilFuncCnt; |
+ |
/** |
* Operations to perform based on whether stencil test passed failed. |
*/ |
@@ -83,98 +84,60 @@ enum GrStencilOp { |
kDecClamp_StencilOp, // decrement and clamp at 0 |
kZero_StencilOp, // zero stencil bits |
kInvert_StencilOp, // invert stencil bits |
- |
- kStencilOpCount |
-}; |
- |
-enum GrStencilFlags { |
- kIsDisabled_StencilFlag = 0x1, |
- kNotDisabled_StencilFlag = 0x2, |
- kDoesWrite_StencilFlag = 0x4, |
- kDoesNotWrite_StencilFlag = 0x8, |
+ kLast_StencilOp = kInvert_StencilOp |
}; |
- |
-/** |
- * 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 GrStencilSettingsStruct { |
- uint8_t fPassOps[2]; // op to perform when faces pass (GrStencilOp) |
- uint8_t fFailOps[2]; // op to perform when faces fail (GrStencilOp) |
- uint8_t fFuncs[2]; // test function for faces (GrStencilFunc) |
- uint8_t fPad0; |
- uint8_t fPad1; |
- uint16_t fFuncMasks[2]; // mask for face tests |
- uint16_t fFuncRefs[2]; // reference values for face tests |
- uint16_t fWriteMasks[2]; // stencil write masks |
- mutable uint32_t fFlags; |
-}; |
-// We rely on this being packed and aligned (memcmp'ed and memcpy'ed) |
-GR_STATIC_ASSERT(sizeof(GrStencilSettingsStruct) % 4 == 0); |
-GR_STATIC_ASSERT(sizeof(GrStencilSettingsStruct) == |
- 4*sizeof(uint8_t) + // ops |
- 2*sizeof(uint8_t) + // funcs |
- 2*sizeof(uint8_t) + // pads |
- 2*sizeof(uint16_t) + // func masks |
- 2*sizeof(uint16_t) + // ref values |
- 2*sizeof(uint16_t) + // 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)) |
+static const int kStencilOpCnt = kLast_StencilOp + 1; |
/** |
* Class representing stencil state. |
*/ |
-class GrStencilSettings : private GrStencilSettingsStruct { |
- |
+class GrStencilSettings { |
public: |
enum Face { |
kFront_Face = 0, |
kBack_Face = 1, |
}; |
+ constexpr GrStencilSettings(GrStencilOp passOp, |
+ GrStencilOp failOp, |
+ GrStencilFunc func, |
+ unsigned short funcMask, |
+ unsigned short funcRef, |
+ unsigned short writeMask) |
+ : fPassOps{(uint8_t)passOp, (uint8_t)passOp} |
+ , fFailOps{(uint8_t)failOp, (uint8_t)failOp} |
+ , fFuncs{(uint8_t)func, (uint8_t)func} |
+ , fPad0(0) |
+ , fPad1(0) |
+ , fFuncMasks{funcMask, funcMask} |
+ , fFuncRefs{funcRef, funcRef} |
+ , fWriteMasks{writeMask, writeMask} |
+ , fFlags(ComputeFlags(passOp, passOp, |
+ failOp, failOp, |
+ func, func, |
+ writeMask, writeMask)) { |
+ } |
+ |
+ constexpr GrStencilSettings(GrStencilOp frontPassOp, GrStencilOp backPassOp, |
+ GrStencilOp frontFailOp, GrStencilOp backFailOp, |
+ GrStencilFunc frontFunc, GrStencilFunc backFunc, |
+ uint16_t frontFuncMask, uint16_t backFuncMask, |
+ uint16_t frontFuncRef, uint16_t backFuncRef, |
+ uint16_t frontWriteMask, uint16_t backWriteMask) |
+ : fPassOps{(uint8_t)frontPassOp, (uint8_t)backPassOp} |
+ , fFailOps{(uint8_t)frontFailOp, (uint8_t)backFailOp} |
+ , fFuncs{(uint8_t)frontFunc, (uint8_t)backFunc} |
+ , fPad0(0) |
+ , fPad1(0) |
+ , fFuncMasks{frontFuncMask, backFuncMask} |
+ , fFuncRefs{frontFuncRef, backFuncRef} |
+ , fWriteMasks{frontWriteMask, backWriteMask} |
+ , fFlags(ComputeFlags(frontPassOp, backPassOp, |
+ frontFailOp, backFailOp, |
+ frontFunc, backFunc, |
+ frontWriteMask, backWriteMask)) { |
+ } |
+ |
GrStencilSettings() { |
fPad0 = fPad1 = 0; |
this->setDisabled(); |
@@ -204,21 +167,6 @@ public: |
fFlags = 0; |
} |
- void setSame(GrStencilOp passOp, |
- GrStencilOp failOp, |
- GrStencilFunc func, |
- unsigned short funcMask, |
- unsigned short funcRef, |
- unsigned short writeMask) { |
- fPassOps[kFront_Face] = fPassOps[kBack_Face] = passOp; |
- fFailOps[kFront_Face] = fFailOps[kBack_Face] = failOp; |
- fFuncs[kFront_Face] = fFuncs[kBack_Face] = func; |
- fFuncMasks[kFront_Face] = fFuncMasks[kBack_Face] = funcMask; |
- fFuncRefs[kFront_Face] = fFuncRefs[kBack_Face] = funcRef; |
- fWriteMasks[kFront_Face] = fWriteMasks[kBack_Face] = writeMask; |
- fFlags = 0; |
- } |
- |
void setDisabled() { |
memset(this, 0, sizeof(*this)); |
GR_STATIC_ASSERT(0 == kKeep_StencilOp); |
@@ -253,10 +201,7 @@ public: |
if (fFlags & kNotDisabled_StencilFlag) { |
return false; |
} |
- bool disabled = GR_STENCIL_SETTINGS_IS_DISABLED( |
- fPassOps[kFront_Face], fPassOps[kBack_Face], |
- fFailOps[kFront_Face], fFailOps[kBack_Face], |
- fFuncs[kFront_Face], fFuncs[kBack_Face]); |
+ bool disabled = this->computeIsDisabled(); |
fFlags |= disabled ? kIsDisabled_StencilFlag : kNotDisabled_StencilFlag; |
return disabled; |
} |
@@ -268,27 +213,22 @@ public: |
if (fFlags & kDoesNotWrite_StencilFlag) { |
return false; |
} |
- bool writes = GR_STENCIL_SETTINGS_DOES_WRITE( |
- fPassOps[kFront_Face], fPassOps[kBack_Face], |
- fFailOps[kFront_Face], fFailOps[kBack_Face], |
- fFuncs[kFront_Face], fFuncs[kBack_Face]); |
+ bool writes = this->computeDoesWrite(); |
fFlags |= writes ? kDoesWrite_StencilFlag : kDoesNotWrite_StencilFlag; |
return writes; |
} |
void invalidate() { |
// write an illegal value to the first member |
- fPassOps[0] = kStencilOpCount; |
+ fPassOps[0] = kStencilOpCnt; |
fFlags = 0; |
} |
- bool isValid() const { |
- return fPassOps[0] < kStencilOpCount; |
- } |
+ bool isValid() const { return fPassOps[0] < kStencilOpCnt; } |
void genKey(GrProcessorKeyBuilder* b) const; |
- bool operator == (const GrStencilSettings& s) const { |
+ bool operator==(const GrStencilSettings& s) const { |
static const size_t gCompareSize = sizeof(GrStencilSettings) - |
sizeof(fFlags); |
SkASSERT((const char*)&fFlags + sizeof(fFlags) == |
@@ -299,11 +239,11 @@ public: |
return 0 == memcmp(this, &s, gCompareSize); |
} |
- bool operator != (const GrStencilSettings& s) const { |
+ bool operator!=(const GrStencilSettings& s) const { |
return !(*this == s); |
} |
- GrStencilSettings& operator =(const GrStencilSettings& s) { |
+ GrStencilSettings& operator=(const GrStencilSettings& s) { |
memcpy(this, &s, sizeof(GrStencilSettings)); |
return *this; |
} |
@@ -345,58 +285,85 @@ private: |
bool invertedFill, |
int* numPasses, |
GrStencilSettings settings[kMaxStencilClipPasses]); |
-}; |
-GR_STATIC_ASSERT(sizeof(GrStencilSettingsStruct) == sizeof(GrStencilSettings)); |
- |
-#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 STRUCT_NAME = { \ |
- {(FRONT_PASS_OP), (BACK_PASS_OP) }, \ |
- {(FRONT_FAIL_OP), (BACK_FAIL_OP) }, \ |
- {(FRONT_FUNC), (BACK_FUNC) }, \ |
- (0), (0), \ |
- {(FRONT_MASK), (BACK_MASK) }, \ |
- {(FRONT_REF), (BACK_REF) }, \ |
- {(FRONT_WRITE_MASK), (BACK_WRITE_MASK)}, \ |
- GR_STENCIL_SETTINGS_DEFAULT_FLAGS( \ |
- FRONT_PASS_OP, BACK_PASS_OP, FRONT_FAIL_OP, BACK_FAIL_OP, \ |
- FRONT_FUNC, BACK_FUNC) \ |
+ constexpr static bool IsDisabled(GrStencilOp frontPassOp, GrStencilOp backPassOp, |
+ GrStencilOp frontFailOp, GrStencilOp backFailOp, |
+ GrStencilFunc frontFunc, GrStencilFunc backFunc) { |
+ return (((frontPassOp == kKeep_StencilOp && frontFailOp == kKeep_StencilOp)) && |
+ ((backPassOp == kKeep_StencilOp && backFailOp == kKeep_StencilOp)) && |
+ frontFunc == kAlways_StencilFunc && |
+ backFunc == kAlways_StencilFunc); |
+ } |
+ |
+ constexpr static bool DoesWrite(GrStencilOp frontPassOp, GrStencilOp backPassOp, |
+ GrStencilOp frontFailOp, GrStencilOp backFailOp, |
+ GrStencilFunc frontFunc, GrStencilFunc backFunc, |
+ uint16_t frontWriteMask, uint16_t backWriteMask) { |
+ return (0 != (frontWriteMask | backWriteMask)) && |
+ // Can we write due to a front face passing the stencil test? |
+ ((frontFunc != kNever_StencilFunc && frontPassOp != kKeep_StencilOp) || |
+ // Can we write due to a back face passing the stencil test? |
+ (backFunc != kNever_StencilFunc && backPassOp != kKeep_StencilOp) || |
+ // Can we write due to a front face failing the stencil test? |
+ (frontFunc != kAlways_StencilFunc && frontFailOp != kKeep_StencilOp) || |
+ // Can we write due to a back face failing the stencil test? |
+ (backFunc != kAlways_StencilFunc && backFailOp != kKeep_StencilOp)); |
+ } |
+ |
+ constexpr static uint32_t ComputeFlags(GrStencilOp frontPassOp, GrStencilOp backPassOp, |
+ GrStencilOp frontFailOp, GrStencilOp backFailOp, |
+ GrStencilFunc frontFunc, GrStencilFunc backFunc, |
+ uint16_t frontWriteMask, uint16_t backWriteMask) { |
+ return (IsDisabled(frontPassOp, backPassOp, frontFailOp, backFailOp, |
+ frontFunc, backFunc) |
+ ? kIsDisabled_StencilFlag |
+ : kNotDisabled_StencilFlag) | |
+ (DoesWrite(frontPassOp, backPassOp, frontFailOp, backFailOp, |
+ frontFunc, backFunc, frontWriteMask, backWriteMask) |
+ ? kDoesWrite_StencilFlag |
+ : kDoesNotWrite_StencilFlag); |
+ } |
+ |
+ bool computeIsDisabled() const { |
+ return IsDisabled((GrStencilOp) fPassOps[kFront_Face], (GrStencilOp) fPassOps[kBack_Face], |
+ (GrStencilOp) fFailOps[kFront_Face], (GrStencilOp) fFailOps[kBack_Face], |
+ (GrStencilFunc) fFuncs[kFront_Face], (GrStencilFunc) fFuncs[kBack_Face]); |
+ } |
+ bool computeDoesWrite() const { |
+ return DoesWrite((GrStencilOp)fPassOps[kFront_Face], (GrStencilOp)fPassOps[kBack_Face], |
+ (GrStencilOp)fFailOps[kFront_Face], (GrStencilOp)fFailOps[kBack_Face], |
+ (GrStencilFunc)fFuncs[kFront_Face], (GrStencilFunc)fFuncs[kBack_Face], |
+ fWriteMasks[kFront_Face], fWriteMasks[kBack_Face]); |
+ } |
+ |
+ enum GrStencilFlags { |
+ kIsDisabled_StencilFlag = 0x1, |
+ kNotDisabled_StencilFlag = 0x2, |
+ kDoesWrite_StencilFlag = 0x4, |
+ kDoesNotWrite_StencilFlag = 0x8, |
}; |
-#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 = \ |
- *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)) |
+ uint8_t fPassOps[2]; // op to perform when faces pass (GrStencilOp) |
+ uint8_t fFailOps[2]; // op to perform when faces fail (GrStencilOp) |
+ uint8_t fFuncs[2]; // test function for faces (GrStencilFunc) |
+ uint8_t fPad0; |
+ uint8_t fPad1; |
+ uint16_t fFuncMasks[2]; // mask for face tests |
+ uint16_t fFuncRefs[2]; // reference values for face tests |
+ uint16_t fWriteMasks[2]; // stencil write masks |
+ mutable uint32_t fFlags; |
+ |
+}; |
+ |
+// We rely on this being packed and aligned (memcmp'ed and memcpy'ed) |
+GR_STATIC_ASSERT(sizeof(GrStencilSettings) % 4 == 0); |
+GR_STATIC_ASSERT(sizeof(GrStencilSettings) == |
+ 4*sizeof(uint8_t) + // ops |
+ 2*sizeof(uint8_t) + // funcs |
+ 2*sizeof(uint8_t) + // pads |
+ 2*sizeof(uint16_t) + // func masks |
+ 2*sizeof(uint16_t) + // ref values |
+ 2*sizeof(uint16_t) + // write masks |
+ sizeof(uint32_t)); // flags |
#endif |