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