diff options
author | bsalomon@google.com <bsalomon@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2012-12-04 15:22:12 +0000 |
---|---|---|
committer | bsalomon@google.com <bsalomon@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2012-12-04 15:22:12 +0000 |
commit | a444430281ea35cb76fb42516978b4a93221c2c7 (patch) | |
tree | 81422ef04fcf935c553944bf9dcfab6f5e54e24e /src/gpu | |
parent | 4b90b1122c93e6600ea352f4ccf1dfc54c8bb146 (diff) |
Make GrReduceClipStack use a caller provided query rect rather than return a
bounds.
R=robertphillips@google.com
Review URL: https://codereview.appspot.com/6865059
git-svn-id: http://skia.googlecode.com/svn/trunk@6665 2bbb7eff-a529-9590-31e7-b0007b416f81
Diffstat (limited to 'src/gpu')
-rw-r--r-- | src/gpu/GrClipMaskManager.cpp | 244 | ||||
-rw-r--r-- | src/gpu/GrClipMaskManager.h | 17 |
2 files changed, 130 insertions, 131 deletions
diff --git a/src/gpu/GrClipMaskManager.cpp b/src/gpu/GrClipMaskManager.cpp index 64ead1a336..1b8bcd4659 100644 --- a/src/gpu/GrClipMaskManager.cpp +++ b/src/gpu/GrClipMaskManager.cpp @@ -39,33 +39,49 @@ based on later intersect operations, and perhaps remove intersect-rects. We coul take a rect in case the caller knows a bound on what is to be drawn through this clip. */ void GrReduceClipStack(const SkClipStack& stack, + const SkRect& queryBounds, ElementList* result, - SkRect* resultBounds, - bool* resultsAreBounded, InitialState* initialState) { result->reset(); if (stack.isWideOpen()) { *initialState = kAllIn_InitialState; - *resultsAreBounded = false; return; } - SkClipStack::BoundsType type; + SkClipStack::BoundsType stackBoundsType; + SkRect stackBounds; bool iior; - stack.getBounds(resultBounds, &type, &iior); + stack.getBounds(&stackBounds, &stackBoundsType, &iior); + if (iior) { - *resultsAreBounded = true; - *initialState = kAllOut_InitialState; - SkClipStack::Iter iter(stack, SkClipStack::Iter::kTop_IterStart); - // iior should only be true if aa/non-aa status matches among all elements. - bool doAA = iter.prev()->isAA(); - SkNEW_INSERT_AT_LLIST_TAIL(result, Element, (*resultBounds, SkRegion::kReplace_Op, doAA)); + SkASSERT(SkClipStack::kNormal_BoundsType == stackBoundsType); + SkRect isectRect; + if (stackBounds.contains(queryBounds)) { + *initialState = kAllIn_InitialState; + } else if (isectRect.intersect(stackBounds, queryBounds)) { + // iior should only be true if aa/non-aa status matches among all elements. + SkClipStack::Iter iter(stack, SkClipStack::Iter::kTop_IterStart); + bool doAA = iter.prev()->isAA(); + SkNEW_INSERT_AT_LLIST_HEAD(result, Element, (isectRect, SkRegion::kReplace_Op, doAA)); + } else { + *initialState = kAllOut_InitialState; + } return; + } else { + if (SkClipStack::kNormal_BoundsType == stackBoundsType) { + if (!SkRect::Intersects(stackBounds, queryBounds)) { + *initialState = kAllOut_InitialState; + return; + } + } else { + if (stackBounds.contains(queryBounds)) { + *initialState = kAllOut_InitialState; + return; + } + } } - *resultsAreBounded = SkClipStack::kNormal_BoundsType == type && !resultBounds->isEmpty(); - // walk backwards until we get to: // a) the beginning // b) an operation that is known to make the bounds all inside/outside @@ -100,23 +116,21 @@ void GrReduceClipStack(const SkClipStack& stack, switch (element->getOp()) { case SkRegion::kDifference_Op: - if (*resultsAreBounded) { - // check if the shape subtracted either contains the entire bounds (and makes - // the clip empty) or is outside the bounds and therefore can be skipped. - if (element->isInverseFilled()) { - if (element->contains(*resultBounds)) { - skippable = true; - } else if (!SkRect::Intersects(element->getBounds(), *resultBounds)) { - *initialState = kAllOut_InitialState; - skippable = true; - } - } else { - if (element->contains(*resultBounds)) { - *initialState = kAllOut_InitialState; - skippable = true; - } else if (!SkRect::Intersects(element->getBounds(), *resultBounds)) { - skippable = true; - } + // check if the shape subtracted either contains the entire bounds (and makes + // the clip empty) or is outside the bounds and therefore can be skipped. + if (element->isInverseFilled()) { + if (element->contains(queryBounds)) { + skippable = true; + } else if (!SkRect::Intersects(element->getBounds(), queryBounds)) { + *initialState = kAllOut_InitialState; + skippable = true; + } + } else { + if (element->contains(queryBounds)) { + *initialState = kAllOut_InitialState; + skippable = true; + } else if (!SkRect::Intersects(element->getBounds(), queryBounds)) { + skippable = true; } } if (!skippable) { @@ -124,24 +138,22 @@ void GrReduceClipStack(const SkClipStack& stack, } break; case SkRegion::kIntersect_Op: - if (*resultsAreBounded) { - // check if the shape intersected contains the entire bounds and therefore can - // be skipped or it is outside the entire bounds and therefore makes the clip - // empty. - if (element->isInverseFilled()) { - if (element->contains(*resultBounds)) { - *initialState = kAllOut_InitialState; - skippable = true; - } else if (!SkRect::Intersects(element->getBounds(), *resultBounds)) { - skippable = true; - } - } else { - if (element->contains(*resultBounds)) { - skippable = true; - } else if (!SkRect::Intersects(element->getBounds(), *resultBounds)) { - *initialState = kAllOut_InitialState; - skippable = true; - } + // check if the shape intersected contains the entire bounds and therefore can + // be skipped or it is outside the entire bounds and therefore makes the clip + // empty. + if (element->isInverseFilled()) { + if (element->contains(queryBounds)) { + *initialState = kAllOut_InitialState; + skippable = true; + } else if (!SkRect::Intersects(element->getBounds(), queryBounds)) { + skippable = true; + } + } else { + if (element->contains(queryBounds)) { + skippable = true; + } else if (!SkRect::Intersects(element->getBounds(), queryBounds)) { + *initialState = kAllOut_InitialState; + skippable = true; } } if (!skippable) { @@ -149,24 +161,22 @@ void GrReduceClipStack(const SkClipStack& stack, } break; case SkRegion::kUnion_Op: - if (*resultsAreBounded) { - // If the union-ed shape contains the entire bounds then after this element - // the bounds is entirely inside the clip. If the union-ed shape is outside the - // bounds then this op can be skipped. - if (element->isInverseFilled()) { - if (element->contains(*resultBounds)) { - skippable = true; - } else if (!SkRect::Intersects(element->getBounds(), *resultBounds)) { - *initialState = kAllIn_InitialState; - skippable = true; - } - } else { - if (element->contains(*resultBounds)) { - *initialState = kAllIn_InitialState; - skippable = true; - } else if (!SkRect::Intersects(element->getBounds(), *resultBounds)) { - skippable = true; - } + // If the union-ed shape contains the entire bounds then after this element + // the bounds is entirely inside the clip. If the union-ed shape is outside the + // bounds then this op can be skipped. + if (element->isInverseFilled()) { + if (element->contains(queryBounds)) { + skippable = true; + } else if (!SkRect::Intersects(element->getBounds(), queryBounds)) { + *initialState = kAllIn_InitialState; + skippable = true; + } + } else { + if (element->contains(queryBounds)) { + *initialState = kAllIn_InitialState; + skippable = true; + } else if (!SkRect::Intersects(element->getBounds(), queryBounds)) { + skippable = true; } } if (!skippable) { @@ -174,23 +184,21 @@ void GrReduceClipStack(const SkClipStack& stack, } break; case SkRegion::kXOR_Op: - if (*resultsAreBounded) { - // If the bounds is entirely inside the shape being xor-ed then the effect is - // to flip the inside/outside state of every point in the bounds. We may be - // able to take advantage of this in the forward pass. If the xor-ed shape - // doesn't intersect the bounds then it can be skipped. - if (element->isInverseFilled()) { - if (element->contains(*resultBounds)) { - skippable = true; - } else if (!SkRect::Intersects(element->getBounds(), *resultBounds)) { - isFlip = true; - } - } else { - if (element->contains(*resultBounds)) { - isFlip = true; - } else if (!SkRect::Intersects(element->getBounds(), *resultBounds)) { - skippable = true; - } + // If the bounds is entirely inside the shape being xor-ed then the effect is + // to flip the inside/outside state of every point in the bounds. We may be + // able to take advantage of this in the forward pass. If the xor-ed shape + // doesn't intersect the bounds then it can be skipped. + if (element->isInverseFilled()) { + if (element->contains(queryBounds)) { + skippable = true; + } else if (!SkRect::Intersects(element->getBounds(), queryBounds)) { + isFlip = true; + } + } else { + if (element->contains(queryBounds)) { + isFlip = true; + } else if (!SkRect::Intersects(element->getBounds(), queryBounds)) { + skippable = true; } } if (!skippable) { @@ -202,21 +210,19 @@ void GrReduceClipStack(const SkClipStack& stack, // and reverses every point inside the bounds. If the shape is completely outside // the bounds then we know after this element is applied that the bounds will be // all outside the current clip.B - if (*resultsAreBounded) { - if (element->isInverseFilled()) { - if (element->contains(*resultBounds)) { - *initialState = kAllOut_InitialState; - skippable = true; - } else if (!SkRect::Intersects(element->getBounds(), *resultBounds)) { - isFlip = true; - } - } else { - if (element->contains(*resultBounds)) { - isFlip = true; - } else if (!SkRect::Intersects(element->getBounds(), *resultBounds)) { - *initialState = kAllOut_InitialState; - skippable = true; - } + if (element->isInverseFilled()) { + if (element->contains(queryBounds)) { + *initialState = kAllOut_InitialState; + skippable = true; + } else if (!SkRect::Intersects(element->getBounds(), queryBounds)) { + isFlip = true; + } + } else { + if (element->contains(queryBounds)) { + isFlip = true; + } else if (!SkRect::Intersects(element->getBounds(), queryBounds)) { + *initialState = kAllOut_InitialState; + skippable = true; } } if (!skippable) { @@ -228,23 +234,21 @@ void GrReduceClipStack(const SkClipStack& stack, // at the replace op or detect here than the shape is either completely inside // or completely outside the bounds. In this latter case it can be skipped by // setting the correct value for initialState. - if (*resultsAreBounded) { - if (element->isInverseFilled()) { - if (element->contains(*resultBounds)) { - *initialState = kAllOut_InitialState; - skippable = true; - } else if (!SkRect::Intersects(element->getBounds(), *resultBounds)) { - *initialState = kAllIn_InitialState; - skippable = true; - } - } else { - if (element->contains(*resultBounds)) { - *initialState = kAllIn_InitialState; - skippable = true; - } else if (!SkRect::Intersects(element->getBounds(), *resultBounds)) { - *initialState = kAllOut_InitialState; - skippable = true; - } + if (element->isInverseFilled()) { + if (element->contains(queryBounds)) { + *initialState = kAllOut_InitialState; + skippable = true; + } else if (!SkRect::Intersects(element->getBounds(), queryBounds)) { + *initialState = kAllIn_InitialState; + skippable = true; + } + } else { + if (element->contains(queryBounds)) { + *initialState = kAllIn_InitialState; + skippable = true; + } else if (!SkRect::Intersects(element->getBounds(), queryBounds)) { + *initialState = kAllOut_InitialState; + skippable = true; } } if (!skippable) { @@ -263,7 +267,7 @@ void GrReduceClipStack(const SkClipStack& stack, SkRegion::kReverseDifference_Op == element->getOp()); SkNEW_INSERT_AT_LLIST_HEAD(result, Element, - (*resultBounds, SkRegion::kReverseDifference_Op, false)); + (queryBounds, SkRegion::kReverseDifference_Op, false)); } else { result->addToHead(*element); } @@ -309,11 +313,9 @@ void GrReduceClipStack(const SkClipStack& stack, *initialState = kAllOut_InitialState; } else { // this picks up flips inserted in the backwards pass. - if (*resultsAreBounded) { - skippable = element->isInverseFilled() ? - !SkRect::Intersects(element->getBounds(), *resultBounds) : - element->contains(*resultBounds); - } + skippable = element->isInverseFilled() ? + !SkRect::Intersects(element->getBounds(), queryBounds) : + element->contains(queryBounds); if (skippable) { *initialState = kAllIn_InitialState; } else { diff --git a/src/gpu/GrClipMaskManager.h b/src/gpu/GrClipMaskManager.h index c3a1b5ee70..0c8484abf1 100644 --- a/src/gpu/GrClipMaskManager.h +++ b/src/gpu/GrClipMaskManager.h @@ -167,19 +167,16 @@ enum InitialState { kAllOut_InitialState, }; -/** This function takes a clip stack and produces a reduced set of SkClipStack::Iter::Clip elements - * in param clips that are equivalent to the full stack. If a finite bound for the area inside the - * clip can be determined resultsAreBounds will be true and resultBounds will be those bounds. When - * the results are bounded it is assumed that the caller will restrict the effect of each operation - * to the bounds or intersect with the bounds as a final step. The initial state of the bounds (or - * the unbounded plane when resultsArBounded is false) before the first element of clips is applied - * is returned via initialState. This function is declared here so that it can be unit-tested. It - * may become a member function of SkClipStack when its interface is determined to be stable. +/** + * This function takes a clip stack and a query rectangle and it produces a reduced set of + * SkClipStack::Elements that are equivalent to applying the full stack to the rectangle. The + * initial state of the query rectangle before the first clip element is applied is returned via + * initialState. This function is declared here so that it can be unit-tested. It may become a + * member function of SkClipStack when its interface is determined to be stable. */ void GrReduceClipStack(const SkClipStack& stack, + const SkRect& queryBounds, ElementList* result, - SkRect* resultBounds, - bool* resultsAreBounded, InitialState* initialState); } // namespace GrReducedClip |