Loading libs/nativewindow/include/system/window.h +10 −1 Original line number Diff line number Diff line Loading @@ -1094,11 +1094,20 @@ enum { */ ANATIVEWINDOW_FRAME_RATE_CATEGORY_NORMAL = 3, /** * Indicates that, as a result of a user interaction, an animation is likely to start. * This category is a signal that a user interaction heuristic determined the need of a * high refresh rate, and is not an explicit request from the app. * As opposed to FRAME_RATE_CATEGORY_HIGH, this vote may be ignored in favor of * more explicit votes. */ ANATIVEWINDOW_FRAME_RATE_CATEGORY_HIGH_HINT = 4, /** * Indicates a frame rate suitable for animations that require a high frame rate, which may * increase smoothness but may also increase power usage. */ ANATIVEWINDOW_FRAME_RATE_CATEGORY_HIGH = 4 ANATIVEWINDOW_FRAME_RATE_CATEGORY_HIGH = 5 }; /* Loading services/surfaceflinger/Scheduler/LayerInfo.cpp +2 −0 Original line number Diff line number Diff line Loading @@ -532,6 +532,8 @@ FrameRateCategory LayerInfo::FrameRate::convertCategory(int8_t category) { return FrameRateCategory::Low; case ANATIVEWINDOW_FRAME_RATE_CATEGORY_NORMAL: return FrameRateCategory::Normal; case ANATIVEWINDOW_FRAME_RATE_CATEGORY_HIGH_HINT: return FrameRateCategory::HighHint; case ANATIVEWINDOW_FRAME_RATE_CATEGORY_HIGH: return FrameRateCategory::High; default: Loading services/surfaceflinger/Scheduler/RefreshRateSelector.cpp +17 −3 Original line number Diff line number Diff line Loading @@ -420,6 +420,11 @@ float RefreshRateSelector::calculateLayerScoreLocked(const LayerRequirement& lay const float seamlessness = isSeamlessSwitch ? 1.0f : kSeamedSwitchPenalty; if (layer.vote == LayerVoteType::ExplicitCategory) { // HighHint is considered later for touch boost. if (layer.frameRateCategory == FrameRateCategory::HighHint) { return 0.f; } if (getFrameRateCategoryRange(layer.frameRateCategory).includes(refreshRate)) { return 1.f; } Loading Loading @@ -507,6 +512,7 @@ auto RefreshRateSelector::getRankedFrameRatesLocked(const std::vector<LayerRequi int explicitExact = 0; int explicitGteLayers = 0; int explicitCategoryVoteLayers = 0; int interactiveLayers = 0; int seamedFocusedLayers = 0; int categorySmoothSwitchOnlyLayers = 0; Loading Loading @@ -534,7 +540,13 @@ auto RefreshRateSelector::getRankedFrameRatesLocked(const std::vector<LayerRequi explicitGteLayers++; break; case LayerVoteType::ExplicitCategory: if (layer.frameRateCategory == FrameRateCategory::HighHint) { // HighHint does not count as an explicit signal from an app. It may be // be a touch signal. interactiveLayers++; } else { explicitCategoryVoteLayers++; } if (layer.frameRateCategory == FrameRateCategory::NoPreference) { // Count this layer for Min vote as well. The explicit vote avoids // touch boost and idle for choosing a category, while Min vote is for correct Loading Loading @@ -831,13 +843,14 @@ auto RefreshRateSelector::getRankedFrameRatesLocked(const std::vector<LayerRequi const auto touchRefreshRates = rankFrameRates(anchorGroup, RefreshRateOrder::Descending); using fps_approx_ops::operator<; if (signals.touch && explicitDefaultVoteLayers == 0 && explicitCategoryVoteLayers == 0 && const bool hasInteraction = signals.touch || interactiveLayers > 0; if (hasInteraction && explicitDefaultVoteLayers == 0 && explicitCategoryVoteLayers == 0 && touchBoostForExplicitExact && scores.front().frameRateMode.fps < touchRefreshRates.front().frameRateMode.fps) { ALOGV("Touch Boost"); ATRACE_FORMAT_INSTANT("%s (Touch Boost [late])", to_string(touchRefreshRates.front().frameRateMode.fps).c_str()); return {touchRefreshRates, GlobalSignals{.touch = true}}; return {touchRefreshRates, GlobalSignals{.touch = signals.touch}}; } // If we never scored any layers, and we don't favor high refresh rates, prefer to stay with the Loading Loading @@ -1512,6 +1525,7 @@ FpsRange RefreshRateSelector::getFrameRateCategoryRange(FrameRateCategory catego return FpsRange{60_Hz, 90_Hz}; case FrameRateCategory::Low: return FpsRange{30_Hz, 30_Hz}; case FrameRateCategory::HighHint: case FrameRateCategory::NoPreference: case FrameRateCategory::Default: LOG_ALWAYS_FATAL("Should not get fps range for frame rate category: %s", Loading services/surfaceflinger/Scheduler/include/scheduler/Fps.h +1 −0 Original line number Diff line number Diff line Loading @@ -88,6 +88,7 @@ enum class FrameRateCategory : int32_t { NoPreference, Low, Normal, HighHint, High, ftl_last = High Loading services/surfaceflinger/tests/unittests/LayerSnapshotTest.cpp +3 −3 Original line number Diff line number Diff line Loading @@ -650,7 +650,7 @@ TEST_F(LayerSnapshotTest, frameRateWithCategory) { // │ └── 13 // └── 2 setFrameRate(11, 244.f, 0, 0); setFrameRateCategory(122, 3 /* Normal */); setFrameRateCategory(122, ANATIVEWINDOW_FRAME_RATE_CATEGORY_NORMAL); UPDATE_AND_VERIFY(mSnapshotBuilder, STARTING_ZORDER); // verify parent 1 gets no vote Loading Loading @@ -845,7 +845,7 @@ TEST_F(LayerSnapshotTest, frameRateSelectionStrategyWithCategory) { // │ │ └── 1221 // │ └── 13 // └── 2 setFrameRateCategory(12, 4 /* high */); setFrameRateCategory(12, ANATIVEWINDOW_FRAME_RATE_CATEGORY_HIGH); setFrameRate(122, 123.f, 0, 0); setFrameRateSelectionStrategy(12, 1 /* OverrideChildren */); Loading Loading @@ -887,7 +887,7 @@ TEST_F(LayerSnapshotTest, frameRateSelectionStrategyWithCategory) { // │ │ └── 1221 // │ └── 13 // └── 2 setFrameRateCategory(12, 0 /* default */); setFrameRateCategory(12, ANATIVEWINDOW_FRAME_RATE_CATEGORY_DEFAULT); setFrameRateSelectionStrategy(12, 0 /* Default */); UPDATE_AND_VERIFY(mSnapshotBuilder, STARTING_ZORDER); // verify parent 1 gets no vote Loading Loading
libs/nativewindow/include/system/window.h +10 −1 Original line number Diff line number Diff line Loading @@ -1094,11 +1094,20 @@ enum { */ ANATIVEWINDOW_FRAME_RATE_CATEGORY_NORMAL = 3, /** * Indicates that, as a result of a user interaction, an animation is likely to start. * This category is a signal that a user interaction heuristic determined the need of a * high refresh rate, and is not an explicit request from the app. * As opposed to FRAME_RATE_CATEGORY_HIGH, this vote may be ignored in favor of * more explicit votes. */ ANATIVEWINDOW_FRAME_RATE_CATEGORY_HIGH_HINT = 4, /** * Indicates a frame rate suitable for animations that require a high frame rate, which may * increase smoothness but may also increase power usage. */ ANATIVEWINDOW_FRAME_RATE_CATEGORY_HIGH = 4 ANATIVEWINDOW_FRAME_RATE_CATEGORY_HIGH = 5 }; /* Loading
services/surfaceflinger/Scheduler/LayerInfo.cpp +2 −0 Original line number Diff line number Diff line Loading @@ -532,6 +532,8 @@ FrameRateCategory LayerInfo::FrameRate::convertCategory(int8_t category) { return FrameRateCategory::Low; case ANATIVEWINDOW_FRAME_RATE_CATEGORY_NORMAL: return FrameRateCategory::Normal; case ANATIVEWINDOW_FRAME_RATE_CATEGORY_HIGH_HINT: return FrameRateCategory::HighHint; case ANATIVEWINDOW_FRAME_RATE_CATEGORY_HIGH: return FrameRateCategory::High; default: Loading
services/surfaceflinger/Scheduler/RefreshRateSelector.cpp +17 −3 Original line number Diff line number Diff line Loading @@ -420,6 +420,11 @@ float RefreshRateSelector::calculateLayerScoreLocked(const LayerRequirement& lay const float seamlessness = isSeamlessSwitch ? 1.0f : kSeamedSwitchPenalty; if (layer.vote == LayerVoteType::ExplicitCategory) { // HighHint is considered later for touch boost. if (layer.frameRateCategory == FrameRateCategory::HighHint) { return 0.f; } if (getFrameRateCategoryRange(layer.frameRateCategory).includes(refreshRate)) { return 1.f; } Loading Loading @@ -507,6 +512,7 @@ auto RefreshRateSelector::getRankedFrameRatesLocked(const std::vector<LayerRequi int explicitExact = 0; int explicitGteLayers = 0; int explicitCategoryVoteLayers = 0; int interactiveLayers = 0; int seamedFocusedLayers = 0; int categorySmoothSwitchOnlyLayers = 0; Loading Loading @@ -534,7 +540,13 @@ auto RefreshRateSelector::getRankedFrameRatesLocked(const std::vector<LayerRequi explicitGteLayers++; break; case LayerVoteType::ExplicitCategory: if (layer.frameRateCategory == FrameRateCategory::HighHint) { // HighHint does not count as an explicit signal from an app. It may be // be a touch signal. interactiveLayers++; } else { explicitCategoryVoteLayers++; } if (layer.frameRateCategory == FrameRateCategory::NoPreference) { // Count this layer for Min vote as well. The explicit vote avoids // touch boost and idle for choosing a category, while Min vote is for correct Loading Loading @@ -831,13 +843,14 @@ auto RefreshRateSelector::getRankedFrameRatesLocked(const std::vector<LayerRequi const auto touchRefreshRates = rankFrameRates(anchorGroup, RefreshRateOrder::Descending); using fps_approx_ops::operator<; if (signals.touch && explicitDefaultVoteLayers == 0 && explicitCategoryVoteLayers == 0 && const bool hasInteraction = signals.touch || interactiveLayers > 0; if (hasInteraction && explicitDefaultVoteLayers == 0 && explicitCategoryVoteLayers == 0 && touchBoostForExplicitExact && scores.front().frameRateMode.fps < touchRefreshRates.front().frameRateMode.fps) { ALOGV("Touch Boost"); ATRACE_FORMAT_INSTANT("%s (Touch Boost [late])", to_string(touchRefreshRates.front().frameRateMode.fps).c_str()); return {touchRefreshRates, GlobalSignals{.touch = true}}; return {touchRefreshRates, GlobalSignals{.touch = signals.touch}}; } // If we never scored any layers, and we don't favor high refresh rates, prefer to stay with the Loading Loading @@ -1512,6 +1525,7 @@ FpsRange RefreshRateSelector::getFrameRateCategoryRange(FrameRateCategory catego return FpsRange{60_Hz, 90_Hz}; case FrameRateCategory::Low: return FpsRange{30_Hz, 30_Hz}; case FrameRateCategory::HighHint: case FrameRateCategory::NoPreference: case FrameRateCategory::Default: LOG_ALWAYS_FATAL("Should not get fps range for frame rate category: %s", Loading
services/surfaceflinger/Scheduler/include/scheduler/Fps.h +1 −0 Original line number Diff line number Diff line Loading @@ -88,6 +88,7 @@ enum class FrameRateCategory : int32_t { NoPreference, Low, Normal, HighHint, High, ftl_last = High Loading
services/surfaceflinger/tests/unittests/LayerSnapshotTest.cpp +3 −3 Original line number Diff line number Diff line Loading @@ -650,7 +650,7 @@ TEST_F(LayerSnapshotTest, frameRateWithCategory) { // │ └── 13 // └── 2 setFrameRate(11, 244.f, 0, 0); setFrameRateCategory(122, 3 /* Normal */); setFrameRateCategory(122, ANATIVEWINDOW_FRAME_RATE_CATEGORY_NORMAL); UPDATE_AND_VERIFY(mSnapshotBuilder, STARTING_ZORDER); // verify parent 1 gets no vote Loading Loading @@ -845,7 +845,7 @@ TEST_F(LayerSnapshotTest, frameRateSelectionStrategyWithCategory) { // │ │ └── 1221 // │ └── 13 // └── 2 setFrameRateCategory(12, 4 /* high */); setFrameRateCategory(12, ANATIVEWINDOW_FRAME_RATE_CATEGORY_HIGH); setFrameRate(122, 123.f, 0, 0); setFrameRateSelectionStrategy(12, 1 /* OverrideChildren */); Loading Loading @@ -887,7 +887,7 @@ TEST_F(LayerSnapshotTest, frameRateSelectionStrategyWithCategory) { // │ │ └── 1221 // │ └── 13 // └── 2 setFrameRateCategory(12, 0 /* default */); setFrameRateCategory(12, ANATIVEWINDOW_FRAME_RATE_CATEGORY_DEFAULT); setFrameRateSelectionStrategy(12, 0 /* Default */); UPDATE_AND_VERIFY(mSnapshotBuilder, STARTING_ZORDER); // verify parent 1 gets no vote Loading