Sat, 03 Jan 2015 20:18:00 +0100
Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.
michael@0 | 1 | |
michael@0 | 2 | /* |
michael@0 | 3 | * Copyright 2011 Google Inc. |
michael@0 | 4 | * |
michael@0 | 5 | * Use of this source code is governed by a BSD-style license that can be |
michael@0 | 6 | * found in the LICENSE file. |
michael@0 | 7 | */ |
michael@0 | 8 | |
michael@0 | 9 | |
michael@0 | 10 | #ifndef GrStencil_DEFINED |
michael@0 | 11 | #define GrStencil_DEFINED |
michael@0 | 12 | |
michael@0 | 13 | #include "GrTypes.h" |
michael@0 | 14 | #include "SkRegion.h" |
michael@0 | 15 | |
michael@0 | 16 | /** |
michael@0 | 17 | * Gr uses the stencil buffer to implement complex clipping inside the |
michael@0 | 18 | * GrDrawTarget class. The GrDrawTarget makes a subset of the stencil buffer |
michael@0 | 19 | * bits available for other uses by external code (clients). Client code can |
michael@0 | 20 | * modify these bits. GrDrawTarget will ignore ref, mask, and writemask bits |
michael@0 | 21 | * provided by clients that overlap the bits used to implement clipping. |
michael@0 | 22 | * |
michael@0 | 23 | * When code outside the GrDrawTarget class uses the stencil buffer the contract |
michael@0 | 24 | * is as follows: |
michael@0 | 25 | * |
michael@0 | 26 | * > Normal stencil funcs allow the client to pass / fail regardless of the |
michael@0 | 27 | * reserved clip bits. |
michael@0 | 28 | * > Additional functions allow a test against the clip along with a limited |
michael@0 | 29 | * set of tests against the client bits. |
michael@0 | 30 | * > Client can assume all client bits are zero initially. |
michael@0 | 31 | * > Client must ensure that after all its passes are finished it has only |
michael@0 | 32 | * written to the color buffer in the region inside the clip. Furthermore, it |
michael@0 | 33 | * must zero all client bits that were modifed (both inside and outside the |
michael@0 | 34 | * clip). |
michael@0 | 35 | */ |
michael@0 | 36 | |
michael@0 | 37 | /** |
michael@0 | 38 | * Determines which pixels pass / fail the stencil test. |
michael@0 | 39 | * Stencil test passes if (ref & mask) FUNC (stencil & mask) is true |
michael@0 | 40 | */ |
michael@0 | 41 | enum GrStencilFunc { |
michael@0 | 42 | kAlways_StencilFunc = 0, |
michael@0 | 43 | kNever_StencilFunc, |
michael@0 | 44 | kGreater_StencilFunc, |
michael@0 | 45 | kGEqual_StencilFunc, |
michael@0 | 46 | kLess_StencilFunc, |
michael@0 | 47 | kLEqual_StencilFunc, |
michael@0 | 48 | kEqual_StencilFunc, |
michael@0 | 49 | kNotEqual_StencilFunc, |
michael@0 | 50 | |
michael@0 | 51 | // Gr stores the current clip in the |
michael@0 | 52 | // stencil buffer in the high bits that |
michael@0 | 53 | // are not directly accessible modifiable |
michael@0 | 54 | // via the GrDrawTarget interface. The below |
michael@0 | 55 | // stencil funcs test against the current |
michael@0 | 56 | // clip in addition to the GrDrawTarget |
michael@0 | 57 | // client's stencil bits. |
michael@0 | 58 | |
michael@0 | 59 | // pass if inside the clip |
michael@0 | 60 | kAlwaysIfInClip_StencilFunc, |
michael@0 | 61 | kEqualIfInClip_StencilFunc, |
michael@0 | 62 | kLessIfInClip_StencilFunc, |
michael@0 | 63 | kLEqualIfInClip_StencilFunc, |
michael@0 | 64 | kNonZeroIfInClip_StencilFunc, // this one forces the ref to be 0 |
michael@0 | 65 | |
michael@0 | 66 | // counts |
michael@0 | 67 | kStencilFuncCount, |
michael@0 | 68 | kClipStencilFuncCount = kNonZeroIfInClip_StencilFunc - |
michael@0 | 69 | kAlwaysIfInClip_StencilFunc + 1, |
michael@0 | 70 | kBasicStencilFuncCount = kStencilFuncCount - kClipStencilFuncCount |
michael@0 | 71 | }; |
michael@0 | 72 | |
michael@0 | 73 | /** |
michael@0 | 74 | * Operations to perform based on whether stencil test passed failed. |
michael@0 | 75 | */ |
michael@0 | 76 | enum GrStencilOp { |
michael@0 | 77 | kKeep_StencilOp = 0, // preserve existing stencil value |
michael@0 | 78 | kReplace_StencilOp, // replace with reference value from stencl test |
michael@0 | 79 | kIncWrap_StencilOp, // increment and wrap at max |
michael@0 | 80 | kIncClamp_StencilOp, // increment and clamp at max |
michael@0 | 81 | kDecWrap_StencilOp, // decrement and wrap at 0 |
michael@0 | 82 | kDecClamp_StencilOp, // decrement and clamp at 0 |
michael@0 | 83 | kZero_StencilOp, // zero stencil bits |
michael@0 | 84 | kInvert_StencilOp, // invert stencil bits |
michael@0 | 85 | |
michael@0 | 86 | kStencilOpCount |
michael@0 | 87 | }; |
michael@0 | 88 | |
michael@0 | 89 | enum GrStencilFlags { |
michael@0 | 90 | kIsDisabled_StencilFlag = 0x1, |
michael@0 | 91 | kNotDisabled_StencilFlag = 0x2, |
michael@0 | 92 | kDoesWrite_StencilFlag = 0x4, |
michael@0 | 93 | kDoesNotWrite_StencilFlag = 0x8, |
michael@0 | 94 | }; |
michael@0 | 95 | |
michael@0 | 96 | /** |
michael@0 | 97 | * GrStencilState needs to be a class with accessors and setters so that it |
michael@0 | 98 | * can maintain flags related to its current state. However, we also want to |
michael@0 | 99 | * be able to declare pre-made stencil settings at compile time (without |
michael@0 | 100 | * inserting static initializer code). So all the data members are in this |
michael@0 | 101 | * struct. A macro defined after the class can be used to jam an instance of |
michael@0 | 102 | * this struct that is created from an initializer list into a |
michael@0 | 103 | * GrStencilSettings. (We hang our heads in shame.) |
michael@0 | 104 | */ |
michael@0 | 105 | struct GrStencilSettingsStruct { |
michael@0 | 106 | uint8_t fPassOps[2]; // op to perform when faces pass (GrStencilOp) |
michael@0 | 107 | uint8_t fFailOps[2]; // op to perform when faces fail (GrStencilOp) |
michael@0 | 108 | uint8_t fFuncs[2]; // test function for faces (GrStencilFunc) |
michael@0 | 109 | uint8_t fPad0; |
michael@0 | 110 | uint8_t fPad1; |
michael@0 | 111 | uint16_t fFuncMasks[2]; // mask for face tests |
michael@0 | 112 | uint16_t fFuncRefs[2]; // reference values for face tests |
michael@0 | 113 | uint16_t fWriteMasks[2]; // stencil write masks |
michael@0 | 114 | mutable uint32_t fFlags; |
michael@0 | 115 | }; |
michael@0 | 116 | // We rely on this being packed and aligned (memcmp'ed and memcpy'ed) |
michael@0 | 117 | GR_STATIC_ASSERT(sizeof(GrStencilSettingsStruct) % 4 == 0); |
michael@0 | 118 | GR_STATIC_ASSERT(sizeof(GrStencilSettingsStruct) == |
michael@0 | 119 | 4*sizeof(uint8_t) + // ops |
michael@0 | 120 | 2*sizeof(uint8_t) + // funcs |
michael@0 | 121 | 2*sizeof(uint8_t) + // pads |
michael@0 | 122 | 2*sizeof(uint16_t) + // func masks |
michael@0 | 123 | 2*sizeof(uint16_t) + // ref values |
michael@0 | 124 | 2*sizeof(uint16_t) + // write masks |
michael@0 | 125 | sizeof(uint32_t)); // flags |
michael@0 | 126 | |
michael@0 | 127 | // This macro is used to compute the GrStencilSettingsStructs flags |
michael@0 | 128 | // associated to disabling. It is used both to define constant structure |
michael@0 | 129 | // initializers and inside GrStencilSettings::isDisabled() |
michael@0 | 130 | // |
michael@0 | 131 | #define GR_STENCIL_SETTINGS_IS_DISABLED( \ |
michael@0 | 132 | FRONT_PASS_OP, BACK_PASS_OP, \ |
michael@0 | 133 | FRONT_FAIL_OP, BACK_FAIL_OP, \ |
michael@0 | 134 | FRONT_FUNC, BACK_FUNC) \ |
michael@0 | 135 | ((FRONT_PASS_OP) == kKeep_StencilOp && \ |
michael@0 | 136 | (BACK_PASS_OP) == kKeep_StencilOp && \ |
michael@0 | 137 | (FRONT_FAIL_OP) == kKeep_StencilOp && \ |
michael@0 | 138 | (BACK_FAIL_OP) == kKeep_StencilOp && \ |
michael@0 | 139 | (FRONT_FUNC) == kAlways_StencilFunc && \ |
michael@0 | 140 | (BACK_FUNC) == kAlways_StencilFunc) |
michael@0 | 141 | |
michael@0 | 142 | #define GR_STENCIL_SETTINGS_DOES_WRITE( \ |
michael@0 | 143 | FRONT_PASS_OP, BACK_PASS_OP, \ |
michael@0 | 144 | FRONT_FAIL_OP, BACK_FAIL_OP, \ |
michael@0 | 145 | FRONT_FUNC, BACK_FUNC) \ |
michael@0 | 146 | (!(((FRONT_FUNC) == kNever_StencilFunc || \ |
michael@0 | 147 | (FRONT_PASS_OP) == kKeep_StencilOp) && \ |
michael@0 | 148 | ((BACK_FUNC) == kNever_StencilFunc || \ |
michael@0 | 149 | (BACK_PASS_OP) == kKeep_StencilOp) && \ |
michael@0 | 150 | ((FRONT_FUNC) == kAlways_StencilFunc || \ |
michael@0 | 151 | (FRONT_FAIL_OP) == kKeep_StencilOp) && \ |
michael@0 | 152 | ((BACK_FUNC) == kAlways_StencilFunc || \ |
michael@0 | 153 | (BACK_FAIL_OP) == kKeep_StencilOp))) |
michael@0 | 154 | |
michael@0 | 155 | #define GR_STENCIL_SETTINGS_DEFAULT_FLAGS( \ |
michael@0 | 156 | FRONT_PASS_OP, BACK_PASS_OP, \ |
michael@0 | 157 | FRONT_FAIL_OP, BACK_FAIL_OP, \ |
michael@0 | 158 | FRONT_FUNC, BACK_FUNC) \ |
michael@0 | 159 | ((GR_STENCIL_SETTINGS_IS_DISABLED(FRONT_PASS_OP,BACK_PASS_OP, \ |
michael@0 | 160 | FRONT_FAIL_OP,BACK_FAIL_OP,FRONT_FUNC,BACK_FUNC) ? \ |
michael@0 | 161 | kIsDisabled_StencilFlag : kNotDisabled_StencilFlag) | \ |
michael@0 | 162 | (GR_STENCIL_SETTINGS_DOES_WRITE(FRONT_PASS_OP,BACK_PASS_OP, \ |
michael@0 | 163 | FRONT_FAIL_OP,BACK_FAIL_OP,FRONT_FUNC,BACK_FUNC) ? \ |
michael@0 | 164 | kDoesWrite_StencilFlag : kDoesNotWrite_StencilFlag)) |
michael@0 | 165 | |
michael@0 | 166 | /** |
michael@0 | 167 | * Class representing stencil state. |
michael@0 | 168 | */ |
michael@0 | 169 | class GrStencilSettings : private GrStencilSettingsStruct { |
michael@0 | 170 | |
michael@0 | 171 | public: |
michael@0 | 172 | enum Face { |
michael@0 | 173 | kFront_Face = 0, |
michael@0 | 174 | kBack_Face = 1, |
michael@0 | 175 | }; |
michael@0 | 176 | |
michael@0 | 177 | GrStencilSettings() { |
michael@0 | 178 | fPad0 = fPad1 = 0; |
michael@0 | 179 | this->setDisabled(); |
michael@0 | 180 | } |
michael@0 | 181 | |
michael@0 | 182 | GrStencilOp passOp(Face f) const { return static_cast<GrStencilOp>(fPassOps[f]); } |
michael@0 | 183 | GrStencilOp failOp(Face f) const { return static_cast<GrStencilOp>(fFailOps[f]); } |
michael@0 | 184 | GrStencilFunc func(Face f) const { return static_cast<GrStencilFunc>(fFuncs[f]); } |
michael@0 | 185 | uint16_t funcMask(Face f) const { return fFuncMasks[f]; } |
michael@0 | 186 | uint16_t funcRef(Face f) const { return fFuncRefs[f]; } |
michael@0 | 187 | uint16_t writeMask(Face f) const { return fWriteMasks[f]; } |
michael@0 | 188 | |
michael@0 | 189 | void setPassOp(Face f, GrStencilOp op) { fPassOps[f] = op; fFlags = 0;} |
michael@0 | 190 | void setFailOp(Face f, GrStencilOp op) { fFailOps[f] = op; fFlags = 0;} |
michael@0 | 191 | void setFunc(Face f, GrStencilFunc func) { fFuncs[f] = func; fFlags = 0;} |
michael@0 | 192 | void setFuncMask(Face f, unsigned short mask) { fFuncMasks[f] = mask; } |
michael@0 | 193 | void setFuncRef(Face f, unsigned short ref) { fFuncRefs[f] = ref; } |
michael@0 | 194 | void setWriteMask(Face f, unsigned short writeMask) { fWriteMasks[f] = writeMask; } |
michael@0 | 195 | |
michael@0 | 196 | void copyFrontSettingsToBack() { |
michael@0 | 197 | fPassOps[kBack_Face] = fPassOps[kFront_Face]; |
michael@0 | 198 | fFailOps[kBack_Face] = fFailOps[kFront_Face]; |
michael@0 | 199 | fFuncs[kBack_Face] = fFuncs[kFront_Face]; |
michael@0 | 200 | fFuncMasks[kBack_Face] = fFuncMasks[kFront_Face]; |
michael@0 | 201 | fFuncRefs[kBack_Face] = fFuncRefs[kFront_Face]; |
michael@0 | 202 | fWriteMasks[kBack_Face] = fWriteMasks[kFront_Face]; |
michael@0 | 203 | fFlags = 0; |
michael@0 | 204 | } |
michael@0 | 205 | |
michael@0 | 206 | void setSame(GrStencilOp passOp, |
michael@0 | 207 | GrStencilOp failOp, |
michael@0 | 208 | GrStencilFunc func, |
michael@0 | 209 | unsigned short funcMask, |
michael@0 | 210 | unsigned short funcRef, |
michael@0 | 211 | unsigned short writeMask) { |
michael@0 | 212 | fPassOps[kFront_Face] = fPassOps[kBack_Face] = passOp; |
michael@0 | 213 | fFailOps[kFront_Face] = fFailOps[kBack_Face] = failOp; |
michael@0 | 214 | fFuncs[kFront_Face] = fFuncs[kBack_Face] = func; |
michael@0 | 215 | fFuncMasks[kFront_Face] = fFuncMasks[kBack_Face] = funcMask; |
michael@0 | 216 | fFuncRefs[kFront_Face] = fFuncRefs[kBack_Face] = funcRef; |
michael@0 | 217 | fWriteMasks[kFront_Face] = fWriteMasks[kBack_Face] = writeMask; |
michael@0 | 218 | fFlags = 0; |
michael@0 | 219 | } |
michael@0 | 220 | |
michael@0 | 221 | void setDisabled() { |
michael@0 | 222 | memset(this, 0, sizeof(*this)); |
michael@0 | 223 | GR_STATIC_ASSERT(0 == kKeep_StencilOp); |
michael@0 | 224 | GR_STATIC_ASSERT(0 == kAlways_StencilFunc); |
michael@0 | 225 | fFlags = kIsDisabled_StencilFlag | kDoesNotWrite_StencilFlag; |
michael@0 | 226 | } |
michael@0 | 227 | |
michael@0 | 228 | bool isTwoSided() const { |
michael@0 | 229 | return fPassOps[kFront_Face] != fPassOps[kBack_Face] || |
michael@0 | 230 | fFailOps[kFront_Face] != fFailOps[kBack_Face] || |
michael@0 | 231 | fFuncs[kFront_Face] != fFuncs[kBack_Face] || |
michael@0 | 232 | fFuncMasks[kFront_Face] != fFuncMasks[kBack_Face] || |
michael@0 | 233 | fFuncRefs[kFront_Face] != fFuncRefs[kBack_Face] || |
michael@0 | 234 | fWriteMasks[kFront_Face] != fWriteMasks[kBack_Face]; |
michael@0 | 235 | } |
michael@0 | 236 | |
michael@0 | 237 | bool usesWrapOp() const { |
michael@0 | 238 | return kIncWrap_StencilOp == fPassOps[kFront_Face] || |
michael@0 | 239 | kDecWrap_StencilOp == fPassOps[kFront_Face] || |
michael@0 | 240 | kIncWrap_StencilOp == fPassOps[kBack_Face] || |
michael@0 | 241 | kDecWrap_StencilOp == fPassOps[kBack_Face] || |
michael@0 | 242 | kIncWrap_StencilOp == fFailOps[kFront_Face] || |
michael@0 | 243 | kDecWrap_StencilOp == fFailOps[kFront_Face] || |
michael@0 | 244 | kIncWrap_StencilOp == fFailOps[kBack_Face] || |
michael@0 | 245 | kDecWrap_StencilOp == fFailOps[kBack_Face]; |
michael@0 | 246 | } |
michael@0 | 247 | |
michael@0 | 248 | bool isDisabled() const { |
michael@0 | 249 | if (fFlags & kIsDisabled_StencilFlag) { |
michael@0 | 250 | return true; |
michael@0 | 251 | } |
michael@0 | 252 | if (fFlags & kNotDisabled_StencilFlag) { |
michael@0 | 253 | return false; |
michael@0 | 254 | } |
michael@0 | 255 | bool disabled = GR_STENCIL_SETTINGS_IS_DISABLED( |
michael@0 | 256 | fPassOps[kFront_Face], fPassOps[kBack_Face], |
michael@0 | 257 | fFailOps[kFront_Face], fFailOps[kBack_Face], |
michael@0 | 258 | fFuncs[kFront_Face], fFuncs[kBack_Face]); |
michael@0 | 259 | fFlags |= disabled ? kIsDisabled_StencilFlag : kNotDisabled_StencilFlag; |
michael@0 | 260 | return disabled; |
michael@0 | 261 | } |
michael@0 | 262 | |
michael@0 | 263 | bool doesWrite() const { |
michael@0 | 264 | if (fFlags & kDoesWrite_StencilFlag) { |
michael@0 | 265 | return true; |
michael@0 | 266 | } |
michael@0 | 267 | if (fFlags & kDoesNotWrite_StencilFlag) { |
michael@0 | 268 | return false; |
michael@0 | 269 | } |
michael@0 | 270 | bool writes = GR_STENCIL_SETTINGS_DOES_WRITE( |
michael@0 | 271 | fPassOps[kFront_Face], fPassOps[kBack_Face], |
michael@0 | 272 | fFailOps[kFront_Face], fFailOps[kBack_Face], |
michael@0 | 273 | fFuncs[kFront_Face], fFuncs[kBack_Face]); |
michael@0 | 274 | fFlags |= writes ? kDoesWrite_StencilFlag : kDoesNotWrite_StencilFlag; |
michael@0 | 275 | return writes; |
michael@0 | 276 | } |
michael@0 | 277 | |
michael@0 | 278 | void invalidate() { |
michael@0 | 279 | // write an illegal value to the first member |
michael@0 | 280 | fPassOps[0] = (GrStencilOp)(uint8_t)-1; |
michael@0 | 281 | fFlags = 0; |
michael@0 | 282 | } |
michael@0 | 283 | |
michael@0 | 284 | bool operator == (const GrStencilSettings& s) const { |
michael@0 | 285 | static const size_t gCompareSize = sizeof(GrStencilSettings) - |
michael@0 | 286 | sizeof(fFlags); |
michael@0 | 287 | SkASSERT((const char*)&fFlags + sizeof(fFlags) == |
michael@0 | 288 | (const char*)this + sizeof(GrStencilSettings)); |
michael@0 | 289 | if (this->isDisabled() & s.isDisabled()) { // using & not && |
michael@0 | 290 | return true; |
michael@0 | 291 | } |
michael@0 | 292 | return 0 == memcmp(this, &s, gCompareSize); |
michael@0 | 293 | } |
michael@0 | 294 | |
michael@0 | 295 | bool operator != (const GrStencilSettings& s) const { |
michael@0 | 296 | return !(*this == s); |
michael@0 | 297 | } |
michael@0 | 298 | |
michael@0 | 299 | GrStencilSettings& operator =(const GrStencilSettings& s) { |
michael@0 | 300 | memcpy(this, &s, sizeof(GrStencilSettings)); |
michael@0 | 301 | return *this; |
michael@0 | 302 | } |
michael@0 | 303 | |
michael@0 | 304 | private: |
michael@0 | 305 | friend class GrClipMaskManager; |
michael@0 | 306 | |
michael@0 | 307 | enum { |
michael@0 | 308 | kMaxStencilClipPasses = 2 // maximum number of passes to add a clip |
michael@0 | 309 | // element to the stencil buffer. |
michael@0 | 310 | }; |
michael@0 | 311 | |
michael@0 | 312 | /** |
michael@0 | 313 | * Given a thing to draw into the stencil clip, a fill type, and a set op |
michael@0 | 314 | * this function determines: |
michael@0 | 315 | * 1. Whether the thing can be draw directly to the stencil clip or |
michael@0 | 316 | * needs to be drawn to the client portion of the stencil first. |
michael@0 | 317 | * 2. How many passes are needed. |
michael@0 | 318 | * 3. What those passes are. |
michael@0 | 319 | * 4. The fill rule that should actually be used to render (will |
michael@0 | 320 | * always be non-inverted). |
michael@0 | 321 | * |
michael@0 | 322 | * @param op the set op to combine this element with the |
michael@0 | 323 | * existing clip |
michael@0 | 324 | * @param stencilClipMask mask with just the stencil bit used for clipping |
michael@0 | 325 | * enabled. |
michael@0 | 326 | * @param invertedFill is this path inverted |
michael@0 | 327 | * @param numPasses out: the number of passes needed to add the |
michael@0 | 328 | * element to the clip. |
michael@0 | 329 | * @param settings out: the stencil settings to use for each pass |
michael@0 | 330 | * |
michael@0 | 331 | * @return true if the clip element's geometry can be drawn directly to the |
michael@0 | 332 | * stencil clip bit. Will only be true if canBeDirect is true. |
michael@0 | 333 | * numPasses will be 1 if return value is true. |
michael@0 | 334 | */ |
michael@0 | 335 | static bool GetClipPasses(SkRegion::Op op, |
michael@0 | 336 | bool canBeDirect, |
michael@0 | 337 | unsigned int stencilClipMask, |
michael@0 | 338 | bool invertedFill, |
michael@0 | 339 | int* numPasses, |
michael@0 | 340 | GrStencilSettings settings[kMaxStencilClipPasses]); |
michael@0 | 341 | }; |
michael@0 | 342 | |
michael@0 | 343 | GR_STATIC_ASSERT(sizeof(GrStencilSettingsStruct) == sizeof(GrStencilSettings)); |
michael@0 | 344 | |
michael@0 | 345 | #define GR_STATIC_CONST_STENCIL_STRUCT(STRUCT_NAME, \ |
michael@0 | 346 | FRONT_PASS_OP, BACK_PASS_OP, \ |
michael@0 | 347 | FRONT_FAIL_OP, BACK_FAIL_OP, \ |
michael@0 | 348 | FRONT_FUNC, BACK_FUNC, \ |
michael@0 | 349 | FRONT_MASK, BACK_MASK, \ |
michael@0 | 350 | FRONT_REF, BACK_REF, \ |
michael@0 | 351 | FRONT_WRITE_MASK, BACK_WRITE_MASK) \ |
michael@0 | 352 | static const GrStencilSettingsStruct STRUCT_NAME = { \ |
michael@0 | 353 | {(FRONT_PASS_OP), (BACK_PASS_OP) }, \ |
michael@0 | 354 | {(FRONT_FAIL_OP), (BACK_FAIL_OP) }, \ |
michael@0 | 355 | {(FRONT_FUNC), (BACK_FUNC) }, \ |
michael@0 | 356 | (0), (0), \ |
michael@0 | 357 | {(FRONT_MASK), (BACK_MASK) }, \ |
michael@0 | 358 | {(FRONT_REF), (BACK_REF) }, \ |
michael@0 | 359 | {(FRONT_WRITE_MASK), (BACK_WRITE_MASK)}, \ |
michael@0 | 360 | GR_STENCIL_SETTINGS_DEFAULT_FLAGS( \ |
michael@0 | 361 | FRONT_PASS_OP, BACK_PASS_OP, FRONT_FAIL_OP, BACK_FAIL_OP, \ |
michael@0 | 362 | FRONT_FUNC, BACK_FUNC) \ |
michael@0 | 363 | }; |
michael@0 | 364 | |
michael@0 | 365 | #define GR_CONST_STENCIL_SETTINGS_PTR_FROM_STRUCT_PTR(STRUCT_PTR) \ |
michael@0 | 366 | reinterpret_cast<const GrStencilSettings*>(STRUCT_PTR) |
michael@0 | 367 | |
michael@0 | 368 | #define GR_STATIC_CONST_SAME_STENCIL_STRUCT(STRUCT_NAME, \ |
michael@0 | 369 | PASS_OP, FAIL_OP, FUNC, MASK, REF, WRITE_MASK) \ |
michael@0 | 370 | GR_STATIC_CONST_STENCIL_STRUCT(STRUCT_NAME, (PASS_OP), (PASS_OP), \ |
michael@0 | 371 | (FAIL_OP),(FAIL_OP), (FUNC), (FUNC), (MASK), (MASK), (REF), (REF), \ |
michael@0 | 372 | (WRITE_MASK),(WRITE_MASK)) |
michael@0 | 373 | |
michael@0 | 374 | #define GR_STATIC_CONST_STENCIL(NAME, \ |
michael@0 | 375 | FRONT_PASS_OP, BACK_PASS_OP, \ |
michael@0 | 376 | FRONT_FAIL_OP, BACK_FAIL_OP, \ |
michael@0 | 377 | FRONT_FUNC, BACK_FUNC, \ |
michael@0 | 378 | FRONT_MASK, BACK_MASK, \ |
michael@0 | 379 | FRONT_REF, BACK_REF, \ |
michael@0 | 380 | FRONT_WRITE_MASK, BACK_WRITE_MASK) \ |
michael@0 | 381 | GR_STATIC_CONST_STENCIL_STRUCT(NAME ## _STRUCT, \ |
michael@0 | 382 | (FRONT_PASS_OP),(BACK_PASS_OP),(FRONT_FAIL_OP),(BACK_FAIL_OP), \ |
michael@0 | 383 | (FRONT_FUNC),(BACK_FUNC),(FRONT_MASK),(BACK_MASK), \ |
michael@0 | 384 | (FRONT_REF),(BACK_REF),(FRONT_WRITE_MASK),(BACK_WRITE_MASK)) \ |
michael@0 | 385 | static const GrStencilSettings& NAME = \ |
michael@0 | 386 | *GR_CONST_STENCIL_SETTINGS_PTR_FROM_STRUCT_PTR(&(NAME ## _STRUCT)); |
michael@0 | 387 | |
michael@0 | 388 | |
michael@0 | 389 | #define GR_STATIC_CONST_SAME_STENCIL(NAME, \ |
michael@0 | 390 | PASS_OP, FAIL_OP, FUNC, MASK, REF, WRITE_MASK) \ |
michael@0 | 391 | GR_STATIC_CONST_STENCIL(NAME, (PASS_OP), (PASS_OP), (FAIL_OP), \ |
michael@0 | 392 | (FAIL_OP), (FUNC), (FUNC), (MASK), (MASK), (REF), (REF), (WRITE_MASK), \ |
michael@0 | 393 | (WRITE_MASK)) |
michael@0 | 394 | |
michael@0 | 395 | #endif |