Improve clip support (add intersect, union and replace.)

This change also modifies the way the clip is stored. The clip is now
always stored in screen-space coordinates.

Change-Id: I96375784d82dfe975bc6477a159e6866e7052487
diff --git a/libs/hwui/Matrix.cpp b/libs/hwui/Matrix.cpp
index 877d3bb..b459202 100644
--- a/libs/hwui/Matrix.cpp
+++ b/libs/hwui/Matrix.cpp
@@ -93,6 +93,25 @@
     v.set(SkMatrix::kMPersp2, data[15]);
 }
 
+void Matrix4::loadInverse(const Matrix4& v) {
+    double scale = 1.0 /
+            (v.data[0]  * ((double) v.data[5]  * v.data[15] - (double) v.data[13] * v.data[7]) +
+             v.data[4]  * ((double) v.data[13] * v.data[3]  - (double) v.data[1]  * v.data[15]) +
+             v.data[12] * ((double) v.data[1]  * v.data[7]  - (double) v.data[5]  * v.data[3]));
+
+    data[0]  = (v.data[5] * v.data[15] - v.data[13] * v.data[7])  * scale;
+    data[4]  = (v.data[12] * v.data[7] - v.data[4]  * v.data[15]) * scale;
+    data[12] = (v.data[4] * v.data[13] - v.data[12] * v.data[5])  * scale;
+
+    data[1]  = (v.data[13] * v.data[3] - v.data[1]  * v.data[15]) * scale;
+    data[5]  = (v.data[0] * v.data[15] - v.data[12] * v.data[3])  * scale;
+    data[13] = (v.data[12] * v.data[1] - v.data[0]  * v.data[13]) * scale;
+
+    data[3]  = (v.data[1] * v.data[7] - v.data[5] * v.data[3]) * scale;
+    data[7]  = (v.data[4] * v.data[3] - v.data[0] * v.data[7]) * scale;
+    data[15] = (v.data[0] * v.data[5] - v.data[4] * v.data[1]) * scale;
+}
+
 void Matrix4::copyTo(float* v) const {
     memcpy(v, data, sizeof(data));
 }