From 6d8029b07e0876de5290fb14c259df9a2d5e65cb Mon Sep 17 00:00:00 2001 From: Simon Zeni Date: Tue, 6 Jul 2021 17:02:04 -0400 Subject: [PATCH] types/wlr_buffer: split wlr_client_buffer_import function `wlr_client_buffer_import` is splitted in two distincts function: - wlr_buffer_from_resource, which transforms a wl_resource into a wlr_buffer - wlr_client_buffer_create, which creates a wlr_client_buffer from a wlr_buffer by creating a texture from it and copying its wl_resource --- include/wlr/types/wlr_buffer.h | 23 +++++++++++++++-------- types/wlr_buffer.c | 22 +++++++++------------- types/wlr_surface.c | 5 +++-- 3 files changed, 27 insertions(+), 23 deletions(-) diff --git a/include/wlr/types/wlr_buffer.h b/include/wlr/types/wlr_buffer.h index c293eb6a..d0df0380 100644 --- a/include/wlr/types/wlr_buffer.h +++ b/include/wlr/types/wlr_buffer.h @@ -14,6 +14,7 @@ #include struct wlr_buffer; +struct wlr_renderer; struct wlr_shm_attributes { int fd; @@ -111,6 +112,14 @@ bool wlr_buffer_get_dmabuf(struct wlr_buffer *buffer, */ bool wlr_buffer_get_shm(struct wlr_buffer *buffer, struct wlr_shm_attributes *attribs); +/** + * Transforms a wl_resource into a wlr_buffer and locks it. Once the caller is + * done with the buffer, they must call wlr_buffer_unlock. + * + * The provided wl_resource must be a wl_buffer. + */ +struct wlr_buffer *wlr_buffer_from_resource(struct wlr_renderer *renderer, + struct wl_resource *resource); /** * A client buffer. @@ -131,7 +140,12 @@ struct wlr_client_buffer { struct wl_listener resource_destroy; }; -struct wlr_renderer; +/** + * Creates a wlr_client_buffer from a given wlr_buffer by creating a texture + * from it, and copying its wl_resource. + */ +struct wlr_client_buffer *wlr_client_buffer_create(struct wlr_buffer *buffer, + struct wlr_renderer *renderer, struct wl_resource *resource); /** * Get a client buffer from a generic buffer. If the buffer isn't a client @@ -147,13 +161,6 @@ bool wlr_resource_is_buffer(struct wl_resource *resource); */ bool wlr_resource_get_buffer_size(struct wl_resource *resource, int *width, int *height); -/** - * Import a client buffer and lock it. - * - * Once the caller is done with the buffer, they must call wlr_buffer_unlock. - */ -struct wlr_client_buffer *wlr_client_buffer_import( - struct wlr_renderer *renderer, struct wl_resource *resource); /** * Try to update the buffer's content. On success, returns the updated buffer * and destroys the provided `buffer`. On error, `buffer` is intact and NULL is diff --git a/types/wlr_buffer.c b/types/wlr_buffer.c index bedd0347..f0d488c7 100644 --- a/types/wlr_buffer.c +++ b/types/wlr_buffer.c @@ -194,9 +194,9 @@ static void client_buffer_resource_handle_destroy(struct wl_listener *listener, // which case we'll read garbage. We decide to accept this risk. } -struct wlr_client_buffer *wlr_client_buffer_import( - struct wlr_renderer *renderer, struct wl_resource *resource) { - assert(wlr_resource_is_buffer(resource)); +struct wlr_buffer *wlr_buffer_from_resource(struct wlr_renderer *renderer, + struct wl_resource *resource) { + assert(resource && wlr_resource_is_buffer(resource)); struct wlr_buffer *buffer; if (wl_shm_buffer_get(resource) != NULL) { @@ -219,16 +219,16 @@ struct wlr_client_buffer *wlr_client_buffer_import( wlr_drm_buffer_from_resource(resource); buffer = wlr_buffer_lock(&drm_buffer->base); } else { - wlr_log(WLR_ERROR, "Cannot upload texture: unknown buffer type"); - - // Instead of just logging the error, also disconnect the client with a - // fatal protocol error so that it's clear something went wrong. - wl_resource_post_error(resource, 0, "unknown buffer type"); + wlr_log(WLR_ERROR, "Unknown buffer type"); return NULL; } + return buffer; +} + +struct wlr_client_buffer *wlr_client_buffer_create(struct wlr_buffer *buffer, + struct wlr_renderer *renderer, struct wl_resource *resource) { struct wlr_texture *texture = wlr_texture_from_buffer(renderer, buffer); - wlr_buffer_unlock(buffer); if (texture == NULL) { wlr_log(WLR_ERROR, "Failed to create texture"); wl_buffer_send_release(resource); @@ -308,10 +308,6 @@ struct wlr_client_buffer *wlr_client_buffer_apply_damage( wl_shm_buffer_end_access(shm_buf); - // We have uploaded the data, we don't need to access the wl_buffer - // anymore - wl_buffer_send_release(resource); - wl_list_remove(&buffer->resource_destroy.link); wl_resource_add_destroy_listener(resource, &buffer->resource_destroy); buffer->resource_destroy.notify = client_buffer_resource_handle_destroy; diff --git a/types/wlr_surface.c b/types/wlr_surface.c index abfcbf73..aa7b3037 100644 --- a/types/wlr_surface.c +++ b/types/wlr_surface.c @@ -365,12 +365,13 @@ static void surface_apply_damage(struct wlr_surface *surface) { } } - struct wlr_client_buffer *buffer = - wlr_client_buffer_import(surface->renderer, resource); + struct wlr_client_buffer *buffer = wlr_client_buffer_create( + surface->current.buffer, surface->renderer, resource); if (buffer == NULL) { wlr_log(WLR_ERROR, "Failed to upload buffer"); return; } + wlr_buffer_unlock(surface->current.buffer); if (surface->buffer != NULL) { wlr_buffer_unlock(&surface->buffer->base);