SF: use peak refresh rate for HWC backpressure
The logic we have for selecting which fence to use to detect
backpressure replies on the assumption that continuously presents as
the rate of vsync. This is not true for VRR displays.
Bug: 296635687
Test: adb root && adb shell service call SurfaceFlinger 1045 f 0.9
Change-Id: Iaceb45741fd657b8c551f51b3c76a643df116da8
diff --git a/services/surfaceflinger/Scheduler/src/FrameTargeter.cpp b/services/surfaceflinger/Scheduler/src/FrameTargeter.cpp
index 7a18654..e80372b 100644
--- a/services/surfaceflinger/Scheduler/src/FrameTargeter.cpp
+++ b/services/surfaceflinger/Scheduler/src/FrameTargeter.cpp
@@ -27,28 +27,28 @@
mHwcFrameMissed("PrevHwcFrameMissed " + displayLabel, false),
mGpuFrameMissed("PrevGpuFrameMissed " + displayLabel, false) {}
-TimePoint FrameTarget::pastVsyncTime(Period vsyncPeriod) const {
+TimePoint FrameTarget::pastVsyncTime(Period minFramePeriod) const {
// TODO(b/267315508): Generalize to N VSYNCs.
- const int shift = static_cast<int>(targetsVsyncsAhead<2>(vsyncPeriod));
- return mExpectedPresentTime - Period::fromNs(vsyncPeriod.ns() << shift);
+ const int shift = static_cast<int>(targetsVsyncsAhead<2>(minFramePeriod));
+ return mExpectedPresentTime - Period::fromNs(minFramePeriod.ns() << shift);
}
-const FenceTimePtr& FrameTarget::presentFenceForPastVsync(Period vsyncPeriod) const {
+const FenceTimePtr& FrameTarget::presentFenceForPastVsync(Period minFramePeriod) const {
// TODO(b/267315508): Generalize to N VSYNCs.
- const size_t i = static_cast<size_t>(targetsVsyncsAhead<2>(vsyncPeriod));
+ const size_t i = static_cast<size_t>(targetsVsyncsAhead<2>(minFramePeriod));
return mPresentFences[i].fenceTime;
}
-bool FrameTarget::wouldPresentEarly(Period vsyncPeriod) const {
+bool FrameTarget::wouldPresentEarly(Period minFramePeriod) const {
// TODO(b/241285475): Since this is called during `composite`, the calls to `targetsVsyncsAhead`
// should use `TimePoint::now()` in case of delays since `mFrameBeginTime`.
// TODO(b/267315508): Generalize to N VSYNCs.
- if (targetsVsyncsAhead<3>(vsyncPeriod)) {
+ if (targetsVsyncsAhead<3>(minFramePeriod)) {
return true;
}
- const auto fence = presentFenceForPastVsync(vsyncPeriod);
+ const auto fence = presentFenceForPastVsync(minFramePeriod);
return fence->isValid() && fence->getSignalTime() != Fence::SIGNAL_TIME_PENDING;
}
@@ -68,6 +68,7 @@
mScheduledPresentTime = args.expectedVsyncTime;
const Period vsyncPeriod = vsyncSource.period();
+ const Period minFramePeriod = vsyncSource.minFramePeriod();
// Calculate the expected present time once and use the cached value throughout this frame to
// make sure all layers are seeing this same value.
@@ -85,7 +86,7 @@
ticks<std::milli, float>(mExpectedPresentTime - TimePoint::now()),
mExpectedPresentTime == args.expectedVsyncTime ? "" : " (adjusted)");
- const FenceTimePtr& pastPresentFence = presentFenceForPastVsync(vsyncPeriod);
+ const FenceTimePtr& pastPresentFence = presentFenceForPastVsync(minFramePeriod);
// In cases where the present fence is about to fire, give it a small grace period instead of
// giving up on the frame.