[SurfaceFlinger] correct present time for negative phase offsets
DispSync::expectedPresentTime returns the expected presentation time for
the current frame, but when we're in negative offsets we are targetting
the following frame instead.
Bug: 133241520
Bug: 134589085
Test: systrace when flinging through news
Change-Id: I7cc05a0b9e8e9b5c3e8d0c4b1d59b0a7dabd43d4
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 50fabe3..dadb3fe 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -1643,6 +1643,18 @@
return fence != Fence::NO_FENCE && (fence->getStatus() == Fence::Status::Unsignaled);
}
+nsecs_t SurfaceFlinger::getExpectedPresentTime() NO_THREAD_SAFETY_ANALYSIS {
+ DisplayStatInfo stats;
+ mScheduler->getDisplayStatInfo(&stats);
+ const nsecs_t presentTime = mScheduler->expectedPresentTime();
+ // Inflate the expected present time if we're targetting the next vsync.
+ const nsecs_t correctedTime =
+ mVsyncModulator.getOffsets().sf < mPhaseOffsets->getOffsetThresholdForNextVsync()
+ ? presentTime
+ : presentTime + stats.vsyncPeriod;
+ return correctedTime;
+}
+
void SurfaceFlinger::onMessageReceived(int32_t what) NO_THREAD_SAFETY_ANALYSIS {
ATRACE_CALL();
switch (what) {
@@ -3244,8 +3256,7 @@
mDrawingState.traverseInZOrder([&](Layer* layer) {
if (layer->hasReadyFrame()) {
frameQueued = true;
- nsecs_t expectedPresentTime;
- expectedPresentTime = mScheduler->expectedPresentTime();
+ const nsecs_t expectedPresentTime = getExpectedPresentTime();
if (layer->shouldPresentNow(expectedPresentTime)) {
mLayersWithQueuedFrames.push_back(layer);
} else {