Add a flag for refresh rate switching
Some devices don't do refresh rate switching, so we should take that
into account when filtering display manager config settings and deciding
scheduling behavior.
This CL adds a sysprop that can be set to indicate if surface flinger
should do refresh rate switching, and modifies surface flinger to have
the correct behavior when we're not doing refresh rate switching.
Bug: 136592946
Bug: 138261472
Test: Ran through various 60/90 switching scenarios on a device with
refresh rate switching.
Test: Set the refresh rate switching sysprop to false, and confirmed we
get a consistent 60Hz.
Test: Inspected dumpsys output and confirmed it looks correct. In
particular, refresh rate stats are output correctly.
Test: Ran automated tests: RefreshRateConfigsTest, RefreshRateStatsTest,
SchedulerTest.
Change-Id: I54cd5be9d2c1b9abc8475c3ce39846cbe9f9fe53
diff --git a/services/surfaceflinger/tests/unittests/RefreshRateConfigsTest.cpp b/services/surfaceflinger/tests/unittests/RefreshRateConfigsTest.cpp
index 5067fe8..f315a8a 100644
--- a/services/surfaceflinger/tests/unittests/RefreshRateConfigsTest.cpp
+++ b/services/surfaceflinger/tests/unittests/RefreshRateConfigsTest.cpp
@@ -23,7 +23,6 @@
#include "DisplayHardware/HWC2.h"
#include "Scheduler/RefreshRateConfigs.h"
-#include "mock/DisplayHardware/MockDisplay.h"
using namespace std::chrono_literals;
using testing::_;
@@ -50,9 +49,8 @@
ASSERT_EQ(left.configId, right.configId);
ASSERT_EQ(left.name, right.name);
ASSERT_EQ(left.fps, right.fps);
+ ASSERT_EQ(left.vsyncPeriod, right.vsyncPeriod);
}
-
- RefreshRateConfigs mConfigs;
};
RefreshRateConfigsTest::RefreshRateConfigsTest() {
@@ -71,101 +69,39 @@
/* ------------------------------------------------------------------------
* Test cases
*/
-TEST_F(RefreshRateConfigsTest, zeroDeviceConfigs_storesPowerSavingConfig) {
- std::vector<std::shared_ptr<const HWC2::Display::Config>> displayConfigs;
- mConfigs.populate(displayConfigs);
-
- // We always store a configuration for screen off.
- const auto& rates = mConfigs.getRefreshRates();
- ASSERT_EQ(1, rates.size());
- const auto& powerSavingRate = rates.find(RefreshRateType::POWER_SAVING);
- ASSERT_NE(rates.end(), powerSavingRate);
- ASSERT_EQ(rates.end(), rates.find(RefreshRateType::PERFORMANCE));
- ASSERT_EQ(rates.end(), rates.find(RefreshRateType::DEFAULT));
-
- RefreshRate expectedConfig =
- RefreshRate{SCREEN_OFF_CONFIG_ID, "ScreenOff", 0, HWC2_SCREEN_OFF_CONFIG_ID};
- assertRatesEqual(expectedConfig, *powerSavingRate->second);
-
- 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, mConfigs.getRefreshRates().size());
+TEST_F(RefreshRateConfigsTest, oneDeviceConfig_isRejected) {
+ std::vector<RefreshRateConfigs::InputConfig> configs{{HWC2_CONFIG_ID_60, VSYNC_60}};
+ auto refreshRateConfigs =
+ std::make_unique<RefreshRateConfigs>(/*refreshRateSwitching=*/true, configs,
+ /*currentConfig=*/0);
+ ASSERT_FALSE(refreshRateConfigs->refreshRateSwitchingSupported());
}
-TEST_F(RefreshRateConfigsTest, oneDeviceConfig_storesDefaultConfig) {
- auto display = new Hwc2::mock::Display();
- std::vector<std::shared_ptr<const HWC2::Display::Config>> displayConfigs;
- auto config60 = HWC2::Display::Config::Builder(*display, CONFIG_ID_60);
- config60.setVsyncPeriod(VSYNC_60);
- displayConfigs.push_back(config60.build());
- mConfigs.populate(displayConfigs);
+TEST_F(RefreshRateConfigsTest, twoDeviceConfigs_storesFullRefreshRateMap) {
+ std::vector<RefreshRateConfigs::InputConfig> configs{{HWC2_CONFIG_ID_60, VSYNC_60},
+ {HWC2_CONFIG_ID_90, VSYNC_90}};
+ auto refreshRateConfigs =
+ std::make_unique<RefreshRateConfigs>(/*refreshRateSwitching=*/true, configs,
+ /*currentConfig=*/0);
- const auto& rates = mConfigs.getRefreshRates();
+ ASSERT_TRUE(refreshRateConfigs->refreshRateSwitchingSupported());
+ const auto& rates = refreshRateConfigs->getRefreshRateMap();
ASSERT_EQ(2, rates.size());
- const auto& powerSavingRate = rates.find(RefreshRateType::POWER_SAVING);
- const auto& defaultRate = rates.find(RefreshRateType::DEFAULT);
- ASSERT_NE(rates.end(), powerSavingRate);
- ASSERT_NE(rates.end(), defaultRate);
- ASSERT_EQ(rates.end(), rates.find(RefreshRateType::PERFORMANCE));
-
- RefreshRate expectedPowerSavingConfig =
- RefreshRate{SCREEN_OFF_CONFIG_ID, "ScreenOff", 0, HWC2_SCREEN_OFF_CONFIG_ID};
- assertRatesEqual(expectedPowerSavingConfig, *powerSavingRate->second);
- RefreshRate expectedDefaultConfig = RefreshRate{CONFIG_ID_60, "60fps", 60, HWC2_CONFIG_ID_60};
- assertRatesEqual(expectedDefaultConfig, *defaultRate->second);
-
- ASSERT_TRUE(mConfigs.getRefreshRate(RefreshRateType::POWER_SAVING));
- assertRatesEqual(expectedPowerSavingConfig,
- *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, mConfigs.getRefreshRates().size());
-}
-
-TEST_F(RefreshRateConfigsTest, twoDeviceConfigs_storesPerformanceConfig) {
- auto display = new Hwc2::mock::Display();
- std::vector<std::shared_ptr<const HWC2::Display::Config>> displayConfigs;
- auto config60 = HWC2::Display::Config::Builder(*display, CONFIG_ID_60);
- config60.setVsyncPeriod(VSYNC_60);
- displayConfigs.push_back(config60.build());
- auto config90 = HWC2::Display::Config::Builder(*display, CONFIG_ID_90);
- config90.setVsyncPeriod(VSYNC_90);
- displayConfigs.push_back(config90.build());
- mConfigs.populate(displayConfigs);
-
- 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);
const auto& performanceRate = rates.find(RefreshRateType::PERFORMANCE);
- ASSERT_NE(rates.end(), powerSavingRate);
ASSERT_NE(rates.end(), defaultRate);
ASSERT_NE(rates.end(), performanceRate);
- RefreshRate expectedPowerSavingConfig =
- RefreshRate{SCREEN_OFF_CONFIG_ID, "ScreenOff", 0, HWC2_SCREEN_OFF_CONFIG_ID};
- assertRatesEqual(expectedPowerSavingConfig, *powerSavingRate->second);
- RefreshRate expectedDefaultConfig = RefreshRate{CONFIG_ID_60, "60fps", 60, HWC2_CONFIG_ID_60};
- assertRatesEqual(expectedDefaultConfig, *defaultRate->second);
- RefreshRate expectedPerformanceConfig =
- RefreshRate{CONFIG_ID_90, "90fps", 90, HWC2_CONFIG_ID_90};
- assertRatesEqual(expectedPerformanceConfig, *performanceRate->second);
+ RefreshRate expectedDefaultConfig = {CONFIG_ID_60, "60fps", 60, VSYNC_60, HWC2_CONFIG_ID_60};
+ assertRatesEqual(expectedDefaultConfig, defaultRate->second);
+ RefreshRate expectedPerformanceConfig = {CONFIG_ID_90, "90fps", 90, VSYNC_90,
+ HWC2_CONFIG_ID_90};
+ assertRatesEqual(expectedPerformanceConfig, performanceRate->second);
- ASSERT_TRUE(mConfigs.getRefreshRate(RefreshRateType::POWER_SAVING));
- assertRatesEqual(expectedPowerSavingConfig,
- *mConfigs.getRefreshRate(RefreshRateType::POWER_SAVING));
- ASSERT_TRUE(mConfigs.getRefreshRate(RefreshRateType::DEFAULT));
- assertRatesEqual(expectedDefaultConfig, *mConfigs.getRefreshRate(RefreshRateType::DEFAULT));
- ASSERT_TRUE(mConfigs.getRefreshRate(RefreshRateType::PERFORMANCE));
+ assertRatesEqual(expectedDefaultConfig,
+ refreshRateConfigs->getRefreshRateFromType(RefreshRateType::DEFAULT));
assertRatesEqual(expectedPerformanceConfig,
- *mConfigs.getRefreshRate(RefreshRateType::PERFORMANCE));
+ refreshRateConfigs->getRefreshRateFromType(RefreshRateType::PERFORMANCE));
}
} // namespace
} // namespace scheduler
diff --git a/services/surfaceflinger/tests/unittests/RefreshRateStatsTest.cpp b/services/surfaceflinger/tests/unittests/RefreshRateStatsTest.cpp
index 411ec61..cec0b32 100644
--- a/services/surfaceflinger/tests/unittests/RefreshRateStatsTest.cpp
+++ b/services/surfaceflinger/tests/unittests/RefreshRateStatsTest.cpp
@@ -22,7 +22,6 @@
#include <thread>
#include "Scheduler/RefreshRateStats.h"
-#include "mock/DisplayHardware/MockDisplay.h"
#include "mock/MockTimeStats.h"
using namespace std::chrono_literals;
@@ -42,9 +41,18 @@
RefreshRateStatsTest();
~RefreshRateStatsTest();
+ void init(const std::vector<RefreshRateConfigs::InputConfig>& configs) {
+ mRefreshRateConfigs = std::make_unique<RefreshRateConfigs>(
+ /*refreshRateSwitching=*/true, configs, /*currentConfig=*/0);
+ mRefreshRateStats =
+ std::make_unique<RefreshRateStats>(*mRefreshRateConfigs, mTimeStats,
+ /*currentConfig=*/0,
+ /*currentPowerMode=*/HWC_POWER_MODE_OFF);
+ }
+
mock::TimeStats mTimeStats;
- RefreshRateConfigs mRefreshRateConfigs;
- RefreshRateStats mRefreshRateStats{mRefreshRateConfigs, mTimeStats};
+ std::unique_ptr<RefreshRateConfigs> mRefreshRateConfigs;
+ std::unique_ptr<RefreshRateStats> mRefreshRateStats;
};
RefreshRateStatsTest::RefreshRateStatsTest() {
@@ -63,63 +71,46 @@
/* ------------------------------------------------------------------------
* Test cases
*/
-TEST_F(RefreshRateStatsTest, canCreateAndDestroyTest) {
- std::vector<std::shared_ptr<const HWC2::Display::Config>> configs;
- mRefreshRateConfigs.populate(configs);
-
- // There is one default config, so the refresh rates should have one item.
- EXPECT_EQ(1, mRefreshRateStats.getTotalTimes().size());
-}
-
TEST_F(RefreshRateStatsTest, oneConfigTest) {
- auto display = new Hwc2::mock::Display();
-
- auto config = HWC2::Display::Config::Builder(*display, CONFIG_ID_90);
- config.setVsyncPeriod(VSYNC_90);
- std::vector<std::shared_ptr<const HWC2::Display::Config>> configs;
- configs.push_back(config.build());
-
- mRefreshRateConfigs.populate(configs);
+ init({{CONFIG_ID_90, VSYNC_90}});
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();
- EXPECT_EQ(2, times.size());
+ std::unordered_map<std::string, int64_t> times = mRefreshRateStats->getTotalTimes();
+ ASSERT_EQ(1, times.size());
EXPECT_NE(0u, times.count("ScreenOff"));
- EXPECT_EQ(1u, times.count("90fps"));
- EXPECT_EQ(0, times["90fps"]);
// Setting up tests on mobile harness can be flaky with time passing, so testing for
// exact time changes can result in flaxy numbers. To avoid that remember old
// numbers to make sure the correct values are increasing in the next test.
int screenOff = times["ScreenOff"];
- int ninety = times["90fps"];
// 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"]);
+ EXPECT_EQ(0u, times.count("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"]);
+ ASSERT_EQ(1u, times.count("90fps"));
+ EXPECT_LT(0, times["90fps"]);
- mRefreshRateStats.setPowerMode(HWC_POWER_MODE_DOZE);
- ninety = mRefreshRateStats.getTotalTimes()["90fps"];
+ mRefreshRateStats->setPowerMode(HWC_POWER_MODE_DOZE);
+ int 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"]);
@@ -127,93 +118,75 @@
}
TEST_F(RefreshRateStatsTest, twoConfigsTest) {
- auto display = new Hwc2::mock::Display();
-
- auto config90 = HWC2::Display::Config::Builder(*display, CONFIG_ID_90);
- config90.setVsyncPeriod(VSYNC_90);
- std::vector<std::shared_ptr<const HWC2::Display::Config>> configs;
- configs.push_back(config90.build());
-
- auto config60 = HWC2::Display::Config::Builder(*display, CONFIG_ID_60);
- config60.setVsyncPeriod(VSYNC_60);
- configs.push_back(config60.build());
-
- mRefreshRateConfigs.populate(configs);
+ init({{CONFIG_ID_90, VSYNC_90}, {CONFIG_ID_60, VSYNC_60}});
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();
- EXPECT_EQ(3, times.size());
+ std::unordered_map<std::string, int64_t> times = mRefreshRateStats->getTotalTimes();
+ ASSERT_EQ(1, times.size());
EXPECT_NE(0u, times.count("ScreenOff"));
- EXPECT_EQ(1u, times.count("60fps"));
- EXPECT_EQ(0, times["60fps"]);
- EXPECT_EQ(1u, times.count("90fps"));
- EXPECT_EQ(0, times["90fps"]);
// Setting up tests on mobile harness can be flaky with time passing, so testing for
// exact time changes can result in flaxy numbers. To avoid that remember old
// numbers to make sure the correct values are increasing in the next test.
int screenOff = times["ScreenOff"];
- int sixty = times["60fps"];
- int ninety = times["90fps"];
// 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"]);
+ ASSERT_EQ(1u, times.count("90fps"));
+ EXPECT_LT(0, 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);
+ int 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"]);
+ ASSERT_EQ(1u, times.count("60fps"));
+ EXPECT_LT(0, times["60fps"]);
- mRefreshRateStats.setConfigMode(CONFIG_ID_90);
- sixty = mRefreshRateStats.getTotalTimes()["60fps"];
+ mRefreshRateStats->setConfigMode(CONFIG_ID_90);
+ int 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"]);
diff --git a/services/surfaceflinger/tests/unittests/SchedulerTest.cpp b/services/surfaceflinger/tests/unittests/SchedulerTest.cpp
index ebcb9d8..bf53124 100644
--- a/services/surfaceflinger/tests/unittests/SchedulerTest.cpp
+++ b/services/surfaceflinger/tests/unittests/SchedulerTest.cpp
@@ -9,6 +9,7 @@
#include "Scheduler/EventControlThread.h"
#include "Scheduler/EventThread.h"
+#include "Scheduler/RefreshRateConfigs.h"
#include "TestableScheduler.h"
#include "mock/MockEventThread.h"
@@ -36,8 +37,8 @@
SchedulerTest();
~SchedulerTest() override;
- scheduler::RefreshRateConfigs mRefreshRateConfigs;
- TestableScheduler mScheduler{mRefreshRateConfigs};
+ std::unique_ptr<scheduler::RefreshRateConfigs> mRefreshRateConfigs;
+ std::unique_ptr<TestableScheduler> mScheduler;
Scheduler::ConnectionHandle mConnectionHandle;
mock::EventThread* mEventThread;
@@ -49,6 +50,13 @@
::testing::UnitTest::GetInstance()->current_test_info();
ALOGD("**** Setting up for %s.%s\n", test_info->test_case_name(), test_info->name());
+ std::vector<scheduler::RefreshRateConfigs::InputConfig> configs{{/*hwcId=*/0, 16666667}};
+ mRefreshRateConfigs =
+ std::make_unique<scheduler::RefreshRateConfigs>(/*refreshRateSwitching=*/false, configs,
+ /*currentConfig=*/0);
+
+ mScheduler = std::make_unique<TestableScheduler>(*mRefreshRateConfigs);
+
auto eventThread = std::make_unique<mock::EventThread>();
mEventThread = eventThread.get();
EXPECT_CALL(*mEventThread, registerDisplayEventConnection(_)).WillOnce(Return(0));
@@ -60,7 +68,7 @@
EXPECT_CALL(*mEventThread, createEventConnection(_, _))
.WillRepeatedly(Return(mEventThreadConnection));
- mConnectionHandle = mScheduler.createConnection(std::move(eventThread));
+ mConnectionHandle = mScheduler->createConnection(std::move(eventThread));
EXPECT_TRUE(mConnectionHandle);
}
@@ -80,61 +88,60 @@
sp<IDisplayEventConnection> connection;
ASSERT_NO_FATAL_FAILURE(
- connection = mScheduler.createDisplayEventConnection(handle, ResyncCallback(),
- ISurfaceComposer::
- eConfigChangedSuppress));
+ connection = mScheduler->createDisplayEventConnection(handle,
+ ISurfaceComposer::
+ eConfigChangedSuppress));
EXPECT_FALSE(connection);
- EXPECT_FALSE(mScheduler.getEventThread(handle));
- EXPECT_FALSE(mScheduler.getEventConnection(handle));
+ EXPECT_FALSE(mScheduler->getEventThread(handle));
+ EXPECT_FALSE(mScheduler->getEventConnection(handle));
// The EXPECT_CALLS make sure we don't call the functions on the subsequent event threads.
EXPECT_CALL(*mEventThread, onHotplugReceived(_, _)).Times(0);
- ASSERT_NO_FATAL_FAILURE(mScheduler.onHotplugReceived(handle, PHYSICAL_DISPLAY_ID, false));
+ ASSERT_NO_FATAL_FAILURE(mScheduler->onHotplugReceived(handle, PHYSICAL_DISPLAY_ID, false));
EXPECT_CALL(*mEventThread, onScreenAcquired()).Times(0);
- ASSERT_NO_FATAL_FAILURE(mScheduler.onScreenAcquired(handle));
+ ASSERT_NO_FATAL_FAILURE(mScheduler->onScreenAcquired(handle));
EXPECT_CALL(*mEventThread, onScreenReleased()).Times(0);
- ASSERT_NO_FATAL_FAILURE(mScheduler.onScreenReleased(handle));
+ ASSERT_NO_FATAL_FAILURE(mScheduler->onScreenReleased(handle));
std::string output;
EXPECT_CALL(*mEventThread, dump(_)).Times(0);
- ASSERT_NO_FATAL_FAILURE(mScheduler.dump(handle, output));
+ ASSERT_NO_FATAL_FAILURE(mScheduler->dump(handle, output));
EXPECT_TRUE(output.empty());
EXPECT_CALL(*mEventThread, setPhaseOffset(_)).Times(0);
- ASSERT_NO_FATAL_FAILURE(mScheduler.setPhaseOffset(handle, 10));
+ ASSERT_NO_FATAL_FAILURE(mScheduler->setPhaseOffset(handle, 10));
}
TEST_F(SchedulerTest, validConnectionHandle) {
sp<IDisplayEventConnection> connection;
ASSERT_NO_FATAL_FAILURE(
- connection =
- mScheduler.createDisplayEventConnection(mConnectionHandle, ResyncCallback(),
- ISurfaceComposer::
- eConfigChangedSuppress));
+ connection = mScheduler->createDisplayEventConnection(mConnectionHandle,
+ ISurfaceComposer::
+ eConfigChangedSuppress));
ASSERT_EQ(mEventThreadConnection, connection);
- EXPECT_TRUE(mScheduler.getEventThread(mConnectionHandle));
- EXPECT_TRUE(mScheduler.getEventConnection(mConnectionHandle));
+ EXPECT_TRUE(mScheduler->getEventThread(mConnectionHandle));
+ EXPECT_TRUE(mScheduler->getEventConnection(mConnectionHandle));
EXPECT_CALL(*mEventThread, onHotplugReceived(PHYSICAL_DISPLAY_ID, false)).Times(1);
ASSERT_NO_FATAL_FAILURE(
- mScheduler.onHotplugReceived(mConnectionHandle, PHYSICAL_DISPLAY_ID, false));
+ mScheduler->onHotplugReceived(mConnectionHandle, PHYSICAL_DISPLAY_ID, false));
EXPECT_CALL(*mEventThread, onScreenAcquired()).Times(1);
- ASSERT_NO_FATAL_FAILURE(mScheduler.onScreenAcquired(mConnectionHandle));
+ ASSERT_NO_FATAL_FAILURE(mScheduler->onScreenAcquired(mConnectionHandle));
EXPECT_CALL(*mEventThread, onScreenReleased()).Times(1);
- ASSERT_NO_FATAL_FAILURE(mScheduler.onScreenReleased(mConnectionHandle));
+ ASSERT_NO_FATAL_FAILURE(mScheduler->onScreenReleased(mConnectionHandle));
std::string output("dump");
EXPECT_CALL(*mEventThread, dump(output)).Times(1);
- ASSERT_NO_FATAL_FAILURE(mScheduler.dump(mConnectionHandle, output));
+ ASSERT_NO_FATAL_FAILURE(mScheduler->dump(mConnectionHandle, output));
EXPECT_FALSE(output.empty());
EXPECT_CALL(*mEventThread, setPhaseOffset(10)).Times(1);
- ASSERT_NO_FATAL_FAILURE(mScheduler.setPhaseOffset(mConnectionHandle, 10));
+ ASSERT_NO_FATAL_FAILURE(mScheduler->setPhaseOffset(mConnectionHandle, 10));
}
} // namespace
diff --git a/services/surfaceflinger/tests/unittests/TestableScheduler.h b/services/surfaceflinger/tests/unittests/TestableScheduler.h
index 780b608..ae72467 100644
--- a/services/surfaceflinger/tests/unittests/TestableScheduler.h
+++ b/services/surfaceflinger/tests/unittests/TestableScheduler.h
@@ -37,7 +37,7 @@
// Used to inject mock event thread.
ConnectionHandle createConnection(std::unique_ptr<EventThread> eventThread) {
- return Scheduler::createConnection(std::move(eventThread), ResyncCallback());
+ return Scheduler::createConnection(std::move(eventThread));
}
/* ------------------------------------------------------------------------
diff --git a/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h b/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
index 9536dd1..5e075b6 100644
--- a/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
+++ b/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
@@ -32,6 +32,7 @@
#include "Layer.h"
#include "NativeWindowSurface.h"
#include "Scheduler/MessageQueue.h"
+#include "Scheduler/RefreshRateConfigs.h"
#include "StartPropertySetThread.h"
#include "SurfaceFlinger.h"
#include "SurfaceFlingerFactory.h"
@@ -194,9 +195,19 @@
std::unique_ptr<EventControlThread> eventControlThread,
std::unique_ptr<EventThread> appEventThread,
std::unique_ptr<EventThread> sfEventThread) {
+ std::vector<scheduler::RefreshRateConfigs::InputConfig> configs{{/*hwcId=*/0, 16666667}};
+ mFlinger->mRefreshRateConfigs =
+ std::make_unique<scheduler::RefreshRateConfigs>(/*refreshRateSwitching=*/false,
+ configs, /*currentConfig=*/0);
+ mFlinger->mRefreshRateStats =
+ std::make_unique<scheduler::RefreshRateStats>(*mFlinger->mRefreshRateConfigs,
+ *mFlinger->mTimeStats,
+ /*currentConfig=*/0,
+ /*powerMode=*/HWC_POWER_MODE_OFF);
+
mScheduler =
new TestableScheduler(std::move(primaryDispSync), std::move(eventControlThread),
- mFlinger->mRefreshRateConfigs);
+ *mFlinger->mRefreshRateConfigs);
mFlinger->mAppConnectionHandle = mScheduler->createConnection(std::move(appEventThread));
mFlinger->mSfConnectionHandle = mScheduler->createConnection(std::move(sfEventThread));