From 24b5d9131672233dfb7d4f03785905e1b494c9e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Molinari?= Date: Fri, 22 Nov 2024 17:08:30 +0100 Subject: [PATCH] gl-renderer: Get legacy EGL buffers info from YUV formats table MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Automatise variant and planes selection for legacy EGL buffers support by using the global information from the YUV formats table and setup texture swizzles for legacy EGL buffers and dma-buf. Signed-off-by: Loïc Molinari --- libweston/renderer-gl/gl-renderer.c | 71 ++++++++++++++++++++--------- 1 file changed, 49 insertions(+), 22 deletions(-) diff --git a/libweston/renderer-gl/gl-renderer.c b/libweston/renderer-gl/gl-renderer.c index 60bc2a5c8..011324ed4 100644 --- a/libweston/renderer-gl/gl-renderer.c +++ b/libweston/renderer-gl/gl-renderer.c @@ -2908,7 +2908,9 @@ ensure_textures(struct gl_buffer_state *gb, GLenum target, int num_textures) for (i = 0; i < num_textures; i++) gl_texture_parameters_init(gb->gr, &gb->parameters[i], target, - NULL, NULL, NULL, false); + NULL, NULL, + gb->texture_format[i].swizzles.array, + false); } static void @@ -3071,10 +3073,10 @@ gl_renderer_fill_buffer_info(struct weston_compositor *ec, struct gl_renderer *gr = get_renderer(ec); struct gl_buffer_state *gb; EGLint format; - uint32_t fourcc = DRM_FORMAT_INVALID; + uint32_t fourcc; GLenum target; EGLint y_inverted; - bool ret = true; + bool rgb, ret = true; int i; /* Ensure that EGL_WL_bind_wayland_display (and EGL_KHR_image_base) is @@ -3108,36 +3110,25 @@ gl_renderer_fill_buffer_info(struct weston_compositor *ec, * TEXTURE_EXTERNAL_OES. */ switch (format) { case EGL_TEXTURE_RGB: - fourcc = DRM_FORMAT_XRGB8888; - gb->num_images = 1; - gb->shader_variant = SHADER_VARIANT_RGBA; - gb->texture_format[0].swizzles.a = GL_ONE; + fourcc = DRM_FORMAT_XBGR8888; + rgb = true; break; case EGL_TEXTURE_RGBA: - fourcc = DRM_FORMAT_ARGB8888; - gb->num_images = 1; - gb->shader_variant = SHADER_VARIANT_RGBA; - gb->texture_format[0].swizzles.a = GL_ALPHA; - break; case EGL_TEXTURE_EXTERNAL_WL: - fourcc = DRM_FORMAT_ARGB8888; - gb->num_images = 1; - gb->shader_variant = SHADER_VARIANT_EXTERNAL; + fourcc = DRM_FORMAT_ABGR8888; + rgb = true; break; case EGL_TEXTURE_Y_XUXV_WL: fourcc = DRM_FORMAT_YUYV; - gb->num_images = 2; - gb->shader_variant = SHADER_VARIANT_Y_XUXV; + rgb = false; break; case EGL_TEXTURE_Y_UV_WL: fourcc = DRM_FORMAT_NV12; - gb->num_images = 2; - gb->shader_variant = SHADER_VARIANT_Y_UV; + rgb = false; break; case EGL_TEXTURE_Y_U_V_WL: fourcc = DRM_FORMAT_YUV420; - gb->num_images = 3; - gb->shader_variant = SHADER_VARIANT_Y_U_V; + rgb = false; break; default: assert(0 && "not reached"); @@ -3147,6 +3138,33 @@ gl_renderer_fill_buffer_info(struct weston_compositor *ec, assert(buffer->pixel_format); buffer->format_modifier = DRM_FORMAT_MOD_INVALID; + /* Initialise buffer state. No need to fill format and type info since + * textures are wrapped by EGL images. Swizzles must be set for correct + * sampling though. */ + if (rgb) { + ARRAY_COPY(gb->texture_format[0].swizzles.array, + buffer->pixel_format->gl.swizzles.array); + gb->shader_variant = format == EGL_TEXTURE_EXTERNAL_WL ? + SHADER_VARIANT_EXTERNAL : SHADER_VARIANT_RGBA; + gb->num_images = 1; + } else { + struct yuv_format_descriptor *desc = NULL; + + for (i = 0; i < (int) ARRAY_LENGTH(yuv_formats); i++) { + if (fourcc == yuv_formats[i].format) { + desc = &yuv_formats[i]; + break; + } + } + assert(desc); + + for (i = 0; i < desc->output_planes; i++) + ARRAY_COPY(gb->texture_format[i].swizzles.array, + desc->plane[i].swizzles.array); + gb->shader_variant = desc->shader_variant; + gb->num_images = desc->output_planes; + } + /* Assume scanout co-ordinate space i.e. (0,0) is top-left * if the query fails */ ret = gr->query_buffer(gr->egl_display, buffer->legacy_buffer, @@ -3378,6 +3396,11 @@ import_yuv_dmabuf(struct gl_renderer *gr, struct gl_buffer_state *gb, } for (j = 0; j < format->output_planes; ++j) { + /* Swizzles must be set for correct sampling in YUV dma-buf + * fallback mode. */ + ARRAY_COPY(gb->texture_format[j].swizzles.array, + format->plane[j].swizzles.array); + gb->images[j] = import_dmabuf_single_plane(gr, info, j, attributes, &format->plane[j]); if (gb->images[j] == EGL_NO_IMAGE_KHR) { @@ -3501,15 +3524,19 @@ import_dmabuf(struct gl_renderer *gr, egl_image = import_simple_dmabuf(gr, &dmabuf->attributes); if (egl_image != EGL_NO_IMAGE_KHR) { + const GLint swizzles[] = { GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA }; GLenum target = choose_texture_target(gr, &dmabuf->attributes); gb->num_images = 1; gb->images[0] = egl_image; + /* The driver defines its own swizzles internally in the case of + * a successful dma-buf import so just set default values. */ + ARRAY_COPY(gb->texture_format[0].swizzles.array, swizzles); + switch (target) { case GL_TEXTURE_2D: gb->shader_variant = SHADER_VARIANT_RGBA; - gb->texture_format[0].swizzles.a = GL_ALPHA; break; default: gb->shader_variant = SHADER_VARIANT_EXTERNAL;