SurfaceFlinger: use config groups
Composer 2.4 adds a new attribute for configs groups. This change
groups configs according to their group and store them in
RefreshRateConfigs.
Test: rev up composer to 2.4 and test refresh rate switching
Test: adb shell /data/nativetest64/libsurfaceflinger_unittest/libsurfaceflinger_unittest
Test: adb shell /data/nativetest64/SurfaceFlinger_test/SurfaceFlinger_test
Bug: 141329414
Fixes: 139751853
Change-Id: Ic0bcd3da4bf6b73efa11a60c2594948ce030362f
diff --git a/services/surfaceflinger/tests/unittests/DisplayTransactionTest.cpp b/services/surfaceflinger/tests/unittests/DisplayTransactionTest.cpp
index db7d04c..76e8171 100644
--- a/services/surfaceflinger/tests/unittests/DisplayTransactionTest.cpp
+++ b/services/surfaceflinger/tests/unittests/DisplayTransactionTest.cpp
@@ -1427,7 +1427,7 @@
// Note: This is not Case::Display::HWC_ACTIVE_CONFIG_ID as the ids are
// remapped, and the test only ever sets up one config. If there were an error
// looking up the remapped index, device->getActiveConfig() would be -1 instead.
- EXPECT_EQ(0, device->getActiveConfig());
+ EXPECT_EQ(0, device->getActiveConfig().value());
EXPECT_EQ(Case::PerFrameMetadataSupport::PER_FRAME_METADATA_KEYS,
device->getSupportedPerFrameMetadata());
}
diff --git a/services/surfaceflinger/tests/unittests/EventThreadTest.cpp b/services/surfaceflinger/tests/unittests/EventThreadTest.cpp
index 2662f52..80bca02 100644
--- a/services/surfaceflinger/tests/unittests/EventThreadTest.cpp
+++ b/services/surfaceflinger/tests/unittests/EventThreadTest.cpp
@@ -26,6 +26,7 @@
#include "AsyncCallRecorder.h"
#include "Scheduler/EventThread.h"
+#include "Scheduler/HwcStrongTypes.h"
using namespace std::chrono_literals;
using namespace std::placeholders;
@@ -34,6 +35,7 @@
using testing::Invoke;
namespace android {
+
namespace {
constexpr PhysicalDisplayId INTERNAL_DISPLAY_ID = 111;
@@ -448,17 +450,17 @@
}
TEST_F(EventThreadTest, postConfigChangedPrimary) {
- mThread->onConfigChanged(INTERNAL_DISPLAY_ID, 7);
+ mThread->onConfigChanged(INTERNAL_DISPLAY_ID, HwcConfigIndexType(7));
expectConfigChangedEventReceivedByConnection(INTERNAL_DISPLAY_ID, 7);
}
TEST_F(EventThreadTest, postConfigChangedExternal) {
- mThread->onConfigChanged(EXTERNAL_DISPLAY_ID, 5);
+ mThread->onConfigChanged(EXTERNAL_DISPLAY_ID, HwcConfigIndexType(5));
expectConfigChangedEventReceivedByConnection(EXTERNAL_DISPLAY_ID, 5);
}
TEST_F(EventThreadTest, postConfigChangedPrimary64bit) {
- mThread->onConfigChanged(DISPLAY_ID_64BIT, 7);
+ mThread->onConfigChanged(DISPLAY_ID_64BIT, HwcConfigIndexType(7));
expectConfigChangedEventReceivedByConnection(DISPLAY_ID_64BIT, 7);
}
@@ -468,7 +470,7 @@
createConnection(suppressConnectionEventRecorder,
ISurfaceComposer::eConfigChangedSuppress);
- mThread->onConfigChanged(INTERNAL_DISPLAY_ID, 9);
+ mThread->onConfigChanged(INTERNAL_DISPLAY_ID, HwcConfigIndexType(9));
expectConfigChangedEventReceivedByConnection(INTERNAL_DISPLAY_ID, 9);
auto args = suppressConnectionEventRecorder.waitForCall();
diff --git a/services/surfaceflinger/tests/unittests/FakePhaseOffsets.h b/services/surfaceflinger/tests/unittests/FakePhaseOffsets.h
index 66c7f6b..da4eea0 100644
--- a/services/surfaceflinger/tests/unittests/FakePhaseOffsets.h
+++ b/services/surfaceflinger/tests/unittests/FakePhaseOffsets.h
@@ -25,16 +25,16 @@
struct FakePhaseOffsets : PhaseOffsets {
static constexpr nsecs_t FAKE_PHASE_OFFSET_NS = 0;
- Offsets getOffsetsForRefreshRate(RefreshRateType) const override { return getCurrentOffsets(); }
+ Offsets getOffsetsForRefreshRate(float) const override { return getCurrentOffsets(); }
Offsets getCurrentOffsets() const override {
- return {{RefreshRateType::DEFAULT, FAKE_PHASE_OFFSET_NS, FAKE_PHASE_OFFSET_NS},
- {RefreshRateType::DEFAULT, FAKE_PHASE_OFFSET_NS, FAKE_PHASE_OFFSET_NS},
- {RefreshRateType::DEFAULT, FAKE_PHASE_OFFSET_NS, FAKE_PHASE_OFFSET_NS},
+ return {{FAKE_PHASE_OFFSET_NS, FAKE_PHASE_OFFSET_NS},
+ {FAKE_PHASE_OFFSET_NS, FAKE_PHASE_OFFSET_NS},
+ {FAKE_PHASE_OFFSET_NS, FAKE_PHASE_OFFSET_NS},
FAKE_PHASE_OFFSET_NS};
}
- void setRefreshRateType(RefreshRateType) override {}
+ void setRefreshRateFps(float) override {}
void dump(std::string&) const override {}
};
diff --git a/services/surfaceflinger/tests/unittests/LayerHistoryTest.cpp b/services/surfaceflinger/tests/unittests/LayerHistoryTest.cpp
index e93d31e..d95252b 100644
--- a/services/surfaceflinger/tests/unittests/LayerHistoryTest.cpp
+++ b/services/surfaceflinger/tests/unittests/LayerHistoryTest.cpp
@@ -44,9 +44,15 @@
auto createLayer() { return sp<mock::MockLayer>(new mock::MockLayer(mFlinger.flinger())); }
RefreshRateConfigs mConfigs{true,
- {RefreshRateConfigs::InputConfig{0, LO_FPS_PERIOD},
- RefreshRateConfigs::InputConfig{1, HI_FPS_PERIOD}},
- 0};
+ {
+ RefreshRateConfigs::InputConfig{HwcConfigIndexType(0),
+ HwcConfigGroupType(0),
+ LO_FPS_PERIOD},
+ RefreshRateConfigs::InputConfig{HwcConfigIndexType(1),
+ HwcConfigGroupType(0),
+ HI_FPS_PERIOD},
+ },
+ HwcConfigIndexType(0)};
TestableScheduler* const mScheduler{new TestableScheduler(mConfigs)};
TestableSurfaceFlinger mFlinger;
@@ -57,7 +63,6 @@
TEST_F(LayerHistoryTest, oneLayer) {
const auto layer = createLayer();
- constexpr bool isHDR = false;
EXPECT_CALL(*layer, isVisible()).WillRepeatedly(Return(true));
EXPECT_EQ(1, layerCount());
@@ -69,14 +74,14 @@
// 0 FPS is returned if active layers have insufficient history.
for (int i = 0; i < PRESENT_TIME_HISTORY_SIZE - 1; i++) {
- history().record(layer.get(), 0, isHDR, mTime);
+ history().record(layer.get(), 0, mTime);
EXPECT_FLOAT_EQ(0, history().summarize(mTime).maxRefreshRate);
EXPECT_EQ(1, activeLayerCount());
}
// High FPS is returned once enough history has been recorded.
for (int i = 0; i < 10; i++) {
- history().record(layer.get(), 0, isHDR, mTime);
+ history().record(layer.get(), 0, mTime);
EXPECT_FLOAT_EQ(HI_FPS, history().summarize(mTime).maxRefreshRate);
EXPECT_EQ(1, activeLayerCount());
}
@@ -84,29 +89,25 @@
TEST_F(LayerHistoryTest, oneHDRLayer) {
const auto layer = createLayer();
- constexpr bool isHDR = true;
EXPECT_CALL(*layer, isVisible()).WillRepeatedly(Return(true));
EXPECT_EQ(1, layerCount());
EXPECT_EQ(0, activeLayerCount());
- history().record(layer.get(), 0, isHDR, mTime);
+ history().record(layer.get(), 0, mTime);
auto summary = history().summarize(mTime);
EXPECT_FLOAT_EQ(0, summary.maxRefreshRate);
- EXPECT_TRUE(summary.isHDR);
EXPECT_EQ(1, activeLayerCount());
EXPECT_CALL(*layer, isVisible()).WillRepeatedly(Return(false));
summary = history().summarize(mTime);
EXPECT_FLOAT_EQ(0, summary.maxRefreshRate);
- EXPECT_FALSE(summary.isHDR);
EXPECT_EQ(0, activeLayerCount());
}
TEST_F(LayerHistoryTest, explicitTimestamp) {
const auto layer = createLayer();
- constexpr bool isHDR = false;
EXPECT_CALL(*layer, isVisible()).WillRepeatedly(Return(true));
EXPECT_EQ(1, layerCount());
@@ -114,7 +115,7 @@
nsecs_t time = mTime;
for (int i = 0; i < PRESENT_TIME_HISTORY_SIZE; i++) {
- history().record(layer.get(), time, isHDR, time);
+ history().record(layer.get(), time, time);
time += LO_FPS_PERIOD;
}
@@ -127,7 +128,6 @@
auto layer1 = createLayer();
auto layer2 = createLayer();
auto layer3 = createLayer();
- constexpr bool isHDR = false;
EXPECT_CALL(*layer1, isVisible()).WillRepeatedly(Return(true));
EXPECT_CALL(*layer2, isVisible()).WillRepeatedly(Return(true));
@@ -141,7 +141,7 @@
// layer1 is active but infrequent.
for (int i = 0; i < PRESENT_TIME_HISTORY_SIZE; i++) {
- history().record(layer1.get(), time, isHDR, time);
+ history().record(layer1.get(), time, time);
time += MAX_FREQUENT_LAYER_PERIOD_NS.count();
}
@@ -151,12 +151,12 @@
// layer2 is frequent and has high refresh rate.
for (int i = 0; i < PRESENT_TIME_HISTORY_SIZE; i++) {
- history().record(layer2.get(), time, isHDR, time);
+ history().record(layer2.get(), time, time);
time += HI_FPS_PERIOD;
}
// layer1 is still active but infrequent.
- history().record(layer1.get(), time, isHDR, time);
+ history().record(layer1.get(), time, time);
EXPECT_FLOAT_EQ(HI_FPS, history().summarize(time).maxRefreshRate);
EXPECT_EQ(2, activeLayerCount());
@@ -165,7 +165,7 @@
// layer1 is no longer active.
// layer2 is frequent and has low refresh rate.
for (int i = 0; i < PRESENT_TIME_HISTORY_SIZE; i++) {
- history().record(layer2.get(), time, isHDR, time);
+ history().record(layer2.get(), time, time);
time += LO_FPS_PERIOD;
}
@@ -178,10 +178,10 @@
constexpr int RATIO = LO_FPS_PERIOD / HI_FPS_PERIOD;
for (int i = 0; i < PRESENT_TIME_HISTORY_SIZE - 1; i++) {
if (i % RATIO == 0) {
- history().record(layer2.get(), time, isHDR, time);
+ history().record(layer2.get(), time, time);
}
- history().record(layer3.get(), time, isHDR, time);
+ history().record(layer3.get(), time, time);
time += HI_FPS_PERIOD;
}
@@ -190,7 +190,7 @@
EXPECT_EQ(2, frequentLayerCount(time));
// layer3 becomes recently active.
- history().record(layer3.get(), time, isHDR, time);
+ history().record(layer3.get(), time, time);
EXPECT_FLOAT_EQ(HI_FPS, history().summarize(time).maxRefreshRate);
EXPECT_EQ(2, activeLayerCount());
EXPECT_EQ(2, frequentLayerCount(time));
@@ -205,7 +205,7 @@
// layer2 still has low refresh rate.
// layer3 becomes inactive.
for (int i = 0; i < PRESENT_TIME_HISTORY_SIZE; i++) {
- history().record(layer2.get(), time, isHDR, time);
+ history().record(layer2.get(), time, time);
time += LO_FPS_PERIOD;
}
@@ -222,7 +222,7 @@
// layer3 becomes active and has high refresh rate.
for (int i = 0; i < PRESENT_TIME_HISTORY_SIZE; i++) {
- history().record(layer3.get(), time, isHDR, time);
+ history().record(layer3.get(), time, time);
time += HI_FPS_PERIOD;
}
diff --git a/services/surfaceflinger/tests/unittests/RefreshRateConfigsTest.cpp b/services/surfaceflinger/tests/unittests/RefreshRateConfigsTest.cpp
index f315a8a..546e65c 100644
--- a/services/surfaceflinger/tests/unittests/RefreshRateConfigsTest.cpp
+++ b/services/surfaceflinger/tests/unittests/RefreshRateConfigsTest.cpp
@@ -30,27 +30,19 @@
namespace android {
namespace scheduler {
-using RefreshRateType = RefreshRateConfigs::RefreshRateType;
using RefreshRate = RefreshRateConfigs::RefreshRate;
class RefreshRateConfigsTest : public testing::Test {
protected:
- static constexpr int CONFIG_ID_60 = 0;
- static constexpr hwc2_config_t HWC2_CONFIG_ID_60 = 0;
- static constexpr int CONFIG_ID_90 = 1;
- static constexpr hwc2_config_t HWC2_CONFIG_ID_90 = 1;
+ static inline const HwcConfigIndexType HWC_CONFIG_ID_60 = HwcConfigIndexType(0);
+ static inline const HwcConfigIndexType HWC_CONFIG_ID_90 = HwcConfigIndexType(1);
+ static inline const HwcConfigGroupType HWC_GROUP_ID_0 = HwcConfigGroupType(0);
+ static inline const HwcConfigGroupType HWC_GROUP_ID_1 = HwcConfigGroupType(1);
static constexpr int64_t VSYNC_60 = 16666667;
static constexpr int64_t VSYNC_90 = 11111111;
RefreshRateConfigsTest();
~RefreshRateConfigsTest();
-
- void assertRatesEqual(const RefreshRate& left, const RefreshRate& right) {
- ASSERT_EQ(left.configId, right.configId);
- ASSERT_EQ(left.name, right.name);
- ASSERT_EQ(left.fps, right.fps);
- ASSERT_EQ(left.vsyncPeriod, right.vsyncPeriod);
- }
};
RefreshRateConfigsTest::RefreshRateConfigsTest() {
@@ -69,40 +61,173 @@
/* ------------------------------------------------------------------------
* Test cases
*/
-TEST_F(RefreshRateConfigsTest, oneDeviceConfig_isRejected) {
- std::vector<RefreshRateConfigs::InputConfig> configs{{HWC2_CONFIG_ID_60, VSYNC_60}};
+TEST_F(RefreshRateConfigsTest, oneDeviceConfig_SwitchingSupported) {
+ std::vector<RefreshRateConfigs::InputConfig> configs{
+ {{HWC_CONFIG_ID_60, HWC_GROUP_ID_0, VSYNC_60}}};
auto refreshRateConfigs =
std::make_unique<RefreshRateConfigs>(/*refreshRateSwitching=*/true, configs,
- /*currentConfig=*/0);
+ /*currentConfigId=*/HWC_CONFIG_ID_60);
+ ASSERT_TRUE(refreshRateConfigs->refreshRateSwitchingSupported());
+}
+
+TEST_F(RefreshRateConfigsTest, oneDeviceConfig_SwitchingNotSupported) {
+ std::vector<RefreshRateConfigs::InputConfig> configs{
+ {{HWC_CONFIG_ID_60, HWC_GROUP_ID_0, VSYNC_60}}};
+ auto refreshRateConfigs =
+ std::make_unique<RefreshRateConfigs>(/*refreshRateSwitching=*/false, configs,
+ /*currentConfigId=*/HWC_CONFIG_ID_60);
ASSERT_FALSE(refreshRateConfigs->refreshRateSwitchingSupported());
}
TEST_F(RefreshRateConfigsTest, twoDeviceConfigs_storesFullRefreshRateMap) {
- std::vector<RefreshRateConfigs::InputConfig> configs{{HWC2_CONFIG_ID_60, VSYNC_60},
- {HWC2_CONFIG_ID_90, VSYNC_90}};
+ std::vector<RefreshRateConfigs::InputConfig> configs{
+ {{HWC_CONFIG_ID_60, HWC_GROUP_ID_0, VSYNC_60},
+ {HWC_CONFIG_ID_90, HWC_GROUP_ID_0, VSYNC_90}}};
auto refreshRateConfigs =
std::make_unique<RefreshRateConfigs>(/*refreshRateSwitching=*/true, configs,
- /*currentConfig=*/0);
+ /*currentConfigId=*/HWC_CONFIG_ID_60);
ASSERT_TRUE(refreshRateConfigs->refreshRateSwitchingSupported());
- const auto& rates = refreshRateConfigs->getRefreshRateMap();
- ASSERT_EQ(2, rates.size());
- const auto& defaultRate = rates.find(RefreshRateType::DEFAULT);
- const auto& performanceRate = rates.find(RefreshRateType::PERFORMANCE);
- ASSERT_NE(rates.end(), defaultRate);
- ASSERT_NE(rates.end(), performanceRate);
- 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);
+ const auto minRate = refreshRateConfigs->getMinRefreshRate();
+ const auto performanceRate = refreshRateConfigs->getMaxRefreshRate();
- assertRatesEqual(expectedDefaultConfig,
- refreshRateConfigs->getRefreshRateFromType(RefreshRateType::DEFAULT));
- assertRatesEqual(expectedPerformanceConfig,
- refreshRateConfigs->getRefreshRateFromType(RefreshRateType::PERFORMANCE));
+ RefreshRate expectedDefaultConfig = {HWC_CONFIG_ID_60, VSYNC_60, HWC_GROUP_ID_0, "60fps", 60};
+ ASSERT_EQ(expectedDefaultConfig, minRate);
+ RefreshRate expectedPerformanceConfig = {HWC_CONFIG_ID_90, VSYNC_90, HWC_GROUP_ID_0, "90fps",
+ 90};
+ ASSERT_EQ(expectedPerformanceConfig, performanceRate);
+
+ const auto minRateByPolicy = refreshRateConfigs->getMinRefreshRateByPolicy();
+ const auto performanceRateByPolicy = refreshRateConfigs->getMaxRefreshRateByPolicy();
+ ASSERT_EQ(minRateByPolicy, minRate);
+ ASSERT_EQ(performanceRateByPolicy, performanceRate);
}
+
+TEST_F(RefreshRateConfigsTest, twoDeviceConfigs_storesFullRefreshRateMap_differentGroups) {
+ std::vector<RefreshRateConfigs::InputConfig> configs{
+ {{HWC_CONFIG_ID_60, HWC_GROUP_ID_0, VSYNC_60},
+ {HWC_CONFIG_ID_90, HWC_GROUP_ID_1, VSYNC_90}}};
+ auto refreshRateConfigs =
+ std::make_unique<RefreshRateConfigs>(/*refreshRateSwitching=*/true, configs,
+ /*currentConfigId=*/HWC_CONFIG_ID_60);
+
+ ASSERT_TRUE(refreshRateConfigs->refreshRateSwitchingSupported());
+ const auto minRate = refreshRateConfigs->getMinRefreshRateByPolicy();
+ const auto performanceRate = refreshRateConfigs->getMaxRefreshRate();
+ const auto minRate60 = refreshRateConfigs->getMinRefreshRateByPolicy();
+ const auto performanceRate60 = refreshRateConfigs->getMaxRefreshRateByPolicy();
+
+ RefreshRate expectedDefaultConfig = {HWC_CONFIG_ID_60, VSYNC_60, HWC_GROUP_ID_0, "60fps", 60};
+ ASSERT_EQ(expectedDefaultConfig, minRate);
+ ASSERT_EQ(expectedDefaultConfig, minRate60);
+ ASSERT_EQ(expectedDefaultConfig, performanceRate60);
+
+ refreshRateConfigs->setPolicy(HWC_CONFIG_ID_90, 60, 90);
+ refreshRateConfigs->setCurrentConfigId(HWC_CONFIG_ID_90);
+
+ ASSERT_TRUE(refreshRateConfigs->refreshRateSwitchingSupported());
+ const auto minRate90 = refreshRateConfigs->getMinRefreshRateByPolicy();
+ const auto performanceRate90 = refreshRateConfigs->getMaxRefreshRateByPolicy();
+
+ RefreshRate expectedPerformanceConfig = {HWC_CONFIG_ID_90, VSYNC_90, HWC_GROUP_ID_1, "90fps",
+ 90};
+ ASSERT_EQ(expectedPerformanceConfig, performanceRate);
+ ASSERT_EQ(expectedPerformanceConfig, minRate90);
+ ASSERT_EQ(expectedPerformanceConfig, performanceRate90);
+}
+
+TEST_F(RefreshRateConfigsTest, twoDeviceConfigs_policyChange) {
+ std::vector<RefreshRateConfigs::InputConfig> configs{
+ {{HWC_CONFIG_ID_60, HWC_GROUP_ID_0, VSYNC_60},
+ {HWC_CONFIG_ID_90, HWC_GROUP_ID_0, VSYNC_90}}};
+ auto refreshRateConfigs =
+ std::make_unique<RefreshRateConfigs>(/*refreshRateSwitching=*/true, configs,
+ /*currentConfigId=*/HWC_CONFIG_ID_60);
+ ASSERT_TRUE(refreshRateConfigs->refreshRateSwitchingSupported());
+ auto minRate = refreshRateConfigs->getMinRefreshRateByPolicy();
+ auto performanceRate = refreshRateConfigs->getMaxRefreshRateByPolicy();
+
+ RefreshRate expectedDefaultConfig = {HWC_CONFIG_ID_60, VSYNC_60, HWC_GROUP_ID_0, "60fps", 60};
+ ASSERT_EQ(expectedDefaultConfig, minRate);
+ RefreshRate expectedPerformanceConfig = {HWC_CONFIG_ID_90, VSYNC_90, HWC_GROUP_ID_0, "90fps",
+ 90};
+ ASSERT_EQ(expectedPerformanceConfig, performanceRate);
+
+ refreshRateConfigs->setPolicy(HWC_CONFIG_ID_60, 60, 60);
+ ASSERT_TRUE(refreshRateConfigs->refreshRateSwitchingSupported());
+
+ auto minRate60 = refreshRateConfigs->getMinRefreshRateByPolicy();
+ auto performanceRate60 = refreshRateConfigs->getMaxRefreshRateByPolicy();
+ ASSERT_EQ(expectedDefaultConfig, minRate60);
+ ASSERT_EQ(expectedDefaultConfig, performanceRate60);
+}
+
+TEST_F(RefreshRateConfigsTest, twoDeviceConfigs_getCurrentRefreshRate) {
+ std::vector<RefreshRateConfigs::InputConfig> configs{
+ {{HWC_CONFIG_ID_60, HWC_GROUP_ID_0, VSYNC_60},
+ {HWC_CONFIG_ID_90, HWC_GROUP_ID_0, VSYNC_90}}};
+ auto refreshRateConfigs =
+ std::make_unique<RefreshRateConfigs>(/*refreshRateSwitching=*/true, configs,
+ /*currentConfigId=*/HWC_CONFIG_ID_60);
+ {
+ auto current = refreshRateConfigs->getCurrentRefreshRate();
+ EXPECT_EQ(current.configId, HWC_CONFIG_ID_60);
+ }
+
+ refreshRateConfigs->setCurrentConfigId(HWC_CONFIG_ID_90);
+ {
+ auto current = refreshRateConfigs->getCurrentRefreshRate();
+ EXPECT_EQ(current.configId, HWC_CONFIG_ID_90);
+ }
+
+ refreshRateConfigs->setPolicy(HWC_CONFIG_ID_60, 90, 90);
+ {
+ auto current = refreshRateConfigs->getCurrentRefreshRate();
+ EXPECT_EQ(current.configId, HWC_CONFIG_ID_90);
+ }
+}
+
+TEST_F(RefreshRateConfigsTest, twoDeviceConfigs_getRefreshRateForContent) {
+ std::vector<RefreshRateConfigs::InputConfig> configs{
+ {{HWC_CONFIG_ID_60, HWC_GROUP_ID_0, VSYNC_60},
+ {HWC_CONFIG_ID_90, HWC_GROUP_ID_0, VSYNC_90}}};
+ auto refreshRateConfigs =
+ std::make_unique<RefreshRateConfigs>(/*refreshRateSwitching=*/true, configs,
+ /*currentConfigId=*/HWC_CONFIG_ID_60);
+
+ ASSERT_TRUE(refreshRateConfigs->refreshRateSwitchingSupported());
+
+ RefreshRate expected60Config = {HWC_CONFIG_ID_60, VSYNC_60, HWC_GROUP_ID_0, "60fps", 60};
+ RefreshRate expected90Config = {HWC_CONFIG_ID_90, VSYNC_90, HWC_GROUP_ID_0, "90fps", 90};
+
+ ASSERT_EQ(expected90Config, refreshRateConfigs->getRefreshRateForContent(90.0f));
+ ASSERT_EQ(expected60Config, refreshRateConfigs->getRefreshRateForContent(60.0f));
+ ASSERT_EQ(expected90Config, refreshRateConfigs->getRefreshRateForContent(45.0f));
+ ASSERT_EQ(expected60Config, refreshRateConfigs->getRefreshRateForContent(30.0f));
+ ASSERT_EQ(expected60Config, refreshRateConfigs->getRefreshRateForContent(24.0f));
+
+ refreshRateConfigs->setPolicy(HWC_CONFIG_ID_60, 60, 60);
+ ASSERT_EQ(expected60Config, refreshRateConfigs->getRefreshRateForContent(90.0f));
+ ASSERT_EQ(expected60Config, refreshRateConfigs->getRefreshRateForContent(60.0f));
+ ASSERT_EQ(expected60Config, refreshRateConfigs->getRefreshRateForContent(45.0f));
+ ASSERT_EQ(expected60Config, refreshRateConfigs->getRefreshRateForContent(30.0f));
+ ASSERT_EQ(expected60Config, refreshRateConfigs->getRefreshRateForContent(24.0f));
+
+ refreshRateConfigs->setPolicy(HWC_CONFIG_ID_60, 90, 90);
+ ASSERT_EQ(expected90Config, refreshRateConfigs->getRefreshRateForContent(90.0f));
+ ASSERT_EQ(expected90Config, refreshRateConfigs->getRefreshRateForContent(60.0f));
+ ASSERT_EQ(expected90Config, refreshRateConfigs->getRefreshRateForContent(45.0f));
+ ASSERT_EQ(expected90Config, refreshRateConfigs->getRefreshRateForContent(30.0f));
+ ASSERT_EQ(expected90Config, refreshRateConfigs->getRefreshRateForContent(24.0f));
+ refreshRateConfigs->setPolicy(HWC_CONFIG_ID_60, 0, 120);
+ ASSERT_EQ(expected90Config, refreshRateConfigs->getRefreshRateForContent(90.0f));
+ ASSERT_EQ(expected60Config, refreshRateConfigs->getRefreshRateForContent(60.0f));
+ ASSERT_EQ(expected90Config, refreshRateConfigs->getRefreshRateForContent(45.0f));
+ ASSERT_EQ(expected60Config, refreshRateConfigs->getRefreshRateForContent(30.0f));
+ ASSERT_EQ(expected60Config, refreshRateConfigs->getRefreshRateForContent(24.0f));
+}
+
} // namespace
} // namespace scheduler
} // namespace android
diff --git a/services/surfaceflinger/tests/unittests/RefreshRateStatsTest.cpp b/services/surfaceflinger/tests/unittests/RefreshRateStatsTest.cpp
index cec0b32..ef4699f 100644
--- a/services/surfaceflinger/tests/unittests/RefreshRateStatsTest.cpp
+++ b/services/surfaceflinger/tests/unittests/RefreshRateStatsTest.cpp
@@ -33,8 +33,9 @@
class RefreshRateStatsTest : public testing::Test {
protected:
- static constexpr int CONFIG_ID_90 = 0;
- static constexpr int CONFIG_ID_60 = 1;
+ static inline const auto CONFIG_ID_0 = HwcConfigIndexType(0);
+ static inline const auto CONFIG_ID_1 = HwcConfigIndexType(1);
+ static inline const auto CONFIG_GROUP_0 = HwcConfigGroupType(0);
static constexpr int64_t VSYNC_90 = 11111111;
static constexpr int64_t VSYNC_60 = 16666667;
@@ -43,10 +44,10 @@
void init(const std::vector<RefreshRateConfigs::InputConfig>& configs) {
mRefreshRateConfigs = std::make_unique<RefreshRateConfigs>(
- /*refreshRateSwitching=*/true, configs, /*currentConfig=*/0);
+ /*refreshRateSwitching=*/true, configs, /*currentConfig=*/CONFIG_ID_0);
mRefreshRateStats =
std::make_unique<RefreshRateStats>(*mRefreshRateConfigs, mTimeStats,
- /*currentConfig=*/0,
+ /*currentConfigId=*/CONFIG_ID_0,
/*currentPowerMode=*/HWC_POWER_MODE_OFF);
}
@@ -72,7 +73,7 @@
* Test cases
*/
TEST_F(RefreshRateStatsTest, oneConfigTest) {
- init({{CONFIG_ID_90, VSYNC_90}});
+ init({{{CONFIG_ID_0, CONFIG_GROUP_0, VSYNC_90}}});
EXPECT_CALL(mTimeStats, recordRefreshRate(0, _)).Times(AtLeast(1));
EXPECT_CALL(mTimeStats, recordRefreshRate(90, _)).Times(AtLeast(1));
@@ -91,7 +92,7 @@
EXPECT_LT(screenOff, times["ScreenOff"]);
EXPECT_EQ(0u, times.count("90fps"));
- mRefreshRateStats->setConfigMode(CONFIG_ID_90);
+ mRefreshRateStats->setConfigMode(CONFIG_ID_0);
mRefreshRateStats->setPowerMode(HWC_POWER_MODE_NORMAL);
screenOff = mRefreshRateStats->getTotalTimes()["ScreenOff"];
std::this_thread::sleep_for(std::chrono::milliseconds(2));
@@ -107,7 +108,7 @@
EXPECT_LT(screenOff, times["ScreenOff"]);
EXPECT_EQ(ninety, times["90fps"]);
- mRefreshRateStats->setConfigMode(CONFIG_ID_90);
+ mRefreshRateStats->setConfigMode(CONFIG_ID_0);
screenOff = mRefreshRateStats->getTotalTimes()["ScreenOff"];
std::this_thread::sleep_for(std::chrono::milliseconds(2));
times = mRefreshRateStats->getTotalTimes();
@@ -118,7 +119,7 @@
}
TEST_F(RefreshRateStatsTest, twoConfigsTest) {
- init({{CONFIG_ID_90, VSYNC_90}, {CONFIG_ID_60, VSYNC_60}});
+ init({{{CONFIG_ID_0, CONFIG_GROUP_0, VSYNC_90}, {CONFIG_ID_1, CONFIG_GROUP_0, VSYNC_60}}});
EXPECT_CALL(mTimeStats, recordRefreshRate(0, _)).Times(AtLeast(1));
EXPECT_CALL(mTimeStats, recordRefreshRate(60, _)).Times(AtLeast(1));
@@ -137,7 +138,7 @@
times = mRefreshRateStats->getTotalTimes();
EXPECT_LT(screenOff, times["ScreenOff"]);
- mRefreshRateStats->setConfigMode(CONFIG_ID_90);
+ mRefreshRateStats->setConfigMode(CONFIG_ID_0);
mRefreshRateStats->setPowerMode(HWC_POWER_MODE_NORMAL);
screenOff = mRefreshRateStats->getTotalTimes()["ScreenOff"];
std::this_thread::sleep_for(std::chrono::milliseconds(2));
@@ -147,7 +148,7 @@
EXPECT_LT(0, times["90fps"]);
// When power mode is normal, time for configs updates.
- mRefreshRateStats->setConfigMode(CONFIG_ID_60);
+ mRefreshRateStats->setConfigMode(CONFIG_ID_1);
int ninety = mRefreshRateStats->getTotalTimes()["90fps"];
std::this_thread::sleep_for(std::chrono::milliseconds(2));
times = mRefreshRateStats->getTotalTimes();
@@ -156,7 +157,7 @@
ASSERT_EQ(1u, times.count("60fps"));
EXPECT_LT(0, times["60fps"]);
- mRefreshRateStats->setConfigMode(CONFIG_ID_90);
+ mRefreshRateStats->setConfigMode(CONFIG_ID_0);
int sixty = mRefreshRateStats->getTotalTimes()["60fps"];
std::this_thread::sleep_for(std::chrono::milliseconds(2));
times = mRefreshRateStats->getTotalTimes();
@@ -164,7 +165,7 @@
EXPECT_LT(ninety, times["90fps"]);
EXPECT_EQ(sixty, times["60fps"]);
- mRefreshRateStats->setConfigMode(CONFIG_ID_60);
+ mRefreshRateStats->setConfigMode(CONFIG_ID_1);
ninety = mRefreshRateStats->getTotalTimes()["90fps"];
std::this_thread::sleep_for(std::chrono::milliseconds(2));
times = mRefreshRateStats->getTotalTimes();
@@ -175,7 +176,7 @@
// 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);
+ mRefreshRateStats->setConfigMode(CONFIG_ID_0);
sixty = mRefreshRateStats->getTotalTimes()["60fps"];
std::this_thread::sleep_for(std::chrono::milliseconds(2));
times = mRefreshRateStats->getTotalTimes();
@@ -183,7 +184,7 @@
EXPECT_EQ(ninety, times["90fps"]);
EXPECT_EQ(sixty, times["60fps"]);
- mRefreshRateStats->setConfigMode(CONFIG_ID_60);
+ mRefreshRateStats->setConfigMode(CONFIG_ID_1);
screenOff = mRefreshRateStats->getTotalTimes()["ScreenOff"];
std::this_thread::sleep_for(std::chrono::milliseconds(2));
times = mRefreshRateStats->getTotalTimes();
diff --git a/services/surfaceflinger/tests/unittests/SchedulerTest.cpp b/services/surfaceflinger/tests/unittests/SchedulerTest.cpp
index b4cc1e1..40536ab 100644
--- a/services/surfaceflinger/tests/unittests/SchedulerTest.cpp
+++ b/services/surfaceflinger/tests/unittests/SchedulerTest.cpp
@@ -50,10 +50,11 @@
::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);
+ std::vector<scheduler::RefreshRateConfigs::InputConfig> configs{
+ {{HwcConfigIndexType(0), HwcConfigGroupType(0), 16666667}}};
+ mRefreshRateConfigs = std::make_unique<
+ scheduler::RefreshRateConfigs>(/*refreshRateSwitching=*/false, configs,
+ /*currentConfig=*/HwcConfigIndexType(0));
mScheduler = std::make_unique<TestableScheduler>(*mRefreshRateConfigs);
diff --git a/services/surfaceflinger/tests/unittests/StrongTypingTest.cpp b/services/surfaceflinger/tests/unittests/StrongTypingTest.cpp
index b9ddcd7..5406879 100644
--- a/services/surfaceflinger/tests/unittests/StrongTypingTest.cpp
+++ b/services/surfaceflinger/tests/unittests/StrongTypingTest.cpp
@@ -56,18 +56,18 @@
EXPECT_THAT(f1 + f2, Eq(FunkyType(32)));
EXPECT_THAT(f2 + f1, Eq(FunkyType(32)));
- EXPECT_THAT(++f1, Eq(11));
- EXPECT_THAT(f1, Eq(11));
- EXPECT_THAT(f1++, Eq(11));
- EXPECT_THAT(f1++, Eq(12));
- EXPECT_THAT(f1, Eq(13));
+ EXPECT_THAT(++f1.value(), Eq(11));
+ EXPECT_THAT(f1.value(), Eq(11));
+ EXPECT_THAT(f1++.value(), Eq(11));
+ EXPECT_THAT(f1++.value(), Eq(12));
+ EXPECT_THAT(f1.value(), Eq(13));
auto f3 = f1;
EXPECT_THAT(f1, Eq(f3));
EXPECT_THAT(f1, Lt(f2));
f3 += f1;
- EXPECT_THAT(f1, Eq(13));
- EXPECT_THAT(f3, Eq(26));
+ EXPECT_THAT(f1.value(), Eq(13));
+ EXPECT_THAT(f3.value(), Eq(26));
}
} // namespace android
diff --git a/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h b/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
index 94fc5f7..c4b8408 100644
--- a/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
+++ b/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
@@ -193,15 +193,15 @@
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);
+ std::vector<scheduler::RefreshRateConfigs::InputConfig> configs{
+ {{HwcConfigIndexType(0), HwcConfigGroupType(0), 16666667}}};
+ mFlinger->mRefreshRateConfigs = std::make_unique<
+ scheduler::RefreshRateConfigs>(/*refreshRateSwitching=*/false, configs,
+ /*currentConfig=*/HwcConfigIndexType(0));
+ mFlinger->mRefreshRateStats = std::make_unique<
+ scheduler::RefreshRateStats>(*mFlinger->mRefreshRateConfigs, *mFlinger->mTimeStats,
+ /*currentConfig=*/HwcConfigIndexType(0),
+ /*powerMode=*/HWC_POWER_MODE_OFF);
mScheduler =
new TestableScheduler(std::move(primaryDispSync), std::move(eventControlThread),
@@ -429,6 +429,7 @@
static constexpr int32_t DEFAULT_WIDTH = 1920;
static constexpr int32_t DEFAULT_HEIGHT = 1280;
static constexpr int32_t DEFAULT_REFRESH_RATE = 16'666'666;
+ static constexpr int32_t DEFAULT_CONFIG_GROUP = 7;
static constexpr int32_t DEFAULT_DPI = 320;
static constexpr int32_t DEFAULT_ACTIVE_CONFIG = 0;
static constexpr int32_t DEFAULT_POWER_MODE = 2;
@@ -452,7 +453,7 @@
return *this;
}
- auto& setRefreshRate(int32_t refreshRate) {
+ auto& setRefreshRate(uint32_t refreshRate) {
mRefreshRate = refreshRate;
return *this;
}
@@ -499,6 +500,7 @@
config.setVsyncPeriod(mRefreshRate);
config.setDpiX(mDpiX);
config.setDpiY(mDpiY);
+ config.setConfigGroup(mConfigGroup);
display->mutableConfigs().emplace(mActiveConfig, config.build());
display->mutableIsConnected() = true;
display->setPowerMode(static_cast<HWC2::PowerMode>(mPowerMode));
@@ -522,8 +524,9 @@
hwc2_display_t mHwcDisplayId = DEFAULT_HWC_DISPLAY_ID;
int32_t mWidth = DEFAULT_WIDTH;
int32_t mHeight = DEFAULT_HEIGHT;
- int32_t mRefreshRate = DEFAULT_REFRESH_RATE;
+ uint32_t mRefreshRate = DEFAULT_REFRESH_RATE;
int32_t mDpiX = DEFAULT_DPI;
+ int32_t mConfigGroup = DEFAULT_CONFIG_GROUP;
int32_t mDpiY = DEFAULT_DPI;
int32_t mActiveConfig = DEFAULT_ACTIVE_CONFIG;
int32_t mPowerMode = DEFAULT_POWER_MODE;
diff --git a/services/surfaceflinger/tests/unittests/mock/MockEventThread.h b/services/surfaceflinger/tests/unittests/mock/MockEventThread.h
index ed35ebf..f7c3804 100644
--- a/services/surfaceflinger/tests/unittests/mock/MockEventThread.h
+++ b/services/surfaceflinger/tests/unittests/mock/MockEventThread.h
@@ -33,7 +33,7 @@
MOCK_METHOD0(onScreenReleased, void());
MOCK_METHOD0(onScreenAcquired, void());
MOCK_METHOD2(onHotplugReceived, void(PhysicalDisplayId, bool));
- MOCK_METHOD2(onConfigChanged, void(PhysicalDisplayId, int32_t));
+ MOCK_METHOD2(onConfigChanged, void(PhysicalDisplayId, HwcConfigIndexType));
MOCK_CONST_METHOD1(dump, void(std::string&));
MOCK_METHOD1(setPhaseOffset, void(nsecs_t phaseOffset));
MOCK_METHOD1(registerDisplayEventConnection,