From 0e521788bcc414c9cf81648d3167757d83deb60f Mon Sep 17 00:00:00 2001 From: Ikalco <73481042+ikalco@users.noreply.github.com> Date: Tue, 15 Apr 2025 18:02:31 -0500 Subject: core: wait for dmabuf readiness (#9806) * add doOnReadable to event loop manager * move syncTimeline addWaiter to doOnReadable * wait on dmabuf buffers to be readable * don't over synchronize in scanout, also give present feedback on same buffer commit --- src/managers/eventLoop/EventLoopManager.cpp | 42 +++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) (limited to 'src/managers/eventLoop/EventLoopManager.cpp') diff --git a/src/managers/eventLoop/EventLoopManager.cpp b/src/managers/eventLoop/EventLoopManager.cpp index 83bdf4a0..d1245bbf 100644 --- a/src/managers/eventLoop/EventLoopManager.cpp +++ b/src/managers/eventLoop/EventLoopManager.cpp @@ -26,6 +26,11 @@ CEventLoopManager::~CEventLoopManager() { wl_event_source_remove(eventSourceData.eventSource); } + for (auto const& w : m_vReadableWaiters) { + if (w->source != nullptr) + wl_event_source_remove(w->source); + } + if (m_sWayland.eventSource) wl_event_source_remove(m_sWayland.eventSource); if (m_sIdle.eventSource) @@ -50,6 +55,33 @@ static int configWatcherWrite(int fd, uint32_t mask, void* data) { return 0; } +static int handleWaiterFD(int fd, uint32_t mask, void* data) { + if (mask & (WL_EVENT_HANGUP | WL_EVENT_ERROR)) { + Debug::log(ERR, "handleWaiterFD: readable waiter error"); + return 0; + } + + if (mask & WL_EVENT_READABLE) + g_pEventLoopManager->onFdReadable((CEventLoopManager::SReadableWaiter*)data); + + return 0; +} + +void CEventLoopManager::onFdReadable(SReadableWaiter* waiter) { + auto it = std::ranges::find_if(m_vReadableWaiters, [waiter](const UP& w) { return waiter == w.get() && w->fd == waiter->fd && w->source == waiter->source; }); + + if (waiter->source) { + wl_event_source_remove(waiter->source); + waiter->source = nullptr; + } + + if (waiter->fn) + waiter->fn(); + + if (it != m_vReadableWaiters.end()) + m_vReadableWaiters.erase(it); +} + void CEventLoopManager::enterLoop() { m_sWayland.eventSource = wl_event_loop_add_fd(m_sWayland.loop, m_sTimers.timerfd.get(), WL_EVENT_READABLE, timerWrite, nullptr); @@ -143,6 +175,16 @@ void CEventLoopManager::doLater(const std::function& fn) { &m_sIdle); } +void CEventLoopManager::doOnReadable(CFileDescriptor fd, const std::function& fn) { + if (!fd.isValid() || fd.isReadable()) { + fn(); + return; + } + + auto& waiter = m_vReadableWaiters.emplace_back(makeUnique(nullptr, std::move(fd), fn)); + waiter->source = wl_event_loop_add_fd(g_pEventLoopManager->m_sWayland.loop, waiter->fd.get(), WL_EVENT_READABLE, ::handleWaiterFD, waiter.get()); +} + void CEventLoopManager::syncPollFDs() { auto aqPollFDs = g_pCompositor->m_pAqBackend->getPollFDs(); -- cgit v1.2.3