| Index: src/gpu/GrReducedClip.cpp
|
| diff --git a/src/gpu/GrReducedClip.cpp b/src/gpu/GrReducedClip.cpp
|
| index 2940f6a682a6db215667f0361dc18d34c9b1be02..f7bac4aa58ab8e1ac6bed3a5f8a9fbb9e95139a4 100644
|
| --- a/src/gpu/GrReducedClip.cpp
|
| +++ b/src/gpu/GrReducedClip.cpp
|
| @@ -1,5 +1,5 @@
|
| /*
|
| - * Copyright 2012 Google Inc.
|
| + * Copyright 2016 Google Inc.
|
| *
|
| * Use of this source code is governed by a BSD-style license that can be
|
| * found in the LICENSE file.
|
| @@ -23,9 +23,11 @@ static GrReducedClip::InitialState reduced_stack_walker(const SkClipStack& stack
|
| // b) an operation that is known to make the bounds all inside/outside
|
| // c) a replace operation
|
|
|
| - static const GrReducedClip::InitialState kUnknown_InitialState =
|
| - static_cast<GrReducedClip::InitialState>(-1);
|
| - GrReducedClip::InitialState initialState = kUnknown_InitialState;
|
| + enum class InitialTriState {
|
| + kUnknown = -1,
|
| + kAllIn = (int)GrReducedClip::InitialState::kAllIn,
|
| + kAllOut = (int)GrReducedClip::InitialState::kAllOut
|
| + } initialState = InitialTriState::kUnknown;
|
|
|
| // During our backwards walk, track whether we've seen ops that either grow or shrink the clip.
|
| // TODO: track these per saved clip so that we can consider them on the forward pass.
|
| @@ -39,18 +41,18 @@ static GrReducedClip::InitialState reduced_stack_walker(const SkClipStack& stack
|
|
|
| SkClipStack::Iter iter(stack, SkClipStack::Iter::kTop_IterStart);
|
| int numAAElements = 0;
|
| - while (kUnknown_InitialState == initialState) {
|
| + while (InitialTriState::kUnknown == initialState) {
|
| const Element* element = iter.prev();
|
| if (nullptr == element) {
|
| - initialState = GrReducedClip::kAllIn_InitialState;
|
| + initialState = InitialTriState::kAllIn;
|
| break;
|
| }
|
| if (SkClipStack::kEmptyGenID == element->getGenID()) {
|
| - initialState = GrReducedClip::kAllOut_InitialState;
|
| + initialState = InitialTriState::kAllOut;
|
| break;
|
| }
|
| if (SkClipStack::kWideOpenGenID == element->getGenID()) {
|
| - initialState = GrReducedClip::kAllIn_InitialState;
|
| + initialState = InitialTriState::kAllIn;
|
| break;
|
| }
|
|
|
| @@ -65,12 +67,12 @@ static GrReducedClip::InitialState reduced_stack_walker(const SkClipStack& stack
|
| if (element->contains(relaxedQueryBounds)) {
|
| skippable = true;
|
| } else if (GrClip::IsOutsideClip(element->getBounds(), queryBounds)) {
|
| - initialState = GrReducedClip::kAllOut_InitialState;
|
| + initialState = InitialTriState::kAllOut;
|
| skippable = true;
|
| }
|
| } else {
|
| if (element->contains(relaxedQueryBounds)) {
|
| - initialState = GrReducedClip::kAllOut_InitialState;
|
| + initialState = InitialTriState::kAllOut;
|
| skippable = true;
|
| } else if (GrClip::IsOutsideClip(element->getBounds(), queryBounds)) {
|
| skippable = true;
|
| @@ -86,7 +88,7 @@ static GrReducedClip::InitialState reduced_stack_walker(const SkClipStack& stack
|
| // empty.
|
| if (element->isInverseFilled()) {
|
| if (element->contains(relaxedQueryBounds)) {
|
| - initialState = GrReducedClip::kAllOut_InitialState;
|
| + initialState = InitialTriState::kAllOut;
|
| skippable = true;
|
| } else if (GrClip::IsOutsideClip(element->getBounds(), queryBounds)) {
|
| skippable = true;
|
| @@ -95,7 +97,7 @@ static GrReducedClip::InitialState reduced_stack_walker(const SkClipStack& stack
|
| if (element->contains(relaxedQueryBounds)) {
|
| skippable = true;
|
| } else if (GrClip::IsOutsideClip(element->getBounds(), queryBounds)) {
|
| - initialState = GrReducedClip::kAllOut_InitialState;
|
| + initialState = InitialTriState::kAllOut;
|
| skippable = true;
|
| }
|
| }
|
| @@ -111,12 +113,12 @@ static GrReducedClip::InitialState reduced_stack_walker(const SkClipStack& stack
|
| if (element->contains(relaxedQueryBounds)) {
|
| skippable = true;
|
| } else if (GrClip::IsOutsideClip(element->getBounds(), queryBounds)) {
|
| - initialState = GrReducedClip::kAllIn_InitialState;
|
| + initialState = InitialTriState::kAllIn;
|
| skippable = true;
|
| }
|
| } else {
|
| if (element->contains(relaxedQueryBounds)) {
|
| - initialState = GrReducedClip::kAllIn_InitialState;
|
| + initialState = InitialTriState::kAllIn;
|
| skippable = true;
|
| } else if (GrClip::IsOutsideClip(element->getBounds(), queryBounds)) {
|
| skippable = true;
|
| @@ -155,7 +157,7 @@ static GrReducedClip::InitialState reduced_stack_walker(const SkClipStack& stack
|
| // all outside the current clip.B
|
| if (element->isInverseFilled()) {
|
| if (element->contains(relaxedQueryBounds)) {
|
| - initialState = GrReducedClip::kAllOut_InitialState;
|
| + initialState = InitialTriState::kAllOut;
|
| skippable = true;
|
| } else if (GrClip::IsOutsideClip(element->getBounds(), queryBounds)) {
|
| isFlip = true;
|
| @@ -164,7 +166,7 @@ static GrReducedClip::InitialState reduced_stack_walker(const SkClipStack& stack
|
| if (element->contains(relaxedQueryBounds)) {
|
| isFlip = true;
|
| } else if (GrClip::IsOutsideClip(element->getBounds(), queryBounds)) {
|
| - initialState = GrReducedClip::kAllOut_InitialState;
|
| + initialState = InitialTriState::kAllOut;
|
| skippable = true;
|
| }
|
| }
|
| @@ -180,23 +182,23 @@ static GrReducedClip::InitialState reduced_stack_walker(const SkClipStack& stack
|
| // setting the correct value for initialState.
|
| if (element->isInverseFilled()) {
|
| if (element->contains(relaxedQueryBounds)) {
|
| - initialState = GrReducedClip::kAllOut_InitialState;
|
| + initialState = InitialTriState::kAllOut;
|
| skippable = true;
|
| } else if (GrClip::IsOutsideClip(element->getBounds(), queryBounds)) {
|
| - initialState = GrReducedClip::kAllIn_InitialState;
|
| + initialState = InitialTriState::kAllIn;
|
| skippable = true;
|
| }
|
| } else {
|
| if (element->contains(relaxedQueryBounds)) {
|
| - initialState = GrReducedClip::kAllIn_InitialState;
|
| + initialState = InitialTriState::kAllIn;
|
| skippable = true;
|
| } else if (GrClip::IsOutsideClip(element->getBounds(), queryBounds)) {
|
| - initialState = GrReducedClip::kAllOut_InitialState;
|
| + initialState = InitialTriState::kAllOut;
|
| skippable = true;
|
| }
|
| }
|
| if (!skippable) {
|
| - initialState = GrReducedClip::kAllOut_InitialState;
|
| + initialState = InitialTriState::kAllOut;
|
| embiggens = emsmallens = true;
|
| }
|
| break;
|
| @@ -230,16 +232,16 @@ static GrReducedClip::InitialState reduced_stack_walker(const SkClipStack& stack
|
| newElement->invertShapeFillType();
|
| newElement->setOp(SkRegion::kDifference_Op);
|
| if (isReplace) {
|
| - SkASSERT(GrReducedClip::kAllOut_InitialState == initialState);
|
| - initialState = GrReducedClip::kAllIn_InitialState;
|
| + SkASSERT(InitialTriState::kAllOut == initialState);
|
| + initialState = InitialTriState::kAllIn;
|
| }
|
| }
|
| }
|
| }
|
| }
|
|
|
| - if ((GrReducedClip::kAllOut_InitialState == initialState && !embiggens) ||
|
| - (GrReducedClip::kAllIn_InitialState == initialState && !emsmallens)) {
|
| + if ((InitialTriState::kAllOut == initialState && !embiggens) ||
|
| + (InitialTriState::kAllIn == initialState && !emsmallens)) {
|
| result->reset();
|
| numAAElements = 0;
|
| } else {
|
| @@ -249,20 +251,20 @@ static GrReducedClip::InitialState reduced_stack_walker(const SkClipStack& stack
|
| switch (element->getOp()) {
|
| case SkRegion::kDifference_Op:
|
| // subtracting from the empty set yields the empty set.
|
| - skippable = GrReducedClip::kAllOut_InitialState == initialState;
|
| + skippable = InitialTriState::kAllOut == initialState;
|
| break;
|
| case SkRegion::kIntersect_Op:
|
| // intersecting with the empty set yields the empty set
|
| - if (GrReducedClip::kAllOut_InitialState == initialState) {
|
| + if (InitialTriState::kAllOut == initialState) {
|
| skippable = true;
|
| } else {
|
| // We can clear to zero and then simply draw the clip element.
|
| - initialState = GrReducedClip::kAllOut_InitialState;
|
| + initialState = InitialTriState::kAllOut;
|
| element->setOp(SkRegion::kReplace_Op);
|
| }
|
| break;
|
| case SkRegion::kUnion_Op:
|
| - if (GrReducedClip::kAllIn_InitialState == initialState) {
|
| + if (InitialTriState::kAllIn == initialState) {
|
| // unioning the infinite plane with anything is a no-op.
|
| skippable = true;
|
| } else {
|
| @@ -271,23 +273,23 @@ static GrReducedClip::InitialState reduced_stack_walker(const SkClipStack& stack
|
| }
|
| break;
|
| case SkRegion::kXOR_Op:
|
| - if (GrReducedClip::kAllOut_InitialState == initialState) {
|
| + if (InitialTriState::kAllOut == initialState) {
|
| // xor could be changed to diff in the kAllIn case, not sure it's a win.
|
| element->setOp(SkRegion::kReplace_Op);
|
| }
|
| break;
|
| case SkRegion::kReverseDifference_Op:
|
| - if (GrReducedClip::kAllIn_InitialState == initialState) {
|
| + if (InitialTriState::kAllIn == initialState) {
|
| // subtracting the whole plane will yield the empty set.
|
| skippable = true;
|
| - initialState = GrReducedClip::kAllOut_InitialState;
|
| + initialState = InitialTriState::kAllOut;
|
| } else {
|
| // this picks up flips inserted in the backwards pass.
|
| skippable = element->isInverseFilled() ?
|
| GrClip::IsOutsideClip(element->getBounds(), queryBounds) :
|
| element->contains(relaxedQueryBounds);
|
| if (skippable) {
|
| - initialState = GrReducedClip::kAllIn_InitialState;
|
| + initialState = InitialTriState::kAllIn;
|
| } else {
|
| element->setOp(SkRegion::kReplace_Op);
|
| }
|
| @@ -315,7 +317,7 @@ static GrReducedClip::InitialState reduced_stack_walker(const SkClipStack& stack
|
| *requiresAA = numAAElements > 0;
|
|
|
| if (0 == result->count()) {
|
| - if (initialState == GrReducedClip::kAllIn_InitialState) {
|
| + if (initialState == InitialTriState::kAllIn) {
|
| *resultGenID = SkClipStack::kWideOpenGenID;
|
| } else {
|
| *resultGenID = SkClipStack::kEmptyGenID;
|
| @@ -323,7 +325,8 @@ static GrReducedClip::InitialState reduced_stack_walker(const SkClipStack& stack
|
| }
|
|
|
| SkASSERT(SkClipStack::kInvalidGenID != *resultGenID);
|
| - return initialState;
|
| + SkASSERT(InitialTriState::kUnknown != initialState);
|
| + return static_cast<GrReducedClip::InitialState>(initialState);
|
| }
|
|
|
| /*
|
| @@ -333,25 +336,20 @@ for the case where the bounds are kInsideOut_BoundsType. We could restrict earli
|
| based on later intersect operations, and perhaps remove intersect-rects. We could optionally
|
| take a rect in case the caller knows a bound on what is to be drawn through this clip.
|
| */
|
| -GrReducedClip::InitialState GrReducedClip::ReduceClipStack(const SkClipStack& stack,
|
| - const SkRect& queryBounds,
|
| - ElementList* result,
|
| - int32_t* resultGenID,
|
| - SkIRect* clipIBounds,
|
| - bool* requiresAA) {
|
| +GrReducedClip::GrReducedClip(const SkClipStack& stack, const SkRect& queryBounds) {
|
| SkASSERT(!queryBounds.isEmpty());
|
| - result->reset();
|
|
|
| // The clip established by the element list might be cached based on the last
|
| // generation id. When we make early returns, we do not know what was the generation
|
| // id that lead to the state. Make a conservative guess.
|
| - *resultGenID = stack.getTopmostGenID();
|
| + fGenID = stack.getTopmostGenID();
|
|
|
| // TODO: instead devise a way of telling the caller to disregard some or all of the clip bounds.
|
| - *clipIBounds = GrClip::GetPixelIBounds(queryBounds);
|
| + fIBounds = GrClip::GetPixelIBounds(queryBounds);
|
|
|
| if (stack.isWideOpen()) {
|
| - return kAllIn_InitialState;
|
| + fInitialState = InitialState::kAllIn;
|
| + return;
|
| }
|
|
|
| SkClipStack::BoundsType stackBoundsType;
|
| @@ -361,7 +359,8 @@ GrReducedClip::InitialState GrReducedClip::ReduceClipStack(const SkClipStack& st
|
|
|
| if (stackBounds.isEmpty() || GrClip::IsOutsideClip(stackBounds, queryBounds)) {
|
| bool insideOut = SkClipStack::kInsideOut_BoundsType == stackBoundsType;
|
| - return insideOut ? kAllIn_InitialState : kAllOut_InitialState;
|
| + fInitialState = insideOut ? InitialState::kAllIn : InitialState::kAllOut;
|
| + return;
|
| }
|
|
|
| if (iior) {
|
| @@ -371,31 +370,39 @@ GrReducedClip::InitialState GrReducedClip::ReduceClipStack(const SkClipStack& st
|
| SkClipStack::Iter iter(stack, SkClipStack::Iter::kTop_IterStart);
|
| if (!iter.prev()->isAA() || GrClip::IsPixelAligned(stackBounds)) {
|
| // The clip is a non-aa rect. This is the one spot where we can actually implement the
|
| - // clip (using clipIBounds) rather than just telling the caller what it should be.
|
| - stackBounds.round(clipIBounds);
|
| - return kAllIn_InitialState;
|
| + // clip (using fIBounds) rather than just telling the caller what it should be.
|
| + stackBounds.round(&fIBounds);
|
| + fInitialState = fIBounds.isEmpty() ? InitialState::kAllOut : InitialState::kAllIn;
|
| + return;
|
| }
|
| if (GrClip::IsInsideClip(stackBounds, queryBounds)) {
|
| - return kAllIn_InitialState;
|
| + fInitialState = InitialState::kAllIn;
|
| + return;
|
| }
|
|
|
| + SkAssertResult(fIBounds.intersect(GrClip::GetPixelIBounds(stackBounds)));
|
| + SkASSERT(!fIBounds.isEmpty()); // Empty should have been blocked by IsOutsideClip above.
|
| +
|
| // Implement the clip with an AA rect element.
|
| - result->addToHead(stackBounds, SkRegion::kReplace_Op, true/*doAA*/);
|
| - *requiresAA = true;
|
| + fElements.addToHead(stackBounds, SkRegion::kReplace_Op, true/*doAA*/);
|
| + fRequiresAA = true;
|
|
|
| - SkAssertResult(clipIBounds->intersect(GrClip::GetPixelIBounds(stackBounds)));
|
| - return kAllOut_InitialState;
|
| + fInitialState = InitialState::kAllOut;
|
| + return;
|
| }
|
|
|
| SkRect tighterQuery = queryBounds;
|
| if (SkClipStack::kNormal_BoundsType == stackBoundsType) {
|
| // Tighten the query by introducing a new clip at the stack's pixel boundaries. (This new
|
| - // clip will be enforced by the scissor through clipIBounds.)
|
| + // clip will be enforced by the scissor through fIBounds.)
|
| SkAssertResult(tighterQuery.intersect(GrClip::GetPixelBounds(stackBounds)));
|
| - *clipIBounds = GrClip::GetPixelIBounds(tighterQuery);
|
| + fIBounds = GrClip::GetPixelIBounds(tighterQuery);
|
| }
|
|
|
| + SkASSERT(!fIBounds.isEmpty()); // Empty should have been blocked by IsOutsideClip above.
|
| +
|
| // Now that we have determined the bounds to use and filtered out the trivial cases, call the
|
| // helper that actually walks the stack.
|
| - return reduced_stack_walker(stack, tighterQuery, *clipIBounds, result, resultGenID, requiresAA);
|
| + fInitialState = reduced_stack_walker(stack, tighterQuery, fIBounds, &fElements, &fGenID,
|
| + &fRequiresAA);
|
| }
|
|
|