1170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com 2170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com/* 3170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com * Copyright 2012 Google Inc. 4170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com * 5170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com * Use of this source code is governed by a BSD-style license that can be 6170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com * found in the LICENSE file. 7170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com */ 8170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com 9170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com#include "GrReducedClip.h" 10170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com 11170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.comtypedef SkClipStack::Element Element; 12170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com//////////////////////////////////////////////////////////////////////////////// 13170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com 14170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.comnamespace GrReducedClip { 15170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com 1634cd70a5810b3cf37b44de1ce080a911a8b342c8bsalomon@google.com// helper function 1734cd70a5810b3cf37b44de1ce080a911a8b342c8bsalomon@google.comvoid reduced_stack_walker(const SkClipStack& stack, 1834cd70a5810b3cf37b44de1ce080a911a8b342c8bsalomon@google.com const SkRect& queryBounds, 1934cd70a5810b3cf37b44de1ce080a911a8b342c8bsalomon@google.com ElementList* result, 20d3e5842db0cb169e10d6da1e62c94ba5cf182bb4commit-bot@chromium.org int32_t* resultGenID, 2134cd70a5810b3cf37b44de1ce080a911a8b342c8bsalomon@google.com InitialState* initialState, 2234cd70a5810b3cf37b44de1ce080a911a8b342c8bsalomon@google.com bool* requiresAA); 2334cd70a5810b3cf37b44de1ce080a911a8b342c8bsalomon@google.com 24170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com/* 25c6b3e48cb3a22d83ba3f4b9a614a5a35b05958a0bsalomon@google.comThere are plenty of optimizations that could be added here. Maybe flips could be folded into 26170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.comearlier operations. Or would inserting flips and reversing earlier ops ever be a win? Perhaps 27170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.comfor the case where the bounds are kInsideOut_BoundsType. We could restrict earlier operations 28170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.combased on later intersect operations, and perhaps remove intersect-rects. We could optionally 29170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.comtake a rect in case the caller knows a bound on what is to be drawn through this clip. 30170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com*/ 3134cd70a5810b3cf37b44de1ce080a911a8b342c8bsalomon@google.comvoid ReduceClipStack(const SkClipStack& stack, 3234cd70a5810b3cf37b44de1ce080a911a8b342c8bsalomon@google.com const SkIRect& queryBounds, 3334cd70a5810b3cf37b44de1ce080a911a8b342c8bsalomon@google.com ElementList* result, 34d3e5842db0cb169e10d6da1e62c94ba5cf182bb4commit-bot@chromium.org int32_t* resultGenID, 3534cd70a5810b3cf37b44de1ce080a911a8b342c8bsalomon@google.com InitialState* initialState, 3634cd70a5810b3cf37b44de1ce080a911a8b342c8bsalomon@google.com SkIRect* tighterBounds, 3734cd70a5810b3cf37b44de1ce080a911a8b342c8bsalomon@google.com bool* requiresAA) { 38170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com result->reset(); 39170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com 40d3e5842db0cb169e10d6da1e62c94ba5cf182bb4commit-bot@chromium.org // The clip established by the element list might be cached based on the last 41d3e5842db0cb169e10d6da1e62c94ba5cf182bb4commit-bot@chromium.org // generation id. When we make early returns, we do not know what was the generation 42d3e5842db0cb169e10d6da1e62c94ba5cf182bb4commit-bot@chromium.org // id that lead to the state. Make a conservative guess. 43d3e5842db0cb169e10d6da1e62c94ba5cf182bb4commit-bot@chromium.org *resultGenID = stack.getTopmostGenID(); 44d3e5842db0cb169e10d6da1e62c94ba5cf182bb4commit-bot@chromium.org 45170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com if (stack.isWideOpen()) { 46170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com *initialState = kAllIn_InitialState; 47170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com return; 48170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com } 49170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com 5034cd70a5810b3cf37b44de1ce080a911a8b342c8bsalomon@google.com 5134cd70a5810b3cf37b44de1ce080a911a8b342c8bsalomon@google.com // We initially look at whether the bounds alone is sufficient. We also use the stack bounds to 5234cd70a5810b3cf37b44de1ce080a911a8b342c8bsalomon@google.com // attempt to compute the tighterBounds. 5334cd70a5810b3cf37b44de1ce080a911a8b342c8bsalomon@google.com 54170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com SkClipStack::BoundsType stackBoundsType; 55170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com SkRect stackBounds; 56170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com bool iior; 57170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com stack.getBounds(&stackBounds, &stackBoundsType, &iior); 58170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com 5934cd70a5810b3cf37b44de1ce080a911a8b342c8bsalomon@google.com const SkIRect* bounds = &queryBounds; 6034cd70a5810b3cf37b44de1ce080a911a8b342c8bsalomon@google.com 614469938e92d779dff05e745559e67907bbf21e78reed@google.com SkRect scalarQueryBounds = SkRect::Make(queryBounds); 6234cd70a5810b3cf37b44de1ce080a911a8b342c8bsalomon@google.com 63170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com if (iior) { 64170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com SkASSERT(SkClipStack::kNormal_BoundsType == stackBoundsType); 65170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com SkRect isectRect; 6634cd70a5810b3cf37b44de1ce080a911a8b342c8bsalomon@google.com if (stackBounds.contains(scalarQueryBounds)) { 67170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com *initialState = kAllIn_InitialState; 6834cd70a5810b3cf37b44de1ce080a911a8b342c8bsalomon@google.com if (NULL != tighterBounds) { 6934cd70a5810b3cf37b44de1ce080a911a8b342c8bsalomon@google.com *tighterBounds = queryBounds; 7034cd70a5810b3cf37b44de1ce080a911a8b342c8bsalomon@google.com } 7134cd70a5810b3cf37b44de1ce080a911a8b342c8bsalomon@google.com if (NULL != requiresAA) { 7234cd70a5810b3cf37b44de1ce080a911a8b342c8bsalomon@google.com *requiresAA = false; 7334cd70a5810b3cf37b44de1ce080a911a8b342c8bsalomon@google.com } 7434cd70a5810b3cf37b44de1ce080a911a8b342c8bsalomon@google.com } else if (isectRect.intersect(stackBounds, scalarQueryBounds)) { 75e5b2af955b7d06815ddd405659ad62a2a8355ca3commit-bot@chromium.org // If the caller asked for tighter integer bounds we may be able to 76e5b2af955b7d06815ddd405659ad62a2a8355ca3commit-bot@chromium.org // return kAllIn and give the bounds with no elements 7734cd70a5810b3cf37b44de1ce080a911a8b342c8bsalomon@google.com if (NULL != tighterBounds) { 7834cd70a5810b3cf37b44de1ce080a911a8b342c8bsalomon@google.com isectRect.roundOut(tighterBounds); 794469938e92d779dff05e745559e67907bbf21e78reed@google.com SkRect scalarTighterBounds = SkRect::Make(*tighterBounds); 8034cd70a5810b3cf37b44de1ce080a911a8b342c8bsalomon@google.com if (scalarTighterBounds == isectRect) { 8134cd70a5810b3cf37b44de1ce080a911a8b342c8bsalomon@google.com // the round-out didn't add any area outside the clip rect. 82d3e5842db0cb169e10d6da1e62c94ba5cf182bb4commit-bot@chromium.org if (NULL != requiresAA) { 83d3e5842db0cb169e10d6da1e62c94ba5cf182bb4commit-bot@chromium.org *requiresAA = false; 84d3e5842db0cb169e10d6da1e62c94ba5cf182bb4commit-bot@chromium.org } 8534cd70a5810b3cf37b44de1ce080a911a8b342c8bsalomon@google.com *initialState = kAllIn_InitialState; 8634cd70a5810b3cf37b44de1ce080a911a8b342c8bsalomon@google.com return; 8734cd70a5810b3cf37b44de1ce080a911a8b342c8bsalomon@google.com } 88e5b2af955b7d06815ddd405659ad62a2a8355ca3commit-bot@chromium.org } 89e5b2af955b7d06815ddd405659ad62a2a8355ca3commit-bot@chromium.org *initialState = kAllOut_InitialState; 90e5b2af955b7d06815ddd405659ad62a2a8355ca3commit-bot@chromium.org // iior should only be true if aa/non-aa status matches among all elements. 91e5b2af955b7d06815ddd405659ad62a2a8355ca3commit-bot@chromium.org SkClipStack::Iter iter(stack, SkClipStack::Iter::kTop_IterStart); 92e5b2af955b7d06815ddd405659ad62a2a8355ca3commit-bot@chromium.org bool doAA = iter.prev()->isAA(); 93e5b2af955b7d06815ddd405659ad62a2a8355ca3commit-bot@chromium.org SkNEW_INSERT_AT_LLIST_HEAD(result, Element, (isectRect, SkRegion::kReplace_Op, doAA)); 94e5b2af955b7d06815ddd405659ad62a2a8355ca3commit-bot@chromium.org if (NULL != requiresAA) { 95e5b2af955b7d06815ddd405659ad62a2a8355ca3commit-bot@chromium.org *requiresAA = doAA; 9634cd70a5810b3cf37b44de1ce080a911a8b342c8bsalomon@google.com } 97170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com } else { 98170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com *initialState = kAllOut_InitialState; 9934cd70a5810b3cf37b44de1ce080a911a8b342c8bsalomon@google.com if (NULL != requiresAA) { 10034cd70a5810b3cf37b44de1ce080a911a8b342c8bsalomon@google.com *requiresAA = false; 10134cd70a5810b3cf37b44de1ce080a911a8b342c8bsalomon@google.com } 102170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com } 103170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com return; 104170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com } else { 105170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com if (SkClipStack::kNormal_BoundsType == stackBoundsType) { 10634cd70a5810b3cf37b44de1ce080a911a8b342c8bsalomon@google.com if (!SkRect::Intersects(stackBounds, scalarQueryBounds)) { 107170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com *initialState = kAllOut_InitialState; 10834cd70a5810b3cf37b44de1ce080a911a8b342c8bsalomon@google.com if (NULL != requiresAA) { 10934cd70a5810b3cf37b44de1ce080a911a8b342c8bsalomon@google.com *requiresAA = false; 11034cd70a5810b3cf37b44de1ce080a911a8b342c8bsalomon@google.com } 111170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com return; 112170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com } 11334cd70a5810b3cf37b44de1ce080a911a8b342c8bsalomon@google.com if (NULL != tighterBounds) { 11434cd70a5810b3cf37b44de1ce080a911a8b342c8bsalomon@google.com SkIRect stackIBounds; 11534cd70a5810b3cf37b44de1ce080a911a8b342c8bsalomon@google.com stackBounds.roundOut(&stackIBounds); 11634cd70a5810b3cf37b44de1ce080a911a8b342c8bsalomon@google.com tighterBounds->intersect(queryBounds, stackIBounds); 11734cd70a5810b3cf37b44de1ce080a911a8b342c8bsalomon@google.com bounds = tighterBounds; 11834cd70a5810b3cf37b44de1ce080a911a8b342c8bsalomon@google.com } 119170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com } else { 12034cd70a5810b3cf37b44de1ce080a911a8b342c8bsalomon@google.com if (stackBounds.contains(scalarQueryBounds)) { 121170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com *initialState = kAllOut_InitialState; 12234cd70a5810b3cf37b44de1ce080a911a8b342c8bsalomon@google.com if (NULL != requiresAA) { 12334cd70a5810b3cf37b44de1ce080a911a8b342c8bsalomon@google.com *requiresAA = false; 12434cd70a5810b3cf37b44de1ce080a911a8b342c8bsalomon@google.com } 125170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com return; 126170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com } 12734cd70a5810b3cf37b44de1ce080a911a8b342c8bsalomon@google.com if (NULL != tighterBounds) { 12834cd70a5810b3cf37b44de1ce080a911a8b342c8bsalomon@google.com *tighterBounds = queryBounds; 12934cd70a5810b3cf37b44de1ce080a911a8b342c8bsalomon@google.com } 130170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com } 131170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com } 132170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com 1334469938e92d779dff05e745559e67907bbf21e78reed@google.com SkRect scalarBounds = SkRect::Make(*bounds); 134d21444aab7128c97f4e0eb5e9bf05111d5037292skia.committer@gmail.com 13534cd70a5810b3cf37b44de1ce080a911a8b342c8bsalomon@google.com // Now that we have determined the bounds to use and filtered out the trivial cases, call the 13634cd70a5810b3cf37b44de1ce080a911a8b342c8bsalomon@google.com // helper that actually walks the stack. 137d3e5842db0cb169e10d6da1e62c94ba5cf182bb4commit-bot@chromium.org reduced_stack_walker(stack, scalarBounds, result, resultGenID, initialState, requiresAA); 138d3e5842db0cb169e10d6da1e62c94ba5cf182bb4commit-bot@chromium.org 139d3e5842db0cb169e10d6da1e62c94ba5cf182bb4commit-bot@chromium.org // The list that was computed in this function may be cached based on the gen id of the last 140d3e5842db0cb169e10d6da1e62c94ba5cf182bb4commit-bot@chromium.org // element. 141d3e5842db0cb169e10d6da1e62c94ba5cf182bb4commit-bot@chromium.org SkASSERT(SkClipStack::kInvalidGenID != *resultGenID); 14234cd70a5810b3cf37b44de1ce080a911a8b342c8bsalomon@google.com} 14334cd70a5810b3cf37b44de1ce080a911a8b342c8bsalomon@google.com 14434cd70a5810b3cf37b44de1ce080a911a8b342c8bsalomon@google.comvoid reduced_stack_walker(const SkClipStack& stack, 14534cd70a5810b3cf37b44de1ce080a911a8b342c8bsalomon@google.com const SkRect& queryBounds, 14634cd70a5810b3cf37b44de1ce080a911a8b342c8bsalomon@google.com ElementList* result, 147d3e5842db0cb169e10d6da1e62c94ba5cf182bb4commit-bot@chromium.org int32_t* resultGenID, 14834cd70a5810b3cf37b44de1ce080a911a8b342c8bsalomon@google.com InitialState* initialState, 14934cd70a5810b3cf37b44de1ce080a911a8b342c8bsalomon@google.com bool* requiresAA) { 15034cd70a5810b3cf37b44de1ce080a911a8b342c8bsalomon@google.com 151170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com // walk backwards until we get to: 152170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com // a) the beginning 153170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com // b) an operation that is known to make the bounds all inside/outside 154170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com // c) a replace operation 155170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com 156170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com static const InitialState kUnknown_InitialState = static_cast<InitialState>(-1); 157170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com *initialState = kUnknown_InitialState; 158170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com 159170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com // During our backwards walk, track whether we've seen ops that either grow or shrink the clip. 160170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com // TODO: track these per saved clip so that we can consider them on the forward pass. 161170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com bool embiggens = false; 162170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com bool emsmallens = false; 163170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com 164170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com SkClipStack::Iter iter(stack, SkClipStack::Iter::kTop_IterStart); 16534cd70a5810b3cf37b44de1ce080a911a8b342c8bsalomon@google.com int numAAElements = 0; 166170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com while ((kUnknown_InitialState == *initialState)) { 167170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com const Element* element = iter.prev(); 168170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com if (NULL == element) { 169170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com *initialState = kAllIn_InitialState; 170170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com break; 171170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com } 172170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com if (SkClipStack::kEmptyGenID == element->getGenID()) { 173170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com *initialState = kAllOut_InitialState; 174170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com break; 175170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com } 176170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com if (SkClipStack::kWideOpenGenID == element->getGenID()) { 177170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com *initialState = kAllIn_InitialState; 178170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com break; 179170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com } 180170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com 181170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com bool skippable = false; 182170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com bool isFlip = false; // does this op just flip the in/out state of every point in the bounds 183170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com 184170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com switch (element->getOp()) { 185170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com case SkRegion::kDifference_Op: 186170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com // check if the shape subtracted either contains the entire bounds (and makes 187170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com // the clip empty) or is outside the bounds and therefore can be skipped. 188170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com if (element->isInverseFilled()) { 189170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com if (element->contains(queryBounds)) { 190170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com skippable = true; 191170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com } else if (!SkRect::Intersects(element->getBounds(), queryBounds)) { 192170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com *initialState = kAllOut_InitialState; 193170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com skippable = true; 194170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com } 195170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com } else { 196170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com if (element->contains(queryBounds)) { 197170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com *initialState = kAllOut_InitialState; 198170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com skippable = true; 199170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com } else if (!SkRect::Intersects(element->getBounds(), queryBounds)) { 200170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com skippable = true; 201170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com } 202170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com } 203170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com if (!skippable) { 204170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com emsmallens = true; 205170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com } 206170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com break; 207170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com case SkRegion::kIntersect_Op: 208170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com // check if the shape intersected contains the entire bounds and therefore can 209170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com // be skipped or it is outside the entire bounds and therefore makes the clip 210170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com // empty. 211170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com if (element->isInverseFilled()) { 212170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com if (element->contains(queryBounds)) { 213170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com *initialState = kAllOut_InitialState; 214170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com skippable = true; 215170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com } else if (!SkRect::Intersects(element->getBounds(), queryBounds)) { 216170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com skippable = true; 217170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com } 218170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com } else { 219170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com if (element->contains(queryBounds)) { 220170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com skippable = true; 221170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com } else if (!SkRect::Intersects(element->getBounds(), queryBounds)) { 222170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com *initialState = kAllOut_InitialState; 223170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com skippable = true; 224170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com } 225170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com } 226170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com if (!skippable) { 227170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com emsmallens = true; 228170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com } 229170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com break; 230170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com case SkRegion::kUnion_Op: 231170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com // If the union-ed shape contains the entire bounds then after this element 232170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com // the bounds is entirely inside the clip. If the union-ed shape is outside the 233170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com // bounds then this op can be skipped. 234170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com if (element->isInverseFilled()) { 235170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com if (element->contains(queryBounds)) { 236170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com skippable = true; 237170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com } else if (!SkRect::Intersects(element->getBounds(), queryBounds)) { 238170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com *initialState = kAllIn_InitialState; 239170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com skippable = true; 240170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com } 241170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com } else { 242170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com if (element->contains(queryBounds)) { 243170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com *initialState = kAllIn_InitialState; 244170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com skippable = true; 245170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com } else if (!SkRect::Intersects(element->getBounds(), queryBounds)) { 246170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com skippable = true; 247170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com } 248170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com } 249170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com if (!skippable) { 250170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com embiggens = true; 251170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com } 252170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com break; 253170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com case SkRegion::kXOR_Op: 254170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com // If the bounds is entirely inside the shape being xor-ed then the effect is 255170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com // to flip the inside/outside state of every point in the bounds. We may be 256170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com // able to take advantage of this in the forward pass. If the xor-ed shape 257170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com // doesn't intersect the bounds then it can be skipped. 258170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com if (element->isInverseFilled()) { 259170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com if (element->contains(queryBounds)) { 260170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com skippable = true; 261170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com } else if (!SkRect::Intersects(element->getBounds(), queryBounds)) { 262170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com isFlip = true; 263170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com } 264170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com } else { 265170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com if (element->contains(queryBounds)) { 266170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com isFlip = true; 267170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com } else if (!SkRect::Intersects(element->getBounds(), queryBounds)) { 268170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com skippable = true; 269170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com } 270170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com } 271170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com if (!skippable) { 272170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com emsmallens = embiggens = true; 273170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com } 274170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com break; 275170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com case SkRegion::kReverseDifference_Op: 276170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com // When the bounds is entirely within the rev-diff shape then this behaves like xor 277170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com // and reverses every point inside the bounds. If the shape is completely outside 278170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com // the bounds then we know after this element is applied that the bounds will be 279170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com // all outside the current clip.B 280170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com if (element->isInverseFilled()) { 281170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com if (element->contains(queryBounds)) { 282170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com *initialState = kAllOut_InitialState; 283170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com skippable = true; 284170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com } else if (!SkRect::Intersects(element->getBounds(), queryBounds)) { 285170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com isFlip = true; 286170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com } 287170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com } else { 288170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com if (element->contains(queryBounds)) { 289170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com isFlip = true; 290170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com } else if (!SkRect::Intersects(element->getBounds(), queryBounds)) { 291170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com *initialState = kAllOut_InitialState; 292170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com skippable = true; 293170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com } 294170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com } 295170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com if (!skippable) { 296170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com emsmallens = embiggens = true; 297170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com } 298170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com break; 299170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com case SkRegion::kReplace_Op: 300170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com // Replace will always terminate our walk. We will either begin the forward walk 301170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com // at the replace op or detect here than the shape is either completely inside 302170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com // or completely outside the bounds. In this latter case it can be skipped by 303170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com // setting the correct value for initialState. 304170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com if (element->isInverseFilled()) { 305170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com if (element->contains(queryBounds)) { 306170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com *initialState = kAllOut_InitialState; 307170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com skippable = true; 308170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com } else if (!SkRect::Intersects(element->getBounds(), queryBounds)) { 309170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com *initialState = kAllIn_InitialState; 310170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com skippable = true; 311170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com } 312170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com } else { 313170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com if (element->contains(queryBounds)) { 314170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com *initialState = kAllIn_InitialState; 315170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com skippable = true; 316170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com } else if (!SkRect::Intersects(element->getBounds(), queryBounds)) { 317170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com *initialState = kAllOut_InitialState; 318170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com skippable = true; 319170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com } 320170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com } 321170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com if (!skippable) { 322170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com *initialState = kAllOut_InitialState; 323170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com embiggens = emsmallens = true; 324170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com } 325170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com break; 326170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com default: 327170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com SkDEBUGFAIL("Unexpected op."); 328170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com break; 329170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com } 330170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com if (!skippable) { 331d3e5842db0cb169e10d6da1e62c94ba5cf182bb4commit-bot@chromium.org if (0 == result->count()) { 332d3e5842db0cb169e10d6da1e62c94ba5cf182bb4commit-bot@chromium.org // This will be the last element. Record the stricter genID. 333d3e5842db0cb169e10d6da1e62c94ba5cf182bb4commit-bot@chromium.org *resultGenID = element->getGenID(); 334d3e5842db0cb169e10d6da1e62c94ba5cf182bb4commit-bot@chromium.org } 335d3e5842db0cb169e10d6da1e62c94ba5cf182bb4commit-bot@chromium.org 336170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com // if it is a flip, change it to a bounds-filling rect 337170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com if (isFlip) { 338170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com SkASSERT(SkRegion::kXOR_Op == element->getOp() || 339170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com SkRegion::kReverseDifference_Op == element->getOp()); 340170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com SkNEW_INSERT_AT_LLIST_HEAD(result, 341170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com Element, 342170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com (queryBounds, SkRegion::kReverseDifference_Op, false)); 343170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com } else { 344c6b3e48cb3a22d83ba3f4b9a614a5a35b05958a0bsalomon@google.com Element* newElement = result->addToHead(*element); 345c6b3e48cb3a22d83ba3f4b9a614a5a35b05958a0bsalomon@google.com if (newElement->isAA()) { 34634cd70a5810b3cf37b44de1ce080a911a8b342c8bsalomon@google.com ++numAAElements; 34734cd70a5810b3cf37b44de1ce080a911a8b342c8bsalomon@google.com } 348c6b3e48cb3a22d83ba3f4b9a614a5a35b05958a0bsalomon@google.com // Intersecting an inverse shape is the same as differencing the non-inverse shape. 34945a15f551b5b3c6c747d8eaf6466b7d3b76a8faebsalomon@google.com // Replacing with an inverse shape is the same as setting initialState=kAllIn and 350c6b3e48cb3a22d83ba3f4b9a614a5a35b05958a0bsalomon@google.com // differencing the non-inverse shape. 351c6b3e48cb3a22d83ba3f4b9a614a5a35b05958a0bsalomon@google.com bool isReplace = SkRegion::kReplace_Op == newElement->getOp(); 352c6b3e48cb3a22d83ba3f4b9a614a5a35b05958a0bsalomon@google.com if (newElement->isInverseFilled() && 353c6b3e48cb3a22d83ba3f4b9a614a5a35b05958a0bsalomon@google.com (SkRegion::kIntersect_Op == newElement->getOp() || isReplace)) { 354c6b3e48cb3a22d83ba3f4b9a614a5a35b05958a0bsalomon@google.com newElement->invertShapeFillType(); 355c6b3e48cb3a22d83ba3f4b9a614a5a35b05958a0bsalomon@google.com newElement->setOp(SkRegion::kDifference_Op); 356c6b3e48cb3a22d83ba3f4b9a614a5a35b05958a0bsalomon@google.com if (isReplace) { 357c6b3e48cb3a22d83ba3f4b9a614a5a35b05958a0bsalomon@google.com SkASSERT(kAllOut_InitialState == *initialState); 358c6b3e48cb3a22d83ba3f4b9a614a5a35b05958a0bsalomon@google.com *initialState = kAllIn_InitialState; 359c6b3e48cb3a22d83ba3f4b9a614a5a35b05958a0bsalomon@google.com } 360c6b3e48cb3a22d83ba3f4b9a614a5a35b05958a0bsalomon@google.com } 361170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com } 362170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com } 363170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com } 364170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com 365170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com if ((kAllOut_InitialState == *initialState && !embiggens) || 366170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com (kAllIn_InitialState == *initialState && !emsmallens)) { 367170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com result->reset(); 368170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com } else { 369170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com Element* element = result->headIter().get(); 370170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com while (NULL != element) { 371170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com bool skippable = false; 372170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com switch (element->getOp()) { 373170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com case SkRegion::kDifference_Op: 374170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com // subtracting from the empty set yields the empty set. 375170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com skippable = kAllOut_InitialState == *initialState; 376170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com break; 377170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com case SkRegion::kIntersect_Op: 378170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com // intersecting with the empty set yields the empty set 379db62709fc19522b39a645557e45417aa82708107commit-bot@chromium.org if (kAllOut_InitialState == *initialState) { 380db62709fc19522b39a645557e45417aa82708107commit-bot@chromium.org skippable = true; 381db62709fc19522b39a645557e45417aa82708107commit-bot@chromium.org } else { 382db62709fc19522b39a645557e45417aa82708107commit-bot@chromium.org // We can clear to zero and then simply draw the clip element. 383db62709fc19522b39a645557e45417aa82708107commit-bot@chromium.org *initialState = kAllOut_InitialState; 384db62709fc19522b39a645557e45417aa82708107commit-bot@chromium.org element->setOp(SkRegion::kReplace_Op); 385db62709fc19522b39a645557e45417aa82708107commit-bot@chromium.org } 386170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com break; 387170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com case SkRegion::kUnion_Op: 388170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com if (kAllIn_InitialState == *initialState) { 389170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com // unioning the infinite plane with anything is a no-op. 390170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com skippable = true; 391170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com } else { 392170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com // unioning the empty set with a shape is the shape. 393170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com element->setOp(SkRegion::kReplace_Op); 394170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com } 395170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com break; 396170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com case SkRegion::kXOR_Op: 397170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com if (kAllOut_InitialState == *initialState) { 398170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com // xor could be changed to diff in the kAllIn case, not sure it's a win. 399170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com element->setOp(SkRegion::kReplace_Op); 400170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com } 401170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com break; 402170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com case SkRegion::kReverseDifference_Op: 403170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com if (kAllIn_InitialState == *initialState) { 404170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com // subtracting the whole plane will yield the empty set. 405170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com skippable = true; 406170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com *initialState = kAllOut_InitialState; 407170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com } else { 408170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com // this picks up flips inserted in the backwards pass. 409170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com skippable = element->isInverseFilled() ? 410170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com !SkRect::Intersects(element->getBounds(), queryBounds) : 411170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com element->contains(queryBounds); 412170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com if (skippable) { 413170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com *initialState = kAllIn_InitialState; 414170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com } else { 415170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com element->setOp(SkRegion::kReplace_Op); 416170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com } 417170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com } 418170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com break; 419170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com case SkRegion::kReplace_Op: 420170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com skippable = false; // we would have skipped it in the backwards walk if we 421170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com // could've. 422170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com break; 423170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com default: 424170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com SkDEBUGFAIL("Unexpected op."); 425170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com break; 426170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com } 427170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com if (!skippable) { 428170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com break; 429170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com } else { 43034cd70a5810b3cf37b44de1ce080a911a8b342c8bsalomon@google.com if (element->isAA()) { 43134cd70a5810b3cf37b44de1ce080a911a8b342c8bsalomon@google.com --numAAElements; 43234cd70a5810b3cf37b44de1ce080a911a8b342c8bsalomon@google.com } 433170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com result->popHead(); 434170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com element = result->headIter().get(); 435170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com } 436170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com } 437170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com } 43834cd70a5810b3cf37b44de1ce080a911a8b342c8bsalomon@google.com if (NULL != requiresAA) { 43934cd70a5810b3cf37b44de1ce080a911a8b342c8bsalomon@google.com *requiresAA = numAAElements > 0; 44034cd70a5810b3cf37b44de1ce080a911a8b342c8bsalomon@google.com } 441d3e5842db0cb169e10d6da1e62c94ba5cf182bb4commit-bot@chromium.org 442d3e5842db0cb169e10d6da1e62c94ba5cf182bb4commit-bot@chromium.org if (0 == result->count()) { 443d3e5842db0cb169e10d6da1e62c94ba5cf182bb4commit-bot@chromium.org if (*initialState == kAllIn_InitialState) { 444d3e5842db0cb169e10d6da1e62c94ba5cf182bb4commit-bot@chromium.org *resultGenID = SkClipStack::kWideOpenGenID; 445d3e5842db0cb169e10d6da1e62c94ba5cf182bb4commit-bot@chromium.org } else { 446d3e5842db0cb169e10d6da1e62c94ba5cf182bb4commit-bot@chromium.org *resultGenID = SkClipStack::kEmptyGenID; 447d3e5842db0cb169e10d6da1e62c94ba5cf182bb4commit-bot@chromium.org } 448d3e5842db0cb169e10d6da1e62c94ba5cf182bb4commit-bot@chromium.org } 449170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com} 450170bd792e17469769d145b7dc15dea6cd01b7966bsalomon@google.com} // namespace GrReducedClip 451