Merge "SF: reset idle state when RefreshRateConfigs changes" into sc-v2-dev am: 2731fe5378

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/native/+/16235719

Change-Id: Ia851cb8d41c2b898b7a86826e967da30d02e8e09
diff --git a/services/surfaceflinger/Scheduler/RefreshRateConfigs.cpp b/services/surfaceflinger/Scheduler/RefreshRateConfigs.cpp
index ee1d730..0ee9fb3 100644
--- a/services/surfaceflinger/Scheduler/RefreshRateConfigs.cpp
+++ b/services/surfaceflinger/Scheduler/RefreshRateConfigs.cpp
@@ -701,7 +701,6 @@
                 [getCallback] {
                     if (const auto callback = getCallback()) callback->onExpired();
                 });
-        mIdleTimer->start();
     }
 }
 
diff --git a/services/surfaceflinger/Scheduler/RefreshRateConfigs.h b/services/surfaceflinger/Scheduler/RefreshRateConfigs.h
index 2addc83..21867cc 100644
--- a/services/surfaceflinger/Scheduler/RefreshRateConfigs.h
+++ b/services/surfaceflinger/Scheduler/RefreshRateConfigs.h
@@ -362,10 +362,22 @@
                                std::function<void()> kernelTimerExpired) {
         std::scoped_lock lock(mIdleTimerCallbacksMutex);
         mIdleTimerCallbacks.emplace();
-        mIdleTimerCallbacks->platform.onReset = platformTimerReset;
-        mIdleTimerCallbacks->platform.onExpired = platformTimerExpired;
-        mIdleTimerCallbacks->kernel.onReset = kernelTimerReset;
-        mIdleTimerCallbacks->kernel.onExpired = kernelTimerExpired;
+        mIdleTimerCallbacks->platform.onReset = std::move(platformTimerReset);
+        mIdleTimerCallbacks->platform.onExpired = std::move(platformTimerExpired);
+        mIdleTimerCallbacks->kernel.onReset = std::move(kernelTimerReset);
+        mIdleTimerCallbacks->kernel.onExpired = std::move(kernelTimerExpired);
+    }
+
+    void startIdleTimer() {
+        if (mIdleTimer) {
+            mIdleTimer->start();
+        }
+    }
+
+    void stopIdleTimer() {
+        if (mIdleTimer) {
+            mIdleTimer->stop();
+        }
     }
 
     void resetIdleTimer(bool kernelOnly) {
diff --git a/services/surfaceflinger/Scheduler/Scheduler.h b/services/surfaceflinger/Scheduler/Scheduler.h
index ee519f3..bbbbca5 100644
--- a/services/surfaceflinger/Scheduler/Scheduler.h
+++ b/services/surfaceflinger/Scheduler/Scheduler.h
@@ -181,17 +181,32 @@
 
     void setRefreshRateConfigs(std::shared_ptr<scheduler::RefreshRateConfigs> refreshRateConfigs)
             EXCLUDES(mRefreshRateConfigsLock) {
-        std::scoped_lock lock(mRefreshRateConfigsLock);
-        mRefreshRateConfigs = std::move(refreshRateConfigs);
-        mRefreshRateConfigs->setIdleTimerCallbacks(
-                [this] { std::invoke(&Scheduler::idleTimerCallback, this, TimerState::Reset); },
-                [this] { std::invoke(&Scheduler::idleTimerCallback, this, TimerState::Expired); },
-                [this] {
-                    std::invoke(&Scheduler::kernelIdleTimerCallback, this, TimerState::Reset);
-                },
-                [this] {
-                    std::invoke(&Scheduler::kernelIdleTimerCallback, this, TimerState::Expired);
-                });
+        // We need to stop the idle timer on the previous RefreshRateConfigs instance
+        // and cleanup the scheduler's state before we switch to the other RefreshRateConfigs.
+        {
+            std::scoped_lock lock(mRefreshRateConfigsLock);
+            if (mRefreshRateConfigs) mRefreshRateConfigs->stopIdleTimer();
+        }
+        {
+            std::scoped_lock lock(mFeatureStateLock);
+            mFeatures = {};
+        }
+        {
+            std::scoped_lock lock(mRefreshRateConfigsLock);
+            mRefreshRateConfigs = std::move(refreshRateConfigs);
+            mRefreshRateConfigs->setIdleTimerCallbacks(
+                    [this] { std::invoke(&Scheduler::idleTimerCallback, this, TimerState::Reset); },
+                    [this] {
+                        std::invoke(&Scheduler::idleTimerCallback, this, TimerState::Expired);
+                    },
+                    [this] {
+                        std::invoke(&Scheduler::kernelIdleTimerCallback, this, TimerState::Reset);
+                    },
+                    [this] {
+                        std::invoke(&Scheduler::kernelIdleTimerCallback, this, TimerState::Expired);
+                    });
+            mRefreshRateConfigs->startIdleTimer();
+        }
     }
 
     nsecs_t getVsyncPeriodFromRefreshRateConfigs() const EXCLUDES(mRefreshRateConfigsLock) {