From d3b461c0d2451b6873b344990ed2c7127ac6865d Mon Sep 17 00:00:00 2001 From: Simon Ser Date: Tue, 4 Jul 2023 13:41:25 +0200 Subject: [PATCH] linux-dmabuf-v1: add wlr_compositor_dmabuf_waiter_create() --- include/wlr/types/wlr_linux_dmabuf_v1.h | 6 +++ types/wlr_linux_dmabuf_v1.c | 54 +++++++++++++++++++++++++ 2 files changed, 60 insertions(+) diff --git a/include/wlr/types/wlr_linux_dmabuf_v1.h b/include/wlr/types/wlr_linux_dmabuf_v1.h index 581ff1f3c..d06ec09b4 100644 --- a/include/wlr/types/wlr_linux_dmabuf_v1.h +++ b/include/wlr/types/wlr_linux_dmabuf_v1.h @@ -16,6 +16,7 @@ #include #include +struct wlr_compositor; struct wlr_surface; struct wlr_dmabuf_v1_buffer { @@ -158,5 +159,10 @@ void wlr_surface_dmabuf_waiter_init(struct wlr_surface_dmabuf_waiter *waiter, * immediately. */ void wlr_surface_dmabuf_waiter_finish(struct wlr_surface_dmabuf_waiter *waiter); +/** + * Initialize a compositor-wide DMA-BUF waiter, which will listen for new + * surfaces and attach DMA-BUF surface waiters to them. + */ +void wlr_compositor_dmabuf_waiter_create(struct wlr_compositor *compositor); #endif diff --git a/types/wlr_linux_dmabuf_v1.c b/types/wlr_linux_dmabuf_v1.c index 23a7dc0b4..479109695 100644 --- a/types/wlr_linux_dmabuf_v1.c +++ b/types/wlr_linux_dmabuf_v1.c @@ -1292,3 +1292,57 @@ void wlr_surface_dmabuf_waiter_finish(struct wlr_surface_dmabuf_waiter *waiter) wl_list_remove(&waiter->commits); wl_list_remove(&waiter->client_commit.link); } + +struct wlr_compositor_dmabuf_waiter { + struct wl_listener new_surface; + struct wl_listener destroy; +}; + +struct wlr_compositor_dmabuf_waiter_surface { + struct wlr_surface_dmabuf_waiter base; + struct wl_listener destroy; +}; + +static void compositor_dmabuf_waiter_surface_handle_destroy(struct wl_listener *listener, void *data) { + struct wlr_compositor_dmabuf_waiter_surface *waiter_surface = + wl_container_of(listener, waiter_surface, destroy); + wlr_surface_dmabuf_waiter_finish(&waiter_surface->base); + wl_list_remove(&waiter_surface->destroy.link); + free(waiter_surface); +} + +static void compositor_dmabuf_waiter_handle_new_surface(struct wl_listener *listener, void *data) { + struct wlr_surface *surface = data; + + struct wlr_compositor_dmabuf_waiter_surface *waiter_surface = calloc(1, sizeof(*waiter_surface)); + if (waiter_surface == NULL) { + wlr_log(WLR_ERROR, "Allocation failed"); + return; + } + + wlr_surface_dmabuf_waiter_init(&waiter_surface->base, surface); + + waiter_surface->destroy.notify = compositor_dmabuf_waiter_surface_handle_destroy; + wl_signal_add(&surface->events.destroy, &waiter_surface->destroy); +} + +static void compositor_dmabuf_waiter_handle_destroy(struct wl_listener *listener, void *data) { + struct wlr_compositor_dmabuf_waiter *waiter = + wl_container_of(listener, waiter, destroy); + wl_list_remove(&waiter->new_surface.link); + wl_list_remove(&waiter->destroy.link); + free(waiter); +} + +void wlr_compositor_dmabuf_waiter_create(struct wlr_compositor *compositor) { + struct wlr_compositor_dmabuf_waiter *waiter = calloc(1, sizeof(*waiter)); + if (waiter == NULL) { + wlr_log(WLR_ERROR, "Allocation failed"); + return; + } + + waiter->new_surface.notify = compositor_dmabuf_waiter_handle_new_surface; + wl_signal_add(&compositor->events.new_surface, &waiter->new_surface); + waiter->destroy.notify = compositor_dmabuf_waiter_handle_destroy; + wl_signal_add(&compositor->events.destroy, &waiter->destroy); +}