Home | History | Annotate | Download | only in include
      1 /*
      2     Copyright 2011 Google Inc.
      3 
      4     Licensed under the Apache License, Version 2.0 (the "License");
      5     you may not use this file except in compliance with the License.
      6     You may obtain a copy of the License at
      7 
      8          http://www.apache.org/licenses/LICENSE-2.0
      9 
     10     Unless required by applicable law or agreed to in writing, software
     11     distributed under the License is distributed on an "AS IS" BASIS,
     12     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13     See the License for the specific language governing permissions and
     14     limitations under the License.
     15  */
     16 
     17 #ifndef GrStencil_DEFINED
     18 #define GrStencil_DEFINED
     19 
     20 #include "GrTypes.h"
     21 /**
     22  * Gr uses the stencil buffer to implement complex clipping inside the
     23  * GrDrawTarget class. The GrDrawTarget makes a subset of the stencil buffer
     24  * bits available for other uses by external code (clients). Client code can
     25  * modify these bits. GrDrawTarget will ignore ref, mask, and writemask bits
     26  * provided by clients that overlap the bits used to implement clipping. The
     27  * client can use the getUsableStencilBits() function to find out how many
     28  * client accessible stencil bits are available.
     29  *
     30  * When code outside the GrDrawTarget class uses the stencil buffer the contract
     31  * is as follows:
     32  *
     33  * > Normal stencil funcs allow the GrGpu client to modify the client bits of
     34  *   the stencil buffer outside of the clip.
     35  * > Special functions allow a test against the clip. These are more limited
     36  *   than the general stencil functions.
     37  * > Client can assume all client bits are zero initially.
     38  * > Client must ensure that after all its passes are finished it has only
     39  *   written to the color buffer in the region inside the clip. Furthermore, it
     40  *   must zero all client bits that were modifed (both inside and outside the
     41  *   clip).
     42  */
     43 
     44 /**
     45  * Determines which pixels pass / fail the stencil test.
     46  * Stencil test passes if (ref & mask) FUNC (stencil & mask) is true
     47  */
     48 enum GrStencilFunc {
     49     kAlways_StencilFunc = 0,
     50     kNever_StencilFunc,
     51     kGreater_StencilFunc,
     52     kGEqual_StencilFunc,
     53     kLess_StencilFunc,
     54     kLEqual_StencilFunc,
     55     kEqual_StencilFunc,
     56     kNotEqual_StencilFunc,
     57 
     58     // Gr stores the current clip in the
     59     // stencil buffer in the high bits that
     60     // are not directly accessible modifiable
     61     // via the GrDrawTarget interface. The below
     62     // stencil funcs test against the current
     63     // clip in addition to the GrDrawTarget
     64     // client's stencil bits.
     65 
     66     // pass if inside the clip
     67     kAlwaysIfInClip_StencilFunc,
     68     kEqualIfInClip_StencilFunc,
     69     kLessIfInClip_StencilFunc,
     70     kLEqualIfInClip_StencilFunc,
     71     kNonZeroIfInClip_StencilFunc, // this one forces the ref to be 0
     72 
     73     // counts
     74     kStencilFuncCount,
     75     kClipStencilFuncCount = kNonZeroIfInClip_StencilFunc -
     76                             kAlwaysIfInClip_StencilFunc + 1,
     77     kBasicStencilFuncCount = kStencilFuncCount - kClipStencilFuncCount
     78 };
     79 
     80 /**
     81  * Operations to perform based on whether stencil test passed failed.
     82  */
     83 enum GrStencilOp {
     84     kKeep_StencilOp = 0,    // preserve existing stencil value
     85     kReplace_StencilOp,     // replace with reference value from stencl test
     86     kIncWrap_StencilOp,     // increment and wrap at max
     87     kIncClamp_StencilOp,    // increment and clamp at max
     88     kDecWrap_StencilOp,     // decrement and wrap at 0
     89     kDecClamp_StencilOp,    // decrement and clamp at 0
     90     kZero_StencilOp,        // zero stencil bits
     91     kInvert_StencilOp,      // invert stencil bits
     92 
     93     kStencilOpCount
     94 };
     95 
     96 /**
     97  * Struct representing stencil state.
     98  */
     99 struct GrStencilSettings {
    100     GrStencilOp   fFrontPassOp;     // op to perform when front faces pass
    101     GrStencilOp   fBackPassOp;      // op to perform when back faces pass
    102     GrStencilOp   fFrontFailOp;     // op to perform when front faces fail
    103     GrStencilOp   fBackFailOp;      // op to perform when back faces fail
    104     GrStencilFunc fFrontFunc;       // test function for front faces
    105     GrStencilFunc fBackFunc;        // test function for back faces
    106     unsigned int fFrontFuncMask;    // mask for front face test
    107     unsigned int fBackFuncMask;     // mask for back face test
    108     unsigned int fFrontFuncRef;     // reference value for front face test
    109     unsigned int fBackFuncRef;      // reference value for back face test
    110     unsigned int fFrontWriteMask;   // stencil write mask for front faces
    111     unsigned int fBackWriteMask;    // stencil write mask for back faces
    112 
    113     bool operator == (const GrStencilSettings& s) const {
    114         // make sure this is tightly packed.
    115         GR_STATIC_ASSERT(0 == sizeof(GrStencilOp)%4);
    116         GR_STATIC_ASSERT(0 == sizeof(GrStencilFunc)%4);
    117         GR_STATIC_ASSERT(sizeof(GrStencilSettings) ==
    118                         4*sizeof(GrStencilOp) +
    119                         2*sizeof(GrStencilFunc) +
    120                         6*sizeof(unsigned int));
    121         return 0 == memcmp(this, &s, sizeof(GrStencilSettings));
    122     }
    123 
    124     bool operator != (const GrStencilSettings& s) const {
    125         return !(*this == s);
    126     }
    127 
    128     GrStencilSettings& operator =(const GrStencilSettings& s) {
    129         memcpy(this, &s, sizeof(GrStencilSettings));
    130         return *this;
    131     }
    132 
    133     void setSame(GrStencilOp passOp,
    134                  GrStencilOp failOp,
    135                  GrStencilFunc func,
    136                  unsigned int funcMask,
    137                  unsigned int funcRef,
    138                  unsigned int writeMask) {
    139         fFrontPassOp        = passOp;
    140         fBackPassOp         = passOp;
    141         fFrontFailOp        = failOp;
    142         fBackFailOp         = failOp;
    143         fFrontFunc          = func;
    144         fBackFunc           = func;
    145         fFrontFuncMask      = funcMask;
    146         fBackFuncMask       = funcMask;
    147         fFrontFuncRef       = funcRef;
    148         fBackFuncRef        = funcRef;
    149         fFrontWriteMask     = writeMask;
    150         fBackWriteMask      = writeMask;
    151     }
    152 
    153     // canonical value for disabled stenciling
    154     static const GrStencilSettings gDisabled;
    155     void setDisabled() {
    156         *this = gDisabled;
    157     }
    158     bool isDisabled() const {
    159         return kKeep_StencilOp == fFrontPassOp   &&
    160                kKeep_StencilOp == fBackPassOp    &&
    161                kKeep_StencilOp == fFrontFailOp   &&
    162                kKeep_StencilOp == fBackFailOp   &&
    163                kAlways_StencilFunc == fFrontFunc &&
    164                kAlways_StencilFunc == fBackFunc;
    165     }
    166     void invalidate()  {
    167         // just write an illegal value to the first member
    168         fFrontPassOp = (GrStencilOp)-1;
    169     }
    170 
    171 private:
    172     friend class GrGpu;
    173 
    174     enum {
    175         kMaxStencilClipPasses = 2  // maximum number of passes to add a clip
    176                                    // element to the stencil buffer.
    177     };
    178 
    179     /**
    180      * Given a thing to draw into the stencil clip, a fill type, and a set op
    181      * this function determines:
    182      *      1. Whether the thing can be draw directly to the stencil clip or
    183      *      needs to be drawn to the client portion of the stencil first.
    184      *      2. How many passes are needed.
    185      *      3. What those passes are.
    186      *      4. The fill rule that should actually be used to render (will
    187      *         always be non-inverted).
    188      *
    189      * @param op                the set op to combine this element with the
    190      *                          existing clip
    191      * @param stencilClipMask   mask with just the stencil bit used for clipping
    192      *                          enabled.
    193      * @param invertedFill      is this path inverted
    194      * @param numPasses         out: the number of passes needed to add the
    195      *                               element to the clip.
    196      * @param settings          out: the stencil settings to use for each pass
    197      *
    198      * @return true if the clip element's geometry can be drawn directly to the
    199      *         stencil clip bit. Will only be true if canBeDirect is true.
    200      *         numPasses will be 1 if return value is true.
    201      */
    202     static bool GetClipPasses(GrSetOp op,
    203                               bool canBeDirect,
    204                               unsigned int stencilClipMask,
    205                               bool invertedFill,
    206                               int* numPasses,
    207                               GrStencilSettings settings[kMaxStencilClipPasses]);
    208 };
    209 
    210 #endif
    211