SurfaceFlinger: fix early latching of buffers
Use the FrameTimeline::SurfaceFrame predicted present time
to avoid latching a buffer too early (i.e. before the time
SurfaceFlinger planned to latch this buffer when the app requested
a vsync callback).
Bug: 169901895
Test: expand notification shade and observe systrace
Change-Id: I823546992c89f88c0c29b839ce21c79ff1ffcfbd
diff --git a/services/surfaceflinger/BufferLayer.cpp b/services/surfaceflinger/BufferLayer.cpp
index fa75ffa..6561707 100644
--- a/services/surfaceflinger/BufferLayer.cpp
+++ b/services/surfaceflinger/BufferLayer.cpp
@@ -389,6 +389,20 @@
mBufferInfo.mFrameLatencyNeeded = true;
}
+bool BufferLayer::frameIsEarly(nsecs_t expectedPresentTime) const {
+ // TODO(b/169901895): kEarlyLatchVsyncThreshold should be based on the
+ // vsync period. We can do this change as soon as ag/13100772 is merged.
+ constexpr static std::chrono::nanoseconds kEarlyLatchVsyncThreshold = 5ms;
+
+ const auto presentTime = nextPredictedPresentTime();
+ if (std::abs(presentTime - expectedPresentTime) >= kEarlyLatchMaxThreshold.count()) {
+ return false;
+ }
+
+ return presentTime >= expectedPresentTime &&
+ presentTime - expectedPresentTime >= kEarlyLatchVsyncThreshold.count();
+}
+
bool BufferLayer::latchBuffer(bool& recomputeVisibleRegions, nsecs_t latchTime,
nsecs_t expectedPresentTime) {
ATRACE_CALL();
@@ -421,6 +435,12 @@
return false;
}
+ if (frameIsEarly(expectedPresentTime)) {
+ ATRACE_NAME("frameIsEarly()");
+ mFlinger->signalLayerUpdate();
+ return false;
+ }
+
// If the head buffer's acquire fence hasn't signaled yet, return and
// try again later
if (!fenceHasSignaled()) {