aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/gpu
diff options
context:
space:
mode:
authorGravatar bsalomon@google.com <bsalomon@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2012-12-04 15:22:12 +0000
committerGravatar bsalomon@google.com <bsalomon@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2012-12-04 15:22:12 +0000
commita444430281ea35cb76fb42516978b4a93221c2c7 (patch)
tree81422ef04fcf935c553944bf9dcfab6f5e54e24e /src/gpu
parent4b90b1122c93e6600ea352f4ccf1dfc54c8bb146 (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.cpp244
-rw-r--r--src/gpu/GrClipMaskManager.h17
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