180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/* 380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Copyright 2011 Google Inc. 480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * 580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Use of this source code is governed by a BSD-style license that can be 680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * found in the LICENSE file. 780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru */ 880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkClipStack.h" 980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkPath.h" 1080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkThread.h" 1180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 1280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include <new> 1380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 1480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 1580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru// 0-2 are reserved for invalid, empty & wide-open 16363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenbergerstatic const int32_t kFirstUnreservedGenID = 3; 17363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenbergerint32_t SkClipStack::gGenID = kFirstUnreservedGenID; 18363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger 19363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenbergervoid SkClipStack::Element::invertShapeFillType() { 20363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger switch (fType) { 21363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger case kRect_Type: 22363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger fPath.reset(); 23363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger fPath.addRect(fRect); 24363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger fPath.setFillType(SkPath::kInverseWinding_FillType); 25363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger fType = kPath_Type; 26363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger break; 27363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger case kPath_Type: 28363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger fPath.toggleInverseFillType(); 29363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger case kEmpty_Type: 30363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger break; 3180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 32363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger} 3380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 34363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenbergervoid SkClipStack::Element::checkEmpty() const { 35363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger SkASSERT(fFiniteBound.isEmpty()); 36363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger SkASSERT(kNormal_BoundsType == fFiniteBoundType); 37363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger SkASSERT(!fIsIntersectionOfRects); 38363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger SkASSERT(kEmptyGenID == fGenID); 39363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger SkASSERT(fPath.isEmpty()); 40363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger} 4180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 42363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenbergerbool SkClipStack::Element::canBeIntersectedInPlace(int saveCount, SkRegion::Op op) const { 43363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger if (kEmpty_Type == fType && 44363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger (SkRegion::kDifference_Op == op || SkRegion::kIntersect_Op == op)) { 45363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger return true; 4680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 47363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger // Only clips within the same save/restore frame (as captured by 48363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger // the save count) can be merged 49363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger return fSaveCount == saveCount && 50363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger SkRegion::kIntersect_Op == op && 51363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger (SkRegion::kIntersect_Op == fOp || SkRegion::kReplace_Op == fOp); 52363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger} 5380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 54363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenbergerbool SkClipStack::Element::rectRectIntersectAllowed(const SkRect& newR, bool newAA) const { 55363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger SkASSERT(kRect_Type == fType); 5680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 57363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger if (fDoAA == newAA) { 58363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger // if the AA setting is the same there is no issue 59363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger return true; 6080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 6180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 62363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger if (!SkRect::Intersects(fRect, newR)) { 63363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger // The calling code will correctly set the result to the empty clip 64363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger return true; 65363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger } 6680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 67363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger if (fRect.contains(newR)) { 68363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger // if the new rect carves out a portion of the old one there is no 69363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger // issue 70363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger return true; 7180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 7280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 73363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger // So either the two overlap in some complex manner or newR contains oldR. 74363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger // In the first, case the edges will require different AA. In the second, 75363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger // the AA setting that would be carried forward is incorrect (e.g., oldR 76363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger // is AA while newR is BW but since newR contains oldR, oldR will be 77363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger // drawn BW) since the new AA setting will predominate. 78363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger return false; 79363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger} 8080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 81363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger// a mirror of combineBoundsRevDiff 82363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenbergervoid SkClipStack::Element::combineBoundsDiff(FillCombo combination, const SkRect& prevFinite) { 83363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger switch (combination) { 84363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger case kInvPrev_InvCur_FillCombo: 85363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger // In this case the only pixels that can remain set 86363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger // are inside the current clip rect since the extensions 87363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger // to infinity of both clips cancel out and whatever 88363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger // is outside of the current clip is removed 89363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger fFiniteBoundType = kNormal_BoundsType; 90363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger break; 91363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger case kInvPrev_Cur_FillCombo: 92363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger // In this case the current op is finite so the only pixels 93363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger // that aren't set are whatever isn't set in the previous 94363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger // clip and whatever this clip carves out 95363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger fFiniteBound.join(prevFinite); 96363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger fFiniteBoundType = kInsideOut_BoundsType; 97363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger break; 98363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger case kPrev_InvCur_FillCombo: 99363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger // In this case everything outside of this clip's bound 100363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger // is erased, so the only pixels that can remain set 101363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger // occur w/in the intersection of the two finite bounds 102363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger if (!fFiniteBound.intersect(prevFinite)) { 103363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger fFiniteBound.setEmpty(); 104363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger fGenID = kEmptyGenID; 105363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger } 106363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger fFiniteBoundType = kNormal_BoundsType; 107363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger break; 108363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger case kPrev_Cur_FillCombo: 109363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger // The most conservative result bound is that of the 110363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger // prior clip. This could be wildly incorrect if the 111363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger // second clip either exactly matches the first clip 112363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger // (which should yield the empty set) or reduces the 113363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger // size of the prior bound (e.g., if the second clip 114363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger // exactly matched the bottom half of the prior clip). 115363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger // We ignore these two possibilities. 116363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger fFiniteBound = prevFinite; 117363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger break; 118363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger default: 119363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger SkDEBUGFAIL("SkClipStack::Element::combineBoundsDiff Invalid fill combination"); 120363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger break; 12180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 122363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger} 12380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 124363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenbergervoid SkClipStack::Element::combineBoundsXOR(int combination, const SkRect& prevFinite) { 12580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 126363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger switch (combination) { 127363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger case kInvPrev_Cur_FillCombo: // fall through 128363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger case kPrev_InvCur_FillCombo: 129363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger // With only one of the clips inverted the result will always 130363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger // extend to infinity. The only pixels that may be un-writeable 131363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger // lie within the union of the two finite bounds 132363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger fFiniteBound.join(prevFinite); 133363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger fFiniteBoundType = kInsideOut_BoundsType; 134363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger break; 135363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger case kInvPrev_InvCur_FillCombo: 136363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger // The only pixels that can survive are within the 137363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger // union of the two bounding boxes since the extensions 138363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger // to infinity of both clips cancel out 139363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger // fall through! 140363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger case kPrev_Cur_FillCombo: 141363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger // The most conservative bound for xor is the 142363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger // union of the two bounds. If the two clips exactly overlapped 143363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger // the xor could yield the empty set. Similarly the xor 144363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger // could reduce the size of the original clip's bound (e.g., 145363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger // if the second clip exactly matched the bottom half of the 146363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger // first clip). We ignore these two cases. 147363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger fFiniteBound.join(prevFinite); 148363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger fFiniteBoundType = kNormal_BoundsType; 149363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger break; 150363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger default: 151363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger SkDEBUGFAIL("SkClipStack::Element::combineBoundsXOR Invalid fill combination"); 152363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger break; 15380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 154363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger} 15580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 156363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger// a mirror of combineBoundsIntersection 157363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenbergervoid SkClipStack::Element::combineBoundsUnion(int combination, const SkRect& prevFinite) { 15880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 159363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger switch (combination) { 160363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger case kInvPrev_InvCur_FillCombo: 161363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger if (!fFiniteBound.intersect(prevFinite)) { 162363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger fFiniteBound.setEmpty(); 163363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger fGenID = kWideOpenGenID; 164363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger } 165363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger fFiniteBoundType = kInsideOut_BoundsType; 166363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger break; 167363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger case kInvPrev_Cur_FillCombo: 168363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger // The only pixels that won't be drawable are inside 169363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger // the prior clip's finite bound 170363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger fFiniteBound = prevFinite; 171363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger fFiniteBoundType = kInsideOut_BoundsType; 172363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger break; 173363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger case kPrev_InvCur_FillCombo: 174363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger // The only pixels that won't be drawable are inside 175363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger // this clip's finite bound 176363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger break; 177363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger case kPrev_Cur_FillCombo: 178363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger fFiniteBound.join(prevFinite); 179363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger break; 180363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger default: 181363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger SkDEBUGFAIL("SkClipStack::Element::combineBoundsUnion Invalid fill combination"); 182363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger break; 18380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 184363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger} 18580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 186363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger// a mirror of combineBoundsUnion 187363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenbergervoid SkClipStack::Element::combineBoundsIntersection(int combination, const SkRect& prevFinite) { 18880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 189363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger switch (combination) { 190363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger case kInvPrev_InvCur_FillCombo: 191363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger // The only pixels that aren't writable in this case 192363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger // occur in the union of the two finite bounds 193363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger fFiniteBound.join(prevFinite); 194363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger fFiniteBoundType = kInsideOut_BoundsType; 195363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger break; 196363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger case kInvPrev_Cur_FillCombo: 197363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger // In this case the only pixels that will remain writeable 198363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger // are within the current clip 199363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger break; 200363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger case kPrev_InvCur_FillCombo: 201363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger // In this case the only pixels that will remain writeable 202363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger // are with the previous clip 203363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger fFiniteBound = prevFinite; 204363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger fFiniteBoundType = kNormal_BoundsType; 205363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger break; 206363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger case kPrev_Cur_FillCombo: 207363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger if (!fFiniteBound.intersect(prevFinite)) { 208363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger fFiniteBound.setEmpty(); 209363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger fGenID = kEmptyGenID; 210363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger } 211363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger break; 212363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger default: 213363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger SkDEBUGFAIL("SkClipStack::Element::combineBoundsIntersection Invalid fill combination"); 214363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger break; 21580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 216363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger} 21780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 218363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger// a mirror of combineBoundsDiff 219363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenbergervoid SkClipStack::Element::combineBoundsRevDiff(int combination, const SkRect& prevFinite) { 22080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 221363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger switch (combination) { 222363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger case kInvPrev_InvCur_FillCombo: 223363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger // The only pixels that can survive are in the 224363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger // previous bound since the extensions to infinity in 225363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger // both clips cancel out 226363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger fFiniteBound = prevFinite; 22780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fFiniteBoundType = kNormal_BoundsType; 228363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger break; 229363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger case kInvPrev_Cur_FillCombo: 230363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger if (!fFiniteBound.intersect(prevFinite)) { 231363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger fFiniteBound.setEmpty(); 232363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger fGenID = kEmptyGenID; 23380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 234363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger fFiniteBoundType = kNormal_BoundsType; 235363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger break; 236363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger case kPrev_InvCur_FillCombo: 237363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger fFiniteBound.join(prevFinite); 238363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger fFiniteBoundType = kInsideOut_BoundsType; 239363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger break; 240363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger case kPrev_Cur_FillCombo: 241363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger // Fall through - as with the kDifference_Op case, the 242363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger // most conservative result bound is the bound of the 243363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger // current clip. The prior clip could reduce the size of this 244363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger // bound (as in the kDifference_Op case) but we are ignoring 245363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger // those cases. 246363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger break; 247363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger default: 248363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger SkDEBUGFAIL("SkClipStack::Element::combineBoundsRevDiff Invalid fill combination"); 249363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger break; 250363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger } 251363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger} 25280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 253363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenbergervoid SkClipStack::Element::updateBoundAndGenID(const Element* prior) { 254363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger // We set this first here but we may overwrite it later if we determine that the clip is 255363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger // either wide-open or empty. 256363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger fGenID = GetNextGenID(); 25780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 258363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger // First, optimistically update the current Element's bound information 259363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger // with the current clip's bound 260363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger fIsIntersectionOfRects = false; 261363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger if (kRect_Type == fType) { 262363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger fFiniteBound = fRect; 263363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger fFiniteBoundType = kNormal_BoundsType; 26480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 265363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger if (SkRegion::kReplace_Op == fOp || 266363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger (SkRegion::kIntersect_Op == fOp && NULL == prior) || 267363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger (SkRegion::kIntersect_Op == fOp && prior->fIsIntersectionOfRects && 268363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger prior->rectRectIntersectAllowed(fRect, fDoAA))) { 269363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger fIsIntersectionOfRects = true; 27080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 27180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 272363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger } else { 273363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger SkASSERT(kPath_Type == fType); 27480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 275363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger fFiniteBound = fPath.getBounds(); 27680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 277363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger if (fPath.isInverseFillType()) { 278363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger fFiniteBoundType = kInsideOut_BoundsType; 27980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } else { 280363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger fFiniteBoundType = kNormal_BoundsType; 28180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 282363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger } 28380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 284363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger if (!fDoAA) { 285363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger // Here we mimic a non-anti-aliased scanline system. If there is 286363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger // no anti-aliasing we can integerize the bounding box to exclude 287363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger // fractional parts that won't be rendered. 288363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger // Note: the left edge is handled slightly differently below. We 289363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger // are a bit more generous in the rounding since we don't want to 290363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger // risk missing the left pixels when fLeft is very close to .5 291363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger fFiniteBound.set(SkIntToScalar(SkScalarFloorToInt(fFiniteBound.fLeft+0.45f)), 292363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger SkIntToScalar(SkScalarRound(fFiniteBound.fTop)), 293363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger SkIntToScalar(SkScalarRound(fFiniteBound.fRight)), 294363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger SkIntToScalar(SkScalarRound(fFiniteBound.fBottom))); 295363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger } 296363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger 297363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger // Now determine the previous Element's bound information taking into 298363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger // account that there may be no previous clip 299363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger SkRect prevFinite; 300363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger SkClipStack::BoundsType prevType; 301363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger 302363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger if (NULL == prior) { 303363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger // no prior clip means the entire plane is writable 304363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger prevFinite.setEmpty(); // there are no pixels that cannot be drawn to 305363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger prevType = kInsideOut_BoundsType; 306363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger } else { 307363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger prevFinite = prior->fFiniteBound; 308363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger prevType = prior->fFiniteBoundType; 309363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger } 31080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 311363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger FillCombo combination = kPrev_Cur_FillCombo; 312363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger if (kInsideOut_BoundsType == fFiniteBoundType) { 313363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger combination = (FillCombo) (combination | 0x01); 314363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger } 315363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger if (kInsideOut_BoundsType == prevType) { 316363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger combination = (FillCombo) (combination | 0x02); 317363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger } 31880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 319363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger SkASSERT(kInvPrev_InvCur_FillCombo == combination || 320363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger kInvPrev_Cur_FillCombo == combination || 321363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger kPrev_InvCur_FillCombo == combination || 322363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger kPrev_Cur_FillCombo == combination); 323363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger 324363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger // Now integrate with clip with the prior clips 325363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger switch (fOp) { 326363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger case SkRegion::kDifference_Op: 327363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger this->combineBoundsDiff(combination, prevFinite); 328363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger break; 329363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger case SkRegion::kXOR_Op: 330363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger this->combineBoundsXOR(combination, prevFinite); 331363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger break; 332363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger case SkRegion::kUnion_Op: 333363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger this->combineBoundsUnion(combination, prevFinite); 334363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger break; 335363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger case SkRegion::kIntersect_Op: 336363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger this->combineBoundsIntersection(combination, prevFinite); 337363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger break; 338363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger case SkRegion::kReverseDifference_Op: 339363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger this->combineBoundsRevDiff(combination, prevFinite); 340363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger break; 341363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger case SkRegion::kReplace_Op: 342363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger // Replace just ignores everything prior 343363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger // The current clip's bound information is already filled in 344363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger // so nothing to do 345363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger break; 346363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger default: 347363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger SkDebugf("SkRegion::Op error/n"); 348363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger SkASSERT(0); 349363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger break; 35080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 351363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger} 35280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 353363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger// This constant determines how many Element's are allocated together as a block in 35480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru// the deque. As such it needs to balance allocating too much memory vs. 35580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru// incurring allocation/deallocation thrashing. It should roughly correspond to 35680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru// the deepest save/restore stack we expect to see. 357363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenbergerstatic const int kDefaultElementAllocCnt = 8; 35880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 35980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruSkClipStack::SkClipStack() 360363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger : fDeque(sizeof(Element), kDefaultElementAllocCnt) 36180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru , fSaveCount(0) { 36280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 36380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 36480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruSkClipStack::SkClipStack(const SkClipStack& b) 365363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger : fDeque(sizeof(Element), kDefaultElementAllocCnt) { 36680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *this = b; 36780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 36880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 36980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruSkClipStack::SkClipStack(const SkRect& r) 370363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger : fDeque(sizeof(Element), kDefaultElementAllocCnt) 37180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru , fSaveCount(0) { 37280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (!r.isEmpty()) { 37380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru this->clipDevRect(r, SkRegion::kReplace_Op, false); 37480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 37580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 37680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 37780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruSkClipStack::SkClipStack(const SkIRect& r) 378363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger : fDeque(sizeof(Element), kDefaultElementAllocCnt) 37980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru , fSaveCount(0) { 38080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (!r.isEmpty()) { 38180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkRect temp; 38280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru temp.set(r); 38380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru this->clipDevRect(temp, SkRegion::kReplace_Op, false); 38480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 38580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 38680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 38780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruSkClipStack::~SkClipStack() { 38880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru reset(); 38980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 39080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 39180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruSkClipStack& SkClipStack::operator=(const SkClipStack& b) { 39280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (this == &b) { 39380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return *this; 39480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 39580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru reset(); 39680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 39780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fSaveCount = b.fSaveCount; 39880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkDeque::F2BIter recIter(b.fDeque); 399363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger for (const Element* element = (const Element*)recIter.next(); 400363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger element != NULL; 401363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger element = (const Element*)recIter.next()) { 402363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger new (fDeque.push_back()) Element(*element); 40380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 40480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 40580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return *this; 40680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 40780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 40880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querubool SkClipStack::operator==(const SkClipStack& b) const { 40980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (fSaveCount != b.fSaveCount || 41080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fDeque.count() != b.fDeque.count()) { 41180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return false; 41280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 41380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkDeque::F2BIter myIter(fDeque); 41480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkDeque::F2BIter bIter(b.fDeque); 415363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger const Element* myElement = (const Element*)myIter.next(); 416363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger const Element* bElement = (const Element*)bIter.next(); 41780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 418363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger while (myElement != NULL && bElement != NULL) { 419363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger if (*myElement != *bElement) { 42080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return false; 42180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 422363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger myElement = (const Element*)myIter.next(); 423363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger bElement = (const Element*)bIter.next(); 42480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 425363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger return myElement == NULL && bElement == NULL; 42680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 42780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 42880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkClipStack::reset() { 42980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // We used a placement new for each object in fDeque, so we're responsible 43080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // for calling the destructor on each of them as well. 43180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru while (!fDeque.empty()) { 432363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger Element* element = (Element*)fDeque.back(); 433363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger element->~Element(); 43480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fDeque.pop_back(); 43580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 43680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 43780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fSaveCount = 0; 43880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 43980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 44080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkClipStack::save() { 44180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fSaveCount += 1; 44280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 44380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 44480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkClipStack::restore() { 44580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fSaveCount -= 1; 44680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru while (!fDeque.empty()) { 447363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger Element* element = (Element*)fDeque.back(); 448363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger if (element->fSaveCount <= fSaveCount) { 44980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru break; 45080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 451363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger this->purgeClip(element); 452363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger element->~Element(); 45380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fDeque.pop_back(); 45480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 45580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 45680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 45780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkClipStack::getBounds(SkRect* canvFiniteBound, 45880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru BoundsType* boundType, 45980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru bool* isIntersectionOfRects) const { 46080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkASSERT(NULL != canvFiniteBound && NULL != boundType); 46180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 462363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger Element* element = (Element*)fDeque.back(); 46380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 464363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger if (NULL == element) { 46580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // the clip is wide open - the infinite plane w/ no pixels un-writeable 46680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru canvFiniteBound->setEmpty(); 46780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *boundType = kInsideOut_BoundsType; 46880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (NULL != isIntersectionOfRects) { 46980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *isIntersectionOfRects = false; 47080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 47180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return; 47280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 47380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 474363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger *canvFiniteBound = element->fFiniteBound; 475363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger *boundType = element->fFiniteBoundType; 47680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (NULL != isIntersectionOfRects) { 477363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger *isIntersectionOfRects = element->fIsIntersectionOfRects; 47880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 47980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 48080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 48180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querubool SkClipStack::intersectRectWithClip(SkRect* rect) const { 48280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkASSERT(NULL != rect); 48380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 48480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkRect bounds; 48580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkClipStack::BoundsType bt; 48680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru this->getBounds(&bounds, &bt); 48780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (bt == SkClipStack::kInsideOut_BoundsType) { 48880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (bounds.contains(*rect)) { 48980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return false; 49080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } else { 49180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // If rect's x values are both within bound's x range we 49280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // could clip here. Same for y. But we don't bother to check. 49380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return true; 49480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 49580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } else { 49680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return rect->intersect(bounds); 49780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 49880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 49980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 500363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenbergerbool SkClipStack::quickContains(const SkRect& rect) const { 501363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger 502363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger Iter iter(*this, Iter::kTop_IterStart); 503363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger const Element* element = iter.prev(); 504363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger while (element != NULL) { 505363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger if (SkRegion::kIntersect_Op != element->getOp() && SkRegion::kReplace_Op != element->getOp()) 506363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger return false; 507363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger if (element->isInverseFilled()) { 508363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger // Part of 'rect' could be trimmed off by the inverse-filled clip element 509363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger if (SkRect::Intersects(element->getBounds(), rect)) { 510363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger return false; 511363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger } 512363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger } else { 513363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger if (!element->contains(rect)) { 514363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger return false; 515363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger } 516363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger } 517363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger if (SkRegion::kReplace_Op == element->getOp()) { 518363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger break; 519363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger } 520363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger element = iter.prev(); 521363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger } 522363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger return true; 523363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger} 52480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 525363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenbergervoid SkClipStack::clipDevRect(const SkRect& rect, SkRegion::Op op, bool doAA) { 52680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 52780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // Use reverse iterator instead of back because Rect path may need previous 52880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkDeque::Iter iter(fDeque, SkDeque::Iter::kBack_IterStart); 529363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger Element* element = (Element*) iter.prev(); 53080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 531363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger if (element && element->canBeIntersectedInPlace(fSaveCount, op)) { 532363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger switch (element->fType) { 533363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger case Element::kEmpty_Type: 534363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger element->checkEmpty(); 53580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return; 536363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger case Element::kRect_Type: 537363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger if (element->rectRectIntersectAllowed(rect, doAA)) { 538363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger this->purgeClip(element); 539363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger if (!element->fRect.intersect(rect)) { 540363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger element->setEmpty(); 54180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return; 54280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 54380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 544363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger element->fDoAA = doAA; 545363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger Element* prev = (Element*) iter.prev(); 546363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger element->updateBoundAndGenID(prev); 54780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return; 54880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 54980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru break; 550363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger case Element::kPath_Type: 551363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger if (!SkRect::Intersects(element->fPath.getBounds(), rect)) { 552363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger this->purgeClip(element); 553363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger element->setEmpty(); 55480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return; 55580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 55680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru break; 55780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 55880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 559363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger new (fDeque.push_back()) Element(fSaveCount, rect, op, doAA); 560363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger ((Element*) fDeque.back())->updateBoundAndGenID(element); 56180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 562363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger if (element && element->fSaveCount == fSaveCount) { 563363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger this->purgeClip(element); 56480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 56580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 56680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 56780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkClipStack::clipDevPath(const SkPath& path, SkRegion::Op op, bool doAA) { 56880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkRect alt; 569363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger if (path.isRect(&alt) && !path.isInverseFillType()) { 57080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return this->clipDevRect(alt, op, doAA); 57180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 57280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 573363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger Element* element = (Element*)fDeque.back(); 574363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger if (element && element->canBeIntersectedInPlace(fSaveCount, op)) { 57580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru const SkRect& pathBounds = path.getBounds(); 576363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger switch (element->fType) { 577363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger case Element::kEmpty_Type: 578363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger element->checkEmpty(); 57980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return; 580363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger case Element::kRect_Type: 581363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger if (!SkRect::Intersects(element->fRect, pathBounds)) { 582363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger this->purgeClip(element); 583363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger element->setEmpty(); 58480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return; 58580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 58680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru break; 587363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger case Element::kPath_Type: 588363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger if (!SkRect::Intersects(element->fPath.getBounds(), pathBounds)) { 589363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger this->purgeClip(element); 590363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger element->setEmpty(); 59180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return; 59280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 59380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru break; 59480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 59580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 596363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger new (fDeque.push_back()) Element(fSaveCount, path, op, doAA); 597363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger ((Element*) fDeque.back())->updateBoundAndGenID(element); 59880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 599363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger if (element && element->fSaveCount == fSaveCount) { 600363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger this->purgeClip(element); 60180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 60280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 60380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 60480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkClipStack::clipEmpty() { 60580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 606363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger Element* element = (Element*) fDeque.back(); 60780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 608363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger if (element && element->canBeIntersectedInPlace(fSaveCount, SkRegion::kIntersect_Op)) { 609363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger switch (element->fType) { 610363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger case Element::kEmpty_Type: 611363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger element->checkEmpty(); 61280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return; 613363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger case Element::kRect_Type: 614363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger case Element::kPath_Type: 615363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger this->purgeClip(element); 616363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger element->setEmpty(); 61780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return; 61880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 61980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 620363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger new (fDeque.push_back()) Element(fSaveCount); 62180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 622363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger if (element && element->fSaveCount == fSaveCount) { 623363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger this->purgeClip(element); 62480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 625363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger ((Element*)fDeque.back())->fGenID = kEmptyGenID; 62680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 62780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 62880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querubool SkClipStack::isWideOpen() const { 62980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (0 == fDeque.count()) { 63080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return true; 63180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 63280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 633363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger const Element* back = (const Element*) fDeque.back(); 634363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger return kWideOpenGenID == back->fGenID || 635363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger (kInsideOut_BoundsType == back->fFiniteBoundType && back->fFiniteBound.isEmpty()); 63680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 63780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 63880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/////////////////////////////////////////////////////////////////////////////// 63980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 64080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruSkClipStack::Iter::Iter() : fStack(NULL) { 64180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 64280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 64380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruSkClipStack::Iter::Iter(const SkClipStack& stack, IterStart startLoc) 64480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru : fStack(&stack) { 64580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru this->reset(stack, startLoc); 64680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 64780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 648363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenbergerconst SkClipStack::Element* SkClipStack::Iter::next() { 649363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger return (const SkClipStack::Element*)fIter.next(); 65080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 65180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 652363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenbergerconst SkClipStack::Element* SkClipStack::Iter::prev() { 653363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger return (const SkClipStack::Element*)fIter.prev(); 65480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 65580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 656363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenbergerconst SkClipStack::Element* SkClipStack::Iter::skipToTopmost(SkRegion::Op op) { 65780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 65880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (NULL == fStack) { 65980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return NULL; 66080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 66180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 66280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fIter.reset(fStack->fDeque, SkDeque::Iter::kBack_IterStart); 66380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 664363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger const SkClipStack::Element* element = NULL; 66580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 666363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger for (element = (const SkClipStack::Element*) fIter.prev(); 667363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger NULL != element; 668363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger element = (const SkClipStack::Element*) fIter.prev()) { 66980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 670363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger if (op == element->fOp) { 67180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // The Deque's iterator is actually one pace ahead of the 672363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger // returned value. So while "element" is the element we want to 67380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // return, the iterator is actually pointing at (and will 67480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // return on the next "next" or "prev" call) the element 67580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // in front of it in the deque. Bump the iterator forward a 67680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // step so we get the expected result. 67780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (NULL == fIter.next()) { 67880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // The reverse iterator has run off the front of the deque 67980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // (i.e., the "op" clip is the first clip) and can't 68080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // recover. Reset the iterator to start at the front. 68180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fIter.reset(fStack->fDeque, SkDeque::Iter::kFront_IterStart); 68280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 68380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru break; 68480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 68580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 68680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 687363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger if (NULL == element) { 68880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // There were no "op" clips 68980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fIter.reset(fStack->fDeque, SkDeque::Iter::kFront_IterStart); 69080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 69180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 69280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return this->next(); 69380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 69480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 69580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkClipStack::Iter::reset(const SkClipStack& stack, IterStart startLoc) { 69680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fStack = &stack; 69780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fIter.reset(stack.fDeque, static_cast<SkDeque::Iter::IterStart>(startLoc)); 69880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 69980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 70080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru// helper method 70180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkClipStack::getConservativeBounds(int offsetX, 70280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int offsetY, 70380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int maxWidth, 70480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int maxHeight, 70580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkRect* devBounds, 70680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru bool* isIntersectionOfRects) const { 70780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkASSERT(NULL != devBounds); 70880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 70980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru devBounds->setLTRB(0, 0, 71080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkIntToScalar(maxWidth), SkIntToScalar(maxHeight)); 71180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 71280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkRect temp; 71380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkClipStack::BoundsType boundType; 71480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 71580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // temp starts off in canvas space here 71680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru this->getBounds(&temp, &boundType, isIntersectionOfRects); 71780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (SkClipStack::kInsideOut_BoundsType == boundType) { 71880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return; 71980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 72080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 72180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // but is converted to device space here 72280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru temp.offset(SkIntToScalar(offsetX), SkIntToScalar(offsetY)); 72380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 72480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (!devBounds->intersect(temp)) { 72580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru devBounds->setEmpty(); 72680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 72780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 72880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 72980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkClipStack::addPurgeClipCallback(PFPurgeClipCB callback, void* data) const { 73080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru ClipCallbackData temp = { callback, data }; 73180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fCallbackData.append(1, &temp); 73280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 73380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 73480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkClipStack::removePurgeClipCallback(PFPurgeClipCB callback, void* data) const { 73580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru ClipCallbackData temp = { callback, data }; 73680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int index = fCallbackData.find(temp); 73780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (index >= 0) { 73880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fCallbackData.removeShuffle(index); 73980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 74080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 74180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 742363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger// The clip state represented by 'element' will never be used again. Purge it. 743363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenbergervoid SkClipStack::purgeClip(Element* element) { 744363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger SkASSERT(NULL != element); 745363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger if (element->fGenID >= 0 && element->fGenID < kFirstUnreservedGenID) { 746363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger return; 747363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger } 74880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 74980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru for (int i = 0; i < fCallbackData.count(); ++i) { 750363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger (*fCallbackData[i].fCallback)(element->fGenID, fCallbackData[i].fData); 75180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 75280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 753363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger // Invalidate element's gen ID so handlers can detect already handled records 754363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger element->fGenID = kInvalidGenID; 75580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 75680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 75780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruint32_t SkClipStack::GetNextGenID() { 758363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger // TODO: handle overflow. 75980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return sk_atomic_inc(&gGenID); 76080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 76180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 76280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruint32_t SkClipStack::getTopmostGenID() const { 76380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 76480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (fDeque.empty()) { 76580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return kInvalidGenID; 76680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 76780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 768363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger Element* element = (Element*)fDeque.back(); 769363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger return element->fGenID; 77080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 771