SF: Match followers' refresh rate to pacesetter's
Multi-display refresh rate selection was flawed: The scheduler runs the
refresh rate selection algorithm for each display, and then filters the
candidate modes of each follower to match the pacesetter's refresh rate.
This means that:
1. The followers incorrectly consider refresh rates that don't match the
pacesetter. Because the DM-specified constraint is [59, 61] Hz, some
situations caused selection of a fractional rate (e.g. 59.94) instead
of 60 on certain external displays. The result would be black screens
for several seconds due to mode sets if the selection was not stable.
2. The followers incorrectly evaluate heuristics that should only affect
the pacesetter, e.g. per-surface votes, global signals.
Fix this by teaching RefreshRateSelector about follower displays.
Foldables also benefit from no longer running the algorithm twice.
Fixes: 324188430
Bug: 329111930
Test: No black screen for 4 seconds upon rotating mirrored YouTube.
Test: 60+60 still works on foldables.
Test: RefreshRateSelectorTest.pacesetterConsidered
Change-Id: Ie1b27e81d860a709c85651f068fedb2b496861de
diff --git a/services/surfaceflinger/Scheduler/Scheduler.h b/services/surfaceflinger/Scheduler/Scheduler.h
index 494a91b..c408a56 100644
--- a/services/surfaceflinger/Scheduler/Scheduler.h
+++ b/services/surfaceflinger/Scheduler/Scheduler.h
@@ -402,6 +402,11 @@
DisplayModeChoice(FrameRateMode mode, GlobalSignals consideredSignals)
: mode(std::move(mode)), consideredSignals(consideredSignals) {}
+ static DisplayModeChoice from(RefreshRateSelector::RankedFrameRates rankedFrameRates) {
+ return {rankedFrameRates.ranking.front().frameRateMode,
+ rankedFrameRates.consideredSignals};
+ }
+
FrameRateMode mode;
GlobalSignals consideredSignals;