SF: Only latch buffers after fence signals

Changes SurfaceFlinger to only latch a buffer after its corresponding
acquire fence has signaled. This will enable us to move
SurfaceFlinger closer to vsync since there is no risk of fence waits
blocking composition.

Bug: 29413700
Change-Id: I26f4fd600c1611b8d736ec654d1f0f02cf69ae5f
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index 5145a3f..548b048 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -1100,6 +1100,25 @@
     }
 }
 
+bool Layer::headFenceHasSignaled() const {
+#ifdef USE_HWC2
+    Mutex::Autolock lock(mQueueItemLock);
+    if (mQueueItems.empty()) {
+        return true;
+    }
+    if (mQueueItems[0].mIsDroppable) {
+        // Even though this buffer's fence may not have signaled yet, it could
+        // be replaced by another buffer before it has a chance to, which means
+        // that it's possible to get into a situation where a buffer is never
+        // able to be latched. To avoid this, grab this buffer anyway.
+        return true;
+    }
+    return mQueueItems[0].mFence->getSignalTime() != INT64_MAX;
+#else
+    return true;
+#endif
+}
+
 bool Layer::addSyncPoint(const std::shared_ptr<SyncPoint>& point) {
     if (point->getFrameNumber() <= mCurrentFrameNumber) {
         // Don't bother with a SyncPoint, since we've already latched the
@@ -1357,9 +1376,10 @@
 
 void Layer::notifyAvailableFrames() {
     auto headFrameNumber = getHeadFrameNumber();
+    bool headFenceSignaled = headFenceHasSignaled();
     Mutex::Autolock lock(mLocalSyncPointMutex);
     for (auto& point : mLocalSyncPoints) {
-        if (headFrameNumber >= point->getFrameNumber()) {
+        if (headFrameNumber >= point->getFrameNumber() && headFenceSignaled) {
             point->setFrameAvailable();
         }
     }
@@ -1756,6 +1776,13 @@
             return outDirtyRegion;
         }
 
+        // If the head buffer's acquire fence hasn't signaled yet, return and
+        // try again later
+        if (!headFenceHasSignaled()) {
+            mFlinger->signalLayerUpdate();
+            return outDirtyRegion;
+        }
+
         // Capture the old state of the layer for comparisons later
         const State& s(getDrawingState());
         const bool oldOpacity = isOpaque(s);
diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h
index a51c804..78a8427 100644
--- a/services/surfaceflinger/Layer.h
+++ b/services/surfaceflinger/Layer.h
@@ -510,6 +510,7 @@
     std::list<std::shared_ptr<SyncPoint>> mRemoteSyncPoints;
 
     uint64_t getHeadFrameNumber() const;
+    bool headFenceHasSignaled() const;
 
     // Returns false if the relevant frame has already been latched
     bool addSyncPoint(const std::shared_ptr<SyncPoint>& point);