Avoid redundant setMatrix calls from setMatrixInTransaction
This matches the behavior of setPositionInTransaction and setSizeInTransaction.

By eliminating calls to setMatrix, we avoid triggering redundant
SurfaceFlinger invalidates. This is particularly noteworthy on Android
Wear where we must update the minute hand every 60 seconds, but want the
device to spend as much time sleeping as possible.

See b/31489482

Change-Id: I424bb9f60c3033921fa04e7abcfc552500114f1f
diff --git a/services/core/java/com/android/server/wm/WindowSurfaceController.java b/services/core/java/com/android/server/wm/WindowSurfaceController.java
index f5ed9d1..961f742f 100644
--- a/services/core/java/com/android/server/wm/WindowSurfaceController.java
+++ b/services/core/java/com/android/server/wm/WindowSurfaceController.java
@@ -57,6 +57,12 @@
     private float mSurfaceW = 0;
     private float mSurfaceH = 0;
 
+    // Initialize to the identity matrix.
+    private float mLastDsdx = 1;
+    private float mLastDtdx = 0;
+    private float mLastDsdy = 0;
+    private float mLastDtdy = 1;
+
     private float mSurfaceAlpha = 0;
 
     private int mSurfaceLayer = 0;
@@ -266,6 +272,17 @@
 
     void setMatrixInTransaction(float dsdx, float dtdx, float dsdy, float dtdy,
             boolean recoveringMemory) {
+        final boolean matrixChanged = mLastDsdx != dsdx || mLastDtdx != dtdx ||
+                                      mLastDsdy != dsdy || mLastDtdy != dtdy;
+        if (!matrixChanged) {
+            return;
+        }
+
+        mLastDsdx = dsdx;
+        mLastDtdx = dtdx;
+        mLastDsdy = dsdy;
+        mLastDtdy = dtdy;
+
         try {
             if (SHOW_TRANSACTIONS) logSurface(
                     "MATRIX [" + dsdx + "," + dtdx + "," + dsdy + "," + dtdy + "]", null);
@@ -281,7 +298,6 @@
                 mAnimator.reclaimSomeSurfaceMemory("matrix", true);
             }
         }
-        return;
     }
 
     boolean setSizeInTransaction(int width, int height, boolean recoveringMemory) {
@@ -318,6 +334,10 @@
                 mSurfaceControl.setAlpha(alpha);
                 mSurfaceLayer = layer;
                 mSurfaceControl.setLayer(layer);
+                mLastDsdx = dsdx;
+                mLastDtdx = dtdx;
+                mLastDsdy = dsdy;
+                mLastDtdy = dtdy;
                 mSurfaceControl.setMatrix(
                         dsdx, dtdx, dsdy, dtdy);