SF: do not skip a frame if it will not cause backpressure on dvrr

Bug: 340633280
Test: android.platform.test.scenario.sysui.people.PeopleSpaceActivityMicrobenchmark#startPeopleSpaceActivity
Change-Id: If230ef0ab2f8ac3846e4e3701e51d1821192548c
diff --git a/services/surfaceflinger/Scheduler/VSyncPredictor.cpp b/services/surfaceflinger/Scheduler/VSyncPredictor.cpp
index 0b47924..85ce713 100644
--- a/services/surfaceflinger/Scheduler/VSyncPredictor.cpp
+++ b/services/surfaceflinger/Scheduler/VSyncPredictor.cpp
@@ -650,29 +650,33 @@
     const auto threshold = model.slope / 2;
     const auto lastFrameMissed =
             lastVsyncOpt && std::abs(*lastVsyncOpt - missedVsync.vsync.ns()) < threshold;
-    if (FlagManager::getInstance().vrr_config() && lastFrameMissed) {
-        // If the last frame missed is the last vsync, we already shifted the timeline. Depends on
-        // whether we skipped the frame (onFrameMissed) or not (onFrameBegin) we apply a different
-        // fixup. There is no need to to shift the vsync timeline again.
-        vsyncTime += missedVsync.fixup.ns();
-        ATRACE_FORMAT_INSTANT("lastFrameMissed");
-    } else if (FlagManager::getInstance().vrr_config() && minFramePeriodOpt && mRenderRateOpt &&
-               lastVsyncOpt) {
-        // lastVsyncOpt is based on the old timeline before we shifted it. we should correct it
-        // first before trying to use it.
-        lastVsyncOpt = snapToVsyncAlignedWithRenderRate(model, *lastVsyncOpt);
-        const auto vsyncDiff = vsyncTime - *lastVsyncOpt;
-        if (vsyncDiff <= minFramePeriodOpt->ns() - threshold) {
-            // avoid a duplicate vsync
-            ATRACE_FORMAT_INSTANT("skipping a vsync to avoid duplicate frame. next in %.2f which "
-                                  "is %.2f "
-                                  "from "
-                                  "prev. "
-                                  "adjust by %.2f",
-                                  static_cast<float>(vsyncTime - TimePoint::now().ns()) / 1e6f,
-                                  static_cast<float>(vsyncDiff) / 1e6f,
-                                  static_cast<float>(mRenderRateOpt->getPeriodNsecs()) / 1e6f);
-            vsyncTime += mRenderRateOpt->getPeriodNsecs();
+    const auto mightBackpressure = minFramePeriodOpt && mRenderRateOpt &&
+            mRenderRateOpt->getPeriod() < 2 * (*minFramePeriodOpt);
+    if (FlagManager::getInstance().vrr_config()) {
+        if (lastFrameMissed) {
+            // If the last frame missed is the last vsync, we already shifted the timeline. Depends
+            // on whether we skipped the frame (onFrameMissed) or not (onFrameBegin) we apply a
+            // different fixup. There is no need to to shift the vsync timeline again.
+            vsyncTime += missedVsync.fixup.ns();
+            ATRACE_FORMAT_INSTANT("lastFrameMissed");
+        } else if (mightBackpressure && lastVsyncOpt) {
+            // lastVsyncOpt is based on the old timeline before we shifted it. we should correct it
+            // first before trying to use it.
+            lastVsyncOpt = snapToVsyncAlignedWithRenderRate(model, *lastVsyncOpt);
+            const auto vsyncDiff = vsyncTime - *lastVsyncOpt;
+            if (vsyncDiff <= minFramePeriodOpt->ns() - threshold) {
+                // avoid a duplicate vsync
+                ATRACE_FORMAT_INSTANT("skipping a vsync to avoid duplicate frame. next in %.2f "
+                                      "which "
+                                      "is %.2f "
+                                      "from "
+                                      "prev. "
+                                      "adjust by %.2f",
+                                      static_cast<float>(vsyncTime - TimePoint::now().ns()) / 1e6f,
+                                      static_cast<float>(vsyncDiff) / 1e6f,
+                                      static_cast<float>(mRenderRateOpt->getPeriodNsecs()) / 1e6f);
+                vsyncTime += mRenderRateOpt->getPeriodNsecs();
+            }
         }
     }