Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / third_party / skia / src / gpu / GrReducedClip.cpp
index 2083af9..3040b46 100644 (file)
@@ -1,4 +1,3 @@
-
 /*
  * Copyright 2012 Google Inc.
  *
 #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);
+}