From cb7dd008877ec881dc25d7c941bda802a0b467ff Mon Sep 17 00:00:00 2001 From: Yiwei Zhang Date: Tue, 16 Apr 2019 11:03:01 -0700 Subject: TimeStats: fix a racing case setPostTime is plumbed without BufferQueue lock, and it's called at the end of queueBuffer. If the addAndGetFrameTimestamps is delayed by queueBuffer back pressure (this could happen on special SF/BQ configs), setAcquireFence will be called with a out-of-bound index internally. So this change will tweak the order of the back Pressure logic to make the post time correct when queueBuffer back pressure happens as well as guarding the TimeStats more strictly. Bug: 130515827 Test: all SurfaceFlinger tests Change-Id: I2eace6d8693cc647284de0f33e7b58a6bf79eaaf --- libs/gui/BufferQueueProducer.cpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'libs/gui/BufferQueueProducer.cpp') diff --git a/libs/gui/BufferQueueProducer.cpp b/libs/gui/BufferQueueProducer.cpp index 4ff69c57ce..c94c6b31c6 100644 --- a/libs/gui/BufferQueueProducer.cpp +++ b/libs/gui/BufferQueueProducer.cpp @@ -1007,14 +1007,6 @@ status_t BufferQueueProducer::queueBuffer(int slot, mCallbackCondition.notify_all(); } - // Wait without lock held - if (connectedApi == 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. - lastQueuedFence->waitForever("Throttling EGL Production"); - } - // Update and get FrameEventHistory. nsecs_t postedTime = systemTime(SYSTEM_TIME_MONOTONIC); NewFrameEventsEntry newFrameEventsEntry = { @@ -1026,6 +1018,14 @@ status_t BufferQueueProducer::queueBuffer(int slot, addAndGetFrameTimestamps(&newFrameEventsEntry, getFrameTimestamps ? &output->frameTimestamps : nullptr); + // Wait without lock held + if (connectedApi == 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. + lastQueuedFence->waitForever("Throttling EGL Production"); + } + return NO_ERROR; } -- cgit v1.2.3-59-g8ed1b