Improve handling of inverse clip paths in GrClipMaskManager.

Will require rebaselining of complexclip_aa and complexclip_aa_layer on GPU.

R=robertphillips@google.com
Review URL: https://codereview.appspot.com/6907052

git-svn-id: http://skia.googlecode.com/svn/trunk@6712 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/src/gpu/GrReducedClip.cpp b/src/gpu/GrReducedClip.cpp
index baa8533..5287858 100644
--- a/src/gpu/GrReducedClip.cpp
+++ b/src/gpu/GrReducedClip.cpp
@@ -21,9 +21,7 @@
                           bool* requiresAA);
 
 /*
-There are plenty of optimizations that could be added here. For example we could consider
-checking for cases where an inverse path can be changed to a regular fill with a different op.
-(e.g. [kIntersect, inverse path] -> [kDifference, path]). Maybe flips could be folded into
+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
@@ -322,10 +320,23 @@
                                            Element,
                                            (queryBounds, SkRegion::kReverseDifference_Op, false));
             } else {
-                result->addToHead(*element);
-                if (element->isAA()) {
+                Element* newElement = result->addToHead(*element);
+                if (newElement->isAA()) {
                     ++numAAElements;
                 }
+                // Intersecting an inverse shape is the same as differencing the non-inverse shape.
+                // Replacing with a inverse shape the same as setting initialState=kAllIn and
+                // differencing the non-inverse shape.
+                bool isReplace = SkRegion::kReplace_Op == newElement->getOp();
+                if (newElement->isInverseFilled() &&
+                    (SkRegion::kIntersect_Op == newElement->getOp() || isReplace)) {
+                    newElement->invertShapeFillType();
+                    newElement->setOp(SkRegion::kDifference_Op);
+                    if (isReplace) {
+                        SkASSERT(kAllOut_InitialState == *initialState);
+                        *initialState = kAllIn_InitialState;
+                    }
+                }
             }
         }
     }