Transfer HWC release fences to BufferQueue

After a HWC set, each SurfaceFlinger Layer retrieves the release fence
HWC returned and gives it to the layer's SurfaceTexture. The
SurfaceTexture accumulates the fences into a merged fence until the
next updateTexImage, then passes the merged fence to the BufferQueue
in releaseBuffer.

In a follow-on change, BufferQueue will return the fence along with
the buffer slot in dequeueBuffer. For now, dequeueBuffer waits for the
fence to signal before returning.

The releaseFence default value for BufferQueue::releaseBuffer() is
temporary to avoid transient build breaks with a multi-project
checkin. It'll disappear in the next change.

Change-Id: Iaa9a0d5775235585d9cbf453d3a64623d08013d9
diff --git a/services/surfaceflinger/DisplayHardware/FramebufferSurface.cpp b/services/surfaceflinger/DisplayHardware/FramebufferSurface.cpp
index 02ec86e..02d2b10 100644
--- a/services/surfaceflinger/DisplayHardware/FramebufferSurface.cpp
+++ b/services/surfaceflinger/DisplayHardware/FramebufferSurface.cpp
@@ -109,7 +109,7 @@
                     self->fbDev->post(self->fbDev, self->mBuffers[item.mBuf]->handle);
                     if (self->mCurrentBufferIndex >= 0) {
                         self->mBufferQueue->releaseBuffer(self->mCurrentBufferIndex,
-                                EGL_NO_DISPLAY, EGL_NO_SYNC_KHR);
+                                EGL_NO_DISPLAY, EGL_NO_SYNC_KHR, Fence::NO_FENCE);
                     }
                     self->mCurrentBufferIndex = item.mBuf;
                 }
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.cpp b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
index 385be63..7c09ab2 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.cpp
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
@@ -346,6 +346,10 @@
     virtual uint32_t getHints() const {
         return getLayer()->hints;
     }
+    virtual int getAndResetReleaseFenceFd() {
+        // not supported on VERSION_03
+        return -1;
+    }
 
     virtual void setDefaultState() {
         getLayer()->compositionType = HWC_FRAMEBUFFER;
@@ -407,6 +411,11 @@
     virtual uint32_t getHints() const {
         return getLayer()->hints;
     }
+    virtual int getAndResetReleaseFenceFd() {
+        int fd = getLayer()->releaseFenceFd;
+        getLayer()->releaseFenceFd = -1;
+        return fd;
+    }
 
     virtual void setDefaultState() {
         getLayer()->compositionType = HWC_FRAMEBUFFER;
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.h b/services/surfaceflinger/DisplayHardware/HWComposer.h
index 05c6f6d..cb4c2db 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.h
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.h
@@ -100,6 +100,7 @@
     public:
         virtual int32_t getCompositionType() const = 0;
         virtual uint32_t getHints() const = 0;
+        virtual int getAndResetReleaseFenceFd() = 0;
         virtual void setDefaultState() = 0;
         virtual void setSkip(bool skip) = 0;
         virtual void setBlending(uint32_t blending) = 0;
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index 890bcb4..64e4b5f 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -71,7 +71,11 @@
     glGenTextures(1, &mTextureName);
 }
 
-void Layer::onLayerDisplayed() {
+void Layer::onLayerDisplayed(HWComposer::HWCLayerInterface* layer) {
+    if (layer) {
+        mSurfaceTexture->setReleaseFence(layer->getAndResetReleaseFenceFd());
+    }
+
     if (mFrameLatencyNeeded) {
         const DisplayHardware& hw(graphicPlane(0).displayHardware());
         mFrameStats[mFrameLatencyOffset].timestamp = mSurfaceTexture->getTimestamp();
diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h
index 7a164aa..32456f4 100644
--- a/services/surfaceflinger/Layer.h
+++ b/services/surfaceflinger/Layer.h
@@ -82,7 +82,7 @@
     // LayerBaseClient interface
     virtual wp<IBinder> getSurfaceTextureBinder() const;
 
-    virtual void onLayerDisplayed();
+    virtual void onLayerDisplayed(HWComposer::HWCLayerInterface* layer);
     virtual bool onPreComposition();
 
     // only for debugging
diff --git a/services/surfaceflinger/LayerBase.h b/services/surfaceflinger/LayerBase.h
index 4d5d1e4..698cdb8 100644
--- a/services/surfaceflinger/LayerBase.h
+++ b/services/surfaceflinger/LayerBase.h
@@ -210,7 +210,7 @@
 
     /** called after page-flip
      */
-    virtual void onLayerDisplayed() { }
+    virtual void onLayerDisplayed(HWComposer::HWCLayerInterface* layer) { }
 
     /** called before composition.
      * returns true if the layer has pending updates.
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index e059f1c..981d694 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -472,8 +472,17 @@
     hw.flip(mSwapRegion);
 
     size_t numLayers = mVisibleLayersSortedByZ.size();
-    for (size_t i = 0; i < numLayers; i++) {
-        mVisibleLayersSortedByZ[i]->onLayerDisplayed();
+    HWComposer& hwc(graphicPlane(0).displayHardware().getHwComposer());
+    if (hwc.initCheck() == NO_ERROR) {
+        HWComposer::LayerListIterator cur = hwc.begin();
+        const HWComposer::LayerListIterator end = hwc.end();
+        for (size_t i = 0; cur != end && i < numLayers; ++i, ++cur) {
+            mVisibleLayersSortedByZ[i]->onLayerDisplayed(&*cur);
+        }
+    } else {
+        for (size_t i = 0; i < numLayers; i++) {
+            mVisibleLayersSortedByZ[i]->onLayerDisplayed(NULL);
+        }
     }
 
     mLastSwapBufferTime = systemTime() - now;