Merge changes from topic \\'seamless-rotation\\' into nyc-mr1-dev am: 4bfbe1f7ef
am: d99daf4fe6

Change-Id: Iaabf524a3b835b794b2b1269cd573b66676be9a1
diff --git a/include/gui/ISurfaceComposerClient.h b/include/gui/ISurfaceComposerClient.h
index bb79bd0..c27a741 100644
--- a/include/gui/ISurfaceComposerClient.h
+++ b/include/gui/ISurfaceComposerClient.h
@@ -77,6 +77,9 @@
      * 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;
 };
 
 // ----------------------------------------------------------------------------
diff --git a/include/gui/SurfaceComposerClient.h b/include/gui/SurfaceComposerClient.h
index 312e02f..95e8b70 100644
--- a/include/gui/SurfaceComposerClient.h
+++ b/include/gui/SurfaceComposerClient.h
@@ -140,13 +140,16 @@
             const sp<IBinder>& handle, uint64_t frameNumber);
     status_t    setOverrideScalingMode(const sp<IBinder>& id,
             int32_t overrideScalingMode);
-    status_t    setPositionAppliesWithResize(const sp<IBinder>& id);
+    status_t    setGeometryAppliesWithResize(const sp<IBinder>& id);
 
     status_t    destroySurface(const sp<IBinder>& id);
 
     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 fafd194..5e731c3 100644
--- a/include/gui/SurfaceControl.h
+++ b/include/gui/SurfaceControl.h
@@ -73,10 +73,11 @@
     status_t    setCrop(const Rect& crop);
     status_t    setFinalCrop(const Rect& crop);
 
-    // If the size changes in this transaction, position updates specified
+    // If the size changes in this transaction, all geometry updates specified
     // in this transaction will not complete until a buffer of the new size
-    // arrives.
-    status_t    setPositionAppliesWithResize();
+    // arrives. As some elements normally apply immediately, this enables
+    // freezing the total geometry of a surface until a resize is completed.
+    status_t    setGeometryAppliesWithResize();
 
     // Defers applying any changes made in this transaction until the Layer
     // identified by handle reaches the given frameNumber
@@ -96,6 +97,8 @@
     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/include/private/gui/LayerState.h b/include/private/gui/LayerState.h
index 4885e05..4b3fcc6 100644
--- a/include/private/gui/LayerState.h
+++ b/include/private/gui/LayerState.h
@@ -55,7 +55,7 @@
         eDeferTransaction           = 0x00000200,
         eFinalCropChanged           = 0x00000400,
         eOverrideScalingModeChanged = 0x00000800,
-        ePositionAppliesWithResize  = 0x00001000,
+        eGeometryAppliesWithResize  = 0x00001000,
     };
 
     layer_state_t()
diff --git a/libs/gui/ISurfaceComposerClient.cpp b/libs/gui/ISurfaceComposerClient.cpp
index decffbf..47cb047 100644
--- a/libs/gui/ISurfaceComposerClient.cpp
+++ b/libs/gui/ISurfaceComposerClient.cpp
@@ -41,7 +41,8 @@
     CREATE_SURFACE = IBinder::FIRST_CALL_TRANSACTION,
     DESTROY_SURFACE,
     CLEAR_LAYER_FRAME_STATS,
-    GET_LAYER_FRAME_STATS
+    GET_LAYER_FRAME_STATS,
+    GET_TRANSFORM_TO_DISPLAY_INVERSE
 };
 
 class BpSurfaceComposerClient : public BpInterface<ISurfaceComposerClient>
@@ -94,6 +95,35 @@
         reply.read(*outStats);
         return reply.readInt32();
     }
+
+    virtual status_t getTransformToDisplayInverse(const sp<IBinder>& handle,
+            bool* outTransformToDisplayInverse) const {
+        Parcel data, reply;
+        status_t result =
+                data.writeInterfaceToken(ISurfaceComposerClient::getInterfaceDescriptor());
+        if (result != NO_ERROR) {
+            return result;
+        }
+        result = data.writeStrongBinder(handle);
+        if (result != NO_ERROR) {
+            return result;
+        }
+        result = remote()->transact(GET_TRANSFORM_TO_DISPLAY_INVERSE, data, &reply);
+        if (result != NO_ERROR) {
+            return result;
+        }
+        int transformInverse;
+        result = reply.readInt32(&transformInverse);
+        if (result != NO_ERROR) {
+            return result;
+        }
+        *outTransformToDisplayInverse = transformInverse != 0 ? true : false;
+        status_t result2 = reply.readInt32(&result);
+        if (result2 != NO_ERROR) {
+            return result2;
+        }
+        return result;
+    }
 };
 
 // Out-of-line virtual method definition to trigger vtable emission in this
@@ -145,6 +175,25 @@
             reply->writeInt32(result);
             return NO_ERROR;
         }
+        case GET_TRANSFORM_TO_DISPLAY_INVERSE: {
+            CHECK_INTERFACE(ISurfaceComposerClient, data, reply);
+            sp<IBinder> handle;
+            status_t result = data.readStrongBinder(&handle);
+            if (result != NO_ERROR) {
+                return result;
+            }
+            bool transformInverse = false;
+            result = getTransformToDisplayInverse(handle, &transformInverse);
+            if (result != NO_ERROR) {
+                return result;
+            }
+            result = reply->writeInt32(transformInverse ? 1 : 0);
+            if (result != NO_ERROR) {
+                return result;
+            }
+            result = reply->writeInt32(NO_ERROR);
+            return result;
+        }
         default:
             return BBinder::onTransact(code, data, reply, flags);
     }
diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp
index 2189047..059223d 100644
--- a/libs/gui/SurfaceComposerClient.cpp
+++ b/libs/gui/SurfaceComposerClient.cpp
@@ -165,7 +165,7 @@
             uint64_t frameNumber);
     status_t setOverrideScalingMode(const sp<SurfaceComposerClient>& client,
             const sp<IBinder>& id, int32_t overrideScalingMode);
-    status_t setPositionAppliesWithResize(const sp<SurfaceComposerClient>& client,
+    status_t setGeometryAppliesWithResize(const sp<SurfaceComposerClient>& client,
             const sp<IBinder>& id);
 
     void setDisplaySurface(const sp<IBinder>& token,
@@ -445,7 +445,7 @@
     return NO_ERROR;
 }
 
-status_t Composer::setPositionAppliesWithResize(
+status_t Composer::setGeometryAppliesWithResize(
         const sp<SurfaceComposerClient>& client,
         const sp<IBinder>& id) {
     Mutex::Autolock lock(mLock);
@@ -453,7 +453,7 @@
     if (!s) {
         return BAD_INDEX;
     }
-    s->what |= layer_state_t::ePositionAppliesWithResize;
+    s->what |= layer_state_t::eGeometryAppliesWithResize;
     return NO_ERROR;
 }
 
@@ -612,6 +612,14 @@
     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;
 }
@@ -699,9 +707,9 @@
             this, id, overrideScalingMode);
 }
 
-status_t SurfaceComposerClient::setPositionAppliesWithResize(
+status_t SurfaceComposerClient::setGeometryAppliesWithResize(
         const sp<IBinder>& id) {
-    return getComposer().setPositionAppliesWithResize(this, id);
+    return getComposer().setGeometryAppliesWithResize(this, id);
 }
 
 // ----------------------------------------------------------------------------
diff --git a/libs/gui/SurfaceControl.cpp b/libs/gui/SurfaceControl.cpp
index 4671e50..33c1d90 100644
--- a/libs/gui/SurfaceControl.cpp
+++ b/libs/gui/SurfaceControl.cpp
@@ -112,10 +112,10 @@
     if (err < 0) return err;
     return mClient->setPosition(mHandle, x, y);
 }
-status_t SurfaceControl::setPositionAppliesWithResize() {
+status_t SurfaceControl::setGeometryAppliesWithResize() {
     status_t err = validate();
     if (err < 0) return err;
-    return mClient->setPositionAppliesWithResize(mHandle);
+    return mClient->setGeometryAppliesWithResize(mHandle);
 }
 status_t SurfaceControl::setSize(uint32_t w, uint32_t h) {
     status_t err = validate();
@@ -190,6 +190,13 @@
     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 2a025b8..415bdca 100644
--- a/services/surfaceflinger/Client.cpp
+++ b/services/surfaceflinger/Client.cpp
@@ -173,5 +173,15 @@
     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 b6d7381..12db505 100644
--- a/services/surfaceflinger/Client.h
+++ b/services/surfaceflinger/Client.h
@@ -63,6 +63,8 @@
     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 5e61efd..feece55 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -1567,11 +1567,15 @@
     setTransactionFlags(eTransactionNeeded);
     return true;
 }
-bool Layer::setCrop(const Rect& crop) {
+
+bool Layer::setCrop(const Rect& crop, bool immediate) {
     if (mCurrentState.crop == crop)
         return false;
     mCurrentState.sequence++;
-    mCurrentState.crop = crop;
+    mCurrentState.requestedCrop = crop;
+    if (immediate) {
+        mCurrentState.crop = crop;
+    }
     mCurrentState.modified = true;
     setTransactionFlags(eTransactionNeeded);
     return true;
@@ -1762,16 +1766,19 @@
             bool stickyTransformSet;
             const char* name;
             int32_t overrideScalingMode;
+            bool& freezePositionUpdates;
 
             Reject(Layer::State& front, Layer::State& current,
                     bool& recomputeVisibleRegions, bool stickySet,
                     const char* name,
-                    int32_t overrideScalingMode)
+                    int32_t overrideScalingMode,
+                    bool& freezePositionUpdates)
                 : front(front), current(current),
                   recomputeVisibleRegions(recomputeVisibleRegions),
                   stickyTransformSet(stickySet),
                   name(name),
-                  overrideScalingMode(overrideScalingMode) {
+                  overrideScalingMode(overrideScalingMode),
+                  freezePositionUpdates(freezePositionUpdates) {
             }
 
             virtual bool reject(const sp<GraphicBuffer>& buf,
@@ -1863,13 +1870,20 @@
                     recomputeVisibleRegions = true;
                 }
 
+                if (front.crop != front.requestedCrop) {
+                    front.crop = front.requestedCrop;
+                    current.crop = front.requestedCrop;
+                    recomputeVisibleRegions = true;
+                }
+                freezePositionUpdates = false;
+
                 return false;
             }
         };
 
         Reject r(mDrawingState, getCurrentState(), recomputeVisibleRegions,
                 getProducerStickyTransform() != 0, mName.string(),
-                mOverrideScalingMode);
+                mOverrideScalingMode, mFreezePositionUpdates);
 
 
         // Check all of our local sync points to ensure that all transactions
@@ -2012,7 +2026,6 @@
             if (bufWidth != uint32_t(oldActiveBuffer->width) ||
                 bufHeight != uint32_t(oldActiveBuffer->height)) {
                 recomputeVisibleRegions = true;
-                mFreezePositionUpdates = false;
             }
         }
 
@@ -2190,6 +2203,10 @@
     return history;
 }
 
+bool Layer::getTransformToDisplayInverse() const {
+    return mSurfaceFlingerConsumer->getTransformToDisplayInverse();
+}
+
 // ---------------------------------------------------------------------------
 
 Layer::LayerCleaner::LayerCleaner(const sp<SurfaceFlinger>& flinger,
diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h
index 4257c37..a51c804 100644
--- a/services/surfaceflinger/Layer.h
+++ b/services/surfaceflinger/Layer.h
@@ -96,7 +96,9 @@
         Transform transform;
 
         inline bool operator ==(const Geometry& rhs) const {
-          return (w == rhs.w && h == rhs.h);
+            return (w == rhs.w && h == rhs.h) &&
+                    (transform.tx() == rhs.transform.tx()) &&
+                    (transform.ty() == rhs.transform.ty());
         }
         inline bool operator !=(const Geometry& rhs) const {
             return !operator ==(rhs);
@@ -120,6 +122,8 @@
         bool modified;
 
         Rect crop;
+        Rect requestedCrop;
+
         Rect finalCrop;
 
         // If set, defers this state update until the Layer identified by handle
@@ -156,7 +160,7 @@
     bool setMatrix(const layer_state_t::matrix22_t& matrix);
     bool setTransparentRegionHint(const Region& transparent);
     bool setFlags(uint8_t flags, uint8_t mask);
-    bool setCrop(const Rect& crop);
+    bool setCrop(const Rect& crop, bool immediate);
     bool setFinalCrop(const Rect& crop);
     bool setLayerStack(uint32_t layerStack);
     void deferTransactionUntil(const sp<IBinder>& handle, uint64_t frameNumber);
@@ -414,6 +418,8 @@
         return mFlinger->getFrameTimestamps(*this, frameNumber, outTimestamps);
     }
 
+    bool getTransformToDisplayInverse() const;
+
 protected:
     // constant
     sp<SurfaceFlinger> mFlinger;
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 097c15b..f6c6de1 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -2260,10 +2260,10 @@
     sp<Layer> layer(client->getLayerUser(s.surface));
     if (layer != 0) {
         const uint32_t what = s.what;
-        bool positionAppliesWithResize =
-                what & layer_state_t::ePositionAppliesWithResize;
+        bool geometryAppliesWithResize =
+                what & layer_state_t::eGeometryAppliesWithResize;
         if (what & layer_state_t::ePositionChanged) {
-            if (layer->setPosition(s.x, s.y, !positionAppliesWithResize)) {
+            if (layer->setPosition(s.x, s.y, !geometryAppliesWithResize)) {
                 flags |= eTraversalNeeded;
             }
         }
@@ -2300,7 +2300,7 @@
                 flags |= eTraversalNeeded;
         }
         if (what & layer_state_t::eCropChanged) {
-            if (layer->setCrop(s.crop))
+            if (layer->setCrop(s.crop, !geometryAppliesWithResize))
                 flags |= eTraversalNeeded;
         }
         if (what & layer_state_t::eFinalCropChanged) {
diff --git a/services/surfaceflinger/SurfaceFlingerConsumer.cpp b/services/surfaceflinger/SurfaceFlingerConsumer.cpp
index ba0a527..e0e4c61 100644
--- a/services/surfaceflinger/SurfaceFlingerConsumer.cpp
+++ b/services/surfaceflinger/SurfaceFlingerConsumer.cpp
@@ -129,6 +129,7 @@
 }
 
 bool SurfaceFlingerConsumer::getTransformToDisplayInverse() const {
+    Mutex::Autolock lock(mMutex);
     return mTransformToDisplayInverse;
 }
 
diff --git a/services/surfaceflinger/SurfaceFlingerConsumer.h b/services/surfaceflinger/SurfaceFlingerConsumer.h
index 3762659..4271039 100644
--- a/services/surfaceflinger/SurfaceFlingerConsumer.h
+++ b/services/surfaceflinger/SurfaceFlingerConsumer.h
@@ -66,8 +66,9 @@
     // See GLConsumer::bindTextureImageLocked().
     status_t bindTextureImage();
 
-    // must be called from SF main thread
     bool getTransformToDisplayInverse() const;
+
+    // must be called from SF main thread
     const Region& getSurfaceDamage() const;
 
     // Sets the contents changed listener. This should be used instead of
diff --git a/services/surfaceflinger/SurfaceFlinger_hwc1.cpp b/services/surfaceflinger/SurfaceFlinger_hwc1.cpp
index b49f8af..b67b70d 100644
--- a/services/surfaceflinger/SurfaceFlinger_hwc1.cpp
+++ b/services/surfaceflinger/SurfaceFlinger_hwc1.cpp
@@ -2263,10 +2263,10 @@
     sp<Layer> layer(client->getLayerUser(s.surface));
     if (layer != 0) {
         const uint32_t what = s.what;
-        bool positionAppliesWithResize =
-                what & layer_state_t::ePositionAppliesWithResize;
+        bool geometryAppliesWithResize =
+                what & layer_state_t::eGeometryAppliesWithResize;
         if (what & layer_state_t::ePositionChanged) {
-            if (layer->setPosition(s.x, s.y, !positionAppliesWithResize)) {
+            if (layer->setPosition(s.x, s.y, !geometryAppliesWithResize)) {
                 flags |= eTraversalNeeded;
             }
         }
@@ -2303,7 +2303,7 @@
                 flags |= eTraversalNeeded;
         }
         if (what & layer_state_t::eCropChanged) {
-            if (layer->setCrop(s.crop))
+            if (layer->setCrop(s.crop, !geometryAppliesWithResize))
                 flags |= eTraversalNeeded;
         }
         if (what & layer_state_t::eFinalCropChanged) {