Merge "Latch transform with geometry state." into nyc-dev
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index 04256e1..77d9d0f 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -116,6 +116,7 @@
 
     mCurrentState.active.w = w;
     mCurrentState.active.h = h;
+    mCurrentState.active.transform.set(0, 0);
     mCurrentState.active.crop.makeInvalid();
     mCurrentState.z = 0;
 #ifdef USE_HWC2
@@ -126,7 +127,6 @@
     mCurrentState.layerStack = 0;
     mCurrentState.flags = layerFlags;
     mCurrentState.sequence = 0;
-    mCurrentState.transform.set(0, 0);
     mCurrentState.requested = mCurrentState.active;
 
     // drawing state & current state are identical
@@ -399,9 +399,9 @@
         activeCrop = s.active.crop;
     }
 
-    activeCrop = s.transform.transform(activeCrop);
+    activeCrop = s.active.transform.transform(activeCrop);
     activeCrop.intersect(hw->getViewport(), &activeCrop);
-    activeCrop = s.transform.inverse().transform(activeCrop);
+    activeCrop = s.active.transform.inverse().transform(activeCrop);
 
     // This needs to be here as transform.transform(Rect) computes the
     // transformed rect and then takes the bounding box of the result before
@@ -534,13 +534,13 @@
     Region activeTransparentRegion(s.activeTransparentRegion);
     if (!s.active.crop.isEmpty()) {
         Rect activeCrop(s.active.crop);
-        activeCrop = s.transform.transform(activeCrop);
+        activeCrop = s.active.transform.transform(activeCrop);
 #ifdef USE_HWC2
         activeCrop.intersect(displayDevice->getViewport(), &activeCrop);
 #else
         activeCrop.intersect(hw->getViewport(), &activeCrop);
 #endif
-        activeCrop = s.transform.inverse().transform(activeCrop);
+        activeCrop = s.active.transform.inverse().transform(activeCrop);
         // This needs to be here as transform.transform(Rect) computes the
         // transformed rect and then takes the bounding box of the result before
         // returning. This means
@@ -557,7 +557,7 @@
         activeTransparentRegion.orSelf(Rect(activeCrop.right, activeCrop.top,
                 s.active.w, activeCrop.bottom));
     }
-    Rect frame(s.transform.transform(computeBounds(activeTransparentRegion)));
+    Rect frame(s.active.transform.transform(computeBounds(activeTransparentRegion)));
 #ifdef USE_HWC2
     frame.intersect(displayDevice->getViewport(), &frame);
     const Transform& tr(displayDevice->getTransform());
@@ -603,7 +603,7 @@
      */
 
     const Transform bufferOrientation(mCurrentTransform);
-    Transform transform(tr * s.transform * bufferOrientation);
+    Transform transform(tr * s.active.transform * bufferOrientation);
 
     if (mSurfaceFlingerConsumer->getTransformToDisplayInverse()) {
         /*
@@ -825,7 +825,7 @@
     }
     // subtract the transparent region and snap to the bounds
     Rect bounds = reduce(win, s.activeTransparentRegion);
-    Rect frame(s.transform.transform(bounds));
+    Rect frame(s.active.transform.transform(bounds));
     frame.intersect(hw->getViewport(), &frame);
     const Transform& tr(hw->getTransform());
     return Rect(tr.transform(frame));
@@ -1120,7 +1120,7 @@
 {
     const Layer::State& s(getDrawingState());
     const Transform tr(useIdentityTransform ?
-            hw->getTransform() : hw->getTransform() * s.transform);
+            hw->getTransform() : hw->getTransform() * s.active.transform);
     const uint32_t hw_h = hw->getHeight();
     Rect win(s.active.w, s.active.h);
     if (!s.active.crop.isEmpty()) {
@@ -1403,8 +1403,8 @@
         this->contentDirty = true;
 
         // we may use linear filtering, if the matrix scales us
-        const uint8_t type = c.transform.getType();
-        mNeedsFiltering = (!c.transform.preserveRects() ||
+        const uint8_t type = c.active.transform.getType();
+        mNeedsFiltering = (!c.active.transform.preserveRects() ||
                 (type >= Transform::SCALE));
     }
 
@@ -1426,10 +1426,10 @@
 }
 
 bool Layer::setPosition(float x, float y) {
-    if (mCurrentState.transform.tx() == x && mCurrentState.transform.ty() == y)
+    if (mCurrentState.requested.transform.tx() == x && mCurrentState.requested.transform.ty() == y)
         return false;
     mCurrentState.sequence++;
-    mCurrentState.transform.set(x, y);
+    mCurrentState.requested.transform.set(x, y);
     mCurrentState.modified = true;
     setTransactionFlags(eTransactionNeeded);
     return true;
@@ -1467,7 +1467,7 @@
 }
 bool Layer::setMatrix(const layer_state_t::matrix22_t& matrix) {
     mCurrentState.sequence++;
-    mCurrentState.transform.set(
+    mCurrentState.requested.transform.set(
             matrix.dsdx, matrix.dsdy, matrix.dtdx, matrix.dtdy);
     mCurrentState.modified = true;
     setTransactionFlags(eTransactionNeeded);
@@ -1632,7 +1632,7 @@
         recomputeVisibleRegions = true;
 
         const State& s(getDrawingState());
-        return s.transform.transform(Region(Rect(s.active.w, s.active.h)));
+        return s.active.transform.transform(Region(Rect(s.active.w, s.active.h)));
     }
 
     Region outDirtyRegion;
@@ -1938,7 +1938,7 @@
         Region dirtyRegion(Rect(s.active.w, s.active.h));
 
         // transform the dirty region to window-manager space
-        outDirtyRegion = (s.transform.transform(dirtyRegion));
+        outDirtyRegion = (s.active.transform.transform(dirtyRegion));
     }
     return outDirtyRegion;
 }
@@ -2000,13 +2000,13 @@
             "alpha=0x%02x, flags=0x%08x, tr=[%.2f, %.2f][%.2f, %.2f]\n"
 #endif
             "      client=%p\n",
-            s.layerStack, s.z, s.transform.tx(), s.transform.ty(), s.active.w, s.active.h,
+            s.layerStack, s.z, s.active.transform.tx(), s.active.transform.ty(), s.active.w, s.active.h,
             s.active.crop.left, s.active.crop.top,
             s.active.crop.right, s.active.crop.bottom,
             isOpaque(s), contentDirty,
             s.alpha, s.flags,
-            s.transform[0][0], s.transform[0][1],
-            s.transform[1][0], s.transform[1][1],
+            s.active.transform[0][0], s.active.transform[0][1],
+            s.active.transform[1][0], s.active.transform[1][1],
             client.get());
 
     sp<const GraphicBuffer> buf0(mActiveBuffer);
diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h
index 26e1adb..b0088e6 100644
--- a/services/surfaceflinger/Layer.h
+++ b/services/surfaceflinger/Layer.h
@@ -94,6 +94,8 @@
         uint32_t w;
         uint32_t h;
         Rect crop;
+        Transform transform;
+
         inline bool operator ==(const Geometry& rhs) const {
             return (w == rhs.w && h == rhs.h && crop == rhs.crop);
         }
@@ -116,7 +118,6 @@
         uint8_t mask;
         uint8_t reserved[2];
         int32_t sequence; // changes when visible regions can change
-        Transform transform;
         bool modified;
 
         // If set, defers this state update until the Layer identified by handle
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 0a3534f..db03c23 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -1563,7 +1563,7 @@
                 //       compute the actual visible region
                 // TODO: we could cache the transformed region
                 const Layer::State& s(layer->getDrawingState());
-                Region visibleReg = s.transform.transform(
+                Region visibleReg = s.active.transform.transform(
                         Region(Rect(s.active.w, s.active.h)));
                 invalidateLayerStack(s.layerStack, visibleReg);
             }
@@ -1666,12 +1666,12 @@
         // handle hidden surfaces by setting the visible region to empty
         if (CC_LIKELY(layer->isVisible())) {
             const bool translucent = !layer->isOpaque(s);
-            Rect bounds(s.transform.transform(layer->computeBounds()));
+            Rect bounds(s.active.transform.transform(layer->computeBounds()));
             visibleRegion.set(bounds);
             if (!visibleRegion.isEmpty()) {
                 // Remove the transparent area from the visible region
                 if (translucent) {
-                    const Transform tr(s.transform);
+                    const Transform tr(s.active.transform);
                     if (tr.transformed()) {
                         if (tr.preserveRects()) {
                             // transform the transparent region
@@ -1687,7 +1687,7 @@
                 }
 
                 // compute the opaque region
-                const int32_t layerOrientation = s.transform.getOrientation();
+                const int32_t layerOrientation = s.active.transform.getOrientation();
                 if (s.alpha == 1.0f && !translucent &&
                         ((layerOrientation & Transform::ROT_INVALID) == false)) {
                     // the opaque region is the layer's footprint
diff --git a/services/surfaceflinger/SurfaceFlinger_hwc1.cpp b/services/surfaceflinger/SurfaceFlinger_hwc1.cpp
index 737cc82..16332f3 100644
--- a/services/surfaceflinger/SurfaceFlinger_hwc1.cpp
+++ b/services/surfaceflinger/SurfaceFlinger_hwc1.cpp
@@ -1593,7 +1593,7 @@
                 //       compute the actual visible region
                 // TODO: we could cache the transformed region
                 const Layer::State& s(layer->getDrawingState());
-                Region visibleReg = s.transform.transform(
+                Region visibleReg = s.active.transform.transform(
                         Region(Rect(s.active.w, s.active.h)));
                 invalidateLayerStack(s.layerStack, visibleReg);
             }
@@ -1707,12 +1707,12 @@
         // handle hidden surfaces by setting the visible region to empty
         if (CC_LIKELY(layer->isVisible())) {
             const bool translucent = !layer->isOpaque(s);
-            Rect bounds(s.transform.transform(layer->computeBounds()));
+            Rect bounds(s.active.transform.transform(layer->computeBounds()));
             visibleRegion.set(bounds);
             if (!visibleRegion.isEmpty()) {
                 // Remove the transparent area from the visible region
                 if (translucent) {
-                    const Transform tr(s.transform);
+                    const Transform tr(s.active.transform);
                     if (tr.transformed()) {
                         if (tr.preserveRects()) {
                             // transform the transparent region
@@ -1728,7 +1728,7 @@
                 }
 
                 // compute the opaque region
-                const int32_t layerOrientation = s.transform.getOrientation();
+                const int32_t layerOrientation = s.active.transform.getOrientation();
                 if (s.alpha==255 && !translucent &&
                         ((layerOrientation & Transform::ROT_INVALID) == false)) {
                     // the opaque region is the layer's footprint