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/protocols/core/Compositor.cpp | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) (limited to 'src/protocols/core/Compositor.cpp') diff --git a/src/protocols/core/Compositor.cpp b/src/protocols/core/Compositor.cpp index 3cc04cda..827ec311 100644 --- a/src/protocols/core/Compositor.cpp +++ b/src/protocols/core/Compositor.cpp @@ -10,8 +10,10 @@ #include "../../helpers/sync/SyncReleaser.hpp" #include "../PresentationTime.hpp" #include "../DRMSyncobj.hpp" +#include "../types/DMABuffer.hpp" #include "../../render/Renderer.hpp" #include "config/ConfigValue.hpp" +#include "../../managers/eventLoop/EventLoopManager.hpp" #include "protocols/types/SurfaceRole.hpp" #include "render/Texture.hpp" #include @@ -123,16 +125,15 @@ CWLSurfaceResource::CWLSurfaceResource(SP resource_) : resource(reso return; } - if ((!pending.updated.buffer) || // no new buffer attached - (!pending.buffer && !pending.texture) || // null buffer attached - (!pending.updated.acquire && pending.buffer->isSynchronous()) // synchronous buffers (ex. shm) can be read immediately + if ((!pending.updated.buffer) || // no new buffer attached + (!pending.buffer && !pending.texture) // null buffer attached ) { commitState(pending); pending.reset(); return; } - // save state while we wait for buffer to become ready + // save state while we wait for buffer to become ready to read const auto& state = pendingStates.emplace(makeUnique(pending)); pending.reset(); @@ -152,13 +153,19 @@ CWLSurfaceResource::CWLSurfaceResource(SP resource_) : resource(reso if (state->updated.acquire) { // wait on acquire point for this surface, from explicit sync protocol state->acquire.addWaiter(whenReadable); - } else if (state->buffer->dmabuf().success) { - // https://www.kernel.org/doc/html/latest/driver-api/dma-buf.html#implicit-fence-poll-support - // TODO: wait for the dma-buf fd's to become readable + } else if (state->buffer->isSynchronous()) { + // synchronous (shm) buffers can be read immediately whenReadable(); + } else if (state->buffer->type() == Aquamarine::BUFFER_TYPE_DMABUF && state->buffer->dmabuf().success) { + // async buffer and is dmabuf, then we can wait on implicit fences + auto syncFd = dynamic_cast(state->buffer.buffer.get())->exportSyncFile(); + + if (syncFd.isValid()) + g_pEventLoopManager->doOnReadable(std::move(syncFd), whenReadable); + else + whenReadable(); } else { - // huh??? only buffers with acquire or dmabuf should get through here... - Debug::log(ERR, "BUG THIS: wl_surface.commit: non-acquire non-dmabuf buffers needs wait..."); + Debug::log(ERR, "BUG THIS: wl_surface.commit: no acquire, non-dmabuf, async buffer, needs wait... this shouldn't happen"); whenReadable(); } }); -- cgit v1.2.3