[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/BufferQueueLayer.cpp b/services/surfaceflinger/BufferQueueLayer.cpp
index bd0b55f..57f1008 100644
--- a/services/surfaceflinger/BufferQueueLayer.cpp
+++ b/services/surfaceflinger/BufferQueueLayer.cpp
@@ -143,7 +143,7 @@
     }
 
     Mutex::Autolock lock(mQueueItemLock);
-    return mQueueItems[0].mTimestamp <= mFlinger->mScheduler->expectedPresentTime();
+    return mQueueItems[0].mTimestamp <= mFlinger->getExpectedPresentTime();
 }
 
 nsecs_t BufferQueueLayer::getDesiredPresentTime() {
diff --git a/services/surfaceflinger/BufferStateLayer.cpp b/services/surfaceflinger/BufferStateLayer.cpp
index 05c721f..203bd72 100644
--- a/services/surfaceflinger/BufferStateLayer.cpp
+++ b/services/surfaceflinger/BufferStateLayer.cpp
@@ -380,7 +380,7 @@
         return true;
     }
 
-    return mDesiredPresentTime <= mFlinger->mScheduler->expectedPresentTime();
+    return mDesiredPresentTime <= mFlinger->getExpectedPresentTime();
 }
 
 nsecs_t BufferStateLayer::getDesiredPresentTime() {
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 {
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index 74fefa7..3d98ec1 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -298,6 +298,11 @@
     // TODO: this should be made accessible only to MessageQueue
     void onMessageReceived(int32_t what);
 
+    // Returns the expected present time for this frame.
+    // When we are in negative offsets, we perform a correction so that the
+    // predicted vsync for the *next* frame is used instead.
+    nsecs_t getExpectedPresentTime();
+
     // for debugging only
     // TODO: this should be made accessible only to HWComposer
     const Vector<sp<Layer>>& getLayerSortedByZForHwcDisplay(DisplayId displayId);