Loading services/surfaceflinger/Scheduler/LayerHistory.cpp +8 −0 Original line number Diff line number Diff line Loading @@ -20,6 +20,7 @@ #include "LayerHistory.h" #include <android-base/stringprintf.h> #include <cutils/properties.h> #include <utils/Log.h> #include <utils/Timers.h> Loading Loading @@ -183,4 +184,11 @@ void LayerHistory::clear() { mActiveLayersEnd = 0; } std::string LayerHistory::dump() const { std::lock_guard lock(mLock); return base::StringPrintf("LayerHistory{size=%zu, active=%zu}", mLayerInfos.size(), mActiveLayersEnd); } } // namespace android::scheduler::impl services/surfaceflinger/Scheduler/LayerHistory.h +4 −0 Original line number Diff line number Diff line Loading @@ -22,6 +22,7 @@ #include <memory> #include <mutex> #include <string> #include <utility> #include <vector> Loading Loading @@ -71,6 +72,7 @@ public: virtual Summary summarize(nsecs_t now) = 0; virtual void clear() = 0; virtual std::string dump() const = 0; }; namespace impl { Loading @@ -97,6 +99,7 @@ public: android::scheduler::LayerHistory::Summary summarize(nsecs_t now) override; void clear() override; std::string dump() const override; private: friend class android::scheduler::LayerHistoryTest; Loading Loading @@ -155,6 +158,7 @@ public: android::scheduler::LayerHistory::Summary summarize(nsecs_t /*now*/) override; void clear() override; std::string dump() const override; private: friend android::scheduler::LayerHistoryTestV2; Loading services/surfaceflinger/Scheduler/LayerHistoryV2.cpp +8 −2 Original line number Diff line number Diff line Loading @@ -20,6 +20,7 @@ #include "LayerHistory.h" #include <android-base/stringprintf.h> #include <cutils/properties.h> #include <utils/Log.h> #include <utils/Timers.h> Loading @@ -31,9 +32,8 @@ #include <utility> #include "../Layer.h" #include "SchedulerUtils.h" #include "LayerInfoV2.h" #include "SchedulerUtils.h" namespace android::scheduler::impl { Loading Loading @@ -214,4 +214,10 @@ void LayerHistoryV2::clear() { } } std::string LayerHistoryV2::dump() const { std::lock_guard lock(mLock); return base::StringPrintf("LayerHistoryV2{size=%zu, active=%zu}", mLayerInfos.size(), mActiveLayersEnd); } } // namespace android::scheduler::impl services/surfaceflinger/Scheduler/RefreshRateConfigs.h +5 −0 Original line number Diff line number Diff line Loading @@ -280,6 +280,11 @@ public: RefreshRateConfigs(const std::vector<std::shared_ptr<const HWC2::Display::Config>>& configs, HwcConfigIndexType currentConfigId); // Returns whether switching configs (refresh rate or resolution) is possible. // TODO(b/158780872): Consider HAL support, and skip frame rate detection if the configs only // differ in resolution. bool canSwitch() const { return mRefreshRates.size() > 1; } // Class to enumerate options around toggling the kernel timer on and off. We have an option // for no change to avoid extra calls to kernel. enum class KernelIdleTimerAction { Loading services/surfaceflinger/Scheduler/Scheduler.cpp +38 −26 Original line number Diff line number Diff line Loading @@ -61,6 +61,7 @@ } while (false) namespace android { namespace { std::unique_ptr<DispSync> createDispSync(bool supportKernelTimer) { // TODO (140302863) remove this and use the vsync_reactor system. Loading Loading @@ -97,25 +98,27 @@ std::unique_ptr<DispSync> createDispSync(bool supportKernelTimer) { } } const char* toContentDetectionString(bool useContentDetection, bool useContentDetectionV2) { if (!useContentDetection) return "off"; return useContentDetectionV2 ? "V2" : "V1"; } } // namespace Scheduler::Scheduler(impl::EventControlThread::SetVSyncEnabledFunction function, const scheduler::RefreshRateConfigs& refreshRateConfig, const scheduler::RefreshRateConfigs& refreshRateConfigs, ISchedulerCallback& schedulerCallback, bool useContentDetectionV2, bool useContentDetection) : mSupportKernelTimer(sysprop::support_kernel_idle_timer(false)), mPrimaryDispSync(createDispSync(mSupportKernelTimer)), mEventControlThread(new impl::EventControlThread(std::move(function))), mLayerHistory(createLayerHistory(refreshRateConfigs, useContentDetectionV2)), mSchedulerCallback(schedulerCallback), mRefreshRateConfigs(refreshRateConfig), mRefreshRateConfigs(refreshRateConfigs), mUseContentDetection(useContentDetection), mUseContentDetectionV2(useContentDetectionV2) { using namespace sysprop; if (mUseContentDetectionV2) { mLayerHistory = std::make_unique<scheduler::impl::LayerHistoryV2>(refreshRateConfig); } else { mLayerHistory = std::make_unique<scheduler::impl::LayerHistory>(); } const int setIdleTimerMs = property_get_int32("debug.sf.set_idle_timer_ms", 0); if (const auto millis = setIdleTimerMs ? setIdleTimerMs : set_idle_timer_ms(0); millis > 0) { Loading Loading @@ -149,11 +152,13 @@ Scheduler::Scheduler(impl::EventControlThread::SetVSyncEnabledFunction function, Scheduler::Scheduler(std::unique_ptr<DispSync> primaryDispSync, std::unique_ptr<EventControlThread> eventControlThread, const scheduler::RefreshRateConfigs& configs, ISchedulerCallback& schedulerCallback, bool useContentDetectionV2, ISchedulerCallback& schedulerCallback, std::unique_ptr<LayerHistory> layerHistory, bool useContentDetectionV2, bool useContentDetection) : mSupportKernelTimer(false), mPrimaryDispSync(std::move(primaryDispSync)), mEventControlThread(std::move(eventControlThread)), mLayerHistory(std::move(layerHistory)), mSchedulerCallback(schedulerCallback), mRefreshRateConfigs(configs), mUseContentDetection(useContentDetection), Loading @@ -166,6 +171,17 @@ Scheduler::~Scheduler() { mIdleTimer.reset(); } std::unique_ptr<LayerHistory> Scheduler::createLayerHistory( const scheduler::RefreshRateConfigs& configs, bool useContentDetectionV2) { if (!configs.canSwitch()) return nullptr; if (useContentDetectionV2) { return std::make_unique<scheduler::impl::LayerHistoryV2>(configs); } return std::make_unique<scheduler::impl::LayerHistory>(); } DispSync& Scheduler::getPrimaryDispSync() { return *mPrimaryDispSync; } Loading Loading @@ -499,16 +515,7 @@ void Scheduler::resetIdleTimer() { } void Scheduler::notifyTouchEvent() { if (!mTouchTimer) return; // Touch event will boost the refresh rate to performance. // Clear Layer History to get fresh FPS detection. // NOTE: Instead of checking all the layers, we should be checking the layer // that is currently on top. b/142507166 will give us this capability. std::lock_guard<std::mutex> lock(mFeatureStateLock); if (mLayerHistory) { // Layer History will be cleared based on RefreshRateConfigs::getBestRefreshRate if (mTouchTimer) { mTouchTimer->reset(); if (mSupportKernelTimer && mIdleTimer) { Loading Loading @@ -564,9 +571,15 @@ void Scheduler::idleTimerCallback(TimerState state) { void Scheduler::touchTimerCallback(TimerState state) { const TouchState touch = state == TimerState::Reset ? TouchState::Active : TouchState::Inactive; // Touch event will boost the refresh rate to performance. // Clear layer history to get fresh FPS detection. // NOTE: Instead of checking all the layers, we should be checking the layer // that is currently on top. b/142507166 will give us this capability. if (handleTimerStateChanged(&mFeatures.touch, touch)) { if (mLayerHistory) { mLayerHistory->clear(); } } ATRACE_INT("TouchState", static_cast<int>(touch)); } Loading @@ -577,14 +590,13 @@ void Scheduler::displayPowerTimerCallback(TimerState state) { void Scheduler::dump(std::string& result) const { using base::StringAppendF; const char* const states[] = {"off", "on"}; StringAppendF(&result, "+ Idle timer: %s\n", mIdleTimer ? mIdleTimer->dump().c_str() : states[0]); StringAppendF(&result, "+ Idle timer: %s\n", mIdleTimer ? mIdleTimer->dump().c_str() : "off"); StringAppendF(&result, "+ Touch timer: %s\n", mTouchTimer ? mTouchTimer->dump().c_str() : states[0]); StringAppendF(&result, "+ Use content detection: %s\n\n", sysprop::use_content_detection_for_refresh_rate(false) ? "on" : "off"); mTouchTimer ? mTouchTimer->dump().c_str() : "off"); StringAppendF(&result, "+ Content detection: %s %s\n\n", toContentDetectionString(mUseContentDetection, mUseContentDetectionV2), mLayerHistory ? mLayerHistory->dump().c_str() : "(no layer history)"); } template <class T> Loading Loading
services/surfaceflinger/Scheduler/LayerHistory.cpp +8 −0 Original line number Diff line number Diff line Loading @@ -20,6 +20,7 @@ #include "LayerHistory.h" #include <android-base/stringprintf.h> #include <cutils/properties.h> #include <utils/Log.h> #include <utils/Timers.h> Loading Loading @@ -183,4 +184,11 @@ void LayerHistory::clear() { mActiveLayersEnd = 0; } std::string LayerHistory::dump() const { std::lock_guard lock(mLock); return base::StringPrintf("LayerHistory{size=%zu, active=%zu}", mLayerInfos.size(), mActiveLayersEnd); } } // namespace android::scheduler::impl
services/surfaceflinger/Scheduler/LayerHistory.h +4 −0 Original line number Diff line number Diff line Loading @@ -22,6 +22,7 @@ #include <memory> #include <mutex> #include <string> #include <utility> #include <vector> Loading Loading @@ -71,6 +72,7 @@ public: virtual Summary summarize(nsecs_t now) = 0; virtual void clear() = 0; virtual std::string dump() const = 0; }; namespace impl { Loading @@ -97,6 +99,7 @@ public: android::scheduler::LayerHistory::Summary summarize(nsecs_t now) override; void clear() override; std::string dump() const override; private: friend class android::scheduler::LayerHistoryTest; Loading Loading @@ -155,6 +158,7 @@ public: android::scheduler::LayerHistory::Summary summarize(nsecs_t /*now*/) override; void clear() override; std::string dump() const override; private: friend android::scheduler::LayerHistoryTestV2; Loading
services/surfaceflinger/Scheduler/LayerHistoryV2.cpp +8 −2 Original line number Diff line number Diff line Loading @@ -20,6 +20,7 @@ #include "LayerHistory.h" #include <android-base/stringprintf.h> #include <cutils/properties.h> #include <utils/Log.h> #include <utils/Timers.h> Loading @@ -31,9 +32,8 @@ #include <utility> #include "../Layer.h" #include "SchedulerUtils.h" #include "LayerInfoV2.h" #include "SchedulerUtils.h" namespace android::scheduler::impl { Loading Loading @@ -214,4 +214,10 @@ void LayerHistoryV2::clear() { } } std::string LayerHistoryV2::dump() const { std::lock_guard lock(mLock); return base::StringPrintf("LayerHistoryV2{size=%zu, active=%zu}", mLayerInfos.size(), mActiveLayersEnd); } } // namespace android::scheduler::impl
services/surfaceflinger/Scheduler/RefreshRateConfigs.h +5 −0 Original line number Diff line number Diff line Loading @@ -280,6 +280,11 @@ public: RefreshRateConfigs(const std::vector<std::shared_ptr<const HWC2::Display::Config>>& configs, HwcConfigIndexType currentConfigId); // Returns whether switching configs (refresh rate or resolution) is possible. // TODO(b/158780872): Consider HAL support, and skip frame rate detection if the configs only // differ in resolution. bool canSwitch() const { return mRefreshRates.size() > 1; } // Class to enumerate options around toggling the kernel timer on and off. We have an option // for no change to avoid extra calls to kernel. enum class KernelIdleTimerAction { Loading
services/surfaceflinger/Scheduler/Scheduler.cpp +38 −26 Original line number Diff line number Diff line Loading @@ -61,6 +61,7 @@ } while (false) namespace android { namespace { std::unique_ptr<DispSync> createDispSync(bool supportKernelTimer) { // TODO (140302863) remove this and use the vsync_reactor system. Loading Loading @@ -97,25 +98,27 @@ std::unique_ptr<DispSync> createDispSync(bool supportKernelTimer) { } } const char* toContentDetectionString(bool useContentDetection, bool useContentDetectionV2) { if (!useContentDetection) return "off"; return useContentDetectionV2 ? "V2" : "V1"; } } // namespace Scheduler::Scheduler(impl::EventControlThread::SetVSyncEnabledFunction function, const scheduler::RefreshRateConfigs& refreshRateConfig, const scheduler::RefreshRateConfigs& refreshRateConfigs, ISchedulerCallback& schedulerCallback, bool useContentDetectionV2, bool useContentDetection) : mSupportKernelTimer(sysprop::support_kernel_idle_timer(false)), mPrimaryDispSync(createDispSync(mSupportKernelTimer)), mEventControlThread(new impl::EventControlThread(std::move(function))), mLayerHistory(createLayerHistory(refreshRateConfigs, useContentDetectionV2)), mSchedulerCallback(schedulerCallback), mRefreshRateConfigs(refreshRateConfig), mRefreshRateConfigs(refreshRateConfigs), mUseContentDetection(useContentDetection), mUseContentDetectionV2(useContentDetectionV2) { using namespace sysprop; if (mUseContentDetectionV2) { mLayerHistory = std::make_unique<scheduler::impl::LayerHistoryV2>(refreshRateConfig); } else { mLayerHistory = std::make_unique<scheduler::impl::LayerHistory>(); } const int setIdleTimerMs = property_get_int32("debug.sf.set_idle_timer_ms", 0); if (const auto millis = setIdleTimerMs ? setIdleTimerMs : set_idle_timer_ms(0); millis > 0) { Loading Loading @@ -149,11 +152,13 @@ Scheduler::Scheduler(impl::EventControlThread::SetVSyncEnabledFunction function, Scheduler::Scheduler(std::unique_ptr<DispSync> primaryDispSync, std::unique_ptr<EventControlThread> eventControlThread, const scheduler::RefreshRateConfigs& configs, ISchedulerCallback& schedulerCallback, bool useContentDetectionV2, ISchedulerCallback& schedulerCallback, std::unique_ptr<LayerHistory> layerHistory, bool useContentDetectionV2, bool useContentDetection) : mSupportKernelTimer(false), mPrimaryDispSync(std::move(primaryDispSync)), mEventControlThread(std::move(eventControlThread)), mLayerHistory(std::move(layerHistory)), mSchedulerCallback(schedulerCallback), mRefreshRateConfigs(configs), mUseContentDetection(useContentDetection), Loading @@ -166,6 +171,17 @@ Scheduler::~Scheduler() { mIdleTimer.reset(); } std::unique_ptr<LayerHistory> Scheduler::createLayerHistory( const scheduler::RefreshRateConfigs& configs, bool useContentDetectionV2) { if (!configs.canSwitch()) return nullptr; if (useContentDetectionV2) { return std::make_unique<scheduler::impl::LayerHistoryV2>(configs); } return std::make_unique<scheduler::impl::LayerHistory>(); } DispSync& Scheduler::getPrimaryDispSync() { return *mPrimaryDispSync; } Loading Loading @@ -499,16 +515,7 @@ void Scheduler::resetIdleTimer() { } void Scheduler::notifyTouchEvent() { if (!mTouchTimer) return; // Touch event will boost the refresh rate to performance. // Clear Layer History to get fresh FPS detection. // NOTE: Instead of checking all the layers, we should be checking the layer // that is currently on top. b/142507166 will give us this capability. std::lock_guard<std::mutex> lock(mFeatureStateLock); if (mLayerHistory) { // Layer History will be cleared based on RefreshRateConfigs::getBestRefreshRate if (mTouchTimer) { mTouchTimer->reset(); if (mSupportKernelTimer && mIdleTimer) { Loading Loading @@ -564,9 +571,15 @@ void Scheduler::idleTimerCallback(TimerState state) { void Scheduler::touchTimerCallback(TimerState state) { const TouchState touch = state == TimerState::Reset ? TouchState::Active : TouchState::Inactive; // Touch event will boost the refresh rate to performance. // Clear layer history to get fresh FPS detection. // NOTE: Instead of checking all the layers, we should be checking the layer // that is currently on top. b/142507166 will give us this capability. if (handleTimerStateChanged(&mFeatures.touch, touch)) { if (mLayerHistory) { mLayerHistory->clear(); } } ATRACE_INT("TouchState", static_cast<int>(touch)); } Loading @@ -577,14 +590,13 @@ void Scheduler::displayPowerTimerCallback(TimerState state) { void Scheduler::dump(std::string& result) const { using base::StringAppendF; const char* const states[] = {"off", "on"}; StringAppendF(&result, "+ Idle timer: %s\n", mIdleTimer ? mIdleTimer->dump().c_str() : states[0]); StringAppendF(&result, "+ Idle timer: %s\n", mIdleTimer ? mIdleTimer->dump().c_str() : "off"); StringAppendF(&result, "+ Touch timer: %s\n", mTouchTimer ? mTouchTimer->dump().c_str() : states[0]); StringAppendF(&result, "+ Use content detection: %s\n\n", sysprop::use_content_detection_for_refresh_rate(false) ? "on" : "off"); mTouchTimer ? mTouchTimer->dump().c_str() : "off"); StringAppendF(&result, "+ Content detection: %s %s\n\n", toContentDetectionString(mUseContentDetection, mUseContentDetectionV2), mLayerHistory ? mLayerHistory->dump().c_str() : "(no layer history)"); } template <class T> Loading