Index: src/gpu/GrReducedClip.cpp |
diff --git a/src/gpu/GrReducedClip.cpp b/src/gpu/GrReducedClip.cpp |
index a5f4519ea7d7eaca4961bdee5d78cefcf7d68423..8480e041b8dd24971ebc384f981a8a8165e02f64 100644 |
--- a/src/gpu/GrReducedClip.cpp |
+++ b/src/gpu/GrReducedClip.cpp |
@@ -17,6 +17,7 @@ namespace GrReducedClip { |
void reduced_stack_walker(const SkClipStack& stack, |
const SkRect& queryBounds, |
ElementList* result, |
+ int32_t* resultGenID, |
InitialState* initialState, |
bool* requiresAA); |
@@ -30,11 +31,17 @@ take a rect in case the caller knows a bound on what is to be drawn through this |
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; |
@@ -70,7 +77,9 @@ void ReduceClipStack(const SkClipStack& stack, |
SkRect scalarTighterBounds = SkRect::Make(*tighterBounds); |
if (scalarTighterBounds == isectRect) { |
// the round-out didn't add any area outside the clip rect. |
- *requiresAA = false; |
+ if (NULL != requiresAA) { |
+ *requiresAA = false; |
+ } |
*initialState = kAllIn_InitialState; |
return; |
} |
@@ -123,12 +132,17 @@ void ReduceClipStack(const SkClipStack& stack, |
// 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, initialState, requiresAA); |
+ 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) { |
@@ -312,6 +326,11 @@ void reduced_stack_walker(const SkClipStack& stack, |
break; |
} |
if (!skippable) { |
+ if (0 == result->count()) { |
+ // This will be the last element. Record the stricter genID. |
+ *resultGenID = element->getGenID(); |
+ } |
+ |
// if it is a flip, change it to a bounds-filling rect |
if (isFlip) { |
SkASSERT(SkRegion::kXOR_Op == element->getOp() || |
@@ -417,5 +436,13 @@ void reduced_stack_walker(const SkClipStack& stack, |
if (NULL != requiresAA) { |
*requiresAA = numAAElements > 0; |
} |
+ |
+ if (0 == result->count()) { |
+ if (*initialState == kAllIn_InitialState) { |
+ *resultGenID = SkClipStack::kWideOpenGenID; |
+ } else { |
+ *resultGenID = SkClipStack::kEmptyGenID; |
+ } |
+ } |
} |
} // namespace GrReducedClip |