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/Matrix.h b/libs/hwui/Matrix.h
index f86823d..46a5597 100644
--- a/libs/hwui/Matrix.h
+++ b/libs/hwui/Matrix.h
@@ -48,6 +48,21 @@
         kPerspective2 = 15
     };
 
+    // NOTE: The flags from kTypeIdentity to kTypePerspective
+    //       must be kept in sync with the type flags found
+    //       in SkMatrix
+    enum Type {
+        kTypeIdentity = 0,
+        kTypeTranslate = 0x1,
+        kTypeScale = 0x2,
+        kTypeAffine = 0x4,
+        kTypePerspective = 0x8,
+        kTypeRectToRect = 0x10,
+        kTypeUnknown = 0x20,
+    };
+
+    static const int sGeometryMask = 0xf;
+
     Matrix4() {
         loadIdentity();
     }
@@ -75,11 +90,14 @@
     void loadTranslate(float x, float y, float z);
     void loadScale(float sx, float sy, float sz);
     void loadSkew(float sx, float sy);
+    void loadRotate(float angle);
     void loadRotate(float angle, float x, float y, float z);
     void loadMultiply(const Matrix4& u, const Matrix4& v);
 
     void loadOrtho(float left, float right, float bottom, float top, float near, float far);
 
+    uint32_t getType() const;
+
     void multiply(const Matrix4& v) {
         Matrix4 u;
         u.loadMultiply(*this, v);
@@ -112,10 +130,14 @@
         multiply(u);
     }
 
-    bool isPureTranslate() const;
+    /**
+     * If the matrix is identity or translate and/or scale.
+     */
     bool isSimple() const;
+    bool isPureTranslate() const;
     bool isIdentity() const;
     bool isPerspective() const;
+    bool rectToRect() const;
 
     bool changesBounds() const;
 
@@ -131,8 +153,7 @@
     void dump() const;
 
 private:
-    bool mSimpleMatrix;
-    bool mIsIdentity;
+    mutable uint32_t mType;
 
     inline float get(int i, int j) const {
         return data[i * 4 + j];
@@ -141,6 +162,9 @@
     inline void set(int i, int j, float v) {
         data[i * 4 + j] = v;
     }
+
+    uint32_t getGeometryType() const;
+
 }; // class Matrix4
 
 ///////////////////////////////////////////////////////////////////////////////