From 827ea06c443c60a8697255b375880ca3f6181252 Mon Sep 17 00:00:00 2001 From: Kenny Levinsen Date: Sun, 7 Jul 2024 13:31:56 +0200 Subject: [PATCH] render/swapchain: Add-on to get swapchain from buffer This can be used to cache things shared between render buffers (e.g., blending buffers) on the swapchain instance itself. --- include/wlr/render/swapchain.h | 6 +++++ render/swapchain.c | 44 ++++++++++++++++++++++++++++++++++ 2 files changed, 50 insertions(+) diff --git a/include/wlr/render/swapchain.h b/include/wlr/render/swapchain.h index 2317f1b62..5537efc73 100644 --- a/include/wlr/render/swapchain.h +++ b/include/wlr/render/swapchain.h @@ -4,6 +4,7 @@ #include #include #include +#include #define WLR_SWAPCHAIN_CAP 4 @@ -23,6 +24,8 @@ struct wlr_swapchain { struct wlr_swapchain_slot slots[WLR_SWAPCHAIN_CAP]; struct wl_listener allocator_destroy; + + struct wlr_addon_set addons; }; struct wlr_swapchain *wlr_swapchain_create( @@ -43,4 +46,7 @@ struct wlr_buffer *wlr_swapchain_acquire(struct wlr_swapchain *swapchain); bool wlr_swapchain_has_buffer(struct wlr_swapchain *swapchain, struct wlr_buffer *buffer); +struct wlr_swapchain *wlr_swapchain_try_from_wlr_buffer( + struct wlr_buffer *buffer); + #endif diff --git a/render/swapchain.c b/render/swapchain.c index 233d85eb0..0fecba1ce 100644 --- a/render/swapchain.c +++ b/render/swapchain.c @@ -6,6 +6,36 @@ #include "render/allocator/allocator.h" #include "render/drm_format_set.h" +struct wlr_swapchain_buffer { + struct wlr_addon buffer_addon; + struct wlr_swapchain *swapchain; +}; + +static void wlr_swapchain_buffer_destroy(struct wlr_addon *addon) { + struct wlr_swapchain_buffer *swapchain_buffer = + wl_container_of(addon, swapchain_buffer, buffer_addon); + wlr_addon_finish(&swapchain_buffer->buffer_addon); + swapchain_buffer->swapchain = NULL; + free(swapchain_buffer); +} + +static const struct wlr_addon_interface buffer_addon_impl = { + .name = "wlr_swapchain_buffer", + .destroy = wlr_swapchain_buffer_destroy, +}; + +struct wlr_swapchain *wlr_swapchain_try_from_wlr_buffer(struct wlr_buffer *buffer) { + struct wlr_addon *addon = + wlr_addon_find(&buffer->addons, NULL, &buffer_addon_impl); + if (addon == NULL) { + return NULL; + } + + struct wlr_swapchain_buffer *swapchain_buffer = + wl_container_of(addon, swapchain_buffer, buffer_addon); + return swapchain_buffer->swapchain; +} + static void swapchain_handle_allocator_destroy(struct wl_listener *listener, void *data) { struct wlr_swapchain *swapchain = @@ -33,6 +63,7 @@ struct wlr_swapchain *wlr_swapchain_create( swapchain->allocator_destroy.notify = swapchain_handle_allocator_destroy; wl_signal_add(&alloc->events.destroy, &swapchain->allocator_destroy); + wlr_addon_set_init(&swapchain->addons); return swapchain; } @@ -54,6 +85,7 @@ void wlr_swapchain_destroy(struct wlr_swapchain *swapchain) { } wl_list_remove(&swapchain->allocator_destroy.link); wlr_drm_format_finish(&swapchain->format); + wlr_addon_set_finish(&swapchain->addons); free(swapchain); } @@ -98,13 +130,25 @@ struct wlr_buffer *wlr_swapchain_acquire(struct wlr_swapchain *swapchain) { return NULL; } + struct wlr_swapchain_buffer *swapchain_buffer = + calloc(1, sizeof(*swapchain_buffer)); + if (swapchain_buffer == NULL) { + return NULL; + } + swapchain_buffer->swapchain = swapchain; + wlr_log(WLR_DEBUG, "Allocating new swapchain buffer"); free_slot->buffer = wlr_allocator_create_buffer(swapchain->allocator, swapchain->width, swapchain->height, &swapchain->format); if (free_slot->buffer == NULL) { wlr_log(WLR_ERROR, "Failed to allocate buffer"); + free(swapchain_buffer); return NULL; } + + wlr_addon_init(&swapchain_buffer->buffer_addon, &free_slot->buffer->addons, + NULL, &buffer_addon_impl); + return slot_acquire(swapchain, free_slot); }