diff options
11 files changed, 61 insertions, 46 deletions
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp index effbed67b8..6ff23c5f51 100644 --- a/services/surfaceflinger/Layer.cpp +++ b/services/surfaceflinger/Layer.cpp @@ -80,7 +80,6 @@ Layer::Layer(const LayerCreationArgs& args) mName(args.name), mClientRef(args.client), mWindowType(args.metadata.getInt32(METADATA_WINDOW_TYPE, 0)) { - uint32_t layerFlags = 0; if (args.flags & ISurfaceComposerClient::eHidden) layerFlags |= layer_state_t::eLayerHidden; if (args.flags & ISurfaceComposerClient::eOpaque) layerFlags |= layer_state_t::eLayerOpaque; @@ -1264,6 +1263,9 @@ bool Layer::setShadowRadius(float shadowRadius) { } bool Layer::setFrameRate(FrameRate frameRate) { + if (!mFlinger->useFrameRateApi) { + return false; + } if (mCurrentState.frameRate == frameRate) { return false; } diff --git a/services/surfaceflinger/Scheduler/LayerHistory.cpp b/services/surfaceflinger/Scheduler/LayerHistory.cpp index 9aada11473..b313777253 100644 --- a/services/surfaceflinger/Scheduler/LayerHistory.cpp +++ b/services/surfaceflinger/Scheduler/LayerHistory.cpp @@ -66,7 +66,6 @@ void trace(const wp<Layer>& weak, int fps) { ATRACE_INT(tag.c_str(), fps); ALOGD("%s: %s @ %d Hz", __FUNCTION__, name.c_str(), fps); } - } // namespace LayerHistory::LayerHistory() @@ -102,23 +101,6 @@ LayerHistory::Summary LayerHistory::summarize(nsecs_t now) { partitionLayers(now); - // Find the maximum refresh rate among recently active layers. - for (const auto& [activeLayer, info] : activeLayers()) { - const bool recent = info->isRecentlyActive(now); - - if (recent || CC_UNLIKELY(mTraceEnabled)) { - const float refreshRate = info->getRefreshRate(now); - if (recent && refreshRate > 0.0f) { - if (const auto layer = activeLayer.promote(); layer) { - const int32_t priority = layer->getFrameRateSelectionPriority(); - // TODO(b/142507166): This is where the scoring algorithm should live. - // Layers should be organized by priority - ALOGD("Layer has priority: %d", priority); - } - } - } - } - LayerHistory::Summary summary; for (const auto& [weakLayer, info] : activeLayers()) { const bool recent = info->isRecentlyActive(now); @@ -196,6 +178,5 @@ void LayerHistory::clear() { mActiveLayersEnd = 0; } - } // namespace android::scheduler::impl diff --git a/services/surfaceflinger/Scheduler/LayerHistoryV2.cpp b/services/surfaceflinger/Scheduler/LayerHistoryV2.cpp index ce085f4a1d..6ef6ce414b 100644 --- a/services/surfaceflinger/Scheduler/LayerHistoryV2.cpp +++ b/services/surfaceflinger/Scheduler/LayerHistoryV2.cpp @@ -79,7 +79,6 @@ void trace(const wp<Layer>& weak, LayerHistory::LayerVoteType type, int fps) { ALOGD("%s: %s @ %d Hz", __FUNCTION__, name.c_str(), fps); } - } // namespace LayerHistoryV2::LayerHistoryV2() @@ -124,6 +123,10 @@ LayerHistoryV2::Summary LayerHistoryV2::summarize(nsecs_t now) { continue; } + // TODO(b/144307188): This needs to be plugged into layer summary as + // an additional parameter. + ALOGV("Layer has priority: %d", strong->getFrameRateSelectionPriority()); + const bool recent = info->isRecentlyActive(now); if (recent) { const auto [type, refreshRate] = info->getRefreshRate(now); @@ -212,5 +215,4 @@ void LayerHistoryV2::clear() { mActiveLayersEnd = 0; } - } // namespace android::scheduler::impl diff --git a/services/surfaceflinger/Scheduler/Scheduler.cpp b/services/surfaceflinger/Scheduler/Scheduler.cpp index 94791ebf28..2b70d65588 100644 --- a/services/surfaceflinger/Scheduler/Scheduler.cpp +++ b/services/surfaceflinger/Scheduler/Scheduler.cpp @@ -108,13 +108,10 @@ Scheduler::Scheduler(impl::EventControlThread::SetVSyncEnabledFunction function, mUseContentDetectionV2(useContentDetectionV2) { using namespace sysprop; - if (property_get_bool("debug.sf.use_content_detection_for_refresh_rate", 0) || - use_content_detection_for_refresh_rate(false)) { - if (mUseContentDetectionV2) { - mLayerHistory = std::make_unique<scheduler::impl::LayerHistoryV2>(); - } else { - mLayerHistory = std::make_unique<scheduler::impl::LayerHistory>(); - } + if (mUseContentDetectionV2) { + mLayerHistory = std::make_unique<scheduler::impl::LayerHistoryV2>(); + } else { + mLayerHistory = std::make_unique<scheduler::impl::LayerHistory>(); } const int setIdleTimerMs = property_get_int32("debug.sf.set_idle_timer_ms", 0); @@ -438,7 +435,7 @@ void Scheduler::chooseRefreshRateForContent() { mFeatures.contentDetection = !summary.empty() ? ContentDetectionState::On : ContentDetectionState::Off; - newConfigId = calculateRefreshRateType(); + newConfigId = calculateRefreshRateConfigIndexType(); if (mFeatures.configId == newConfigId) { return; } @@ -531,8 +528,6 @@ void Scheduler::dump(std::string& result) const { using base::StringAppendF; const char* const states[] = {"off", "on"}; - StringAppendF(&result, "+ Content detection: %s\n", states[mLayerHistory != nullptr]); - StringAppendF(&result, "+ Idle timer: %s\n", mIdleTimer ? mIdleTimer->dump().c_str() : states[0]); StringAppendF(&result, "+ Touch timer: %s\n\n", @@ -549,7 +544,7 @@ void Scheduler::handleTimerStateChanged(T* currentState, T newState, bool eventO return; } *currentState = newState; - newConfigId = calculateRefreshRateType(); + newConfigId = calculateRefreshRateConfigIndexType(); if (mFeatures.configId == newConfigId) { return; } @@ -563,6 +558,7 @@ void Scheduler::handleTimerStateChanged(T* currentState, T newState, bool eventO } bool Scheduler::layerHistoryHasClientSpecifiedFrameRate() { + // Traverse all the layers to see if any of them requested frame rate. for (const auto& layer : mFeatures.contentRequirements) { if (layer.vote == scheduler::RefreshRateConfigs::LayerVoteType::ExplicitDefault || layer.vote == scheduler::RefreshRateConfigs::LayerVoteType::ExplicitExactOrMultiple) { @@ -573,10 +569,9 @@ bool Scheduler::layerHistoryHasClientSpecifiedFrameRate() { return false; } -HwcConfigIndexType Scheduler::calculateRefreshRateType() { +HwcConfigIndexType Scheduler::calculateRefreshRateConfigIndexType() { // 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. + // their request should be honored depending on other active layers. if (layerHistoryHasClientSpecifiedFrameRate()) { if (!mUseContentDetectionV2) { return mRefreshRateConfigs.getRefreshRateForContent(mFeatures.contentRequirements) @@ -587,23 +582,23 @@ HwcConfigIndexType Scheduler::calculateRefreshRateType() { } } - // 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 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 the layer history doesn't have the frame rate specified, check for other features and + // honor them. NOTE: If we remove the kernel idle timer, and use our internal idle timer, this + // code will have to be refactored. 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 (mDisplayPowerTimer && (!mFeatures.isDisplayPowerStateNormal || mFeatures.displayPowerTimer == TimerState::Reset)) { return mRefreshRateConfigs.getMaxRefreshRateByPolicy().configId; } - // As long as touch is active we want to be in performance mode + // As long as touch is active we want to be in performance mode. 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 timer has expired as it means there is no new content on the screen. if (mIdleTimer && mFeatures.idleTimer == TimerState::Expired) { return mRefreshRateConfigs.getMinRefreshRateByPolicy().configId; } @@ -611,7 +606,7 @@ HwcConfigIndexType Scheduler::calculateRefreshRateType() { if (!mUseContentDetectionV2) { // 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. + // NOTE: V1 always calls this, but this is not a default behavior for V2. return mRefreshRateConfigs.getMaxRefreshRateByPolicy().configId; } @@ -633,7 +628,7 @@ 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(); + mFeatures.configId = calculateRefreshRateConfigIndexType(); } return mFeatures.configId; } diff --git a/services/surfaceflinger/Scheduler/Scheduler.h b/services/surfaceflinger/Scheduler/Scheduler.h index 01062f85b9..c2345ccc14 100644 --- a/services/surfaceflinger/Scheduler/Scheduler.h +++ b/services/surfaceflinger/Scheduler/Scheduler.h @@ -177,7 +177,10 @@ private: void setVsyncPeriod(nsecs_t period); - HwcConfigIndexType calculateRefreshRateType() REQUIRES(mFeatureStateLock); + // This function checks whether individual features that are affecting the refresh rate + // selection were initialized, prioritizes them, and calculates the HwcConfigIndexType + // for the suggested refresh rate. + HwcConfigIndexType calculateRefreshRateConfigIndexType() REQUIRES(mFeatureStateLock); bool layerHistoryHasClientSpecifiedFrameRate() REQUIRES(mFeatureStateLock); diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index e8c7a55bc6..1a4d316c5d 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -228,6 +228,7 @@ Dataspace SurfaceFlinger::defaultCompositionDataspace = Dataspace::V0_SRGB; ui::PixelFormat SurfaceFlinger::defaultCompositionPixelFormat = ui::PixelFormat::RGBA_8888; Dataspace SurfaceFlinger::wideColorGamutCompositionDataspace = Dataspace::V0_SRGB; ui::PixelFormat SurfaceFlinger::wideColorGamutCompositionPixelFormat = ui::PixelFormat::RGBA_8888; +bool SurfaceFlinger::useFrameRateApi; std::string getHwcServiceName() { char value[PROPERTY_VALUE_MAX] = {}; @@ -387,6 +388,8 @@ SurfaceFlinger::SurfaceFlinger(Factory& factory) : SurfaceFlinger(factory, SkipI // for production purposes later on. setenv("TREBLE_TESTING_OVERRIDE", "true", true); } + + useFrameRateApi = use_frame_rate_api(true); } void SurfaceFlinger::onFirstRef() diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h index ccf57946ab..8cabcf0ef6 100644 --- a/services/surfaceflinger/SurfaceFlinger.h +++ b/services/surfaceflinger/SurfaceFlinger.h @@ -248,6 +248,11 @@ public: static ui::Dataspace wideColorGamutCompositionDataspace; static ui::PixelFormat wideColorGamutCompositionPixelFormat; + // Whether to use frame rate API when deciding about the refresh rate of the display. This + // variable is caches in SF, so that we can check it with each layer creation, and a void the + // overhead that is caused by reading from sysprop. + static bool useFrameRateApi; + static char const* getServiceName() ANDROID_API { return "SurfaceFlinger"; } diff --git a/services/surfaceflinger/SurfaceFlingerProperties.cpp b/services/surfaceflinger/SurfaceFlingerProperties.cpp index 269cf94b4d..1a611f5d7e 100644 --- a/services/surfaceflinger/SurfaceFlingerProperties.cpp +++ b/services/surfaceflinger/SurfaceFlingerProperties.cpp @@ -297,6 +297,14 @@ bool support_kernel_idle_timer(bool defaultValue) { return defaultValue; } +bool use_frame_rate_api(bool defaultValue) { + auto temp = SurfaceFlingerProperties::use_frame_rate_api(); + if (temp.has_value()) { + return *temp; + } + return defaultValue; +} + #define DISPLAY_PRIMARY_SIZE 3 constexpr float kSrgbRedX = 0.4123f; diff --git a/services/surfaceflinger/SurfaceFlingerProperties.h b/services/surfaceflinger/SurfaceFlingerProperties.h index 440df49d94..4c6e191e70 100644 --- a/services/surfaceflinger/SurfaceFlingerProperties.h +++ b/services/surfaceflinger/SurfaceFlingerProperties.h @@ -87,6 +87,8 @@ bool enable_protected_contents(bool defaultValue); bool support_kernel_idle_timer(bool defaultValue); +bool use_frame_rate_api(bool defaultValue); + android::ui::DisplayPrimaries getDisplayNativePrimaries(); } // namespace sysprop } // namespace android diff --git a/services/surfaceflinger/sysprop/SurfaceFlingerProperties.sysprop b/services/surfaceflinger/sysprop/SurfaceFlingerProperties.sysprop index 71f8d6a7d9..b19eae62e5 100644 --- a/services/surfaceflinger/sysprop/SurfaceFlingerProperties.sysprop +++ b/services/surfaceflinger/sysprop/SurfaceFlingerProperties.sysprop @@ -393,3 +393,13 @@ prop { access: Readonly prop_name: "ro.surface_flinger.supports_background_blur" } + +# Indicates whether Scheduler should use frame rate API when adjusting the +# display refresh rate. +prop { + api_name: "use_frame_rate_api" + type: Boolean + scope: Public + access: Readonly + prop_name: "ro.surface_flinger.use_frame_rate_api" +} diff --git a/services/surfaceflinger/sysprop/api/SurfaceFlingerProperties-current.txt b/services/surfaceflinger/sysprop/api/SurfaceFlingerProperties-current.txt index cdfd0f53aa..c66523a517 100644 --- a/services/surfaceflinger/sysprop/api/SurfaceFlingerProperties-current.txt +++ b/services/surfaceflinger/sysprop/api/SurfaceFlingerProperties-current.txt @@ -121,6 +121,10 @@ props { prop_name: "ro.surface_flinger.use_context_priority" } prop { + api_name: "use_frame_rate_api" + prop_name: "ro.surface_flinger.use_frame_rate_api" + } + prop { api_name: "use_smart_90_for_video" prop_name: "ro.surface_flinger.use_smart_90_for_video" deprecated: true |