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

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

Issue 2222873002: Encapsulate GrReducedClip result in class members (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Created 4 years, 4 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
OLDNEW
1 /* 1 /*
2 * Copyright 2012 Google Inc. 2 * Copyright 2016 Google Inc.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license that can be 4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file. 5 * found in the LICENSE file.
6 */ 6 */
7 7
8 #include "GrReducedClip.h" 8 #include "GrReducedClip.h"
9 9
10 #include "GrClip.h" 10 #include "GrClip.h"
11 11
12 typedef SkClipStack::Element Element; 12 typedef SkClipStack::Element Element;
13 13
14 static GrReducedClip::InitialState reduced_stack_walker(const SkClipStack& stack , 14 static GrReducedClip::InitialState reduced_stack_walker(const SkClipStack& stack ,
15 const SkRect& queryBound s, 15 const SkRect& queryBound s,
16 const SkIRect& clipIBoun ds, 16 const SkIRect& clipIBoun ds,
17 GrReducedClip::ElementLi st* result, 17 GrReducedClip::ElementLi st* result,
18 int32_t* resultGenID, 18 int32_t* resultGenID,
19 bool* requiresAA) { 19 bool* requiresAA) {
20 20
21 // walk backwards until we get to: 21 // walk backwards until we get to:
22 // a) the beginning 22 // a) the beginning
23 // b) an operation that is known to make the bounds all inside/outside 23 // b) an operation that is known to make the bounds all inside/outside
24 // c) a replace operation 24 // c) a replace operation
25 25
26 static const GrReducedClip::InitialState kUnknown_InitialState = 26 enum class InitialTriState {
27 static_cast<GrReducedClip::InitialState>(-1); 27 kUnknown = -1,
28 GrReducedClip::InitialState initialState = kUnknown_InitialState; 28 kAllIn = (int)GrReducedClip::InitialState::kAllIn,
29 kAllOut = (int)GrReducedClip::InitialState::kAllOut
30 } initialState = InitialTriState::kUnknown;
29 31
30 // During our backwards walk, track whether we've seen ops that either grow or shrink the clip. 32 // During our backwards walk, track whether we've seen ops that either grow or shrink the clip.
31 // TODO: track these per saved clip so that we can consider them on the forw ard pass. 33 // TODO: track these per saved clip so that we can consider them on the forw ard pass.
32 bool embiggens = false; 34 bool embiggens = false;
33 bool emsmallens = false; 35 bool emsmallens = false;
34 36
35 // We use a slightly relaxed set of query bounds for element containment tes ts. This is to 37 // We use a slightly relaxed set of query bounds for element containment tes ts. This is to
36 // account for floating point rounding error that may have occurred during c oord transforms. 38 // account for floating point rounding error that may have occurred during c oord transforms.
37 SkRect relaxedQueryBounds = queryBounds.makeInset(GrClip::kBoundsTolerance, 39 SkRect relaxedQueryBounds = queryBounds.makeInset(GrClip::kBoundsTolerance,
38 GrClip::kBoundsTolerance); 40 GrClip::kBoundsTolerance);
39 41
40 SkClipStack::Iter iter(stack, SkClipStack::Iter::kTop_IterStart); 42 SkClipStack::Iter iter(stack, SkClipStack::Iter::kTop_IterStart);
41 int numAAElements = 0; 43 int numAAElements = 0;
42 while (kUnknown_InitialState == initialState) { 44 while (InitialTriState::kUnknown == initialState) {
43 const Element* element = iter.prev(); 45 const Element* element = iter.prev();
44 if (nullptr == element) { 46 if (nullptr == element) {
45 initialState = GrReducedClip::kAllIn_InitialState; 47 initialState = InitialTriState::kAllIn;
46 break; 48 break;
47 } 49 }
48 if (SkClipStack::kEmptyGenID == element->getGenID()) { 50 if (SkClipStack::kEmptyGenID == element->getGenID()) {
49 initialState = GrReducedClip::kAllOut_InitialState; 51 initialState = InitialTriState::kAllOut;
50 break; 52 break;
51 } 53 }
52 if (SkClipStack::kWideOpenGenID == element->getGenID()) { 54 if (SkClipStack::kWideOpenGenID == element->getGenID()) {
53 initialState = GrReducedClip::kAllIn_InitialState; 55 initialState = InitialTriState::kAllIn;
54 break; 56 break;
55 } 57 }
56 58
57 bool skippable = false; 59 bool skippable = false;
58 bool isFlip = false; // does this op just flip the in/out state of every point in the bounds 60 bool isFlip = false; // does this op just flip the in/out state of every point in the bounds
59 61
60 switch (element->getOp()) { 62 switch (element->getOp()) {
61 case SkRegion::kDifference_Op: 63 case SkRegion::kDifference_Op:
62 // check if the shape subtracted either contains the entire boun ds (and makes 64 // check if the shape subtracted either contains the entire boun ds (and makes
63 // the clip empty) or is outside the bounds and therefore can be skipped. 65 // the clip empty) or is outside the bounds and therefore can be skipped.
64 if (element->isInverseFilled()) { 66 if (element->isInverseFilled()) {
65 if (element->contains(relaxedQueryBounds)) { 67 if (element->contains(relaxedQueryBounds)) {
66 skippable = true; 68 skippable = true;
67 } else if (GrClip::IsOutsideClip(element->getBounds(), query Bounds)) { 69 } else if (GrClip::IsOutsideClip(element->getBounds(), query Bounds)) {
68 initialState = GrReducedClip::kAllOut_InitialState; 70 initialState = InitialTriState::kAllOut;
69 skippable = true; 71 skippable = true;
70 } 72 }
71 } else { 73 } else {
72 if (element->contains(relaxedQueryBounds)) { 74 if (element->contains(relaxedQueryBounds)) {
73 initialState = GrReducedClip::kAllOut_InitialState; 75 initialState = InitialTriState::kAllOut;
74 skippable = true; 76 skippable = true;
75 } else if (GrClip::IsOutsideClip(element->getBounds(), query Bounds)) { 77 } else if (GrClip::IsOutsideClip(element->getBounds(), query Bounds)) {
76 skippable = true; 78 skippable = true;
77 } 79 }
78 } 80 }
79 if (!skippable) { 81 if (!skippable) {
80 emsmallens = true; 82 emsmallens = true;
81 } 83 }
82 break; 84 break;
83 case SkRegion::kIntersect_Op: 85 case SkRegion::kIntersect_Op:
84 // check if the shape intersected contains the entire bounds and therefore can 86 // check if the shape intersected contains the entire bounds and therefore can
85 // be skipped or it is outside the entire bounds and therefore m akes the clip 87 // be skipped or it is outside the entire bounds and therefore m akes the clip
86 // empty. 88 // empty.
87 if (element->isInverseFilled()) { 89 if (element->isInverseFilled()) {
88 if (element->contains(relaxedQueryBounds)) { 90 if (element->contains(relaxedQueryBounds)) {
89 initialState = GrReducedClip::kAllOut_InitialState; 91 initialState = InitialTriState::kAllOut;
90 skippable = true; 92 skippable = true;
91 } else if (GrClip::IsOutsideClip(element->getBounds(), query Bounds)) { 93 } else if (GrClip::IsOutsideClip(element->getBounds(), query Bounds)) {
92 skippable = true; 94 skippable = true;
93 } 95 }
94 } else { 96 } else {
95 if (element->contains(relaxedQueryBounds)) { 97 if (element->contains(relaxedQueryBounds)) {
96 skippable = true; 98 skippable = true;
97 } else if (GrClip::IsOutsideClip(element->getBounds(), query Bounds)) { 99 } else if (GrClip::IsOutsideClip(element->getBounds(), query Bounds)) {
98 initialState = GrReducedClip::kAllOut_InitialState; 100 initialState = InitialTriState::kAllOut;
99 skippable = true; 101 skippable = true;
100 } 102 }
101 } 103 }
102 if (!skippable) { 104 if (!skippable) {
103 emsmallens = true; 105 emsmallens = true;
104 } 106 }
105 break; 107 break;
106 case SkRegion::kUnion_Op: 108 case SkRegion::kUnion_Op:
107 // If the union-ed shape contains the entire bounds then after t his element 109 // If the union-ed shape contains the entire bounds then after t his element
108 // the bounds is entirely inside the clip. If the union-ed shape is outside the 110 // the bounds is entirely inside the clip. If the union-ed shape is outside the
109 // bounds then this op can be skipped. 111 // bounds then this op can be skipped.
110 if (element->isInverseFilled()) { 112 if (element->isInverseFilled()) {
111 if (element->contains(relaxedQueryBounds)) { 113 if (element->contains(relaxedQueryBounds)) {
112 skippable = true; 114 skippable = true;
113 } else if (GrClip::IsOutsideClip(element->getBounds(), query Bounds)) { 115 } else if (GrClip::IsOutsideClip(element->getBounds(), query Bounds)) {
114 initialState = GrReducedClip::kAllIn_InitialState; 116 initialState = InitialTriState::kAllIn;
115 skippable = true; 117 skippable = true;
116 } 118 }
117 } else { 119 } else {
118 if (element->contains(relaxedQueryBounds)) { 120 if (element->contains(relaxedQueryBounds)) {
119 initialState = GrReducedClip::kAllIn_InitialState; 121 initialState = InitialTriState::kAllIn;
120 skippable = true; 122 skippable = true;
121 } else if (GrClip::IsOutsideClip(element->getBounds(), query Bounds)) { 123 } else if (GrClip::IsOutsideClip(element->getBounds(), query Bounds)) {
122 skippable = true; 124 skippable = true;
123 } 125 }
124 } 126 }
125 if (!skippable) { 127 if (!skippable) {
126 embiggens = true; 128 embiggens = true;
127 } 129 }
128 break; 130 break;
129 case SkRegion::kXOR_Op: 131 case SkRegion::kXOR_Op:
(...skipping 18 matching lines...) Expand all
148 emsmallens = embiggens = true; 150 emsmallens = embiggens = true;
149 } 151 }
150 break; 152 break;
151 case SkRegion::kReverseDifference_Op: 153 case SkRegion::kReverseDifference_Op:
152 // When the bounds is entirely within the rev-diff shape then th is behaves like xor 154 // When the bounds is entirely within the rev-diff shape then th is behaves like xor
153 // and reverses every point inside the bounds. If the shape is c ompletely outside 155 // and reverses every point inside the bounds. If the shape is c ompletely outside
154 // the bounds then we know after this element is applied that th e bounds will be 156 // the bounds then we know after this element is applied that th e bounds will be
155 // all outside the current clip.B 157 // all outside the current clip.B
156 if (element->isInverseFilled()) { 158 if (element->isInverseFilled()) {
157 if (element->contains(relaxedQueryBounds)) { 159 if (element->contains(relaxedQueryBounds)) {
158 initialState = GrReducedClip::kAllOut_InitialState; 160 initialState = InitialTriState::kAllOut;
159 skippable = true; 161 skippable = true;
160 } else if (GrClip::IsOutsideClip(element->getBounds(), query Bounds)) { 162 } else if (GrClip::IsOutsideClip(element->getBounds(), query Bounds)) {
161 isFlip = true; 163 isFlip = true;
162 } 164 }
163 } else { 165 } else {
164 if (element->contains(relaxedQueryBounds)) { 166 if (element->contains(relaxedQueryBounds)) {
165 isFlip = true; 167 isFlip = true;
166 } else if (GrClip::IsOutsideClip(element->getBounds(), query Bounds)) { 168 } else if (GrClip::IsOutsideClip(element->getBounds(), query Bounds)) {
167 initialState = GrReducedClip::kAllOut_InitialState; 169 initialState = InitialTriState::kAllOut;
168 skippable = true; 170 skippable = true;
169 } 171 }
170 } 172 }
171 if (!skippable) { 173 if (!skippable) {
172 emsmallens = embiggens = true; 174 emsmallens = embiggens = true;
173 } 175 }
174 break; 176 break;
175 177
176 case SkRegion::kReplace_Op: 178 case SkRegion::kReplace_Op:
177 // Replace will always terminate our walk. We will either begin the forward walk 179 // Replace will always terminate our walk. We will either begin the forward walk
178 // at the replace op or detect here than the shape is either com pletely inside 180 // at the replace op or detect here than the shape is either com pletely inside
179 // or completely outside the bounds. In this latter case it can be skipped by 181 // or completely outside the bounds. In this latter case it can be skipped by
180 // setting the correct value for initialState. 182 // setting the correct value for initialState.
181 if (element->isInverseFilled()) { 183 if (element->isInverseFilled()) {
182 if (element->contains(relaxedQueryBounds)) { 184 if (element->contains(relaxedQueryBounds)) {
183 initialState = GrReducedClip::kAllOut_InitialState; 185 initialState = InitialTriState::kAllOut;
184 skippable = true; 186 skippable = true;
185 } else if (GrClip::IsOutsideClip(element->getBounds(), query Bounds)) { 187 } else if (GrClip::IsOutsideClip(element->getBounds(), query Bounds)) {
186 initialState = GrReducedClip::kAllIn_InitialState; 188 initialState = InitialTriState::kAllIn;
187 skippable = true; 189 skippable = true;
188 } 190 }
189 } else { 191 } else {
190 if (element->contains(relaxedQueryBounds)) { 192 if (element->contains(relaxedQueryBounds)) {
191 initialState = GrReducedClip::kAllIn_InitialState; 193 initialState = InitialTriState::kAllIn;
192 skippable = true; 194 skippable = true;
193 } else if (GrClip::IsOutsideClip(element->getBounds(), query Bounds)) { 195 } else if (GrClip::IsOutsideClip(element->getBounds(), query Bounds)) {
194 initialState = GrReducedClip::kAllOut_InitialState; 196 initialState = InitialTriState::kAllOut;
195 skippable = true; 197 skippable = true;
196 } 198 }
197 } 199 }
198 if (!skippable) { 200 if (!skippable) {
199 initialState = GrReducedClip::kAllOut_InitialState; 201 initialState = InitialTriState::kAllOut;
200 embiggens = emsmallens = true; 202 embiggens = emsmallens = true;
201 } 203 }
202 break; 204 break;
203 default: 205 default:
204 SkDEBUGFAIL("Unexpected op."); 206 SkDEBUGFAIL("Unexpected op.");
205 break; 207 break;
206 } 208 }
207 if (!skippable) { 209 if (!skippable) {
208 if (0 == result->count()) { 210 if (0 == result->count()) {
209 // This will be the last element. Record the stricter genID. 211 // This will be the last element. Record the stricter genID.
(...skipping 13 matching lines...) Expand all
223 } 225 }
224 // Intersecting an inverse shape is the same as differencing the non-inverse shape. 226 // Intersecting an inverse shape is the same as differencing the non-inverse shape.
225 // Replacing with an inverse shape is the same as setting initia lState=kAllIn and 227 // Replacing with an inverse shape is the same as setting initia lState=kAllIn and
226 // differencing the non-inverse shape. 228 // differencing the non-inverse shape.
227 bool isReplace = SkRegion::kReplace_Op == newElement->getOp(); 229 bool isReplace = SkRegion::kReplace_Op == newElement->getOp();
228 if (newElement->isInverseFilled() && 230 if (newElement->isInverseFilled() &&
229 (SkRegion::kIntersect_Op == newElement->getOp() || isReplace )) { 231 (SkRegion::kIntersect_Op == newElement->getOp() || isReplace )) {
230 newElement->invertShapeFillType(); 232 newElement->invertShapeFillType();
231 newElement->setOp(SkRegion::kDifference_Op); 233 newElement->setOp(SkRegion::kDifference_Op);
232 if (isReplace) { 234 if (isReplace) {
233 SkASSERT(GrReducedClip::kAllOut_InitialState == initialS tate); 235 SkASSERT(InitialTriState::kAllOut == initialState);
234 initialState = GrReducedClip::kAllIn_InitialState; 236 initialState = InitialTriState::kAllIn;
235 } 237 }
236 } 238 }
237 } 239 }
238 } 240 }
239 } 241 }
240 242
241 if ((GrReducedClip::kAllOut_InitialState == initialState && !embiggens) || 243 if ((InitialTriState::kAllOut == initialState && !embiggens) ||
242 (GrReducedClip::kAllIn_InitialState == initialState && !emsmallens)) { 244 (InitialTriState::kAllIn == initialState && !emsmallens)) {
243 result->reset(); 245 result->reset();
244 numAAElements = 0; 246 numAAElements = 0;
245 } else { 247 } else {
246 Element* element = result->headIter().get(); 248 Element* element = result->headIter().get();
247 while (element) { 249 while (element) {
248 bool skippable = false; 250 bool skippable = false;
249 switch (element->getOp()) { 251 switch (element->getOp()) {
250 case SkRegion::kDifference_Op: 252 case SkRegion::kDifference_Op:
251 // subtracting from the empty set yields the empty set. 253 // subtracting from the empty set yields the empty set.
252 skippable = GrReducedClip::kAllOut_InitialState == initialSt ate; 254 skippable = InitialTriState::kAllOut == initialState;
253 break; 255 break;
254 case SkRegion::kIntersect_Op: 256 case SkRegion::kIntersect_Op:
255 // intersecting with the empty set yields the empty set 257 // intersecting with the empty set yields the empty set
256 if (GrReducedClip::kAllOut_InitialState == initialState) { 258 if (InitialTriState::kAllOut == initialState) {
257 skippable = true; 259 skippable = true;
258 } else { 260 } else {
259 // We can clear to zero and then simply draw the clip el ement. 261 // We can clear to zero and then simply draw the clip el ement.
260 initialState = GrReducedClip::kAllOut_InitialState; 262 initialState = InitialTriState::kAllOut;
261 element->setOp(SkRegion::kReplace_Op); 263 element->setOp(SkRegion::kReplace_Op);
262 } 264 }
263 break; 265 break;
264 case SkRegion::kUnion_Op: 266 case SkRegion::kUnion_Op:
265 if (GrReducedClip::kAllIn_InitialState == initialState) { 267 if (InitialTriState::kAllIn == initialState) {
266 // unioning the infinite plane with anything is a no-op. 268 // unioning the infinite plane with anything is a no-op.
267 skippable = true; 269 skippable = true;
268 } else { 270 } else {
269 // unioning the empty set with a shape is the shape. 271 // unioning the empty set with a shape is the shape.
270 element->setOp(SkRegion::kReplace_Op); 272 element->setOp(SkRegion::kReplace_Op);
271 } 273 }
272 break; 274 break;
273 case SkRegion::kXOR_Op: 275 case SkRegion::kXOR_Op:
274 if (GrReducedClip::kAllOut_InitialState == initialState) { 276 if (InitialTriState::kAllOut == initialState) {
275 // xor could be changed to diff in the kAllIn case, not sure it's a win. 277 // xor could be changed to diff in the kAllIn case, not sure it's a win.
276 element->setOp(SkRegion::kReplace_Op); 278 element->setOp(SkRegion::kReplace_Op);
277 } 279 }
278 break; 280 break;
279 case SkRegion::kReverseDifference_Op: 281 case SkRegion::kReverseDifference_Op:
280 if (GrReducedClip::kAllIn_InitialState == initialState) { 282 if (InitialTriState::kAllIn == initialState) {
281 // subtracting the whole plane will yield the empty set. 283 // subtracting the whole plane will yield the empty set.
282 skippable = true; 284 skippable = true;
283 initialState = GrReducedClip::kAllOut_InitialState; 285 initialState = InitialTriState::kAllOut;
284 } else { 286 } else {
285 // this picks up flips inserted in the backwards pass. 287 // this picks up flips inserted in the backwards pass.
286 skippable = element->isInverseFilled() ? 288 skippable = element->isInverseFilled() ?
287 GrClip::IsOutsideClip(element->getBounds(), queryBou nds) : 289 GrClip::IsOutsideClip(element->getBounds(), queryBou nds) :
288 element->contains(relaxedQueryBounds); 290 element->contains(relaxedQueryBounds);
289 if (skippable) { 291 if (skippable) {
290 initialState = GrReducedClip::kAllIn_InitialState; 292 initialState = InitialTriState::kAllIn;
291 } else { 293 } else {
292 element->setOp(SkRegion::kReplace_Op); 294 element->setOp(SkRegion::kReplace_Op);
293 } 295 }
294 } 296 }
295 break; 297 break;
296 case SkRegion::kReplace_Op: 298 case SkRegion::kReplace_Op:
297 skippable = false; // we would have skipped it in the backwa rds walk if we 299 skippable = false; // we would have skipped it in the backwa rds walk if we
298 // could've. 300 // could've.
299 break; 301 break;
300 default: 302 default:
301 SkDEBUGFAIL("Unexpected op."); 303 SkDEBUGFAIL("Unexpected op.");
302 break; 304 break;
303 } 305 }
304 if (!skippable) { 306 if (!skippable) {
305 break; 307 break;
306 } else { 308 } else {
307 if (element->isAA()) { 309 if (element->isAA()) {
308 --numAAElements; 310 --numAAElements;
309 } 311 }
310 result->popHead(); 312 result->popHead();
311 element = result->headIter().get(); 313 element = result->headIter().get();
312 } 314 }
313 } 315 }
314 } 316 }
315 *requiresAA = numAAElements > 0; 317 *requiresAA = numAAElements > 0;
316 318
317 if (0 == result->count()) { 319 if (0 == result->count()) {
318 if (initialState == GrReducedClip::kAllIn_InitialState) { 320 if (initialState == InitialTriState::kAllIn) {
319 *resultGenID = SkClipStack::kWideOpenGenID; 321 *resultGenID = SkClipStack::kWideOpenGenID;
320 } else { 322 } else {
321 *resultGenID = SkClipStack::kEmptyGenID; 323 *resultGenID = SkClipStack::kEmptyGenID;
322 } 324 }
323 } 325 }
324 326
325 SkASSERT(SkClipStack::kInvalidGenID != *resultGenID); 327 SkASSERT(SkClipStack::kInvalidGenID != *resultGenID);
326 return initialState; 328 SkASSERT(InitialTriState::kUnknown != initialState);
329 return static_cast<GrReducedClip::InitialState>(initialState);
327 } 330 }
328 331
329 /* 332 /*
330 There are plenty of optimizations that could be added here. Maybe flips could be folded into 333 There are plenty of optimizations that could be added here. Maybe flips could be folded into
331 earlier operations. Or would inserting flips and reversing earlier ops ever be a win? Perhaps 334 earlier operations. Or would inserting flips and reversing earlier ops ever be a win? Perhaps
332 for the case where the bounds are kInsideOut_BoundsType. We could restrict earli er operations 335 for the case where the bounds are kInsideOut_BoundsType. We could restrict earli er operations
333 based on later intersect operations, and perhaps remove intersect-rects. We coul d optionally 336 based on later intersect operations, and perhaps remove intersect-rects. We coul d optionally
334 take a rect in case the caller knows a bound on what is to be drawn through this clip. 337 take a rect in case the caller knows a bound on what is to be drawn through this clip.
335 */ 338 */
336 GrReducedClip::InitialState GrReducedClip::ReduceClipStack(const SkClipStack& st ack, 339 GrReducedClip::GrReducedClip(const SkClipStack& stack, const SkRect& queryBounds ) {
337 const SkRect& queryBo unds,
338 ElementList* result,
339 int32_t* resultGenID,
340 SkIRect* clipIBounds,
341 bool* requiresAA) {
342 SkASSERT(!queryBounds.isEmpty()); 340 SkASSERT(!queryBounds.isEmpty());
343 result->reset();
344 341
345 // The clip established by the element list might be cached based on the las t 342 // The clip established by the element list might be cached based on the las t
346 // generation id. When we make early returns, we do not know what was the ge neration 343 // generation id. When we make early returns, we do not know what was the ge neration
347 // id that lead to the state. Make a conservative guess. 344 // id that lead to the state. Make a conservative guess.
348 *resultGenID = stack.getTopmostGenID(); 345 fGenID = stack.getTopmostGenID();
349 346
350 // TODO: instead devise a way of telling the caller to disregard some or all of the clip bounds. 347 // TODO: instead devise a way of telling the caller to disregard some or all of the clip bounds.
351 *clipIBounds = GrClip::GetPixelIBounds(queryBounds); 348 fIBounds = GrClip::GetPixelIBounds(queryBounds);
352 349
353 if (stack.isWideOpen()) { 350 if (stack.isWideOpen()) {
354 return kAllIn_InitialState; 351 fInitialState = InitialState::kAllIn;
352 return;
355 } 353 }
356 354
357 SkClipStack::BoundsType stackBoundsType; 355 SkClipStack::BoundsType stackBoundsType;
358 SkRect stackBounds; 356 SkRect stackBounds;
359 bool iior; 357 bool iior;
360 stack.getBounds(&stackBounds, &stackBoundsType, &iior); 358 stack.getBounds(&stackBounds, &stackBoundsType, &iior);
361 359
362 if (stackBounds.isEmpty() || GrClip::IsOutsideClip(stackBounds, queryBounds) ) { 360 if (stackBounds.isEmpty() || GrClip::IsOutsideClip(stackBounds, queryBounds) ) {
363 bool insideOut = SkClipStack::kInsideOut_BoundsType == stackBoundsType; 361 bool insideOut = SkClipStack::kInsideOut_BoundsType == stackBoundsType;
364 return insideOut ? kAllIn_InitialState : kAllOut_InitialState; 362 fInitialState = insideOut ? InitialState::kAllIn : InitialState::kAllOut ;
363 return;
365 } 364 }
366 365
367 if (iior) { 366 if (iior) {
368 // "Is intersection of rects" means the clip is a single rect indicated by the stack bounds. 367 // "Is intersection of rects" means the clip is a single rect indicated by the stack bounds.
369 // This should only be true if aa/non-aa status matches among all elemen ts. 368 // This should only be true if aa/non-aa status matches among all elemen ts.
370 SkASSERT(SkClipStack::kNormal_BoundsType == stackBoundsType); 369 SkASSERT(SkClipStack::kNormal_BoundsType == stackBoundsType);
371 SkClipStack::Iter iter(stack, SkClipStack::Iter::kTop_IterStart); 370 SkClipStack::Iter iter(stack, SkClipStack::Iter::kTop_IterStart);
372 if (!iter.prev()->isAA() || GrClip::IsPixelAligned(stackBounds)) { 371 if (!iter.prev()->isAA() || GrClip::IsPixelAligned(stackBounds)) {
373 // The clip is a non-aa rect. This is the one spot where we can actu ally implement the 372 // The clip is a non-aa rect. This is the one spot where we can actu ally implement the
374 // clip (using clipIBounds) rather than just telling the caller what it should be. 373 // clip (using fIBounds) rather than just telling the caller what it should be.
375 stackBounds.round(clipIBounds); 374 stackBounds.round(&fIBounds);
376 return kAllIn_InitialState; 375 fInitialState = fIBounds.isEmpty() ? InitialState::kAllOut : Initial State::kAllIn;
376 return;
377 } 377 }
378 if (GrClip::IsInsideClip(stackBounds, queryBounds)) { 378 if (GrClip::IsInsideClip(stackBounds, queryBounds)) {
379 return kAllIn_InitialState; 379 fInitialState = InitialState::kAllIn;
380 return;
380 } 381 }
381 382
383 SkAssertResult(fIBounds.intersect(GrClip::GetPixelIBounds(stackBounds))) ;
384 SkASSERT(!fIBounds.isEmpty()); // Empty should have been blocked by IsOu tsideClip above.
385
382 // Implement the clip with an AA rect element. 386 // Implement the clip with an AA rect element.
383 result->addToHead(stackBounds, SkRegion::kReplace_Op, true/*doAA*/); 387 fElements.addToHead(stackBounds, SkRegion::kReplace_Op, true/*doAA*/);
384 *requiresAA = true; 388 fRequiresAA = true;
385 389
386 SkAssertResult(clipIBounds->intersect(GrClip::GetPixelIBounds(stackBound s))); 390 fInitialState = InitialState::kAllOut;
387 return kAllOut_InitialState; 391 return;
388 } 392 }
389 393
390 SkRect tighterQuery = queryBounds; 394 SkRect tighterQuery = queryBounds;
391 if (SkClipStack::kNormal_BoundsType == stackBoundsType) { 395 if (SkClipStack::kNormal_BoundsType == stackBoundsType) {
392 // Tighten the query by introducing a new clip at the stack's pixel boun daries. (This new 396 // Tighten the query by introducing a new clip at the stack's pixel boun daries. (This new
393 // clip will be enforced by the scissor through clipIBounds.) 397 // clip will be enforced by the scissor through fIBounds.)
394 SkAssertResult(tighterQuery.intersect(GrClip::GetPixelBounds(stackBounds ))); 398 SkAssertResult(tighterQuery.intersect(GrClip::GetPixelBounds(stackBounds )));
395 *clipIBounds = GrClip::GetPixelIBounds(tighterQuery); 399 fIBounds = GrClip::GetPixelIBounds(tighterQuery);
396 } 400 }
397 401
402 SkASSERT(!fIBounds.isEmpty()); // Empty should have been blocked by IsOutsid eClip above.
403
398 // Now that we have determined the bounds to use and filtered out the trivia l cases, call the 404 // Now that we have determined the bounds to use and filtered out the trivia l cases, call the
399 // helper that actually walks the stack. 405 // helper that actually walks the stack.
400 return reduced_stack_walker(stack, tighterQuery, *clipIBounds, result, resul tGenID, requiresAA); 406 fInitialState = reduced_stack_walker(stack, tighterQuery, fIBounds, &fElemen ts, &fGenID,
407 &fRequiresAA);
401 } 408 }
OLDNEW
« include/gpu/GrClip.h ('K') | « src/gpu/GrReducedClip.h ('k') | src/utils/SkLua.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698