diff options
author | 2019-04-16 11:03:01 -0700 | |
---|---|---|
committer | 2019-04-16 18:27:56 +0000 | |
commit | a5da6fe761fc65a8cfac87ae1bee0cd6ed380da9 (patch) | |
tree | 9996e79f9463ddeeebded1ca9b1fa1149821bc9f /libs/gui/BufferQueueProducer.cpp | |
parent | 94c1d740cfe001e5faf62d3c447c4e1e9f4aa325 (diff) |
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
Diffstat (limited to 'libs/gui/BufferQueueProducer.cpp')
-rw-r--r-- | libs/gui/BufferQueueProducer.cpp | 16 |
1 files changed, 8 insertions, 8 deletions
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; } |