From e797e5a324f1b4e30447a70c2700c10604ec6c6c Mon Sep 17 00:00:00 2001 From: Kirill Primak Date: Fri, 9 Aug 2024 15:57:45 +0300 Subject: [PATCH] output: make swapchain lazy --- src/dulcepan.h | 1 + src/output.c | 38 +++++++++++++++++++++----------------- 2 files changed, 22 insertions(+), 17 deletions(-) diff --git a/src/dulcepan.h b/src/dulcepan.h index 073d860..007dd9a 100644 --- a/src/dulcepan.h +++ b/src/dulcepan.h @@ -71,6 +71,7 @@ struct dp_output { void *frame_data; size_t frame_size; + // wl_buffer is NULL if uninitialized struct dp_buffer swapchain[DP_SWAPCHAIN_LEN]; struct wl_list link; diff --git a/src/output.c b/src/output.c index 224f801..c286468 100644 --- a/src/output.c +++ b/src/output.c @@ -126,6 +126,19 @@ static const struct wl_buffer_listener buffer_listener = { .release = buffer_handle_release, }; +static void init_buffer(struct dp_output *output, struct dp_buffer *buffer) { + int stride = output->transformed_width * 4; + + buffer->wl_buffer = + dp_buffer_create(output->state, output->transformed_width, output->transformed_height, + stride, WL_SHM_FORMAT_ARGB8888, &buffer->data, &buffer->size); + buffer->cairo_surface = cairo_image_surface_create_for_data(buffer->data, CAIRO_FORMAT_ARGB32, + output->transformed_width, output->transformed_height, stride); + buffer->cairo = cairo_create(buffer->cairo_surface); + + wl_buffer_add_listener(buffer->wl_buffer, &buffer_listener, buffer); +} + static void output_handle_geometry(void *data, struct wl_output *wl_output, int32_t x, int32_t y, int32_t phys_width, int32_t phys_height, int32_t subpixel, const char *make, const char *model, int32_t transform) { @@ -208,19 +221,6 @@ static void output_handle_done(void *data, struct wl_output *wl_output) { wl_subsurface_set_desync(output->select_subsurface); wl_surface_set_user_data(output->select_surface, output); - - for (size_t i = 0; i < DP_SWAPCHAIN_LEN; i++) { - struct dp_buffer *buffer = &output->swapchain[i]; - int stride = output->transformed_width * 4; - buffer->wl_buffer = - dp_buffer_create(state, output->transformed_width, output->transformed_height, - stride, WL_SHM_FORMAT_ARGB8888, &buffer->data, &buffer->size); - buffer->cairo_surface = cairo_image_surface_create_for_data(buffer->data, - CAIRO_FORMAT_ARGB32, output->transformed_width, output->transformed_height, stride); - buffer->cairo = cairo_create(buffer->cairo_surface); - - wl_buffer_add_listener(buffer->wl_buffer, &buffer_listener, buffer); - } } static void output_handle_scale(void *data, struct wl_output *wl_output, int32_t scale) { @@ -330,6 +330,8 @@ static void redraw(struct dp_output *output) { if (buffer == NULL) { dp_log_error("Output %s: no free buffers in a swapchain\n", output->name); return; + } else if (buffer->wl_buffer == NULL) { + init_buffer(output, buffer); } buffer->used = true; @@ -438,10 +440,12 @@ void dp_output_destroy(struct dp_output *output) { for (size_t i = 0; i < DP_SWAPCHAIN_LEN; i++) { struct dp_buffer *buffer = &output->swapchain[i]; - wl_buffer_destroy(buffer->wl_buffer); - cairo_destroy(buffer->cairo); - cairo_surface_destroy(buffer->cairo_surface); - munmap(buffer->data, buffer->size); + if (buffer->wl_buffer != NULL) { + wl_buffer_destroy(buffer->wl_buffer); + cairo_destroy(buffer->cairo); + cairo_surface_destroy(buffer->cairo_surface); + munmap(buffer->data, buffer->size); + } } wl_subsurface_destroy(output->select_subsurface);