From 7e6f55f336b68dab71185253de4d1e4c22f9ef4a Mon Sep 17 00:00:00 2001 From: Daniel Stone Date: Fri, 23 Feb 2024 11:45:15 +0000 Subject: [PATCH] egl/wayland: Fix EGL_EXT_present_opaque This extension has been broken ever since the initial commit. It created an XRGB DRIImage for the driver to render to, so whilst the presentation was opaque, the buffer also completely lacked an alpha channel. Fix it by making sure we only modify the FourCC we send to the Wayland server when creating a buffer. Closes: mesa/mesa#5886 Fixes: 9aee7855d2dd ("egl: implement EGL_EXT_present_opaque on wayland") Part-of: (cherry picked from commit 9ea9a963aa142910ed3a0fcea9060d3a92ee5ab7) --- .pick_status.json | 2 +- src/egl/drivers/dri2/platform_wayland.c | 61 ++++++------------------- 2 files changed, 15 insertions(+), 48 deletions(-) diff --git a/.pick_status.json b/.pick_status.json index 64482bf2177..66ab91119f3 100644 --- a/.pick_status.json +++ b/.pick_status.json @@ -474,7 +474,7 @@ "description": "egl/wayland: Fix EGL_EXT_present_opaque", "nominated": true, "nomination_type": 1, - "resolution": 0, + "resolution": 1, "main_sha": null, "because_sha": "9aee7855d2ddf47169270d5d1e3e92ff6e5f65c2", "notes": null diff --git a/src/egl/drivers/dri2/platform_wayland.c b/src/egl/drivers/dri2/platform_wayland.c index d243b6f1e5d..00d53e9b3fe 100644 --- a/src/egl/drivers/dri2/platform_wayland.c +++ b/src/egl/drivers/dri2/platform_wayland.c @@ -246,7 +246,7 @@ static const struct dri2_wl_visual { static int dri2_wl_visual_idx_from_config(struct dri2_egl_display *dri2_dpy, - const __DRIconfig *config, bool force_opaque) + const __DRIconfig *config) { int shifts[4]; unsigned int sizes[4]; @@ -256,16 +256,13 @@ dri2_wl_visual_idx_from_config(struct dri2_egl_display *dri2_dpy, for (unsigned int i = 0; i < ARRAY_SIZE(dri2_wl_visuals); i++) { const struct dri2_wl_visual *wl_visual = &dri2_wl_visuals[i]; - int cmp_rgb_shifts = - memcmp(shifts, wl_visual->rgba_shifts, 3 * sizeof(shifts[0])); - int cmp_rgb_sizes = - memcmp(sizes, wl_visual->rgba_sizes, 3 * sizeof(sizes[0])); + int cmp_rgba_shifts = + memcmp(shifts, wl_visual->rgba_shifts, 4 * sizeof(shifts[0])); + int cmp_rgba_sizes = + memcmp(sizes, wl_visual->rgba_sizes, 4 * sizeof(sizes[0])); - if (cmp_rgb_shifts == 0 && cmp_rgb_sizes == 0 && - wl_visual->rgba_shifts[3] == (force_opaque ? -1 : shifts[3]) && - wl_visual->rgba_sizes[3] == (force_opaque ? 0 : sizes[3])) { + if (cmp_rgba_shifts == 0 && cmp_rgba_sizes == 0) return i; - } } return -1; @@ -318,7 +315,7 @@ dri2_wl_is_format_supported(void *user_data, uint32_t format) for (int i = 0; dri2_dpy->driver_configs[i]; i++) if (j == dri2_wl_visual_idx_from_config( - dri2_dpy, dri2_dpy->driver_configs[i], false)) + dri2_dpy, dri2_dpy->driver_configs[i])) return true; return false; @@ -726,43 +723,10 @@ dri2_wl_create_window_surface(_EGLDisplay *disp, _EGLConfig *conf, dri2_surf->base.Width = window->width; dri2_surf->base.Height = window->height; -#ifndef NDEBUG - /* Enforce that every visual has an opaque variant (requirement to support - * EGL_EXT_present_opaque) - */ - for (unsigned int i = 0; i < ARRAY_SIZE(dri2_wl_visuals); i++) { - const struct dri2_wl_visual *transparent_visual = &dri2_wl_visuals[i]; - if (transparent_visual->rgba_sizes[3] == 0) { - continue; - } - - bool found_opaque_equivalent = false; - for (unsigned int j = 0; j < ARRAY_SIZE(dri2_wl_visuals); j++) { - const struct dri2_wl_visual *opaque_visual = &dri2_wl_visuals[j]; - if (opaque_visual->rgba_sizes[3] != 0) { - continue; - } - - int cmp_rgb_shifts = - memcmp(transparent_visual->rgba_shifts, opaque_visual->rgba_shifts, - 3 * sizeof(opaque_visual->rgba_shifts[0])); - int cmp_rgb_sizes = - memcmp(transparent_visual->rgba_sizes, opaque_visual->rgba_sizes, - 3 * sizeof(opaque_visual->rgba_sizes[0])); - - if (cmp_rgb_shifts == 0 && cmp_rgb_sizes == 0) { - found_opaque_equivalent = true; - break; - } - } - - assert(found_opaque_equivalent); - } -#endif - - visual_idx = dri2_wl_visual_idx_from_config(dri2_dpy, config, - dri2_surf->base.PresentOpaque); + visual_idx = dri2_wl_visual_idx_from_config(dri2_dpy, config); assert(visual_idx != -1); + assert(dri2_wl_visuals[visual_idx].dri_image_format != + __DRI_IMAGE_FORMAT_NONE); if (dri2_dpy->wl_dmabuf || dri2_dpy->wl_drm) { dri2_surf->format = dri2_wl_visuals[visual_idx].wl_drm_format; @@ -1517,6 +1481,9 @@ create_wl_buffer(struct dri2_egl_display *dri2_dpy, close(fd); } + if (dri2_surf && dri2_surf->base.PresentOpaque) + fourcc = dri2_wl_visuals[visual_idx].opaque_wl_drm_format; + ret = zwp_linux_buffer_params_v1_create_immed(params, width, height, fourcc, 0); zwp_linux_buffer_params_v1_destroy(params); @@ -2100,7 +2067,7 @@ dri2_wl_add_configs_for_visuals(_EGLDisplay *disp) /* No match for config. Try if we can blitImage convert to a visual */ c = dri2_wl_visual_idx_from_config(dri2_dpy, - dri2_dpy->driver_configs[i], false); + dri2_dpy->driver_configs[i]); if (c == -1) continue;