Merge "SurfaceFlinger: check fence when acquiring buffer with PTS"
diff --git a/services/surfaceflinger/BufferQueueLayer.cpp b/services/surfaceflinger/BufferQueueLayer.cpp
index 93b2b99..3915757 100644
--- a/services/surfaceflinger/BufferQueueLayer.cpp
+++ b/services/surfaceflinger/BufferQueueLayer.cpp
@@ -234,9 +234,28 @@
     const nsecs_t expectedPresentTime = mFlinger->mUseScheduler
             ? mFlinger->mScheduler->mPrimaryDispSync->expectedPresentTime()
             : mFlinger->mPrimaryDispSync->expectedPresentTime();
+
+    // updateTexImage() below might drop the some buffers at the head of the queue if there is a
+    // buffer behind them which is timely to be presented. However this buffer may not be signaled
+    // yet. The code below makes sure that this wouldn't happen by setting maxFrameNumber to the
+    // last buffer that was signaled.
+    uint64_t lastSignaledFrameNumber = mLastFrameNumberReceived;
+    {
+        Mutex::Autolock lock(mQueueItemLock);
+        for (int i = 0; i < mQueueItems.size(); i++) {
+            bool fenceSignaled =
+                    mQueueItems[i].mFenceTime->getSignalTime() != Fence::SIGNAL_TIME_PENDING;
+            if (!fenceSignaled) {
+                break;
+            }
+            lastSignaledFrameNumber = mQueueItems[i].mFrameNumber;
+        }
+    }
+    const uint64_t maxFrameNumberToAcquire =
+            std::min(mLastFrameNumberReceived.load(), lastSignaledFrameNumber);
     status_t updateResult =
             mConsumer->updateTexImage(&r, expectedPresentTime, &mAutoRefresh, &queuedBuffer,
-                                      mLastFrameNumberReceived, releaseFence);
+                                      maxFrameNumberToAcquire, releaseFence);
     if (updateResult == BufferQueue::PRESENT_LATER) {
         // Producer doesn't want buffer to be displayed yet.  Signal a
         // layer update so we check again at the next opportunity.