Loading services/surfaceflinger/Scheduler/Scheduler.cpp +9 −11 Original line number Diff line number Diff line Loading @@ -308,14 +308,10 @@ void Scheduler::incrementFrameCounter() { mLayerHistory.incrementCounter(); } void Scheduler::setExpiredIdleTimerCallback(const ExpiredIdleTimerCallback& expiredTimerCallback) { void Scheduler::setChangeRefreshRateCallback( const ChangeRefreshRateCallback& changeRefreshRateCallback) { std::lock_guard<std::mutex> lock(mCallbackLock); mExpiredTimerCallback = expiredTimerCallback; } void Scheduler::setResetIdleTimerCallback(const ResetIdleTimerCallback& resetTimerCallback) { std::lock_guard<std::mutex> lock(mCallbackLock); mResetTimerCallback = resetTimerCallback; mChangeRefreshRateCallback = changeRefreshRateCallback; } void Scheduler::updateFrameSkipping(const int64_t skipCount) { Loading Loading @@ -414,16 +410,18 @@ void Scheduler::resetIdleTimer() { void Scheduler::resetTimerCallback() { std::lock_guard<std::mutex> lock(mCallbackLock); if (mResetTimerCallback) { mResetTimerCallback(); if (mChangeRefreshRateCallback) { // We do not notify the applications about config changes when idle timer is reset. mChangeRefreshRateCallback(RefreshRateType::PERFORMANCE, ConfigEvent::None); ATRACE_INT("ExpiredIdleTimer", 0); } } void Scheduler::expiredTimerCallback() { std::lock_guard<std::mutex> lock(mCallbackLock); if (mExpiredTimerCallback) { mExpiredTimerCallback(); if (mChangeRefreshRateCallback) { // We do not notify the applications about config changes when idle timer expires. mChangeRefreshRateCallback(RefreshRateType::DEFAULT, ConfigEvent::None); ATRACE_INT("ExpiredIdleTimer", 1); } } Loading services/surfaceflinger/Scheduler/Scheduler.h +16 −8 Original line number Diff line number Diff line Loading @@ -28,6 +28,7 @@ #include "IdleTimer.h" #include "InjectVSyncSource.h" #include "LayerHistory.h" #include "RefreshRateConfigs.h" #include "SchedulerUtils.h" namespace android { Loading @@ -36,9 +37,19 @@ class EventControlThread; class Scheduler { public: using ExpiredIdleTimerCallback = std::function<void()>; // Enum to keep track of whether we trigger event to notify choreographer of config changes. enum class ConfigEvent { None, Changed }; // logical or operator with the semantics of at least one of the events is Changed friend ConfigEvent operator|(const ConfigEvent& first, const ConfigEvent& second) { if (first == ConfigEvent::Changed) return ConfigEvent::Changed; if (second == ConfigEvent::Changed) return ConfigEvent::Changed; return ConfigEvent::None; } using RefreshRateType = scheduler::RefreshRateConfigs::RefreshRateType; using ChangeRefreshRateCallback = std::function<void(RefreshRateType, ConfigEvent)>; using GetVsyncPeriod = std::function<nsecs_t()>; using ResetIdleTimerCallback = std::function<void()>; // Enum to indicate whether to start the transaction early, or at vsync time. enum class TransactionStart { EARLY, NORMAL }; Loading Loading @@ -135,10 +146,8 @@ public: const std::string layerName); // Increments counter in the layer history to indicate that SF has started a new frame. void incrementFrameCounter(); // Callback that gets invoked once the idle timer expires. void setExpiredIdleTimerCallback(const ExpiredIdleTimerCallback& expiredTimerCallback); // Callback that gets invoked once the idle timer is reset. void setResetIdleTimerCallback(const ResetIdleTimerCallback& resetTimerCallback); // Callback that gets invoked when Scheduler wants to change the refresh rate. void setChangeRefreshRateCallback(const ChangeRefreshRateCallback& changeRefreshRateCallback); // Returns relevant information about Scheduler for dumpsys purposes. std::string doDump(); Loading Loading @@ -216,8 +225,7 @@ private: std::unique_ptr<scheduler::IdleTimer> mIdleTimer; std::mutex mCallbackLock; ExpiredIdleTimerCallback mExpiredTimerCallback GUARDED_BY(mCallbackLock); ExpiredIdleTimerCallback mResetTimerCallback GUARDED_BY(mCallbackLock); ChangeRefreshRateCallback mChangeRefreshRateCallback GUARDED_BY(mCallbackLock); }; } // namespace android services/surfaceflinger/SurfaceFlinger.cpp +13 −16 Original line number Diff line number Diff line Loading @@ -571,11 +571,11 @@ void SurfaceFlinger::bootFinished() if (mUse90Hz) { mPhaseOffsets->setRefreshRateType( scheduler::RefreshRateConfigs::RefreshRateType::PERFORMANCE); setRefreshRateTo(RefreshRateType::PERFORMANCE, ConfigEvent::None); setRefreshRateTo(RefreshRateType::PERFORMANCE, Scheduler::ConfigEvent::None); } else { mPhaseOffsets->setRefreshRateType( scheduler::RefreshRateConfigs::RefreshRateType::DEFAULT); setRefreshRateTo(RefreshRateType::DEFAULT, ConfigEvent::None); setRefreshRateTo(RefreshRateType::DEFAULT, Scheduler::ConfigEvent::None); } })); } Loading Loading @@ -700,13 +700,10 @@ void SurfaceFlinger::init() { } if (mUse90Hz) { mScheduler->setExpiredIdleTimerCallback([this] { mScheduler->setChangeRefreshRateCallback( [this](RefreshRateType type, Scheduler::ConfigEvent event) { Mutex::Autolock lock(mStateLock); setRefreshRateTo(RefreshRateType::DEFAULT, ConfigEvent::None); }); mScheduler->setResetIdleTimerCallback([this] { Mutex::Autolock lock(mStateLock); setRefreshRateTo(RefreshRateType::PERFORMANCE, ConfigEvent::None); setRefreshRateTo(type, event); }); } mRefreshRateConfigs[*display->getId()] = std::make_shared<scheduler::RefreshRateConfigs>( Loading Loading @@ -917,7 +914,7 @@ int SurfaceFlinger::getActiveConfig(const sp<IBinder>& displayToken) { } void SurfaceFlinger::setDesiredActiveConfig(const sp<IBinder>& displayToken, int mode, ConfigEvent event) { Scheduler::ConfigEvent event) { ATRACE_CALL(); // Lock is acquired by setRefreshRateTo. Loading @@ -941,7 +938,7 @@ void SurfaceFlinger::setDesiredActiveConfig(const sp<IBinder>& displayToken, int // config twice. However event generation config might have changed so we need to update it // accordingly std::lock_guard<std::mutex> lock(mActiveConfigLock); const ConfigEvent desiredConfig = mDesiredActiveConfig.event | event; const Scheduler::ConfigEvent desiredConfig = mDesiredActiveConfig.event | event; mDesiredActiveConfig = ActiveConfigInfo{mode, displayToken, desiredConfig}; if (!mDesiredActiveConfigChanged) { Loading Loading @@ -975,7 +972,7 @@ void SurfaceFlinger::setActiveConfigInternal() { mScheduler->resyncToHardwareVsync(true, getVsyncPeriod()); ATRACE_INT("ActiveConfigMode", mUpcomingActiveConfig.configId); if (mUpcomingActiveConfig.event != ConfigEvent::None) { if (mUpcomingActiveConfig.event != Scheduler::ConfigEvent::None) { mScheduler->onConfigChanged(mAppConnectionHandle, display->getId()->value, mUpcomingActiveConfig.configId); } Loading Loading @@ -1416,9 +1413,8 @@ bool SurfaceFlinger::isConfigAllowed(const DisplayId& displayId, int32_t config) return mAllowedConfigs[displayId]->isConfigAllowed(config); } void SurfaceFlinger::setRefreshRateTo(RefreshRateType refreshRate, ConfigEvent event) { void SurfaceFlinger::setRefreshRateTo(RefreshRateType refreshRate, Scheduler::ConfigEvent event) { ATRACE_CALL(); mPhaseOffsets->setRefreshRateType(refreshRate); const auto [early, gl, late] = mPhaseOffsets->getCurrentOffsets(); Loading Loading @@ -5656,7 +5652,8 @@ void SurfaceFlinger::setAllowedDisplayConfigsInternal( // we may want to enhance this logic to pick a similar config // to the current one ALOGV("Old config is not allowed - switching to config %d", config.configId); setDesiredActiveConfig(displayToken, config.configId, ConfigEvent::Changed); setDesiredActiveConfig(displayToken, config.configId, Scheduler::ConfigEvent::Changed); break; } } Loading services/surfaceflinger/SurfaceFlinger.h +5 −14 Original line number Diff line number Diff line Loading @@ -522,20 +522,11 @@ private: void signalLayerUpdate(); void signalRefresh(); enum class ConfigEvent { None, Changed }; // logical or operator with the semantics of at least one of the events is Changed friend ConfigEvent operator|(const ConfigEvent& first, const ConfigEvent& second) { if (first == ConfigEvent::Changed) return ConfigEvent::Changed; if (second == ConfigEvent::Changed) return ConfigEvent::Changed; return ConfigEvent::None; } // called on the main thread in response to initializeDisplays() void onInitializeDisplays() REQUIRES(mStateLock); // Sets the desired active config bit. It obtains the lock, and sets mDesiredActiveConfig. void setDesiredActiveConfig(const sp<IBinder>& displayToken, int mode, ConfigEvent event) REQUIRES(mStateLock); void setDesiredActiveConfig(const sp<IBinder>& displayToken, int mode, Scheduler::ConfigEvent event) REQUIRES(mStateLock); // Once HWC has returned the present fence, this sets the active config and a new refresh // rate in SF. It also triggers HWC vsync. void setActiveConfigInternal() REQUIRES(mStateLock); Loading Loading @@ -816,8 +807,8 @@ private: // Sets the refresh rate by switching active configs, if they are available for // the desired refresh rate. void setRefreshRateTo(scheduler::RefreshRateConfigs::RefreshRateType, ConfigEvent event) REQUIRES(mStateLock); void setRefreshRateTo(scheduler::RefreshRateConfigs::RefreshRateType, Scheduler::ConfigEvent event) REQUIRES(mStateLock); bool isConfigAllowed(const DisplayId& displayId, int32_t config); Loading Loading @@ -1126,7 +1117,7 @@ private: struct ActiveConfigInfo { int configId; sp<IBinder> displayToken; ConfigEvent event; Scheduler::ConfigEvent event; bool operator!=(const ActiveConfigInfo& other) const { if (configId != other.configId) { Loading Loading
services/surfaceflinger/Scheduler/Scheduler.cpp +9 −11 Original line number Diff line number Diff line Loading @@ -308,14 +308,10 @@ void Scheduler::incrementFrameCounter() { mLayerHistory.incrementCounter(); } void Scheduler::setExpiredIdleTimerCallback(const ExpiredIdleTimerCallback& expiredTimerCallback) { void Scheduler::setChangeRefreshRateCallback( const ChangeRefreshRateCallback& changeRefreshRateCallback) { std::lock_guard<std::mutex> lock(mCallbackLock); mExpiredTimerCallback = expiredTimerCallback; } void Scheduler::setResetIdleTimerCallback(const ResetIdleTimerCallback& resetTimerCallback) { std::lock_guard<std::mutex> lock(mCallbackLock); mResetTimerCallback = resetTimerCallback; mChangeRefreshRateCallback = changeRefreshRateCallback; } void Scheduler::updateFrameSkipping(const int64_t skipCount) { Loading Loading @@ -414,16 +410,18 @@ void Scheduler::resetIdleTimer() { void Scheduler::resetTimerCallback() { std::lock_guard<std::mutex> lock(mCallbackLock); if (mResetTimerCallback) { mResetTimerCallback(); if (mChangeRefreshRateCallback) { // We do not notify the applications about config changes when idle timer is reset. mChangeRefreshRateCallback(RefreshRateType::PERFORMANCE, ConfigEvent::None); ATRACE_INT("ExpiredIdleTimer", 0); } } void Scheduler::expiredTimerCallback() { std::lock_guard<std::mutex> lock(mCallbackLock); if (mExpiredTimerCallback) { mExpiredTimerCallback(); if (mChangeRefreshRateCallback) { // We do not notify the applications about config changes when idle timer expires. mChangeRefreshRateCallback(RefreshRateType::DEFAULT, ConfigEvent::None); ATRACE_INT("ExpiredIdleTimer", 1); } } Loading
services/surfaceflinger/Scheduler/Scheduler.h +16 −8 Original line number Diff line number Diff line Loading @@ -28,6 +28,7 @@ #include "IdleTimer.h" #include "InjectVSyncSource.h" #include "LayerHistory.h" #include "RefreshRateConfigs.h" #include "SchedulerUtils.h" namespace android { Loading @@ -36,9 +37,19 @@ class EventControlThread; class Scheduler { public: using ExpiredIdleTimerCallback = std::function<void()>; // Enum to keep track of whether we trigger event to notify choreographer of config changes. enum class ConfigEvent { None, Changed }; // logical or operator with the semantics of at least one of the events is Changed friend ConfigEvent operator|(const ConfigEvent& first, const ConfigEvent& second) { if (first == ConfigEvent::Changed) return ConfigEvent::Changed; if (second == ConfigEvent::Changed) return ConfigEvent::Changed; return ConfigEvent::None; } using RefreshRateType = scheduler::RefreshRateConfigs::RefreshRateType; using ChangeRefreshRateCallback = std::function<void(RefreshRateType, ConfigEvent)>; using GetVsyncPeriod = std::function<nsecs_t()>; using ResetIdleTimerCallback = std::function<void()>; // Enum to indicate whether to start the transaction early, or at vsync time. enum class TransactionStart { EARLY, NORMAL }; Loading Loading @@ -135,10 +146,8 @@ public: const std::string layerName); // Increments counter in the layer history to indicate that SF has started a new frame. void incrementFrameCounter(); // Callback that gets invoked once the idle timer expires. void setExpiredIdleTimerCallback(const ExpiredIdleTimerCallback& expiredTimerCallback); // Callback that gets invoked once the idle timer is reset. void setResetIdleTimerCallback(const ResetIdleTimerCallback& resetTimerCallback); // Callback that gets invoked when Scheduler wants to change the refresh rate. void setChangeRefreshRateCallback(const ChangeRefreshRateCallback& changeRefreshRateCallback); // Returns relevant information about Scheduler for dumpsys purposes. std::string doDump(); Loading Loading @@ -216,8 +225,7 @@ private: std::unique_ptr<scheduler::IdleTimer> mIdleTimer; std::mutex mCallbackLock; ExpiredIdleTimerCallback mExpiredTimerCallback GUARDED_BY(mCallbackLock); ExpiredIdleTimerCallback mResetTimerCallback GUARDED_BY(mCallbackLock); ChangeRefreshRateCallback mChangeRefreshRateCallback GUARDED_BY(mCallbackLock); }; } // namespace android
services/surfaceflinger/SurfaceFlinger.cpp +13 −16 Original line number Diff line number Diff line Loading @@ -571,11 +571,11 @@ void SurfaceFlinger::bootFinished() if (mUse90Hz) { mPhaseOffsets->setRefreshRateType( scheduler::RefreshRateConfigs::RefreshRateType::PERFORMANCE); setRefreshRateTo(RefreshRateType::PERFORMANCE, ConfigEvent::None); setRefreshRateTo(RefreshRateType::PERFORMANCE, Scheduler::ConfigEvent::None); } else { mPhaseOffsets->setRefreshRateType( scheduler::RefreshRateConfigs::RefreshRateType::DEFAULT); setRefreshRateTo(RefreshRateType::DEFAULT, ConfigEvent::None); setRefreshRateTo(RefreshRateType::DEFAULT, Scheduler::ConfigEvent::None); } })); } Loading Loading @@ -700,13 +700,10 @@ void SurfaceFlinger::init() { } if (mUse90Hz) { mScheduler->setExpiredIdleTimerCallback([this] { mScheduler->setChangeRefreshRateCallback( [this](RefreshRateType type, Scheduler::ConfigEvent event) { Mutex::Autolock lock(mStateLock); setRefreshRateTo(RefreshRateType::DEFAULT, ConfigEvent::None); }); mScheduler->setResetIdleTimerCallback([this] { Mutex::Autolock lock(mStateLock); setRefreshRateTo(RefreshRateType::PERFORMANCE, ConfigEvent::None); setRefreshRateTo(type, event); }); } mRefreshRateConfigs[*display->getId()] = std::make_shared<scheduler::RefreshRateConfigs>( Loading Loading @@ -917,7 +914,7 @@ int SurfaceFlinger::getActiveConfig(const sp<IBinder>& displayToken) { } void SurfaceFlinger::setDesiredActiveConfig(const sp<IBinder>& displayToken, int mode, ConfigEvent event) { Scheduler::ConfigEvent event) { ATRACE_CALL(); // Lock is acquired by setRefreshRateTo. Loading @@ -941,7 +938,7 @@ void SurfaceFlinger::setDesiredActiveConfig(const sp<IBinder>& displayToken, int // config twice. However event generation config might have changed so we need to update it // accordingly std::lock_guard<std::mutex> lock(mActiveConfigLock); const ConfigEvent desiredConfig = mDesiredActiveConfig.event | event; const Scheduler::ConfigEvent desiredConfig = mDesiredActiveConfig.event | event; mDesiredActiveConfig = ActiveConfigInfo{mode, displayToken, desiredConfig}; if (!mDesiredActiveConfigChanged) { Loading Loading @@ -975,7 +972,7 @@ void SurfaceFlinger::setActiveConfigInternal() { mScheduler->resyncToHardwareVsync(true, getVsyncPeriod()); ATRACE_INT("ActiveConfigMode", mUpcomingActiveConfig.configId); if (mUpcomingActiveConfig.event != ConfigEvent::None) { if (mUpcomingActiveConfig.event != Scheduler::ConfigEvent::None) { mScheduler->onConfigChanged(mAppConnectionHandle, display->getId()->value, mUpcomingActiveConfig.configId); } Loading Loading @@ -1416,9 +1413,8 @@ bool SurfaceFlinger::isConfigAllowed(const DisplayId& displayId, int32_t config) return mAllowedConfigs[displayId]->isConfigAllowed(config); } void SurfaceFlinger::setRefreshRateTo(RefreshRateType refreshRate, ConfigEvent event) { void SurfaceFlinger::setRefreshRateTo(RefreshRateType refreshRate, Scheduler::ConfigEvent event) { ATRACE_CALL(); mPhaseOffsets->setRefreshRateType(refreshRate); const auto [early, gl, late] = mPhaseOffsets->getCurrentOffsets(); Loading Loading @@ -5656,7 +5652,8 @@ void SurfaceFlinger::setAllowedDisplayConfigsInternal( // we may want to enhance this logic to pick a similar config // to the current one ALOGV("Old config is not allowed - switching to config %d", config.configId); setDesiredActiveConfig(displayToken, config.configId, ConfigEvent::Changed); setDesiredActiveConfig(displayToken, config.configId, Scheduler::ConfigEvent::Changed); break; } } Loading
services/surfaceflinger/SurfaceFlinger.h +5 −14 Original line number Diff line number Diff line Loading @@ -522,20 +522,11 @@ private: void signalLayerUpdate(); void signalRefresh(); enum class ConfigEvent { None, Changed }; // logical or operator with the semantics of at least one of the events is Changed friend ConfigEvent operator|(const ConfigEvent& first, const ConfigEvent& second) { if (first == ConfigEvent::Changed) return ConfigEvent::Changed; if (second == ConfigEvent::Changed) return ConfigEvent::Changed; return ConfigEvent::None; } // called on the main thread in response to initializeDisplays() void onInitializeDisplays() REQUIRES(mStateLock); // Sets the desired active config bit. It obtains the lock, and sets mDesiredActiveConfig. void setDesiredActiveConfig(const sp<IBinder>& displayToken, int mode, ConfigEvent event) REQUIRES(mStateLock); void setDesiredActiveConfig(const sp<IBinder>& displayToken, int mode, Scheduler::ConfigEvent event) REQUIRES(mStateLock); // Once HWC has returned the present fence, this sets the active config and a new refresh // rate in SF. It also triggers HWC vsync. void setActiveConfigInternal() REQUIRES(mStateLock); Loading Loading @@ -816,8 +807,8 @@ private: // Sets the refresh rate by switching active configs, if they are available for // the desired refresh rate. void setRefreshRateTo(scheduler::RefreshRateConfigs::RefreshRateType, ConfigEvent event) REQUIRES(mStateLock); void setRefreshRateTo(scheduler::RefreshRateConfigs::RefreshRateType, Scheduler::ConfigEvent event) REQUIRES(mStateLock); bool isConfigAllowed(const DisplayId& displayId, int32_t config); Loading Loading @@ -1126,7 +1117,7 @@ private: struct ActiveConfigInfo { int configId; sp<IBinder> displayToken; ConfigEvent event; Scheduler::ConfigEvent event; bool operator!=(const ActiveConfigInfo& other) const { if (configId != other.configId) { Loading