Loading services/surfaceflinger/Scheduler/RefreshRateConfigs.cpp +4 −16 Original line number Diff line number Diff line Loading @@ -216,21 +216,13 @@ const AllRefreshRatesMapType& RefreshRateConfigs::getAllRefreshRates() const { const RefreshRate& RefreshRateConfigs::getMinRefreshRateByPolicy() const { std::lock_guard lock(mLock); if (!mRefreshRateSwitching) { return *mCurrentRefreshRate; } else { return *mAvailableRefreshRates.front(); } } const RefreshRate& RefreshRateConfigs::getMaxRefreshRateByPolicy() const { std::lock_guard lock(mLock); if (!mRefreshRateSwitching) { return *mCurrentRefreshRate; } else { return *mAvailableRefreshRates.back(); } } const RefreshRate& RefreshRateConfigs::getCurrentRefreshRate() const { std::lock_guard lock(mLock); Loading @@ -242,18 +234,14 @@ void RefreshRateConfigs::setCurrentConfigId(HwcConfigIndexType configId) { mCurrentRefreshRate = &mRefreshRates.at(configId); } RefreshRateConfigs::RefreshRateConfigs(bool refreshRateSwitching, const std::vector<InputConfig>& configs, HwcConfigIndexType currentHwcConfig) : mRefreshRateSwitching(refreshRateSwitching) { RefreshRateConfigs::RefreshRateConfigs(const std::vector<InputConfig>& configs, HwcConfigIndexType currentHwcConfig) { init(configs, currentHwcConfig); } RefreshRateConfigs::RefreshRateConfigs( bool refreshRateSwitching, const std::vector<std::shared_ptr<const HWC2::Display::Config>>& configs, HwcConfigIndexType currentConfigId) : mRefreshRateSwitching(refreshRateSwitching) { HwcConfigIndexType currentConfigId) { std::vector<InputConfig> inputConfigs; for (size_t configId = 0; configId < configs.size(); ++configId) { auto configGroup = HwcConfigGroupType(configs[configId]->getConfigGroup()); Loading services/surfaceflinger/Scheduler/RefreshRateConfigs.h +2 −8 Original line number Diff line number Diff line Loading @@ -94,9 +94,6 @@ public: // Returns true if config is allowed by the current policy. bool isConfigAllowed(HwcConfigIndexType config) const EXCLUDES(mLock); // Returns true if this device is doing refresh rate switching. This won't change at runtime. bool refreshRateSwitchingSupported() const { return mRefreshRateSwitching; } // Describes the different options the layer voted for refresh rate enum class LayerVoteType { NoVote, // Doesn't care about the refresh rate Loading Loading @@ -167,10 +164,9 @@ public: nsecs_t vsyncPeriod = 0; }; RefreshRateConfigs(bool refreshRateSwitching, const std::vector<InputConfig>& configs, RefreshRateConfigs(const std::vector<InputConfig>& configs, HwcConfigIndexType currentHwcConfig); RefreshRateConfigs(bool refreshRateSwitching, const std::vector<std::shared_ptr<const HWC2::Display::Config>>& configs, RefreshRateConfigs(const std::vector<std::shared_ptr<const HWC2::Display::Config>>& configs, HwcConfigIndexType currentConfigId); private: Loading Loading @@ -208,8 +204,6 @@ private: const RefreshRate* mMinSupportedRefreshRate; const RefreshRate* mMaxSupportedRefreshRate; const bool mRefreshRateSwitching; mutable std::mutex mLock; }; Loading services/surfaceflinger/Scheduler/Scheduler.cpp +31 −20 Original line number Diff line number Diff line Loading @@ -530,8 +530,6 @@ void Scheduler::dump(std::string& result) const { using base::StringAppendF; const char* const states[] = {"off", "on"}; const bool supported = mRefreshRateConfigs.refreshRateSwitchingSupported(); StringAppendF(&result, "+ Refresh rate switching: %s\n", states[supported]); StringAppendF(&result, "+ Content detection: %s\n", states[mLayerHistory != nullptr]); StringAppendF(&result, "+ Idle timer: %s\n", Loading Loading @@ -575,35 +573,44 @@ bool Scheduler::layerHistoryHasClientSpecifiedFrameRate() { } HwcConfigIndexType Scheduler::calculateRefreshRateType() { if (!mRefreshRateConfigs.refreshRateSwitchingSupported()) { return mRefreshRateConfigs.getCurrentRefreshRate().configId; // This block of the code checks whether any layers used the SetFrameRate API. If they have, // their request should be honored regardless of whether the device has refresh rate switching // turned off. if (layerHistoryHasClientSpecifiedFrameRate()) { if (!mUseContentDetectionV2) { return mRefreshRateConfigs.getRefreshRateForContent(mFeatures.contentRequirements) .configId; } else { return mRefreshRateConfigs.getRefreshRateForContentV2(mFeatures.contentRequirements) .configId; } } // If the layer history doesn't have the frame rate specified, use the old path. NOTE: // if we remove the kernel idle timer, and use our internal idle timer, this code will have to // be refactored. if (!layerHistoryHasClientSpecifiedFrameRate()) { // 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 (!mFeatures.isDisplayPowerStateNormal || mFeatures.displayPowerTimer == TimerState::Reset) { if (mDisplayPowerTimer && (!mFeatures.isDisplayPowerStateNormal || mFeatures.displayPowerTimer == TimerState::Reset)) { return mRefreshRateConfigs.getMaxRefreshRateByPolicy().configId; } // As long as touch is active we want to be in performance mode if (mFeatures.touch == TouchState::Active) { if (mTouchTimer && mFeatures.touch == TouchState::Active) { return mRefreshRateConfigs.getMaxRefreshRateByPolicy().configId; } // If timer has expired as it means there is no new content on the screen if (mFeatures.idleTimer == TimerState::Expired) { if (mIdleTimer && mFeatures.idleTimer == TimerState::Expired) { return mRefreshRateConfigs.getMinRefreshRateByPolicy().configId; } } if (!mUseContentDetectionV2) { // If content detection is off we choose performance as we don't know the content fps // If content detection is off we choose performance as we don't know the content fps. if (mFeatures.contentDetection == ContentDetectionState::Off) { // TODO(b/148428554): Be careful to not always call this. return mRefreshRateConfigs.getMaxRefreshRateByPolicy().configId; } Loading @@ -623,6 +630,10 @@ HwcConfigIndexType Scheduler::calculateRefreshRateType() { std::optional<HwcConfigIndexType> Scheduler::getPreferredConfigId() { std::lock_guard<std::mutex> lock(mFeatureStateLock); // Make sure that the default config ID is first updated, before returned. if (mFeatures.configId.has_value()) { mFeatures.configId = calculateRefreshRateType(); } return mFeatures.configId; } Loading services/surfaceflinger/SurfaceFlinger.cpp +13 −27 Original line number Diff line number Diff line Loading @@ -556,12 +556,6 @@ void SurfaceFlinger::bootFinished() readPersistentProperties(); mBootStage = BootStage::FINISHED; if (mRefreshRateConfigs->refreshRateSwitchingSupported()) { // set the refresh rate according to the policy const auto& performanceRefreshRate = mRefreshRateConfigs->getMaxRefreshRateByPolicy(); changeRefreshRateLocked(performanceRefreshRate, Scheduler::ConfigEvent::None); } if (property_get_bool("sf.debug.show_refresh_rate_overlay", false)) { mRefreshRateOverlay = std::make_unique<RefreshRateOverlay>(*this); mRefreshRateOverlay->changeRefreshRate(mRefreshRateConfigs->getCurrentRefreshRate()); Loading Loading @@ -2718,8 +2712,7 @@ void SurfaceFlinger::initScheduler(DisplayId primaryDisplayId) { auto currentConfig = HwcConfigIndexType(getHwComposer().getActiveConfigIndex(primaryDisplayId)); mRefreshRateConfigs = std::make_unique<scheduler::RefreshRateConfigs>(refresh_rate_switching(false), getHwComposer().getConfigs( std::make_unique<scheduler::RefreshRateConfigs>(getHwComposer().getConfigs( primaryDisplayId), currentConfig); mRefreshRateStats = Loading Loading @@ -5709,26 +5702,19 @@ status_t SurfaceFlinger::setDesiredDisplayConfigSpecsInternal(const sp<DisplayDe mScheduler->onConfigChanged(mAppConnectionHandle, display->getId()->value, display->getActiveConfig(), vsyncPeriod); if (mRefreshRateConfigs->refreshRateSwitchingSupported()) { auto configId = mScheduler->getPreferredConfigId(); auto preferredRefreshRate = configId ? mRefreshRateConfigs->getRefreshRateFromConfigId(*configId) : mRefreshRateConfigs->getMinRefreshRateByPolicy(); // NOTE: Choose the default config ID, if Scheduler doesn't have one in mind. : mRefreshRateConfigs->getRefreshRateFromConfigId(defaultConfig); ALOGV("trying to switch to Scheduler preferred config %d (%s)", preferredRefreshRate.configId.value(), preferredRefreshRate.name.c_str()); if (isDisplayConfigAllowed(preferredRefreshRate.configId)) { ALOGV("switching to Scheduler preferred config %d", preferredRefreshRate.configId.value()); setDesiredActiveConfig( {preferredRefreshRate.configId, Scheduler::ConfigEvent::Changed}); } else { // Set the highest allowed config setDesiredActiveConfig({mRefreshRateConfigs->getMaxRefreshRateByPolicy().configId, Scheduler::ConfigEvent::Changed}); } ALOGV("switching to Scheduler preferred config %d", preferredRefreshRate.configId.value()); setDesiredActiveConfig({preferredRefreshRate.configId, Scheduler::ConfigEvent::Changed}); } else { ALOGV("switching to config %d", defaultConfig.value()); setDesiredActiveConfig({defaultConfig, Scheduler::ConfigEvent::Changed}); LOG_ALWAYS_FATAL("Desired config not allowed: %d", preferredRefreshRate.configId.value()); } return NO_ERROR; Loading services/surfaceflinger/SurfaceFlingerProperties.cpp +5 −0 Original line number Diff line number Diff line Loading @@ -19,6 +19,7 @@ #include <android/hardware/configstore/1.1/types.h> #include <configstore/Utils.h> #include <log/log.h> #include <cstdlib> #include <tuple> Loading Loading @@ -227,8 +228,12 @@ int64_t color_space_agnostic_dataspace(Dataspace defaultValue) { } bool refresh_rate_switching(bool defaultValue) { #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wdeprecated-declarations" auto temp = SurfaceFlingerProperties::refresh_rate_switching(); #pragma clang diagnostic pop if (temp.has_value()) { ALOGW("Using deprecated refresh_rate_switching sysprop. Value: %d", *temp); return *temp; } return defaultValue; Loading Loading
services/surfaceflinger/Scheduler/RefreshRateConfigs.cpp +4 −16 Original line number Diff line number Diff line Loading @@ -216,21 +216,13 @@ const AllRefreshRatesMapType& RefreshRateConfigs::getAllRefreshRates() const { const RefreshRate& RefreshRateConfigs::getMinRefreshRateByPolicy() const { std::lock_guard lock(mLock); if (!mRefreshRateSwitching) { return *mCurrentRefreshRate; } else { return *mAvailableRefreshRates.front(); } } const RefreshRate& RefreshRateConfigs::getMaxRefreshRateByPolicy() const { std::lock_guard lock(mLock); if (!mRefreshRateSwitching) { return *mCurrentRefreshRate; } else { return *mAvailableRefreshRates.back(); } } const RefreshRate& RefreshRateConfigs::getCurrentRefreshRate() const { std::lock_guard lock(mLock); Loading @@ -242,18 +234,14 @@ void RefreshRateConfigs::setCurrentConfigId(HwcConfigIndexType configId) { mCurrentRefreshRate = &mRefreshRates.at(configId); } RefreshRateConfigs::RefreshRateConfigs(bool refreshRateSwitching, const std::vector<InputConfig>& configs, HwcConfigIndexType currentHwcConfig) : mRefreshRateSwitching(refreshRateSwitching) { RefreshRateConfigs::RefreshRateConfigs(const std::vector<InputConfig>& configs, HwcConfigIndexType currentHwcConfig) { init(configs, currentHwcConfig); } RefreshRateConfigs::RefreshRateConfigs( bool refreshRateSwitching, const std::vector<std::shared_ptr<const HWC2::Display::Config>>& configs, HwcConfigIndexType currentConfigId) : mRefreshRateSwitching(refreshRateSwitching) { HwcConfigIndexType currentConfigId) { std::vector<InputConfig> inputConfigs; for (size_t configId = 0; configId < configs.size(); ++configId) { auto configGroup = HwcConfigGroupType(configs[configId]->getConfigGroup()); Loading
services/surfaceflinger/Scheduler/RefreshRateConfigs.h +2 −8 Original line number Diff line number Diff line Loading @@ -94,9 +94,6 @@ public: // Returns true if config is allowed by the current policy. bool isConfigAllowed(HwcConfigIndexType config) const EXCLUDES(mLock); // Returns true if this device is doing refresh rate switching. This won't change at runtime. bool refreshRateSwitchingSupported() const { return mRefreshRateSwitching; } // Describes the different options the layer voted for refresh rate enum class LayerVoteType { NoVote, // Doesn't care about the refresh rate Loading Loading @@ -167,10 +164,9 @@ public: nsecs_t vsyncPeriod = 0; }; RefreshRateConfigs(bool refreshRateSwitching, const std::vector<InputConfig>& configs, RefreshRateConfigs(const std::vector<InputConfig>& configs, HwcConfigIndexType currentHwcConfig); RefreshRateConfigs(bool refreshRateSwitching, const std::vector<std::shared_ptr<const HWC2::Display::Config>>& configs, RefreshRateConfigs(const std::vector<std::shared_ptr<const HWC2::Display::Config>>& configs, HwcConfigIndexType currentConfigId); private: Loading Loading @@ -208,8 +204,6 @@ private: const RefreshRate* mMinSupportedRefreshRate; const RefreshRate* mMaxSupportedRefreshRate; const bool mRefreshRateSwitching; mutable std::mutex mLock; }; Loading
services/surfaceflinger/Scheduler/Scheduler.cpp +31 −20 Original line number Diff line number Diff line Loading @@ -530,8 +530,6 @@ void Scheduler::dump(std::string& result) const { using base::StringAppendF; const char* const states[] = {"off", "on"}; const bool supported = mRefreshRateConfigs.refreshRateSwitchingSupported(); StringAppendF(&result, "+ Refresh rate switching: %s\n", states[supported]); StringAppendF(&result, "+ Content detection: %s\n", states[mLayerHistory != nullptr]); StringAppendF(&result, "+ Idle timer: %s\n", Loading Loading @@ -575,35 +573,44 @@ bool Scheduler::layerHistoryHasClientSpecifiedFrameRate() { } HwcConfigIndexType Scheduler::calculateRefreshRateType() { if (!mRefreshRateConfigs.refreshRateSwitchingSupported()) { return mRefreshRateConfigs.getCurrentRefreshRate().configId; // This block of the code checks whether any layers used the SetFrameRate API. If they have, // their request should be honored regardless of whether the device has refresh rate switching // turned off. if (layerHistoryHasClientSpecifiedFrameRate()) { if (!mUseContentDetectionV2) { return mRefreshRateConfigs.getRefreshRateForContent(mFeatures.contentRequirements) .configId; } else { return mRefreshRateConfigs.getRefreshRateForContentV2(mFeatures.contentRequirements) .configId; } } // If the layer history doesn't have the frame rate specified, use the old path. NOTE: // if we remove the kernel idle timer, and use our internal idle timer, this code will have to // be refactored. if (!layerHistoryHasClientSpecifiedFrameRate()) { // 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 (!mFeatures.isDisplayPowerStateNormal || mFeatures.displayPowerTimer == TimerState::Reset) { if (mDisplayPowerTimer && (!mFeatures.isDisplayPowerStateNormal || mFeatures.displayPowerTimer == TimerState::Reset)) { return mRefreshRateConfigs.getMaxRefreshRateByPolicy().configId; } // As long as touch is active we want to be in performance mode if (mFeatures.touch == TouchState::Active) { if (mTouchTimer && mFeatures.touch == TouchState::Active) { return mRefreshRateConfigs.getMaxRefreshRateByPolicy().configId; } // If timer has expired as it means there is no new content on the screen if (mFeatures.idleTimer == TimerState::Expired) { if (mIdleTimer && mFeatures.idleTimer == TimerState::Expired) { return mRefreshRateConfigs.getMinRefreshRateByPolicy().configId; } } if (!mUseContentDetectionV2) { // If content detection is off we choose performance as we don't know the content fps // If content detection is off we choose performance as we don't know the content fps. if (mFeatures.contentDetection == ContentDetectionState::Off) { // TODO(b/148428554): Be careful to not always call this. return mRefreshRateConfigs.getMaxRefreshRateByPolicy().configId; } Loading @@ -623,6 +630,10 @@ HwcConfigIndexType Scheduler::calculateRefreshRateType() { std::optional<HwcConfigIndexType> Scheduler::getPreferredConfigId() { std::lock_guard<std::mutex> lock(mFeatureStateLock); // Make sure that the default config ID is first updated, before returned. if (mFeatures.configId.has_value()) { mFeatures.configId = calculateRefreshRateType(); } return mFeatures.configId; } Loading
services/surfaceflinger/SurfaceFlinger.cpp +13 −27 Original line number Diff line number Diff line Loading @@ -556,12 +556,6 @@ void SurfaceFlinger::bootFinished() readPersistentProperties(); mBootStage = BootStage::FINISHED; if (mRefreshRateConfigs->refreshRateSwitchingSupported()) { // set the refresh rate according to the policy const auto& performanceRefreshRate = mRefreshRateConfigs->getMaxRefreshRateByPolicy(); changeRefreshRateLocked(performanceRefreshRate, Scheduler::ConfigEvent::None); } if (property_get_bool("sf.debug.show_refresh_rate_overlay", false)) { mRefreshRateOverlay = std::make_unique<RefreshRateOverlay>(*this); mRefreshRateOverlay->changeRefreshRate(mRefreshRateConfigs->getCurrentRefreshRate()); Loading Loading @@ -2718,8 +2712,7 @@ void SurfaceFlinger::initScheduler(DisplayId primaryDisplayId) { auto currentConfig = HwcConfigIndexType(getHwComposer().getActiveConfigIndex(primaryDisplayId)); mRefreshRateConfigs = std::make_unique<scheduler::RefreshRateConfigs>(refresh_rate_switching(false), getHwComposer().getConfigs( std::make_unique<scheduler::RefreshRateConfigs>(getHwComposer().getConfigs( primaryDisplayId), currentConfig); mRefreshRateStats = Loading Loading @@ -5709,26 +5702,19 @@ status_t SurfaceFlinger::setDesiredDisplayConfigSpecsInternal(const sp<DisplayDe mScheduler->onConfigChanged(mAppConnectionHandle, display->getId()->value, display->getActiveConfig(), vsyncPeriod); if (mRefreshRateConfigs->refreshRateSwitchingSupported()) { auto configId = mScheduler->getPreferredConfigId(); auto preferredRefreshRate = configId ? mRefreshRateConfigs->getRefreshRateFromConfigId(*configId) : mRefreshRateConfigs->getMinRefreshRateByPolicy(); // NOTE: Choose the default config ID, if Scheduler doesn't have one in mind. : mRefreshRateConfigs->getRefreshRateFromConfigId(defaultConfig); ALOGV("trying to switch to Scheduler preferred config %d (%s)", preferredRefreshRate.configId.value(), preferredRefreshRate.name.c_str()); if (isDisplayConfigAllowed(preferredRefreshRate.configId)) { ALOGV("switching to Scheduler preferred config %d", preferredRefreshRate.configId.value()); setDesiredActiveConfig( {preferredRefreshRate.configId, Scheduler::ConfigEvent::Changed}); } else { // Set the highest allowed config setDesiredActiveConfig({mRefreshRateConfigs->getMaxRefreshRateByPolicy().configId, Scheduler::ConfigEvent::Changed}); } ALOGV("switching to Scheduler preferred config %d", preferredRefreshRate.configId.value()); setDesiredActiveConfig({preferredRefreshRate.configId, Scheduler::ConfigEvent::Changed}); } else { ALOGV("switching to config %d", defaultConfig.value()); setDesiredActiveConfig({defaultConfig, Scheduler::ConfigEvent::Changed}); LOG_ALWAYS_FATAL("Desired config not allowed: %d", preferredRefreshRate.configId.value()); } return NO_ERROR; Loading
services/surfaceflinger/SurfaceFlingerProperties.cpp +5 −0 Original line number Diff line number Diff line Loading @@ -19,6 +19,7 @@ #include <android/hardware/configstore/1.1/types.h> #include <configstore/Utils.h> #include <log/log.h> #include <cstdlib> #include <tuple> Loading Loading @@ -227,8 +228,12 @@ int64_t color_space_agnostic_dataspace(Dataspace defaultValue) { } bool refresh_rate_switching(bool defaultValue) { #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wdeprecated-declarations" auto temp = SurfaceFlingerProperties::refresh_rate_switching(); #pragma clang diagnostic pop if (temp.has_value()) { ALOGW("Using deprecated refresh_rate_switching sysprop. Value: %d", *temp); return *temp; } return defaultValue; Loading