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);