SF: Unify data types for display modes
Remove the RefreshRateConfigs::RefreshRate wrapper around DisplayMode.
Store DisplayModes as a SmallMap, so that RefreshRateConfigs uses the
same data structure for lookup by ID. Use iterators into that map for
all bookkeeping in RefreshRateConfigs.
Bug: 182939859
Bug: 185535769
Test: libsurfaceflinger_unittest
Change-Id: I7708fa997089802c45d906b17b7a073f5c82105e
diff --git a/services/surfaceflinger/Scheduler/Scheduler.cpp b/services/surfaceflinger/Scheduler/Scheduler.cpp
index 1fa455a..74d7739 100644
--- a/services/surfaceflinger/Scheduler/Scheduler.cpp
+++ b/services/surfaceflinger/Scheduler/Scheduler.cpp
@@ -166,18 +166,15 @@
impl::EventThread::GetVsyncPeriodFunction Scheduler::makeGetVsyncPeriodFunction() const {
return [this](uid_t uid) {
- const auto refreshRateConfigs = holdRefreshRateConfigs();
- nsecs_t basePeriod = refreshRateConfigs->getCurrentRefreshRate().getVsyncPeriod();
+ const Fps refreshRate = holdRefreshRateConfigs()->getActiveMode()->getFps();
+ const nsecs_t basePeriod = refreshRate.getPeriodNsecs();
+
const auto frameRate = getFrameRateOverride(uid);
if (!frameRate.has_value()) {
return basePeriod;
}
- const auto divisor =
- scheduler::RefreshRateConfigs::getFrameRateDivisor(refreshRateConfigs
- ->getCurrentRefreshRate()
- .getFps(),
- *frameRate);
+ const auto divisor = RefreshRateConfigs::getFrameRateDivisor(refreshRate, *frameRate);
if (divisor <= 1) {
return basePeriod;
}
@@ -307,7 +304,7 @@
// mode change is in progress. In that case we shouldn't dispatch an event
// as it will be dispatched when the current mode changes.
if (std::scoped_lock lock(mRefreshRateConfigsLock);
- mRefreshRateConfigs->getCurrentRefreshRate().getMode() != mPolicy.mode) {
+ mRefreshRateConfigs->getActiveMode() != mPolicy.mode) {
return;
}
@@ -422,7 +419,7 @@
}
}
-void Scheduler::resyncToHardwareVsync(bool makeAvailable, nsecs_t period) {
+void Scheduler::resyncToHardwareVsync(bool makeAvailable, Fps refreshRate) {
{
std::lock_guard<std::mutex> lock(mHWVsyncLock);
if (makeAvailable) {
@@ -434,11 +431,7 @@
}
}
- if (period <= 0) {
- return;
- }
-
- setVsyncPeriod(period);
+ setVsyncPeriod(refreshRate.getPeriodNsecs());
}
void Scheduler::resync() {
@@ -448,15 +441,17 @@
const nsecs_t last = mLastResyncTime.exchange(now);
if (now - last > kIgnoreDelay) {
- const auto vsyncPeriod = [&] {
+ const auto refreshRate = [&] {
std::scoped_lock lock(mRefreshRateConfigsLock);
- return mRefreshRateConfigs->getCurrentRefreshRate().getVsyncPeriod();
+ return mRefreshRateConfigs->getActiveMode()->getFps();
}();
- resyncToHardwareVsync(false, vsyncPeriod);
+ resyncToHardwareVsync(false, refreshRate);
}
}
void Scheduler::setVsyncPeriod(nsecs_t period) {
+ if (period <= 0) return;
+
std::lock_guard<std::mutex> lock(mHWVsyncLock);
mVsyncSchedule->getController().startPeriodTransition(period);
@@ -578,21 +573,20 @@
// TODO(145561154): cleanup the kernel idle timer implementation and the refresh rate
// magic number
- const auto refreshRate = [&] {
+ const Fps refreshRate = [&] {
std::scoped_lock lock(mRefreshRateConfigsLock);
- return mRefreshRateConfigs->getCurrentRefreshRate();
+ return mRefreshRateConfigs->getActiveMode()->getFps();
}();
constexpr Fps FPS_THRESHOLD_FOR_KERNEL_TIMER = 65_Hz;
using namespace fps_approx_ops;
- if (state == TimerState::Reset && refreshRate.getFps() > FPS_THRESHOLD_FOR_KERNEL_TIMER) {
+ if (state == TimerState::Reset && refreshRate > FPS_THRESHOLD_FOR_KERNEL_TIMER) {
// If we're not in performance mode then the kernel timer shouldn't do
// anything, as the refresh rate during DPU power collapse will be the
// same.
- resyncToHardwareVsync(true /* makeAvailable */, refreshRate.getVsyncPeriod());
- } else if (state == TimerState::Expired &&
- refreshRate.getFps() <= FPS_THRESHOLD_FOR_KERNEL_TIMER) {
+ resyncToHardwareVsync(true /* makeAvailable */, refreshRate);
+ } else if (state == TimerState::Expired && refreshRate <= FPS_THRESHOLD_FOR_KERNEL_TIMER) {
// Disable HW VSYNC if the timer expired, as we don't need it enabled if
// we're not pushing frames, and if we're in PERFORMANCE mode then we'll
// need to update the VsyncController model anyway.
@@ -693,11 +687,9 @@
}
}
if (refreshRateChanged) {
- const auto newRefreshRate = refreshRateConfigs->getRefreshRateFromModeId(newMode->getId());
-
- mSchedulerCallback.changeRefreshRate(newRefreshRate,
- consideredSignals.idle ? DisplayModeEvent::None
- : DisplayModeEvent::Changed);
+ mSchedulerCallback.requestDisplayMode(std::move(newMode),
+ consideredSignals.idle ? DisplayModeEvent::None
+ : DisplayModeEvent::Changed);
}
if (frameRateOverridesChanged) {
mSchedulerCallback.triggerOnFrameRateOverridesChanged();
@@ -715,16 +707,13 @@
if (mDisplayPowerTimer &&
(!mPolicy.isDisplayPowerStateNormal || mPolicy.displayPowerTimer == TimerState::Reset)) {
constexpr GlobalSignals kNoSignals;
- return {configs->getMaxRefreshRateByPolicy().getMode(), kNoSignals};
+ return {configs->getMaxRefreshRateByPolicy(), kNoSignals};
}
const GlobalSignals signals{.touch = mTouchTimer && mPolicy.touch == TouchState::Active,
.idle = mPolicy.idleTimer == TimerState::Expired};
- const auto [refreshRate, consideredSignals] =
- configs->getBestRefreshRate(mPolicy.contentRequirements, signals);
-
- return {refreshRate.getMode(), consideredSignals};
+ return configs->getBestRefreshRate(mPolicy.contentRequirements, signals);
}
DisplayModePtr Scheduler::getPreferredDisplayMode() {