diff options
| -rw-r--r-- | services/surfaceflinger/BufferQueueLayer.cpp | 21 |
1 files changed, 20 insertions, 1 deletions
diff --git a/services/surfaceflinger/BufferQueueLayer.cpp b/services/surfaceflinger/BufferQueueLayer.cpp index edfeb0bcfd..b39116ab39 100644 --- a/services/surfaceflinger/BufferQueueLayer.cpp +++ b/services/surfaceflinger/BufferQueueLayer.cpp @@ -235,9 +235,28 @@ status_t BufferQueueLayer::updateTexImage(bool& recomputeVisibleRegions, nsecs_t 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. |