• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
setSameGrStencilSettings133     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;
setDisabledGrStencilSettings155     void setDisabled() {
156         *this = gDisabled;
157     }
isDisabledGrStencilSettings158     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     }
invalidateGrStencilSettings166     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