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
diff --git a/libs/gui/BufferQueueProducer.cpp b/libs/gui/BufferQueueProducer.cpp
index 4ff69c5..c94c6b3 100644
--- a/libs/gui/BufferQueueProducer.cpp
+++ b/libs/gui/BufferQueueProducer.cpp
@@ -1007,14 +1007,6 @@
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 @@
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;
}