BufferQueueProducer: Throttle EGL frame production.

Throttling was previously controlled by a combination of the
driver and the number of buffers in the queue. This patch makes
a more consistent trade-off, which allows two GPU frames pending
but not three. More buffering could improve throughput in the
case of varying frame times, but this also increases latency.

Bug: 17502897
Change-Id: I4ee68019ca94c635294c5959931a555a6c4ef2df
This commit is contained in:
Eric Penner 2014-09-30 11:28:30 -07:00
parent 6c925ede62
commit 99a0afbaee
2 changed files with 17 additions and 1 deletions

View File

@ -197,6 +197,12 @@ private:
uint32_t mStickyTransform;
// This saves the fence from the last queueBuffer, such that the
// next queueBuffer call can throttle buffer production. The prior
// queueBuffer's fence is not nessessarily available elsewhere,
// since the previous buffer might have already been acquired.
sp<Fence> mLastQueueBufferFence;
}; // class BufferQueueProducer
} // namespace android

View File

@ -38,7 +38,8 @@ BufferQueueProducer::BufferQueueProducer(const sp<BufferQueueCore>& core) :
mCore(core),
mSlots(core->mSlots),
mConsumerName(),
mStickyTransform(0) {}
mStickyTransform(0),
mLastQueueBufferFence(Fence::NO_FENCE) {}
BufferQueueProducer::~BufferQueueProducer() {}
@ -644,6 +645,15 @@ status_t BufferQueueProducer::queueBuffer(int slot,
ATRACE_INT(mCore->mConsumerName.string(), mCore->mQueue.size());
} // Autolock scope
// Wait without lock held
if (mCore->mConnectedApi == NATIVE_WINDOW_API_EGL) {
// Waiting here allows for two full buffers to be queued but not a
// third. In the event that frames take varying time, this makes a
// small trade-off in favor of latency rather than throughput.
mLastQueueBufferFence->waitForever("Throttling EGL Production");
mLastQueueBufferFence = fence;
}
// Call back without lock held
if (listener != NULL) {
listener->onFrameAvailable();