Loading libs/nativewindow/include/system/window.h +6 −1 Original line number Diff line number Diff line Loading @@ -1057,7 +1057,12 @@ enum { /** * This surface will vote for the minimum refresh rate. */ ANATIVEWINDOW_FRAME_RATE_MIN ANATIVEWINDOW_FRAME_RATE_MIN, /** * The surface requests a frame rate that is greater than or equal to `frameRate`. */ ANATIVEWINDOW_FRAME_RATE_GTE }; /* Loading services/surfaceflinger/Scheduler/FrameRateCompatibility.h +2 −0 Original line number Diff line number Diff line Loading @@ -29,6 +29,8 @@ enum class FrameRateCompatibility { ExactOrMultiple, // Layer needs the exact frame rate (or a multiple of it) to present the // content properly. Any other value will result in a pull down. Gte, // Layer needs greater than or equal to the frame rate. NoVote, // Layer doesn't have any requirements for the refresh rate and // should not be considered when the display refresh rate is determined. Loading services/surfaceflinger/Scheduler/LayerHistory.cpp +2 −0 Original line number Diff line number Diff line Loading @@ -278,6 +278,8 @@ void LayerHistory::partitionLayers(nsecs_t now) { return LayerVoteType::NoVote; case Layer::FrameRateCompatibility::Exact: return LayerVoteType::ExplicitExact; case Layer::FrameRateCompatibility::Gte: return LayerVoteType::ExplicitGte; } }(); Loading services/surfaceflinger/Scheduler/LayerInfo.cpp +2 −0 Original line number Diff line number Diff line Loading @@ -496,6 +496,8 @@ FrameRateCompatibility LayerInfo::FrameRate::convertCompatibility(int8_t compati return FrameRateCompatibility::Exact; case ANATIVEWINDOW_FRAME_RATE_MIN: return FrameRateCompatibility::Min; case ANATIVEWINDOW_FRAME_RATE_GTE: return FrameRateCompatibility::Gte; case ANATIVEWINDOW_FRAME_RATE_NO_VOTE: return FrameRateCompatibility::NoVote; default: Loading services/surfaceflinger/Scheduler/RefreshRateSelector.cpp +28 −7 Original line number Diff line number Diff line Loading @@ -332,6 +332,15 @@ float RefreshRateSelector::calculateNonExactMatchingLayerScoreLocked(const Layer return calculateNonExactMatchingDefaultLayerScoreLocked(displayPeriod, layerPeriod); } if (layer.vote == LayerVoteType::ExplicitGte) { using fps_approx_ops::operator>=; if (refreshRate >= layer.desiredRefreshRate) { return 1.0f; } else { return calculateDistanceScoreLocked(layer.desiredRefreshRate, refreshRate); } } if (layer.vote == LayerVoteType::ExplicitExactOrMultiple || layer.vote == LayerVoteType::Heuristic) { using fps_approx_ops::operator<; Loading Loading @@ -390,13 +399,20 @@ float RefreshRateSelector::calculateNonExactMatchingLayerScoreLocked(const Layer return 0; } float RefreshRateSelector::calculateDistanceScoreFromMax(Fps refreshRate) const { const auto& maxFps = mAppRequestFrameRates.back().fps; const float ratio = refreshRate.getValue() / maxFps.getValue(); // Use ratio^2 to get a lower score the more we get further from peak float RefreshRateSelector::calculateDistanceScoreLocked(Fps referenceRate, Fps refreshRate) const { using fps_approx_ops::operator>=; const float ratio = referenceRate >= refreshRate ? refreshRate.getValue() / referenceRate.getValue() : referenceRate.getValue() / refreshRate.getValue(); // Use ratio^2 to get a lower score the more we get further from the reference rate. return ratio * ratio; } float RefreshRateSelector::calculateDistanceScoreFromMaxLocked(Fps refreshRate) const { const auto& maxFps = mAppRequestFrameRates.back().fps; return calculateDistanceScoreLocked(maxFps, refreshRate); } float RefreshRateSelector::calculateLayerScoreLocked(const LayerRequirement& layer, Fps refreshRate, bool isSeamlessSwitch) const { // Slightly prefer seamless switches. Loading @@ -421,7 +437,7 @@ float RefreshRateSelector::calculateLayerScoreLocked(const LayerRequirement& lay // If the layer wants Max, give higher score to the higher refresh rate if (layer.vote == LayerVoteType::Max) { return calculateDistanceScoreFromMax(refreshRate); return calculateDistanceScoreFromMaxLocked(refreshRate); } if (layer.vote == LayerVoteType::ExplicitExact) { Loading Loading @@ -489,6 +505,7 @@ auto RefreshRateSelector::getRankedFrameRatesLocked(const std::vector<LayerRequi int explicitDefaultVoteLayers = 0; int explicitExactOrMultipleVoteLayers = 0; int explicitExact = 0; int explicitGteLayers = 0; int explicitCategoryVoteLayers = 0; int seamedFocusedLayers = 0; int categorySmoothSwitchOnlyLayers = 0; Loading @@ -513,6 +530,9 @@ auto RefreshRateSelector::getRankedFrameRatesLocked(const std::vector<LayerRequi case LayerVoteType::ExplicitExact: explicitExact++; break; case LayerVoteType::ExplicitGte: explicitGteLayers++; break; case LayerVoteType::ExplicitCategory: explicitCategoryVoteLayers++; if (layer.frameRateCategory == FrameRateCategory::NoPreference) { Loading @@ -535,7 +555,7 @@ auto RefreshRateSelector::getRankedFrameRatesLocked(const std::vector<LayerRequi } const bool hasExplicitVoteLayers = explicitDefaultVoteLayers > 0 || explicitExactOrMultipleVoteLayers > 0 || explicitExact > 0 || explicitExactOrMultipleVoteLayers > 0 || explicitExact > 0 || explicitGteLayers > 0 || explicitCategoryVoteLayers > 0; const Policy* policy = getCurrentPolicyLocked(); Loading Loading @@ -688,6 +708,7 @@ auto RefreshRateSelector::getRankedFrameRatesLocked(const std::vector<LayerRequi case LayerVoteType::Max: case LayerVoteType::ExplicitDefault: case LayerVoteType::ExplicitExact: case LayerVoteType::ExplicitGte: case LayerVoteType::ExplicitCategory: return false; } Loading Loading @@ -1081,7 +1102,7 @@ auto RefreshRateSelector::rankFrameRates(std::optional<int> anchorGroupOpt, return; } float score = calculateDistanceScoreFromMax(frameRateMode.fps); float score = calculateDistanceScoreFromMaxLocked(frameRateMode.fps); if (ascending) { score = 1.0f / score; Loading Loading
libs/nativewindow/include/system/window.h +6 −1 Original line number Diff line number Diff line Loading @@ -1057,7 +1057,12 @@ enum { /** * This surface will vote for the minimum refresh rate. */ ANATIVEWINDOW_FRAME_RATE_MIN ANATIVEWINDOW_FRAME_RATE_MIN, /** * The surface requests a frame rate that is greater than or equal to `frameRate`. */ ANATIVEWINDOW_FRAME_RATE_GTE }; /* Loading
services/surfaceflinger/Scheduler/FrameRateCompatibility.h +2 −0 Original line number Diff line number Diff line Loading @@ -29,6 +29,8 @@ enum class FrameRateCompatibility { ExactOrMultiple, // Layer needs the exact frame rate (or a multiple of it) to present the // content properly. Any other value will result in a pull down. Gte, // Layer needs greater than or equal to the frame rate. NoVote, // Layer doesn't have any requirements for the refresh rate and // should not be considered when the display refresh rate is determined. Loading
services/surfaceflinger/Scheduler/LayerHistory.cpp +2 −0 Original line number Diff line number Diff line Loading @@ -278,6 +278,8 @@ void LayerHistory::partitionLayers(nsecs_t now) { return LayerVoteType::NoVote; case Layer::FrameRateCompatibility::Exact: return LayerVoteType::ExplicitExact; case Layer::FrameRateCompatibility::Gte: return LayerVoteType::ExplicitGte; } }(); Loading
services/surfaceflinger/Scheduler/LayerInfo.cpp +2 −0 Original line number Diff line number Diff line Loading @@ -496,6 +496,8 @@ FrameRateCompatibility LayerInfo::FrameRate::convertCompatibility(int8_t compati return FrameRateCompatibility::Exact; case ANATIVEWINDOW_FRAME_RATE_MIN: return FrameRateCompatibility::Min; case ANATIVEWINDOW_FRAME_RATE_GTE: return FrameRateCompatibility::Gte; case ANATIVEWINDOW_FRAME_RATE_NO_VOTE: return FrameRateCompatibility::NoVote; default: Loading
services/surfaceflinger/Scheduler/RefreshRateSelector.cpp +28 −7 Original line number Diff line number Diff line Loading @@ -332,6 +332,15 @@ float RefreshRateSelector::calculateNonExactMatchingLayerScoreLocked(const Layer return calculateNonExactMatchingDefaultLayerScoreLocked(displayPeriod, layerPeriod); } if (layer.vote == LayerVoteType::ExplicitGte) { using fps_approx_ops::operator>=; if (refreshRate >= layer.desiredRefreshRate) { return 1.0f; } else { return calculateDistanceScoreLocked(layer.desiredRefreshRate, refreshRate); } } if (layer.vote == LayerVoteType::ExplicitExactOrMultiple || layer.vote == LayerVoteType::Heuristic) { using fps_approx_ops::operator<; Loading Loading @@ -390,13 +399,20 @@ float RefreshRateSelector::calculateNonExactMatchingLayerScoreLocked(const Layer return 0; } float RefreshRateSelector::calculateDistanceScoreFromMax(Fps refreshRate) const { const auto& maxFps = mAppRequestFrameRates.back().fps; const float ratio = refreshRate.getValue() / maxFps.getValue(); // Use ratio^2 to get a lower score the more we get further from peak float RefreshRateSelector::calculateDistanceScoreLocked(Fps referenceRate, Fps refreshRate) const { using fps_approx_ops::operator>=; const float ratio = referenceRate >= refreshRate ? refreshRate.getValue() / referenceRate.getValue() : referenceRate.getValue() / refreshRate.getValue(); // Use ratio^2 to get a lower score the more we get further from the reference rate. return ratio * ratio; } float RefreshRateSelector::calculateDistanceScoreFromMaxLocked(Fps refreshRate) const { const auto& maxFps = mAppRequestFrameRates.back().fps; return calculateDistanceScoreLocked(maxFps, refreshRate); } float RefreshRateSelector::calculateLayerScoreLocked(const LayerRequirement& layer, Fps refreshRate, bool isSeamlessSwitch) const { // Slightly prefer seamless switches. Loading @@ -421,7 +437,7 @@ float RefreshRateSelector::calculateLayerScoreLocked(const LayerRequirement& lay // If the layer wants Max, give higher score to the higher refresh rate if (layer.vote == LayerVoteType::Max) { return calculateDistanceScoreFromMax(refreshRate); return calculateDistanceScoreFromMaxLocked(refreshRate); } if (layer.vote == LayerVoteType::ExplicitExact) { Loading Loading @@ -489,6 +505,7 @@ auto RefreshRateSelector::getRankedFrameRatesLocked(const std::vector<LayerRequi int explicitDefaultVoteLayers = 0; int explicitExactOrMultipleVoteLayers = 0; int explicitExact = 0; int explicitGteLayers = 0; int explicitCategoryVoteLayers = 0; int seamedFocusedLayers = 0; int categorySmoothSwitchOnlyLayers = 0; Loading @@ -513,6 +530,9 @@ auto RefreshRateSelector::getRankedFrameRatesLocked(const std::vector<LayerRequi case LayerVoteType::ExplicitExact: explicitExact++; break; case LayerVoteType::ExplicitGte: explicitGteLayers++; break; case LayerVoteType::ExplicitCategory: explicitCategoryVoteLayers++; if (layer.frameRateCategory == FrameRateCategory::NoPreference) { Loading @@ -535,7 +555,7 @@ auto RefreshRateSelector::getRankedFrameRatesLocked(const std::vector<LayerRequi } const bool hasExplicitVoteLayers = explicitDefaultVoteLayers > 0 || explicitExactOrMultipleVoteLayers > 0 || explicitExact > 0 || explicitExactOrMultipleVoteLayers > 0 || explicitExact > 0 || explicitGteLayers > 0 || explicitCategoryVoteLayers > 0; const Policy* policy = getCurrentPolicyLocked(); Loading Loading @@ -688,6 +708,7 @@ auto RefreshRateSelector::getRankedFrameRatesLocked(const std::vector<LayerRequi case LayerVoteType::Max: case LayerVoteType::ExplicitDefault: case LayerVoteType::ExplicitExact: case LayerVoteType::ExplicitGte: case LayerVoteType::ExplicitCategory: return false; } Loading Loading @@ -1081,7 +1102,7 @@ auto RefreshRateSelector::rankFrameRates(std::optional<int> anchorGroupOpt, return; } float score = calculateDistanceScoreFromMax(frameRateMode.fps); float score = calculateDistanceScoreFromMaxLocked(frameRateMode.fps); if (ascending) { score = 1.0f / score; Loading