Loading services/surfaceflinger/Scheduler/Scheduler.cpp +40 −2 Original line number Diff line number Diff line Loading @@ -47,6 +47,10 @@ #include "OneShotTimer.h" #include "SchedulerUtils.h" #include "SurfaceFlingerProperties.h" #include "Timer.h" #include "VSyncDispatchTimerQueue.h" #include "VSyncPredictor.h" #include "VSyncReactor.h" #define RETURN_IF_INVALID_HANDLE(handle, ...) \ do { \ Loading @@ -58,11 +62,45 @@ namespace android { std::unique_ptr<DispSync> createDispSync() { // TODO (140302863) remove this and use the vsync_reactor system. if (property_get_bool("debug.sf.vsync_reactor", false)) { // TODO (144707443) tune Predictor tunables. static constexpr int default_rate = 60; static constexpr auto initial_period = std::chrono::duration<nsecs_t, std::ratio<1, default_rate>>(1); static constexpr size_t vsyncTimestampHistorySize = 20; static constexpr size_t minimumSamplesForPrediction = 6; static constexpr uint32_t discardOutlierPercent = 20; auto tracker = std::make_unique< scheduler::VSyncPredictor>(std::chrono::duration_cast<std::chrono::nanoseconds>( initial_period) .count(), vsyncTimestampHistorySize, minimumSamplesForPrediction, discardOutlierPercent); static constexpr auto vsyncMoveThreshold = std::chrono::duration_cast<std::chrono::nanoseconds>(3ms); static constexpr auto timerSlack = std::chrono::duration_cast<std::chrono::nanoseconds>(500us); auto dispatch = std::make_unique< scheduler::VSyncDispatchTimerQueue>(std::make_unique<scheduler::Timer>(), *tracker, timerSlack.count(), vsyncMoveThreshold.count()); static constexpr size_t pendingFenceLimit = 20; return std::make_unique<scheduler::VSyncReactor>(std::make_unique<scheduler::SystemClock>(), std::move(dispatch), std::move(tracker), pendingFenceLimit); } else { return std::make_unique<impl::DispSync>("SchedulerDispSync", sysprop::running_without_sync_framework(true)); } } Scheduler::Scheduler(impl::EventControlThread::SetVSyncEnabledFunction function, const scheduler::RefreshRateConfigs& refreshRateConfig, ISchedulerCallback& schedulerCallback) : mPrimaryDispSync(new impl::DispSync("SchedulerDispSync", sysprop::running_without_sync_framework(true))), : mPrimaryDispSync(createDispSync()), mEventControlThread(new impl::EventControlThread(std::move(function))), mSupportKernelTimer(sysprop::support_kernel_idle_timer(false)), mSchedulerCallback(schedulerCallback), Loading services/surfaceflinger/Scheduler/VSyncReactor.cpp +10 −1 Original line number Diff line number Diff line Loading @@ -26,12 +26,15 @@ namespace android::scheduler { Clock::~Clock() = default; nsecs_t SystemClock::now() const { return systemTime(SYSTEM_TIME_MONOTONIC); } VSyncReactor::VSyncReactor(std::unique_ptr<Clock> clock, std::unique_ptr<VSyncDispatch> dispatch, std::unique_ptr<VSyncTracker> tracker, size_t pendingFenceLimit) : mClock(std::move(clock)), mDispatch(std::move(dispatch)), mTracker(std::move(tracker)), mDispatch(std::move(dispatch)), mPendingLimit(pendingFenceLimit) {} VSyncReactor::~VSyncReactor() = default; Loading Loading @@ -245,4 +248,10 @@ status_t VSyncReactor::changePhaseOffset(DispSync::Callback* callback, nsecs_t p return NO_ERROR; } void VSyncReactor::dump(std::string& result) const { result += "VsyncReactor in use\n"; // TODO (b/144927823): add more information! } void VSyncReactor::reset() {} } // namespace android::scheduler services/surfaceflinger/Scheduler/VSyncReactor.h +22 −15 Original line number Diff line number Diff line Loading @@ -23,7 +23,7 @@ #include <unordered_map> #include <vector> #include "DispSync.h" #include "TimeKeeper.h" namespace android::scheduler { class Clock; Loading @@ -32,35 +32,38 @@ class VSyncTracker; class CallbackRepeater; // TODO (b/145217110): consider renaming. class VSyncReactor /* TODO (b/140201379): : public android::DispSync */ { 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); ~VSyncReactor(); bool addPresentFence(const std::shared_ptr<FenceTime>& fence); void setIgnorePresentFences(bool ignoration); bool addPresentFence(const std::shared_ptr<FenceTime>& fence) final; void setIgnorePresentFences(bool ignoration) final; nsecs_t computeNextRefresh(int periodOffset) const; nsecs_t expectedPresentTime(); nsecs_t computeNextRefresh(int periodOffset) const final; nsecs_t expectedPresentTime() final; void setPeriod(nsecs_t period); nsecs_t getPeriod(); void setPeriod(nsecs_t period) final; nsecs_t getPeriod() final; // TODO: (b/145626181) remove begin,endResync functions from DispSync i/f when possible. void beginResync(); bool addResyncSample(nsecs_t timestamp, bool* periodFlushed); void endResync(); void beginResync() final; bool addResyncSample(nsecs_t timestamp, bool* periodFlushed) final; void endResync() final; status_t addEventListener(const char* name, nsecs_t phase, DispSync::Callback* callback, nsecs_t lastCallbackTime); status_t removeEventListener(DispSync::Callback* callback, nsecs_t* outLastCallback); status_t changePhaseOffset(DispSync::Callback* callback, nsecs_t phase); nsecs_t lastCallbackTime) final; status_t removeEventListener(DispSync::Callback* callback, nsecs_t* outLastCallback) final; status_t changePhaseOffset(DispSync::Callback* callback, nsecs_t phase) final; void dump(std::string& result) const final; void reset() final; private: std::unique_ptr<Clock> const mClock; std::unique_ptr<VSyncDispatch> const mDispatch; std::unique_ptr<VSyncTracker> const mTracker; std::unique_ptr<VSyncDispatch> const mDispatch; size_t const mPendingLimit; std::mutex mMutex; Loading @@ -71,4 +74,8 @@ private: GUARDED_BY(mMutex); }; class SystemClock : public Clock { nsecs_t now() const final; }; } // namespace android::scheduler Loading
services/surfaceflinger/Scheduler/Scheduler.cpp +40 −2 Original line number Diff line number Diff line Loading @@ -47,6 +47,10 @@ #include "OneShotTimer.h" #include "SchedulerUtils.h" #include "SurfaceFlingerProperties.h" #include "Timer.h" #include "VSyncDispatchTimerQueue.h" #include "VSyncPredictor.h" #include "VSyncReactor.h" #define RETURN_IF_INVALID_HANDLE(handle, ...) \ do { \ Loading @@ -58,11 +62,45 @@ namespace android { std::unique_ptr<DispSync> createDispSync() { // TODO (140302863) remove this and use the vsync_reactor system. if (property_get_bool("debug.sf.vsync_reactor", false)) { // TODO (144707443) tune Predictor tunables. static constexpr int default_rate = 60; static constexpr auto initial_period = std::chrono::duration<nsecs_t, std::ratio<1, default_rate>>(1); static constexpr size_t vsyncTimestampHistorySize = 20; static constexpr size_t minimumSamplesForPrediction = 6; static constexpr uint32_t discardOutlierPercent = 20; auto tracker = std::make_unique< scheduler::VSyncPredictor>(std::chrono::duration_cast<std::chrono::nanoseconds>( initial_period) .count(), vsyncTimestampHistorySize, minimumSamplesForPrediction, discardOutlierPercent); static constexpr auto vsyncMoveThreshold = std::chrono::duration_cast<std::chrono::nanoseconds>(3ms); static constexpr auto timerSlack = std::chrono::duration_cast<std::chrono::nanoseconds>(500us); auto dispatch = std::make_unique< scheduler::VSyncDispatchTimerQueue>(std::make_unique<scheduler::Timer>(), *tracker, timerSlack.count(), vsyncMoveThreshold.count()); static constexpr size_t pendingFenceLimit = 20; return std::make_unique<scheduler::VSyncReactor>(std::make_unique<scheduler::SystemClock>(), std::move(dispatch), std::move(tracker), pendingFenceLimit); } else { return std::make_unique<impl::DispSync>("SchedulerDispSync", sysprop::running_without_sync_framework(true)); } } Scheduler::Scheduler(impl::EventControlThread::SetVSyncEnabledFunction function, const scheduler::RefreshRateConfigs& refreshRateConfig, ISchedulerCallback& schedulerCallback) : mPrimaryDispSync(new impl::DispSync("SchedulerDispSync", sysprop::running_without_sync_framework(true))), : mPrimaryDispSync(createDispSync()), mEventControlThread(new impl::EventControlThread(std::move(function))), mSupportKernelTimer(sysprop::support_kernel_idle_timer(false)), mSchedulerCallback(schedulerCallback), Loading
services/surfaceflinger/Scheduler/VSyncReactor.cpp +10 −1 Original line number Diff line number Diff line Loading @@ -26,12 +26,15 @@ namespace android::scheduler { Clock::~Clock() = default; nsecs_t SystemClock::now() const { return systemTime(SYSTEM_TIME_MONOTONIC); } VSyncReactor::VSyncReactor(std::unique_ptr<Clock> clock, std::unique_ptr<VSyncDispatch> dispatch, std::unique_ptr<VSyncTracker> tracker, size_t pendingFenceLimit) : mClock(std::move(clock)), mDispatch(std::move(dispatch)), mTracker(std::move(tracker)), mDispatch(std::move(dispatch)), mPendingLimit(pendingFenceLimit) {} VSyncReactor::~VSyncReactor() = default; Loading Loading @@ -245,4 +248,10 @@ status_t VSyncReactor::changePhaseOffset(DispSync::Callback* callback, nsecs_t p return NO_ERROR; } void VSyncReactor::dump(std::string& result) const { result += "VsyncReactor in use\n"; // TODO (b/144927823): add more information! } void VSyncReactor::reset() {} } // namespace android::scheduler
services/surfaceflinger/Scheduler/VSyncReactor.h +22 −15 Original line number Diff line number Diff line Loading @@ -23,7 +23,7 @@ #include <unordered_map> #include <vector> #include "DispSync.h" #include "TimeKeeper.h" namespace android::scheduler { class Clock; Loading @@ -32,35 +32,38 @@ class VSyncTracker; class CallbackRepeater; // TODO (b/145217110): consider renaming. class VSyncReactor /* TODO (b/140201379): : public android::DispSync */ { 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); ~VSyncReactor(); bool addPresentFence(const std::shared_ptr<FenceTime>& fence); void setIgnorePresentFences(bool ignoration); bool addPresentFence(const std::shared_ptr<FenceTime>& fence) final; void setIgnorePresentFences(bool ignoration) final; nsecs_t computeNextRefresh(int periodOffset) const; nsecs_t expectedPresentTime(); nsecs_t computeNextRefresh(int periodOffset) const final; nsecs_t expectedPresentTime() final; void setPeriod(nsecs_t period); nsecs_t getPeriod(); void setPeriod(nsecs_t period) final; nsecs_t getPeriod() final; // TODO: (b/145626181) remove begin,endResync functions from DispSync i/f when possible. void beginResync(); bool addResyncSample(nsecs_t timestamp, bool* periodFlushed); void endResync(); void beginResync() final; bool addResyncSample(nsecs_t timestamp, bool* periodFlushed) final; void endResync() final; status_t addEventListener(const char* name, nsecs_t phase, DispSync::Callback* callback, nsecs_t lastCallbackTime); status_t removeEventListener(DispSync::Callback* callback, nsecs_t* outLastCallback); status_t changePhaseOffset(DispSync::Callback* callback, nsecs_t phase); nsecs_t lastCallbackTime) final; status_t removeEventListener(DispSync::Callback* callback, nsecs_t* outLastCallback) final; status_t changePhaseOffset(DispSync::Callback* callback, nsecs_t phase) final; void dump(std::string& result) const final; void reset() final; private: std::unique_ptr<Clock> const mClock; std::unique_ptr<VSyncDispatch> const mDispatch; std::unique_ptr<VSyncTracker> const mTracker; std::unique_ptr<VSyncDispatch> const mDispatch; size_t const mPendingLimit; std::mutex mMutex; Loading @@ -71,4 +74,8 @@ private: GUARDED_BY(mMutex); }; class SystemClock : public Clock { nsecs_t now() const final; }; } // namespace android::scheduler