gfx/skia/trunk/src/gpu/GrStencil.cpp

Sat, 03 Jan 2015 20:18:00 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Sat, 03 Jan 2015 20:18:00 +0100
branch
TOR_BUG_3246
changeset 7
129ffea94266
permissions
-rw-r--r--

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 #include "GrStencil.h"
michael@0 11
michael@0 12 ////////////////////////////////////////////////////////////////////////////////
michael@0 13 // Stencil Rules for Merging user stencil space into clip
michael@0 14
michael@0 15 // We can't include the clip bit in the ref or mask values because the division
michael@0 16 // between user and clip bits in the stencil depends on the number of stencil
michael@0 17 // bits in the runtime. Comments below indicate what the code should do to
michael@0 18 // incorporate the clip bit into these settings.
michael@0 19
michael@0 20 ///////
michael@0 21 // Replace
michael@0 22
michael@0 23 // set the ref to be the clip bit, but mask it out for the test
michael@0 24 GR_STATIC_CONST_SAME_STENCIL(gUserToClipReplace,
michael@0 25 kReplace_StencilOp,
michael@0 26 kZero_StencilOp,
michael@0 27 kLess_StencilFunc,
michael@0 28 0xffff, // unset clip bit
michael@0 29 0x0000, // set clip bit
michael@0 30 0xffff);
michael@0 31
michael@0 32 GR_STATIC_CONST_SAME_STENCIL(gInvUserToClipReplace,
michael@0 33 kReplace_StencilOp,
michael@0 34 kZero_StencilOp,
michael@0 35 kEqual_StencilFunc,
michael@0 36 0xffff, // unset clip bit
michael@0 37 0x0000, // set clip bit
michael@0 38 0xffff);
michael@0 39
michael@0 40 ///////
michael@0 41 // Intersect
michael@0 42 GR_STATIC_CONST_SAME_STENCIL(gUserToClipIsect,
michael@0 43 kReplace_StencilOp,
michael@0 44 kZero_StencilOp,
michael@0 45 kLess_StencilFunc,
michael@0 46 0xffff,
michael@0 47 0x0000, // set clip bit
michael@0 48 0xffff);
michael@0 49
michael@0 50 GR_STATIC_CONST_SAME_STENCIL(gInvUserToClipIsect,
michael@0 51 kReplace_StencilOp,
michael@0 52 kZero_StencilOp,
michael@0 53 kEqual_StencilFunc,
michael@0 54 0xffff,
michael@0 55 0x0000, // set clip bit
michael@0 56 0xffff);
michael@0 57
michael@0 58 ///////
michael@0 59 // Difference
michael@0 60 GR_STATIC_CONST_SAME_STENCIL(gUserToClipDiff,
michael@0 61 kReplace_StencilOp,
michael@0 62 kZero_StencilOp,
michael@0 63 kEqual_StencilFunc,
michael@0 64 0xffff,
michael@0 65 0x0000, // set clip bit
michael@0 66 0xffff);
michael@0 67
michael@0 68 GR_STATIC_CONST_SAME_STENCIL(gInvUserToClipDiff,
michael@0 69 kReplace_StencilOp,
michael@0 70 kZero_StencilOp,
michael@0 71 kLess_StencilFunc,
michael@0 72 0xffff,
michael@0 73 0x0000, // set clip bit
michael@0 74 0xffff);
michael@0 75
michael@0 76 ///////
michael@0 77 // Union
michael@0 78
michael@0 79 // first pass makes all the passing cases >= just clip bit set.
michael@0 80 GR_STATIC_CONST_SAME_STENCIL(gUserToClipUnionPass0,
michael@0 81 kReplace_StencilOp,
michael@0 82 kKeep_StencilOp,
michael@0 83 kLEqual_StencilFunc,
michael@0 84 0xffff,
michael@0 85 0x0001, // set clip bit
michael@0 86 0xffff);
michael@0 87
michael@0 88 // second pass allows anything greater than just clip bit set to pass
michael@0 89 GR_STATIC_CONST_SAME_STENCIL(gUserToClipUnionPass1,
michael@0 90 kReplace_StencilOp,
michael@0 91 kZero_StencilOp,
michael@0 92 kLEqual_StencilFunc,
michael@0 93 0xffff,
michael@0 94 0x0000, // set clip bit
michael@0 95 0xffff);
michael@0 96
michael@0 97 // first pass finds zeros in the user bits and if found sets
michael@0 98 // the clip bit to 1
michael@0 99 GR_STATIC_CONST_SAME_STENCIL(gInvUserToClipUnionPass0,
michael@0 100 kReplace_StencilOp,
michael@0 101 kKeep_StencilOp,
michael@0 102 kEqual_StencilFunc,
michael@0 103 0xffff,
michael@0 104 0x0000, // set clip bit
michael@0 105 0x0000 // set clip bit
michael@0 106 );
michael@0 107
michael@0 108 // second pass zeros the user bits
michael@0 109 GR_STATIC_CONST_SAME_STENCIL(gInvUserToClipUnionPass1,
michael@0 110 kZero_StencilOp,
michael@0 111 kZero_StencilOp,
michael@0 112 kLess_StencilFunc,
michael@0 113 0xffff,
michael@0 114 0x0000,
michael@0 115 0xffff // unset clip bit
michael@0 116 );
michael@0 117
michael@0 118 ///////
michael@0 119 // Xor
michael@0 120 GR_STATIC_CONST_SAME_STENCIL(gUserToClipXorPass0,
michael@0 121 kInvert_StencilOp,
michael@0 122 kKeep_StencilOp,
michael@0 123 kEqual_StencilFunc,
michael@0 124 0xffff, // unset clip bit
michael@0 125 0x0000,
michael@0 126 0xffff);
michael@0 127
michael@0 128 GR_STATIC_CONST_SAME_STENCIL(gUserToClipXorPass1,
michael@0 129 kReplace_StencilOp,
michael@0 130 kZero_StencilOp,
michael@0 131 kGreater_StencilFunc,
michael@0 132 0xffff,
michael@0 133 0x0000, // set clip bit
michael@0 134 0xffff);
michael@0 135
michael@0 136 GR_STATIC_CONST_SAME_STENCIL(gInvUserToClipXorPass0,
michael@0 137 kInvert_StencilOp,
michael@0 138 kKeep_StencilOp,
michael@0 139 kEqual_StencilFunc,
michael@0 140 0xffff, // unset clip bit
michael@0 141 0x0000,
michael@0 142 0xffff);
michael@0 143
michael@0 144 GR_STATIC_CONST_SAME_STENCIL(gInvUserToClipXorPass1,
michael@0 145 kReplace_StencilOp,
michael@0 146 kZero_StencilOp,
michael@0 147 kLess_StencilFunc,
michael@0 148 0xffff,
michael@0 149 0x0000, // set clip bit
michael@0 150 0xffff);
michael@0 151
michael@0 152 ///////
michael@0 153 // Reverse Diff
michael@0 154 GR_STATIC_CONST_SAME_STENCIL(gUserToClipRDiffPass0,
michael@0 155 kInvert_StencilOp,
michael@0 156 kZero_StencilOp,
michael@0 157 kLess_StencilFunc,
michael@0 158 0xffff, // unset clip bit
michael@0 159 0x0000, // set clip bit
michael@0 160 0xffff);
michael@0 161
michael@0 162 GR_STATIC_CONST_SAME_STENCIL(gUserToClipRDiffPass1,
michael@0 163 kReplace_StencilOp,
michael@0 164 kZero_StencilOp,
michael@0 165 kEqual_StencilFunc,
michael@0 166 0x0000, // set clip bit
michael@0 167 0x0000, // set clip bit
michael@0 168 0xffff);
michael@0 169
michael@0 170 // We are looking for stencil values that are all zero. The first pass sets the
michael@0 171 // clip bit if the stencil is all zeros. The second pass clears the user bits.
michael@0 172 GR_STATIC_CONST_SAME_STENCIL(gInvUserToClipRDiffPass0,
michael@0 173 kInvert_StencilOp,
michael@0 174 kZero_StencilOp,
michael@0 175 kEqual_StencilFunc,
michael@0 176 0xffff,
michael@0 177 0x0000,
michael@0 178 0x0000 // set clip bit
michael@0 179 );
michael@0 180
michael@0 181 GR_STATIC_CONST_SAME_STENCIL(gInvUserToClipRDiffPass1,
michael@0 182 kZero_StencilOp,
michael@0 183 kZero_StencilOp,
michael@0 184 kAlways_StencilFunc,
michael@0 185 0xffff,
michael@0 186 0x0000,
michael@0 187 0xffff // unset clip bit
michael@0 188 );
michael@0 189
michael@0 190 ///////
michael@0 191 // Direct to Stencil
michael@0 192
michael@0 193 // We can render a clip element directly without first writing to the client
michael@0 194 // portion of the clip when the fill is not inverse and the set operation will
michael@0 195 // only modify the in/out status of samples covered by the clip element.
michael@0 196
michael@0 197 // this one only works if used right after stencil clip was cleared.
michael@0 198 // Our clip mask creation code doesn't allow midstream replace ops.
michael@0 199 GR_STATIC_CONST_SAME_STENCIL(gReplaceClip,
michael@0 200 kReplace_StencilOp,
michael@0 201 kReplace_StencilOp,
michael@0 202 kAlways_StencilFunc,
michael@0 203 0xffff,
michael@0 204 0x0000, // set clip bit
michael@0 205 0x0000 // set clipBit
michael@0 206 );
michael@0 207
michael@0 208 GR_STATIC_CONST_SAME_STENCIL(gUnionClip,
michael@0 209 kReplace_StencilOp,
michael@0 210 kReplace_StencilOp,
michael@0 211 kAlways_StencilFunc,
michael@0 212 0xffff,
michael@0 213 0x0000, // set clip bit
michael@0 214 0x0000 // set clip bit
michael@0 215 );
michael@0 216
michael@0 217 GR_STATIC_CONST_SAME_STENCIL(gXorClip,
michael@0 218 kInvert_StencilOp,
michael@0 219 kInvert_StencilOp,
michael@0 220 kAlways_StencilFunc,
michael@0 221 0xffff,
michael@0 222 0x0000,
michael@0 223 0x0000 // set clip bit
michael@0 224 );
michael@0 225
michael@0 226 GR_STATIC_CONST_SAME_STENCIL(gDiffClip,
michael@0 227 kZero_StencilOp,
michael@0 228 kZero_StencilOp,
michael@0 229 kAlways_StencilFunc,
michael@0 230 0xffff,
michael@0 231 0x0000,
michael@0 232 0x0000 // set clip bit
michael@0 233 );
michael@0 234
michael@0 235 bool GrStencilSettings::GetClipPasses(
michael@0 236 SkRegion::Op op,
michael@0 237 bool canBeDirect,
michael@0 238 unsigned int stencilClipMask,
michael@0 239 bool invertedFill,
michael@0 240 int* numPasses,
michael@0 241 GrStencilSettings settings[kMaxStencilClipPasses]) {
michael@0 242 if (canBeDirect && !invertedFill) {
michael@0 243 *numPasses = 0;
michael@0 244 switch (op) {
michael@0 245 case SkRegion::kReplace_Op:
michael@0 246 *numPasses = 1;
michael@0 247 settings[0] = gReplaceClip;
michael@0 248 break;
michael@0 249 case SkRegion::kUnion_Op:
michael@0 250 *numPasses = 1;
michael@0 251 settings[0] = gUnionClip;
michael@0 252 break;
michael@0 253 case SkRegion::kXOR_Op:
michael@0 254 *numPasses = 1;
michael@0 255 settings[0] = gXorClip;
michael@0 256 break;
michael@0 257 case SkRegion::kDifference_Op:
michael@0 258 *numPasses = 1;
michael@0 259 settings[0] = gDiffClip;
michael@0 260 break;
michael@0 261 default: // suppress warning
michael@0 262 break;
michael@0 263 }
michael@0 264 if (1 == *numPasses) {
michael@0 265 settings[0].fFuncRefs[kFront_Face] |= stencilClipMask;
michael@0 266 settings[0].fWriteMasks[kFront_Face] |= stencilClipMask;
michael@0 267 settings[0].fFuncRefs[kBack_Face] =
michael@0 268 settings[0].fFuncRefs[kFront_Face];
michael@0 269 settings[0].fWriteMasks[kBack_Face] =
michael@0 270 settings[0].fWriteMasks[kFront_Face];
michael@0 271 return true;
michael@0 272 }
michael@0 273 }
michael@0 274 switch (op) {
michael@0 275 // if we make the path renderer go to stencil we always give it a
michael@0 276 // non-inverted fill and we use the stencil rules on the client->clipbit
michael@0 277 // pass to select either the zeros or nonzeros.
michael@0 278 case SkRegion::kReplace_Op:
michael@0 279 *numPasses= 1;
michael@0 280 settings[0] = invertedFill ? gInvUserToClipReplace :
michael@0 281 gUserToClipReplace;
michael@0 282 settings[0].fFuncMasks[kFront_Face] &= ~stencilClipMask;
michael@0 283 settings[0].fFuncRefs[kFront_Face] |= stencilClipMask;
michael@0 284 settings[0].fFuncMasks[kBack_Face] =
michael@0 285 settings[0].fFuncMasks[kFront_Face];
michael@0 286 settings[0].fFuncRefs[kBack_Face] =
michael@0 287 settings[0].fFuncRefs[kFront_Face];
michael@0 288 break;
michael@0 289 case SkRegion::kIntersect_Op:
michael@0 290 *numPasses = 1;
michael@0 291 settings[0] = invertedFill ? gInvUserToClipIsect : gUserToClipIsect;
michael@0 292 settings[0].fFuncRefs[kFront_Face] = stencilClipMask;
michael@0 293 settings[0].fFuncRefs[kBack_Face] =
michael@0 294 settings[0].fFuncRefs[kFront_Face];
michael@0 295 break;
michael@0 296 case SkRegion::kUnion_Op:
michael@0 297 *numPasses = 2;
michael@0 298 if (invertedFill) {
michael@0 299 settings[0] = gInvUserToClipUnionPass0;
michael@0 300 settings[0].fFuncMasks[kFront_Face] &= ~stencilClipMask;
michael@0 301 settings[0].fFuncMasks[kBack_Face] =
michael@0 302 settings[0].fFuncMasks[kFront_Face];
michael@0 303 settings[0].fFuncRefs[kFront_Face] |= stencilClipMask;
michael@0 304 settings[0].fFuncRefs[kBack_Face] =
michael@0 305 settings[0].fFuncRefs[kFront_Face];
michael@0 306 settings[0].fWriteMasks[kFront_Face] |= stencilClipMask;
michael@0 307 settings[0].fWriteMasks[kBack_Face] =
michael@0 308 settings[0].fWriteMasks[kFront_Face];
michael@0 309
michael@0 310 settings[1] = gInvUserToClipUnionPass1;
michael@0 311 settings[1].fWriteMasks[kFront_Face] &= ~stencilClipMask;
michael@0 312 settings[1].fWriteMasks[kBack_Face] &=
michael@0 313 settings[1].fWriteMasks[kFront_Face];
michael@0 314
michael@0 315 } else {
michael@0 316 settings[0] = gUserToClipUnionPass0;
michael@0 317 settings[0].fFuncMasks[kFront_Face] &= ~stencilClipMask;
michael@0 318 settings[0].fFuncRefs[kFront_Face] |= stencilClipMask;
michael@0 319 settings[0].fFuncMasks[kBack_Face] =
michael@0 320 settings[0].fFuncMasks[kFront_Face];
michael@0 321 settings[0].fFuncRefs[kBack_Face] =
michael@0 322 settings[0].fFuncRefs[kFront_Face];
michael@0 323
michael@0 324 settings[1] = gUserToClipUnionPass1;
michael@0 325 settings[1].fFuncRefs[kFront_Face] |= stencilClipMask;
michael@0 326 settings[1].fFuncRefs[kBack_Face] =
michael@0 327 settings[1].fFuncRefs[kFront_Face];
michael@0 328 }
michael@0 329 break;
michael@0 330 case SkRegion::kXOR_Op:
michael@0 331 *numPasses = 2;
michael@0 332 if (invertedFill) {
michael@0 333 settings[0] = gInvUserToClipXorPass0;
michael@0 334 settings[0].fFuncMasks[kFront_Face] &= ~stencilClipMask;
michael@0 335 settings[0].fFuncMasks[kBack_Face] =
michael@0 336 settings[0].fFuncMasks[kFront_Face];
michael@0 337
michael@0 338 settings[1] = gInvUserToClipXorPass1;
michael@0 339 settings[1].fFuncRefs[kFront_Face] |= stencilClipMask;
michael@0 340 settings[1].fFuncRefs[kBack_Face] =
michael@0 341 settings[1].fFuncRefs[kFront_Face];
michael@0 342 } else {
michael@0 343 settings[0] = gUserToClipXorPass0;
michael@0 344 settings[0].fFuncMasks[kFront_Face] &= ~stencilClipMask;
michael@0 345 settings[0].fFuncMasks[kBack_Face] =
michael@0 346 settings[0].fFuncMasks[kFront_Face];
michael@0 347
michael@0 348 settings[1] = gUserToClipXorPass1;
michael@0 349 settings[1].fFuncRefs[kFront_Face] |= stencilClipMask;
michael@0 350 settings[1].fFuncRefs[kBack_Face] =
michael@0 351 settings[1].fFuncRefs[kFront_Face];
michael@0 352 }
michael@0 353 break;
michael@0 354 case SkRegion::kDifference_Op:
michael@0 355 *numPasses = 1;
michael@0 356 settings[0] = invertedFill ? gInvUserToClipDiff : gUserToClipDiff;
michael@0 357 settings[0].fFuncRefs[kFront_Face] |= stencilClipMask;
michael@0 358 settings[0].fFuncRefs[kBack_Face] =
michael@0 359 settings[0].fFuncRefs[kFront_Face];
michael@0 360 break;
michael@0 361 case SkRegion::kReverseDifference_Op:
michael@0 362 if (invertedFill) {
michael@0 363 *numPasses = 2;
michael@0 364 settings[0] = gInvUserToClipRDiffPass0;
michael@0 365 settings[0].fWriteMasks[kFront_Face] |= stencilClipMask;
michael@0 366 settings[0].fWriteMasks[kBack_Face] =
michael@0 367 settings[0].fWriteMasks[kFront_Face];
michael@0 368 settings[1] = gInvUserToClipRDiffPass1;
michael@0 369 settings[1].fWriteMasks[kFront_Face] &= ~stencilClipMask;
michael@0 370 settings[1].fWriteMasks[kBack_Face] =
michael@0 371 settings[1].fWriteMasks[kFront_Face];
michael@0 372 } else {
michael@0 373 *numPasses = 2;
michael@0 374 settings[0] = gUserToClipRDiffPass0;
michael@0 375 settings[0].fFuncMasks[kFront_Face] &= ~stencilClipMask;
michael@0 376 settings[0].fFuncMasks[kBack_Face] =
michael@0 377 settings[0].fFuncMasks[kFront_Face];
michael@0 378 settings[0].fFuncRefs[kFront_Face] |= stencilClipMask;
michael@0 379 settings[0].fFuncRefs[kBack_Face] =
michael@0 380 settings[0].fFuncRefs[kFront_Face];
michael@0 381
michael@0 382 settings[1] = gUserToClipRDiffPass1;
michael@0 383 settings[1].fFuncMasks[kFront_Face] |= stencilClipMask;
michael@0 384 settings[1].fFuncRefs[kFront_Face] |= stencilClipMask;
michael@0 385 settings[1].fFuncMasks[kBack_Face] =
michael@0 386 settings[1].fFuncMasks[kFront_Face];
michael@0 387 settings[1].fFuncRefs[kBack_Face] =
michael@0 388 settings[1].fFuncRefs[kFront_Face];
michael@0 389 }
michael@0 390 break;
michael@0 391 default:
michael@0 392 GrCrash("Unknown set op");
michael@0 393 }
michael@0 394 return false;
michael@0 395 }

mercurial