blob: 44a390d3fcc10f06afef9d632845cc44d5c9ca6f [file] [log] [blame]
bsalomon@google.comd302f142011-03-03 13:54:13 +00001/*
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 */
48enum 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 */
83enum 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 */
99struct 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 &&
bsalomon@google.comd7beab42011-05-27 16:42:30 +0000162 kKeep_StencilOp == fBackFailOp &&
bsalomon@google.comd302f142011-03-03 13:54:13 +0000163 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
171private:
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.
bsalomon@google.com5aaa69e2011-03-04 20:29:08 +0000193 * @param invertedFill is this path inverted
bsalomon@google.comd302f142011-03-03 13:54:13 +0000194 * @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,
bsalomon@google.com5aaa69e2011-03-04 20:29:08 +0000205 bool invertedFill,
bsalomon@google.comd302f142011-03-03 13:54:13 +0000206 int* numPasses,
207 GrStencilSettings settings[kMaxStencilClipPasses]);
208};
209
210#endif