Fix seamless rotation with SurfaceView WM bypass.

First a brief review on seamless rotation. In seamless rotation
the WM will do the following atomically:

1. Update the display transform.
2. Set window transforms to make the surfaces at their old size appear
   at the correct location in the new coordinate space.
3. Set a flag to undo the transforms when the surfaces resize.

However, windows with NATIVE_WINDOW_TRANSFORM_DISPLAY needed to be special cased.
The flag will perform step 2 in terms of buffer mapping, but not in terms of bounds
computation. So to compensate the WM would apply the transform to the bounds,
set these bounds, and then skip applying the transform matrix (as the buffer is
transformed by the flag).

Now that the WM can't see the Camera view, it can't implement this special logic
and the Camera view inherits the parent transform. We compensate for this in
SurfaceFlinger by omitting parent rotation transform components for
Surfaces with NATIVE_WINDOW_TRANSFORM_INVERSE_DISPLAY. To some extent this
breaks arbitrary rotation for surfaces with NATIVE_WINDOW_TRANSFORM_INVERSE_DISPLAY
but this is essentially ok:

1. We lived with that bug until N-MR1
2. We fixed it in N-MR1 because the camera was falling back to ROTATE
   a lot which shouldn't be happening anymore, following introduction
   of specifying rotation animation in manifest.

Test: Rotate camera, disable HWC, rotate camera some more. Switch to front camera, repeat.
Bug: 36230754
Bug: 36727915
Change-Id: Ied390c9cb3968fcce32a84ee7947f699746fdc81
(cherry picked from commit cae605cd5668f8107e340ad8a672c7f034147401)
diff --git a/include/gui/ISurfaceComposerClient.h b/include/gui/ISurfaceComposerClient.h
index 1c89000..a680bc6 100644
--- a/include/gui/ISurfaceComposerClient.h
+++ b/include/gui/ISurfaceComposerClient.h
@@ -34,7 +34,6 @@
         DestroySurface,
         ClearLayerFrameStats,
         GetLayerFrameStats,
-        GetTransformToDisplayInverse,
         Last,
     };
 
@@ -76,9 +75,6 @@
      * Requires ACCESS_SURFACE_FLINGER permission
      */
     virtual status_t getLayerFrameStats(const sp<IBinder>& handle, FrameStats* outStats) const = 0;
-
-    virtual status_t getTransformToDisplayInverse(const sp<IBinder>& handle,
-                                                  bool* outTransformToDisplayInverse) const = 0;
 };
 
 class BnSurfaceComposerClient : public SafeBnInterface<ISurfaceComposerClient> {
diff --git a/include/gui/SurfaceComposerClient.h b/include/gui/SurfaceComposerClient.h
index 1e8cf76..394425a 100644
--- a/include/gui/SurfaceComposerClient.h
+++ b/include/gui/SurfaceComposerClient.h
@@ -169,9 +169,6 @@
     status_t clearLayerFrameStats(const sp<IBinder>& token) const;
     status_t getLayerFrameStats(const sp<IBinder>& token, FrameStats* outStats) const;
 
-    status_t getTransformToDisplayInverse(const sp<IBinder>& token,
-            bool* outTransformToDisplayInverse) const;
-
     static status_t clearAnimationFrameStats();
     static status_t getAnimationFrameStats(FrameStats* outStats);
 
diff --git a/include/gui/SurfaceControl.h b/include/gui/SurfaceControl.h
index 8ee35bc..3cff7df 100644
--- a/include/gui/SurfaceControl.h
+++ b/include/gui/SurfaceControl.h
@@ -119,8 +119,6 @@
     status_t clearLayerFrameStats() const;
     status_t getLayerFrameStats(FrameStats* outStats) const;
 
-    status_t getTransformToDisplayInverse(bool* outTransformToDisplayInverse) const;
-
 private:
     // can't be copied
     SurfaceControl& operator = (SurfaceControl& rhs);
diff --git a/libs/gui/ISurfaceComposerClient.cpp b/libs/gui/ISurfaceComposerClient.cpp
index 853e23a..2d2146b 100644
--- a/libs/gui/ISurfaceComposerClient.cpp
+++ b/libs/gui/ISurfaceComposerClient.cpp
@@ -68,14 +68,6 @@
                 &ISurfaceComposerClient::getLayerFrameStats)>(Tag::GetLayerFrameStats, handle,
                                                               outStats);
     }
-
-    status_t getTransformToDisplayInverse(const sp<IBinder>& handle,
-                                          bool* outTransformToDisplayInverse) const override {
-        return callRemote<decltype(
-                &ISurfaceComposerClient::
-                        getTransformToDisplayInverse)>(Tag::GetTransformToDisplayInverse, handle,
-                                                       outTransformToDisplayInverse);
-    }
 };
 
 // Out-of-line virtual method definition to trigger vtable emission in this
@@ -105,9 +97,6 @@
         case Tag::GetLayerFrameStats: {
             return callLocal(data, reply, &ISurfaceComposerClient::getLayerFrameStats);
         }
-        case Tag::GetTransformToDisplayInverse: {
-            return callLocal(data, reply, &ISurfaceComposerClient::getTransformToDisplayInverse);
-        }
         case Tag::Last:
             // Should not be possible because of the check at the beginning of the method
             return BBinder::onTransact(code, data, reply, flags);
diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp
index 088933a..56c7586 100644
--- a/libs/gui/SurfaceComposerClient.cpp
+++ b/libs/gui/SurfaceComposerClient.cpp
@@ -711,14 +711,6 @@
     return mClient->getLayerFrameStats(token, outStats);
 }
 
-status_t SurfaceComposerClient::getTransformToDisplayInverse(const sp<IBinder>& token,
-        bool* outTransformToDisplayInverse) const {
-    if (mStatus != NO_ERROR) {
-        return mStatus;
-    }
-    return mClient->getTransformToDisplayInverse(token, outTransformToDisplayInverse);
-}
-
 inline Composer& SurfaceComposerClient::getComposer() {
     return mComposer;
 }
diff --git a/libs/gui/SurfaceControl.cpp b/libs/gui/SurfaceControl.cpp
index 1e69379..7a68f11 100644
--- a/libs/gui/SurfaceControl.cpp
+++ b/libs/gui/SurfaceControl.cpp
@@ -209,13 +209,6 @@
     return client->getLayerFrameStats(mHandle, outStats);
 }
 
-status_t SurfaceControl::getTransformToDisplayInverse(bool* outTransformToDisplayInverse) const {
-    status_t err = validate();
-    if (err < 0) return err;
-    const sp<SurfaceComposerClient>& client(mClient);
-    return client->getTransformToDisplayInverse(mHandle, outTransformToDisplayInverse);
-}
-
 status_t SurfaceControl::validate() const
 {
     if (mHandle==0 || mClient==0) {
diff --git a/services/surfaceflinger/Client.cpp b/services/surfaceflinger/Client.cpp
index 9ddae2b..e9a2513 100644
--- a/services/surfaceflinger/Client.cpp
+++ b/services/surfaceflinger/Client.cpp
@@ -210,15 +210,5 @@
     return NO_ERROR;
 }
 
-status_t Client::getTransformToDisplayInverse(const sp<IBinder>& handle,
-        bool* outTransformToDisplayInverse) const {
-    sp<Layer> layer = getLayerUser(handle);
-    if (layer == NULL) {
-        return NAME_NOT_FOUND;
-    }
-    *outTransformToDisplayInverse = layer->getTransformToDisplayInverse();
-    return NO_ERROR;
-}
-
 // ---------------------------------------------------------------------------
 }; // namespace android
diff --git a/services/surfaceflinger/Client.h b/services/surfaceflinger/Client.h
index 141f6c7..b5f98b8 100644
--- a/services/surfaceflinger/Client.h
+++ b/services/surfaceflinger/Client.h
@@ -67,8 +67,6 @@
     virtual status_t clearLayerFrameStats(const sp<IBinder>& handle) const;
 
     virtual status_t getLayerFrameStats(const sp<IBinder>& handle, FrameStats* outStats) const;
-    virtual status_t getTransformToDisplayInverse(
-            const sp<IBinder>& handle, bool* outTransformToDisplayInverse) const;
 
     virtual status_t onTransact(
         uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags);
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index ac7e083..16d8160 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -505,7 +505,7 @@
     // which means using the inverse of the current transform set on the
     // SurfaceFlingerConsumer.
     uint32_t invTransform = mCurrentTransform;
-    if (mSurfaceFlingerConsumer->getTransformToDisplayInverse()) {
+    if (getTransformToDisplayInverse()) {
         /*
          * the code below applies the primary display's inverse transform to the
          * buffer
@@ -713,7 +713,7 @@
     const Transform bufferOrientation(mCurrentTransform);
     Transform transform(tr * t * bufferOrientation);
 
-    if (mSurfaceFlingerConsumer->getTransformToDisplayInverse()) {
+    if (getTransformToDisplayInverse()) {
         /*
          * the code below applies the primary display's inverse transform to the
          * buffer
@@ -725,8 +725,14 @@
             invTransform ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
                     NATIVE_WINDOW_TRANSFORM_FLIP_H;
         }
-        // and apply to the current transform
-        transform = Transform(invTransform) * transform;
+
+        /*
+         * Here we cancel out the orientation component of the WM transform.
+         * The scaling and translate components are already included in our bounds
+         * computation so it's enough to just omit it in the composition.
+         * See comment in onDraw with ref to b/36727915 for why.
+         */
+        transform = Transform(invTransform) * tr * bufferOrientation;
     }
 
     // this gives us only the "orientation" component of the transform
@@ -987,6 +993,24 @@
     onDraw(hw, Region(hw->bounds()), false);
 }
 
+static constexpr mat4 inverseOrientation(uint32_t transform) {
+    const mat4 flipH(-1,0,0,0,  0,1,0,0, 0,0,1,0, 1,0,0,1);
+    const mat4 flipV( 1,0,0,0, 0,-1,0,0, 0,0,1,0, 0,1,0,1);
+    const mat4 rot90( 0,1,0,0, -1,0,0,0, 0,0,1,0, 1,0,0,1);
+    mat4 tr;
+
+    if (transform & NATIVE_WINDOW_TRANSFORM_ROT_90) {
+        tr = tr * rot90;
+    }
+    if (transform & NATIVE_WINDOW_TRANSFORM_FLIP_H) {
+        tr = tr * flipH;
+    }
+    if (transform & NATIVE_WINDOW_TRANSFORM_FLIP_V) {
+        tr = tr * flipV;
+    }
+    return inverse(tr);
+}
+
 void Layer::onDraw(const sp<const DisplayDevice>& hw, const Region& clip,
         bool useIdentityTransform) const
 {
@@ -1041,30 +1065,29 @@
         mSurfaceFlingerConsumer->setFilteringEnabled(useFiltering);
         mSurfaceFlingerConsumer->getTransformMatrix(textureMatrix);
 
-        if (mSurfaceFlingerConsumer->getTransformToDisplayInverse()) {
+        if (getTransformToDisplayInverse()) {
 
             /*
              * the code below applies the primary display's inverse transform to
              * the texture transform
              */
-
-            // create a 4x4 transform matrix from the display transform flags
-            const mat4 flipH(-1,0,0,0,  0,1,0,0, 0,0,1,0, 1,0,0,1);
-            const mat4 flipV( 1,0,0,0, 0,-1,0,0, 0,0,1,0, 0,1,0,1);
-            const mat4 rot90( 0,1,0,0, -1,0,0,0, 0,0,1,0, 1,0,0,1);
-
-            mat4 tr;
             uint32_t transform =
                     DisplayDevice::getPrimaryDisplayOrientationTransform();
-            if (transform & NATIVE_WINDOW_TRANSFORM_ROT_90)
-                tr = tr * rot90;
-            if (transform & NATIVE_WINDOW_TRANSFORM_FLIP_H)
-                tr = tr * flipH;
-            if (transform & NATIVE_WINDOW_TRANSFORM_FLIP_V)
-                tr = tr * flipV;
+            mat4 tr = inverseOrientation(transform);
 
-            // calculate the inverse
-            tr = inverse(tr);
+            /**
+             * TODO(b/36727915): This is basically a hack.
+             *
+             * Ensure that regardless of the parent transformation,
+             * this buffer is always transformed from native display
+             * orientation to display orientation. For example, in the case
+             * of a camera where the buffer remains in native orientation,
+             * we want the pixels to always be upright.
+             */
+            if (getParent() != nullptr) {
+                const auto parentTransform = getParent()->getTransform();
+                tr = tr * inverseOrientation(parentTransform.getOrientation());
+            }
 
             // and finally apply it to the original texture matrix
             const mat4 texTransform(mat4(static_cast<const float*>(textureMatrix)) * tr);