From a5da6fe761fc65a8cfac87ae1bee0cd6ed380da9 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 Merged-In: 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 c96a2dd6a3..9d7f14cb6e 100644 --- a/libs/gui/BufferQueueProducer.cpp +++ b/libs/gui/BufferQueueProducer.cpp @@ -989,14 +989,6 @@ status_t BufferQueueProducer::queueBuffer(int slot, mCallbackCondition.broadcast(); } - // 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 = { @@ -1008,6 +1000,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