blob: eb65eff82818fd558311a316fd6d94a5a8394102 [file] [log] [blame]
epoger@google.comec3ed6a2011-07-28 14:26:00 +00001
bsalomon@google.comd302f142011-03-03 13:54:13 +00002/*
epoger@google.comec3ed6a2011-07-28 14:26:00 +00003 * 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.
bsalomon@google.comd302f142011-03-03 13:54:13 +00007 */
8
epoger@google.comec3ed6a2011-07-28 14:26:00 +00009
bsalomon@google.comd302f142011-03-03 13:54:13 +000010#ifndef GrStencil_DEFINED
11#define GrStencil_DEFINED
12
13#include "GrTypes.h"
14/**
15 * Gr uses the stencil buffer to implement complex clipping inside the
16 * GrDrawTarget class. The GrDrawTarget makes a subset of the stencil buffer
17 * bits available for other uses by external code (clients). Client code can
18 * modify these bits. GrDrawTarget will ignore ref, mask, and writemask bits
19 * provided by clients that overlap the bits used to implement clipping. The
20 * client can use the getUsableStencilBits() function to find out how many
21 * client accessible stencil bits are available.
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 GrGpu client to modify the client bits of
27 * the stencil buffer outside of the clip.
28 * > Special functions allow a test against the clip. These are more limited
29 * than the general stencil functions.
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 */
36
37/**
38 * Determines which pixels pass / fail the stencil test.
39 * Stencil test passes if (ref & mask) FUNC (stencil & mask) is true
40 */
41enum 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,
50
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.
58
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
65
66 // counts
67 kStencilFuncCount,
68 kClipStencilFuncCount = kNonZeroIfInClip_StencilFunc -
69 kAlwaysIfInClip_StencilFunc + 1,
70 kBasicStencilFuncCount = kStencilFuncCount - kClipStencilFuncCount
71};
72
73/**
74 * Operations to perform based on whether stencil test passed failed.
75 */
76enum 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
85
86 kStencilOpCount
87};
88
89/**
90 * Struct representing stencil state.
91 */
92struct GrStencilSettings {
93 GrStencilOp fFrontPassOp; // op to perform when front faces pass
94 GrStencilOp fBackPassOp; // op to perform when back faces pass
95 GrStencilOp fFrontFailOp; // op to perform when front faces fail
96 GrStencilOp fBackFailOp; // op to perform when back faces fail
97 GrStencilFunc fFrontFunc; // test function for front faces
98 GrStencilFunc fBackFunc; // test function for back faces
99 unsigned int fFrontFuncMask; // mask for front face test
100 unsigned int fBackFuncMask; // mask for back face test
101 unsigned int fFrontFuncRef; // reference value for front face test
102 unsigned int fBackFuncRef; // reference value for back face test
103 unsigned int fFrontWriteMask; // stencil write mask for front faces
104 unsigned int fBackWriteMask; // stencil write mask for back faces
105
106 bool operator == (const GrStencilSettings& s) const {
107 // make sure this is tightly packed.
108 GR_STATIC_ASSERT(0 == sizeof(GrStencilOp)%4);
109 GR_STATIC_ASSERT(0 == sizeof(GrStencilFunc)%4);
110 GR_STATIC_ASSERT(sizeof(GrStencilSettings) ==
111 4*sizeof(GrStencilOp) +
112 2*sizeof(GrStencilFunc) +
113 6*sizeof(unsigned int));
114 return 0 == memcmp(this, &s, sizeof(GrStencilSettings));
115 }
116
117 bool operator != (const GrStencilSettings& s) const {
118 return !(*this == s);
119 }
120
121 GrStencilSettings& operator =(const GrStencilSettings& s) {
122 memcpy(this, &s, sizeof(GrStencilSettings));
123 return *this;
124 }
125
126 void setSame(GrStencilOp passOp,
127 GrStencilOp failOp,
128 GrStencilFunc func,
129 unsigned int funcMask,
130 unsigned int funcRef,
131 unsigned int writeMask) {
132 fFrontPassOp = passOp;
133 fBackPassOp = passOp;
134 fFrontFailOp = failOp;
135 fBackFailOp = failOp;
136 fFrontFunc = func;
137 fBackFunc = func;
138 fFrontFuncMask = funcMask;
139 fBackFuncMask = funcMask;
140 fFrontFuncRef = funcRef;
141 fBackFuncRef = funcRef;
142 fFrontWriteMask = writeMask;
143 fBackWriteMask = writeMask;
144 }
145
146 // canonical value for disabled stenciling
147 static const GrStencilSettings gDisabled;
148 void setDisabled() {
149 *this = gDisabled;
150 }
151 bool isDisabled() const {
152 return kKeep_StencilOp == fFrontPassOp &&
153 kKeep_StencilOp == fBackPassOp &&
154 kKeep_StencilOp == fFrontFailOp &&
bsalomon@google.comd7beab42011-05-27 16:42:30 +0000155 kKeep_StencilOp == fBackFailOp &&
bsalomon@google.comd302f142011-03-03 13:54:13 +0000156 kAlways_StencilFunc == fFrontFunc &&
157 kAlways_StencilFunc == fBackFunc;
158 }
159 void invalidate() {
160 // just write an illegal value to the first member
161 fFrontPassOp = (GrStencilOp)-1;
162 }
163
164private:
165 friend class GrGpu;
166
167 enum {
168 kMaxStencilClipPasses = 2 // maximum number of passes to add a clip
169 // element to the stencil buffer.
170 };
171
172 /**
173 * Given a thing to draw into the stencil clip, a fill type, and a set op
174 * this function determines:
175 * 1. Whether the thing can be draw directly to the stencil clip or
176 * needs to be drawn to the client portion of the stencil first.
177 * 2. How many passes are needed.
178 * 3. What those passes are.
179 * 4. The fill rule that should actually be used to render (will
180 * always be non-inverted).
181 *
182 * @param op the set op to combine this element with the
183 * existing clip
184 * @param stencilClipMask mask with just the stencil bit used for clipping
185 * enabled.
bsalomon@google.com5aaa69e2011-03-04 20:29:08 +0000186 * @param invertedFill is this path inverted
bsalomon@google.comd302f142011-03-03 13:54:13 +0000187 * @param numPasses out: the number of passes needed to add the
188 * element to the clip.
189 * @param settings out: the stencil settings to use for each pass
190 *
191 * @return true if the clip element's geometry can be drawn directly to the
192 * stencil clip bit. Will only be true if canBeDirect is true.
193 * numPasses will be 1 if return value is true.
194 */
195 static bool GetClipPasses(GrSetOp op,
196 bool canBeDirect,
197 unsigned int stencilClipMask,
bsalomon@google.com5aaa69e2011-03-04 20:29:08 +0000198 bool invertedFill,
bsalomon@google.comd302f142011-03-03 13:54:13 +0000199 int* numPasses,
200 GrStencilSettings settings[kMaxStencilClipPasses]);
201};
202
203#endif