diff options
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); |