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

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.

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

mercurial