SurfaceFlinger: Consider resolution when switching refresh rate

Do not change refresh rate across configs with multiple resolutions

Bug: 150237118
Test: adb shell /data/nativetest64/libsurfaceflinger_unittest/libsurfaceflinger_unittest
Change-Id: I9b0f355a72343cf120229b98e6ad082ea75d3080
diff --git a/services/surfaceflinger/Scheduler/RefreshRateConfigs.cpp b/services/surfaceflinger/Scheduler/RefreshRateConfigs.cpp
index 14ef733..5634adb 100644
--- a/services/surfaceflinger/Scheduler/RefreshRateConfigs.cpp
+++ b/services/surfaceflinger/Scheduler/RefreshRateConfigs.cpp
@@ -53,7 +53,7 @@
     if (explicitContentFramerate != 0) {
         contentFramerate = explicitContentFramerate;
     } else if (contentFramerate == 0) {
-        contentFramerate = round<int>(mMaxSupportedRefreshRate->fps);
+        contentFramerate = round<int>(mMaxSupportedRefreshRate->getFps());
     }
     ATRACE_INT("ContentFPS", contentFramerate);
 
@@ -177,7 +177,7 @@
                 continue;
             }
 
-            const auto displayPeriod = scores[i].first->vsyncPeriod;
+            const auto displayPeriod = scores[i].first->hwcConfig->getVsyncPeriod();
             const auto layerPeriod = round<nsecs_t>(1e9f / layer.desiredRefreshRate);
             if (layer.vote == LayerVoteType::ExplicitDefault) {
                 const auto layerScore = [&]() {
@@ -309,21 +309,30 @@
     mCurrentRefreshRate = mRefreshRates.at(configId).get();
 }
 
-RefreshRateConfigs::RefreshRateConfigs(const std::vector<InputConfig>& configs,
-                                       HwcConfigIndexType currentHwcConfig) {
-    init(configs, currentHwcConfig);
-}
-
 RefreshRateConfigs::RefreshRateConfigs(
         const std::vector<std::shared_ptr<const HWC2::Display::Config>>& configs,
         HwcConfigIndexType currentConfigId) {
-    std::vector<InputConfig> inputConfigs;
-    for (size_t configId = 0; configId < configs.size(); ++configId) {
-        auto configGroup = HwcConfigGroupType(configs[configId]->getConfigGroup());
-        inputConfigs.push_back({HwcConfigIndexType(static_cast<int>(configId)), configGroup,
-                                configs[configId]->getVsyncPeriod()});
+    LOG_ALWAYS_FATAL_IF(configs.empty());
+    LOG_ALWAYS_FATAL_IF(currentConfigId.value() >= configs.size());
+
+    for (auto configId = HwcConfigIndexType(0); configId.value() < configs.size(); configId++) {
+        const auto& config = configs.at(static_cast<size_t>(configId.value()));
+        const float fps = 1e9f / config->getVsyncPeriod();
+        mRefreshRates.emplace(configId,
+                              std::make_unique<RefreshRate>(configId, config,
+                                                            base::StringPrintf("%2.ffps", fps), fps,
+                                                            RefreshRate::ConstructorTag(0)));
+        if (configId == currentConfigId) {
+            mCurrentRefreshRate = mRefreshRates.at(configId).get();
+        }
     }
-    init(inputConfigs, currentConfigId);
+
+    std::vector<const RefreshRate*> sortedConfigs;
+    getSortedRefreshRateList([](const RefreshRate&) { return true; }, &sortedConfigs);
+    mDisplayManagerPolicy.defaultConfig = currentConfigId;
+    mMinSupportedRefreshRate = sortedConfigs.front();
+    mMaxSupportedRefreshRate = sortedConfigs.back();
+    constructAvailableRefreshRates();
 }
 
 bool RefreshRateConfigs::isPolicyValid(const Policy& policy) {
@@ -406,10 +415,13 @@
 
     std::sort(outRefreshRates->begin(), outRefreshRates->end(),
               [](const auto refreshRate1, const auto refreshRate2) {
-                  if (refreshRate1->vsyncPeriod != refreshRate2->vsyncPeriod) {
-                      return refreshRate1->vsyncPeriod > refreshRate2->vsyncPeriod;
+                  if (refreshRate1->hwcConfig->getVsyncPeriod() !=
+                      refreshRate2->hwcConfig->getVsyncPeriod()) {
+                      return refreshRate1->hwcConfig->getVsyncPeriod() >
+                              refreshRate2->hwcConfig->getVsyncPeriod();
                   } else {
-                      return refreshRate1->configGroup > refreshRate2->configGroup;
+                      return refreshRate1->hwcConfig->getConfigGroup() >
+                              refreshRate2->hwcConfig->getConfigGroup();
                   }
               });
 }
@@ -417,13 +429,20 @@
 void RefreshRateConfigs::constructAvailableRefreshRates() {
     // Filter configs based on current policy and sort based on vsync period
     const Policy* policy = getCurrentPolicyLocked();
-    HwcConfigGroupType group = mRefreshRates.at(policy->defaultConfig)->configGroup;
+    const auto& defaultConfig = mRefreshRates.at(policy->defaultConfig)->hwcConfig;
     ALOGV("constructAvailableRefreshRates: default %d group %d min %.2f max %.2f",
-          policy->defaultConfig.value(), group.value(), policy->minRefreshRate,
+          policy->defaultConfig.value(), defaultConfig->getConfigGroup(), policy->minRefreshRate,
           policy->maxRefreshRate);
     getSortedRefreshRateList(
             [&](const RefreshRate& refreshRate) REQUIRES(mLock) {
-                return (policy->allowGroupSwitching || refreshRate.configGroup == group) &&
+                const auto& hwcConfig = refreshRate.hwcConfig;
+
+                return hwcConfig->getHeight() == defaultConfig->getHeight() &&
+                        hwcConfig->getWidth() == defaultConfig->getWidth() &&
+                        hwcConfig->getDpiX() == defaultConfig->getDpiX() &&
+                        hwcConfig->getDpiY() == defaultConfig->getDpiY() &&
+                        (policy->allowGroupSwitching ||
+                         hwcConfig->getConfigGroup() == defaultConfig->getConfigGroup()) &&
                         refreshRate.inPolicy(policy->minRefreshRate, policy->maxRefreshRate);
             },
             &mAvailableRefreshRates);
@@ -440,30 +459,4 @@
                         policy->maxRefreshRate);
 }
 
-// NO_THREAD_SAFETY_ANALYSIS since this is called from the constructor
-void RefreshRateConfigs::init(const std::vector<InputConfig>& configs,
-                              HwcConfigIndexType currentHwcConfig) NO_THREAD_SAFETY_ANALYSIS {
-    LOG_ALWAYS_FATAL_IF(configs.empty());
-    LOG_ALWAYS_FATAL_IF(currentHwcConfig.value() >= configs.size());
-
-    for (const auto& config : configs) {
-        const float fps = 1e9f / config.vsyncPeriod;
-        mRefreshRates.emplace(config.configId,
-                              std::make_unique<RefreshRate>(config.configId, config.vsyncPeriod,
-                                                            config.configGroup,
-                                                            base::StringPrintf("%2.ffps", fps),
-                                                            fps));
-        if (config.configId == currentHwcConfig) {
-            mCurrentRefreshRate = mRefreshRates.at(config.configId).get();
-        }
-    }
-
-    std::vector<const RefreshRate*> sortedConfigs;
-    getSortedRefreshRateList([](const RefreshRate&) { return true; }, &sortedConfigs);
-    mDisplayManagerPolicy.defaultConfig = currentHwcConfig;
-    mMinSupportedRefreshRate = sortedConfigs.front();
-    mMaxSupportedRefreshRate = sortedConfigs.back();
-    constructAvailableRefreshRates();
-}
-
 } // namespace android::scheduler