diff options
author | Ady Abraham <adyabr@google.com> | 2021-11-10 19:46:09 -0800 |
---|---|---|
committer | Ady Abraham <adyabr@google.com> | 2021-11-15 11:37:29 -0800 |
commit | 11663406f0e40d26e71d90f6a31ff75ed17a6638 (patch) | |
tree | 3383966d7de6260829a61ebef04dfb689a976897 | |
parent | fe34457d2e4644d47d1d8047894c7819d5cd34a5 (diff) | |
download | native-11663406f0e40d26e71d90f6a31ff75ed17a6638.tar.gz |
SF: reset idle state when RefreshRateConfigs changes
RefreshRateConfigs calls back into Scheduler for updating the idle timer.
When RefreshRateConfigs changes as a result of the active display changed,
we need to stop the idle timer on the old RefreshRateConfigs and reset
Scheduler's state.
Bug: 205664808
Test: manual using below steps
1. Boot device on unfold state
2. Fold device
3. Unfold device
4. Launch Chrome from taskbar
Change-Id: I554fe2b2447c0ad662f06329ff74e0b9b3e999b3
-rw-r--r-- | services/surfaceflinger/Scheduler/RefreshRateConfigs.cpp | 1 | ||||
-rw-r--r-- | services/surfaceflinger/Scheduler/RefreshRateConfigs.h | 20 | ||||
-rw-r--r-- | services/surfaceflinger/Scheduler/Scheduler.h | 37 |
3 files changed, 42 insertions, 16 deletions
diff --git a/services/surfaceflinger/Scheduler/RefreshRateConfigs.cpp b/services/surfaceflinger/Scheduler/RefreshRateConfigs.cpp index ee1d7301c1..0ee9fb353d 100644 --- a/services/surfaceflinger/Scheduler/RefreshRateConfigs.cpp +++ b/services/surfaceflinger/Scheduler/RefreshRateConfigs.cpp @@ -701,7 +701,6 @@ void RefreshRateConfigs::initializeIdleTimer() { [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 2addc83225..21867ccac9 100644 --- a/services/surfaceflinger/Scheduler/RefreshRateConfigs.h +++ b/services/surfaceflinger/Scheduler/RefreshRateConfigs.h @@ -362,10 +362,22 @@ public: 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 ee519f33a3..bbbbca5b2f 100644 --- a/services/surfaceflinger/Scheduler/Scheduler.h +++ b/services/surfaceflinger/Scheduler/Scheduler.h @@ -181,17 +181,32 @@ public: 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) { |