Loading services/surfaceflinger/Scheduler/RefreshRateSelector.cpp +13 −0 Original line number Diff line number Diff line Loading @@ -302,6 +302,19 @@ float RefreshRateSelector::calculateNonExactMatchingLayerScoreLocked(const Layer if (layer.vote == LayerVoteType::ExplicitExactOrMultiple || layer.vote == LayerVoteType::Heuristic) { using fps_approx_ops::operator<; if (refreshRate < 60_Hz) { const bool favorsAtLeast60 = std::find_if(mFrameRatesThatFavorsAtLeast60.begin(), mFrameRatesThatFavorsAtLeast60.end(), [&](Fps fps) { using fps_approx_ops::operator==; return fps == layer.desiredRefreshRate; }) != mFrameRatesThatFavorsAtLeast60.end(); if (favorsAtLeast60) { return 0; } } const float multiplier = refreshRate.getValue() / layer.desiredRefreshRate.getValue(); // We only want to score this layer as a fractional pair if the content is not Loading services/surfaceflinger/Scheduler/RefreshRateSelector.h +7 −0 Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ #include <algorithm> #include <numeric> #include <set> #include <type_traits> #include <utility> #include <variant> Loading Loading @@ -500,6 +501,12 @@ private: const std::vector<Fps> mKnownFrameRates; const Config mConfig; // A list of known frame rates that favors at least 60Hz if there is no exact match display // refresh rate const std::vector<Fps> mFrameRatesThatFavorsAtLeast60 = {23.976_Hz, 25_Hz, 29.97_Hz, 50_Hz, 59.94_Hz}; Config::FrameRateOverride mFrameRateOverrideConfig; struct GetRankedFrameRatesCache { Loading services/surfaceflinger/tests/unittests/RefreshRateSelectorTest.cpp +73 −5 Original line number Diff line number Diff line Loading @@ -222,6 +222,7 @@ protected: makeModes(kMode60, kMode90, kMode72_G1, kMode120_G1, kMode30_G1, kMode25_G1, kMode50); static inline const DisplayModes kModes_60_120 = makeModes(kMode60, kMode120); static inline const DisplayModes kModes_1_5_10 = makeModes(kMode1, kMode5, kMode10); static inline const DisplayModes kModes_60_90_120 = makeModes(kMode60, kMode90, kMode120); // This is a typical TV configuration. static inline const DisplayModes kModes_24_25_30_50_60_Frac = Loading Loading @@ -1413,7 +1414,9 @@ TEST_P(RefreshRateSelectorTest, getBestFrameRateMode_ExplicitDefault) { ss << "ExplicitDefault " << desired; lr.name = ss.str(); EXPECT_EQ(expected, selector.getBestFrameRateMode(layers)->getFps()); const auto bestFps = selector.getBestFrameRateMode(layers)->getFps(); EXPECT_EQ(expected, bestFps) << "expected " << expected << " for " << desired << " but got " << bestFps; } } Loading @@ -1422,7 +1425,7 @@ TEST_P(RefreshRateSelectorTest, std::vector<LayerRequirement> layers = {{.weight = 1.f}}; auto& lr = layers[0]; // Test that 23.976 will choose 24 if 23.976 is not supported // Test that 23.976 will prefer 60 over 59.94 and 30 { auto selector = createSelector(makeModes(kMode24, kMode25, kMode30, kMode30Frac, kMode60, kMode60Frac), Loading @@ -1431,7 +1434,7 @@ TEST_P(RefreshRateSelectorTest, lr.vote = LayerVoteType::ExplicitExactOrMultiple; lr.desiredRefreshRate = 23.976_Hz; lr.name = "ExplicitExactOrMultiple 23.976 Hz"; EXPECT_EQ(kModeId24, selector.getBestFrameRateMode(layers)->getId()); EXPECT_EQ(kModeId60, selector.getBestFrameRateMode(layers)->getId()); } // Test that 24 will choose 23.976 if 24 is not supported Loading @@ -1456,13 +1459,13 @@ TEST_P(RefreshRateSelectorTest, EXPECT_EQ(kModeId60Frac, selector.getBestFrameRateMode(layers)->getId()); } // Test that 29.97 will choose 30 if 59.94 is not supported // Test that 29.97 will choose 60 if 59.94 is not supported { auto selector = createSelector(makeModes(kMode30, kMode60), kModeId60); lr.desiredRefreshRate = 29.97_Hz; lr.name = "ExplicitExactOrMultiple 29.97 Hz"; EXPECT_EQ(kModeId30, selector.getBestFrameRateMode(layers)->getId()); EXPECT_EQ(kModeId60, selector.getBestFrameRateMode(layers)->getId()); } // Test that 59.94 will choose 60 if 59.94 is not supported Loading Loading @@ -2516,6 +2519,71 @@ TEST_P(RefreshRateSelectorTest, isFractionalPairOrMultiple) { EXPECT_FALSE(RefreshRateSelector::isFractionalPairOrMultiple(29.97_Hz, 59.94_Hz)); } TEST_P(RefreshRateSelectorTest, test23976Chooses120) { auto selector = createSelector(kModes_60_90_120, kModeId120); std::vector<LayerRequirement> layers = {{.weight = 1.f}}; layers[0].name = "23.976 ExplicitExactOrMultiple"; layers[0].vote = LayerVoteType::ExplicitExactOrMultiple; layers[0].desiredRefreshRate = 23.976_Hz; EXPECT_FRAME_RATE_MODE(kMode120, 120_Hz, selector.getBestScoredFrameRate(layers).frameRateMode); } TEST_P(RefreshRateSelectorTest, test23976Chooses60IfThresholdIs120) { auto selector = createSelector(kModes_60_90_120, kModeId120, {.frameRateMultipleThreshold = 120}); std::vector<LayerRequirement> layers = {{.weight = 1.f}}; layers[0].name = "23.976 ExplicitExactOrMultiple"; layers[0].vote = LayerVoteType::ExplicitExactOrMultiple; layers[0].desiredRefreshRate = 23.976_Hz; EXPECT_FRAME_RATE_MODE(kMode60, 60_Hz, selector.getBestScoredFrameRate(layers).frameRateMode); } TEST_P(RefreshRateSelectorTest, test25Chooses60) { auto selector = createSelector(kModes_60_90_120, kModeId120); std::vector<LayerRequirement> layers = {{.weight = 1.f}}; layers[0].name = "25 ExplicitExactOrMultiple"; layers[0].vote = LayerVoteType::ExplicitExactOrMultiple; layers[0].desiredRefreshRate = 25.00_Hz; EXPECT_FRAME_RATE_MODE(kMode60, 60_Hz, selector.getBestScoredFrameRate(layers).frameRateMode); } TEST_P(RefreshRateSelectorTest, test2997Chooses60) { auto selector = createSelector(kModes_60_90_120, kModeId120); std::vector<LayerRequirement> layers = {{.weight = 1.f}}; layers[0].name = "29.97 ExplicitExactOrMultiple"; layers[0].vote = LayerVoteType::ExplicitExactOrMultiple; layers[0].desiredRefreshRate = 29.97_Hz; EXPECT_FRAME_RATE_MODE(kMode60, 60_Hz, selector.getBestScoredFrameRate(layers).frameRateMode); } TEST_P(RefreshRateSelectorTest, test50Chooses120) { auto selector = createSelector(kModes_60_90_120, kModeId120); std::vector<LayerRequirement> layers = {{.weight = 1.f}}; layers[0].name = "50 ExplicitExactOrMultiple"; layers[0].vote = LayerVoteType::ExplicitExactOrMultiple; layers[0].desiredRefreshRate = 50.00_Hz; EXPECT_FRAME_RATE_MODE(kMode120, 120_Hz, selector.getBestScoredFrameRate(layers).frameRateMode); } TEST_P(RefreshRateSelectorTest, test50Chooses60IfThresholdIs120) { auto selector = createSelector(kModes_60_90_120, kModeId120, {.frameRateMultipleThreshold = 120}); std::vector<LayerRequirement> layers = {{.weight = 1.f}}; layers[0].name = "50 ExplicitExactOrMultiple"; layers[0].vote = LayerVoteType::ExplicitExactOrMultiple; layers[0].desiredRefreshRate = 50.00_Hz; EXPECT_FRAME_RATE_MODE(kMode60, 60_Hz, selector.getBestScoredFrameRate(layers).frameRateMode); } TEST_P(RefreshRateSelectorTest, test5994Chooses60) { auto selector = createSelector(kModes_60_90_120, kModeId120); std::vector<LayerRequirement> layers = {{.weight = 1.f}}; layers[0].name = "59.94 ExplicitExactOrMultiple"; layers[0].vote = LayerVoteType::ExplicitExactOrMultiple; layers[0].desiredRefreshRate = 59.94_Hz; EXPECT_FRAME_RATE_MODE(kMode60, 60_Hz, selector.getBestScoredFrameRate(layers).frameRateMode); } TEST_P(RefreshRateSelectorTest, getFrameRateOverrides_noLayers) { auto selector = createSelector(kModes_30_60_72_90_120, kModeId120); Loading Loading
services/surfaceflinger/Scheduler/RefreshRateSelector.cpp +13 −0 Original line number Diff line number Diff line Loading @@ -302,6 +302,19 @@ float RefreshRateSelector::calculateNonExactMatchingLayerScoreLocked(const Layer if (layer.vote == LayerVoteType::ExplicitExactOrMultiple || layer.vote == LayerVoteType::Heuristic) { using fps_approx_ops::operator<; if (refreshRate < 60_Hz) { const bool favorsAtLeast60 = std::find_if(mFrameRatesThatFavorsAtLeast60.begin(), mFrameRatesThatFavorsAtLeast60.end(), [&](Fps fps) { using fps_approx_ops::operator==; return fps == layer.desiredRefreshRate; }) != mFrameRatesThatFavorsAtLeast60.end(); if (favorsAtLeast60) { return 0; } } const float multiplier = refreshRate.getValue() / layer.desiredRefreshRate.getValue(); // We only want to score this layer as a fractional pair if the content is not Loading
services/surfaceflinger/Scheduler/RefreshRateSelector.h +7 −0 Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ #include <algorithm> #include <numeric> #include <set> #include <type_traits> #include <utility> #include <variant> Loading Loading @@ -500,6 +501,12 @@ private: const std::vector<Fps> mKnownFrameRates; const Config mConfig; // A list of known frame rates that favors at least 60Hz if there is no exact match display // refresh rate const std::vector<Fps> mFrameRatesThatFavorsAtLeast60 = {23.976_Hz, 25_Hz, 29.97_Hz, 50_Hz, 59.94_Hz}; Config::FrameRateOverride mFrameRateOverrideConfig; struct GetRankedFrameRatesCache { Loading
services/surfaceflinger/tests/unittests/RefreshRateSelectorTest.cpp +73 −5 Original line number Diff line number Diff line Loading @@ -222,6 +222,7 @@ protected: makeModes(kMode60, kMode90, kMode72_G1, kMode120_G1, kMode30_G1, kMode25_G1, kMode50); static inline const DisplayModes kModes_60_120 = makeModes(kMode60, kMode120); static inline const DisplayModes kModes_1_5_10 = makeModes(kMode1, kMode5, kMode10); static inline const DisplayModes kModes_60_90_120 = makeModes(kMode60, kMode90, kMode120); // This is a typical TV configuration. static inline const DisplayModes kModes_24_25_30_50_60_Frac = Loading Loading @@ -1413,7 +1414,9 @@ TEST_P(RefreshRateSelectorTest, getBestFrameRateMode_ExplicitDefault) { ss << "ExplicitDefault " << desired; lr.name = ss.str(); EXPECT_EQ(expected, selector.getBestFrameRateMode(layers)->getFps()); const auto bestFps = selector.getBestFrameRateMode(layers)->getFps(); EXPECT_EQ(expected, bestFps) << "expected " << expected << " for " << desired << " but got " << bestFps; } } Loading @@ -1422,7 +1425,7 @@ TEST_P(RefreshRateSelectorTest, std::vector<LayerRequirement> layers = {{.weight = 1.f}}; auto& lr = layers[0]; // Test that 23.976 will choose 24 if 23.976 is not supported // Test that 23.976 will prefer 60 over 59.94 and 30 { auto selector = createSelector(makeModes(kMode24, kMode25, kMode30, kMode30Frac, kMode60, kMode60Frac), Loading @@ -1431,7 +1434,7 @@ TEST_P(RefreshRateSelectorTest, lr.vote = LayerVoteType::ExplicitExactOrMultiple; lr.desiredRefreshRate = 23.976_Hz; lr.name = "ExplicitExactOrMultiple 23.976 Hz"; EXPECT_EQ(kModeId24, selector.getBestFrameRateMode(layers)->getId()); EXPECT_EQ(kModeId60, selector.getBestFrameRateMode(layers)->getId()); } // Test that 24 will choose 23.976 if 24 is not supported Loading @@ -1456,13 +1459,13 @@ TEST_P(RefreshRateSelectorTest, EXPECT_EQ(kModeId60Frac, selector.getBestFrameRateMode(layers)->getId()); } // Test that 29.97 will choose 30 if 59.94 is not supported // Test that 29.97 will choose 60 if 59.94 is not supported { auto selector = createSelector(makeModes(kMode30, kMode60), kModeId60); lr.desiredRefreshRate = 29.97_Hz; lr.name = "ExplicitExactOrMultiple 29.97 Hz"; EXPECT_EQ(kModeId30, selector.getBestFrameRateMode(layers)->getId()); EXPECT_EQ(kModeId60, selector.getBestFrameRateMode(layers)->getId()); } // Test that 59.94 will choose 60 if 59.94 is not supported Loading Loading @@ -2516,6 +2519,71 @@ TEST_P(RefreshRateSelectorTest, isFractionalPairOrMultiple) { EXPECT_FALSE(RefreshRateSelector::isFractionalPairOrMultiple(29.97_Hz, 59.94_Hz)); } TEST_P(RefreshRateSelectorTest, test23976Chooses120) { auto selector = createSelector(kModes_60_90_120, kModeId120); std::vector<LayerRequirement> layers = {{.weight = 1.f}}; layers[0].name = "23.976 ExplicitExactOrMultiple"; layers[0].vote = LayerVoteType::ExplicitExactOrMultiple; layers[0].desiredRefreshRate = 23.976_Hz; EXPECT_FRAME_RATE_MODE(kMode120, 120_Hz, selector.getBestScoredFrameRate(layers).frameRateMode); } TEST_P(RefreshRateSelectorTest, test23976Chooses60IfThresholdIs120) { auto selector = createSelector(kModes_60_90_120, kModeId120, {.frameRateMultipleThreshold = 120}); std::vector<LayerRequirement> layers = {{.weight = 1.f}}; layers[0].name = "23.976 ExplicitExactOrMultiple"; layers[0].vote = LayerVoteType::ExplicitExactOrMultiple; layers[0].desiredRefreshRate = 23.976_Hz; EXPECT_FRAME_RATE_MODE(kMode60, 60_Hz, selector.getBestScoredFrameRate(layers).frameRateMode); } TEST_P(RefreshRateSelectorTest, test25Chooses60) { auto selector = createSelector(kModes_60_90_120, kModeId120); std::vector<LayerRequirement> layers = {{.weight = 1.f}}; layers[0].name = "25 ExplicitExactOrMultiple"; layers[0].vote = LayerVoteType::ExplicitExactOrMultiple; layers[0].desiredRefreshRate = 25.00_Hz; EXPECT_FRAME_RATE_MODE(kMode60, 60_Hz, selector.getBestScoredFrameRate(layers).frameRateMode); } TEST_P(RefreshRateSelectorTest, test2997Chooses60) { auto selector = createSelector(kModes_60_90_120, kModeId120); std::vector<LayerRequirement> layers = {{.weight = 1.f}}; layers[0].name = "29.97 ExplicitExactOrMultiple"; layers[0].vote = LayerVoteType::ExplicitExactOrMultiple; layers[0].desiredRefreshRate = 29.97_Hz; EXPECT_FRAME_RATE_MODE(kMode60, 60_Hz, selector.getBestScoredFrameRate(layers).frameRateMode); } TEST_P(RefreshRateSelectorTest, test50Chooses120) { auto selector = createSelector(kModes_60_90_120, kModeId120); std::vector<LayerRequirement> layers = {{.weight = 1.f}}; layers[0].name = "50 ExplicitExactOrMultiple"; layers[0].vote = LayerVoteType::ExplicitExactOrMultiple; layers[0].desiredRefreshRate = 50.00_Hz; EXPECT_FRAME_RATE_MODE(kMode120, 120_Hz, selector.getBestScoredFrameRate(layers).frameRateMode); } TEST_P(RefreshRateSelectorTest, test50Chooses60IfThresholdIs120) { auto selector = createSelector(kModes_60_90_120, kModeId120, {.frameRateMultipleThreshold = 120}); std::vector<LayerRequirement> layers = {{.weight = 1.f}}; layers[0].name = "50 ExplicitExactOrMultiple"; layers[0].vote = LayerVoteType::ExplicitExactOrMultiple; layers[0].desiredRefreshRate = 50.00_Hz; EXPECT_FRAME_RATE_MODE(kMode60, 60_Hz, selector.getBestScoredFrameRate(layers).frameRateMode); } TEST_P(RefreshRateSelectorTest, test5994Chooses60) { auto selector = createSelector(kModes_60_90_120, kModeId120); std::vector<LayerRequirement> layers = {{.weight = 1.f}}; layers[0].name = "59.94 ExplicitExactOrMultiple"; layers[0].vote = LayerVoteType::ExplicitExactOrMultiple; layers[0].desiredRefreshRate = 59.94_Hz; EXPECT_FRAME_RATE_MODE(kMode60, 60_Hz, selector.getBestScoredFrameRate(layers).frameRateMode); } TEST_P(RefreshRateSelectorTest, getFrameRateOverrides_noLayers) { auto selector = createSelector(kModes_30_60_72_90_120, kModeId120); Loading