OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2011 Google Inc. | 2 * Copyright 2011 Google Inc. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
6 */ | 6 */ |
7 | 7 |
8 | 8 |
9 #ifndef GrStencil_DEFINED | 9 #ifndef GrStencil_DEFINED |
10 #define GrStencil_DEFINED | 10 #define GrStencil_DEFINED |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
57 // clip in addition to the GrDrawTarget | 57 // clip in addition to the GrDrawTarget |
58 // client's stencil bits. | 58 // client's stencil bits. |
59 | 59 |
60 // pass if inside the clip | 60 // pass if inside the clip |
61 kAlwaysIfInClip_StencilFunc, | 61 kAlwaysIfInClip_StencilFunc, |
62 kEqualIfInClip_StencilFunc, | 62 kEqualIfInClip_StencilFunc, |
63 kLessIfInClip_StencilFunc, | 63 kLessIfInClip_StencilFunc, |
64 kLEqualIfInClip_StencilFunc, | 64 kLEqualIfInClip_StencilFunc, |
65 kNonZeroIfInClip_StencilFunc, // this one forces the ref to be 0 | 65 kNonZeroIfInClip_StencilFunc, // this one forces the ref to be 0 |
66 | 66 |
67 // counts | 67 kLast_StencilFunc = kNonZeroIfInClip_StencilFunc |
68 kStencilFuncCount, | |
69 kClipStencilFuncCount = kNonZeroIfInClip_StencilFunc - | |
70 kAlwaysIfInClip_StencilFunc + 1, | |
71 kBasicStencilFuncCount = kStencilFuncCount - kClipStencilFuncCount | |
72 }; | 68 }; |
73 | 69 |
| 70 static const int kStencilFuncCnt = kLast_StencilFunc + 1; |
| 71 static const int kClipStencilFuncCnt = |
| 72 kNonZeroIfInClip_StencilFunc - kAlwaysIfInClip_StencilFunc + 1; |
| 73 static const int kBasicStencilFuncCnt = kStencilFuncCnt - kClipStencilFuncCnt; |
| 74 |
74 /** | 75 /** |
75 * Operations to perform based on whether stencil test passed failed. | 76 * Operations to perform based on whether stencil test passed failed. |
76 */ | 77 */ |
77 enum GrStencilOp { | 78 enum GrStencilOp { |
78 kKeep_StencilOp = 0, // preserve existing stencil value | 79 kKeep_StencilOp = 0, // preserve existing stencil value |
79 kReplace_StencilOp, // replace with reference value from stencl test | 80 kReplace_StencilOp, // replace with reference value from stencl test |
80 kIncWrap_StencilOp, // increment and wrap at max | 81 kIncWrap_StencilOp, // increment and wrap at max |
81 kIncClamp_StencilOp, // increment and clamp at max | 82 kIncClamp_StencilOp, // increment and clamp at max |
82 kDecWrap_StencilOp, // decrement and wrap at 0 | 83 kDecWrap_StencilOp, // decrement and wrap at 0 |
83 kDecClamp_StencilOp, // decrement and clamp at 0 | 84 kDecClamp_StencilOp, // decrement and clamp at 0 |
84 kZero_StencilOp, // zero stencil bits | 85 kZero_StencilOp, // zero stencil bits |
85 kInvert_StencilOp, // invert stencil bits | 86 kInvert_StencilOp, // invert stencil bits |
86 | 87 kLast_StencilOp = kInvert_StencilOp |
87 kStencilOpCount | |
88 }; | 88 }; |
89 | 89 static const int kStencilOpCnt = kLast_StencilOp + 1; |
90 enum GrStencilFlags { | |
91 kIsDisabled_StencilFlag = 0x1, | |
92 kNotDisabled_StencilFlag = 0x2, | |
93 kDoesWrite_StencilFlag = 0x4, | |
94 kDoesNotWrite_StencilFlag = 0x8, | |
95 }; | |
96 | |
97 /** | |
98 * GrStencilState needs to be a class with accessors and setters so that it | |
99 * can maintain flags related to its current state. However, we also want to | |
100 * be able to declare pre-made stencil settings at compile time (without | |
101 * inserting static initializer code). So all the data members are in this | |
102 * struct. A macro defined after the class can be used to jam an instance of | |
103 * this struct that is created from an initializer list into a | |
104 * GrStencilSettings. (We hang our heads in shame.) | |
105 */ | |
106 struct GrStencilSettingsStruct { | |
107 uint8_t fPassOps[2]; // op to perform when faces pass (GrStencilOp) | |
108 uint8_t fFailOps[2]; // op to perform when faces fail (GrStencilOp) | |
109 uint8_t fFuncs[2]; // test function for faces (GrStencilFunc) | |
110 uint8_t fPad0; | |
111 uint8_t fPad1; | |
112 uint16_t fFuncMasks[2]; // mask for face tests | |
113 uint16_t fFuncRefs[2]; // reference values for face tests | |
114 uint16_t fWriteMasks[2]; // stencil write masks | |
115 mutable uint32_t fFlags; | |
116 }; | |
117 // We rely on this being packed and aligned (memcmp'ed and memcpy'ed) | |
118 GR_STATIC_ASSERT(sizeof(GrStencilSettingsStruct) % 4 == 0); | |
119 GR_STATIC_ASSERT(sizeof(GrStencilSettingsStruct) == | |
120 4*sizeof(uint8_t) + // ops | |
121 2*sizeof(uint8_t) + // funcs | |
122 2*sizeof(uint8_t) + // pads | |
123 2*sizeof(uint16_t) + // func masks | |
124 2*sizeof(uint16_t) + // ref values | |
125 2*sizeof(uint16_t) + // write masks | |
126 sizeof(uint32_t)); // flags | |
127 | |
128 // This macro is used to compute the GrStencilSettingsStructs flags | |
129 // associated to disabling. It is used both to define constant structure | |
130 // initializers and inside GrStencilSettings::isDisabled() | |
131 // | |
132 #define GR_STENCIL_SETTINGS_IS_DISABLED( \ | |
133 FRONT_PASS_OP, BACK_PASS_OP, \ | |
134 FRONT_FAIL_OP, BACK_FAIL_OP, \ | |
135 FRONT_FUNC, BACK_FUNC) \ | |
136 ((FRONT_PASS_OP) == kKeep_StencilOp && \ | |
137 (BACK_PASS_OP) == kKeep_StencilOp && \ | |
138 (FRONT_FAIL_OP) == kKeep_StencilOp && \ | |
139 (BACK_FAIL_OP) == kKeep_StencilOp && \ | |
140 (FRONT_FUNC) == kAlways_StencilFunc && \ | |
141 (BACK_FUNC) == kAlways_StencilFunc) | |
142 | |
143 #define GR_STENCIL_SETTINGS_DOES_WRITE( \ | |
144 FRONT_PASS_OP, BACK_PASS_OP, \ | |
145 FRONT_FAIL_OP, BACK_FAIL_OP, \ | |
146 FRONT_FUNC, BACK_FUNC) \ | |
147 (!(((FRONT_FUNC) == kNever_StencilFunc || \ | |
148 (FRONT_PASS_OP) == kKeep_StencilOp) && \ | |
149 ((BACK_FUNC) == kNever_StencilFunc || \ | |
150 (BACK_PASS_OP) == kKeep_StencilOp) && \ | |
151 ((FRONT_FUNC) == kAlways_StencilFunc || \ | |
152 (FRONT_FAIL_OP) == kKeep_StencilOp) && \ | |
153 ((BACK_FUNC) == kAlways_StencilFunc || \ | |
154 (BACK_FAIL_OP) == kKeep_StencilOp))) | |
155 | |
156 #define GR_STENCIL_SETTINGS_DEFAULT_FLAGS( \ | |
157 FRONT_PASS_OP, BACK_PASS_OP, \ | |
158 FRONT_FAIL_OP, BACK_FAIL_OP, \ | |
159 FRONT_FUNC, BACK_FUNC) \ | |
160 ((GR_STENCIL_SETTINGS_IS_DISABLED(FRONT_PASS_OP,BACK_PASS_OP, \ | |
161 FRONT_FAIL_OP,BACK_FAIL_OP,FRONT_FUNC,BACK_FUNC) ? \ | |
162 kIsDisabled_StencilFlag : kNotDisabled_StencilFlag) | \ | |
163 (GR_STENCIL_SETTINGS_DOES_WRITE(FRONT_PASS_OP,BACK_PASS_OP, \ | |
164 FRONT_FAIL_OP,BACK_FAIL_OP,FRONT_FUNC,BACK_FUNC) ? \ | |
165 kDoesWrite_StencilFlag : kDoesNotWrite_StencilFlag)) | |
166 | 90 |
167 /** | 91 /** |
168 * Class representing stencil state. | 92 * Class representing stencil state. |
169 */ | 93 */ |
170 class GrStencilSettings : private GrStencilSettingsStruct { | 94 class GrStencilSettings { |
171 | |
172 public: | 95 public: |
173 enum Face { | 96 enum Face { |
174 kFront_Face = 0, | 97 kFront_Face = 0, |
175 kBack_Face = 1, | 98 kBack_Face = 1, |
176 }; | 99 }; |
177 | 100 |
| 101 constexpr GrStencilSettings(GrStencilOp passOp, |
| 102 GrStencilOp failOp, |
| 103 GrStencilFunc func, |
| 104 unsigned short funcMask, |
| 105 unsigned short funcRef, |
| 106 unsigned short writeMask) |
| 107 : fPassOps{(uint8_t)passOp, (uint8_t)passOp} |
| 108 , fFailOps{(uint8_t)failOp, (uint8_t)failOp} |
| 109 , fFuncs{(uint8_t)func, (uint8_t)func} |
| 110 , fPad0(0) |
| 111 , fPad1(0) |
| 112 , fFuncMasks{funcMask, funcMask} |
| 113 , fFuncRefs{funcRef, funcRef} |
| 114 , fWriteMasks{writeMask, writeMask} |
| 115 , fFlags(ComputeFlags(passOp, passOp, |
| 116 failOp, failOp, |
| 117 func, func, |
| 118 writeMask, writeMask)) { |
| 119 } |
| 120 |
| 121 constexpr GrStencilSettings(GrStencilOp frontPassOp, GrStencilOp backPassOp
, |
| 122 GrStencilOp frontFailOp, GrStencilOp backFailOp
, |
| 123 GrStencilFunc frontFunc, GrStencilFunc backFunc
, |
| 124 uint16_t frontFuncMask, uint16_t backFuncMask, |
| 125 uint16_t frontFuncRef, uint16_t backFuncRef, |
| 126 uint16_t frontWriteMask, uint16_t backWriteMask
) |
| 127 : fPassOps{(uint8_t)frontPassOp, (uint8_t)backPassOp} |
| 128 , fFailOps{(uint8_t)frontFailOp, (uint8_t)backFailOp} |
| 129 , fFuncs{(uint8_t)frontFunc, (uint8_t)backFunc} |
| 130 , fPad0(0) |
| 131 , fPad1(0) |
| 132 , fFuncMasks{frontFuncMask, backFuncMask} |
| 133 , fFuncRefs{frontFuncRef, backFuncRef} |
| 134 , fWriteMasks{frontWriteMask, backWriteMask} |
| 135 , fFlags(ComputeFlags(frontPassOp, backPassOp, |
| 136 frontFailOp, backFailOp, |
| 137 frontFunc, backFunc, |
| 138 frontWriteMask, backWriteMask)) { |
| 139 } |
| 140 |
178 GrStencilSettings() { | 141 GrStencilSettings() { |
179 fPad0 = fPad1 = 0; | 142 fPad0 = fPad1 = 0; |
180 this->setDisabled(); | 143 this->setDisabled(); |
181 } | 144 } |
182 | 145 |
183 GrStencilOp passOp(Face f) const { return static_cast<GrStencilOp>(fPassOps[
f]); } | 146 GrStencilOp passOp(Face f) const { return static_cast<GrStencilOp>(fPassOps[
f]); } |
184 GrStencilOp failOp(Face f) const { return static_cast<GrStencilOp>(fFailOps[
f]); } | 147 GrStencilOp failOp(Face f) const { return static_cast<GrStencilOp>(fFailOps[
f]); } |
185 GrStencilFunc func(Face f) const { return static_cast<GrStencilFunc>(fFuncs[
f]); } | 148 GrStencilFunc func(Face f) const { return static_cast<GrStencilFunc>(fFuncs[
f]); } |
186 uint16_t funcMask(Face f) const { return fFuncMasks[f]; } | 149 uint16_t funcMask(Face f) const { return fFuncMasks[f]; } |
187 uint16_t funcRef(Face f) const { return fFuncRefs[f]; } | 150 uint16_t funcRef(Face f) const { return fFuncRefs[f]; } |
188 uint16_t writeMask(Face f) const { return fWriteMasks[f]; } | 151 uint16_t writeMask(Face f) const { return fWriteMasks[f]; } |
189 | 152 |
190 void setPassOp(Face f, GrStencilOp op) { fPassOps[f] = op; fFlags = 0;} | 153 void setPassOp(Face f, GrStencilOp op) { fPassOps[f] = op; fFlags = 0;} |
191 void setFailOp(Face f, GrStencilOp op) { fFailOps[f] = op; fFlags = 0;} | 154 void setFailOp(Face f, GrStencilOp op) { fFailOps[f] = op; fFlags = 0;} |
192 void setFunc(Face f, GrStencilFunc func) { fFuncs[f] = func; fFlags = 0;} | 155 void setFunc(Face f, GrStencilFunc func) { fFuncs[f] = func; fFlags = 0;} |
193 void setFuncMask(Face f, unsigned short mask) { fFuncMasks[f] = mask; } | 156 void setFuncMask(Face f, unsigned short mask) { fFuncMasks[f] = mask; } |
194 void setFuncRef(Face f, unsigned short ref) { fFuncRefs[f] = ref; } | 157 void setFuncRef(Face f, unsigned short ref) { fFuncRefs[f] = ref; } |
195 void setWriteMask(Face f, unsigned short writeMask) { fWriteMasks[f] = write
Mask; } | 158 void setWriteMask(Face f, unsigned short writeMask) { fWriteMasks[f] = write
Mask; } |
196 | 159 |
197 void copyFrontSettingsToBack() { | 160 void copyFrontSettingsToBack() { |
198 fPassOps[kBack_Face] = fPassOps[kFront_Face]; | 161 fPassOps[kBack_Face] = fPassOps[kFront_Face]; |
199 fFailOps[kBack_Face] = fFailOps[kFront_Face]; | 162 fFailOps[kBack_Face] = fFailOps[kFront_Face]; |
200 fFuncs[kBack_Face] = fFuncs[kFront_Face]; | 163 fFuncs[kBack_Face] = fFuncs[kFront_Face]; |
201 fFuncMasks[kBack_Face] = fFuncMasks[kFront_Face]; | 164 fFuncMasks[kBack_Face] = fFuncMasks[kFront_Face]; |
202 fFuncRefs[kBack_Face] = fFuncRefs[kFront_Face]; | 165 fFuncRefs[kBack_Face] = fFuncRefs[kFront_Face]; |
203 fWriteMasks[kBack_Face] = fWriteMasks[kFront_Face]; | 166 fWriteMasks[kBack_Face] = fWriteMasks[kFront_Face]; |
204 fFlags = 0; | 167 fFlags = 0; |
205 } | 168 } |
206 | 169 |
207 void setSame(GrStencilOp passOp, | |
208 GrStencilOp failOp, | |
209 GrStencilFunc func, | |
210 unsigned short funcMask, | |
211 unsigned short funcRef, | |
212 unsigned short writeMask) { | |
213 fPassOps[kFront_Face] = fPassOps[kBack_Face] = passOp; | |
214 fFailOps[kFront_Face] = fFailOps[kBack_Face] = failOp; | |
215 fFuncs[kFront_Face] = fFuncs[kBack_Face] = func; | |
216 fFuncMasks[kFront_Face] = fFuncMasks[kBack_Face] = funcMask; | |
217 fFuncRefs[kFront_Face] = fFuncRefs[kBack_Face] = funcRef; | |
218 fWriteMasks[kFront_Face] = fWriteMasks[kBack_Face] = writeMask; | |
219 fFlags = 0; | |
220 } | |
221 | |
222 void setDisabled() { | 170 void setDisabled() { |
223 memset(this, 0, sizeof(*this)); | 171 memset(this, 0, sizeof(*this)); |
224 GR_STATIC_ASSERT(0 == kKeep_StencilOp); | 172 GR_STATIC_ASSERT(0 == kKeep_StencilOp); |
225 GR_STATIC_ASSERT(0 == kAlways_StencilFunc); | 173 GR_STATIC_ASSERT(0 == kAlways_StencilFunc); |
226 fFlags = kIsDisabled_StencilFlag | kDoesNotWrite_StencilFlag; | 174 fFlags = kIsDisabled_StencilFlag | kDoesNotWrite_StencilFlag; |
227 } | 175 } |
228 | 176 |
229 bool isTwoSided() const { | 177 bool isTwoSided() const { |
230 return fPassOps[kFront_Face] != fPassOps[kBack_Face] || | 178 return fPassOps[kFront_Face] != fPassOps[kBack_Face] || |
231 fFailOps[kFront_Face] != fFailOps[kBack_Face] || | 179 fFailOps[kFront_Face] != fFailOps[kBack_Face] || |
(...skipping 14 matching lines...) Expand all Loading... |
246 kDecWrap_StencilOp == fFailOps[kBack_Face]; | 194 kDecWrap_StencilOp == fFailOps[kBack_Face]; |
247 } | 195 } |
248 | 196 |
249 bool isDisabled() const { | 197 bool isDisabled() const { |
250 if (fFlags & kIsDisabled_StencilFlag) { | 198 if (fFlags & kIsDisabled_StencilFlag) { |
251 return true; | 199 return true; |
252 } | 200 } |
253 if (fFlags & kNotDisabled_StencilFlag) { | 201 if (fFlags & kNotDisabled_StencilFlag) { |
254 return false; | 202 return false; |
255 } | 203 } |
256 bool disabled = GR_STENCIL_SETTINGS_IS_DISABLED( | 204 bool disabled = this->computeIsDisabled(); |
257 fPassOps[kFront_Face], fPassOps[kBack_Face], | |
258 fFailOps[kFront_Face], fFailOps[kBack_Face], | |
259 fFuncs[kFront_Face], fFuncs[kBack_Face]); | |
260 fFlags |= disabled ? kIsDisabled_StencilFlag : kNotDisabled_StencilFlag; | 205 fFlags |= disabled ? kIsDisabled_StencilFlag : kNotDisabled_StencilFlag; |
261 return disabled; | 206 return disabled; |
262 } | 207 } |
263 | 208 |
264 bool doesWrite() const { | 209 bool doesWrite() const { |
265 if (fFlags & kDoesWrite_StencilFlag) { | 210 if (fFlags & kDoesWrite_StencilFlag) { |
266 return true; | 211 return true; |
267 } | 212 } |
268 if (fFlags & kDoesNotWrite_StencilFlag) { | 213 if (fFlags & kDoesNotWrite_StencilFlag) { |
269 return false; | 214 return false; |
270 } | 215 } |
271 bool writes = GR_STENCIL_SETTINGS_DOES_WRITE( | 216 bool writes = this->computeDoesWrite(); |
272 fPassOps[kFront_Face], fPassOps[kBack_Face], | |
273 fFailOps[kFront_Face], fFailOps[kBack_Face], | |
274 fFuncs[kFront_Face], fFuncs[kBack_Face]); | |
275 fFlags |= writes ? kDoesWrite_StencilFlag : kDoesNotWrite_StencilFlag; | 217 fFlags |= writes ? kDoesWrite_StencilFlag : kDoesNotWrite_StencilFlag; |
276 return writes; | 218 return writes; |
277 } | 219 } |
278 | 220 |
279 void invalidate() { | 221 void invalidate() { |
280 // write an illegal value to the first member | 222 // write an illegal value to the first member |
281 fPassOps[0] = kStencilOpCount; | 223 fPassOps[0] = kStencilOpCnt; |
282 fFlags = 0; | 224 fFlags = 0; |
283 } | 225 } |
284 | 226 |
285 bool isValid() const { | 227 bool isValid() const { return fPassOps[0] < kStencilOpCnt; } |
286 return fPassOps[0] < kStencilOpCount; | |
287 } | |
288 | 228 |
289 void genKey(GrProcessorKeyBuilder* b) const; | 229 void genKey(GrProcessorKeyBuilder* b) const; |
290 | 230 |
291 bool operator == (const GrStencilSettings& s) const { | 231 bool operator==(const GrStencilSettings& s) const { |
292 static const size_t gCompareSize = sizeof(GrStencilSettings) - | 232 static const size_t gCompareSize = sizeof(GrStencilSettings) - |
293 sizeof(fFlags); | 233 sizeof(fFlags); |
294 SkASSERT((const char*)&fFlags + sizeof(fFlags) == | 234 SkASSERT((const char*)&fFlags + sizeof(fFlags) == |
295 (const char*)this + sizeof(GrStencilSettings)); | 235 (const char*)this + sizeof(GrStencilSettings)); |
296 if (this->isDisabled() & s.isDisabled()) { // using & not && | 236 if (this->isDisabled() & s.isDisabled()) { // using & not && |
297 return true; | 237 return true; |
298 } | 238 } |
299 return 0 == memcmp(this, &s, gCompareSize); | 239 return 0 == memcmp(this, &s, gCompareSize); |
300 } | 240 } |
301 | 241 |
302 bool operator != (const GrStencilSettings& s) const { | 242 bool operator!=(const GrStencilSettings& s) const { |
303 return !(*this == s); | 243 return !(*this == s); |
304 } | 244 } |
305 | 245 |
306 GrStencilSettings& operator =(const GrStencilSettings& s) { | 246 GrStencilSettings& operator=(const GrStencilSettings& s) { |
307 memcpy(this, &s, sizeof(GrStencilSettings)); | 247 memcpy(this, &s, sizeof(GrStencilSettings)); |
308 return *this; | 248 return *this; |
309 } | 249 } |
310 | 250 |
311 private: | 251 private: |
312 friend class GrClipMaskManager; | 252 friend class GrClipMaskManager; |
313 | 253 |
314 enum { | 254 enum { |
315 kMaxStencilClipPasses = 2 // maximum number of passes to add a clip | 255 kMaxStencilClipPasses = 2 // maximum number of passes to add a clip |
316 // element to the stencil buffer. | 256 // element to the stencil buffer. |
(...skipping 21 matching lines...) Expand all Loading... |
338 * @return true if the clip element's geometry can be drawn directly to the | 278 * @return true if the clip element's geometry can be drawn directly to the |
339 * stencil clip bit. Will only be true if canBeDirect is true. | 279 * stencil clip bit. Will only be true if canBeDirect is true. |
340 * numPasses will be 1 if return value is true. | 280 * numPasses will be 1 if return value is true. |
341 */ | 281 */ |
342 static bool GetClipPasses(SkRegion::Op op, | 282 static bool GetClipPasses(SkRegion::Op op, |
343 bool canBeDirect, | 283 bool canBeDirect, |
344 unsigned int stencilClipMask, | 284 unsigned int stencilClipMask, |
345 bool invertedFill, | 285 bool invertedFill, |
346 int* numPasses, | 286 int* numPasses, |
347 GrStencilSettings settings[kMaxStencilClipPasses])
; | 287 GrStencilSettings settings[kMaxStencilClipPasses])
; |
| 288 |
| 289 constexpr static bool IsDisabled(GrStencilOp frontPassOp, GrStencilOp backP
assOp, |
| 290 GrStencilOp frontFailOp, GrStencilOp backF
ailOp, |
| 291 GrStencilFunc frontFunc, GrStencilFunc bac
kFunc) { |
| 292 return (((frontPassOp == kKeep_StencilOp && frontFailOp == kKeep_Stencil
Op)) && |
| 293 ((backPassOp == kKeep_StencilOp && backFailOp == kKeep_Stencil
Op)) && |
| 294 frontFunc == kAlways_StencilFunc && |
| 295 backFunc == kAlways_StencilFunc); |
| 296 } |
| 297 |
| 298 constexpr static bool DoesWrite(GrStencilOp frontPassOp, GrStencilOp backPa
ssOp, |
| 299 GrStencilOp frontFailOp, GrStencilOp backFa
ilOp, |
| 300 GrStencilFunc frontFunc, GrStencilFunc back
Func, |
| 301 uint16_t frontWriteMask, uint16_t backWrite
Mask) { |
| 302 return (0 != (frontWriteMask | backWriteMask)) && |
| 303 // Can we write due to a front face passing the stencil test? |
| 304 ((frontFunc != kNever_StencilFunc && frontPassOp != kKeep_Stenci
lOp) || |
| 305 // Can we write due to a back face passing the stencil test? |
| 306 (backFunc != kNever_StencilFunc && backPassOp != kKeep_Stenci
lOp) || |
| 307 // Can we write due to a front face failing the stencil test? |
| 308 (frontFunc != kAlways_StencilFunc && frontFailOp != kKeep_Stenci
lOp) || |
| 309 // Can we write due to a back face failing the stencil test? |
| 310 (backFunc != kAlways_StencilFunc && backFailOp != kKeep_Stenci
lOp)); |
| 311 } |
| 312 |
| 313 constexpr static uint32_t ComputeFlags(GrStencilOp frontPassOp, GrStencilOp
backPassOp, |
| 314 GrStencilOp frontFailOp, GrStencilOp
backFailOp, |
| 315 GrStencilFunc frontFunc, GrStencilFu
nc backFunc, |
| 316 uint16_t frontWriteMask, uint16_t ba
ckWriteMask) { |
| 317 return (IsDisabled(frontPassOp, backPassOp, frontFailOp, backFailOp, |
| 318 frontFunc, backFunc) |
| 319 ? kIsDisabled_StencilFlag |
| 320 : kNotDisabled_StencilFlag) | |
| 321 (DoesWrite(frontPassOp, backPassOp, frontFailOp, backFailOp, |
| 322 frontFunc, backFunc, frontWriteMask, backWriteMask) |
| 323 ? kDoesWrite_StencilFlag |
| 324 : kDoesNotWrite_StencilFlag); |
| 325 } |
| 326 |
| 327 bool computeIsDisabled() const { |
| 328 return IsDisabled((GrStencilOp) fPassOps[kFront_Face], (GrStencilOp) fPa
ssOps[kBack_Face], |
| 329 (GrStencilOp) fFailOps[kFront_Face], (GrStencilOp) fFa
ilOps[kBack_Face], |
| 330 (GrStencilFunc) fFuncs[kFront_Face], (GrStencilFunc) f
Funcs[kBack_Face]); |
| 331 } |
| 332 bool computeDoesWrite() const { |
| 333 return DoesWrite((GrStencilOp)fPassOps[kFront_Face], (GrStencilOp)fPassO
ps[kBack_Face], |
| 334 (GrStencilOp)fFailOps[kFront_Face], (GrStencilOp)fFailO
ps[kBack_Face], |
| 335 (GrStencilFunc)fFuncs[kFront_Face], (GrStencilFunc)fFun
cs[kBack_Face], |
| 336 fWriteMasks[kFront_Face], fWriteMasks[kBack_F
ace]); |
| 337 } |
| 338 |
| 339 enum GrStencilFlags { |
| 340 kIsDisabled_StencilFlag = 0x1, |
| 341 kNotDisabled_StencilFlag = 0x2, |
| 342 kDoesWrite_StencilFlag = 0x4, |
| 343 kDoesNotWrite_StencilFlag = 0x8, |
| 344 }; |
| 345 |
| 346 uint8_t fPassOps[2]; // op to perform when faces pass (GrStencilOp) |
| 347 uint8_t fFailOps[2]; // op to perform when faces fail (GrStencilOp) |
| 348 uint8_t fFuncs[2]; // test function for faces (GrStencilFunc) |
| 349 uint8_t fPad0; |
| 350 uint8_t fPad1; |
| 351 uint16_t fFuncMasks[2]; // mask for face tests |
| 352 uint16_t fFuncRefs[2]; // reference values for face tests |
| 353 uint16_t fWriteMasks[2]; // stencil write masks |
| 354 mutable uint32_t fFlags; |
| 355 |
348 }; | 356 }; |
349 | 357 |
350 GR_STATIC_ASSERT(sizeof(GrStencilSettingsStruct) == sizeof(GrStencilSettings)); | 358 // We rely on this being packed and aligned (memcmp'ed and memcpy'ed) |
351 | 359 GR_STATIC_ASSERT(sizeof(GrStencilSettings) % 4 == 0); |
352 #define GR_STATIC_CONST_STENCIL_STRUCT(STRUCT_NAME, \ | 360 GR_STATIC_ASSERT(sizeof(GrStencilSettings) == |
353 FRONT_PASS_OP, BACK_PASS_OP, \ | 361 4*sizeof(uint8_t) + // ops |
354 FRONT_FAIL_OP, BACK_FAIL_OP, \ | 362 2*sizeof(uint8_t) + // funcs |
355 FRONT_FUNC, BACK_FUNC, \ | 363 2*sizeof(uint8_t) + // pads |
356 FRONT_MASK, BACK_MASK, \ | 364 2*sizeof(uint16_t) + // func masks |
357 FRONT_REF, BACK_REF, \ | 365 2*sizeof(uint16_t) + // ref values |
358 FRONT_WRITE_MASK, BACK_WRITE_MASK) \ | 366 2*sizeof(uint16_t) + // write masks |
359 static const GrStencilSettingsStruct STRUCT_NAME = { \ | 367 sizeof(uint32_t)); // flags |
360 {(FRONT_PASS_OP), (BACK_PASS_OP) }, \ | |
361 {(FRONT_FAIL_OP), (BACK_FAIL_OP) }, \ | |
362 {(FRONT_FUNC), (BACK_FUNC) }, \ | |
363 (0), (0), \ | |
364 {(FRONT_MASK), (BACK_MASK) }, \ | |
365 {(FRONT_REF), (BACK_REF) }, \ | |
366 {(FRONT_WRITE_MASK), (BACK_WRITE_MASK)}, \ | |
367 GR_STENCIL_SETTINGS_DEFAULT_FLAGS( \ | |
368 FRONT_PASS_OP, BACK_PASS_OP, FRONT_FAIL_OP, BACK_FAIL_OP, \ | |
369 FRONT_FUNC, BACK_FUNC) \ | |
370 }; | |
371 | |
372 #define GR_CONST_STENCIL_SETTINGS_PTR_FROM_STRUCT_PTR(STRUCT_PTR) \ | |
373 reinterpret_cast<const GrStencilSettings*>(STRUCT_PTR) | |
374 | |
375 #define GR_STATIC_CONST_SAME_STENCIL_STRUCT(STRUCT_NAME, \ | |
376 PASS_OP, FAIL_OP, FUNC, MASK, REF, WRITE_MASK) \ | |
377 GR_STATIC_CONST_STENCIL_STRUCT(STRUCT_NAME, (PASS_OP), (PASS_OP), \ | |
378 (FAIL_OP),(FAIL_OP), (FUNC), (FUNC), (MASK), (MASK), (REF), (REF), \ | |
379 (WRITE_MASK),(WRITE_MASK)) | |
380 | |
381 #define GR_STATIC_CONST_STENCIL(NAME, \ | |
382 FRONT_PASS_OP, BACK_PASS_OP, \ | |
383 FRONT_FAIL_OP, BACK_FAIL_OP, \ | |
384 FRONT_FUNC, BACK_FUNC, \ | |
385 FRONT_MASK, BACK_MASK, \ | |
386 FRONT_REF, BACK_REF, \ | |
387 FRONT_WRITE_MASK, BACK_WRITE_MASK) \ | |
388 GR_STATIC_CONST_STENCIL_STRUCT(NAME ## _STRUCT, \ | |
389 (FRONT_PASS_OP),(BACK_PASS_OP),(FRONT_FAIL_OP),(BACK_FAIL_OP), \ | |
390 (FRONT_FUNC),(BACK_FUNC),(FRONT_MASK),(BACK_MASK), \ | |
391 (FRONT_REF),(BACK_REF),(FRONT_WRITE_MASK),(BACK_WRITE_MASK)) \ | |
392 static const GrStencilSettings& NAME = \ | |
393 *GR_CONST_STENCIL_SETTINGS_PTR_FROM_STRUCT_PTR(&(NAME ## _STRUCT)); | |
394 | |
395 | |
396 #define GR_STATIC_CONST_SAME_STENCIL(NAME, \ | |
397 PASS_OP, FAIL_OP, FUNC, MASK, REF, WRITE_MASK) \ | |
398 GR_STATIC_CONST_STENCIL(NAME, (PASS_OP), (PASS_OP), (FAIL_OP), \ | |
399 (FAIL_OP), (FUNC), (FUNC), (MASK), (MASK), (REF), (REF), (WRITE_MASK), \ | |
400 (WRITE_MASK)) | |
401 | 368 |
402 #endif | 369 #endif |
OLD | NEW |