summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--services/surfaceflinger/Layer.cpp4
-rw-r--r--services/surfaceflinger/Scheduler/LayerHistory.cpp19
-rw-r--r--services/surfaceflinger/Scheduler/LayerHistoryV2.cpp6
-rw-r--r--services/surfaceflinger/Scheduler/Scheduler.cpp41
-rw-r--r--services/surfaceflinger/Scheduler/Scheduler.h5
-rw-r--r--services/surfaceflinger/SurfaceFlinger.cpp3
-rw-r--r--services/surfaceflinger/SurfaceFlinger.h5
-rw-r--r--services/surfaceflinger/SurfaceFlingerProperties.cpp8
-rw-r--r--services/surfaceflinger/SurfaceFlingerProperties.h2
-rw-r--r--services/surfaceflinger/sysprop/SurfaceFlingerProperties.sysprop10
-rw-r--r--services/surfaceflinger/sysprop/api/SurfaceFlingerProperties-current.txt4
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