summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--services/surfaceflinger/Scheduler/Scheduler.cpp12
-rw-r--r--services/surfaceflinger/Scheduler/Scheduler.h6
-rw-r--r--services/surfaceflinger/Scheduler/VSyncReactor.cpp14
-rw-r--r--services/surfaceflinger/Scheduler/VSyncReactor.h4
-rw-r--r--services/surfaceflinger/tests/unittests/VSyncReactorTest.cpp25
5 files changed, 47 insertions, 14 deletions
diff --git a/services/surfaceflinger/Scheduler/Scheduler.cpp b/services/surfaceflinger/Scheduler/Scheduler.cpp
index d874c53c06..e250bbf064 100644
--- a/services/surfaceflinger/Scheduler/Scheduler.cpp
+++ b/services/surfaceflinger/Scheduler/Scheduler.cpp
@@ -62,7 +62,7 @@
namespace android {
-std::unique_ptr<DispSync> createDispSync() {
+std::unique_ptr<DispSync> createDispSync(bool supportKernelTimer) {
// TODO (140302863) remove this and use the vsync_reactor system.
if (property_get_bool("debug.sf.vsync_reactor", true)) {
// TODO (144707443) tune Predictor tunables.
@@ -90,7 +90,7 @@ std::unique_ptr<DispSync> createDispSync() {
static constexpr size_t pendingFenceLimit = 20;
return std::make_unique<scheduler::VSyncReactor>(std::make_unique<scheduler::SystemClock>(),
std::move(dispatch), std::move(tracker),
- pendingFenceLimit);
+ pendingFenceLimit, supportKernelTimer);
} else {
return std::make_unique<impl::DispSync>("SchedulerDispSync",
sysprop::running_without_sync_framework(true));
@@ -101,9 +101,9 @@ Scheduler::Scheduler(impl::EventControlThread::SetVSyncEnabledFunction function,
const scheduler::RefreshRateConfigs& refreshRateConfig,
ISchedulerCallback& schedulerCallback, bool useContentDetectionV2,
bool useContentDetection)
- : mPrimaryDispSync(createDispSync()),
+ : mSupportKernelTimer(sysprop::support_kernel_idle_timer(false)),
+ mPrimaryDispSync(createDispSync(mSupportKernelTimer)),
mEventControlThread(new impl::EventControlThread(std::move(function))),
- mSupportKernelTimer(sysprop::support_kernel_idle_timer(false)),
mSchedulerCallback(schedulerCallback),
mRefreshRateConfigs(refreshRateConfig),
mUseContentDetection(useContentDetection),
@@ -151,9 +151,9 @@ Scheduler::Scheduler(std::unique_ptr<DispSync> primaryDispSync,
const scheduler::RefreshRateConfigs& configs,
ISchedulerCallback& schedulerCallback, bool useContentDetectionV2,
bool useContentDetection)
- : mPrimaryDispSync(std::move(primaryDispSync)),
+ : mSupportKernelTimer(false),
+ mPrimaryDispSync(std::move(primaryDispSync)),
mEventControlThread(std::move(eventControlThread)),
- mSupportKernelTimer(false),
mSchedulerCallback(schedulerCallback),
mRefreshRateConfigs(configs),
mUseContentDetection(useContentDetection),
diff --git a/services/surfaceflinger/Scheduler/Scheduler.h b/services/surfaceflinger/Scheduler/Scheduler.h
index c519826c6a..ebee9e3a8f 100644
--- a/services/surfaceflinger/Scheduler/Scheduler.h
+++ b/services/surfaceflinger/Scheduler/Scheduler.h
@@ -208,15 +208,15 @@ private:
std::atomic<nsecs_t> mLastResyncTime = 0;
+ // Whether to use idle timer callbacks that support the kernel timer.
+ const bool mSupportKernelTimer;
+
std::unique_ptr<DispSync> mPrimaryDispSync;
std::unique_ptr<EventControlThread> mEventControlThread;
// Used to choose refresh rate if content detection is enabled.
std::unique_ptr<LayerHistory> mLayerHistory;
- // Whether to use idle timer callbacks that support the kernel timer.
- const bool mSupportKernelTimer;
-
// Timer that records time between requests for next vsync.
std::optional<scheduler::OneShotTimer> mIdleTimer;
// Timer used to monitor touch events.
diff --git a/services/surfaceflinger/Scheduler/VSyncReactor.cpp b/services/surfaceflinger/Scheduler/VSyncReactor.cpp
index 5f0c9ce40c..16d102cac1 100644
--- a/services/surfaceflinger/Scheduler/VSyncReactor.cpp
+++ b/services/surfaceflinger/Scheduler/VSyncReactor.cpp
@@ -56,14 +56,16 @@ private:
};
VSyncReactor::VSyncReactor(std::unique_ptr<Clock> clock, std::unique_ptr<VSyncDispatch> dispatch,
- std::unique_ptr<VSyncTracker> tracker, size_t pendingFenceLimit)
+ std::unique_ptr<VSyncTracker> tracker, size_t pendingFenceLimit,
+ bool supportKernelIdleTimer)
: mClock(std::move(clock)),
mTracker(std::move(tracker)),
mDispatch(std::move(dispatch)),
mPendingLimit(pendingFenceLimit),
mPredictedVsyncTracer(property_get_bool("debug.sf.show_predicted_vsync", false)
? std::make_unique<PredictedVsyncTracer>(*mDispatch)
- : nullptr) {}
+ : nullptr),
+ mSupportKernelIdleTimer(supportKernelIdleTimer) {}
VSyncReactor::~VSyncReactor() = default;
@@ -249,7 +251,8 @@ void VSyncReactor::setPeriod(nsecs_t period) {
ATRACE_INT64("VSR-setPeriod", period);
std::lock_guard lk(mMutex);
mLastHwVsync.reset();
- if (period == getPeriod()) {
+
+ if (!mSupportKernelIdleTimer && period == getPeriod()) {
endPeriodTransition();
} else {
startPeriodTransition(period);
@@ -275,6 +278,11 @@ bool VSyncReactor::periodConfirmed(nsecs_t vsync_timestamp, std::optional<nsecs_
return false;
}
+ if (mSupportKernelIdleTimer) {
+ // Clear out the Composer-provided period and use the allowance logic below
+ HwcVsyncPeriod = {};
+ }
+
auto const period = mPeriodTransitioningTo ? *mPeriodTransitioningTo : getPeriod();
static constexpr int allowancePercent = 10;
static constexpr std::ratio<allowancePercent, 100> allowancePercentRatio;
diff --git a/services/surfaceflinger/Scheduler/VSyncReactor.h b/services/surfaceflinger/Scheduler/VSyncReactor.h
index 31ddf5a186..265d89c4b4 100644
--- a/services/surfaceflinger/Scheduler/VSyncReactor.h
+++ b/services/surfaceflinger/Scheduler/VSyncReactor.h
@@ -36,7 +36,8 @@ class PredictedVsyncTracer;
class VSyncReactor : public android::DispSync {
public:
VSyncReactor(std::unique_ptr<Clock> clock, std::unique_ptr<VSyncDispatch> dispatch,
- std::unique_ptr<VSyncTracker> tracker, size_t pendingFenceLimit);
+ std::unique_ptr<VSyncTracker> tracker, size_t pendingFenceLimit,
+ bool supportKernelIdleTimer);
~VSyncReactor();
bool addPresentFence(const std::shared_ptr<FenceTime>& fence) final;
@@ -89,6 +90,7 @@ private:
GUARDED_BY(mMutex);
const std::unique_ptr<PredictedVsyncTracer> mPredictedVsyncTracer;
+ const bool mSupportKernelIdleTimer = false;
};
class SystemClock : public Clock {
diff --git a/services/surfaceflinger/tests/unittests/VSyncReactorTest.cpp b/services/surfaceflinger/tests/unittests/VSyncReactorTest.cpp
index 3f14d652ce..ccbd17fa36 100644
--- a/services/surfaceflinger/tests/unittests/VSyncReactorTest.cpp
+++ b/services/surfaceflinger/tests/unittests/VSyncReactorTest.cpp
@@ -157,7 +157,8 @@ protected:
mMockClock(std::make_shared<NiceMock<MockClock>>()),
mReactor(std::make_unique<ClockWrapper>(mMockClock),
std::make_unique<VSyncDispatchWrapper>(mMockDispatch),
- std::make_unique<VSyncTrackerWrapper>(mMockTracker), kPendingLimit) {
+ std::make_unique<VSyncTrackerWrapper>(mMockTracker), kPendingLimit,
+ false /* supportKernelIdleTimer */) {
ON_CALL(*mMockClock, now()).WillByDefault(Return(mFakeNow));
ON_CALL(*mMockTracker, currentPeriod()).WillByDefault(Return(period));
}
@@ -663,6 +664,28 @@ TEST_F(VSyncReactorTest, periodChangeWithGivenVsyncPeriod) {
EXPECT_TRUE(mReactor.addPresentFence(generateSignalledFenceWithTime(0)));
}
+TEST_F(VSyncReactorTest, periodIsMeasuredIfIgnoringComposer) {
+ // Create a reactor which supports the kernel idle timer
+ auto idleReactor = VSyncReactor(std::make_unique<ClockWrapper>(mMockClock),
+ std::make_unique<VSyncDispatchWrapper>(mMockDispatch),
+ std::make_unique<VSyncTrackerWrapper>(mMockTracker),
+ kPendingLimit, true /* supportKernelIdleTimer */);
+
+ bool periodFlushed = true;
+ EXPECT_CALL(*mMockTracker, addVsyncTimestamp(_)).Times(2);
+ idleReactor.setIgnorePresentFences(true);
+
+ nsecs_t const newPeriod = 5000;
+ idleReactor.setPeriod(newPeriod);
+
+ EXPECT_TRUE(idleReactor.addResyncSample(0, 0, &periodFlushed));
+ EXPECT_FALSE(periodFlushed);
+ EXPECT_FALSE(idleReactor.addResyncSample(newPeriod, 0, &periodFlushed));
+ EXPECT_TRUE(periodFlushed);
+
+ EXPECT_TRUE(idleReactor.addPresentFence(generateSignalledFenceWithTime(0)));
+}
+
using VSyncReactorDeathTest = VSyncReactorTest;
TEST_F(VSyncReactorDeathTest, invalidRemoval) {
mReactor.addEventListener(mName, mPhase, &outerCb, lastCallbackTime);