Implement clipRect with a transform, clipRegion & clipPath
Bug #7146141

When non-rectangular clipping occurs in a layer the render buffer
used as the stencil buffer is not cached. If this happens on a
View's hardware layer the render buffer will live for as long
as the layer is bound to the view. When a stencil buffer is
required because of a call to Canvas.saveLayer() it will be allocated
on every frame. A future change will address this problem.

If "show GPU overdraw" is enabled, non-rectangular clips are not
supported anymore and we fall back to rectangular clips instead.
This is a limitation imposed by OpenGL ES that cannot be worked
around at this time.

This change also improves the Matrix4 implementation to easily
detect when a rect remains a rect after transform.

Change-Id: I0e69fb901792d38bc0c4ca1bf9fdb02d7db415b9
diff --git a/libs/hwui/OpenGLRenderer.h b/libs/hwui/OpenGLRenderer.h
index f07325f..d4e1eb5 100644
--- a/libs/hwui/OpenGLRenderer.h
+++ b/libs/hwui/OpenGLRenderer.h
@@ -287,6 +287,19 @@
     void resumeAfterLayer();
 
     /**
+     * This method is called whenever a stencil buffer is required. Subclasses
+     * should override this method and call attachStencilBufferToLayer() on the
+     * appropriate layer(s).
+     */
+    virtual void ensureStencilBuffer();
+
+    /**
+     * Obtains a stencil render buffer (allocating it if necessary) and
+     * attaches it to the specified layer.
+     */
+    void attachStencilBufferToLayer(Layer* layer);
+
+    /**
      * Compose the layer defined in the current snapshot with the layer
      * defined by the previous snapshot.
      *
@@ -423,6 +436,12 @@
     void setScissorFromClip();
 
     /**
+     * Sets the clipping region using the stencil buffer. The clip region
+     * is defined by the current snapshot's clipRegion member.
+     */
+    void setStencilFromClip();
+
+    /**
      * Performs a quick reject but does not affect the scissor. Returns
      * the transformed rect to test and the current clip.
      */
@@ -524,9 +543,10 @@
      * @param color The rectangles' ARGB color, defined as a packed 32 bits word
      * @param mode The Skia xfermode to use
      * @param ignoreTransform True if the current transform should be ignored
+     * @param dirty True if calling this method should dirty the current layer
      */
     status_t drawColorRects(const float* rects, int count, int color,
-            SkXfermode::Mode mode, bool ignoreTransform = false);
+            SkXfermode::Mode mode, bool ignoreTransform = false, bool dirty = true);
 
     /**
      * Draws the shape represented by the specified path texture.
@@ -774,6 +794,19 @@
      */
     void drawRegionRects(const Region& region);
 
+    /**
+     * Renders the specified region as a series of rectangles. The region
+     * must be in screen-space coordinates.
+     */
+    void drawRegionRects(const SkRegion& region, int color, SkXfermode::Mode mode,
+            bool dirty = false);
+
+    /**
+     * Draws the current clip region if any. Only when DEBUG_CLIP_REGIONS
+     * is turned on.
+     */
+    void debugClip();
+
     void debugOverdraw(bool enable, bool clear);
     void renderOverdraw();