DO NOT MERGE Extend mPreviousPresentFences for high refresh rate

To provide hardware enough time to display a frame under high refresh
rate with long sf-duration, we extend mPreviousPresentFences by storing
extra slots. We check proper present fence at different moment
according to vsync period and sf-duration.

Bug: 241193992
Bug: 361005063
Change-Id: Ibe9b06e590ed420f29c790188dee11674fca5a2e
Merged-In: Ib603c0fd29a3e4cb2fcd99dca59bbd5bfb55a787
diff --git a/services/surfaceflinger/Scheduler/include/scheduler/FrameTargeter.h b/services/surfaceflinger/Scheduler/include/scheduler/FrameTargeter.h
index d37d2dc..2c397bd 100644
--- a/services/surfaceflinger/Scheduler/include/scheduler/FrameTargeter.h
+++ b/services/surfaceflinger/Scheduler/include/scheduler/FrameTargeter.h
@@ -106,7 +106,8 @@
         FenceTimePtr fenceTime = FenceTime::NO_FENCE;
         TimePoint expectedPresentTime = TimePoint();
     };
-    std::array<FenceWithFenceTime, 2> mPresentFences;
+    // size should be longest sf-duration / shortest vsync period and round up
+    std::array<FenceWithFenceTime, 5> mPresentFences; // currently consider 166hz.
     utils::RingBuffer<FenceWithFenceTime, 5> mFenceWithFenceTimes;
 
     TimePoint mLastSignaledFrameTime;
@@ -131,6 +132,18 @@
         }
         return pastFenceTimePtr;
     }
+
+    size_t getPresentFenceShift(Period minFramePeriod) const {
+        const bool isTwoVsyncsAhead = targetsVsyncsAhead<2>(minFramePeriod);
+        size_t shift = 0;
+        if (isTwoVsyncsAhead) {
+            shift = static_cast<size_t>(expectedFrameDuration().ns() / minFramePeriod.ns());
+            if (shift >= mPresentFences.size()) {
+                shift = mPresentFences.size() - 1;
+            }
+        }
+        return shift;
+    }
 };
 
 // Computes a display's per-frame metrics about past/upcoming targeting of present deadlines.
diff --git a/services/surfaceflinger/Scheduler/src/FrameTargeter.cpp b/services/surfaceflinger/Scheduler/src/FrameTargeter.cpp
index badd21e..7036e67 100644
--- a/services/surfaceflinger/Scheduler/src/FrameTargeter.cpp
+++ b/services/surfaceflinger/Scheduler/src/FrameTargeter.cpp
@@ -30,7 +30,7 @@
 
 TimePoint FrameTarget::pastVsyncTime(Period minFramePeriod) const {
     // TODO(b/267315508): Generalize to N VSYNCs.
-    const int shift = static_cast<int>(targetsVsyncsAhead<2>(minFramePeriod));
+    const size_t shift = getPresentFenceShift(minFramePeriod);
     return mExpectedPresentTime - Period::fromNs(minFramePeriod.ns() << shift);
 }
 
@@ -38,8 +38,10 @@
     if (FlagManager::getInstance().allow_n_vsyncs_in_targeter()) {
         return pastVsyncTimePtr();
     }
-    const size_t i = static_cast<size_t>(targetsVsyncsAhead<2>(minFramePeriod));
-    return mPresentFences[i].fenceTime;
+
+    const size_t shift = getPresentFenceShift(minFramePeriod);
+    ATRACE_FORMAT("mPresentFences shift=%zu", shift);
+    return mPresentFences[shift].fenceTime;
 }
 
 bool FrameTarget::wouldPresentEarly(Period minFramePeriod) const {
@@ -151,7 +153,9 @@
     if (FlagManager::getInstance().allow_n_vsyncs_in_targeter()) {
         addFence(std::move(presentFence), presentFenceTime, mExpectedPresentTime);
     } else {
-        mPresentFences[1] = mPresentFences[0];
+        for (size_t i = mPresentFences.size()-1; i >= 1; i--) {
+            mPresentFences[i] = mPresentFences[i-1];
+        }
         mPresentFences[0] = {std::move(presentFence), presentFenceTime, mExpectedPresentTime};
     }
     return presentFenceTime;