SF: Remove per-display state in scheduler
This CL removes per-display RefreshRateConfigs and AllowedDisplayConfigs
to avoid bugs in the untested multi-display code path of the scheduler,
adds checks to prevent crashes if the internal display is removed, and
cleans up related code by:
1) Replacing AllowedDisplayConfigs with a simple set.
2) Making setAllowedDisplayConfigs consistent with setPowerMode.
3) Removing unnecessary locking and allocation.
Bug: 129433906
Test: Boot with single/multiple display(s)
Change-Id: I3f59e9bdeaceb2cf48b4b9b71cd27f1d6a574680
diff --git a/services/surfaceflinger/tests/unittests/AllowedDisplayConfigsTest.cpp b/services/surfaceflinger/tests/unittests/AllowedDisplayConfigsTest.cpp
deleted file mode 100644
index 4274254..0000000
--- a/services/surfaceflinger/tests/unittests/AllowedDisplayConfigsTest.cpp
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * Copyright 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#undef LOG_TAG
-#define LOG_TAG "LibSurfaceFlingerUnittests"
-#define LOG_NDEBUG 0
-
-#include <memory>
-#include <vector>
-
-#include <gtest/gtest.h>
-
-#include <log/log.h>
-
-#include "AllowedDisplayConfigs.h"
-
-namespace android {
-namespace {
-
-class AllowedDisplayConfigsTest : public testing::Test {
-protected:
- AllowedDisplayConfigsTest();
- ~AllowedDisplayConfigsTest() override;
-
- void buildAllowedConfigs();
-
- const std::vector<int32_t> expectedConfigs = {0, 2, 7, 129};
- constexpr static int32_t notAllowedConfig = 5;
- std::unique_ptr<const AllowedDisplayConfigs> mAllowedConfigs;
-};
-
-AllowedDisplayConfigsTest::AllowedDisplayConfigsTest() {
- const ::testing::TestInfo* const test_info =
- ::testing::UnitTest::GetInstance()->current_test_info();
- ALOGD("**** Setting up for %s.%s\n", test_info->test_case_name(), test_info->name());
-}
-
-AllowedDisplayConfigsTest::~AllowedDisplayConfigsTest() {
- const ::testing::TestInfo* const test_info =
- ::testing::UnitTest::GetInstance()->current_test_info();
- ALOGD("**** Tearing down after %s.%s\n", test_info->test_case_name(), test_info->name());
-}
-
-void AllowedDisplayConfigsTest::buildAllowedConfigs() {
- AllowedDisplayConfigs::Builder builder;
- for (int config : expectedConfigs) {
- builder.addConfig(config);
- }
- mAllowedConfigs = builder.build();
-}
-
-/* ------------------------------------------------------------------------
- * Test cases
- */
-
-TEST_F(AllowedDisplayConfigsTest, checkConfigs) {
- buildAllowedConfigs();
-
- // Check that all expected configs are allowed
- for (int config : expectedConfigs) {
- EXPECT_TRUE(mAllowedConfigs->isConfigAllowed(config));
- }
-
- // Check that all the allowed configs are expected
- std::vector<int32_t> allowedConfigVector;
- mAllowedConfigs->getAllowedConfigs(&allowedConfigVector);
- EXPECT_EQ(allowedConfigVector, expectedConfigs);
-
- // Check that notAllowedConfig is indeed not allowed
- EXPECT_TRUE(std::find(expectedConfigs.begin(), expectedConfigs.end(), notAllowedConfig) ==
- expectedConfigs.end());
- EXPECT_FALSE(mAllowedConfigs->isConfigAllowed(notAllowedConfig));
-}
-
-TEST_F(AllowedDisplayConfigsTest, getAllowedConfigsNullptr) {
- buildAllowedConfigs();
-
- // No other expectations rather than no crash
- mAllowedConfigs->getAllowedConfigs(nullptr);
-}
-
-} // namespace
-} // namespace android
diff --git a/services/surfaceflinger/tests/unittests/Android.bp b/services/surfaceflinger/tests/unittests/Android.bp
index d4eac88..85e9ce5 100644
--- a/services/surfaceflinger/tests/unittests/Android.bp
+++ b/services/surfaceflinger/tests/unittests/Android.bp
@@ -35,7 +35,6 @@
srcs: [
":libsurfaceflinger_sources",
"libsurfaceflinger_unittest_main.cpp",
- "AllowedDisplayConfigsTest.cpp",
"CompositionTest.cpp",
"DispSyncSourceTest.cpp",
"DisplayIdentificationTest.cpp",
diff --git a/services/surfaceflinger/tests/unittests/RefreshRateConfigsTest.cpp b/services/surfaceflinger/tests/unittests/RefreshRateConfigsTest.cpp
index b218ad6..8b37c22 100644
--- a/services/surfaceflinger/tests/unittests/RefreshRateConfigsTest.cpp
+++ b/services/surfaceflinger/tests/unittests/RefreshRateConfigsTest.cpp
@@ -49,6 +49,8 @@
ASSERT_EQ(left.name, right.name);
ASSERT_EQ(left.fps, right.fps);
}
+
+ RefreshRateConfigs mConfigs;
};
RefreshRateConfigsTest::RefreshRateConfigsTest() {
@@ -69,10 +71,10 @@
*/
TEST_F(RefreshRateConfigsTest, zeroDeviceConfigs_storesPowerSavingConfig) {
std::vector<std::shared_ptr<const HWC2::Display::Config>> displayConfigs;
- RefreshRateConfigs configs(displayConfigs);
+ mConfigs.populate(displayConfigs);
// We always store a configuration for screen off.
- const auto& rates = configs.getRefreshRates();
+ const auto& rates = mConfigs.getRefreshRates();
ASSERT_EQ(1, rates.size());
const auto& powerSavingRate = rates.find(RefreshRateType::POWER_SAVING);
ASSERT_NE(rates.end(), powerSavingRate);
@@ -82,13 +84,13 @@
RefreshRate expectedConfig = RefreshRate{SCREEN_OFF_CONFIG_ID, "ScreenOff", 0};
assertRatesEqual(expectedConfig, *powerSavingRate->second);
- ASSERT_TRUE(configs.getRefreshRate(RefreshRateType::POWER_SAVING));
- assertRatesEqual(expectedConfig, *configs.getRefreshRate(RefreshRateType::POWER_SAVING));
- ASSERT_FALSE(configs.getRefreshRate(RefreshRateType::PERFORMANCE));
- ASSERT_FALSE(configs.getRefreshRate(RefreshRateType::DEFAULT));
+ ASSERT_TRUE(mConfigs.getRefreshRate(RefreshRateType::POWER_SAVING));
+ assertRatesEqual(expectedConfig, *mConfigs.getRefreshRate(RefreshRateType::POWER_SAVING));
+ ASSERT_FALSE(mConfigs.getRefreshRate(RefreshRateType::PERFORMANCE));
+ ASSERT_FALSE(mConfigs.getRefreshRate(RefreshRateType::DEFAULT));
// Sanity check that getRefreshRate() does not modify the underlying configs.
- ASSERT_EQ(1, configs.getRefreshRates().size());
+ ASSERT_EQ(1, mConfigs.getRefreshRates().size());
}
TEST_F(RefreshRateConfigsTest, oneDeviceConfig_storesDefaultConfig) {
@@ -97,9 +99,9 @@
auto config60 = HWC2::Display::Config::Builder(*display, CONFIG_ID_60);
config60.setVsyncPeriod(VSYNC_60);
displayConfigs.push_back(config60.build());
- RefreshRateConfigs configs(displayConfigs);
+ mConfigs.populate(displayConfigs);
- const auto& rates = configs.getRefreshRates();
+ const auto& rates = mConfigs.getRefreshRates();
ASSERT_EQ(2, rates.size());
const auto& powerSavingRate = rates.find(RefreshRateType::POWER_SAVING);
const auto& defaultRate = rates.find(RefreshRateType::DEFAULT);
@@ -112,15 +114,15 @@
RefreshRate expectedDefaultConfig = RefreshRate{CONFIG_ID_60, "60fps", 60};
assertRatesEqual(expectedDefaultConfig, *defaultRate->second);
- ASSERT_TRUE(configs.getRefreshRate(RefreshRateType::POWER_SAVING));
+ ASSERT_TRUE(mConfigs.getRefreshRate(RefreshRateType::POWER_SAVING));
assertRatesEqual(expectedPowerSavingConfig,
- *configs.getRefreshRate(RefreshRateType::POWER_SAVING));
- ASSERT_TRUE(configs.getRefreshRate(RefreshRateType::DEFAULT));
- assertRatesEqual(expectedDefaultConfig, *configs.getRefreshRate(RefreshRateType::DEFAULT));
- ASSERT_FALSE(configs.getRefreshRate(RefreshRateType::PERFORMANCE));
+ *mConfigs.getRefreshRate(RefreshRateType::POWER_SAVING));
+ ASSERT_TRUE(mConfigs.getRefreshRate(RefreshRateType::DEFAULT));
+ assertRatesEqual(expectedDefaultConfig, *mConfigs.getRefreshRate(RefreshRateType::DEFAULT));
+ ASSERT_FALSE(mConfigs.getRefreshRate(RefreshRateType::PERFORMANCE));
// Sanity check that getRefreshRate() does not modify the underlying configs.
- ASSERT_EQ(2, configs.getRefreshRates().size());
+ ASSERT_EQ(2, mConfigs.getRefreshRates().size());
}
TEST_F(RefreshRateConfigsTest, twoDeviceConfigs_storesPerformanceConfig) {
@@ -132,9 +134,9 @@
auto config90 = HWC2::Display::Config::Builder(*display, CONFIG_ID_90);
config90.setVsyncPeriod(VSYNC_90);
displayConfigs.push_back(config90.build());
- RefreshRateConfigs configs(displayConfigs);
+ mConfigs.populate(displayConfigs);
- const auto& rates = configs.getRefreshRates();
+ const auto& rates = mConfigs.getRefreshRates();
ASSERT_EQ(3, rates.size());
const auto& powerSavingRate = rates.find(RefreshRateType::POWER_SAVING);
const auto& defaultRate = rates.find(RefreshRateType::DEFAULT);
@@ -150,14 +152,14 @@
RefreshRate expectedPerformanceConfig = RefreshRate{CONFIG_ID_90, "90fps", 90};
assertRatesEqual(expectedPerformanceConfig, *performanceRate->second);
- ASSERT_TRUE(configs.getRefreshRate(RefreshRateType::POWER_SAVING));
+ ASSERT_TRUE(mConfigs.getRefreshRate(RefreshRateType::POWER_SAVING));
assertRatesEqual(expectedPowerSavingConfig,
- *configs.getRefreshRate(RefreshRateType::POWER_SAVING));
- ASSERT_TRUE(configs.getRefreshRate(RefreshRateType::DEFAULT));
- assertRatesEqual(expectedDefaultConfig, *configs.getRefreshRate(RefreshRateType::DEFAULT));
- ASSERT_TRUE(configs.getRefreshRate(RefreshRateType::PERFORMANCE));
+ *mConfigs.getRefreshRate(RefreshRateType::POWER_SAVING));
+ ASSERT_TRUE(mConfigs.getRefreshRate(RefreshRateType::DEFAULT));
+ assertRatesEqual(expectedDefaultConfig, *mConfigs.getRefreshRate(RefreshRateType::DEFAULT));
+ ASSERT_TRUE(mConfigs.getRefreshRate(RefreshRateType::PERFORMANCE));
assertRatesEqual(expectedPerformanceConfig,
- *configs.getRefreshRate(RefreshRateType::PERFORMANCE));
+ *mConfigs.getRefreshRate(RefreshRateType::PERFORMANCE));
}
} // namespace
} // namespace scheduler
diff --git a/services/surfaceflinger/tests/unittests/RefreshRateStatsTest.cpp b/services/surfaceflinger/tests/unittests/RefreshRateStatsTest.cpp
index 10f5af8..411ec61 100644
--- a/services/surfaceflinger/tests/unittests/RefreshRateStatsTest.cpp
+++ b/services/surfaceflinger/tests/unittests/RefreshRateStatsTest.cpp
@@ -42,11 +42,9 @@
RefreshRateStatsTest();
~RefreshRateStatsTest();
- void init(std::vector<std::shared_ptr<const HWC2::Display::Config>> configs);
-
- std::unique_ptr<RefreshRateStats> mRefreshRateStats;
- std::shared_ptr<android::mock::TimeStats> mTimeStats;
- std::shared_ptr<RefreshRateConfigs> mRefreshRateConfigs;
+ mock::TimeStats mTimeStats;
+ RefreshRateConfigs mRefreshRateConfigs;
+ RefreshRateStats mRefreshRateStats{mRefreshRateConfigs, mTimeStats};
};
RefreshRateStatsTest::RefreshRateStatsTest() {
@@ -61,22 +59,16 @@
ALOGD("**** Tearing down after %s.%s\n", test_info->test_case_name(), test_info->name());
}
-void RefreshRateStatsTest::init(std::vector<std::shared_ptr<const HWC2::Display::Config>> configs) {
- mTimeStats = std::make_shared<android::mock::TimeStats>();
- mRefreshRateConfigs = std::make_shared<RefreshRateConfigs>(configs);
- mRefreshRateStats = std::make_unique<RefreshRateStats>(mRefreshRateConfigs, mTimeStats);
-}
-
namespace {
/* ------------------------------------------------------------------------
* Test cases
*/
TEST_F(RefreshRateStatsTest, canCreateAndDestroyTest) {
std::vector<std::shared_ptr<const HWC2::Display::Config>> configs;
- init(configs);
+ mRefreshRateConfigs.populate(configs);
// There is one default config, so the refresh rates should have one item.
- EXPECT_EQ(1, mRefreshRateStats->getTotalTimes().size());
+ EXPECT_EQ(1, mRefreshRateStats.getTotalTimes().size());
}
TEST_F(RefreshRateStatsTest, oneConfigTest) {
@@ -87,12 +79,12 @@
std::vector<std::shared_ptr<const HWC2::Display::Config>> configs;
configs.push_back(config.build());
- init(configs);
+ mRefreshRateConfigs.populate(configs);
- EXPECT_CALL(*mTimeStats, recordRefreshRate(0, _)).Times(AtLeast(1));
- EXPECT_CALL(*mTimeStats, recordRefreshRate(90, _)).Times(AtLeast(1));
+ EXPECT_CALL(mTimeStats, recordRefreshRate(0, _)).Times(AtLeast(1));
+ EXPECT_CALL(mTimeStats, recordRefreshRate(90, _)).Times(AtLeast(1));
- std::unordered_map<std::string, int64_t> times = mRefreshRateStats->getTotalTimes();
+ std::unordered_map<std::string, int64_t> times = mRefreshRateStats.getTotalTimes();
EXPECT_EQ(2, times.size());
EXPECT_NE(0u, times.count("ScreenOff"));
EXPECT_EQ(1u, times.count("90fps"));
@@ -105,29 +97,29 @@
// Screen is off by default.
std::this_thread::sleep_for(std::chrono::milliseconds(2));
- times = mRefreshRateStats->getTotalTimes();
+ times = mRefreshRateStats.getTotalTimes();
EXPECT_LT(screenOff, times["ScreenOff"]);
EXPECT_EQ(0, times["90fps"]);
- mRefreshRateStats->setConfigMode(CONFIG_ID_90);
- mRefreshRateStats->setPowerMode(HWC_POWER_MODE_NORMAL);
- screenOff = mRefreshRateStats->getTotalTimes()["ScreenOff"];
+ mRefreshRateStats.setConfigMode(CONFIG_ID_90);
+ mRefreshRateStats.setPowerMode(HWC_POWER_MODE_NORMAL);
+ screenOff = mRefreshRateStats.getTotalTimes()["ScreenOff"];
std::this_thread::sleep_for(std::chrono::milliseconds(2));
- times = mRefreshRateStats->getTotalTimes();
+ times = mRefreshRateStats.getTotalTimes();
EXPECT_EQ(screenOff, times["ScreenOff"]);
EXPECT_LT(ninety, times["90fps"]);
- mRefreshRateStats->setPowerMode(HWC_POWER_MODE_DOZE);
- ninety = mRefreshRateStats->getTotalTimes()["90fps"];
+ mRefreshRateStats.setPowerMode(HWC_POWER_MODE_DOZE);
+ ninety = mRefreshRateStats.getTotalTimes()["90fps"];
std::this_thread::sleep_for(std::chrono::milliseconds(2));
- times = mRefreshRateStats->getTotalTimes();
+ times = mRefreshRateStats.getTotalTimes();
EXPECT_LT(screenOff, times["ScreenOff"]);
EXPECT_EQ(ninety, times["90fps"]);
- mRefreshRateStats->setConfigMode(CONFIG_ID_90);
- screenOff = mRefreshRateStats->getTotalTimes()["ScreenOff"];
+ mRefreshRateStats.setConfigMode(CONFIG_ID_90);
+ screenOff = mRefreshRateStats.getTotalTimes()["ScreenOff"];
std::this_thread::sleep_for(std::chrono::milliseconds(2));
- times = mRefreshRateStats->getTotalTimes();
+ times = mRefreshRateStats.getTotalTimes();
// Because the power mode is not HWC_POWER_MODE_NORMAL, switching the config
// does not update refresh rates that come from the config.
EXPECT_LT(screenOff, times["ScreenOff"]);
@@ -146,13 +138,13 @@
config60.setVsyncPeriod(VSYNC_60);
configs.push_back(config60.build());
- init(configs);
+ mRefreshRateConfigs.populate(configs);
- EXPECT_CALL(*mTimeStats, recordRefreshRate(0, _)).Times(AtLeast(1));
- EXPECT_CALL(*mTimeStats, recordRefreshRate(60, _)).Times(AtLeast(1));
- EXPECT_CALL(*mTimeStats, recordRefreshRate(90, _)).Times(AtLeast(1));
+ EXPECT_CALL(mTimeStats, recordRefreshRate(0, _)).Times(AtLeast(1));
+ EXPECT_CALL(mTimeStats, recordRefreshRate(60, _)).Times(AtLeast(1));
+ EXPECT_CALL(mTimeStats, recordRefreshRate(90, _)).Times(AtLeast(1));
- std::unordered_map<std::string, int64_t> times = mRefreshRateStats->getTotalTimes();
+ std::unordered_map<std::string, int64_t> times = mRefreshRateStats.getTotalTimes();
EXPECT_EQ(3, times.size());
EXPECT_NE(0u, times.count("ScreenOff"));
EXPECT_EQ(1u, times.count("60fps"));
@@ -168,60 +160,60 @@
// Screen is off by default.
std::this_thread::sleep_for(std::chrono::milliseconds(2));
- times = mRefreshRateStats->getTotalTimes();
+ times = mRefreshRateStats.getTotalTimes();
EXPECT_LT(screenOff, times["ScreenOff"]);
EXPECT_EQ(sixty, times["60fps"]);
EXPECT_EQ(ninety, times["90fps"]);
- mRefreshRateStats->setConfigMode(CONFIG_ID_90);
- mRefreshRateStats->setPowerMode(HWC_POWER_MODE_NORMAL);
- screenOff = mRefreshRateStats->getTotalTimes()["ScreenOff"];
+ mRefreshRateStats.setConfigMode(CONFIG_ID_90);
+ mRefreshRateStats.setPowerMode(HWC_POWER_MODE_NORMAL);
+ screenOff = mRefreshRateStats.getTotalTimes()["ScreenOff"];
std::this_thread::sleep_for(std::chrono::milliseconds(2));
- times = mRefreshRateStats->getTotalTimes();
+ times = mRefreshRateStats.getTotalTimes();
EXPECT_EQ(screenOff, times["ScreenOff"]);
EXPECT_EQ(sixty, times["60fps"]);
EXPECT_LT(ninety, times["90fps"]);
// When power mode is normal, time for configs updates.
- mRefreshRateStats->setConfigMode(CONFIG_ID_60);
- ninety = mRefreshRateStats->getTotalTimes()["90fps"];
+ mRefreshRateStats.setConfigMode(CONFIG_ID_60);
+ ninety = mRefreshRateStats.getTotalTimes()["90fps"];
std::this_thread::sleep_for(std::chrono::milliseconds(2));
- times = mRefreshRateStats->getTotalTimes();
+ times = mRefreshRateStats.getTotalTimes();
EXPECT_EQ(screenOff, times["ScreenOff"]);
EXPECT_EQ(ninety, times["90fps"]);
EXPECT_LT(sixty, times["60fps"]);
- mRefreshRateStats->setConfigMode(CONFIG_ID_90);
- sixty = mRefreshRateStats->getTotalTimes()["60fps"];
+ mRefreshRateStats.setConfigMode(CONFIG_ID_90);
+ sixty = mRefreshRateStats.getTotalTimes()["60fps"];
std::this_thread::sleep_for(std::chrono::milliseconds(2));
- times = mRefreshRateStats->getTotalTimes();
+ times = mRefreshRateStats.getTotalTimes();
EXPECT_EQ(screenOff, times["ScreenOff"]);
EXPECT_LT(ninety, times["90fps"]);
EXPECT_EQ(sixty, times["60fps"]);
- mRefreshRateStats->setConfigMode(CONFIG_ID_60);
- ninety = mRefreshRateStats->getTotalTimes()["90fps"];
+ mRefreshRateStats.setConfigMode(CONFIG_ID_60);
+ ninety = mRefreshRateStats.getTotalTimes()["90fps"];
std::this_thread::sleep_for(std::chrono::milliseconds(2));
- times = mRefreshRateStats->getTotalTimes();
+ times = mRefreshRateStats.getTotalTimes();
EXPECT_EQ(screenOff, times["ScreenOff"]);
EXPECT_EQ(ninety, times["90fps"]);
EXPECT_LT(sixty, times["60fps"]);
// Because the power mode is not HWC_POWER_MODE_NORMAL, switching the config
// does not update refresh rates that come from the config.
- mRefreshRateStats->setPowerMode(HWC_POWER_MODE_DOZE);
- mRefreshRateStats->setConfigMode(CONFIG_ID_90);
- sixty = mRefreshRateStats->getTotalTimes()["60fps"];
+ mRefreshRateStats.setPowerMode(HWC_POWER_MODE_DOZE);
+ mRefreshRateStats.setConfigMode(CONFIG_ID_90);
+ sixty = mRefreshRateStats.getTotalTimes()["60fps"];
std::this_thread::sleep_for(std::chrono::milliseconds(2));
- times = mRefreshRateStats->getTotalTimes();
+ times = mRefreshRateStats.getTotalTimes();
EXPECT_LT(screenOff, times["ScreenOff"]);
EXPECT_EQ(ninety, times["90fps"]);
EXPECT_EQ(sixty, times["60fps"]);
- mRefreshRateStats->setConfigMode(CONFIG_ID_60);
- screenOff = mRefreshRateStats->getTotalTimes()["ScreenOff"];
+ mRefreshRateStats.setConfigMode(CONFIG_ID_60);
+ screenOff = mRefreshRateStats.getTotalTimes()["ScreenOff"];
std::this_thread::sleep_for(std::chrono::milliseconds(2));
- times = mRefreshRateStats->getTotalTimes();
+ times = mRefreshRateStats.getTotalTimes();
EXPECT_LT(screenOff, times["ScreenOff"]);
EXPECT_EQ(ninety, times["90fps"]);
EXPECT_EQ(sixty, times["60fps"]);