Loading services/surfaceflinger/Scheduler/RefreshRateConfigs.cpp +36 −6 Original line number Diff line number Diff line Loading @@ -107,9 +107,39 @@ std::pair<nsecs_t, nsecs_t> RefreshRateConfigs::getDisplayFrames(nsecs_t layerPe return {quotient, remainder}; } bool RefreshRateConfigs::isVoteAllowed(const LayerRequirement& layer, const RefreshRate& refreshRate) const { switch (layer.vote) { case LayerVoteType::ExplicitExactOrMultiple: case LayerVoteType::Heuristic: if (mConfig.frameRateMultipleThreshold != 0 && refreshRate.fps.greaterThanOrEqualWithMargin( Fps(mConfig.frameRateMultipleThreshold)) && layer.desiredRefreshRate.lessThanWithMargin( Fps(mConfig.frameRateMultipleThreshold / 2))) { // Don't vote high refresh rates past the threshold for layers with a low desired // refresh rate. For example, desired 24 fps with 120 Hz threshold means no vote for // 120 Hz, but desired 60 fps should have a vote. return false; } break; case LayerVoteType::ExplicitDefault: case LayerVoteType::ExplicitExact: case LayerVoteType::Max: case LayerVoteType::Min: case LayerVoteType::NoVote: break; } return true; } float RefreshRateConfigs::calculateLayerScoreLocked(const LayerRequirement& layer, const RefreshRate& refreshRate, bool isSeamlessSwitch) const { if (!isVoteAllowed(layer, refreshRate)) { return 0; } // Slightly prefer seamless switches. constexpr float kSeamedSwitchPenalty = 0.95f; const float seamlessness = isSeamlessSwitch ? 1.0f : kSeamedSwitchPenalty; Loading Loading @@ -331,8 +361,9 @@ RefreshRate RefreshRateConfigs::getBestRefreshRateLocked( const auto& defaultMode = mRefreshRates.at(policy->defaultMode); for (const auto& layer : layers) { ALOGV("Calculating score for %s (%s, weight %.2f)", layer.name.c_str(), layerVoteTypeString(layer.vote).c_str(), layer.weight); ALOGV("Calculating score for %s (%s, weight %.2f, desired %.2f) ", layer.name.c_str(), layerVoteTypeString(layer.vote).c_str(), layer.weight, layer.desiredRefreshRate.getValue()); if (layer.vote == LayerVoteType::NoVote || layer.vote == LayerVoteType::Min) { continue; } Loading Loading @@ -646,9 +677,8 @@ void RefreshRateConfigs::setCurrentModeId(DisplayModeId modeId) { } RefreshRateConfigs::RefreshRateConfigs(const DisplayModes& modes, DisplayModeId currentModeId, bool enableFrameRateOverride) : mKnownFrameRates(constructKnownFrameRates(modes)), mEnableFrameRateOverride(enableFrameRateOverride) { Config config) : mKnownFrameRates(constructKnownFrameRates(modes)), mConfig(config) { updateDisplayModes(modes, currentModeId); } Loading Loading @@ -685,7 +715,7 @@ void RefreshRateConfigs::updateDisplayModes(const DisplayModes& modes, mMaxSupportedRefreshRate = sortedModes.back(); mSupportsFrameRateOverride = false; if (mEnableFrameRateOverride) { if (mConfig.enableFrameRateOverride) { for (const auto& mode1 : sortedModes) { for (const auto& mode2 : sortedModes) { if (getFrameRateDivider(mode1->getFps(), mode2->getFps()) >= 2) { Loading services/surfaceflinger/Scheduler/RefreshRateConfigs.h +17 −3 Original line number Diff line number Diff line Loading @@ -302,8 +302,19 @@ public: // Returns a known frame rate that is the closest to frameRate Fps findClosestKnownFrameRate(Fps frameRate) const; // Configuration flags. struct Config { bool enableFrameRateOverride = false; // Specifies the upper refresh rate threshold (inclusive) for layer vote types of multiple // or heuristic, such that refresh rates higher than this value will not be voted for. 0 if // no threshold is set. int frameRateMultipleThreshold = 0; }; RefreshRateConfigs(const DisplayModes& modes, DisplayModeId currentModeId, bool enableFrameRateOverride = false); Config config = {.enableFrameRateOverride = false, .frameRateMultipleThreshold = 0}); void updateDisplayModes(const DisplayModes& mode, DisplayModeId currentModeId) EXCLUDES(mLock); Loading Loading @@ -387,6 +398,9 @@ private: const Policy* getCurrentPolicyLocked() const REQUIRES(mLock); bool isPolicyValidLocked(const Policy& policy) const REQUIRES(mLock); // Returns whether the layer is allowed to vote for the given refresh rate. bool isVoteAllowed(const LayerRequirement&, const RefreshRate&) const; // calculates a score for a layer. Used to determine the display refresh rate // and the frame rate override for certains applications. float calculateLayerScoreLocked(const LayerRequirement&, const RefreshRate&, Loading Loading @@ -424,7 +438,7 @@ private: // from based on the closest value. const std::vector<Fps> mKnownFrameRates; const bool mEnableFrameRateOverride; const Config mConfig; bool mSupportsFrameRateOverride; struct GetBestRefreshRateInvocation { Loading services/surfaceflinger/SurfaceFlinger.cpp +9 −4 Original line number Diff line number Diff line Loading @@ -3118,10 +3118,15 @@ void SurfaceFlinger::initScheduler(const DisplayDeviceState& displayState) { return; } const auto displayId = displayState.physical->id; mRefreshRateConfigs = std::make_unique< scheduler::RefreshRateConfigs>(displayState.physical->supportedModes, displayState.physical->activeMode->getId(), android::sysprop::enable_frame_rate_override(false)); scheduler::RefreshRateConfigs::Config config = {.enableFrameRateOverride = android::sysprop::enable_frame_rate_override(false), .frameRateMultipleThreshold = base::GetIntProperty("debug.sf.frame_rate_multiple_threshold", 0)}; mRefreshRateConfigs = std::make_unique<scheduler::RefreshRateConfigs>(displayState.physical->supportedModes, displayState.physical->activeMode ->getId(), config); const auto currRefreshRate = displayState.physical->activeMode->getFps(); mRefreshRateStats = std::make_unique<scheduler::RefreshRateStats>(*mTimeStats, currRefreshRate, hal::PowerMode::OFF); Loading services/surfaceflinger/tests/unittests/RefreshRateConfigsTest.cpp +168 −10 Original line number Diff line number Diff line Loading @@ -165,6 +165,7 @@ protected: RefreshRate::ConstructorTag(0)}; RefreshRate mExpected120Config = {HWC_CONFIG_ID_120, mConfig120, Fps(120), RefreshRate::ConstructorTag(0)}; private: DisplayModePtr createDisplayMode(DisplayModeId modeId, int32_t group, int64_t vsyncPeriod, ui::Size resolution = ui::Size()); Loading Loading @@ -487,6 +488,52 @@ TEST_F(RefreshRateConfigsTest, getBestRefreshRate_60_90) { refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); } TEST_F(RefreshRateConfigsTest, getBestRefreshRate_multipleThreshold_60_90) { RefreshRateConfigs::Config config = {.frameRateMultipleThreshold = 90}; auto refreshRateConfigs = std::make_unique<RefreshRateConfigs>(m60_90Device, /*currentConfigId=*/HWC_CONFIG_ID_60, config); auto layers = std::vector<LayerRequirement>{LayerRequirement{.weight = 1.0f}}; auto& lr = layers[0]; lr.vote = LayerVoteType::Min; lr.name = "Min"; EXPECT_EQ(mExpected60Config, refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); lr.vote = LayerVoteType::Max; lr.name = "Max"; EXPECT_EQ(mExpected90Config, refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); lr.desiredRefreshRate = Fps(90.0f); lr.vote = LayerVoteType::Heuristic; lr.name = "90Hz Heuristic"; EXPECT_EQ(mExpected90Config, refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); lr.desiredRefreshRate = Fps(60.0f); lr.name = "60Hz Heuristic"; EXPECT_EQ(mExpected60Config, refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); lr.desiredRefreshRate = Fps(45.0f); lr.name = "45Hz Heuristic"; EXPECT_EQ(mExpected90Config, refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); lr.desiredRefreshRate = Fps(30.0f); lr.name = "30Hz Heuristic"; EXPECT_EQ(mExpected60Config, refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); lr.desiredRefreshRate = Fps(24.0f); lr.name = "24Hz Heuristic"; EXPECT_EQ(mExpected60Config, refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); } TEST_F(RefreshRateConfigsTest, getBestRefreshRate_60_72_90) { auto refreshRateConfigs = std::make_unique<RefreshRateConfigs>(m60_72_90Device, Loading Loading @@ -649,6 +696,99 @@ TEST_F(RefreshRateConfigsTest, getBestRefreshRate_30_60_90_120_DifferentTypes) { refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); } TEST_F(RefreshRateConfigsTest, getBestRefreshRate_30_60_90_120_DifferentTypes_multipleThreshold) { RefreshRateConfigs::Config config = {.frameRateMultipleThreshold = 120}; auto refreshRateConfigs = std::make_unique<RefreshRateConfigs>(m30_60_72_90_120Device, /*currentConfigId=*/HWC_CONFIG_ID_60, config); auto layers = std::vector<LayerRequirement>{LayerRequirement{.weight = 1.0f}, LayerRequirement{.weight = 1.0f}}; auto& lr1 = layers[0]; auto& lr2 = layers[1]; lr1.desiredRefreshRate = Fps(24.0f); lr1.vote = LayerVoteType::ExplicitDefault; lr1.name = "24Hz ExplicitDefault"; lr2.desiredRefreshRate = Fps(60.0f); lr2.vote = LayerVoteType::Heuristic; lr2.name = "60Hz Heuristic"; EXPECT_EQ(mExpected120Config, refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); lr1.desiredRefreshRate = Fps(24.0f); lr1.vote = LayerVoteType::ExplicitExactOrMultiple; lr1.name = "24Hz ExplicitExactOrMultiple"; lr2.desiredRefreshRate = Fps(60.0f); lr2.vote = LayerVoteType::Heuristic; lr2.name = "60Hz Heuristic"; EXPECT_EQ(mExpected60Config, refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); lr1.desiredRefreshRate = Fps(24.0f); lr1.vote = LayerVoteType::ExplicitExactOrMultiple; lr1.name = "24Hz ExplicitExactOrMultiple"; lr2.desiredRefreshRate = Fps(60.0f); lr2.vote = LayerVoteType::ExplicitDefault; lr2.name = "60Hz ExplicitDefault"; EXPECT_EQ(mExpected72Config, refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); lr1.desiredRefreshRate = Fps(24.0f); lr1.vote = LayerVoteType::ExplicitExactOrMultiple; lr1.name = "24Hz ExplicitExactOrMultiple"; lr2.desiredRefreshRate = Fps(90.0f); lr2.vote = LayerVoteType::Heuristic; lr2.name = "90Hz Heuristic"; EXPECT_EQ(mExpected90Config, refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); lr1.desiredRefreshRate = Fps(24.0f); lr1.vote = LayerVoteType::ExplicitExactOrMultiple; lr1.name = "24Hz ExplicitExactOrMultiple"; lr2.desiredRefreshRate = Fps(90.0f); lr2.vote = LayerVoteType::ExplicitDefault; lr2.name = "90Hz Heuristic"; EXPECT_EQ(mExpected72Config, refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); lr1.desiredRefreshRate = Fps(24.0f); lr1.vote = LayerVoteType::ExplicitDefault; lr1.name = "24Hz ExplicitDefault"; lr2.desiredRefreshRate = Fps(90.0f); lr2.vote = LayerVoteType::Heuristic; lr2.name = "90Hz Heuristic"; EXPECT_EQ(mExpected90Config, refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); lr1.desiredRefreshRate = Fps(24.0f); lr1.vote = LayerVoteType::Heuristic; lr1.name = "24Hz Heuristic"; lr2.desiredRefreshRate = Fps(90.0f); lr2.vote = LayerVoteType::ExplicitDefault; lr2.name = "90Hz ExplicitDefault"; EXPECT_EQ(mExpected72Config, refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); lr1.desiredRefreshRate = Fps(24.0f); lr1.vote = LayerVoteType::ExplicitExactOrMultiple; lr1.name = "24Hz ExplicitExactOrMultiple"; lr2.desiredRefreshRate = Fps(90.0f); lr2.vote = LayerVoteType::ExplicitDefault; lr2.name = "90Hz ExplicitDefault"; EXPECT_EQ(mExpected72Config, refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); lr1.desiredRefreshRate = Fps(24.0f); lr1.vote = LayerVoteType::ExplicitDefault; lr1.name = "24Hz ExplicitDefault"; lr2.desiredRefreshRate = Fps(90.0f); lr2.vote = LayerVoteType::ExplicitExactOrMultiple; lr2.name = "90Hz ExplicitExactOrMultiple"; EXPECT_EQ(mExpected90Config, refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); } TEST_F(RefreshRateConfigsTest, getBestRefreshRate_30_60) { auto refreshRateConfigs = std::make_unique<RefreshRateConfigs>(m30_60Device, Loading Loading @@ -819,6 +959,24 @@ TEST_F(RefreshRateConfigsTest, getBestRefreshRate_24FpsVideo) { } } TEST_F(RefreshRateConfigsTest, getBestRefreshRate_24FpsVideo_multipleThreshold_60_120) { RefreshRateConfigs::Config config = {.frameRateMultipleThreshold = 120}; auto refreshRateConfigs = std::make_unique<RefreshRateConfigs>(m60_120Device, /*currentConfigId=*/HWC_CONFIG_ID_60, config); auto layers = std::vector<LayerRequirement>{LayerRequirement{.weight = 1.0f}}; auto& lr = layers[0]; lr.vote = LayerVoteType::ExplicitExactOrMultiple; for (float fps = 23.0f; fps < 25.0f; fps += 0.1f) { lr.desiredRefreshRate = Fps(fps); const auto& refreshRate = refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}); EXPECT_EQ(mExpected60Config, refreshRate) << fps << "Hz chooses " << refreshRate.getName(); } } TEST_F(RefreshRateConfigsTest, twoDeviceConfigs_getBestRefreshRate_Explicit) { auto refreshRateConfigs = std::make_unique<RefreshRateConfigs>(m60_90Device, Loading Loading @@ -1732,10 +1890,10 @@ TEST_F(RefreshRateConfigsTest, getBestRefreshRate_ExplicitExact) { } TEST_F(RefreshRateConfigsTest, getBestRefreshRate_ExplicitExactEnableFrameRateOverride) { RefreshRateConfigs::Config config = {.enableFrameRateOverride = true}; auto refreshRateConfigs = std::make_unique<RefreshRateConfigs>(m30_60_72_90_120Device, /*currentConfigId=*/HWC_CONFIG_ID_60, /*enableFrameRateOverride=*/true); /*currentConfigId=*/HWC_CONFIG_ID_60, config); auto layers = std::vector<LayerRequirement>{LayerRequirement{.weight = 1.0f}, LayerRequirement{.weight = 0.5f}}; Loading Loading @@ -1846,10 +2004,10 @@ TEST_F(RefreshRateConfigsTest, getBestRefreshRate_WritesCache) { } TEST_F(RefreshRateConfigsTest, getBestRefreshRate_ExplicitExactTouchBoost) { RefreshRateConfigs::Config config = {.enableFrameRateOverride = true}; auto refreshRateConfigs = std::make_unique<RefreshRateConfigs>(m60_120Device, /*currentConfigId=*/HWC_CONFIG_ID_60, /*enableFrameRateOverride=*/true); /*currentConfigId=*/HWC_CONFIG_ID_60, config); auto layers = std::vector<LayerRequirement>{LayerRequirement{.weight = 1.0f}, LayerRequirement{.weight = 0.5f}}; Loading Loading @@ -1950,10 +2108,10 @@ TEST_F(RefreshRateConfigsTest, getFrameRateOverrides_noLayers) { } TEST_F(RefreshRateConfigsTest, getFrameRateOverrides_60on120) { RefreshRateConfigs::Config config = {.enableFrameRateOverride = true}; auto refreshRateConfigs = std::make_unique<RefreshRateConfigs>(m30_60_72_90_120Device, /*currentConfigId=*/ HWC_CONFIG_ID_120, /*enableFrameRateOverride=*/true); HWC_CONFIG_ID_120, config); auto layers = std::vector<LayerRequirement>{LayerRequirement{.weight = 1.0f}}; layers[0].name = "Test layer"; Loading Loading @@ -1995,10 +2153,10 @@ TEST_F(RefreshRateConfigsTest, getFrameRateOverrides_60on120) { } TEST_F(RefreshRateConfigsTest, getFrameRateOverrides_twoUids) { RefreshRateConfigs::Config config = {.enableFrameRateOverride = true}; auto refreshRateConfigs = std::make_unique<RefreshRateConfigs>(m30_60_72_90_120Device, /*currentConfigId=*/ HWC_CONFIG_ID_120, /*enableFrameRateOverride=*/true); HWC_CONFIG_ID_120, config); auto layers = std::vector<LayerRequirement>{ LayerRequirement{.ownerUid = 1234, .weight = 1.0f}, Loading Loading @@ -2035,10 +2193,10 @@ TEST_F(RefreshRateConfigsTest, getFrameRateOverrides_twoUids) { } TEST_F(RefreshRateConfigsTest, getFrameRateOverrides_touch) { RefreshRateConfigs::Config config = {.enableFrameRateOverride = true}; auto refreshRateConfigs = std::make_unique<RefreshRateConfigs>(m30_60_72_90_120Device, /*currentConfigId=*/ HWC_CONFIG_ID_120, /*enableFrameRateOverride=*/true); HWC_CONFIG_ID_120, config); auto layers = std::vector<LayerRequirement>{ LayerRequirement{.ownerUid = 1234, .weight = 1.0f}, Loading Loading
services/surfaceflinger/Scheduler/RefreshRateConfigs.cpp +36 −6 Original line number Diff line number Diff line Loading @@ -107,9 +107,39 @@ std::pair<nsecs_t, nsecs_t> RefreshRateConfigs::getDisplayFrames(nsecs_t layerPe return {quotient, remainder}; } bool RefreshRateConfigs::isVoteAllowed(const LayerRequirement& layer, const RefreshRate& refreshRate) const { switch (layer.vote) { case LayerVoteType::ExplicitExactOrMultiple: case LayerVoteType::Heuristic: if (mConfig.frameRateMultipleThreshold != 0 && refreshRate.fps.greaterThanOrEqualWithMargin( Fps(mConfig.frameRateMultipleThreshold)) && layer.desiredRefreshRate.lessThanWithMargin( Fps(mConfig.frameRateMultipleThreshold / 2))) { // Don't vote high refresh rates past the threshold for layers with a low desired // refresh rate. For example, desired 24 fps with 120 Hz threshold means no vote for // 120 Hz, but desired 60 fps should have a vote. return false; } break; case LayerVoteType::ExplicitDefault: case LayerVoteType::ExplicitExact: case LayerVoteType::Max: case LayerVoteType::Min: case LayerVoteType::NoVote: break; } return true; } float RefreshRateConfigs::calculateLayerScoreLocked(const LayerRequirement& layer, const RefreshRate& refreshRate, bool isSeamlessSwitch) const { if (!isVoteAllowed(layer, refreshRate)) { return 0; } // Slightly prefer seamless switches. constexpr float kSeamedSwitchPenalty = 0.95f; const float seamlessness = isSeamlessSwitch ? 1.0f : kSeamedSwitchPenalty; Loading Loading @@ -331,8 +361,9 @@ RefreshRate RefreshRateConfigs::getBestRefreshRateLocked( const auto& defaultMode = mRefreshRates.at(policy->defaultMode); for (const auto& layer : layers) { ALOGV("Calculating score for %s (%s, weight %.2f)", layer.name.c_str(), layerVoteTypeString(layer.vote).c_str(), layer.weight); ALOGV("Calculating score for %s (%s, weight %.2f, desired %.2f) ", layer.name.c_str(), layerVoteTypeString(layer.vote).c_str(), layer.weight, layer.desiredRefreshRate.getValue()); if (layer.vote == LayerVoteType::NoVote || layer.vote == LayerVoteType::Min) { continue; } Loading Loading @@ -646,9 +677,8 @@ void RefreshRateConfigs::setCurrentModeId(DisplayModeId modeId) { } RefreshRateConfigs::RefreshRateConfigs(const DisplayModes& modes, DisplayModeId currentModeId, bool enableFrameRateOverride) : mKnownFrameRates(constructKnownFrameRates(modes)), mEnableFrameRateOverride(enableFrameRateOverride) { Config config) : mKnownFrameRates(constructKnownFrameRates(modes)), mConfig(config) { updateDisplayModes(modes, currentModeId); } Loading Loading @@ -685,7 +715,7 @@ void RefreshRateConfigs::updateDisplayModes(const DisplayModes& modes, mMaxSupportedRefreshRate = sortedModes.back(); mSupportsFrameRateOverride = false; if (mEnableFrameRateOverride) { if (mConfig.enableFrameRateOverride) { for (const auto& mode1 : sortedModes) { for (const auto& mode2 : sortedModes) { if (getFrameRateDivider(mode1->getFps(), mode2->getFps()) >= 2) { Loading
services/surfaceflinger/Scheduler/RefreshRateConfigs.h +17 −3 Original line number Diff line number Diff line Loading @@ -302,8 +302,19 @@ public: // Returns a known frame rate that is the closest to frameRate Fps findClosestKnownFrameRate(Fps frameRate) const; // Configuration flags. struct Config { bool enableFrameRateOverride = false; // Specifies the upper refresh rate threshold (inclusive) for layer vote types of multiple // or heuristic, such that refresh rates higher than this value will not be voted for. 0 if // no threshold is set. int frameRateMultipleThreshold = 0; }; RefreshRateConfigs(const DisplayModes& modes, DisplayModeId currentModeId, bool enableFrameRateOverride = false); Config config = {.enableFrameRateOverride = false, .frameRateMultipleThreshold = 0}); void updateDisplayModes(const DisplayModes& mode, DisplayModeId currentModeId) EXCLUDES(mLock); Loading Loading @@ -387,6 +398,9 @@ private: const Policy* getCurrentPolicyLocked() const REQUIRES(mLock); bool isPolicyValidLocked(const Policy& policy) const REQUIRES(mLock); // Returns whether the layer is allowed to vote for the given refresh rate. bool isVoteAllowed(const LayerRequirement&, const RefreshRate&) const; // calculates a score for a layer. Used to determine the display refresh rate // and the frame rate override for certains applications. float calculateLayerScoreLocked(const LayerRequirement&, const RefreshRate&, Loading Loading @@ -424,7 +438,7 @@ private: // from based on the closest value. const std::vector<Fps> mKnownFrameRates; const bool mEnableFrameRateOverride; const Config mConfig; bool mSupportsFrameRateOverride; struct GetBestRefreshRateInvocation { Loading
services/surfaceflinger/SurfaceFlinger.cpp +9 −4 Original line number Diff line number Diff line Loading @@ -3118,10 +3118,15 @@ void SurfaceFlinger::initScheduler(const DisplayDeviceState& displayState) { return; } const auto displayId = displayState.physical->id; mRefreshRateConfigs = std::make_unique< scheduler::RefreshRateConfigs>(displayState.physical->supportedModes, displayState.physical->activeMode->getId(), android::sysprop::enable_frame_rate_override(false)); scheduler::RefreshRateConfigs::Config config = {.enableFrameRateOverride = android::sysprop::enable_frame_rate_override(false), .frameRateMultipleThreshold = base::GetIntProperty("debug.sf.frame_rate_multiple_threshold", 0)}; mRefreshRateConfigs = std::make_unique<scheduler::RefreshRateConfigs>(displayState.physical->supportedModes, displayState.physical->activeMode ->getId(), config); const auto currRefreshRate = displayState.physical->activeMode->getFps(); mRefreshRateStats = std::make_unique<scheduler::RefreshRateStats>(*mTimeStats, currRefreshRate, hal::PowerMode::OFF); Loading
services/surfaceflinger/tests/unittests/RefreshRateConfigsTest.cpp +168 −10 Original line number Diff line number Diff line Loading @@ -165,6 +165,7 @@ protected: RefreshRate::ConstructorTag(0)}; RefreshRate mExpected120Config = {HWC_CONFIG_ID_120, mConfig120, Fps(120), RefreshRate::ConstructorTag(0)}; private: DisplayModePtr createDisplayMode(DisplayModeId modeId, int32_t group, int64_t vsyncPeriod, ui::Size resolution = ui::Size()); Loading Loading @@ -487,6 +488,52 @@ TEST_F(RefreshRateConfigsTest, getBestRefreshRate_60_90) { refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); } TEST_F(RefreshRateConfigsTest, getBestRefreshRate_multipleThreshold_60_90) { RefreshRateConfigs::Config config = {.frameRateMultipleThreshold = 90}; auto refreshRateConfigs = std::make_unique<RefreshRateConfigs>(m60_90Device, /*currentConfigId=*/HWC_CONFIG_ID_60, config); auto layers = std::vector<LayerRequirement>{LayerRequirement{.weight = 1.0f}}; auto& lr = layers[0]; lr.vote = LayerVoteType::Min; lr.name = "Min"; EXPECT_EQ(mExpected60Config, refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); lr.vote = LayerVoteType::Max; lr.name = "Max"; EXPECT_EQ(mExpected90Config, refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); lr.desiredRefreshRate = Fps(90.0f); lr.vote = LayerVoteType::Heuristic; lr.name = "90Hz Heuristic"; EXPECT_EQ(mExpected90Config, refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); lr.desiredRefreshRate = Fps(60.0f); lr.name = "60Hz Heuristic"; EXPECT_EQ(mExpected60Config, refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); lr.desiredRefreshRate = Fps(45.0f); lr.name = "45Hz Heuristic"; EXPECT_EQ(mExpected90Config, refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); lr.desiredRefreshRate = Fps(30.0f); lr.name = "30Hz Heuristic"; EXPECT_EQ(mExpected60Config, refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); lr.desiredRefreshRate = Fps(24.0f); lr.name = "24Hz Heuristic"; EXPECT_EQ(mExpected60Config, refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); } TEST_F(RefreshRateConfigsTest, getBestRefreshRate_60_72_90) { auto refreshRateConfigs = std::make_unique<RefreshRateConfigs>(m60_72_90Device, Loading Loading @@ -649,6 +696,99 @@ TEST_F(RefreshRateConfigsTest, getBestRefreshRate_30_60_90_120_DifferentTypes) { refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); } TEST_F(RefreshRateConfigsTest, getBestRefreshRate_30_60_90_120_DifferentTypes_multipleThreshold) { RefreshRateConfigs::Config config = {.frameRateMultipleThreshold = 120}; auto refreshRateConfigs = std::make_unique<RefreshRateConfigs>(m30_60_72_90_120Device, /*currentConfigId=*/HWC_CONFIG_ID_60, config); auto layers = std::vector<LayerRequirement>{LayerRequirement{.weight = 1.0f}, LayerRequirement{.weight = 1.0f}}; auto& lr1 = layers[0]; auto& lr2 = layers[1]; lr1.desiredRefreshRate = Fps(24.0f); lr1.vote = LayerVoteType::ExplicitDefault; lr1.name = "24Hz ExplicitDefault"; lr2.desiredRefreshRate = Fps(60.0f); lr2.vote = LayerVoteType::Heuristic; lr2.name = "60Hz Heuristic"; EXPECT_EQ(mExpected120Config, refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); lr1.desiredRefreshRate = Fps(24.0f); lr1.vote = LayerVoteType::ExplicitExactOrMultiple; lr1.name = "24Hz ExplicitExactOrMultiple"; lr2.desiredRefreshRate = Fps(60.0f); lr2.vote = LayerVoteType::Heuristic; lr2.name = "60Hz Heuristic"; EXPECT_EQ(mExpected60Config, refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); lr1.desiredRefreshRate = Fps(24.0f); lr1.vote = LayerVoteType::ExplicitExactOrMultiple; lr1.name = "24Hz ExplicitExactOrMultiple"; lr2.desiredRefreshRate = Fps(60.0f); lr2.vote = LayerVoteType::ExplicitDefault; lr2.name = "60Hz ExplicitDefault"; EXPECT_EQ(mExpected72Config, refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); lr1.desiredRefreshRate = Fps(24.0f); lr1.vote = LayerVoteType::ExplicitExactOrMultiple; lr1.name = "24Hz ExplicitExactOrMultiple"; lr2.desiredRefreshRate = Fps(90.0f); lr2.vote = LayerVoteType::Heuristic; lr2.name = "90Hz Heuristic"; EXPECT_EQ(mExpected90Config, refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); lr1.desiredRefreshRate = Fps(24.0f); lr1.vote = LayerVoteType::ExplicitExactOrMultiple; lr1.name = "24Hz ExplicitExactOrMultiple"; lr2.desiredRefreshRate = Fps(90.0f); lr2.vote = LayerVoteType::ExplicitDefault; lr2.name = "90Hz Heuristic"; EXPECT_EQ(mExpected72Config, refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); lr1.desiredRefreshRate = Fps(24.0f); lr1.vote = LayerVoteType::ExplicitDefault; lr1.name = "24Hz ExplicitDefault"; lr2.desiredRefreshRate = Fps(90.0f); lr2.vote = LayerVoteType::Heuristic; lr2.name = "90Hz Heuristic"; EXPECT_EQ(mExpected90Config, refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); lr1.desiredRefreshRate = Fps(24.0f); lr1.vote = LayerVoteType::Heuristic; lr1.name = "24Hz Heuristic"; lr2.desiredRefreshRate = Fps(90.0f); lr2.vote = LayerVoteType::ExplicitDefault; lr2.name = "90Hz ExplicitDefault"; EXPECT_EQ(mExpected72Config, refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); lr1.desiredRefreshRate = Fps(24.0f); lr1.vote = LayerVoteType::ExplicitExactOrMultiple; lr1.name = "24Hz ExplicitExactOrMultiple"; lr2.desiredRefreshRate = Fps(90.0f); lr2.vote = LayerVoteType::ExplicitDefault; lr2.name = "90Hz ExplicitDefault"; EXPECT_EQ(mExpected72Config, refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); lr1.desiredRefreshRate = Fps(24.0f); lr1.vote = LayerVoteType::ExplicitDefault; lr1.name = "24Hz ExplicitDefault"; lr2.desiredRefreshRate = Fps(90.0f); lr2.vote = LayerVoteType::ExplicitExactOrMultiple; lr2.name = "90Hz ExplicitExactOrMultiple"; EXPECT_EQ(mExpected90Config, refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})); } TEST_F(RefreshRateConfigsTest, getBestRefreshRate_30_60) { auto refreshRateConfigs = std::make_unique<RefreshRateConfigs>(m30_60Device, Loading Loading @@ -819,6 +959,24 @@ TEST_F(RefreshRateConfigsTest, getBestRefreshRate_24FpsVideo) { } } TEST_F(RefreshRateConfigsTest, getBestRefreshRate_24FpsVideo_multipleThreshold_60_120) { RefreshRateConfigs::Config config = {.frameRateMultipleThreshold = 120}; auto refreshRateConfigs = std::make_unique<RefreshRateConfigs>(m60_120Device, /*currentConfigId=*/HWC_CONFIG_ID_60, config); auto layers = std::vector<LayerRequirement>{LayerRequirement{.weight = 1.0f}}; auto& lr = layers[0]; lr.vote = LayerVoteType::ExplicitExactOrMultiple; for (float fps = 23.0f; fps < 25.0f; fps += 0.1f) { lr.desiredRefreshRate = Fps(fps); const auto& refreshRate = refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}); EXPECT_EQ(mExpected60Config, refreshRate) << fps << "Hz chooses " << refreshRate.getName(); } } TEST_F(RefreshRateConfigsTest, twoDeviceConfigs_getBestRefreshRate_Explicit) { auto refreshRateConfigs = std::make_unique<RefreshRateConfigs>(m60_90Device, Loading Loading @@ -1732,10 +1890,10 @@ TEST_F(RefreshRateConfigsTest, getBestRefreshRate_ExplicitExact) { } TEST_F(RefreshRateConfigsTest, getBestRefreshRate_ExplicitExactEnableFrameRateOverride) { RefreshRateConfigs::Config config = {.enableFrameRateOverride = true}; auto refreshRateConfigs = std::make_unique<RefreshRateConfigs>(m30_60_72_90_120Device, /*currentConfigId=*/HWC_CONFIG_ID_60, /*enableFrameRateOverride=*/true); /*currentConfigId=*/HWC_CONFIG_ID_60, config); auto layers = std::vector<LayerRequirement>{LayerRequirement{.weight = 1.0f}, LayerRequirement{.weight = 0.5f}}; Loading Loading @@ -1846,10 +2004,10 @@ TEST_F(RefreshRateConfigsTest, getBestRefreshRate_WritesCache) { } TEST_F(RefreshRateConfigsTest, getBestRefreshRate_ExplicitExactTouchBoost) { RefreshRateConfigs::Config config = {.enableFrameRateOverride = true}; auto refreshRateConfigs = std::make_unique<RefreshRateConfigs>(m60_120Device, /*currentConfigId=*/HWC_CONFIG_ID_60, /*enableFrameRateOverride=*/true); /*currentConfigId=*/HWC_CONFIG_ID_60, config); auto layers = std::vector<LayerRequirement>{LayerRequirement{.weight = 1.0f}, LayerRequirement{.weight = 0.5f}}; Loading Loading @@ -1950,10 +2108,10 @@ TEST_F(RefreshRateConfigsTest, getFrameRateOverrides_noLayers) { } TEST_F(RefreshRateConfigsTest, getFrameRateOverrides_60on120) { RefreshRateConfigs::Config config = {.enableFrameRateOverride = true}; auto refreshRateConfigs = std::make_unique<RefreshRateConfigs>(m30_60_72_90_120Device, /*currentConfigId=*/ HWC_CONFIG_ID_120, /*enableFrameRateOverride=*/true); HWC_CONFIG_ID_120, config); auto layers = std::vector<LayerRequirement>{LayerRequirement{.weight = 1.0f}}; layers[0].name = "Test layer"; Loading Loading @@ -1995,10 +2153,10 @@ TEST_F(RefreshRateConfigsTest, getFrameRateOverrides_60on120) { } TEST_F(RefreshRateConfigsTest, getFrameRateOverrides_twoUids) { RefreshRateConfigs::Config config = {.enableFrameRateOverride = true}; auto refreshRateConfigs = std::make_unique<RefreshRateConfigs>(m30_60_72_90_120Device, /*currentConfigId=*/ HWC_CONFIG_ID_120, /*enableFrameRateOverride=*/true); HWC_CONFIG_ID_120, config); auto layers = std::vector<LayerRequirement>{ LayerRequirement{.ownerUid = 1234, .weight = 1.0f}, Loading Loading @@ -2035,10 +2193,10 @@ TEST_F(RefreshRateConfigsTest, getFrameRateOverrides_twoUids) { } TEST_F(RefreshRateConfigsTest, getFrameRateOverrides_touch) { RefreshRateConfigs::Config config = {.enableFrameRateOverride = true}; auto refreshRateConfigs = std::make_unique<RefreshRateConfigs>(m30_60_72_90_120Device, /*currentConfigId=*/ HWC_CONFIG_ID_120, /*enableFrameRateOverride=*/true); HWC_CONFIG_ID_120, config); auto layers = std::vector<LayerRequirement>{ LayerRequirement{.ownerUid = 1234, .weight = 1.0f}, Loading