1 /*
2 * Copyright 2011 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8
9 #include "src/gpu/GrStencilSettings.h"
10
11 #include "src/gpu/GrProcessor.h"
12
13 constexpr const GrUserStencilSettings gUnused(
14 GrUserStencilSettings::StaticInit<
15 0x0000,
16 GrUserStencilTest::kAlwaysIfInClip,
17 0xffff,
18 GrUserStencilOp::kKeep,
19 GrUserStencilOp::kKeep,
20 0x0000>()
21 );
22
23 #ifdef SK_ENABLE_STENCIL_CULLING_OHOS
24 #define GENERATE_STENCIL_SETTINGS(name, refValue) \
25 constexpr const GrUserStencilSettings name( \
26 GrUserStencilSettings::StaticInit< \
27 refValue, \
28 GrUserStencilTest::kGEqual, \
29 0xffff, \
30 GrUserStencilOp::kKeep, \
31 GrUserStencilOp::kKeep, \
32 0x0000>() \
33 )
34
35 GENERATE_STENCIL_SETTINGS(gGEqual0, 0x0000);
36 GENERATE_STENCIL_SETTINGS(gGEqual1, 0x0001);
37 GENERATE_STENCIL_SETTINGS(gGEqual2, 0x0002);
38 GENERATE_STENCIL_SETTINGS(gGEqual3, 0x0003);
39 GENERATE_STENCIL_SETTINGS(gGEqual4, 0x0004);
40 GENERATE_STENCIL_SETTINGS(gGEqual5, 0x0005);
41
42 const GrUserStencilSettings *GrUserStencilSettings::kGE[kStencilLayersMax] = {&gGEqual0, &gGEqual1, &gGEqual2,
43 &gGEqual3, &gGEqual4, &gGEqual5};
44 #endif
45 static_assert(kAll_StencilFlags == (gUnused.fCWFlags[0] & gUnused.fCCWFlags[0]));
46
47 const GrUserStencilSettings& GrUserStencilSettings::kUnused = gUnused;
48
reset(const GrUserStencilSettings & user,bool hasStencilClip,int numStencilBits)49 void GrStencilSettings::reset(const GrUserStencilSettings& user, bool hasStencilClip,
50 int numStencilBits) {
51 uint16_t cwFlags = user.fCWFlags[hasStencilClip];
52 if (cwFlags & kSingleSided_StencilFlag) {
53 SkASSERT(cwFlags == user.fCCWFlags[hasStencilClip]);
54 fFlags = cwFlags;
55 if (!this->isDisabled()) {
56 fCWFace.reset(user.fCWFace, hasStencilClip, numStencilBits);
57 }
58 return;
59 }
60
61 uint16_t ccwFlags = user.fCCWFlags[hasStencilClip];
62 fFlags = cwFlags & ccwFlags;
63 if (this->isDisabled()) {
64 return;
65 }
66 if (!(cwFlags & kDisabled_StencilFlag)) {
67 fCWFace.reset(user.fCWFace, hasStencilClip, numStencilBits);
68 } else {
69 fCWFace.setDisabled();
70 }
71 if (!(ccwFlags & kDisabled_StencilFlag)) {
72 fCCWFace.reset(user.fCCWFace, hasStencilClip, numStencilBits);
73 } else {
74 fCCWFace.setDisabled();
75 }
76 }
77
reset(const GrStencilSettings & that)78 void GrStencilSettings::reset(const GrStencilSettings& that) {
79 fFlags = that.fFlags;
80 if ((kInvalid_PrivateFlag | kDisabled_StencilFlag) & fFlags) {
81 return;
82 }
83 if (!this->isTwoSided()) {
84 memcpy(&fCWFace, &that.fCWFace, sizeof(Face));
85 } else {
86 memcpy(&fCWFace, &that.fCWFace, 2 * sizeof(Face));
87 static_assert(sizeof(Face) ==
88 offsetof(GrStencilSettings, fCCWFace) - offsetof(GrStencilSettings, fCWFace));
89 }
90 }
91
operator ==(const GrStencilSettings & that) const92 bool GrStencilSettings::operator==(const GrStencilSettings& that) const {
93 if ((kInvalid_PrivateFlag | kDisabled_StencilFlag) & (fFlags | that.fFlags)) {
94 // At least one is invalid and/or disabled.
95 if (kInvalid_PrivateFlag & (fFlags | that.fFlags)) {
96 return false; // We never allow invalid stencils to be equal.
97 }
98 // They're only equal if both are disabled.
99 return kDisabled_StencilFlag & (fFlags & that.fFlags);
100 }
101 if (kSingleSided_StencilFlag & (fFlags & that.fFlags)) {
102 return 0 == memcmp(&fCWFace, &that.fCWFace, sizeof(Face)); // Both are single sided.
103 } else if (kSingleSided_StencilFlag & (fFlags | that.fFlags)) {
104 return false;
105 } else {
106 return 0 == memcmp(&fCWFace, &that.fCWFace, 2 * sizeof(Face));
107 static_assert(sizeof(Face) ==
108 offsetof(GrStencilSettings, fCCWFace) - offsetof(GrStencilSettings, fCWFace));
109 }
110 // memcmp relies on GrStencilSettings::Face being tightly packed.
111 static_assert(0 == offsetof(Face, fRef));
112 static_assert(2 == sizeof(Face::fRef));
113 static_assert(2 == offsetof(Face, fTest));
114 static_assert(2 == sizeof(Face::fTest));
115 static_assert(4 == offsetof(Face, fTestMask));
116 static_assert(2 == sizeof(Face::fTestMask));
117 static_assert(6 == offsetof(Face, fPassOp));
118 static_assert(1 == sizeof(Face::fPassOp));
119 static_assert(7 == offsetof(Face, fFailOp));
120 static_assert(1 == sizeof(Face::fFailOp));
121 static_assert(8 == offsetof(Face, fWriteMask));
122 static_assert(2 == sizeof(Face::fWriteMask));
123 static_assert(10 == sizeof(Face));
124 }
125
126 static constexpr GrStencilTest gUserStencilTestToRaw[kGrUserStencilTestCount] = {
127 // Tests that respect the clip.
128 GrStencilTest::kAlways, // kAlwaysIfInClip (This is only for when there is not a stencil clip).
129 GrStencilTest::kEqual, // kEqualIfInClip.
130 GrStencilTest::kLess, // kLessIfInClip.
131 GrStencilTest::kLEqual, // kLEqualIfInClip.
132
133 // Tests that ignore the clip.
134 GrStencilTest::kAlways,
135 GrStencilTest::kNever,
136 GrStencilTest::kGreater,
137 GrStencilTest::kGEqual,
138 GrStencilTest::kLess,
139 GrStencilTest::kLEqual,
140 GrStencilTest::kEqual,
141 GrStencilTest::kNotEqual
142 };
143
144 static_assert(0 == (int)GrUserStencilTest::kAlwaysIfInClip);
145 static_assert(1 == (int)GrUserStencilTest::kEqualIfInClip);
146 static_assert(2 == (int)GrUserStencilTest::kLessIfInClip);
147 static_assert(3 == (int)GrUserStencilTest::kLEqualIfInClip);
148 static_assert(4 == (int)GrUserStencilTest::kAlways);
149 static_assert(5 == (int)GrUserStencilTest::kNever);
150 static_assert(6 == (int)GrUserStencilTest::kGreater);
151 static_assert(7 == (int)GrUserStencilTest::kGEqual);
152 static_assert(8 == (int)GrUserStencilTest::kLess);
153 static_assert(9 == (int)GrUserStencilTest::kLEqual);
154 static_assert(10 == (int)GrUserStencilTest::kEqual);
155 static_assert(11 == (int)GrUserStencilTest::kNotEqual);
156
157 static constexpr GrStencilOp gUserStencilOpToRaw[kGrUserStencilOpCount] = {
158 GrStencilOp::kKeep,
159
160 // Ops that only modify user bits.
161 GrStencilOp::kZero,
162 GrStencilOp::kReplace,
163 GrStencilOp::kInvert,
164 GrStencilOp::kIncWrap,
165 GrStencilOp::kDecWrap,
166 GrStencilOp::kIncClamp, // kIncMaybeClamp.
167 GrStencilOp::kDecClamp, // kDecMaybeClamp.
168
169 // Ops that only modify the clip bit.
170 GrStencilOp::kZero, // kZeroClipBit.
171 GrStencilOp::kReplace, // kSetClipBit.
172 GrStencilOp::kInvert, // kInvertClipBit.
173
174 // Ops that modify clip and user bits.
175 GrStencilOp::kReplace, // kSetClipAndReplaceUserBits.
176 GrStencilOp::kZero // kZeroClipAndUserBits.
177 };
178
179 static_assert(0 == (int)GrUserStencilOp::kKeep);
180 static_assert(1 == (int)GrUserStencilOp::kZero);
181 static_assert(2 == (int)GrUserStencilOp::kReplace);
182 static_assert(3 == (int)GrUserStencilOp::kInvert);
183 static_assert(4 == (int)GrUserStencilOp::kIncWrap);
184 static_assert(5 == (int)GrUserStencilOp::kDecWrap);
185 static_assert(6 == (int)GrUserStencilOp::kIncMaybeClamp);
186 static_assert(7 == (int)GrUserStencilOp::kDecMaybeClamp);
187 static_assert(8 == (int)GrUserStencilOp::kZeroClipBit);
188 static_assert(9 == (int)GrUserStencilOp::kSetClipBit);
189 static_assert(10 == (int)GrUserStencilOp::kInvertClipBit);
190 static_assert(11 == (int)GrUserStencilOp::kSetClipAndReplaceUserBits);
191 static_assert(12 == (int)GrUserStencilOp::kZeroClipAndUserBits);
192
reset(const GrUserStencilSettings::Face & user,bool hasStencilClip,int numStencilBits)193 void GrStencilSettings::Face::reset(const GrUserStencilSettings::Face& user, bool hasStencilClip,
194 int numStencilBits) {
195 SkASSERT(user.fTest < (GrUserStencilTest)kGrUserStencilTestCount);
196 SkASSERT(user.fPassOp < (GrUserStencilOp)kGrUserStencilOpCount);
197 SkASSERT(user.fFailOp < (GrUserStencilOp)kGrUserStencilOpCount);
198 SkASSERT(numStencilBits > 0 && numStencilBits <= 16);
199 int clipBit = 1 << (numStencilBits - 1);
200 int userMask = clipBit - 1;
201
202 GrUserStencilOp maxOp = std::max(user.fPassOp, user.fFailOp);
203 SkDEBUGCODE(GrUserStencilOp otherOp = std::min(user.fPassOp, user.fFailOp);)
204 if (maxOp <= kLastUserOnlyStencilOp) {
205 // Ops that only modify user bits.
206 fWriteMask = user.fWriteMask & userMask;
207 SkASSERT(otherOp <= kLastUserOnlyStencilOp);
208 } else if (maxOp <= kLastClipOnlyStencilOp) {
209 // Ops that only modify the clip bit.
210 fWriteMask = clipBit;
211 SkASSERT(GrUserStencilOp::kKeep == otherOp ||
212 (otherOp > kLastUserOnlyStencilOp && otherOp <= kLastClipOnlyStencilOp));
213 } else {
214 // Ops that modify both clip and user bits.
215 fWriteMask = clipBit | (user.fWriteMask & userMask);
216 SkASSERT(GrUserStencilOp::kKeep == otherOp || otherOp > kLastClipOnlyStencilOp);
217 }
218
219 fFailOp = gUserStencilOpToRaw[(int)user.fFailOp];
220 fPassOp = gUserStencilOpToRaw[(int)user.fPassOp];
221
222 if (!hasStencilClip || user.fTest > kLastClippedStencilTest) {
223 // Ignore the clip.
224 fTestMask = user.fTestMask & userMask;
225 fTest = gUserStencilTestToRaw[(int)user.fTest];
226 } else if (GrUserStencilTest::kAlwaysIfInClip != user.fTest) {
227 // Respect the clip.
228 fTestMask = clipBit | (user.fTestMask & userMask);
229 fTest = gUserStencilTestToRaw[(int)user.fTest];
230 } else {
231 // Test only for clip.
232 fTestMask = clipBit;
233 fTest = GrStencilTest::kEqual;
234 }
235
236 fRef = (clipBit | user.fRef) & (fTestMask | fWriteMask);
237 }
238
setDisabled()239 void GrStencilSettings::Face::setDisabled() {
240 memset(this, 0, sizeof(*this));
241 static_assert(0 == (int)GrStencilTest::kAlways);
242 static_assert(0 == (int)GrStencilOp::kKeep);
243 }
244
245 static constexpr GrUserStencilSettings gZeroStencilClipBit(
246 GrUserStencilSettings::StaticInit<
247 0x0000,
248 GrUserStencilTest::kAlways,
249 0xffff,
250 GrUserStencilOp::kZeroClipBit,
251 GrUserStencilOp::kZeroClipBit,
252 0x0000>()
253 );
254 static constexpr GrUserStencilSettings gSetStencilClipBit(
255 GrUserStencilSettings::StaticInit<
256 0x0000,
257 GrUserStencilTest::kAlways,
258 0xffff,
259 GrUserStencilOp::kSetClipBit,
260 GrUserStencilOp::kSetClipBit,
261 0x0000>()
262 );
263
SetClipBitSettings(bool setToInside)264 const GrUserStencilSettings* GrStencilSettings::SetClipBitSettings(bool setToInside) {
265 return setToInside ? &gSetStencilClipBit : &gZeroStencilClipBit;
266 }
267
genKey(GrProcessorKeyBuilder * b,bool includeRefs) const268 void GrStencilSettings::genKey(GrProcessorKeyBuilder* b, bool includeRefs) const {
269 b->addBits(6, fFlags, "stencilFlags");
270 if (this->isDisabled()) {
271 return;
272 }
273 if (!this->isTwoSided()) {
274 if (includeRefs) {
275 b->addBytes(sizeof(Face), &fCWFace, "stencilCWFace");
276 } else {
277 Face tempFace = fCWFace;
278 tempFace.fRef = 0;
279 b->addBytes(sizeof(Face), &tempFace, "stencilCWFace");
280 }
281 } else {
282 if (includeRefs) {
283 b->addBytes(sizeof(Face), &fCWFace, "stencilCWFace");
284 b->addBytes(sizeof(Face), &fCCWFace, "stencilCCWFace");
285 } else {
286 Face tempFaces[2];
287 tempFaces[0] = fCWFace;
288 tempFaces[0].fRef = 0;
289 tempFaces[1] = fCCWFace;
290 tempFaces[1].fRef = 0;
291 b->addBytes(sizeof(Face), &tempFaces[0], "stencilCWFace");
292 b->addBytes(sizeof(Face), &tempFaces[1], "stencilCCWFace");
293 }
294 }
295 // We rely on GrStencilSettings::Face being tightly packed for the key to be reliable.
296 static_assert(0 == offsetof(Face, fRef));
297 static_assert(2 == sizeof(Face::fRef));
298 static_assert(2 == offsetof(Face, fTest));
299 static_assert(2 == sizeof(Face::fTest));
300 static_assert(4 == offsetof(Face, fTestMask));
301 static_assert(2 == sizeof(Face::fTestMask));
302 static_assert(6 == offsetof(Face, fPassOp));
303 static_assert(1 == sizeof(Face::fPassOp));
304 static_assert(7 == offsetof(Face, fFailOp));
305 static_assert(1 == sizeof(Face::fFailOp));
306 static_assert(8 == offsetof(Face, fWriteMask));
307 static_assert(2 == sizeof(Face::fWriteMask));
308 static_assert(10 == sizeof(Face));
309 }
310