Loading services/surfaceflinger/Scheduler/MessageQueue.cpp +40 −24 Original line number Diff line number Diff line Loading @@ -69,17 +69,33 @@ void MessageQueue::init(const sp<SurfaceFlinger>& flinger) { // TODO(b/169865816): refactor VSyncInjections to use MessageQueue directly // and remove the EventThread from MessageQueue void MessageQueue::setEventConnection(const sp<EventThreadConnection>& connection) { if (mEventTube.getFd() >= 0) { mLooper->removeFd(mEventTube.getFd()); void MessageQueue::setInjector(sp<EventThreadConnection> connection) { auto& tube = mInjector.tube; if (const int fd = tube.getFd(); fd >= 0) { mLooper->removeFd(fd); } mEvents = connection; if (mEvents) { mEvents->stealReceiveChannel(&mEventTube); mLooper->addFd(mEventTube.getFd(), 0, Looper::EVENT_INPUT, MessageQueue::cb_eventReceiver, if (connection) { // The EventThreadConnection is retained when disabling injection, so avoid subsequently // stealing invalid FDs. Note that the stolen FDs are kept open. if (tube.getFd() < 0) { connection->stealReceiveChannel(&tube); } else { ALOGW("Recycling channel for VSYNC injection."); } mLooper->addFd( tube.getFd(), 0, Looper::EVENT_INPUT, [](int, int, void* data) { reinterpret_cast<MessageQueue*>(data)->injectorCallback(); return 1; // Keep registration. }, this); } std::lock_guard lock(mInjector.mutex); mInjector.connection = std::move(connection); } void MessageQueue::vsyncCallback(nsecs_t vsyncTime, nsecs_t targetWakeupTime, nsecs_t readyTime) { Loading Loading @@ -149,29 +165,31 @@ void MessageQueue::postMessage(sp<MessageHandler>&& handler) { void MessageQueue::invalidate() { ATRACE_CALL(); if (mEvents) { mEvents->requestNextVsync(); } else { { std::lock_guard lock(mInjector.mutex); if (CC_UNLIKELY(mInjector.connection)) { ALOGD("%s while injecting VSYNC", __FUNCTION__); mInjector.connection->requestNextVsync(); return; } } std::lock_guard lock(mVsync.mutex); mVsync.mScheduled = true; mVsync.registration->schedule({mVsync.workDuration.get().count(), /*readyDuration=*/0, mVsync.lastCallbackTime.count()}); } mVsync.registration->schedule({.workDuration = mVsync.workDuration.get().count(), .readyDuration = 0, .earliestVsync = mVsync.lastCallbackTime.count()}); } void MessageQueue::refresh() { mHandler->dispatchRefresh(); } int MessageQueue::cb_eventReceiver(int fd, int events, void* data) { MessageQueue* queue = reinterpret_cast<MessageQueue*>(data); return queue->eventReceiver(fd, events); } int MessageQueue::eventReceiver(int /*fd*/, int /*events*/) { void MessageQueue::injectorCallback() { ssize_t n; DisplayEventReceiver::Event buffer[8]; while ((n = DisplayEventReceiver::getEvents(&mEventTube, buffer, 8)) > 0) { while ((n = DisplayEventReceiver::getEvents(&mInjector.tube, buffer, 8)) > 0) { for (int i = 0; i < n; i++) { if (buffer[i].header.type == DisplayEventReceiver::DISPLAY_EVENT_VSYNC) { mHandler->dispatchInvalidate(buffer[i].vsync.vsyncId, Loading @@ -180,8 +198,6 @@ int MessageQueue::eventReceiver(int /*fd*/, int /*events*/) { } } } return 1; } } // namespace android::impl services/surfaceflinger/Scheduler/MessageQueue.h +13 −10 Original line number Diff line number Diff line Loading @@ -21,12 +21,11 @@ #include <type_traits> #include <utility> #include <utils/Looper.h> #include <utils/Timers.h> #include <utils/threads.h> #include <android-base/thread_annotations.h> #include <gui/IDisplayEventConnection.h> #include <private/gui/BitTube.h> #include <utils/Looper.h> #include <utils/Timers.h> #include "EventThread.h" #include "TracedOrdinal.h" Loading Loading @@ -68,7 +67,7 @@ public: 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 setInjector(sp<EventThreadConnection>) = 0; virtual void waitMessage() = 0; virtual void postMessage(sp<MessageHandler>&&) = 0; virtual void invalidate() = 0; Loading Loading @@ -99,7 +98,6 @@ protected: sp<SurfaceFlinger> mFlinger; sp<Looper> mLooper; sp<EventThreadConnection> mEvents; struct Vsync { frametimeline::TokenManager* tokenManager = nullptr; Loading @@ -113,14 +111,19 @@ protected: TracedOrdinal<int> value = {"VSYNC-sf", 0}; }; struct Injector { gui::BitTube tube; std::mutex mutex; sp<EventThreadConnection> connection GUARDED_BY(mutex); }; Vsync mVsync; Injector mInjector; gui::BitTube mEventTube; sp<Handler> mHandler; static int cb_eventReceiver(int fd, int events, void* data); int eventReceiver(int fd, int events); void vsyncCallback(nsecs_t vsyncTime, nsecs_t targetWakeupTime, nsecs_t readyTime); void injectorCallback(); public: ~MessageQueue() override = default; Loading @@ -128,7 +131,7 @@ public: 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 setInjector(sp<EventThreadConnection>) override; void waitMessage() override; void postMessage(sp<MessageHandler>&&) override; Loading services/surfaceflinger/Scheduler/Scheduler.cpp +4 −0 Original line number Diff line number Diff line Loading @@ -436,6 +436,10 @@ Scheduler::ConnectionHandle Scheduler::enableVSyncInjection(bool enable) { impl::EventThread::InterceptVSyncsCallback(), impl::EventThread::ThrottleVsyncCallback()); // EventThread does not dispatch VSYNC unless the display is connected and powered on. eventThread->onHotplugReceived(PhysicalDisplayId::fromPort(0), true); eventThread->onScreenAcquired(); mInjectorConnectionHandle = createConnection(std::move(eventThread)); } Loading services/surfaceflinger/SurfaceFlinger.cpp +1 −2 Original line number Diff line number Diff line Loading @@ -1431,8 +1431,7 @@ status_t SurfaceFlinger::enableVSyncInjections(bool enable) { Mutex::Autolock lock(mStateLock); if (const auto handle = mScheduler->enableVSyncInjection(enable)) { mEventQueue->setEventConnection(enable ? mScheduler->getEventConnection(handle) : nullptr); mEventQueue->setInjector(enable ? mScheduler->getEventConnection(handle) : nullptr); } }).wait(); Loading services/surfaceflinger/tests/fakehwc/FakeComposerClient.cpp +1 −0 Original line number Diff line number Diff line Loading @@ -907,6 +907,7 @@ void FakeComposerClient::onSurfaceFlingerStart() { } void FakeComposerClient::onSurfaceFlingerStop() { mSurfaceComposer->enableVSyncInjections(false); mSurfaceComposer->dispose(); mSurfaceComposer.clear(); } Loading Loading
services/surfaceflinger/Scheduler/MessageQueue.cpp +40 −24 Original line number Diff line number Diff line Loading @@ -69,17 +69,33 @@ void MessageQueue::init(const sp<SurfaceFlinger>& flinger) { // TODO(b/169865816): refactor VSyncInjections to use MessageQueue directly // and remove the EventThread from MessageQueue void MessageQueue::setEventConnection(const sp<EventThreadConnection>& connection) { if (mEventTube.getFd() >= 0) { mLooper->removeFd(mEventTube.getFd()); void MessageQueue::setInjector(sp<EventThreadConnection> connection) { auto& tube = mInjector.tube; if (const int fd = tube.getFd(); fd >= 0) { mLooper->removeFd(fd); } mEvents = connection; if (mEvents) { mEvents->stealReceiveChannel(&mEventTube); mLooper->addFd(mEventTube.getFd(), 0, Looper::EVENT_INPUT, MessageQueue::cb_eventReceiver, if (connection) { // The EventThreadConnection is retained when disabling injection, so avoid subsequently // stealing invalid FDs. Note that the stolen FDs are kept open. if (tube.getFd() < 0) { connection->stealReceiveChannel(&tube); } else { ALOGW("Recycling channel for VSYNC injection."); } mLooper->addFd( tube.getFd(), 0, Looper::EVENT_INPUT, [](int, int, void* data) { reinterpret_cast<MessageQueue*>(data)->injectorCallback(); return 1; // Keep registration. }, this); } std::lock_guard lock(mInjector.mutex); mInjector.connection = std::move(connection); } void MessageQueue::vsyncCallback(nsecs_t vsyncTime, nsecs_t targetWakeupTime, nsecs_t readyTime) { Loading Loading @@ -149,29 +165,31 @@ void MessageQueue::postMessage(sp<MessageHandler>&& handler) { void MessageQueue::invalidate() { ATRACE_CALL(); if (mEvents) { mEvents->requestNextVsync(); } else { { std::lock_guard lock(mInjector.mutex); if (CC_UNLIKELY(mInjector.connection)) { ALOGD("%s while injecting VSYNC", __FUNCTION__); mInjector.connection->requestNextVsync(); return; } } std::lock_guard lock(mVsync.mutex); mVsync.mScheduled = true; mVsync.registration->schedule({mVsync.workDuration.get().count(), /*readyDuration=*/0, mVsync.lastCallbackTime.count()}); } mVsync.registration->schedule({.workDuration = mVsync.workDuration.get().count(), .readyDuration = 0, .earliestVsync = mVsync.lastCallbackTime.count()}); } void MessageQueue::refresh() { mHandler->dispatchRefresh(); } int MessageQueue::cb_eventReceiver(int fd, int events, void* data) { MessageQueue* queue = reinterpret_cast<MessageQueue*>(data); return queue->eventReceiver(fd, events); } int MessageQueue::eventReceiver(int /*fd*/, int /*events*/) { void MessageQueue::injectorCallback() { ssize_t n; DisplayEventReceiver::Event buffer[8]; while ((n = DisplayEventReceiver::getEvents(&mEventTube, buffer, 8)) > 0) { while ((n = DisplayEventReceiver::getEvents(&mInjector.tube, buffer, 8)) > 0) { for (int i = 0; i < n; i++) { if (buffer[i].header.type == DisplayEventReceiver::DISPLAY_EVENT_VSYNC) { mHandler->dispatchInvalidate(buffer[i].vsync.vsyncId, Loading @@ -180,8 +198,6 @@ int MessageQueue::eventReceiver(int /*fd*/, int /*events*/) { } } } return 1; } } // namespace android::impl
services/surfaceflinger/Scheduler/MessageQueue.h +13 −10 Original line number Diff line number Diff line Loading @@ -21,12 +21,11 @@ #include <type_traits> #include <utility> #include <utils/Looper.h> #include <utils/Timers.h> #include <utils/threads.h> #include <android-base/thread_annotations.h> #include <gui/IDisplayEventConnection.h> #include <private/gui/BitTube.h> #include <utils/Looper.h> #include <utils/Timers.h> #include "EventThread.h" #include "TracedOrdinal.h" Loading Loading @@ -68,7 +67,7 @@ public: 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 setInjector(sp<EventThreadConnection>) = 0; virtual void waitMessage() = 0; virtual void postMessage(sp<MessageHandler>&&) = 0; virtual void invalidate() = 0; Loading Loading @@ -99,7 +98,6 @@ protected: sp<SurfaceFlinger> mFlinger; sp<Looper> mLooper; sp<EventThreadConnection> mEvents; struct Vsync { frametimeline::TokenManager* tokenManager = nullptr; Loading @@ -113,14 +111,19 @@ protected: TracedOrdinal<int> value = {"VSYNC-sf", 0}; }; struct Injector { gui::BitTube tube; std::mutex mutex; sp<EventThreadConnection> connection GUARDED_BY(mutex); }; Vsync mVsync; Injector mInjector; gui::BitTube mEventTube; sp<Handler> mHandler; static int cb_eventReceiver(int fd, int events, void* data); int eventReceiver(int fd, int events); void vsyncCallback(nsecs_t vsyncTime, nsecs_t targetWakeupTime, nsecs_t readyTime); void injectorCallback(); public: ~MessageQueue() override = default; Loading @@ -128,7 +131,7 @@ public: 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 setInjector(sp<EventThreadConnection>) override; void waitMessage() override; void postMessage(sp<MessageHandler>&&) override; Loading
services/surfaceflinger/Scheduler/Scheduler.cpp +4 −0 Original line number Diff line number Diff line Loading @@ -436,6 +436,10 @@ Scheduler::ConnectionHandle Scheduler::enableVSyncInjection(bool enable) { impl::EventThread::InterceptVSyncsCallback(), impl::EventThread::ThrottleVsyncCallback()); // EventThread does not dispatch VSYNC unless the display is connected and powered on. eventThread->onHotplugReceived(PhysicalDisplayId::fromPort(0), true); eventThread->onScreenAcquired(); mInjectorConnectionHandle = createConnection(std::move(eventThread)); } Loading
services/surfaceflinger/SurfaceFlinger.cpp +1 −2 Original line number Diff line number Diff line Loading @@ -1431,8 +1431,7 @@ status_t SurfaceFlinger::enableVSyncInjections(bool enable) { Mutex::Autolock lock(mStateLock); if (const auto handle = mScheduler->enableVSyncInjection(enable)) { mEventQueue->setEventConnection(enable ? mScheduler->getEventConnection(handle) : nullptr); mEventQueue->setInjector(enable ? mScheduler->getEventConnection(handle) : nullptr); } }).wait(); Loading
services/surfaceflinger/tests/fakehwc/FakeComposerClient.cpp +1 −0 Original line number Diff line number Diff line Loading @@ -907,6 +907,7 @@ void FakeComposerClient::onSurfaceFlingerStart() { } void FakeComposerClient::onSurfaceFlingerStop() { mSurfaceComposer->enableVSyncInjections(false); mSurfaceComposer->dispose(); mSurfaceComposer.clear(); } Loading