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