Loading services/surfaceflinger/Scheduler/RefreshRateConfigs.cpp +15 −14 Original line number Diff line number Diff line Loading @@ -42,9 +42,9 @@ struct RefreshRateScore { DisplayModeIterator modeIt; float overallScore; struct { float belowThreshold; float aboveThreshold; } fixedRateLayersScore; float modeBelowThreshold; float modeAboveThreshold; } fixedRateBelowThresholdLayersScore; }; template <typename Iterator> Loading Loading @@ -385,7 +385,7 @@ auto RefreshRateConfigs::getBestRefreshRateLocked(const std::vector<LayerRequire const auto weight = layer.weight; for (auto& [modeIt, overallScore, fixedRateScore] : scores) { for (auto& [modeIt, overallScore, fixedRateBelowThresholdLayersScore] : scores) { const auto& [id, mode] = *modeIt; const bool isSeamlessSwitch = mode->getGroup() == mActiveModeIt->second->getGroup(); Loading Loading @@ -451,21 +451,22 @@ auto RefreshRateConfigs::getBestRefreshRateLocked(const std::vector<LayerRequire return false; } }(layer.vote); const bool layerAboveThreshold = mConfig.frameRateMultipleThreshold != 0 && mode->getFps() >= Fps::fromValue(mConfig.frameRateMultipleThreshold) && const bool layerBelowThreshold = mConfig.frameRateMultipleThreshold != 0 && layer.desiredRefreshRate < Fps::fromValue(mConfig.frameRateMultipleThreshold / 2); if (fixedSourceLayer) { if (layerAboveThreshold) { const bool modeAboveThreshold = layerBelowThreshold && mode->getFps() >= Fps::fromValue(mConfig.frameRateMultipleThreshold); if (fixedSourceLayer && layerBelowThreshold) { if (modeAboveThreshold) { ALOGV("%s gives %s fixed source (above threshold) score of %.4f", formatLayerInfo(layer, weight).c_str(), to_string(mode->getFps()).c_str(), layerScore); fixedRateScore.aboveThreshold += weightedLayerScore; fixedRateBelowThresholdLayersScore.modeAboveThreshold += weightedLayerScore; } else { ALOGV("%s gives %s fixed source (below threshold) score of %.4f", formatLayerInfo(layer, weight).c_str(), to_string(mode->getFps()).c_str(), layerScore); fixedRateScore.belowThreshold += weightedLayerScore; fixedRateBelowThresholdLayersScore.modeBelowThreshold += weightedLayerScore; } } else { ALOGV("%s gives %s score of %.4f", formatLayerInfo(layer, weight).c_str(), Loading @@ -476,7 +477,7 @@ auto RefreshRateConfigs::getBestRefreshRateLocked(const std::vector<LayerRequire } // We want to find the best refresh rate without the fixed source layers, // so we could know whether we should add the aboveThreshold scores or not. // so we could know whether we should add the modeAboveThreshold scores or not. // If the best refresh rate is already above the threshold, it means that // some non-fixed source layers already scored it, so we can just add the score // for all fixed source layers, even the ones that are above the threshold. Loading @@ -500,10 +501,10 @@ auto RefreshRateConfigs::getBestRefreshRateLocked(const std::vector<LayerRequire }(); // Now we can add the fixed rate layers score for (auto& [modeIt, overallScore, fixedRateScore] : scores) { overallScore += fixedRateScore.belowThreshold; for (auto& [modeIt, overallScore, fixedRateBelowThresholdLayersScore] : scores) { overallScore += fixedRateBelowThresholdLayersScore.modeBelowThreshold; if (maxScoreAboveThreshold) { overallScore += fixedRateScore.aboveThreshold; overallScore += fixedRateBelowThresholdLayersScore.modeAboveThreshold; } ALOGV("%s adjusted overallScore is %.4f", to_string(modeIt->second->getFps()).c_str(), overallScore); Loading services/surfaceflinger/tests/unittests/RefreshRateConfigsTest.cpp +21 −1 Original line number Diff line number Diff line Loading @@ -564,9 +564,10 @@ TEST_F(RefreshRateConfigsTest, getBestRefreshRate_30_60_90_120_DifferentTypes_mu TestableRefreshRateConfigs configs(kModes_30_60_72_90_120, kModeId60, {.frameRateMultipleThreshold = 120}); std::vector<LayerRequirement> layers = {{.weight = 1.f}, {.weight = 1.f}}; std::vector<LayerRequirement> layers = {{.weight = 1.f}, {.weight = 1.f}, {.weight = 1.f}}; auto& lr1 = layers[0]; auto& lr2 = layers[1]; auto& lr3 = layers[2]; lr1.desiredRefreshRate = 24_Hz; lr1.vote = LayerVoteType::ExplicitDefault; Loading Loading @@ -662,6 +663,25 @@ TEST_F(RefreshRateConfigsTest, getBestRefreshRate_30_60_90_120_DifferentTypes_mu lr2.vote = LayerVoteType::ExplicitExact; lr2.name = "120Hz ExplicitExact"; EXPECT_EQ(kMode120, configs.getBestRefreshRate(layers)); lr1.desiredRefreshRate = 10_Hz; lr1.vote = LayerVoteType::ExplicitExactOrMultiple; lr1.name = "30Hz ExplicitExactOrMultiple"; lr2.desiredRefreshRate = 120_Hz; lr2.vote = LayerVoteType::Heuristic; lr2.name = "120Hz ExplicitExact"; EXPECT_EQ(kMode120, configs.getBestRefreshRate(layers)); lr1.desiredRefreshRate = 30_Hz; lr1.vote = LayerVoteType::ExplicitExactOrMultiple; lr1.name = "30Hz ExplicitExactOrMultiple"; lr2.desiredRefreshRate = 30_Hz; lr2.vote = LayerVoteType::ExplicitExactOrMultiple; lr2.name = "30Hz ExplicitExactOrMultiple"; lr3.vote = LayerVoteType::Heuristic; lr3.desiredRefreshRate = 120_Hz; lr3.name = "120Hz Heuristic"; EXPECT_EQ(kMode120, configs.getBestRefreshRate(layers)); } TEST_F(RefreshRateConfigsTest, getBestRefreshRate_30_60) { Loading Loading
services/surfaceflinger/Scheduler/RefreshRateConfigs.cpp +15 −14 Original line number Diff line number Diff line Loading @@ -42,9 +42,9 @@ struct RefreshRateScore { DisplayModeIterator modeIt; float overallScore; struct { float belowThreshold; float aboveThreshold; } fixedRateLayersScore; float modeBelowThreshold; float modeAboveThreshold; } fixedRateBelowThresholdLayersScore; }; template <typename Iterator> Loading Loading @@ -385,7 +385,7 @@ auto RefreshRateConfigs::getBestRefreshRateLocked(const std::vector<LayerRequire const auto weight = layer.weight; for (auto& [modeIt, overallScore, fixedRateScore] : scores) { for (auto& [modeIt, overallScore, fixedRateBelowThresholdLayersScore] : scores) { const auto& [id, mode] = *modeIt; const bool isSeamlessSwitch = mode->getGroup() == mActiveModeIt->second->getGroup(); Loading Loading @@ -451,21 +451,22 @@ auto RefreshRateConfigs::getBestRefreshRateLocked(const std::vector<LayerRequire return false; } }(layer.vote); const bool layerAboveThreshold = mConfig.frameRateMultipleThreshold != 0 && mode->getFps() >= Fps::fromValue(mConfig.frameRateMultipleThreshold) && const bool layerBelowThreshold = mConfig.frameRateMultipleThreshold != 0 && layer.desiredRefreshRate < Fps::fromValue(mConfig.frameRateMultipleThreshold / 2); if (fixedSourceLayer) { if (layerAboveThreshold) { const bool modeAboveThreshold = layerBelowThreshold && mode->getFps() >= Fps::fromValue(mConfig.frameRateMultipleThreshold); if (fixedSourceLayer && layerBelowThreshold) { if (modeAboveThreshold) { ALOGV("%s gives %s fixed source (above threshold) score of %.4f", formatLayerInfo(layer, weight).c_str(), to_string(mode->getFps()).c_str(), layerScore); fixedRateScore.aboveThreshold += weightedLayerScore; fixedRateBelowThresholdLayersScore.modeAboveThreshold += weightedLayerScore; } else { ALOGV("%s gives %s fixed source (below threshold) score of %.4f", formatLayerInfo(layer, weight).c_str(), to_string(mode->getFps()).c_str(), layerScore); fixedRateScore.belowThreshold += weightedLayerScore; fixedRateBelowThresholdLayersScore.modeBelowThreshold += weightedLayerScore; } } else { ALOGV("%s gives %s score of %.4f", formatLayerInfo(layer, weight).c_str(), Loading @@ -476,7 +477,7 @@ auto RefreshRateConfigs::getBestRefreshRateLocked(const std::vector<LayerRequire } // We want to find the best refresh rate without the fixed source layers, // so we could know whether we should add the aboveThreshold scores or not. // so we could know whether we should add the modeAboveThreshold scores or not. // If the best refresh rate is already above the threshold, it means that // some non-fixed source layers already scored it, so we can just add the score // for all fixed source layers, even the ones that are above the threshold. Loading @@ -500,10 +501,10 @@ auto RefreshRateConfigs::getBestRefreshRateLocked(const std::vector<LayerRequire }(); // Now we can add the fixed rate layers score for (auto& [modeIt, overallScore, fixedRateScore] : scores) { overallScore += fixedRateScore.belowThreshold; for (auto& [modeIt, overallScore, fixedRateBelowThresholdLayersScore] : scores) { overallScore += fixedRateBelowThresholdLayersScore.modeBelowThreshold; if (maxScoreAboveThreshold) { overallScore += fixedRateScore.aboveThreshold; overallScore += fixedRateBelowThresholdLayersScore.modeAboveThreshold; } ALOGV("%s adjusted overallScore is %.4f", to_string(modeIt->second->getFps()).c_str(), overallScore); Loading
services/surfaceflinger/tests/unittests/RefreshRateConfigsTest.cpp +21 −1 Original line number Diff line number Diff line Loading @@ -564,9 +564,10 @@ TEST_F(RefreshRateConfigsTest, getBestRefreshRate_30_60_90_120_DifferentTypes_mu TestableRefreshRateConfigs configs(kModes_30_60_72_90_120, kModeId60, {.frameRateMultipleThreshold = 120}); std::vector<LayerRequirement> layers = {{.weight = 1.f}, {.weight = 1.f}}; std::vector<LayerRequirement> layers = {{.weight = 1.f}, {.weight = 1.f}, {.weight = 1.f}}; auto& lr1 = layers[0]; auto& lr2 = layers[1]; auto& lr3 = layers[2]; lr1.desiredRefreshRate = 24_Hz; lr1.vote = LayerVoteType::ExplicitDefault; Loading Loading @@ -662,6 +663,25 @@ TEST_F(RefreshRateConfigsTest, getBestRefreshRate_30_60_90_120_DifferentTypes_mu lr2.vote = LayerVoteType::ExplicitExact; lr2.name = "120Hz ExplicitExact"; EXPECT_EQ(kMode120, configs.getBestRefreshRate(layers)); lr1.desiredRefreshRate = 10_Hz; lr1.vote = LayerVoteType::ExplicitExactOrMultiple; lr1.name = "30Hz ExplicitExactOrMultiple"; lr2.desiredRefreshRate = 120_Hz; lr2.vote = LayerVoteType::Heuristic; lr2.name = "120Hz ExplicitExact"; EXPECT_EQ(kMode120, configs.getBestRefreshRate(layers)); lr1.desiredRefreshRate = 30_Hz; lr1.vote = LayerVoteType::ExplicitExactOrMultiple; lr1.name = "30Hz ExplicitExactOrMultiple"; lr2.desiredRefreshRate = 30_Hz; lr2.vote = LayerVoteType::ExplicitExactOrMultiple; lr2.name = "30Hz ExplicitExactOrMultiple"; lr3.vote = LayerVoteType::Heuristic; lr3.desiredRefreshRate = 120_Hz; lr3.name = "120Hz Heuristic"; EXPECT_EQ(kMode120, configs.getBestRefreshRate(layers)); } TEST_F(RefreshRateConfigsTest, getBestRefreshRate_30_60) { Loading