• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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