diff options
author | 2014-10-23 17:47:18 -0700 | |
---|---|---|
committer | 2014-10-23 17:47:18 -0700 | |
commit | bf54e49e30cdc92f9ce3f336cc48cf6b236ddeab (patch) | |
tree | 3b62abba64515973a5f2cd6429250d97f3805cb9 /src/gpu | |
parent | 11ed6b8140ad067bf64087b5b0deca8fe903d20c (diff) |
Cleanup: Turn GrReducedClip into a class with a static function.
Clean up namespace usage.
Similar to what was done in
https://skia.googlesource.com/skia/+/a5414c4a8efc3119ee20fcee96c0bf68a04909c7
BUG=None
TEST=None
R=bsalomon@google.com
Review URL: https://codereview.chromium.org/653393003
Diffstat (limited to 'src/gpu')
-rw-r--r-- | src/gpu/GrClipMaskManager.cpp | 51 | ||||
-rw-r--r-- | src/gpu/GrReducedClip.cpp | 326 | ||||
-rw-r--r-- | src/gpu/GrReducedClip.h | 65 |
3 files changed, 215 insertions, 227 deletions
diff --git a/src/gpu/GrClipMaskManager.cpp b/src/gpu/GrClipMaskManager.cpp index 1d055655e5..414bbabed6 100644 --- a/src/gpu/GrClipMaskManager.cpp +++ b/src/gpu/GrClipMaskManager.cpp @@ -28,8 +28,6 @@ typedef SkClipStack::Element Element; -using namespace GrReducedClip; - //////////////////////////////////////////////////////////////////////////////// namespace { // set up the draw state to enable the aa clipping mask. Besides setting up the @@ -85,14 +83,14 @@ bool path_needs_SW_renderer(GrContext* context, * will be used on any element. If so, it returns true to indicate that the * entire clip should be rendered in SW and then uploaded en masse to the gpu. */ -bool GrClipMaskManager::useSWOnlyPath(const ElementList& elements) { +bool GrClipMaskManager::useSWOnlyPath(const GrReducedClip::ElementList& elements) { // TODO: generalize this function so that when // a clip gets complex enough it can just be done in SW regardless // of whether it would invoke the GrSoftwarePathRenderer. SkStrokeRec stroke(SkStrokeRec::kFill_InitStyle); - for (ElementList::Iter iter(elements.headIter()); iter.get(); iter.next()) { + for (GrReducedClip::ElementList::Iter iter(elements.headIter()); iter.get(); iter.next()) { const Element* element = iter.get(); // rects can always be drawn directly w/o using the software path // Skip rrects once we're drawing them directly. @@ -107,7 +105,7 @@ bool GrClipMaskManager::useSWOnlyPath(const ElementList& elements) { return false; } -bool GrClipMaskManager::installClipEffects(const ElementList& elements, +bool GrClipMaskManager::installClipEffects(const GrReducedClip::ElementList& elements, GrDrawState::AutoRestoreEffects* are, const SkVector& clipToRTOffset, const SkRect* drawBounds) { @@ -121,7 +119,7 @@ bool GrClipMaskManager::installClipEffects(const ElementList& elements, are->set(drawState); GrRenderTarget* rt = drawState->getRenderTarget(); - ElementList::Iter iter(elements); + GrReducedClip::ElementList::Iter iter(elements); bool setARE = false; bool failed = false; @@ -217,9 +215,9 @@ bool GrClipMaskManager::setupClipping(const GrClipData* clipDataIn, const SkRect* devBounds) { fCurrClipMaskType = kNone_ClipMaskType; - ElementList elements(16); + GrReducedClip::ElementList elements(16); int32_t genID; - InitialState initialState; + GrReducedClip::InitialState initialState; SkIRect clipSpaceIBounds; bool requiresAA; @@ -234,15 +232,15 @@ bool GrClipMaskManager::setupClipping(const GrClipData* clipDataIn, if (!ignoreClip) { SkIRect clipSpaceRTIBounds = SkIRect::MakeWH(rt->width(), rt->height()); clipSpaceRTIBounds.offset(clipDataIn->fOrigin); - ReduceClipStack(*clipDataIn->fClipStack, - clipSpaceRTIBounds, - &elements, - &genID, - &initialState, - &clipSpaceIBounds, - &requiresAA); + GrReducedClip::ReduceClipStack(*clipDataIn->fClipStack, + clipSpaceRTIBounds, + &elements, + &genID, + &initialState, + &clipSpaceIBounds, + &requiresAA); if (elements.isEmpty()) { - if (kAllIn_InitialState == initialState) { + if (GrReducedClip::kAllIn_InitialState == initialState) { ignoreClip = clipSpaceIBounds == clipSpaceRTIBounds; } else { return false; @@ -534,8 +532,8 @@ GrTexture* GrClipMaskManager::allocMaskTexture(int32_t elementsGenID, //////////////////////////////////////////////////////////////////////////////// // Create a 8-bit clip mask in alpha GrTexture* GrClipMaskManager::createAlphaClipMask(int32_t elementsGenID, - InitialState initialState, - const ElementList& elements, + GrReducedClip::InitialState initialState, + const GrReducedClip::ElementList& elements, const SkIRect& clipSpaceIBounds) { SkASSERT(kNone_ClipMaskType == fCurrClipMaskType); @@ -575,7 +573,7 @@ GrTexture* GrClipMaskManager::createAlphaClipMask(int32_t elementsGenID, // The scratch texture that we are drawing into can be substantially larger than the mask. Only // clear the part that we care about. fGpu->clear(&maskSpaceIBounds, - kAllIn_InitialState == initialState ? 0xffffffff : 0x00000000, + GrReducedClip::kAllIn_InitialState == initialState ? 0xffffffff : 0x00000000, true, result->asRenderTarget()); @@ -588,7 +586,7 @@ GrTexture* GrClipMaskManager::createAlphaClipMask(int32_t elementsGenID, SkAutoTUnref<GrTexture> temp; // walk through each clip element and perform its set op - for (ElementList::Iter iter = elements.headIter(); iter.get(); iter.next()) { + for (GrReducedClip::ElementList::Iter iter = elements.headIter(); iter.get(); iter.next()) { const Element* element = iter.get(); SkRegion::Op op = element->getOp(); bool invert = element->isInverseFilled(); @@ -688,8 +686,8 @@ GrTexture* GrClipMaskManager::createAlphaClipMask(int32_t elementsGenID, // Create a 1-bit clip mask in the stencil buffer. 'devClipBounds' are in device // (as opposed to canvas) coordinates bool GrClipMaskManager::createStencilClipMask(int32_t elementsGenID, - InitialState initialState, - const ElementList& elements, + GrReducedClip::InitialState initialState, + const GrReducedClip::ElementList& elements, const SkIRect& clipSpaceIBounds, const SkIPoint& clipSpaceToStencilOffset) { @@ -737,11 +735,12 @@ bool GrClipMaskManager::createStencilClipMask(int32_t elementsGenID, SkASSERT((clipBit <= 16) && "Ganesh only handles 16b or smaller stencil buffers"); clipBit = (1 << (clipBit-1)); - fGpu->clearStencilClip(rt, stencilSpaceIBounds, kAllIn_InitialState == initialState); + fGpu->clearStencilClip(rt, stencilSpaceIBounds, + GrReducedClip::kAllIn_InitialState == initialState); // walk through each clip element and perform its set op // with the existing clip. - for (ElementList::Iter iter(elements.headIter()); iter.get(); iter.next()) { + for (GrReducedClip::ElementList::Iter iter(elements.headIter()); iter.get(); iter.next()) { const Element* element = iter.get(); bool fillInverted = false; // enabled at bottom of loop @@ -1058,11 +1057,11 @@ GrTexture* GrClipMaskManager::createSoftwareClipMask(int32_t elementsGenID, SkIntToScalar(-clipSpaceIBounds.fTop)); helper.init(maskSpaceIBounds, &matrix, false); - helper.clear(kAllIn_InitialState == initialState ? 0xFF : 0x00); + helper.clear(GrReducedClip::kAllIn_InitialState == initialState ? 0xFF : 0x00); SkStrokeRec stroke(SkStrokeRec::kFill_InitStyle); - for (ElementList::Iter iter(elements.headIter()) ; iter.get(); iter.next()) { + for (GrReducedClip::ElementList::Iter iter(elements.headIter()) ; iter.get(); iter.next()) { const Element* element = iter.get(); SkRegion::Op op = element->getOp(); diff --git a/src/gpu/GrReducedClip.cpp b/src/gpu/GrReducedClip.cpp index 2083af907e..3040b46313 100644 --- a/src/gpu/GrReducedClip.cpp +++ b/src/gpu/GrReducedClip.cpp @@ -1,4 +1,3 @@ - /* * Copyright 2012 Google Inc. * @@ -9,151 +8,21 @@ #include "GrReducedClip.h" typedef SkClipStack::Element Element; -//////////////////////////////////////////////////////////////////////////////// - -namespace GrReducedClip { - -// helper function -void reduced_stack_walker(const SkClipStack& stack, - const SkRect& queryBounds, - ElementList* result, - int32_t* resultGenID, - InitialState* initialState, - bool* requiresAA); - -/* -There are plenty of optimizations that could be added here. Maybe flips could be folded into -earlier operations. Or would inserting flips and reversing earlier ops ever be a win? Perhaps -for the case where the bounds are kInsideOut_BoundsType. We could restrict earlier operations -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. -*/ -void ReduceClipStack(const SkClipStack& stack, - const SkIRect& queryBounds, - ElementList* result, - int32_t* resultGenID, - InitialState* initialState, - SkIRect* tighterBounds, - bool* requiresAA) { - 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(); - - if (stack.isWideOpen()) { - *initialState = kAllIn_InitialState; - return; - } - - - // We initially look at whether the bounds alone is sufficient. We also use the stack bounds to - // attempt to compute the tighterBounds. - - SkClipStack::BoundsType stackBoundsType; - SkRect stackBounds; - bool iior; - stack.getBounds(&stackBounds, &stackBoundsType, &iior); - - const SkIRect* bounds = &queryBounds; - - SkRect scalarQueryBounds = SkRect::Make(queryBounds); - - if (iior) { - SkASSERT(SkClipStack::kNormal_BoundsType == stackBoundsType); - SkRect isectRect; - if (stackBounds.contains(scalarQueryBounds)) { - *initialState = kAllIn_InitialState; - if (tighterBounds) { - *tighterBounds = queryBounds; - } - if (requiresAA) { - *requiresAA = false; - } - } else if (isectRect.intersect(stackBounds, scalarQueryBounds)) { - // If the caller asked for tighter integer bounds we may be able to - // return kAllIn and give the bounds with no elements - if (tighterBounds) { - isectRect.roundOut(tighterBounds); - SkRect scalarTighterBounds = SkRect::Make(*tighterBounds); - if (scalarTighterBounds == isectRect) { - // the round-out didn't add any area outside the clip rect. - if (requiresAA) { - *requiresAA = false; - } - *initialState = kAllIn_InitialState; - return; - } - } - *initialState = kAllOut_InitialState; - // 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)); - if (requiresAA) { - *requiresAA = doAA; - } - } else { - *initialState = kAllOut_InitialState; - if (requiresAA) { - *requiresAA = false; - } - } - return; - } else { - if (SkClipStack::kNormal_BoundsType == stackBoundsType) { - if (!SkRect::Intersects(stackBounds, scalarQueryBounds)) { - *initialState = kAllOut_InitialState; - if (requiresAA) { - *requiresAA = false; - } - return; - } - if (tighterBounds) { - SkIRect stackIBounds; - stackBounds.roundOut(&stackIBounds); - tighterBounds->intersect(queryBounds, stackIBounds); - bounds = tighterBounds; - } - } else { - if (stackBounds.contains(scalarQueryBounds)) { - *initialState = kAllOut_InitialState; - if (requiresAA) { - *requiresAA = false; - } - return; - } - if (tighterBounds) { - *tighterBounds = queryBounds; - } - } - } - - SkRect scalarBounds = SkRect::Make(*bounds); - - // Now that we have determined the bounds to use and filtered out the trivial cases, call the - // helper that actually walks the stack. - reduced_stack_walker(stack, scalarBounds, result, resultGenID, initialState, requiresAA); - - // The list that was computed in this function may be cached based on the gen id of the last - // element. - SkASSERT(SkClipStack::kInvalidGenID != *resultGenID); -} -void reduced_stack_walker(const SkClipStack& stack, - const SkRect& queryBounds, - ElementList* result, - int32_t* resultGenID, - InitialState* initialState, - bool* requiresAA) { +static void reduced_stack_walker(const SkClipStack& stack, + const SkRect& queryBounds, + GrReducedClip::ElementList* result, + int32_t* resultGenID, + GrReducedClip::InitialState* initialState, + bool* requiresAA) { // walk backwards until we get to: // a) the beginning // b) an operation that is known to make the bounds all inside/outside // c) a replace operation - static const InitialState kUnknown_InitialState = static_cast<InitialState>(-1); + static const GrReducedClip::InitialState kUnknown_InitialState = + static_cast<GrReducedClip::InitialState>(-1); *initialState = kUnknown_InitialState; // During our backwards walk, track whether we've seen ops that either grow or shrink the clip. @@ -166,15 +35,15 @@ void reduced_stack_walker(const SkClipStack& stack, while ((kUnknown_InitialState == *initialState)) { const Element* element = iter.prev(); if (NULL == element) { - *initialState = kAllIn_InitialState; + *initialState = GrReducedClip::kAllIn_InitialState; break; } if (SkClipStack::kEmptyGenID == element->getGenID()) { - *initialState = kAllOut_InitialState; + *initialState = GrReducedClip::kAllOut_InitialState; break; } if (SkClipStack::kWideOpenGenID == element->getGenID()) { - *initialState = kAllIn_InitialState; + *initialState = GrReducedClip::kAllIn_InitialState; break; } @@ -189,12 +58,12 @@ void reduced_stack_walker(const SkClipStack& stack, if (element->contains(queryBounds)) { skippable = true; } else if (!SkRect::Intersects(element->getBounds(), queryBounds)) { - *initialState = kAllOut_InitialState; + *initialState = GrReducedClip::kAllOut_InitialState; skippable = true; } } else { if (element->contains(queryBounds)) { - *initialState = kAllOut_InitialState; + *initialState = GrReducedClip::kAllOut_InitialState; skippable = true; } else if (!SkRect::Intersects(element->getBounds(), queryBounds)) { skippable = true; @@ -210,7 +79,7 @@ void reduced_stack_walker(const SkClipStack& stack, // empty. if (element->isInverseFilled()) { if (element->contains(queryBounds)) { - *initialState = kAllOut_InitialState; + *initialState = GrReducedClip::kAllOut_InitialState; skippable = true; } else if (!SkRect::Intersects(element->getBounds(), queryBounds)) { skippable = true; @@ -219,7 +88,7 @@ void reduced_stack_walker(const SkClipStack& stack, if (element->contains(queryBounds)) { skippable = true; } else if (!SkRect::Intersects(element->getBounds(), queryBounds)) { - *initialState = kAllOut_InitialState; + *initialState = GrReducedClip::kAllOut_InitialState; skippable = true; } } @@ -235,12 +104,12 @@ void reduced_stack_walker(const SkClipStack& stack, if (element->contains(queryBounds)) { skippable = true; } else if (!SkRect::Intersects(element->getBounds(), queryBounds)) { - *initialState = kAllIn_InitialState; + *initialState = GrReducedClip::kAllIn_InitialState; skippable = true; } } else { if (element->contains(queryBounds)) { - *initialState = kAllIn_InitialState; + *initialState = GrReducedClip::kAllIn_InitialState; skippable = true; } else if (!SkRect::Intersects(element->getBounds(), queryBounds)) { skippable = true; @@ -279,7 +148,7 @@ void reduced_stack_walker(const SkClipStack& stack, // all outside the current clip.B if (element->isInverseFilled()) { if (element->contains(queryBounds)) { - *initialState = kAllOut_InitialState; + *initialState = GrReducedClip::kAllOut_InitialState; skippable = true; } else if (!SkRect::Intersects(element->getBounds(), queryBounds)) { isFlip = true; @@ -288,7 +157,7 @@ void reduced_stack_walker(const SkClipStack& stack, if (element->contains(queryBounds)) { isFlip = true; } else if (!SkRect::Intersects(element->getBounds(), queryBounds)) { - *initialState = kAllOut_InitialState; + *initialState = GrReducedClip::kAllOut_InitialState; skippable = true; } } @@ -303,23 +172,23 @@ void reduced_stack_walker(const SkClipStack& stack, // setting the correct value for initialState. if (element->isInverseFilled()) { if (element->contains(queryBounds)) { - *initialState = kAllOut_InitialState; + *initialState = GrReducedClip::kAllOut_InitialState; skippable = true; } else if (!SkRect::Intersects(element->getBounds(), queryBounds)) { - *initialState = kAllIn_InitialState; + *initialState = GrReducedClip::kAllIn_InitialState; skippable = true; } } else { if (element->contains(queryBounds)) { - *initialState = kAllIn_InitialState; + *initialState = GrReducedClip::kAllIn_InitialState; skippable = true; } else if (!SkRect::Intersects(element->getBounds(), queryBounds)) { - *initialState = kAllOut_InitialState; + *initialState = GrReducedClip::kAllOut_InitialState; skippable = true; } } if (!skippable) { - *initialState = kAllOut_InitialState; + *initialState = GrReducedClip::kAllOut_InitialState; embiggens = emsmallens = true; } break; @@ -354,16 +223,16 @@ void reduced_stack_walker(const SkClipStack& stack, newElement->invertShapeFillType(); newElement->setOp(SkRegion::kDifference_Op); if (isReplace) { - SkASSERT(kAllOut_InitialState == *initialState); - *initialState = kAllIn_InitialState; + SkASSERT(GrReducedClip::kAllOut_InitialState == *initialState); + *initialState = GrReducedClip::kAllIn_InitialState; } } } } } - if ((kAllOut_InitialState == *initialState && !embiggens) || - (kAllIn_InitialState == *initialState && !emsmallens)) { + if ((GrReducedClip::kAllOut_InitialState == *initialState && !embiggens) || + (GrReducedClip::kAllIn_InitialState == *initialState && !emsmallens)) { result->reset(); } else { Element* element = result->headIter().get(); @@ -372,20 +241,20 @@ void reduced_stack_walker(const SkClipStack& stack, switch (element->getOp()) { case SkRegion::kDifference_Op: // subtracting from the empty set yields the empty set. - skippable = kAllOut_InitialState == *initialState; + skippable = GrReducedClip::kAllOut_InitialState == *initialState; break; case SkRegion::kIntersect_Op: // intersecting with the empty set yields the empty set - if (kAllOut_InitialState == *initialState) { + if (GrReducedClip::kAllOut_InitialState == *initialState) { skippable = true; } else { // We can clear to zero and then simply draw the clip element. - *initialState = kAllOut_InitialState; + *initialState = GrReducedClip::kAllOut_InitialState; element->setOp(SkRegion::kReplace_Op); } break; case SkRegion::kUnion_Op: - if (kAllIn_InitialState == *initialState) { + if (GrReducedClip::kAllIn_InitialState == *initialState) { // unioning the infinite plane with anything is a no-op. skippable = true; } else { @@ -394,23 +263,23 @@ void reduced_stack_walker(const SkClipStack& stack, } break; case SkRegion::kXOR_Op: - if (kAllOut_InitialState == *initialState) { + if (GrReducedClip::kAllOut_InitialState == *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 (kAllIn_InitialState == *initialState) { + if (GrReducedClip::kAllIn_InitialState == *initialState) { // subtracting the whole plane will yield the empty set. skippable = true; - *initialState = kAllOut_InitialState; + *initialState = GrReducedClip::kAllOut_InitialState; } else { // this picks up flips inserted in the backwards pass. skippable = element->isInverseFilled() ? !SkRect::Intersects(element->getBounds(), queryBounds) : element->contains(queryBounds); if (skippable) { - *initialState = kAllIn_InitialState; + *initialState = GrReducedClip::kAllIn_InitialState; } else { element->setOp(SkRegion::kReplace_Op); } @@ -440,11 +309,130 @@ void reduced_stack_walker(const SkClipStack& stack, } if (0 == result->count()) { - if (*initialState == kAllIn_InitialState) { + if (*initialState == GrReducedClip::kAllIn_InitialState) { *resultGenID = SkClipStack::kWideOpenGenID; } else { *resultGenID = SkClipStack::kEmptyGenID; } } } -} // namespace GrReducedClip + +/* +There are plenty of optimizations that could be added here. Maybe flips could be folded into +earlier operations. Or would inserting flips and reversing earlier ops ever be a win? Perhaps +for the case where the bounds are kInsideOut_BoundsType. We could restrict earlier operations +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. +*/ +void GrReducedClip::ReduceClipStack(const SkClipStack& stack, + const SkIRect& queryBounds, + ElementList* result, + int32_t* resultGenID, + InitialState* initialState, + SkIRect* tighterBounds, + bool* requiresAA) { + 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(); + + if (stack.isWideOpen()) { + *initialState = kAllIn_InitialState; + return; + } + + + // We initially look at whether the bounds alone is sufficient. We also use the stack bounds to + // attempt to compute the tighterBounds. + + SkClipStack::BoundsType stackBoundsType; + SkRect stackBounds; + bool iior; + stack.getBounds(&stackBounds, &stackBoundsType, &iior); + + const SkIRect* bounds = &queryBounds; + + SkRect scalarQueryBounds = SkRect::Make(queryBounds); + + if (iior) { + SkASSERT(SkClipStack::kNormal_BoundsType == stackBoundsType); + SkRect isectRect; + if (stackBounds.contains(scalarQueryBounds)) { + *initialState = GrReducedClip::kAllIn_InitialState; + if (tighterBounds) { + *tighterBounds = queryBounds; + } + if (requiresAA) { + *requiresAA = false; + } + } else if (isectRect.intersect(stackBounds, scalarQueryBounds)) { + // If the caller asked for tighter integer bounds we may be able to + // return kAllIn and give the bounds with no elements + if (tighterBounds) { + isectRect.roundOut(tighterBounds); + SkRect scalarTighterBounds = SkRect::Make(*tighterBounds); + if (scalarTighterBounds == isectRect) { + // the round-out didn't add any area outside the clip rect. + if (requiresAA) { + *requiresAA = false; + } + *initialState = GrReducedClip::kAllIn_InitialState; + return; + } + } + *initialState = kAllOut_InitialState; + // 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)); + if (requiresAA) { + *requiresAA = doAA; + } + } else { + *initialState = kAllOut_InitialState; + if (requiresAA) { + *requiresAA = false; + } + } + return; + } else { + if (SkClipStack::kNormal_BoundsType == stackBoundsType) { + if (!SkRect::Intersects(stackBounds, scalarQueryBounds)) { + *initialState = kAllOut_InitialState; + if (requiresAA) { + *requiresAA = false; + } + return; + } + if (tighterBounds) { + SkIRect stackIBounds; + stackBounds.roundOut(&stackIBounds); + tighterBounds->intersect(queryBounds, stackIBounds); + bounds = tighterBounds; + } + } else { + if (stackBounds.contains(scalarQueryBounds)) { + *initialState = kAllOut_InitialState; + if (requiresAA) { + *requiresAA = false; + } + return; + } + if (tighterBounds) { + *tighterBounds = queryBounds; + } + } + } + + SkRect scalarBounds = SkRect::Make(*bounds); + + // Now that we have determined the bounds to use and filtered out the trivial cases, call the + // helper that actually walks the stack. + reduced_stack_walker(stack, scalarBounds, result, resultGenID, initialState, requiresAA); + + // The list that was computed in this function may be cached based on the gen id of the last + // element. + SkASSERT(SkClipStack::kInvalidGenID != *resultGenID); +} diff --git a/src/gpu/GrReducedClip.h b/src/gpu/GrReducedClip.h index e3a28cc0c5..21899c73aa 100644 --- a/src/gpu/GrReducedClip.h +++ b/src/gpu/GrReducedClip.h @@ -1,4 +1,3 @@ - /* * Copyright 2012 Google Inc. * @@ -12,37 +11,39 @@ #include "SkClipStack.h" #include "SkTLList.h" -namespace GrReducedClip { - -typedef SkTLList<SkClipStack::Element> ElementList; - -enum InitialState { - kAllIn_InitialState, - kAllOut_InitialState, +class SK_API GrReducedClip { +public: + typedef SkTLList<SkClipStack::Element> ElementList; + + enum InitialState { + kAllIn_InitialState, + kAllOut_InitialState, + }; + + /** + * 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 clip stack generation id that represents + * the list of elements is returned in resultGenID. The initial state of the + * query rectangle before the first clip element is applied is returned via + * initialState. Optionally, the caller can request a tighter bounds on the + * clip be returned via tighterBounds. If not NULL, tighterBounds will + * always be contained by queryBounds after return. If tighterBounds is + * specified then it is assumed that the caller will implicitly clip against + * it. If the caller specifies non-NULL for requiresAA then it will indicate + * whether anti-aliasing is required to process any of the elements in the + * result. + * + * This may become a member function of SkClipStack when its interface is + * determined to be stable. + */ + static void ReduceClipStack(const SkClipStack& stack, + const SkIRect& queryBounds, + ElementList* result, + int32_t* resultGenID, + InitialState* initialState, + SkIRect* tighterBounds = NULL, + bool* requiresAA = NULL); }; -/** - * 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 clip - * stack generation id that represents the list of elements is returned in resultGenID. The - * initial state of the query rectangle before the first clip element is applied is returned via - * initialState. Optionally, the caller can request a tighter bounds on the clip be returned via - * tighterBounds. If not NULL, tighterBounds will always be contained by queryBounds after return. - * If tighterBounds is specified then it is assumed that the caller will implicitly clip against it. - * If the caller specifies non-NULL for requiresAA then it will indicate whether anti-aliasing is - * required to process any of the elements in the result. - * - * This may become a member function of SkClipStack when its interface is determined to be stable. - * Marked SK_API so that SkLua can call this in a shared library build. - */ -SK_API void ReduceClipStack(const SkClipStack& stack, - const SkIRect& queryBounds, - ElementList* result, - int32_t* resultGenID, - InitialState* initialState, - SkIRect* tighterBounds = NULL, - bool* requiresAA = NULL); - -} // namespace GrReducedClip - #endif |