From 1d5f8af82e975aa94aea41b3fc8d4270663b4720 Mon Sep 17 00:00:00 2001 From: Daniel Stone Date: Fri, 14 Jan 2022 01:02:21 +0000 Subject: [PATCH] gl-renderer: Add hook to fill weston_buffer for EGL Rather than only filling weston_buffer information when we first come to use it, add an explicit hook so we can fill the dimensions the first time the buffer's attached. Signed-off-by: Daniel Stone --- compositor/weston-screenshooter.c | 3 ++- include/libweston/libweston.h | 7 +++++-- libweston/compositor.c | 17 ++++++++++++++-- libweston/renderer-gl/gl-renderer.c | 31 +++++++++++++++++++++-------- 4 files changed, 45 insertions(+), 13 deletions(-) diff --git a/compositor/weston-screenshooter.c b/compositor/weston-screenshooter.c index 18b2dca4..9b437d3c 100644 --- a/compositor/weston-screenshooter.c +++ b/compositor/weston-screenshooter.c @@ -68,8 +68,9 @@ screenshooter_take_shot(struct wl_client *client, { struct weston_output *output = weston_head_from_resource(output_resource)->output; + struct weston_compositor *ec = output->compositor; struct weston_buffer *buffer = - weston_buffer_from_resource(buffer_resource); + weston_buffer_from_resource(ec, buffer_resource); if (buffer == NULL) { wl_resource_post_no_memory(resource); diff --git a/include/libweston/libweston.h b/include/libweston/libweston.h index 76784a4f..974df395 100644 --- a/include/libweston/libweston.h +++ b/include/libweston/libweston.h @@ -934,7 +934,6 @@ struct weston_renderer { float blue, float alpha); void (*destroy)(struct weston_compositor *ec); - /** See weston_surface_get_content_size() */ void (*surface_get_content_size)(struct weston_surface *surface, int *width, int *height); @@ -951,6 +950,9 @@ struct weston_renderer { const struct weston_drm_format_array * (*get_supported_formats)(struct weston_compositor *ec); + + bool (*fill_buffer_info)(struct weston_compositor *ec, + struct weston_buffer *buffer); }; enum weston_capability { @@ -1818,7 +1820,8 @@ weston_surface_copy_content(struct weston_surface *surface, int width, int height); struct weston_buffer * -weston_buffer_from_resource(struct wl_resource *resource); +weston_buffer_from_resource(struct weston_compositor *ec, + struct wl_resource *resource); void weston_compositor_get_time(struct timespec *time); diff --git a/libweston/compositor.c b/libweston/compositor.c index 610f46c1..e9188422 100644 --- a/libweston/compositor.c +++ b/libweston/compositor.c @@ -2385,7 +2385,8 @@ weston_buffer_destroy_handler(struct wl_listener *listener, void *data) } WL_EXPORT struct weston_buffer * -weston_buffer_from_resource(struct wl_resource *resource) +weston_buffer_from_resource(struct weston_compositor *ec, + struct wl_resource *resource) { struct weston_buffer *buffer; struct wl_shm_buffer *shm; @@ -2418,9 +2419,20 @@ weston_buffer_from_resource(struct wl_resource *resource) buffer->height = dmabuf->attributes.height; buffer->y_inverted = !(dmabuf->attributes.flags & ZWP_LINUX_BUFFER_PARAMS_V1_FLAGS_Y_INVERT); + } else { + /* Only taken for legacy EGL buffers */ + if (!ec->renderer->fill_buffer_info || + !ec->renderer->fill_buffer_info(ec, buffer)) { + goto fail; + } } return buffer; + +fail: + wl_list_remove(&buffer->destroy_listener.link); + free(buffer); + return NULL; } static void @@ -3440,10 +3452,11 @@ surface_attach(struct wl_client *client, struct wl_resource *buffer_resource, int32_t sx, int32_t sy) { struct weston_surface *surface = wl_resource_get_user_data(resource); + struct weston_compositor *ec = surface->compositor; struct weston_buffer *buffer = NULL; if (buffer_resource) { - buffer = weston_buffer_from_resource(buffer_resource); + buffer = weston_buffer_from_resource(ec, buffer_resource); if (buffer == NULL) { wl_client_post_no_memory(client); return; diff --git a/libweston/renderer-gl/gl-renderer.c b/libweston/renderer-gl/gl-renderer.c index bf47dd66..72cb3111 100644 --- a/libweston/renderer-gl/gl-renderer.c +++ b/libweston/renderer-gl/gl-renderer.c @@ -2153,6 +2153,28 @@ unsupported: } } +static bool +gl_renderer_fill_buffer_info(struct weston_compositor *ec, + struct weston_buffer *buffer) +{ + struct gl_renderer *gr = get_renderer(ec); + bool ret = true; + + buffer->legacy_buffer = (struct wl_buffer *)buffer->resource; + ret &= gr->query_buffer(gr->egl_display, buffer->legacy_buffer, + EGL_WIDTH, &buffer->width); + ret &= gr->query_buffer(gr->egl_display, buffer->legacy_buffer, + EGL_HEIGHT, &buffer->height); + + /* Assume scanout co-ordinate space i.e. (0,0) is top-left + * if the query fails */ + buffer->y_inverted = true; + gr->query_buffer(gr->egl_display, buffer->legacy_buffer, + EGL_WAYLAND_Y_INVERTED_WL, &buffer->y_inverted); + + return ret; +} + static void gl_renderer_attach_egl(struct weston_surface *es, struct weston_buffer *buffer, uint32_t format) @@ -2164,14 +2186,6 @@ gl_renderer_attach_egl(struct weston_surface *es, struct weston_buffer *buffer, GLenum target; int i, num_planes; - buffer->legacy_buffer = (struct wl_buffer *)buffer->resource; - gr->query_buffer(gr->egl_display, buffer->legacy_buffer, - EGL_WIDTH, &buffer->width); - gr->query_buffer(gr->egl_display, buffer->legacy_buffer, - EGL_HEIGHT, &buffer->height); - gr->query_buffer(gr->egl_display, buffer->legacy_buffer, - EGL_WAYLAND_Y_INVERTED_WL, &buffer->y_inverted); - for (i = 0; i < gs->num_images; i++) { egl_image_unref(gs->images[i]); gs->images[i] = NULL; @@ -3674,6 +3688,7 @@ gl_renderer_display_create(struct weston_compositor *ec, gr->base.surface_get_content_size = gl_renderer_surface_get_content_size; gr->base.surface_copy_content = gl_renderer_surface_copy_content; + gr->base.fill_buffer_info = gl_renderer_fill_buffer_info; if (gl_renderer_setup_egl_display(gr, options->egl_native_display) < 0) goto fail;