OLD | NEW |
---|---|
1 | 1 |
2 /* | 2 /* |
3 * Copyright 2011 Google Inc. | 3 * Copyright 2011 Google Inc. |
4 * | 4 * |
5 * Use of this source code is governed by a BSD-style license that can be | 5 * Use of this source code is governed by a BSD-style license that can be |
6 * found in the LICENSE file. | 6 * found in the LICENSE file. |
7 */ | 7 */ |
8 #include "SkClipStack.h" | 8 #include "SkClipStack.h" |
9 #include "SkPath.h" | 9 #include "SkPath.h" |
10 #include "SkThread.h" | 10 #include "SkThread.h" |
11 | 11 |
12 #include <new> | 12 #include <new> |
13 | 13 |
14 | 14 |
15 // 0-2 are reserved for invalid, empty & wide-open | 15 // 0-2 are reserved for invalid, empty & wide-open |
16 static const int32_t kFirstUnreservedGenID = 3; | 16 static const int32_t kFirstUnreservedGenID = 3; |
17 int32_t SkClipStack::gGenID = kFirstUnreservedGenID; | 17 int32_t SkClipStack::gGenID = kFirstUnreservedGenID; |
18 | 18 |
19 bool SkClipStack::Element::operator== (const Element& element) const { | |
20 if (this == &element) { | |
21 return true; | |
22 } | |
23 if (fOp != element.fOp || | |
24 fType != element.fType || | |
25 fDoAA != element.fDoAA || | |
26 fSaveCount != element.fSaveCount) { | |
27 return false; | |
28 } | |
29 switch (fType) { | |
30 case kPath_Type: | |
31 return fPath == element.fPath; | |
32 case kRRect_Type: | |
33 return fRRect == element.fRRect; | |
34 case kRect_Type: | |
35 return fRect == element.fRect; | |
36 case kEmpty_Type: | |
37 return true; | |
38 default: | |
39 SkDEBUGFAIL("Unexpected type."); | |
40 return false; | |
41 } | |
42 } | |
43 | |
19 void SkClipStack::Element::invertShapeFillType() { | 44 void SkClipStack::Element::invertShapeFillType() { |
20 switch (fType) { | 45 switch (fType) { |
21 case kRect_Type: | 46 case kRect_Type: |
22 fPath.reset(); | 47 fPath.reset(); |
23 fPath.addRect(fRect); | 48 fPath.addRect(fRect); |
24 fPath.setFillType(SkPath::kInverseWinding_FillType); | 49 fPath.setFillType(SkPath::kInverseEvenOdd_FillType); |
robertphillips
2014/02/14 20:36:01
Do we really care about setting fRect to be empty?
bsalomon
2014/02/14 21:20:57
I guess not
| |
50 fRect.setEmpty(); | |
51 fType = kPath_Type; | |
52 break; | |
53 case kRRect_Type: | |
54 fPath.reset(); | |
55 fPath.addRRect(fRRect); | |
56 fPath.setFillType(SkPath::kInverseEvenOdd_FillType); | |
robertphillips
2014/02/14 20:36:01
Same for rrect?
bsalomon
2014/02/14 21:20:57
Done.
| |
57 fRRect.setEmpty(); | |
25 fType = kPath_Type; | 58 fType = kPath_Type; |
26 break; | 59 break; |
27 case kPath_Type: | 60 case kPath_Type: |
28 fPath.toggleInverseFillType(); | 61 fPath.toggleInverseFillType(); |
29 case kEmpty_Type: | 62 case kEmpty_Type: |
robertphillips
2014/02/14 20:36:01
Probably
bsalomon
2014/02/14 21:20:57
Agreed, but don't want to conflate any regressions
| |
63 // Should this set to an empty, inverse filled path? | |
30 break; | 64 break; |
31 } | 65 } |
32 } | 66 } |
67 | |
68 void SkClipStack::Element::initPath(int saveCount, const SkPath& path, SkRegion: :Op op, | |
69 bool doAA) { | |
70 if (!path.isInverseFillType()) { | |
71 if (SkPath::kNone_PathAsRect != path.asRect()) { | |
72 this->initRect(saveCount, path.getBounds(), op, doAA); | |
73 return; | |
74 } | |
75 SkRect ovalRect; | |
76 if (path.isOval(&ovalRect)) { | |
77 SkRRect rrect; | |
78 rrect.setOval(ovalRect); | |
79 this->initRRect(saveCount, rrect, op, doAA); | |
80 return; | |
81 } | |
82 } | |
83 fPath = path; | |
84 fType = kPath_Type; | |
85 this->initCommon(saveCount, op, doAA); | |
86 } | |
87 | |
88 void SkClipStack::Element::asPath(SkPath* path) const { | |
89 switch (fType) { | |
90 case kEmpty_Type: | |
91 path->reset(); | |
92 break; | |
93 case kRect_Type: | |
94 path->reset(); | |
95 path->addRect(fRect); | |
96 break; | |
97 case kRRect_Type: | |
98 path->reset(); | |
99 path->addRRect(fRRect); | |
100 break; | |
101 case kPath_Type: | |
102 *path = fPath; | |
103 break; | |
104 } | |
105 } | |
33 | 106 |
34 void SkClipStack::Element::checkEmpty() const { | 107 void SkClipStack::Element::checkEmpty() const { |
35 SkASSERT(fFiniteBound.isEmpty()); | 108 SkASSERT(fFiniteBound.isEmpty()); |
36 SkASSERT(kNormal_BoundsType == fFiniteBoundType); | 109 SkASSERT(kNormal_BoundsType == fFiniteBoundType); |
37 SkASSERT(!fIsIntersectionOfRects); | 110 SkASSERT(!fIsIntersectionOfRects); |
38 SkASSERT(kEmptyGenID == fGenID); | 111 SkASSERT(kEmptyGenID == fGenID); |
39 SkASSERT(fPath.isEmpty()); | 112 SkASSERT(fPath.isEmpty()); |
40 } | 113 } |
41 | 114 |
42 bool SkClipStack::Element::canBeIntersectedInPlace(int saveCount, SkRegion::Op o p) const { | 115 bool SkClipStack::Element::canBeIntersectedInPlace(int saveCount, SkRegion::Op o p) const { |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
93 // that aren't set are whatever isn't set in the previous | 166 // that aren't set are whatever isn't set in the previous |
94 // clip and whatever this clip carves out | 167 // clip and whatever this clip carves out |
95 fFiniteBound.join(prevFinite); | 168 fFiniteBound.join(prevFinite); |
96 fFiniteBoundType = kInsideOut_BoundsType; | 169 fFiniteBoundType = kInsideOut_BoundsType; |
97 break; | 170 break; |
98 case kPrev_InvCur_FillCombo: | 171 case kPrev_InvCur_FillCombo: |
99 // In this case everything outside of this clip's bound | 172 // In this case everything outside of this clip's bound |
100 // is erased, so the only pixels that can remain set | 173 // is erased, so the only pixels that can remain set |
101 // occur w/in the intersection of the two finite bounds | 174 // occur w/in the intersection of the two finite bounds |
102 if (!fFiniteBound.intersect(prevFinite)) { | 175 if (!fFiniteBound.intersect(prevFinite)) { |
103 fFiniteBound.setEmpty(); | 176 this->setEmpty(); |
104 fGenID = kEmptyGenID; | 177 } else { |
178 fFiniteBoundType = kNormal_BoundsType; | |
105 } | 179 } |
106 fFiniteBoundType = kNormal_BoundsType; | |
107 break; | 180 break; |
108 case kPrev_Cur_FillCombo: | 181 case kPrev_Cur_FillCombo: |
109 // The most conservative result bound is that of the | 182 // The most conservative result bound is that of the |
110 // prior clip. This could be wildly incorrect if the | 183 // prior clip. This could be wildly incorrect if the |
111 // second clip either exactly matches the first clip | 184 // second clip either exactly matches the first clip |
112 // (which should yield the empty set) or reduces the | 185 // (which should yield the empty set) or reduces the |
113 // size of the prior bound (e.g., if the second clip | 186 // size of the prior bound (e.g., if the second clip |
114 // exactly matched the bottom half of the prior clip). | 187 // exactly matched the bottom half of the prior clip). |
115 // We ignore these two possibilities. | 188 // We ignore these two possibilities. |
116 fFiniteBound = prevFinite; | 189 fFiniteBound = prevFinite; |
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
198 // are within the current clip | 271 // are within the current clip |
199 break; | 272 break; |
200 case kPrev_InvCur_FillCombo: | 273 case kPrev_InvCur_FillCombo: |
201 // In this case the only pixels that will remain writeable | 274 // In this case the only pixels that will remain writeable |
202 // are with the previous clip | 275 // are with the previous clip |
203 fFiniteBound = prevFinite; | 276 fFiniteBound = prevFinite; |
204 fFiniteBoundType = kNormal_BoundsType; | 277 fFiniteBoundType = kNormal_BoundsType; |
205 break; | 278 break; |
206 case kPrev_Cur_FillCombo: | 279 case kPrev_Cur_FillCombo: |
207 if (!fFiniteBound.intersect(prevFinite)) { | 280 if (!fFiniteBound.intersect(prevFinite)) { |
208 fFiniteBound.setEmpty(); | 281 this->setEmpty(); |
209 fGenID = kEmptyGenID; | |
210 } | 282 } |
211 break; | 283 break; |
212 default: | 284 default: |
213 SkDEBUGFAIL("SkClipStack::Element::combineBoundsIntersection Invalid fill combination"); | 285 SkDEBUGFAIL("SkClipStack::Element::combineBoundsIntersection Invalid fill combination"); |
214 break; | 286 break; |
215 } | 287 } |
216 } | 288 } |
217 | 289 |
218 // a mirror of combineBoundsDiff | 290 // a mirror of combineBoundsDiff |
219 void SkClipStack::Element::combineBoundsRevDiff(int combination, const SkRect& p revFinite) { | 291 void SkClipStack::Element::combineBoundsRevDiff(int combination, const SkRect& p revFinite) { |
220 | 292 |
221 switch (combination) { | 293 switch (combination) { |
222 case kInvPrev_InvCur_FillCombo: | 294 case kInvPrev_InvCur_FillCombo: |
223 // The only pixels that can survive are in the | 295 // The only pixels that can survive are in the |
224 // previous bound since the extensions to infinity in | 296 // previous bound since the extensions to infinity in |
225 // both clips cancel out | 297 // both clips cancel out |
226 fFiniteBound = prevFinite; | 298 fFiniteBound = prevFinite; |
227 fFiniteBoundType = kNormal_BoundsType; | 299 fFiniteBoundType = kNormal_BoundsType; |
228 break; | 300 break; |
229 case kInvPrev_Cur_FillCombo: | 301 case kInvPrev_Cur_FillCombo: |
230 if (!fFiniteBound.intersect(prevFinite)) { | 302 if (!fFiniteBound.intersect(prevFinite)) { |
231 fFiniteBound.setEmpty(); | 303 this->setEmpty(); |
232 fGenID = kEmptyGenID; | 304 } else { |
305 fFiniteBoundType = kNormal_BoundsType; | |
233 } | 306 } |
234 fFiniteBoundType = kNormal_BoundsType; | |
235 break; | 307 break; |
236 case kPrev_InvCur_FillCombo: | 308 case kPrev_InvCur_FillCombo: |
237 fFiniteBound.join(prevFinite); | 309 fFiniteBound.join(prevFinite); |
238 fFiniteBoundType = kInsideOut_BoundsType; | 310 fFiniteBoundType = kInsideOut_BoundsType; |
239 break; | 311 break; |
240 case kPrev_Cur_FillCombo: | 312 case kPrev_Cur_FillCombo: |
241 // Fall through - as with the kDifference_Op case, the | 313 // Fall through - as with the kDifference_Op case, the |
242 // most conservative result bound is the bound of the | 314 // most conservative result bound is the bound of the |
243 // current clip. The prior clip could reduce the size of this | 315 // current clip. The prior clip could reduce the size of this |
244 // bound (as in the kDifference_Op case) but we are ignoring | 316 // bound (as in the kDifference_Op case) but we are ignoring |
245 // those cases. | 317 // those cases. |
246 break; | 318 break; |
247 default: | 319 default: |
248 SkDEBUGFAIL("SkClipStack::Element::combineBoundsRevDiff Invalid fill combination"); | 320 SkDEBUGFAIL("SkClipStack::Element::combineBoundsRevDiff Invalid fill combination"); |
249 break; | 321 break; |
250 } | 322 } |
251 } | 323 } |
252 | 324 |
253 void SkClipStack::Element::updateBoundAndGenID(const Element* prior) { | 325 void SkClipStack::Element::updateBoundAndGenID(const Element* prior) { |
254 // We set this first here but we may overwrite it later if we determine that the clip is | 326 // We set this first here but we may overwrite it later if we determine that the clip is |
255 // either wide-open or empty. | 327 // either wide-open or empty. |
256 fGenID = GetNextGenID(); | 328 fGenID = GetNextGenID(); |
257 | 329 |
258 // First, optimistically update the current Element's bound information | 330 // First, optimistically update the current Element's bound information |
259 // with the current clip's bound | 331 // with the current clip's bound |
260 fIsIntersectionOfRects = false; | 332 fIsIntersectionOfRects = false; |
261 if (kRect_Type == fType) { | 333 switch (fType) { |
262 fFiniteBound = fRect; | 334 case kRect_Type: |
263 fFiniteBoundType = kNormal_BoundsType; | 335 fFiniteBound = fRect; |
336 fFiniteBoundType = kNormal_BoundsType; | |
264 | 337 |
265 if (SkRegion::kReplace_Op == fOp || | 338 if (SkRegion::kReplace_Op == fOp || |
266 (SkRegion::kIntersect_Op == fOp && NULL == prior) || | 339 (SkRegion::kIntersect_Op == fOp && NULL == prior) || |
267 (SkRegion::kIntersect_Op == fOp && prior->fIsIntersectionOfRects && | 340 (SkRegion::kIntersect_Op == fOp && prior->fIsIntersectionOfRects && |
268 prior->rectRectIntersectAllowed(fRect, fDoAA))) { | 341 prior->rectRectIntersectAllowed(fRect, fDoAA))) { |
269 fIsIntersectionOfRects = true; | 342 fIsIntersectionOfRects = true; |
270 } | 343 } |
344 break; | |
345 case kRRect_Type: | |
346 fFiniteBound = fRRect.getBounds(); | |
347 fFiniteBoundType = kNormal_BoundsType; | |
348 break; | |
349 case kPath_Type: | |
350 fFiniteBound = fPath.getBounds(); | |
271 | 351 |
272 } else { | 352 if (fPath.isInverseFillType()) { |
273 SkASSERT(kPath_Type == fType); | 353 fFiniteBoundType = kInsideOut_BoundsType; |
274 | 354 } else { |
275 fFiniteBound = fPath.getBounds(); | 355 fFiniteBoundType = kNormal_BoundsType; |
276 | 356 } |
277 if (fPath.isInverseFillType()) { | 357 break; |
278 fFiniteBoundType = kInsideOut_BoundsType; | 358 case kEmpty_Type: |
279 } else { | 359 SkDEBUGFAIL("We shouldn't get here with an empty element."); |
280 fFiniteBoundType = kNormal_BoundsType; | 360 break; |
281 } | |
282 } | 361 } |
283 | 362 |
284 if (!fDoAA) { | 363 if (!fDoAA) { |
285 // Here we mimic a non-anti-aliased scanline system. If there is | 364 // Here we mimic a non-anti-aliased scanline system. If there is |
286 // no anti-aliasing we can integerize the bounding box to exclude | 365 // no anti-aliasing we can integerize the bounding box to exclude |
287 // fractional parts that won't be rendered. | 366 // fractional parts that won't be rendered. |
288 // Note: the left edge is handled slightly differently below. We | 367 // Note: the left edge is handled slightly differently below. We |
289 // are a bit more generous in the rounding since we don't want to | 368 // are a bit more generous in the rounding since we don't want to |
290 // risk missing the left pixels when fLeft is very close to .5 | 369 // risk missing the left pixels when fLeft is very close to .5 |
291 fFiniteBound.set(SkScalarFloorToScalar(fFiniteBound.fLeft+0.45f), | 370 fFiniteBound.set(SkScalarFloorToScalar(fFiniteBound.fLeft+0.45f), |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
337 break; | 416 break; |
338 case SkRegion::kReverseDifference_Op: | 417 case SkRegion::kReverseDifference_Op: |
339 this->combineBoundsRevDiff(combination, prevFinite); | 418 this->combineBoundsRevDiff(combination, prevFinite); |
340 break; | 419 break; |
341 case SkRegion::kReplace_Op: | 420 case SkRegion::kReplace_Op: |
342 // Replace just ignores everything prior | 421 // Replace just ignores everything prior |
343 // The current clip's bound information is already filled in | 422 // The current clip's bound information is already filled in |
344 // so nothing to do | 423 // so nothing to do |
345 break; | 424 break; |
346 default: | 425 default: |
347 SkDebugf("SkRegion::Op error/n"); | 426 SkDebugf("SkRegion::Op error\n"); |
348 SkASSERT(0); | 427 SkASSERT(0); |
349 break; | 428 break; |
350 } | 429 } |
351 } | 430 } |
352 | 431 |
353 // This constant determines how many Element's are allocated together as a block in | 432 // This constant determines how many Element's are allocated together as a block in |
354 // the deque. As such it needs to balance allocating too much memory vs. | 433 // the deque. As such it needs to balance allocating too much memory vs. |
355 // incurring allocation/deallocation thrashing. It should roughly correspond to | 434 // incurring allocation/deallocation thrashing. It should roughly correspond to |
356 // the deepest save/restore stack we expect to see. | 435 // the deepest save/restore stack we expect to see. |
357 static const int kDefaultElementAllocCnt = 8; | 436 static const int kDefaultElementAllocCnt = 8; |
(...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
521 } | 600 } |
522 } | 601 } |
523 if (SkRegion::kReplace_Op == element->getOp()) { | 602 if (SkRegion::kReplace_Op == element->getOp()) { |
524 break; | 603 break; |
525 } | 604 } |
526 element = iter.prev(); | 605 element = iter.prev(); |
527 } | 606 } |
528 return true; | 607 return true; |
529 } | 608 } |
530 | 609 |
531 void SkClipStack::clipDevRect(const SkRect& rect, SkRegion::Op op, bool doAA) { | 610 void SkClipStack::pushElement(const Element& element) { |
532 | |
533 // Use reverse iterator instead of back because Rect path may need previous | 611 // Use reverse iterator instead of back because Rect path may need previous |
534 SkDeque::Iter iter(fDeque, SkDeque::Iter::kBack_IterStart); | 612 SkDeque::Iter iter(fDeque, SkDeque::Iter::kBack_IterStart); |
535 Element* element = (Element*) iter.prev(); | 613 Element* prior = (Element*) iter.prev(); |
536 | 614 |
537 if (NULL != element) { | 615 if (NULL != prior) { |
538 if (element->canBeIntersectedInPlace(fSaveCount, op)) { | 616 if (prior->canBeIntersectedInPlace(fSaveCount, element.getOp())) { |
539 switch (element->fType) { | 617 switch (prior->fType) { |
540 case Element::kEmpty_Type: | 618 case Element::kEmpty_Type: |
541 element->checkEmpty(); | 619 prior->checkEmpty(); |
542 return; | 620 return; |
543 case Element::kRect_Type: | 621 case Element::kRect_Type: |
544 if (element->rectRectIntersectAllowed(rect, doAA)) { | 622 if (Element::kRect_Type == element.getType()) { |
545 if (!element->fRect.intersect(rect)) { | 623 if (prior->rectRectIntersectAllowed(element.getRect(), e lement.isAA())) { |
546 element->setEmpty(); | 624 if (!prior->fRect.intersect(element.getRect())) { |
625 prior->setEmpty(); | |
626 return; | |
627 } | |
628 | |
629 prior->fDoAA = element.isAA(); | |
630 Element* priorPrior = (Element*) iter.prev(); | |
631 prior->updateBoundAndGenID(priorPrior); | |
547 return; | 632 return; |
548 } | 633 } |
549 | 634 break; |
550 element->fDoAA = doAA; | |
551 Element* prev = (Element*) iter.prev(); | |
552 element->updateBoundAndGenID(prev); | |
553 return; | |
554 } | 635 } |
555 break; | 636 // fallthrough |
556 case Element::kPath_Type: | 637 default: |
557 if (!SkRect::Intersects(element->fPath.getBounds(), rect)) { | 638 if (!SkRect::Intersects(prior->getBounds(), element.getBound s())) { |
558 element->setEmpty(); | 639 prior->setEmpty(); |
559 return; | 640 return; |
560 } | 641 } |
561 break; | 642 break; |
562 } | 643 } |
563 } else if (SkRegion::kReplace_Op == op) { | 644 } else if (SkRegion::kReplace_Op == element.getOp()) { |
564 this->restoreTo(fSaveCount - 1); | 645 this->restoreTo(fSaveCount - 1); |
565 element = (Element*) fDeque.back(); | 646 prior = (Element*) fDeque.back(); |
566 } | 647 } |
567 } | 648 } |
568 new (fDeque.push_back()) Element(fSaveCount, rect, op, doAA); | 649 Element* newElement = SkNEW_PLACEMENT_ARGS(fDeque.push_back(), Element, (ele ment)); |
569 ((Element*) fDeque.back())->updateBoundAndGenID(element); | 650 newElement->updateBoundAndGenID(prior); |
651 } | |
652 | |
653 void SkClipStack::clipDevRRect(const SkRRect& rrect, SkRegion::Op op, bool doAA) { | |
654 Element element(fSaveCount, rrect, op, doAA); | |
655 this->pushElement(element); | |
656 } | |
657 | |
658 void SkClipStack::clipDevRect(const SkRect& rect, SkRegion::Op op, bool doAA) { | |
659 Element element(fSaveCount, rect, op, doAA); | |
660 this->pushElement(element); | |
570 } | 661 } |
571 | 662 |
572 void SkClipStack::clipDevPath(const SkPath& path, SkRegion::Op op, bool doAA) { | 663 void SkClipStack::clipDevPath(const SkPath& path, SkRegion::Op op, bool doAA) { |
573 SkRect alt; | 664 Element element(fSaveCount, path, op, doAA); |
574 if (path.isRect(&alt) && !path.isInverseFillType()) { | 665 this->pushElement(element); |
575 return this->clipDevRect(alt, op, doAA); | |
576 } | |
577 | |
578 Element* element = (Element*)fDeque.back(); | |
579 if (NULL != element) { | |
580 if (element->canBeIntersectedInPlace(fSaveCount, op)) { | |
581 const SkRect& pathBounds = path.getBounds(); | |
582 switch (element->fType) { | |
583 case Element::kEmpty_Type: | |
584 element->checkEmpty(); | |
585 return; | |
586 case Element::kRect_Type: | |
587 if (!SkRect::Intersects(element->fRect, pathBounds)) { | |
588 element->setEmpty(); | |
589 return; | |
590 } | |
591 break; | |
592 case Element::kPath_Type: | |
593 if (!SkRect::Intersects(element->fPath.getBounds(), pathBoun ds)) { | |
594 element->setEmpty(); | |
595 return; | |
596 } | |
597 break; | |
598 } | |
599 } else if (SkRegion::kReplace_Op == op) { | |
600 this->restoreTo(fSaveCount - 1); | |
601 element = (Element*) fDeque.back(); | |
602 } | |
603 } | |
604 new (fDeque.push_back()) Element(fSaveCount, path, op, doAA); | |
605 ((Element*) fDeque.back())->updateBoundAndGenID(element); | |
606 } | 666 } |
607 | 667 |
608 void SkClipStack::clipEmpty() { | 668 void SkClipStack::clipEmpty() { |
609 | 669 |
610 Element* element = (Element*) fDeque.back(); | 670 Element* element = (Element*) fDeque.back(); |
611 | 671 |
612 if (element && element->canBeIntersectedInPlace(fSaveCount, SkRegion::kInter sect_Op)) { | 672 if (element && element->canBeIntersectedInPlace(fSaveCount, SkRegion::kInter sect_Op)) { |
673 element->setEmpty(); | |
robertphillips
2014/02/14 20:36:01
Seems like we don't really need this switch any mo
bsalomon
2014/02/14 21:20:57
Done.
| |
613 switch (element->fType) { | 674 switch (element->fType) { |
614 case Element::kEmpty_Type: | 675 case Element::kEmpty_Type: |
615 element->checkEmpty(); | 676 element->checkEmpty(); |
616 return; | 677 return; |
617 case Element::kRect_Type: | 678 default: |
618 case Element::kPath_Type: | |
619 element->setEmpty(); | 679 element->setEmpty(); |
620 return; | 680 return; |
621 } | 681 } |
622 } | 682 } |
623 new (fDeque.push_back()) Element(fSaveCount); | 683 new (fDeque.push_back()) Element(fSaveCount); |
624 | 684 |
625 ((Element*)fDeque.back())->fGenID = kEmptyGenID; | 685 ((Element*)fDeque.back())->fGenID = kEmptyGenID; |
626 } | 686 } |
627 | 687 |
628 bool SkClipStack::isWideOpen() const { | 688 bool SkClipStack::isWideOpen() const { |
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
730 return kWideOpenGenID; | 790 return kWideOpenGenID; |
731 } | 791 } |
732 | 792 |
733 const Element* back = static_cast<const Element*>(fDeque.back()); | 793 const Element* back = static_cast<const Element*>(fDeque.back()); |
734 if (kInsideOut_BoundsType == back->fFiniteBoundType && back->fFiniteBound.is Empty()) { | 794 if (kInsideOut_BoundsType == back->fFiniteBoundType && back->fFiniteBound.is Empty()) { |
735 return kWideOpenGenID; | 795 return kWideOpenGenID; |
736 } | 796 } |
737 | 797 |
738 return back->getGenID(); | 798 return back->getGenID(); |
739 } | 799 } |
OLD | NEW |