Skip primaryRangeIsSingleRate check for ARR
If the active mode is ARR enabled, then this means the physical
refresh rate is a single rate that does not change but the device can
render at any of the divisors of the vsync rate.
Therefore doesn't make sense to perform
the primaryRangeIsSingleRate check for ARR mode.
Flag: EXEMPT bugfix
Test: atest RefreshRateSelectorTest
Test: atest FrameRateOverrideTest
Bug: 308020695
Bug: 369287577
Change-Id: Ie16b1561aef05287cdac1908bfe9fd6fd1ab43fa
diff --git a/services/surfaceflinger/Scheduler/RefreshRateSelector.cpp b/services/surfaceflinger/Scheduler/RefreshRateSelector.cpp
index ab9014e..eca8df2 100644
--- a/services/surfaceflinger/Scheduler/RefreshRateSelector.cpp
+++ b/services/surfaceflinger/Scheduler/RefreshRateSelector.cpp
@@ -722,13 +722,17 @@
const bool inPrimaryPhysicalRange =
policy->primaryRanges.physical.includes(modePtr->getPeakFps());
const bool inPrimaryRenderRange = policy->primaryRanges.render.includes(fps);
- if (((policy->primaryRangeIsSingleRate() && !inPrimaryPhysicalRange) ||
+ if (!mIsVrrDevice.load() &&
+ ((policy->primaryRangeIsSingleRate() && !inPrimaryPhysicalRange) ||
!inPrimaryRenderRange) &&
!(layer.focused &&
(layer.vote == LayerVoteType::ExplicitDefault ||
layer.vote == LayerVoteType::ExplicitExact))) {
// Only focused layers with ExplicitDefault frame rate settings are allowed to score
// refresh rates outside the primary range.
+ ALOGV("%s ignores %s (primaryRangeIsSingleRate). Current mode = %s",
+ formatLayerInfo(layer, weight).c_str(), to_string(*modePtr).c_str(),
+ to_string(activeMode).c_str());
continue;
}
@@ -852,7 +856,8 @@
to_string(descending.front().frameRateMode.fps).c_str());
return {descending, kNoSignals};
} else {
- ALOGV("primaryRangeIsSingleRate");
+ ALOGV("%s (primaryRangeIsSingleRate)",
+ to_string(ranking.front().frameRateMode.fps).c_str());
SFTRACE_FORMAT_INSTANT("%s (primaryRangeIsSingleRate)",
to_string(ranking.front().frameRateMode.fps).c_str());
return {ranking, kNoSignals};
@@ -932,6 +937,8 @@
using LayerVoteType = RefreshRateSelector::LayerVoteType;
if (layer->vote == LayerVoteType::Max || layer->vote == LayerVoteType::Heuristic) {
+ ALOGV("%s: %s skips uid=%d due to the vote", __func__,
+ formatLayerInfo(*layer, layer->weight).c_str(), layer->ownerUid);
skipUid = true;
break;
}
@@ -1014,12 +1021,14 @@
// Layers with ExplicitExactOrMultiple expect touch boost
if (globalSignals.touch && hasExplicitExactOrMultiple) {
+ ALOGV("%s: Skipping for touch (input signal): uid=%d", __func__, uid);
continue;
}
// Mirrors getRankedFrameRates. If there is no ExplicitDefault, expect touch boost and
// skip frame rate override.
if (hasHighHint && !hasExplicitDefault) {
+ ALOGV("%s: Skipping for touch (HighHint): uid=%d", __func__, uid);
continue;
}
@@ -1043,6 +1052,9 @@
constexpr bool isSeamlessSwitch = true;
const auto layerScore = calculateLayerScoreLocked(*layer, fps, isSeamlessSwitch);
score += layer->weight * layerScore;
+ ALOGV("%s: %s gives %s fps score of %.4f", __func__,
+ formatLayerInfo(*layer, layer->weight).c_str(), to_string(fps).c_str(),
+ layerScore);
}
}
@@ -1297,6 +1309,8 @@
LOG_ALWAYS_FATAL_IF(!activeModeOpt);
mActiveModeOpt = FrameRateMode{activeModeOpt->get()->getPeakFps(),
ftl::as_non_null(activeModeOpt->get())};
+ mIsVrrDevice = FlagManager::getInstance().vrr_config() &&
+ activeModeOpt->get()->getVrrConfig().has_value();
const auto sortedModes = sortByRefreshRate(mDisplayModes);
mMinRefreshRateModeIt = sortedModes.front();
diff --git a/services/surfaceflinger/tests/unittests/RefreshRateSelectorTest.cpp b/services/surfaceflinger/tests/unittests/RefreshRateSelectorTest.cpp
index 9efe73d..a624af6 100644
--- a/services/surfaceflinger/tests/unittests/RefreshRateSelectorTest.cpp
+++ b/services/surfaceflinger/tests/unittests/RefreshRateSelectorTest.cpp
@@ -304,6 +304,42 @@
<< " category=" << ftl::enum_string(testCase.frameRateCategory);
}
}
+
+ template <class T>
+ std::vector<LayerRequirement> createLayers(const std::initializer_list<T>& surfaceVotes) {
+ std::vector<LayerRequirement> layers;
+ for (auto surfaceVote : surfaceVotes) {
+ ALOGI("**** %s: Adding layers for %s: (desiredFrameRate=%s, voteType=%s), "
+ "(frameRateCategory=%s)",
+ __func__, surfaceVote.name.c_str(),
+ to_string(surfaceVote.desiredFrameRate).c_str(),
+ ftl::enum_string(surfaceVote.voteType).c_str(),
+ ftl::enum_string(surfaceVote.frameRateCategory).c_str());
+
+ if (surfaceVote.desiredFrameRate.isValid()) {
+ std::stringstream ss;
+ ss << surfaceVote.name << " (" << surfaceVote.weight << "): ExplicitDefault ("
+ << to_string(surfaceVote.desiredFrameRate) << ")";
+ LayerRequirement layer = {.name = ss.str(),
+ .vote = surfaceVote.voteType,
+ .desiredRefreshRate = surfaceVote.desiredFrameRate,
+ .weight = surfaceVote.weight};
+ layers.push_back(layer);
+ }
+
+ if (surfaceVote.frameRateCategory != FrameRateCategory::Default) {
+ std::stringstream ss;
+ ss << surfaceVote.name << " (" << surfaceVote.weight << "): ExplicitCategory ("
+ << ftl::enum_string(surfaceVote.frameRateCategory) << ")";
+ LayerRequirement layer = {.name = ss.str(),
+ .vote = LayerVoteType::ExplicitCategory,
+ .frameRateCategory = surfaceVote.frameRateCategory,
+ .weight = surfaceVote.weight};
+ layers.push_back(layer);
+ }
+ }
+ return layers;
+ }
};
RefreshRateSelectorTest::RefreshRateSelectorTest() {
@@ -1772,6 +1808,98 @@
selector);
}
+TEST_P(RefreshRateSelectorTest, getBestFrameRateMode_multiSurface_arr) {
+ if (GetParam() != Config::FrameRateOverride::Enabled) {
+ return;
+ }
+
+ SET_FLAG_FOR_TEST(flags::vrr_config, true);
+
+ auto selector = createSelector(kVrrMode_120, kModeId120);
+
+ // Switch the policy to be more like an ARR device (primary range is a single rate).
+ constexpr FpsRange k120_120Hz = {120_Hz, 120_Hz};
+ constexpr FpsRange k0_120Hz = {0_Hz, 120_Hz};
+ constexpr FpsRanges kPrimaryRanges = {/*physical*/ k120_120Hz,
+ /*render*/ k120_120Hz};
+ constexpr FpsRanges kAppRequestRanges = {/*physical*/ k120_120Hz,
+ /*render*/ k0_120Hz};
+ EXPECT_EQ(SetPolicyResult::Changed,
+ selector.setDisplayManagerPolicy(
+ {/*defaultMode*/ kModeId120, kPrimaryRanges, kAppRequestRanges}));
+
+ // Surface can translate to multiple layers in SF scheduler due to category and frame rate
+ // value.
+ struct SurfaceVote {
+ // Params
+ std::string name = "";
+ Fps desiredFrameRate = 0_Hz;
+ LayerVoteType voteType = LayerVoteType::ExplicitDefault;
+ FrameRateCategory frameRateCategory = FrameRateCategory::Default;
+ float weight = 1.f;
+ };
+
+ auto layers = createLayers(
+ std::initializer_list<SurfaceVote>{{.name = "60 fixed source",
+ .desiredFrameRate = 60_Hz,
+ .voteType = LayerVoteType::ExplicitExactOrMultiple,
+ .weight = 0.27f},
+ {.name = "1 fixed source + NoPreference",
+ .desiredFrameRate = 1_Hz,
+ .voteType = LayerVoteType::ExplicitExactOrMultiple,
+ .frameRateCategory =
+ FrameRateCategory::NoPreference}});
+ auto actualRankedFrameRates = selector.getRankedFrameRates(layers);
+ EXPECT_EQ(60_Hz, actualRankedFrameRates.ranking.front().frameRateMode.fps);
+
+ layers = createLayers(
+ std::initializer_list<SurfaceVote>{{.name = "60 fixed source",
+ .desiredFrameRate = 60_Hz,
+ .voteType = LayerVoteType::ExplicitExactOrMultiple,
+ .weight = 0.27f},
+ {.name = "1 fixed source + Normal",
+ .desiredFrameRate = 1_Hz,
+ .voteType = LayerVoteType::ExplicitExactOrMultiple,
+ .frameRateCategory = FrameRateCategory::Normal}});
+ actualRankedFrameRates = selector.getRankedFrameRates(layers);
+ EXPECT_EQ(60_Hz, actualRankedFrameRates.ranking.front().frameRateMode.fps);
+
+ layers = createLayers(std::initializer_list<SurfaceVote>{
+ {.name = "30 fixed source + NoPreference",
+ .desiredFrameRate = 30_Hz,
+ .voteType = LayerVoteType::ExplicitExactOrMultiple,
+ .frameRateCategory = FrameRateCategory::NoPreference}});
+ actualRankedFrameRates = selector.getRankedFrameRates(layers);
+ EXPECT_EQ(30_Hz, actualRankedFrameRates.ranking.front().frameRateMode.fps);
+
+ layers = createLayers(std::initializer_list<SurfaceVote>{
+ {.name = "1 fixed source + NoPreference",
+ .desiredFrameRate = 1_Hz,
+ .voteType = LayerVoteType::ExplicitExactOrMultiple,
+ .frameRateCategory = FrameRateCategory::NoPreference}});
+ actualRankedFrameRates = selector.getRankedFrameRates(layers);
+ // Result affected by RefreshRateSelector.kMinSupportedFrameRate.
+ EXPECT_EQ(20_Hz, actualRankedFrameRates.ranking.front().frameRateMode.fps);
+
+ layers = createLayers(std::initializer_list<SurfaceVote>{
+ {.name = "24 fixed source + NoPreference",
+ .desiredFrameRate = 24_Hz,
+ .voteType = LayerVoteType::ExplicitExactOrMultiple,
+ .frameRateCategory = FrameRateCategory::NoPreference}});
+ actualRankedFrameRates = selector.getRankedFrameRates(layers);
+ EXPECT_EQ(24_Hz, actualRankedFrameRates.ranking.front().frameRateMode.fps);
+
+ layers = createLayers(std::initializer_list<SurfaceVote>{
+ {.name = "23.976 fixed source + NoPreference",
+ .desiredFrameRate = 23.976_Hz,
+ .voteType = LayerVoteType::ExplicitExactOrMultiple,
+ .frameRateCategory = FrameRateCategory::NoPreference}});
+ actualRankedFrameRates = selector.getRankedFrameRates(layers);
+ // Chooses 120 unless certain threshold is set, see tests test23976Chooses120 and
+ // test23976Chooses60IfThresholdIs120.
+ EXPECT_EQ(120_Hz, actualRankedFrameRates.ranking.front().frameRateMode.fps);
+}
+
TEST_P(RefreshRateSelectorTest, getBestFrameRateMode_withFrameRateCategory_60_120) {
auto selector = createSelector(makeModes(kMode60, kMode120), kModeId60);