Loading services/surfaceflinger/FrameTimeline/FrameTimeline.h +7 −0 Original line number Original line Diff line number Diff line Loading @@ -39,6 +39,13 @@ struct TimelineItem { nsecs_t startTime; nsecs_t startTime; nsecs_t endTime; nsecs_t endTime; nsecs_t presentTime; nsecs_t presentTime; bool operator==(const TimelineItem& other) const { return startTime == other.startTime && endTime == other.endTime && presentTime == other.presentTime; } bool operator!=(const TimelineItem& other) const { return !(*this == other); } }; }; /* /* Loading services/surfaceflinger/Scheduler/MessageQueue.cpp +55 −9 Original line number Original line Diff line number Diff line Loading @@ -14,9 +14,7 @@ * limitations under the License. * limitations under the License. */ */ // TODO(b/129481165): remove the #pragma below and fix conversion issues #define ATRACE_TAG ATRACE_TAG_GRAPHICS #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wconversion" #include <binder/IPCThreadState.h> #include <binder/IPCThreadState.h> Loading @@ -28,6 +26,7 @@ #include <gui/IDisplayEventConnection.h> #include <gui/IDisplayEventConnection.h> #include "EventThread.h" #include "EventThread.h" #include "FrameTimeline.h" #include "MessageQueue.h" #include "MessageQueue.h" #include "SurfaceFlinger.h" #include "SurfaceFlinger.h" Loading Loading @@ -68,16 +67,54 @@ void MessageQueue::init(const sp<SurfaceFlinger>& flinger) { mHandler = new Handler(*this); mHandler = new Handler(*this); } } // TODO(b/169865816): refactor VSyncInjections to use MessageQueue directly // and remove the EventThread from MessageQueue void MessageQueue::setEventConnection(const sp<EventThreadConnection>& connection) { void MessageQueue::setEventConnection(const sp<EventThreadConnection>& connection) { if (mEventTube.getFd() >= 0) { if (mEventTube.getFd() >= 0) { mLooper->removeFd(mEventTube.getFd()); mLooper->removeFd(mEventTube.getFd()); } } mEvents = connection; mEvents = connection; if (mEvents) { mEvents->stealReceiveChannel(&mEventTube); mEvents->stealReceiveChannel(&mEventTube); mLooper->addFd(mEventTube.getFd(), 0, Looper::EVENT_INPUT, MessageQueue::cb_eventReceiver, mLooper->addFd(mEventTube.getFd(), 0, Looper::EVENT_INPUT, MessageQueue::cb_eventReceiver, this); this); } } } void MessageQueue::vsyncCallback(nsecs_t vsyncTime, nsecs_t targetWakeupTime, nsecs_t readyTime) { ATRACE_CALL(); // Trace VSYNC-sf mVsync.value = (mVsync.value + 1) % 2; { std::lock_guard lock(mVsync.mutex); mVsync.lastCallbackTime = std::chrono::nanoseconds(vsyncTime); } mHandler->dispatchInvalidate(mVsync.tokenManager->generateTokenForPredictions( {targetWakeupTime, readyTime, vsyncTime}), vsyncTime); } void MessageQueue::initVsync(scheduler::VSyncDispatch& dispatch, frametimeline::TokenManager& tokenManager, std::chrono::nanoseconds workDuration) { setDuration(workDuration); mVsync.tokenManager = &tokenManager; mVsync.registration = std::make_unique< scheduler::VSyncCallbackRegistration>(dispatch, std::bind(&MessageQueue::vsyncCallback, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3), "sf"); } void MessageQueue::setDuration(std::chrono::nanoseconds workDuration) { ATRACE_CALL(); std::lock_guard lock(mVsync.mutex); mVsync.workDuration = workDuration; } void MessageQueue::waitMessage() { void MessageQueue::waitMessage() { do { do { Loading Loading @@ -106,7 +143,18 @@ void MessageQueue::postMessage(sp<MessageHandler>&& handler) { } } void MessageQueue::invalidate() { void MessageQueue::invalidate() { ATRACE_CALL(); if (mEvents) { mEvents->requestNextVsync(); mEvents->requestNextVsync(); } else { const auto [workDuration, lastVsyncCallback] = [&] { std::lock_guard lock(mVsync.mutex); std::chrono::nanoseconds mWorkDurationNanos = mVsync.workDuration; return std::make_pair(mWorkDurationNanos.count(), mVsync.lastCallbackTime.count()); }(); mVsync.registration->schedule({workDuration, /*readyDuration=*/0, lastVsyncCallback}); } } } void MessageQueue::refresh() { void MessageQueue::refresh() { Loading Loading @@ -135,5 +183,3 @@ int MessageQueue::eventReceiver(int /*fd*/, int /*events*/) { } // namespace android::impl } // namespace android::impl // TODO(b/129481165): remove the #pragma below and fix conversion issues #pragma clang diagnostic pop // ignored "-Wconversion" services/surfaceflinger/Scheduler/MessageQueue.h +28 −4 Original line number Original line Diff line number Diff line Loading @@ -29,6 +29,8 @@ #include <private/gui/BitTube.h> #include <private/gui/BitTube.h> #include "EventThread.h" #include "EventThread.h" #include "TracedOrdinal.h" #include "VSyncDispatch.h" namespace android { namespace android { Loading Loading @@ -63,6 +65,9 @@ public: virtual ~MessageQueue() = default; virtual ~MessageQueue() = default; virtual void init(const sp<SurfaceFlinger>& flinger) = 0; virtual void init(const sp<SurfaceFlinger>& flinger) = 0; virtual void initVsync(scheduler::VSyncDispatch&, frametimeline::TokenManager&, std::chrono::nanoseconds workDuration) = 0; virtual void setDuration(std::chrono::nanoseconds workDuration) = 0; virtual void setEventConnection(const sp<EventThreadConnection>& connection) = 0; virtual void setEventConnection(const sp<EventThreadConnection>& connection) = 0; virtual void waitMessage() = 0; virtual void waitMessage() = 0; virtual void postMessage(sp<MessageHandler>&&) = 0; virtual void postMessage(sp<MessageHandler>&&) = 0; Loading @@ -74,7 +79,8 @@ public: namespace impl { namespace impl { class MessageQueue final : public android::MessageQueue { class MessageQueue : public android::MessageQueue { protected: class Handler : public MessageHandler { class Handler : public MessageHandler { enum { eventMaskInvalidate = 0x1, eventMaskRefresh = 0x2, eventMaskTransaction = 0x4 }; enum { eventMaskInvalidate = 0x1, eventMaskRefresh = 0x2, eventMaskTransaction = 0x4 }; MessageQueue& mQueue; MessageQueue& mQueue; Loading @@ -84,9 +90,9 @@ class MessageQueue final : public android::MessageQueue { public: public: explicit Handler(MessageQueue& queue) : mQueue(queue), mEventMask(0) {} explicit Handler(MessageQueue& queue) : mQueue(queue), mEventMask(0) {} virtual void handleMessage(const Message& message); void handleMessage(const Message& message) override; void dispatchRefresh(); virtual void dispatchRefresh(); void dispatchInvalidate(int64_t vsyncId, nsecs_t expectedVSyncTimestamp); virtual void dispatchInvalidate(int64_t vsyncId, nsecs_t expectedVSyncTimestamp); }; }; friend class Handler; friend class Handler; Loading @@ -94,15 +100,33 @@ class MessageQueue final : public android::MessageQueue { sp<SurfaceFlinger> mFlinger; sp<SurfaceFlinger> mFlinger; sp<Looper> mLooper; sp<Looper> mLooper; sp<EventThreadConnection> mEvents; sp<EventThreadConnection> mEvents; struct Vsync { frametimeline::TokenManager* tokenManager = nullptr; std::unique_ptr<scheduler::VSyncCallbackRegistration> registration; std::mutex mutex; TracedOrdinal<std::chrono::nanoseconds> workDuration GUARDED_BY(mutex) = {"VsyncWorkDuration-sf", std::chrono::nanoseconds(0)}; std::chrono::nanoseconds lastCallbackTime GUARDED_BY(mutex) = std::chrono::nanoseconds{0}; TracedOrdinal<int> value = {"VSYNC-sf", 0}; }; Vsync mVsync; gui::BitTube mEventTube; gui::BitTube mEventTube; sp<Handler> mHandler; sp<Handler> mHandler; static int cb_eventReceiver(int fd, int events, void* data); static int cb_eventReceiver(int fd, int events, void* data); int eventReceiver(int fd, int events); int eventReceiver(int fd, int events); void vsyncCallback(nsecs_t vsyncTime, nsecs_t targetWakeupTime, nsecs_t readyTime); public: public: ~MessageQueue() override = default; ~MessageQueue() override = default; void init(const sp<SurfaceFlinger>& flinger) override; void init(const sp<SurfaceFlinger>& flinger) override; void initVsync(scheduler::VSyncDispatch&, frametimeline::TokenManager&, std::chrono::nanoseconds workDuration) override; void setDuration(std::chrono::nanoseconds workDuration) override; void setEventConnection(const sp<EventThreadConnection>& connection) override; void setEventConnection(const sp<EventThreadConnection>& connection) override; void waitMessage() override; void waitMessage() override; Loading services/surfaceflinger/Scheduler/Scheduler.h +2 −0 Original line number Original line Diff line number Diff line Loading @@ -137,6 +137,8 @@ public: void setDisplayPowerState(bool normal); void setDisplayPowerState(bool normal); scheduler::VSyncDispatch& getVsyncDispatch() { return *mVsyncSchedule.dispatch; } void dump(std::string&) const; void dump(std::string&) const; void dump(ConnectionHandle, std::string&) const; void dump(ConnectionHandle, std::string&) const; void dumpVsync(std::string&) const; void dumpVsync(std::string&) const; Loading services/surfaceflinger/Scheduler/VSyncDispatch.h +7 −0 Original line number Original line Diff line number Diff line Loading @@ -94,6 +94,13 @@ public: nsecs_t workDuration = 0; nsecs_t workDuration = 0; nsecs_t readyDuration = 0; nsecs_t readyDuration = 0; nsecs_t earliestVsync = 0; nsecs_t earliestVsync = 0; bool operator==(const ScheduleTiming& other) const { return workDuration == other.workDuration && readyDuration == other.readyDuration && earliestVsync == other.earliestVsync; } bool operator!=(const ScheduleTiming& other) const { return !(*this == other); } }; }; /* /* Loading Loading
services/surfaceflinger/FrameTimeline/FrameTimeline.h +7 −0 Original line number Original line Diff line number Diff line Loading @@ -39,6 +39,13 @@ struct TimelineItem { nsecs_t startTime; nsecs_t startTime; nsecs_t endTime; nsecs_t endTime; nsecs_t presentTime; nsecs_t presentTime; bool operator==(const TimelineItem& other) const { return startTime == other.startTime && endTime == other.endTime && presentTime == other.presentTime; } bool operator!=(const TimelineItem& other) const { return !(*this == other); } }; }; /* /* Loading
services/surfaceflinger/Scheduler/MessageQueue.cpp +55 −9 Original line number Original line Diff line number Diff line Loading @@ -14,9 +14,7 @@ * limitations under the License. * limitations under the License. */ */ // TODO(b/129481165): remove the #pragma below and fix conversion issues #define ATRACE_TAG ATRACE_TAG_GRAPHICS #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wconversion" #include <binder/IPCThreadState.h> #include <binder/IPCThreadState.h> Loading @@ -28,6 +26,7 @@ #include <gui/IDisplayEventConnection.h> #include <gui/IDisplayEventConnection.h> #include "EventThread.h" #include "EventThread.h" #include "FrameTimeline.h" #include "MessageQueue.h" #include "MessageQueue.h" #include "SurfaceFlinger.h" #include "SurfaceFlinger.h" Loading Loading @@ -68,16 +67,54 @@ void MessageQueue::init(const sp<SurfaceFlinger>& flinger) { mHandler = new Handler(*this); mHandler = new Handler(*this); } } // TODO(b/169865816): refactor VSyncInjections to use MessageQueue directly // and remove the EventThread from MessageQueue void MessageQueue::setEventConnection(const sp<EventThreadConnection>& connection) { void MessageQueue::setEventConnection(const sp<EventThreadConnection>& connection) { if (mEventTube.getFd() >= 0) { if (mEventTube.getFd() >= 0) { mLooper->removeFd(mEventTube.getFd()); mLooper->removeFd(mEventTube.getFd()); } } mEvents = connection; mEvents = connection; if (mEvents) { mEvents->stealReceiveChannel(&mEventTube); mEvents->stealReceiveChannel(&mEventTube); mLooper->addFd(mEventTube.getFd(), 0, Looper::EVENT_INPUT, MessageQueue::cb_eventReceiver, mLooper->addFd(mEventTube.getFd(), 0, Looper::EVENT_INPUT, MessageQueue::cb_eventReceiver, this); this); } } } void MessageQueue::vsyncCallback(nsecs_t vsyncTime, nsecs_t targetWakeupTime, nsecs_t readyTime) { ATRACE_CALL(); // Trace VSYNC-sf mVsync.value = (mVsync.value + 1) % 2; { std::lock_guard lock(mVsync.mutex); mVsync.lastCallbackTime = std::chrono::nanoseconds(vsyncTime); } mHandler->dispatchInvalidate(mVsync.tokenManager->generateTokenForPredictions( {targetWakeupTime, readyTime, vsyncTime}), vsyncTime); } void MessageQueue::initVsync(scheduler::VSyncDispatch& dispatch, frametimeline::TokenManager& tokenManager, std::chrono::nanoseconds workDuration) { setDuration(workDuration); mVsync.tokenManager = &tokenManager; mVsync.registration = std::make_unique< scheduler::VSyncCallbackRegistration>(dispatch, std::bind(&MessageQueue::vsyncCallback, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3), "sf"); } void MessageQueue::setDuration(std::chrono::nanoseconds workDuration) { ATRACE_CALL(); std::lock_guard lock(mVsync.mutex); mVsync.workDuration = workDuration; } void MessageQueue::waitMessage() { void MessageQueue::waitMessage() { do { do { Loading Loading @@ -106,7 +143,18 @@ void MessageQueue::postMessage(sp<MessageHandler>&& handler) { } } void MessageQueue::invalidate() { void MessageQueue::invalidate() { ATRACE_CALL(); if (mEvents) { mEvents->requestNextVsync(); mEvents->requestNextVsync(); } else { const auto [workDuration, lastVsyncCallback] = [&] { std::lock_guard lock(mVsync.mutex); std::chrono::nanoseconds mWorkDurationNanos = mVsync.workDuration; return std::make_pair(mWorkDurationNanos.count(), mVsync.lastCallbackTime.count()); }(); mVsync.registration->schedule({workDuration, /*readyDuration=*/0, lastVsyncCallback}); } } } void MessageQueue::refresh() { void MessageQueue::refresh() { Loading Loading @@ -135,5 +183,3 @@ int MessageQueue::eventReceiver(int /*fd*/, int /*events*/) { } // namespace android::impl } // namespace android::impl // TODO(b/129481165): remove the #pragma below and fix conversion issues #pragma clang diagnostic pop // ignored "-Wconversion"
services/surfaceflinger/Scheduler/MessageQueue.h +28 −4 Original line number Original line Diff line number Diff line Loading @@ -29,6 +29,8 @@ #include <private/gui/BitTube.h> #include <private/gui/BitTube.h> #include "EventThread.h" #include "EventThread.h" #include "TracedOrdinal.h" #include "VSyncDispatch.h" namespace android { namespace android { Loading Loading @@ -63,6 +65,9 @@ public: virtual ~MessageQueue() = default; virtual ~MessageQueue() = default; virtual void init(const sp<SurfaceFlinger>& flinger) = 0; virtual void init(const sp<SurfaceFlinger>& flinger) = 0; virtual void initVsync(scheduler::VSyncDispatch&, frametimeline::TokenManager&, std::chrono::nanoseconds workDuration) = 0; virtual void setDuration(std::chrono::nanoseconds workDuration) = 0; virtual void setEventConnection(const sp<EventThreadConnection>& connection) = 0; virtual void setEventConnection(const sp<EventThreadConnection>& connection) = 0; virtual void waitMessage() = 0; virtual void waitMessage() = 0; virtual void postMessage(sp<MessageHandler>&&) = 0; virtual void postMessage(sp<MessageHandler>&&) = 0; Loading @@ -74,7 +79,8 @@ public: namespace impl { namespace impl { class MessageQueue final : public android::MessageQueue { class MessageQueue : public android::MessageQueue { protected: class Handler : public MessageHandler { class Handler : public MessageHandler { enum { eventMaskInvalidate = 0x1, eventMaskRefresh = 0x2, eventMaskTransaction = 0x4 }; enum { eventMaskInvalidate = 0x1, eventMaskRefresh = 0x2, eventMaskTransaction = 0x4 }; MessageQueue& mQueue; MessageQueue& mQueue; Loading @@ -84,9 +90,9 @@ class MessageQueue final : public android::MessageQueue { public: public: explicit Handler(MessageQueue& queue) : mQueue(queue), mEventMask(0) {} explicit Handler(MessageQueue& queue) : mQueue(queue), mEventMask(0) {} virtual void handleMessage(const Message& message); void handleMessage(const Message& message) override; void dispatchRefresh(); virtual void dispatchRefresh(); void dispatchInvalidate(int64_t vsyncId, nsecs_t expectedVSyncTimestamp); virtual void dispatchInvalidate(int64_t vsyncId, nsecs_t expectedVSyncTimestamp); }; }; friend class Handler; friend class Handler; Loading @@ -94,15 +100,33 @@ class MessageQueue final : public android::MessageQueue { sp<SurfaceFlinger> mFlinger; sp<SurfaceFlinger> mFlinger; sp<Looper> mLooper; sp<Looper> mLooper; sp<EventThreadConnection> mEvents; sp<EventThreadConnection> mEvents; struct Vsync { frametimeline::TokenManager* tokenManager = nullptr; std::unique_ptr<scheduler::VSyncCallbackRegistration> registration; std::mutex mutex; TracedOrdinal<std::chrono::nanoseconds> workDuration GUARDED_BY(mutex) = {"VsyncWorkDuration-sf", std::chrono::nanoseconds(0)}; std::chrono::nanoseconds lastCallbackTime GUARDED_BY(mutex) = std::chrono::nanoseconds{0}; TracedOrdinal<int> value = {"VSYNC-sf", 0}; }; Vsync mVsync; gui::BitTube mEventTube; gui::BitTube mEventTube; sp<Handler> mHandler; sp<Handler> mHandler; static int cb_eventReceiver(int fd, int events, void* data); static int cb_eventReceiver(int fd, int events, void* data); int eventReceiver(int fd, int events); int eventReceiver(int fd, int events); void vsyncCallback(nsecs_t vsyncTime, nsecs_t targetWakeupTime, nsecs_t readyTime); public: public: ~MessageQueue() override = default; ~MessageQueue() override = default; void init(const sp<SurfaceFlinger>& flinger) override; void init(const sp<SurfaceFlinger>& flinger) override; void initVsync(scheduler::VSyncDispatch&, frametimeline::TokenManager&, std::chrono::nanoseconds workDuration) override; void setDuration(std::chrono::nanoseconds workDuration) override; void setEventConnection(const sp<EventThreadConnection>& connection) override; void setEventConnection(const sp<EventThreadConnection>& connection) override; void waitMessage() override; void waitMessage() override; Loading
services/surfaceflinger/Scheduler/Scheduler.h +2 −0 Original line number Original line Diff line number Diff line Loading @@ -137,6 +137,8 @@ public: void setDisplayPowerState(bool normal); void setDisplayPowerState(bool normal); scheduler::VSyncDispatch& getVsyncDispatch() { return *mVsyncSchedule.dispatch; } void dump(std::string&) const; void dump(std::string&) const; void dump(ConnectionHandle, std::string&) const; void dump(ConnectionHandle, std::string&) const; void dumpVsync(std::string&) const; void dumpVsync(std::string&) const; Loading
services/surfaceflinger/Scheduler/VSyncDispatch.h +7 −0 Original line number Original line Diff line number Diff line Loading @@ -94,6 +94,13 @@ public: nsecs_t workDuration = 0; nsecs_t workDuration = 0; nsecs_t readyDuration = 0; nsecs_t readyDuration = 0; nsecs_t earliestVsync = 0; nsecs_t earliestVsync = 0; bool operator==(const ScheduleTiming& other) const { return workDuration == other.workDuration && readyDuration == other.readyDuration && earliestVsync == other.earliestVsync; } bool operator!=(const ScheduleTiming& other) const { return !(*this == other); } }; }; /* /* Loading