Switch from allowed display configs to refresh rate range
This completes the recent work to switch from a list of allowed display
configs to a default config + min/max frame rate.
Bug: 142507213
Test: Ran on a device with refresh rate switching, confirmed expected
60/90 switching behavior when touching the screen.
Test: Launched Google Maps on a device with 60/90 switching, confirmed
the device stays at 60fps.
Test: Checked dumpsys output, confirmed new display config specs
formatting looks good.
Test: Ran on a device with refresh rate switching disallowed via the
ro.surface_flinger.refresh_rate_switching sysprop, and confirmed
we don't do refresh rate switching.
Test: Ran on a device that doesn't support refresh rate switching, and
confirmed normal behavior.
Test: Tested surface flinger's display config back door, confirmed it
still works.
Test: Inspected log output, made sure there's nothing weird.
Test: Ran unit tests for DisplayModeDirector, LocalDisplayAdapter, and
RefreshRateConfigs.
Test: atest FrameworksServicesTests
Test: atest FrameworksMockingServicesTests
Test: adb shell /data/nativetest64/libgui_test/libgui_test
Test: adb shell /data/nativetest64/libsurfaceflinger_unittest/libsurfaceflinger_unittest
Change-Id: I53743a437bce1e3df79539caece0c423051c80a6
diff --git a/services/surfaceflinger/Scheduler/RefreshRateConfigs.cpp b/services/surfaceflinger/Scheduler/RefreshRateConfigs.cpp
index 23fb96a..847e20c 100644
--- a/services/surfaceflinger/Scheduler/RefreshRateConfigs.cpp
+++ b/services/surfaceflinger/Scheduler/RefreshRateConfigs.cpp
@@ -110,13 +110,48 @@
init(inputConfigs, currentConfigId);
}
-void RefreshRateConfigs::setPolicy(HwcConfigIndexType defaultConfigId, float minRefreshRate,
- float maxRefreshRate) {
+status_t RefreshRateConfigs::setPolicy(HwcConfigIndexType defaultConfigId, float minRefreshRate,
+ float maxRefreshRate, bool* outPolicyChanged) {
std::lock_guard lock(mLock);
- mCurrentGroupId = mRefreshRates.at(defaultConfigId).configGroup;
+ bool policyChanged = defaultConfigId != mDefaultConfig ||
+ minRefreshRate != mMinRefreshRateFps || maxRefreshRate != mMaxRefreshRateFps;
+ if (outPolicyChanged) {
+ *outPolicyChanged = policyChanged;
+ }
+ if (!policyChanged) {
+ return NO_ERROR;
+ }
+ // defaultConfigId must be a valid config ID, and within the given refresh rate range.
+ if (mRefreshRates.count(defaultConfigId) == 0) {
+ return BAD_VALUE;
+ }
+ const RefreshRate& refreshRate = mRefreshRates.at(defaultConfigId);
+ if (refreshRate.fps < minRefreshRate || refreshRate.fps > maxRefreshRate) {
+ return BAD_VALUE;
+ }
+ mDefaultConfig = defaultConfigId;
mMinRefreshRateFps = minRefreshRate;
mMaxRefreshRateFps = maxRefreshRate;
constructAvailableRefreshRates();
+ return NO_ERROR;
+}
+
+void RefreshRateConfigs::getPolicy(HwcConfigIndexType* defaultConfigId, float* minRefreshRate,
+ float* maxRefreshRate) const {
+ std::lock_guard lock(mLock);
+ *defaultConfigId = mDefaultConfig;
+ *minRefreshRate = mMinRefreshRateFps;
+ *maxRefreshRate = mMaxRefreshRateFps;
+}
+
+bool RefreshRateConfigs::isConfigAllowed(HwcConfigIndexType config) const {
+ std::lock_guard lock(mLock);
+ for (const RefreshRate* refreshRate : mAvailableRefreshRates) {
+ if (refreshRate->configId == config) {
+ return true;
+ }
+ }
+ return false;
}
void RefreshRateConfigs::getSortedRefreshRateList(
@@ -140,15 +175,18 @@
void RefreshRateConfigs::constructAvailableRefreshRates() {
// Filter configs based on current policy and sort based on vsync period
- ALOGV("constructRefreshRateMap: group %d min %.2f max %.2f", mCurrentGroupId.value(),
- mMinRefreshRateFps, mMaxRefreshRateFps);
+ HwcConfigGroupType group = mRefreshRates.at(mDefaultConfig).configGroup;
+ ALOGV("constructRefreshRateMap: default %d group %d min %.2f max %.2f", mDefaultConfig.value(),
+ group.value(), mMinRefreshRateFps, mMaxRefreshRateFps);
getSortedRefreshRateList(
- [this](const RefreshRate& refreshRate) REQUIRES(mLock) {
- return refreshRate.configGroup == mCurrentGroupId &&
- refreshRate.fps >= mMinRefreshRateFps &&
+ [&](const RefreshRate& refreshRate) REQUIRES(mLock) {
+ return refreshRate.configGroup == group && refreshRate.fps >= mMinRefreshRateFps &&
refreshRate.fps <= mMaxRefreshRateFps;
},
&mAvailableRefreshRates);
+ LOG_ALWAYS_FATAL_IF(mAvailableRefreshRates.empty(),
+ "No compatible display configs for default=%d min=%.0f max=%.0f",
+ mDefaultConfig.value(), mMinRefreshRateFps, mMaxRefreshRateFps);
}
// NO_THREAD_SAFETY_ANALYSIS since this is called from the constructor
@@ -167,12 +205,12 @@
mRefreshRates.emplace(config.configId, buildRefreshRate(config));
if (config.configId == currentHwcConfig) {
mCurrentRefreshRate = &mRefreshRates.at(config.configId);
- mCurrentGroupId = config.configGroup;
}
}
std::vector<const RefreshRate*> sortedConfigs;
getSortedRefreshRateList([](const RefreshRate&) { return true; }, &sortedConfigs);
+ mDefaultConfig = currentHwcConfig;
mMinSupportedRefreshRate = sortedConfigs.front();
mMaxSupportedRefreshRate = sortedConfigs.back();
constructAvailableRefreshRates();
diff --git a/services/surfaceflinger/Scheduler/RefreshRateConfigs.h b/services/surfaceflinger/Scheduler/RefreshRateConfigs.h
index fb14dc7..1e740ca 100644
--- a/services/surfaceflinger/Scheduler/RefreshRateConfigs.h
+++ b/services/surfaceflinger/Scheduler/RefreshRateConfigs.h
@@ -73,9 +73,17 @@
using AllRefreshRatesMapType = std::unordered_map<HwcConfigIndexType, const RefreshRate>;
- // Sets the current policy to choose refresh rates.
- void setPolicy(HwcConfigIndexType defaultConfigId, float minRefreshRate, float maxRefreshRate)
- EXCLUDES(mLock);
+ // Sets the current policy to choose refresh rates. Returns NO_ERROR if the requested policy is
+ // valid, or a negative error value otherwise. policyChanged, if non-null, will be set to true
+ // if the new policy is different from the old policy.
+ status_t setPolicy(HwcConfigIndexType defaultConfigId, float minRefreshRate,
+ float maxRefreshRate, bool* policyChanged) EXCLUDES(mLock);
+ // Gets the current policy.
+ void getPolicy(HwcConfigIndexType* defaultConfigId, float* minRefreshRate,
+ float* maxRefreshRate) const EXCLUDES(mLock);
+
+ // Returns true if config is allowed by the current policy.
+ bool isConfigAllowed(HwcConfigIndexType config) const EXCLUDES(mLock);
// Returns true if this device is doing refresh rate switching. This won't change at runtime.
bool refreshRateSwitchingSupported() const { return mRefreshRateSwitching; }
@@ -143,9 +151,9 @@
// the main thread, and read by the Scheduler (and other objects) on other threads.
const RefreshRate* mCurrentRefreshRate GUARDED_BY(mLock);
- // The current config group. This will change at runtime. This is set by SurfaceFlinger on
+ // The default config. This will change at runtime. This is set by SurfaceFlinger on
// the main thread, and read by the Scheduler (and other objects) on other threads.
- HwcConfigGroupType mCurrentGroupId GUARDED_BY(mLock);
+ HwcConfigIndexType mDefaultConfig GUARDED_BY(mLock);
// The min and max FPS allowed by the policy. This will change at runtime and set by
// SurfaceFlinger on the main thread.