Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(48)

Side by Side Diff: src/gpu/GrStencil.cpp

Issue 1962243002: Separate user and raw stencil settings (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Created 4 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/gpu/GrStencil.h ('k') | src/gpu/GrStencilSettings.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
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 "GrStencil.h"
10
11 #include "GrProcessor.h"
12
13 ////////////////////////////////////////////////////////////////////////////////
14 // Stencil Rules for Merging user stencil space into clip
15
16 // We can't include the clip bit in the ref or mask values because the division
17 // between user and clip bits in the stencil depends on the number of stencil
18 // bits in the runtime. Comments below indicate what the code should do to
19 // incorporate the clip bit into these settings.
20
21 ///////
22 // Replace
23
24 // set the ref to be the clip bit, but mask it out for the test
25 static constexpr GrStencilSettings gUserToClipReplace(
26 kReplace_StencilOp,
27 kZero_StencilOp,
28 kLess_StencilFunc,
29 0xffff, // unset clip bit
30 0x0000, // set clip bit
31 0xffff);
32
33 static constexpr GrStencilSettings gInvUserToClipReplace(
34 kReplace_StencilOp,
35 kZero_StencilOp,
36 kEqual_StencilFunc,
37 0xffff, // unset clip bit
38 0x0000, // set clip bit
39 0xffff);
40
41 ///////
42 // Intersect
43 static constexpr GrStencilSettings gUserToClipIsect(
44 kReplace_StencilOp,
45 kZero_StencilOp,
46 kLess_StencilFunc,
47 0xffff,
48 0x0000, // set clip bit
49 0xffff);
50
51 static constexpr GrStencilSettings gInvUserToClipIsect(
52 kReplace_StencilOp,
53 kZero_StencilOp,
54 kEqual_StencilFunc,
55 0xffff,
56 0x0000, // set clip bit
57 0xffff);
58
59 ///////
60 // Difference
61 static constexpr GrStencilSettings gUserToClipDiff(
62 kReplace_StencilOp,
63 kZero_StencilOp,
64 kEqual_StencilFunc,
65 0xffff,
66 0x0000, // set clip bit
67 0xffff);
68
69 static constexpr GrStencilSettings gInvUserToClipDiff(
70 kReplace_StencilOp,
71 kZero_StencilOp,
72 kLess_StencilFunc,
73 0xffff,
74 0x0000, // set clip bit
75 0xffff);
76
77 ///////
78 // Union
79
80 // first pass makes all the passing cases >= just clip bit set.
81 static constexpr GrStencilSettings gUserToClipUnionPass0(
82 kReplace_StencilOp,
83 kKeep_StencilOp,
84 kLEqual_StencilFunc,
85 0xffff,
86 0x0001, // set clip bit
87 0xffff);
88
89 // second pass allows anything greater than just clip bit set to pass
90 static constexpr GrStencilSettings gUserToClipUnionPass1(
91 kReplace_StencilOp,
92 kZero_StencilOp,
93 kLEqual_StencilFunc,
94 0xffff,
95 0x0000, // set clip bit
96 0xffff);
97
98 // first pass finds zeros in the user bits and if found sets
99 // the clip bit to 1
100 static constexpr GrStencilSettings gInvUserToClipUnionPass0(
101 kReplace_StencilOp,
102 kKeep_StencilOp,
103 kEqual_StencilFunc,
104 0xffff,
105 0x0000, // set clip bit
106 0x0000 // set clip bit
107 );
108
109 // second pass zeros the user bits
110 static constexpr GrStencilSettings gInvUserToClipUnionPass1(
111 kZero_StencilOp,
112 kZero_StencilOp,
113 kLess_StencilFunc,
114 0xffff,
115 0x0000,
116 0xffff // unset clip bit
117 );
118
119 ///////
120 // Xor
121 static constexpr GrStencilSettings gUserToClipXorPass0(
122 kInvert_StencilOp,
123 kKeep_StencilOp,
124 kEqual_StencilFunc,
125 0xffff, // unset clip bit
126 0x0000,
127 0xffff);
128
129 static constexpr GrStencilSettings gUserToClipXorPass1(
130 kReplace_StencilOp,
131 kZero_StencilOp,
132 kGreater_StencilFunc,
133 0xffff,
134 0x0000, // set clip bit
135 0xffff);
136
137 static constexpr GrStencilSettings gInvUserToClipXorPass0(
138 kInvert_StencilOp,
139 kKeep_StencilOp,
140 kEqual_StencilFunc,
141 0xffff, // unset clip bit
142 0x0000,
143 0xffff);
144
145 static constexpr GrStencilSettings gInvUserToClipXorPass1(
146 kReplace_StencilOp,
147 kZero_StencilOp,
148 kLess_StencilFunc,
149 0xffff,
150 0x0000, // set clip bit
151 0xffff);
152
153 ///////
154 // Reverse Diff
155 static constexpr GrStencilSettings gUserToClipRDiffPass0(
156 kInvert_StencilOp,
157 kZero_StencilOp,
158 kLess_StencilFunc,
159 0xffff, // unset clip bit
160 0x0000, // set clip bit
161 0xffff);
162
163 static constexpr GrStencilSettings gUserToClipRDiffPass1(
164 kReplace_StencilOp,
165 kZero_StencilOp,
166 kEqual_StencilFunc,
167 0x0000, // set clip bit
168 0x0000, // set clip bit
169 0xffff);
170
171 // We are looking for stencil values that are all zero. The first pass sets the
172 // clip bit if the stencil is all zeros. The second pass clears the user bits.
173 static constexpr GrStencilSettings gInvUserToClipRDiffPass0(
174 kInvert_StencilOp,
175 kZero_StencilOp,
176 kEqual_StencilFunc,
177 0xffff,
178 0x0000,
179 0x0000 // set clip bit
180 );
181
182 static constexpr GrStencilSettings gInvUserToClipRDiffPass1(
183 kZero_StencilOp,
184 kZero_StencilOp,
185 kAlways_StencilFunc,
186 0xffff,
187 0x0000,
188 0xffff // unset clip bit
189 );
190
191 ///////
192 // Direct to Stencil
193
194 // We can render a clip element directly without first writing to the client
195 // portion of the clip when the fill is not inverse and the set operation will
196 // only modify the in/out status of samples covered by the clip element.
197
198 // this one only works if used right after stencil clip was cleared.
199 // Our clip mask creation code doesn't allow midstream replace ops.
200 static constexpr GrStencilSettings gReplaceClip(
201 kReplace_StencilOp,
202 kReplace_StencilOp,
203 kAlways_StencilFunc,
204 0xffff,
205 0x0000, // set clip bit
206 0x0000 // set clipBit
207 );
208
209 static constexpr GrStencilSettings gUnionClip(
210 kReplace_StencilOp,
211 kReplace_StencilOp,
212 kAlways_StencilFunc,
213 0xffff,
214 0x0000, // set clip bit
215 0x0000 // set clip bit
216 );
217
218 static constexpr GrStencilSettings gXorClip(
219 kInvert_StencilOp,
220 kInvert_StencilOp,
221 kAlways_StencilFunc,
222 0xffff,
223 0x0000,
224 0x0000 // set clip bit
225 );
226
227 static constexpr GrStencilSettings gDiffClip(
228 kZero_StencilOp,
229 kZero_StencilOp,
230 kAlways_StencilFunc,
231 0xffff,
232 0x0000,
233 0x0000 // set clip bit
234 );
235
236 bool GrStencilSettings::GetClipPasses(
237 SkRegion::Op op,
238 bool canBeDirect,
239 unsigned int stencilClipMask,
240 bool invertedFill,
241 int* numPasses,
242 GrStencilSettings settings[kMaxStencilClipPasses]) {
243 if (canBeDirect && !invertedFill) {
244 *numPasses = 0;
245 switch (op) {
246 case SkRegion::kReplace_Op:
247 *numPasses = 1;
248 settings[0] = gReplaceClip;
249 break;
250 case SkRegion::kUnion_Op:
251 *numPasses = 1;
252 settings[0] = gUnionClip;
253 break;
254 case SkRegion::kXOR_Op:
255 *numPasses = 1;
256 settings[0] = gXorClip;
257 break;
258 case SkRegion::kDifference_Op:
259 *numPasses = 1;
260 settings[0] = gDiffClip;
261 break;
262 default: // suppress warning
263 break;
264 }
265 if (1 == *numPasses) {
266 settings[0].fFuncRefs[kFront_Face] |= stencilClipMask;
267 settings[0].fWriteMasks[kFront_Face] |= stencilClipMask;
268 settings[0].fFuncRefs[kBack_Face] =
269 settings[0].fFuncRefs[kFront_Face];
270 settings[0].fWriteMasks[kBack_Face] =
271 settings[0].fWriteMasks[kFront_Face];
272 return true;
273 }
274 }
275 switch (op) {
276 // if we make the path renderer go to stencil we always give it a
277 // non-inverted fill and we use the stencil rules on the client->clipbit
278 // pass to select either the zeros or nonzeros.
279 case SkRegion::kReplace_Op:
280 *numPasses= 1;
281 settings[0] = invertedFill ? gInvUserToClipReplace :
282 gUserToClipReplace;
283 settings[0].fFuncMasks[kFront_Face] &= ~stencilClipMask;
284 settings[0].fFuncRefs[kFront_Face] |= stencilClipMask;
285 settings[0].fFuncMasks[kBack_Face] =
286 settings[0].fFuncMasks[kFront_Face];
287 settings[0].fFuncRefs[kBack_Face] =
288 settings[0].fFuncRefs[kFront_Face];
289 break;
290 case SkRegion::kIntersect_Op:
291 *numPasses = 1;
292 settings[0] = invertedFill ? gInvUserToClipIsect : gUserToClipIsect;
293 settings[0].fFuncRefs[kFront_Face] = stencilClipMask;
294 settings[0].fFuncRefs[kBack_Face] =
295 settings[0].fFuncRefs[kFront_Face];
296 break;
297 case SkRegion::kUnion_Op:
298 *numPasses = 2;
299 if (invertedFill) {
300 settings[0] = gInvUserToClipUnionPass0;
301 settings[0].fFuncMasks[kFront_Face] &= ~stencilClipMask;
302 settings[0].fFuncMasks[kBack_Face] =
303 settings[0].fFuncMasks[kFront_Face];
304 settings[0].fFuncRefs[kFront_Face] |= stencilClipMask;
305 settings[0].fFuncRefs[kBack_Face] =
306 settings[0].fFuncRefs[kFront_Face];
307 settings[0].fWriteMasks[kFront_Face] |= stencilClipMask;
308 settings[0].fWriteMasks[kBack_Face] =
309 settings[0].fWriteMasks[kFront_Face];
310
311 settings[1] = gInvUserToClipUnionPass1;
312 settings[1].fWriteMasks[kFront_Face] &= ~stencilClipMask;
313 settings[1].fWriteMasks[kBack_Face] &=
314 settings[1].fWriteMasks[kFront_Face];
315
316 } else {
317 settings[0] = gUserToClipUnionPass0;
318 settings[0].fFuncMasks[kFront_Face] &= ~stencilClipMask;
319 settings[0].fFuncRefs[kFront_Face] |= stencilClipMask;
320 settings[0].fFuncMasks[kBack_Face] =
321 settings[0].fFuncMasks[kFront_Face];
322 settings[0].fFuncRefs[kBack_Face] =
323 settings[0].fFuncRefs[kFront_Face];
324
325 settings[1] = gUserToClipUnionPass1;
326 settings[1].fFuncRefs[kFront_Face] |= stencilClipMask;
327 settings[1].fFuncRefs[kBack_Face] =
328 settings[1].fFuncRefs[kFront_Face];
329 }
330 break;
331 case SkRegion::kXOR_Op:
332 *numPasses = 2;
333 if (invertedFill) {
334 settings[0] = gInvUserToClipXorPass0;
335 settings[0].fFuncMasks[kFront_Face] &= ~stencilClipMask;
336 settings[0].fFuncMasks[kBack_Face] =
337 settings[0].fFuncMasks[kFront_Face];
338
339 settings[1] = gInvUserToClipXorPass1;
340 settings[1].fFuncRefs[kFront_Face] |= stencilClipMask;
341 settings[1].fFuncRefs[kBack_Face] =
342 settings[1].fFuncRefs[kFront_Face];
343 } else {
344 settings[0] = gUserToClipXorPass0;
345 settings[0].fFuncMasks[kFront_Face] &= ~stencilClipMask;
346 settings[0].fFuncMasks[kBack_Face] =
347 settings[0].fFuncMasks[kFront_Face];
348
349 settings[1] = gUserToClipXorPass1;
350 settings[1].fFuncRefs[kFront_Face] |= stencilClipMask;
351 settings[1].fFuncRefs[kBack_Face] =
352 settings[1].fFuncRefs[kFront_Face];
353 }
354 break;
355 case SkRegion::kDifference_Op:
356 *numPasses = 1;
357 settings[0] = invertedFill ? gInvUserToClipDiff : gUserToClipDiff;
358 settings[0].fFuncRefs[kFront_Face] |= stencilClipMask;
359 settings[0].fFuncRefs[kBack_Face] =
360 settings[0].fFuncRefs[kFront_Face];
361 break;
362 case SkRegion::kReverseDifference_Op:
363 if (invertedFill) {
364 *numPasses = 2;
365 settings[0] = gInvUserToClipRDiffPass0;
366 settings[0].fWriteMasks[kFront_Face] |= stencilClipMask;
367 settings[0].fWriteMasks[kBack_Face] =
368 settings[0].fWriteMasks[kFront_Face];
369 settings[1] = gInvUserToClipRDiffPass1;
370 settings[1].fWriteMasks[kFront_Face] &= ~stencilClipMask;
371 settings[1].fWriteMasks[kBack_Face] =
372 settings[1].fWriteMasks[kFront_Face];
373 } else {
374 *numPasses = 2;
375 settings[0] = gUserToClipRDiffPass0;
376 settings[0].fFuncMasks[kFront_Face] &= ~stencilClipMask;
377 settings[0].fFuncMasks[kBack_Face] =
378 settings[0].fFuncMasks[kFront_Face];
379 settings[0].fFuncRefs[kFront_Face] |= stencilClipMask;
380 settings[0].fFuncRefs[kBack_Face] =
381 settings[0].fFuncRefs[kFront_Face];
382
383 settings[1] = gUserToClipRDiffPass1;
384 settings[1].fFuncMasks[kFront_Face] |= stencilClipMask;
385 settings[1].fFuncRefs[kFront_Face] |= stencilClipMask;
386 settings[1].fFuncMasks[kBack_Face] =
387 settings[1].fFuncMasks[kFront_Face];
388 settings[1].fFuncRefs[kBack_Face] =
389 settings[1].fFuncRefs[kFront_Face];
390 }
391 break;
392 default:
393 SkFAIL("Unknown set op");
394 }
395 return false;
396 }
397
398 void GrStencilSettings::genKey(GrProcessorKeyBuilder* b) const {
399 static const int kCount = sizeof(GrStencilSettings) / sizeof(uint32_t);
400 GR_STATIC_ASSERT(0 == sizeof(GrStencilSettings) % sizeof(uint32_t));
401 uint32_t* key = b->add32n(kCount);
402 memcpy(key, this, sizeof(GrStencilSettings));
403 }
OLDNEW
« no previous file with comments | « src/gpu/GrStencil.h ('k') | src/gpu/GrStencilSettings.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698