summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--services/surfaceflinger/Scheduler/RefreshRateConfigs.cpp10
-rw-r--r--services/surfaceflinger/Scheduler/RefreshRateConfigs.h4
-rw-r--r--services/surfaceflinger/Scheduler/Scheduler.cpp24
-rw-r--r--services/surfaceflinger/Scheduler/Scheduler.h7
-rw-r--r--services/surfaceflinger/SurfaceFlingerDefaultFactory.cpp5
-rw-r--r--services/surfaceflinger/tests/unittests/RefreshRateConfigsTest.cpp25
-rw-r--r--services/surfaceflinger/tests/unittests/TestableScheduler.h4
7 files changed, 70 insertions, 9 deletions
diff --git a/services/surfaceflinger/Scheduler/RefreshRateConfigs.cpp b/services/surfaceflinger/Scheduler/RefreshRateConfigs.cpp
index b876ccdc7e..1765d2d8f7 100644
--- a/services/surfaceflinger/Scheduler/RefreshRateConfigs.cpp
+++ b/services/surfaceflinger/Scheduler/RefreshRateConfigs.cpp
@@ -107,6 +107,12 @@ const RefreshRate& RefreshRateConfigs::getRefreshRateForContentV2(
return *mAvailableRefreshRates.back();
}
+ // If there are not layers, there is not content detection, so return the current
+ // refresh rate.
+ if (layers.empty()) {
+ return getCurrentRefreshRateByPolicyLocked();
+ }
+
int noVoteLayers = 0;
int minVoteLayers = 0;
int maxVoteLayers = 0;
@@ -272,6 +278,10 @@ const RefreshRate& RefreshRateConfigs::getCurrentRefreshRate() const {
const RefreshRate& RefreshRateConfigs::getCurrentRefreshRateByPolicy() const {
std::lock_guard lock(mLock);
+ return getCurrentRefreshRateByPolicyLocked();
+}
+
+const RefreshRate& RefreshRateConfigs::getCurrentRefreshRateByPolicyLocked() const {
if (std::find(mAvailableRefreshRates.begin(), mAvailableRefreshRates.end(),
mCurrentRefreshRate) != mAvailableRefreshRates.end()) {
return *mCurrentRefreshRate;
diff --git a/services/surfaceflinger/Scheduler/RefreshRateConfigs.h b/services/surfaceflinger/Scheduler/RefreshRateConfigs.h
index 0b5c73c9b7..c8aec86db3 100644
--- a/services/surfaceflinger/Scheduler/RefreshRateConfigs.h
+++ b/services/surfaceflinger/Scheduler/RefreshRateConfigs.h
@@ -199,6 +199,10 @@ private:
// display refresh period.
std::pair<nsecs_t, nsecs_t> getDisplayFrames(nsecs_t layerPeriod, nsecs_t displayPeriod) const;
+ // Returns the current refresh rate, if allowed. Otherwise the default that is allowed by
+ // the policy.
+ const RefreshRate& getCurrentRefreshRateByPolicyLocked() const REQUIRES(mLock);
+
// The list of refresh rates, indexed by display config ID. This must not change after this
// object is initialized.
AllRefreshRatesMapType mRefreshRates;
diff --git a/services/surfaceflinger/Scheduler/Scheduler.cpp b/services/surfaceflinger/Scheduler/Scheduler.cpp
index a0d63ba863..54442391ea 100644
--- a/services/surfaceflinger/Scheduler/Scheduler.cpp
+++ b/services/surfaceflinger/Scheduler/Scheduler.cpp
@@ -99,12 +99,14 @@ std::unique_ptr<DispSync> createDispSync() {
Scheduler::Scheduler(impl::EventControlThread::SetVSyncEnabledFunction function,
const scheduler::RefreshRateConfigs& refreshRateConfig,
- ISchedulerCallback& schedulerCallback, bool useContentDetectionV2)
+ ISchedulerCallback& schedulerCallback, bool useContentDetectionV2,
+ bool useContentDetection)
: mPrimaryDispSync(createDispSync()),
mEventControlThread(new impl::EventControlThread(std::move(function))),
mSupportKernelTimer(sysprop::support_kernel_idle_timer(false)),
mSchedulerCallback(schedulerCallback),
mRefreshRateConfigs(refreshRateConfig),
+ mUseContentDetection(useContentDetection),
mUseContentDetectionV2(useContentDetectionV2) {
using namespace sysprop;
@@ -147,12 +149,14 @@ 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, bool useContentDetectionV2,
+ bool useContentDetection)
: mPrimaryDispSync(std::move(primaryDispSync)),
mEventControlThread(std::move(eventControlThread)),
mSupportKernelTimer(false),
mSchedulerCallback(schedulerCallback),
mRefreshRateConfigs(configs),
+ mUseContentDetection(useContentDetection),
mUseContentDetectionV2(useContentDetectionV2) {}
Scheduler::~Scheduler() {
@@ -381,6 +385,17 @@ nsecs_t Scheduler::getDispSyncExpectedPresentTime() {
void Scheduler::registerLayer(Layer* layer) {
if (!mLayerHistory) return;
+ // If the content detection feature is off, all layers are registered at NoVote. We still
+ // keep the layer history, since we use it for other features (like Frame Rate API), so layers
+ // still need to be registered.
+ if (!mUseContentDetection) {
+ mLayerHistory->registerLayer(layer, mRefreshRateConfigs.getMinRefreshRate().fps,
+ mRefreshRateConfigs.getMaxRefreshRate().fps,
+ scheduler::LayerHistory::LayerVoteType::NoVote);
+ return;
+ }
+
+ // In V1 of content detection, all layers are registered as Heuristic (unless it's wallpaper).
if (!mUseContentDetectionV2) {
const auto lowFps = mRefreshRateConfigs.getMinRefreshRate().fps;
const auto highFps = layer->getWindowType() == InputWindowInfo::TYPE_WALLPAPER
@@ -391,6 +406,7 @@ void Scheduler::registerLayer(Layer* layer) {
scheduler::LayerHistory::LayerVoteType::Heuristic);
} else {
if (layer->getWindowType() == InputWindowInfo::TYPE_WALLPAPER) {
+ // Running Wallpaper at Min is considered as part of content detection.
mLayerHistory->registerLayer(layer, mRefreshRateConfigs.getMinRefreshRate().fps,
mRefreshRateConfigs.getMaxRefreshRate().fps,
scheduler::LayerHistory::LayerVoteType::Min);
@@ -539,8 +555,10 @@ void Scheduler::dump(std::string& result) const {
StringAppendF(&result, "+ Idle timer: %s\n",
mIdleTimer ? mIdleTimer->dump().c_str() : states[0]);
- StringAppendF(&result, "+ Touch timer: %s\n\n",
+ 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");
}
template <class T>
diff --git a/services/surfaceflinger/Scheduler/Scheduler.h b/services/surfaceflinger/Scheduler/Scheduler.h
index 6ffda7878a..04cc96a5d1 100644
--- a/services/surfaceflinger/Scheduler/Scheduler.h
+++ b/services/surfaceflinger/Scheduler/Scheduler.h
@@ -64,7 +64,7 @@ public:
Scheduler(impl::EventControlThread::SetVSyncEnabledFunction,
const scheduler::RefreshRateConfigs&, ISchedulerCallback& schedulerCallback,
- bool useContentDetectionV2);
+ bool useContentDetectionV2, bool useContentDetection);
virtual ~Scheduler();
@@ -160,7 +160,7 @@ private:
// Used by tests to inject mocks.
Scheduler(std::unique_ptr<DispSync>, std::unique_ptr<EventControlThread>,
const scheduler::RefreshRateConfigs&, ISchedulerCallback& schedulerCallback,
- bool useContentDetectionV2);
+ bool useContentDetectionV2, bool useContentDetection);
std::unique_ptr<VSyncSource> makePrimaryDispSyncSource(const char* name, nsecs_t phaseOffsetNs);
@@ -246,6 +246,9 @@ private:
GUARDED_BY(mVsyncTimelineLock);
static constexpr std::chrono::nanoseconds MAX_VSYNC_APPLIED_TIME = 200ms;
+ // This variable indicates whether to use the content detection feature at all.
+ const bool mUseContentDetection;
+ // This variable indicates whether to use V2 version of the content detection.
const bool mUseContentDetectionV2;
};
diff --git a/services/surfaceflinger/SurfaceFlingerDefaultFactory.cpp b/services/surfaceflinger/SurfaceFlingerDefaultFactory.cpp
index d49133d1fc..9a01d90664 100644
--- a/services/surfaceflinger/SurfaceFlingerDefaultFactory.cpp
+++ b/services/surfaceflinger/SurfaceFlingerDefaultFactory.cpp
@@ -33,6 +33,7 @@
#include "NativeWindowSurface.h"
#include "StartPropertySetThread.h"
#include "SurfaceFlingerDefaultFactory.h"
+#include "SurfaceFlingerProperties.h"
#include "SurfaceInterceptor.h"
#include "DisplayHardware/ComposerHal.h"
@@ -76,8 +77,8 @@ std::unique_ptr<Scheduler> DefaultFactory::createScheduler(
SetVSyncEnabled setVSyncEnabled, const scheduler::RefreshRateConfigs& configs,
ISchedulerCallback& schedulerCallback) {
return std::make_unique<Scheduler>(std::move(setVSyncEnabled), configs, schedulerCallback,
- property_get_bool("debug.sf.use_content_detection_v2",
- true));
+ property_get_bool("debug.sf.use_content_detection_v2", true),
+ sysprop::use_content_detection_for_refresh_rate(false));
}
std::unique_ptr<SurfaceInterceptor> DefaultFactory::createSurfaceInterceptor(
diff --git a/services/surfaceflinger/tests/unittests/RefreshRateConfigsTest.cpp b/services/surfaceflinger/tests/unittests/RefreshRateConfigsTest.cpp
index 7e625135ae..e7e7f66c95 100644
--- a/services/surfaceflinger/tests/unittests/RefreshRateConfigsTest.cpp
+++ b/services/surfaceflinger/tests/unittests/RefreshRateConfigsTest.cpp
@@ -247,6 +247,31 @@ TEST_F(RefreshRateConfigsTest, twoDeviceConfigs_getRefreshRateForContent) {
refreshRateConfigs->getRefreshRateForContent(makeLayerRequirements(24.0f)));
}
+TEST_F(RefreshRateConfigsTest, getRefreshRateForContentV2_noLayers) {
+ std::vector<RefreshRateConfigs::InputConfig> configs{
+ {{HWC_CONFIG_ID_60, HWC_GROUP_ID_0, VSYNC_60},
+ {HWC_CONFIG_ID_72, HWC_GROUP_ID_0, VSYNC_72},
+ {HWC_CONFIG_ID_90, HWC_GROUP_ID_0, VSYNC_90}}};
+ auto refreshRateConfigs = std::make_unique<RefreshRateConfigs>(configs, /*currentConfigId=*/
+ HWC_CONFIG_ID_72);
+
+ RefreshRate expected60Config = {HWC_CONFIG_ID_60, VSYNC_60, HWC_GROUP_ID_0, "60fps", 60};
+ RefreshRate expected72Config = {HWC_CONFIG_ID_72, VSYNC_72, HWC_GROUP_ID_0, "72fps", 72};
+
+ // If there are not layers, there is not content detection, so return the current
+ // refresh rate.
+ auto layers = std::vector<LayerRequirement>{};
+ EXPECT_EQ(expected72Config,
+ refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/
+ false));
+
+ // Current refresh rate can always be changed.
+ refreshRateConfigs->setCurrentConfigId(HWC_CONFIG_ID_60);
+ EXPECT_EQ(expected60Config,
+ refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/
+ false));
+}
+
TEST_F(RefreshRateConfigsTest, getRefreshRateForContentV2_60_90) {
std::vector<RefreshRateConfigs::InputConfig> configs{
{{HWC_CONFIG_ID_60, HWC_GROUP_ID_0, VSYNC_60},
diff --git a/services/surfaceflinger/tests/unittests/TestableScheduler.h b/services/surfaceflinger/tests/unittests/TestableScheduler.h
index b0b51bdd8a..41b5d49bf8 100644
--- a/services/surfaceflinger/tests/unittests/TestableScheduler.h
+++ b/services/surfaceflinger/tests/unittests/TestableScheduler.h
@@ -29,7 +29,7 @@ namespace android {
class TestableScheduler : public Scheduler, private ISchedulerCallback {
public:
TestableScheduler(const scheduler::RefreshRateConfigs& configs, bool useContentDetectionV2)
- : Scheduler([](bool) {}, configs, *this, useContentDetectionV2) {
+ : Scheduler([](bool) {}, configs, *this, useContentDetectionV2, true) {
if (mUseContentDetectionV2) {
mLayerHistory = std::make_unique<scheduler::impl::LayerHistoryV2>();
} else {
@@ -41,7 +41,7 @@ public:
std::unique_ptr<EventControlThread> eventControlThread,
const scheduler::RefreshRateConfigs& configs, bool useContentDetectionV2)
: Scheduler(std::move(primaryDispSync), std::move(eventControlThread), configs, *this,
- useContentDetectionV2) {
+ useContentDetectionV2, true) {
if (mUseContentDetectionV2) {
mLayerHistory = std::make_unique<scheduler::impl::LayerHistoryV2>();
} else {