Clipping performance improvements

Create a ClipArea class to handle tracking clip regions. This class can
select the most efficient implementation depending on the types of
clipping presented.

ClipArea re-used the rectangle and region-based clipping
implementations as well as adding a "list of rotated rectangles"
approach that is more efficient for rotated views with children.

Change-Id: I2133761a2462ebc0852b394220e265974b3086f0
diff --git a/libs/hwui/Snapshot.h b/libs/hwui/Snapshot.h
index 549de9b..4d704ab 100644
--- a/libs/hwui/Snapshot.h
+++ b/libs/hwui/Snapshot.h
@@ -26,6 +26,7 @@
 
 #include <SkRegion.h>
 
+#include "ClipArea.h"
 #include "Layer.h"
 #include "Matrix.h"
 #include "Outline.h"
@@ -129,6 +130,11 @@
     bool clipRegionTransformed(const SkRegion& region, SkRegion::Op op);
 
     /**
+     * Modifies the current clip with the specified path and operation.
+     */
+    bool clipPath(const SkPath& path, SkRegion::Op op);
+
+    /**
      * Sets the current clip.
      */
     void setClip(float left, float top, float right, float bottom);
@@ -142,7 +148,16 @@
     /**
      * Returns the current clip in render target coordinates.
      */
-    const Rect& getRenderTargetClip() { return *clipRect; }
+    const Rect& getRenderTargetClip() { return mClipArea->getClipRect(); }
+
+    /*
+     * Accessor functions so that the clip area can stay private
+     */
+    bool clipIsEmpty() const { return mClipArea->isEmpty(); }
+    const Rect& getClipRect() const { return mClipArea->getClipRect(); }
+    const SkRegion& getClipRegion() const { return mClipArea->getClipRegion(); }
+    bool clipIsSimple() const { return mClipArea->isSimple(); }
+    const ClipArea& getClipArea() const { return *mClipArea; }
 
     /**
      * Resets the clip to the specified rect.
@@ -156,6 +171,7 @@
 
     void initializeViewport(int width, int height) {
         mViewportData.initialize(width, height);
+        mClipAreaRoot.setViewportDimensions(width, height);
     }
 
     int getViewportWidth() const { return mViewportData.mWidth; }
@@ -175,7 +191,7 @@
 
     /**
      * Indicates whether this snapshot should be ignored. A snapshot
-     * is typicalled ignored if its layer is invisible or empty.
+     * is typically ignored if its layer is invisible or empty.
      */
     bool isIgnored() const;
 
@@ -230,24 +246,6 @@
     mat4* transform;
 
     /**
-     * Current clip rect. The clip is stored in canvas-space coordinates,
-     * (screen-space coordinates in the regular case.)
-     *
-     * This is a reference to a rect owned by this snapshot or another
-     * snapshot. This pointer must not be freed. See ::mClipRectRoot.
-     */
-    Rect* clipRect;
-
-    /**
-     * Current clip region. The clip is stored in canvas-space coordinates,
-     * (screen-space coordinates in the regular case.)
-     *
-     * This is a reference to a region owned by this snapshot or another
-     * snapshot. This pointer must not be freed. See ::mClipRegionRoot.
-     */
-    SkRegion* clipRegion;
-
-    /**
      * The ancestor layer's dirty region.
      *
      * This is a reference to a region owned by a layer. This pointer must
@@ -260,7 +258,7 @@
      * has translucent rendering in a non-overlapping View. This value will be used by
      * the renderer to set the alpha in the current color being used for ensuing drawing
      * operations. The value is inherited by child snapshots because the same value should
-     * be applied to descendents of the current DisplayList (for example, a TextView contains
+     * be applied to descendants of the current DisplayList (for example, a TextView contains
      * the base alpha value which should be applied to the child DisplayLists used for drawing
      * the actual text).
      */
@@ -298,16 +296,12 @@
         mat4 mOrthoMatrix;
     };
 
-    void ensureClipRegion();
-    void copyClipRectFromRegion();
-
-    bool clipRegionOp(float left, float top, float right, float bottom, SkRegion::Op op);
-
     mat4 mTransformRoot;
-    Rect mClipRectRoot;
-    Rect mLocalClip; // don't use directly, call getLocalClip() which initializes this
 
-    SkRegion mClipRegionRoot;
+    ClipArea mClipAreaRoot;
+    ClipArea* mClipArea;
+    Rect mLocalClip;
+
     ViewportData mViewportData;
     Vector3 mRelativeLightCenter;