diff options
| author | 2015-04-28 14:42:06 -0700 | |
|---|---|---|
| committer | 2015-05-01 12:23:44 -0700 | |
| commit | ecc504043fddb7a75042ce402c67aedfac04d5e2 (patch) | |
| tree | ef6b8080362a8655a3291e5757dd72d202701898 /libs/gui/BufferQueueConsumer.cpp | |
| parent | 7b2fc930077b1e6ca5946cae6834902318209474 (diff) | |
SurfaceFlinger: Fix PTS on stale buffers
SurfaceFlinger's (Layer's) shadow copy of the BufferQueue queue was
getting out of sync for a few reasons. This change fixes these by
doing the following:
- Adds a check to re-synchronize the shadow copy every time we
successfully acquire a buffer by first dropping stale buffers before
removing the current buffer.
- Avoids trying to perform updates for buffers which have been rejected
(for incorrect dimensions) by SurfaceFlinger.
- Adds IGraphicBufferConsumer::setShadowQueueSize, which allows the
consumer to notify the BufferQueue that it is maintaining a shadow
copy of the queue and prevents it from dropping so many buffers
during acquireBuffer that it ends up returning a buffer for which the
consumer has not yet received an onFrameAvailable call.
Bug: 20096136
Change-Id: I78d0738428005fc19b3be85cc8f1db498043612f
(cherry picked from commit 2e36f2283f48ab764b496490c73a132acf21df3a)
Diffstat (limited to 'libs/gui/BufferQueueConsumer.cpp')
| -rw-r--r-- | libs/gui/BufferQueueConsumer.cpp | 22 |
1 files changed, 22 insertions, 0 deletions
diff --git a/libs/gui/BufferQueueConsumer.cpp b/libs/gui/BufferQueueConsumer.cpp index c7d5e00326..2deef0e777 100644 --- a/libs/gui/BufferQueueConsumer.cpp +++ b/libs/gui/BufferQueueConsumer.cpp @@ -89,7 +89,20 @@ status_t BufferQueueConsumer::acquireBuffer(BufferItem* outBuffer, // the timestamps are being auto-generated by Surface. If the app isn't // generating timestamps explicitly, it probably doesn't want frames to // be discarded based on them. + // + // If the consumer is shadowing our queue, we also make sure that we + // don't drop so many buffers that the consumer hasn't received the + // onFrameAvailable callback for the buffer it acquires. That is, we + // want the buffer we return to be in the consumer's shadow queue. + size_t droppableBuffers = mCore->mConsumerShadowQueueSize > 1 ? + mCore->mConsumerShadowQueueSize - 1 : 0; while (mCore->mQueue.size() > 1 && !mCore->mQueue[0].mIsAutoTimestamp) { + if (mCore->mConsumerHasShadowQueue && droppableBuffers == 0) { + BQ_LOGV("acquireBuffer: no droppable buffers in consumer's" + " shadow queue, continuing"); + break; + } + // If entry[1] is timely, drop entry[0] (and repeat). We apply an // additional criterion here: we only drop the earlier buffer if our // desiredPresent falls within +/- 1 second of the expected present. @@ -124,6 +137,7 @@ status_t BufferQueueConsumer::acquireBuffer(BufferItem* outBuffer, } mCore->mQueue.erase(front); front = mCore->mQueue.begin(); + --droppableBuffers; } // See if the front buffer is due @@ -537,6 +551,14 @@ sp<NativeHandle> BufferQueueConsumer::getSidebandStream() const { return mCore->mSidebandStream; } +void BufferQueueConsumer::setShadowQueueSize(size_t size) { + ATRACE_CALL(); + BQ_LOGV("setShadowQueueSize: %zu", size); + Mutex::Autolock lock(mCore->mMutex); + mCore->mConsumerHasShadowQueue = true; + mCore->mConsumerShadowQueueSize = size; +} + void BufferQueueConsumer::dump(String8& result, const char* prefix) const { mCore->dump(result, prefix); } |