Support SurfaceView synchronization.

Add API for fetching the next frame number to be produced by
a given buffer producer. Add an API to SurfaceComposer to 
defer execution of the current transaction until a given frame number. 
Together these may be used to synchronize app drawing and surface 
control updates.

Change-Id: I8e0f4993332ac0199c768c88581a453fefbaff1d
diff --git a/libs/gui/BufferQueueProducer.cpp b/libs/gui/BufferQueueProducer.cpp
index 0cb018c..9ef8ff7 100644
--- a/libs/gui/BufferQueueProducer.cpp
+++ b/libs/gui/BufferQueueProducer.cpp
@@ -1151,6 +1151,14 @@
     return mConsumerName;
 }
 
+uint64_t BufferQueueProducer::getNextFrameNumber() const {
+    ATRACE_CALL();
+
+    Mutex::Autolock lock(mCore->mMutex);
+    uint64_t nextFrameNumber = mCore->mFrameCounter + 1;
+    return nextFrameNumber;
+}
+
 void BufferQueueProducer::binderDied(const wp<android::IBinder>& /* who */) {
     // If we're here, it means that a producer we were connected to died.
     // We're guaranteed that we are still connected to it because we remove
diff --git a/libs/gui/IGraphicBufferProducer.cpp b/libs/gui/IGraphicBufferProducer.cpp
index 8ab963d..640a9f2 100644
--- a/libs/gui/IGraphicBufferProducer.cpp
+++ b/libs/gui/IGraphicBufferProducer.cpp
@@ -49,7 +49,8 @@
     SET_GENERATION_NUMBER,
     GET_CONSUMER_NAME,
     SET_MAX_DEQUEUED_BUFFER_COUNT,
-    SET_ASYNC_MODE
+    SET_ASYNC_MODE,
+    GET_NEXT_FRAME_NUMBER
 };
 
 class BpGraphicBufferProducer : public BpInterface<IGraphicBufferProducer>
@@ -326,6 +327,18 @@
         }
         return reply.readString8();
     }
+
+    virtual uint64_t getNextFrameNumber() const {
+        Parcel data, reply;
+        data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor());
+        status_t result = remote()->transact(GET_NEXT_FRAME_NUMBER, data, &reply);
+        if (result != NO_ERROR) {
+            ALOGE("getNextFrameNumber failed to transact: %d", result);
+            return 0;
+        }
+        uint64_t frameNumber = reply.readUint64();
+        return frameNumber;
+    }
 };
 
 // Out-of-line virtual method definition to trigger vtable emission in this
@@ -508,6 +521,12 @@
             reply->writeString8(getConsumerName());
             return NO_ERROR;
         }
+        case GET_NEXT_FRAME_NUMBER: {
+            CHECK_INTERFACE(IGraphicBufferProducer, data, reply);
+            uint64_t frameNumber = getNextFrameNumber();
+            reply->writeUint64(frameNumber);
+            return NO_ERROR;
+        }
     }
     return BBinder::onTransact(code, data, reply, flags);
 }
diff --git a/libs/gui/LayerState.cpp b/libs/gui/LayerState.cpp
index eafda86..06f13e8 100644
--- a/libs/gui/LayerState.cpp
+++ b/libs/gui/LayerState.cpp
@@ -38,6 +38,8 @@
     *reinterpret_cast<layer_state_t::matrix22_t *>(
             output.writeInplace(sizeof(layer_state_t::matrix22_t))) = matrix;
     output.write(crop);
+    output.writeStrongBinder(handle);
+    output.writeUint64(frameNumber);
     output.write(transparentRegion);
     return NO_ERROR;
 }
@@ -62,6 +64,8 @@
         return BAD_VALUE;
     }
     input.read(crop);
+    handle = input.readStrongBinder();
+    frameNumber = input.readUint64();
     input.read(transparentRegion);
     return NO_ERROR;
 }
diff --git a/libs/gui/Surface.cpp b/libs/gui/Surface.cpp
index a31876b..9191b2a 100644
--- a/libs/gui/Surface.cpp
+++ b/libs/gui/Surface.cpp
@@ -111,6 +111,10 @@
     return result;
 }
 
+uint64_t Surface::getNextFrameNumber() const {
+    return mGraphicBufferProducer->getNextFrameNumber();
+}
+
 String8 Surface::getConsumerName() const {
     return mGraphicBufferProducer->getConsumerName();
 }
diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp
index 9167a0c..3242f55 100644
--- a/libs/gui/SurfaceComposerClient.cpp
+++ b/libs/gui/SurfaceComposerClient.cpp
@@ -158,6 +158,9 @@
             const Rect& crop);
     status_t setLayerStack(const sp<SurfaceComposerClient>& client,
             const sp<IBinder>& id, uint32_t layerStack);
+    status_t deferTransactionUntil(const sp<SurfaceComposerClient>& client,
+            const sp<IBinder>& id, const sp<IBinder>& handle,
+            uint64_t frameNumber);
 
     void setDisplaySurface(const sp<IBinder>& token,
             const sp<IGraphicBufferProducer>& bufferProducer);
@@ -383,6 +386,20 @@
     return NO_ERROR;
 }
 
+status_t Composer::deferTransactionUntil(
+        const sp<SurfaceComposerClient>& client, const sp<IBinder>& id,
+        const sp<IBinder>& handle, uint64_t frameNumber) {
+    Mutex::Autolock lock(mLock);
+    layer_state_t* s = getLayerStateLocked(client, id);
+    if (!s) {
+        return BAD_INDEX;
+    }
+    s->what |= layer_state_t::eDeferTransaction;
+    s->handle = handle;
+    s->frameNumber = frameNumber;
+    return NO_ERROR;
+}
+
 // ---------------------------------------------------------------------------
 
 DisplayState& Composer::getDisplayStateLocked(const sp<IBinder>& token) {
@@ -609,6 +626,11 @@
     return getComposer().setMatrix(this, id, dsdx, dtdx, dsdy, dtdy);
 }
 
+status_t SurfaceComposerClient::deferTransactionUntil(const sp<IBinder>& id,
+        const sp<IBinder>& handle, uint64_t frameNumber) {
+    return getComposer().deferTransactionUntil(this, id, handle, frameNumber);
+}
+
 // ----------------------------------------------------------------------------
 
 void SurfaceComposerClient::setDisplaySurface(const sp<IBinder>& token,
diff --git a/libs/gui/SurfaceControl.cpp b/libs/gui/SurfaceControl.cpp
index 1983027..a945358 100644
--- a/libs/gui/SurfaceControl.cpp
+++ b/libs/gui/SurfaceControl.cpp
@@ -145,6 +145,13 @@
     return mClient->setCrop(mHandle, crop);
 }
 
+status_t SurfaceControl::deferTransactionUntil(sp<IBinder> handle,
+        uint64_t frameNumber) {
+    status_t err = validate();
+    if (err < 0) return err;
+    return mClient->deferTransactionUntil(mHandle, handle, frameNumber);
+}
+
 status_t SurfaceControl::clearLayerFrameStats() const {
     status_t err = validate();
     if (err < 0) return err;
@@ -190,5 +197,11 @@
     return mSurfaceData;
 }
 
+sp<IBinder> SurfaceControl::getHandle() const
+{
+    Mutex::Autolock lock(mLock);
+    return mHandle;
+}
+
 // ----------------------------------------------------------------------------
 }; // namespace android