Loading services/surfaceflinger/Scheduler/EventThread.cpp +25 −10 Original line number Diff line number Diff line Loading @@ -238,7 +238,7 @@ EventThread::~EventThread() = default; namespace impl { EventThread::EventThread(const char* name, scheduler::VsyncSchedule& vsyncSchedule, EventThread::EventThread(const char* name, std::shared_ptr<scheduler::VsyncSchedule> vsyncSchedule, android::frametimeline::TokenManager* tokenManager, ThrottleVsyncCallback throttleVsyncCallback, GetVsyncPeriodFunction getVsyncPeriodFunction, Loading @@ -248,13 +248,8 @@ EventThread::EventThread(const char* name, scheduler::VsyncSchedule& vsyncSchedu mVsyncTracer(base::StringPrintf("VSYNC-%s", name), 0), mWorkDuration(base::StringPrintf("VsyncWorkDuration-%s", name), workDuration), mReadyDuration(readyDuration), mVsyncSchedule(vsyncSchedule), mVsyncRegistration( vsyncSchedule.getDispatch(), [this](nsecs_t vsyncTime, nsecs_t wakeupTime, nsecs_t readyTime) { onVsync(vsyncTime, wakeupTime, readyTime); }, name), mVsyncSchedule(std::move(vsyncSchedule)), mVsyncRegistration(mVsyncSchedule->getDispatch(), createDispatchCallback(), name), mTokenManager(tokenManager), mThrottleVsyncCallback(std::move(throttleVsyncCallback)), mGetVsyncPeriodFunction(std::move(getVsyncPeriodFunction)) { Loading Loading @@ -375,7 +370,7 @@ VsyncEventData EventThread::getLatestVsyncEventData( vsyncEventData.frameInterval = frameInterval; const auto [presentTime, deadline] = [&]() -> std::pair<nsecs_t, nsecs_t> { std::lock_guard<std::mutex> lock(mMutex); const auto vsyncTime = mVsyncSchedule.getTracker().nextAnticipatedVSyncTimeFrom( const auto vsyncTime = mVsyncSchedule->getTracker().nextAnticipatedVSyncTimeFrom( systemTime() + mWorkDuration.get().count() + mReadyDuration.count()); return {vsyncTime, vsyncTime - mReadyDuration.count()}; }(); Loading Loading @@ -533,7 +528,7 @@ bool EventThread::shouldConsumeEvent(const DisplayEventReceiver::Event& event, const auto throttleVsync = [&] { const auto& vsyncData = event.vsync.vsyncData; if (connection->frameRate.isValid()) { return !mVsyncSchedule.getTracker() return !mVsyncSchedule->getTracker() .isVSyncInPhase(vsyncData.preferredExpectedPresentationTime(), connection->frameRate); } Loading Loading @@ -696,6 +691,26 @@ const char* EventThread::toCString(State state) { } } void EventThread::onNewVsyncSchedule(std::shared_ptr<scheduler::VsyncSchedule> schedule) { std::lock_guard<std::mutex> lock(mMutex); const bool reschedule = mVsyncRegistration.cancel() == scheduler::CancelResult::Cancelled; mVsyncSchedule = std::move(schedule); mVsyncRegistration = scheduler::VSyncCallbackRegistration(mVsyncSchedule->getDispatch(), createDispatchCallback(), mThreadName); if (reschedule) { mVsyncRegistration.schedule({.workDuration = mWorkDuration.get().count(), .readyDuration = mReadyDuration.count(), .earliestVsync = mLastVsyncCallbackTime.ns()}); } } scheduler::VSyncDispatch::Callback EventThread::createDispatchCallback() { return [this](nsecs_t vsyncTime, nsecs_t wakeupTime, nsecs_t readyTime) { onVsync(vsyncTime, wakeupTime, readyTime); }; } } // namespace impl } // namespace android Loading services/surfaceflinger/Scheduler/EventThread.h +9 −3 Original line number Diff line number Diff line Loading @@ -133,6 +133,8 @@ public: // Retrieves the number of event connections tracked by this EventThread. virtual size_t getEventThreadConnectionCount() = 0; virtual void onNewVsyncSchedule(std::shared_ptr<scheduler::VsyncSchedule>) = 0; }; namespace impl { Loading @@ -142,8 +144,8 @@ public: using ThrottleVsyncCallback = std::function<bool(nsecs_t, uid_t)>; using GetVsyncPeriodFunction = std::function<nsecs_t(uid_t)>; EventThread(const char* name, scheduler::VsyncSchedule&, frametimeline::TokenManager*, ThrottleVsyncCallback, GetVsyncPeriodFunction, EventThread(const char* name, std::shared_ptr<scheduler::VsyncSchedule>, frametimeline::TokenManager*, ThrottleVsyncCallback, GetVsyncPeriodFunction, std::chrono::nanoseconds workDuration, std::chrono::nanoseconds readyDuration); ~EventThread(); Loading Loading @@ -172,6 +174,8 @@ public: size_t getEventThreadConnectionCount() override; void onNewVsyncSchedule(std::shared_ptr<scheduler::VsyncSchedule>) override; private: friend EventThreadTest; Loading @@ -195,11 +199,13 @@ private: nsecs_t timestamp, nsecs_t preferredExpectedPresentationTime, nsecs_t preferredDeadlineTimestamp) const; scheduler::VSyncDispatch::Callback createDispatchCallback(); const char* const mThreadName; TracedOrdinal<int> mVsyncTracer; TracedOrdinal<std::chrono::nanoseconds> mWorkDuration GUARDED_BY(mMutex); std::chrono::nanoseconds mReadyDuration GUARDED_BY(mMutex); scheduler::VsyncSchedule& mVsyncSchedule; std::shared_ptr<scheduler::VsyncSchedule> mVsyncSchedule; TimePoint mLastVsyncCallbackTime GUARDED_BY(mMutex) = TimePoint::now(); scheduler::VSyncCallbackRegistration mVsyncRegistration GUARDED_BY(mMutex); frametimeline::TokenManager* const mTokenManager; Loading services/surfaceflinger/Scheduler/ISchedulerCallback.h +3 −1 Original line number Diff line number Diff line Loading @@ -18,12 +18,14 @@ #include <vector> #include <ui/DisplayId.h> #include "Display/DisplayModeRequest.h" namespace android::scheduler { struct ISchedulerCallback { virtual void setVsyncEnabled(bool) = 0; virtual void setVsyncEnabled(PhysicalDisplayId, bool) = 0; virtual void requestDisplayModes(std::vector<display::DisplayModeRequest>) = 0; virtual void kernelTimerChanged(bool expired) = 0; virtual void triggerOnFrameRateOverridesChanged() = 0; Loading services/surfaceflinger/Scheduler/MessageQueue.cpp +19 −2 Original line number Diff line number Diff line Loading @@ -75,19 +75,36 @@ void MessageQueue::vsyncCallback(nsecs_t vsyncTime, nsecs_t targetWakeupTime, ns mHandler->dispatchFrame(vsyncId, expectedVsyncTime); } void MessageQueue::initVsync(scheduler::VSyncDispatch& dispatch, void MessageQueue::initVsync(std::shared_ptr<scheduler::VSyncDispatch> dispatch, frametimeline::TokenManager& tokenManager, std::chrono::nanoseconds workDuration) { std::lock_guard lock(mVsync.mutex); mVsync.workDuration = workDuration; mVsync.tokenManager = &tokenManager; onNewVsyncScheduleLocked(std::move(dispatch)); } void MessageQueue::onNewVsyncSchedule(std::shared_ptr<scheduler::VSyncDispatch> dispatch) { std::lock_guard lock(mVsync.mutex); onNewVsyncScheduleLocked(std::move(dispatch)); } void MessageQueue::onNewVsyncScheduleLocked(std::shared_ptr<scheduler::VSyncDispatch> dispatch) { const bool reschedule = mVsync.registration && mVsync.registration->cancel() == scheduler::CancelResult::Cancelled; mVsync.registration = std::make_unique< scheduler::VSyncCallbackRegistration>(dispatch, scheduler::VSyncCallbackRegistration>(std::move(dispatch), std::bind(&MessageQueue::vsyncCallback, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3), "sf"); if (reschedule) { mVsync.scheduledFrameTime = mVsync.registration->schedule({.workDuration = mVsync.workDuration.get().count(), .readyDuration = 0, .earliestVsync = mVsync.lastCallbackTime.ns()}); } } void MessageQueue::destroyVsync() { Loading services/surfaceflinger/Scheduler/MessageQueue.h +6 −2 Original line number Diff line number Diff line Loading @@ -65,7 +65,7 @@ class MessageQueue { public: virtual ~MessageQueue() = default; virtual void initVsync(scheduler::VSyncDispatch&, frametimeline::TokenManager&, virtual void initVsync(std::shared_ptr<scheduler::VSyncDispatch>, frametimeline::TokenManager&, std::chrono::nanoseconds workDuration) = 0; virtual void destroyVsync() = 0; virtual void setDuration(std::chrono::nanoseconds workDuration) = 0; Loading Loading @@ -106,6 +106,8 @@ protected: void vsyncCallback(nsecs_t vsyncTime, nsecs_t targetWakeupTime, nsecs_t readyTime); void onNewVsyncSchedule(std::shared_ptr<scheduler::VSyncDispatch>) EXCLUDES(mVsync.mutex); private: virtual void onFrameSignal(ICompositor&, VsyncId, TimePoint expectedVsyncTime) = 0; Loading @@ -127,10 +129,12 @@ private: Vsync mVsync; void onNewVsyncScheduleLocked(std::shared_ptr<scheduler::VSyncDispatch>) REQUIRES(mVsync.mutex); public: explicit MessageQueue(ICompositor&); void initVsync(scheduler::VSyncDispatch&, frametimeline::TokenManager&, void initVsync(std::shared_ptr<scheduler::VSyncDispatch>, frametimeline::TokenManager&, std::chrono::nanoseconds workDuration) override; void destroyVsync() override; void setDuration(std::chrono::nanoseconds workDuration) override; Loading Loading
services/surfaceflinger/Scheduler/EventThread.cpp +25 −10 Original line number Diff line number Diff line Loading @@ -238,7 +238,7 @@ EventThread::~EventThread() = default; namespace impl { EventThread::EventThread(const char* name, scheduler::VsyncSchedule& vsyncSchedule, EventThread::EventThread(const char* name, std::shared_ptr<scheduler::VsyncSchedule> vsyncSchedule, android::frametimeline::TokenManager* tokenManager, ThrottleVsyncCallback throttleVsyncCallback, GetVsyncPeriodFunction getVsyncPeriodFunction, Loading @@ -248,13 +248,8 @@ EventThread::EventThread(const char* name, scheduler::VsyncSchedule& vsyncSchedu mVsyncTracer(base::StringPrintf("VSYNC-%s", name), 0), mWorkDuration(base::StringPrintf("VsyncWorkDuration-%s", name), workDuration), mReadyDuration(readyDuration), mVsyncSchedule(vsyncSchedule), mVsyncRegistration( vsyncSchedule.getDispatch(), [this](nsecs_t vsyncTime, nsecs_t wakeupTime, nsecs_t readyTime) { onVsync(vsyncTime, wakeupTime, readyTime); }, name), mVsyncSchedule(std::move(vsyncSchedule)), mVsyncRegistration(mVsyncSchedule->getDispatch(), createDispatchCallback(), name), mTokenManager(tokenManager), mThrottleVsyncCallback(std::move(throttleVsyncCallback)), mGetVsyncPeriodFunction(std::move(getVsyncPeriodFunction)) { Loading Loading @@ -375,7 +370,7 @@ VsyncEventData EventThread::getLatestVsyncEventData( vsyncEventData.frameInterval = frameInterval; const auto [presentTime, deadline] = [&]() -> std::pair<nsecs_t, nsecs_t> { std::lock_guard<std::mutex> lock(mMutex); const auto vsyncTime = mVsyncSchedule.getTracker().nextAnticipatedVSyncTimeFrom( const auto vsyncTime = mVsyncSchedule->getTracker().nextAnticipatedVSyncTimeFrom( systemTime() + mWorkDuration.get().count() + mReadyDuration.count()); return {vsyncTime, vsyncTime - mReadyDuration.count()}; }(); Loading Loading @@ -533,7 +528,7 @@ bool EventThread::shouldConsumeEvent(const DisplayEventReceiver::Event& event, const auto throttleVsync = [&] { const auto& vsyncData = event.vsync.vsyncData; if (connection->frameRate.isValid()) { return !mVsyncSchedule.getTracker() return !mVsyncSchedule->getTracker() .isVSyncInPhase(vsyncData.preferredExpectedPresentationTime(), connection->frameRate); } Loading Loading @@ -696,6 +691,26 @@ const char* EventThread::toCString(State state) { } } void EventThread::onNewVsyncSchedule(std::shared_ptr<scheduler::VsyncSchedule> schedule) { std::lock_guard<std::mutex> lock(mMutex); const bool reschedule = mVsyncRegistration.cancel() == scheduler::CancelResult::Cancelled; mVsyncSchedule = std::move(schedule); mVsyncRegistration = scheduler::VSyncCallbackRegistration(mVsyncSchedule->getDispatch(), createDispatchCallback(), mThreadName); if (reschedule) { mVsyncRegistration.schedule({.workDuration = mWorkDuration.get().count(), .readyDuration = mReadyDuration.count(), .earliestVsync = mLastVsyncCallbackTime.ns()}); } } scheduler::VSyncDispatch::Callback EventThread::createDispatchCallback() { return [this](nsecs_t vsyncTime, nsecs_t wakeupTime, nsecs_t readyTime) { onVsync(vsyncTime, wakeupTime, readyTime); }; } } // namespace impl } // namespace android Loading
services/surfaceflinger/Scheduler/EventThread.h +9 −3 Original line number Diff line number Diff line Loading @@ -133,6 +133,8 @@ public: // Retrieves the number of event connections tracked by this EventThread. virtual size_t getEventThreadConnectionCount() = 0; virtual void onNewVsyncSchedule(std::shared_ptr<scheduler::VsyncSchedule>) = 0; }; namespace impl { Loading @@ -142,8 +144,8 @@ public: using ThrottleVsyncCallback = std::function<bool(nsecs_t, uid_t)>; using GetVsyncPeriodFunction = std::function<nsecs_t(uid_t)>; EventThread(const char* name, scheduler::VsyncSchedule&, frametimeline::TokenManager*, ThrottleVsyncCallback, GetVsyncPeriodFunction, EventThread(const char* name, std::shared_ptr<scheduler::VsyncSchedule>, frametimeline::TokenManager*, ThrottleVsyncCallback, GetVsyncPeriodFunction, std::chrono::nanoseconds workDuration, std::chrono::nanoseconds readyDuration); ~EventThread(); Loading Loading @@ -172,6 +174,8 @@ public: size_t getEventThreadConnectionCount() override; void onNewVsyncSchedule(std::shared_ptr<scheduler::VsyncSchedule>) override; private: friend EventThreadTest; Loading @@ -195,11 +199,13 @@ private: nsecs_t timestamp, nsecs_t preferredExpectedPresentationTime, nsecs_t preferredDeadlineTimestamp) const; scheduler::VSyncDispatch::Callback createDispatchCallback(); const char* const mThreadName; TracedOrdinal<int> mVsyncTracer; TracedOrdinal<std::chrono::nanoseconds> mWorkDuration GUARDED_BY(mMutex); std::chrono::nanoseconds mReadyDuration GUARDED_BY(mMutex); scheduler::VsyncSchedule& mVsyncSchedule; std::shared_ptr<scheduler::VsyncSchedule> mVsyncSchedule; TimePoint mLastVsyncCallbackTime GUARDED_BY(mMutex) = TimePoint::now(); scheduler::VSyncCallbackRegistration mVsyncRegistration GUARDED_BY(mMutex); frametimeline::TokenManager* const mTokenManager; Loading
services/surfaceflinger/Scheduler/ISchedulerCallback.h +3 −1 Original line number Diff line number Diff line Loading @@ -18,12 +18,14 @@ #include <vector> #include <ui/DisplayId.h> #include "Display/DisplayModeRequest.h" namespace android::scheduler { struct ISchedulerCallback { virtual void setVsyncEnabled(bool) = 0; virtual void setVsyncEnabled(PhysicalDisplayId, bool) = 0; virtual void requestDisplayModes(std::vector<display::DisplayModeRequest>) = 0; virtual void kernelTimerChanged(bool expired) = 0; virtual void triggerOnFrameRateOverridesChanged() = 0; Loading
services/surfaceflinger/Scheduler/MessageQueue.cpp +19 −2 Original line number Diff line number Diff line Loading @@ -75,19 +75,36 @@ void MessageQueue::vsyncCallback(nsecs_t vsyncTime, nsecs_t targetWakeupTime, ns mHandler->dispatchFrame(vsyncId, expectedVsyncTime); } void MessageQueue::initVsync(scheduler::VSyncDispatch& dispatch, void MessageQueue::initVsync(std::shared_ptr<scheduler::VSyncDispatch> dispatch, frametimeline::TokenManager& tokenManager, std::chrono::nanoseconds workDuration) { std::lock_guard lock(mVsync.mutex); mVsync.workDuration = workDuration; mVsync.tokenManager = &tokenManager; onNewVsyncScheduleLocked(std::move(dispatch)); } void MessageQueue::onNewVsyncSchedule(std::shared_ptr<scheduler::VSyncDispatch> dispatch) { std::lock_guard lock(mVsync.mutex); onNewVsyncScheduleLocked(std::move(dispatch)); } void MessageQueue::onNewVsyncScheduleLocked(std::shared_ptr<scheduler::VSyncDispatch> dispatch) { const bool reschedule = mVsync.registration && mVsync.registration->cancel() == scheduler::CancelResult::Cancelled; mVsync.registration = std::make_unique< scheduler::VSyncCallbackRegistration>(dispatch, scheduler::VSyncCallbackRegistration>(std::move(dispatch), std::bind(&MessageQueue::vsyncCallback, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3), "sf"); if (reschedule) { mVsync.scheduledFrameTime = mVsync.registration->schedule({.workDuration = mVsync.workDuration.get().count(), .readyDuration = 0, .earliestVsync = mVsync.lastCallbackTime.ns()}); } } void MessageQueue::destroyVsync() { Loading
services/surfaceflinger/Scheduler/MessageQueue.h +6 −2 Original line number Diff line number Diff line Loading @@ -65,7 +65,7 @@ class MessageQueue { public: virtual ~MessageQueue() = default; virtual void initVsync(scheduler::VSyncDispatch&, frametimeline::TokenManager&, virtual void initVsync(std::shared_ptr<scheduler::VSyncDispatch>, frametimeline::TokenManager&, std::chrono::nanoseconds workDuration) = 0; virtual void destroyVsync() = 0; virtual void setDuration(std::chrono::nanoseconds workDuration) = 0; Loading Loading @@ -106,6 +106,8 @@ protected: void vsyncCallback(nsecs_t vsyncTime, nsecs_t targetWakeupTime, nsecs_t readyTime); void onNewVsyncSchedule(std::shared_ptr<scheduler::VSyncDispatch>) EXCLUDES(mVsync.mutex); private: virtual void onFrameSignal(ICompositor&, VsyncId, TimePoint expectedVsyncTime) = 0; Loading @@ -127,10 +129,12 @@ private: Vsync mVsync; void onNewVsyncScheduleLocked(std::shared_ptr<scheduler::VSyncDispatch>) REQUIRES(mVsync.mutex); public: explicit MessageQueue(ICompositor&); void initVsync(scheduler::VSyncDispatch&, frametimeline::TokenManager&, void initVsync(std::shared_ptr<scheduler::VSyncDispatch>, frametimeline::TokenManager&, std::chrono::nanoseconds workDuration) override; void destroyVsync() override; void setDuration(std::chrono::nanoseconds workDuration) override; Loading