SF Adds powerOnImminent to the GlobalSignals
This helps with moving the refresh rate selection into
RefreshRateConfigs instead of calling from Scheduler.
BUG: 240743471
Test: atest libsurfaceflinger_unittest
Change-Id: I4dba607e82ddb139be3daebe7f5c764fd5ae418c
diff --git a/services/surfaceflinger/Scheduler/RefreshRateConfigs.cpp b/services/surfaceflinger/Scheduler/RefreshRateConfigs.cpp
index d270655..00886f0 100644
--- a/services/surfaceflinger/Scheduler/RefreshRateConfigs.cpp
+++ b/services/surfaceflinger/Scheduler/RefreshRateConfigs.cpp
@@ -280,6 +280,15 @@
ATRACE_CALL();
ALOGV("%s: %zu layers", __func__, layers.size());
+ const auto& activeMode = *getActiveModeItLocked()->second;
+
+ // Keep the display at max refresh rate for the duration of powering on the display.
+ if (signals.powerOnImminent) {
+ ALOGV("Power On Imminent");
+ const auto& max = getMaxRefreshRateByPolicyLocked(activeMode.getGroup());
+ return {max, GlobalSignals{.powerOnImminent = true}};
+ }
+
int noVoteLayers = 0;
int minVoteLayers = 0;
int maxVoteLayers = 0;
@@ -326,7 +335,6 @@
const Policy* policy = getCurrentPolicyLocked();
const auto& defaultMode = mDisplayModes.get(policy->defaultMode)->get();
- const auto& activeMode = *getActiveModeItLocked()->second;
// If the default mode group is different from the group of current mode,
// this means a layer requesting a seamed mode switch just disappeared and
diff --git a/services/surfaceflinger/Scheduler/RefreshRateConfigs.h b/services/surfaceflinger/Scheduler/RefreshRateConfigs.h
index b2cfb03..19bcb94 100644
--- a/services/surfaceflinger/Scheduler/RefreshRateConfigs.h
+++ b/services/surfaceflinger/Scheduler/RefreshRateConfigs.h
@@ -185,9 +185,13 @@
bool touch = false;
// True if the system hasn't seen any buffers posted to layers recently.
bool idle = false;
+ // Whether the display is about to be powered on, or has been in PowerMode::ON
+ // within the timeout of DisplayPowerTimer.
+ bool powerOnImminent = false;
bool operator==(GlobalSignals other) const {
- return touch == other.touch && idle == other.idle;
+ return touch == other.touch && idle == other.idle &&
+ powerOnImminent == other.powerOnImminent;
}
};
diff --git a/services/surfaceflinger/Scheduler/Scheduler.cpp b/services/surfaceflinger/Scheduler/Scheduler.cpp
index bec39a7..ff6b461 100644
--- a/services/surfaceflinger/Scheduler/Scheduler.cpp
+++ b/services/surfaceflinger/Scheduler/Scheduler.cpp
@@ -704,17 +704,13 @@
const auto configs = holdRefreshRateConfigs();
- // If Display Power is not in normal operation we want to be in performance mode. When coming
- // back to normal mode, a grace period is given with DisplayPowerTimer.
- if (mDisplayPowerTimer &&
- (mPolicy.displayPowerMode != hal::PowerMode::ON ||
- mPolicy.displayPowerTimer == TimerState::Reset)) {
- constexpr GlobalSignals kNoSignals;
- return {configs->getMaxRefreshRateByPolicy(), kNoSignals};
- }
+ const bool powerOnImminent = mDisplayPowerTimer &&
+ (mPolicy.displayPowerMode != hal::PowerMode::ON ||
+ mPolicy.displayPowerTimer == TimerState::Reset);
const GlobalSignals signals{.touch = mTouchTimer && mPolicy.touch == TouchState::Active,
- .idle = mPolicy.idleTimer == TimerState::Expired};
+ .idle = mPolicy.idleTimer == TimerState::Expired,
+ .powerOnImminent = powerOnImminent};
return configs->getBestRefreshRate(mPolicy.contentRequirements, signals);
}
diff --git a/services/surfaceflinger/tests/unittests/RefreshRateConfigsTest.cpp b/services/surfaceflinger/tests/unittests/RefreshRateConfigsTest.cpp
index 4f20932..5d9b2a8 100644
--- a/services/surfaceflinger/tests/unittests/RefreshRateConfigsTest.cpp
+++ b/services/surfaceflinger/tests/unittests/RefreshRateConfigsTest.cpp
@@ -977,6 +977,32 @@
EXPECT_EQ(kMode90, configs.getBestRefreshRate(layers));
}
+TEST_F(RefreshRateConfigsTest, powerOnImminentConsidered) {
+ RefreshRateConfigs configs(kModes_60_90, kModeId60);
+
+ auto [refreshRate, signals] = configs.getBestRefreshRate({}, {});
+ EXPECT_FALSE(signals.powerOnImminent);
+ EXPECT_EQ(kMode90, refreshRate);
+
+ std::tie(refreshRate, signals) = configs.getBestRefreshRate({}, {.powerOnImminent = true});
+ EXPECT_TRUE(signals.powerOnImminent);
+ EXPECT_EQ(kMode90, refreshRate);
+
+ std::vector<LayerRequirement> layers = {{.weight = 1.f}};
+ auto& lr1 = layers[0];
+ lr1.vote = LayerVoteType::ExplicitExactOrMultiple;
+ lr1.desiredRefreshRate = 60_Hz;
+ lr1.name = "60Hz ExplicitExactOrMultiple";
+
+ std::tie(refreshRate, signals) = configs.getBestRefreshRate(layers, {.powerOnImminent = false});
+ EXPECT_FALSE(signals.powerOnImminent);
+ EXPECT_EQ(kMode60, refreshRate);
+
+ std::tie(refreshRate, signals) = configs.getBestRefreshRate(layers, {.powerOnImminent = true});
+ EXPECT_TRUE(signals.powerOnImminent);
+ EXPECT_EQ(kMode90, refreshRate);
+}
+
TEST_F(RefreshRateConfigsTest, touchConsidered) {
RefreshRateConfigs configs(kModes_60_90, kModeId60);