From 90a19074b4e1d4d8f8ababaade8170c05aeecffe Mon Sep 17 00:00:00 2001 From: Hal Gentz Date: Thu, 10 Oct 2019 18:35:50 -0600 Subject: [PATCH] egl: Fixes transparency with EGL and X11. This commit does this by allowing both RGB and RGBA visuals to match with EGL configs. We also expose the `EGL_MESA_config_select_group` egl extension, which is similar to GLX's visual select group extension, to allow the RGBA visuals to get less priority. Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=67676 Fixes: 049f343e8ac "egl: Allow 24-bit visuals for 32-bit RGBA8888 configs" Cc: mesa-stable@lists.freedesktop.org Reviewed-by: Adam Jackson Signed-off-by: Hal Gentz --- include/GL/internal/dri_interface.h | 3 ++- src/egl/drivers/dri2/egl_dri2.c | 4 ++++ src/egl/drivers/dri2/platform_x11.c | 29 +++++++++++++---------------- src/egl/main/eglconfig.c | 9 +++++++++ src/egl/main/eglconfig.h | 2 ++ src/egl/main/eglglobals.c | 3 ++- src/mesa/drivers/dri/common/utils.c | 2 ++ src/mesa/main/mtypes.h | 3 +++ 8 files changed, 37 insertions(+), 18 deletions(-) diff --git a/include/GL/internal/dri_interface.h b/include/GL/internal/dri_interface.h index f19ec5168a5..718b7dde87c 100644 --- a/include/GL/internal/dri_interface.h +++ b/include/GL/internal/dri_interface.h @@ -813,7 +813,8 @@ struct __DRIuseInvalidateExtensionRec { #define __DRI_ATTRIB_GREEN_SHIFT 51 #define __DRI_ATTRIB_BLUE_SHIFT 52 #define __DRI_ATTRIB_ALPHA_SHIFT 53 -#define __DRI_ATTRIB_MAX 54 +#define __DRI_ATTRIB_CONFIG_SELECT_GROUP 54 +#define __DRI_ATTRIB_MAX 55 /* __DRI_ATTRIB_RENDER_TYPE */ #define __DRI_ATTRIB_RGBA_BIT 0x01 diff --git a/src/egl/drivers/dri2/egl_dri2.c b/src/egl/drivers/dri2/egl_dri2.c index 23d0e469427..63864346594 100644 --- a/src/egl/drivers/dri2/egl_dri2.c +++ b/src/egl/drivers/dri2/egl_dri2.c @@ -187,6 +187,7 @@ static const EGLint dri2_to_egl_attribute_map[__DRI_ATTRIB_MAX] = { [__DRI_ATTRIB_MAX_SWAP_INTERVAL] = EGL_MAX_SWAP_INTERVAL, [__DRI_ATTRIB_MIN_SWAP_INTERVAL] = EGL_MIN_SWAP_INTERVAL, [__DRI_ATTRIB_YINVERTED] = EGL_Y_INVERTED_NOK, + [__DRI_ATTRIB_CONFIG_SELECT_GROUP] = EGL_CONFIG_SELECT_GROUP_MESA, }; const __DRIconfig * @@ -202,6 +203,9 @@ dri2_get_dri_config(struct dri2_egl_config *conf, EGLint surface_type, static EGLBoolean dri2_match_config(const _EGLConfig *conf, const _EGLConfig *criteria) { + if (conf->NativeVisualID != criteria->NativeVisualID) + return EGL_FALSE; + if (_eglCompareConfigs(conf, criteria, NULL, EGL_FALSE) != 0) return EGL_FALSE; diff --git a/src/egl/drivers/dri2/platform_x11.c b/src/egl/drivers/dri2/platform_x11.c index 5a1e2f31890..414d5f74c5d 100644 --- a/src/egl/drivers/dri2/platform_x11.c +++ b/src/egl/drivers/dri2/platform_x11.c @@ -816,28 +816,25 @@ dri2_x11_add_configs_for_visuals(struct dri2_egl_display *dri2_dpy, if (dri2_conf->base.ConfigID == config_count + 1) config_count++; - /* Allow a 24-bit RGB visual to match a 32-bit RGBA EGLConfig. - * Ditto for 30-bit RGB visuals to match a 32-bit RGBA EGLConfig. + /* Allows RGB visuals to match a 32-bit RGBA EGLConfig. * Otherwise it will only match a 32-bit RGBA visual. On a * composited window manager on X11, this will make all of the * EGLConfigs with destination alpha get blended by the * compositor. This is probably not what the application * wants... especially on drivers that only have 32-bit RGBA * EGLConfigs! */ - if (d.data->depth == 24 || d.data->depth == 30) { - unsigned int rgba_mask = ~(visuals[i].red_mask | - visuals[i].green_mask | - visuals[i].blue_mask); - rgba_shifts[3] = ffs(rgba_mask) - 1; - rgba_sizes[3] = util_bitcount(rgba_mask); - dri2_conf = dri2_add_config(disp, config, config_count + 1, - surface_type, config_attrs, - rgba_shifts, rgba_sizes); - if (dri2_conf) - if (dri2_conf->base.ConfigID == config_count + 1) - config_count++; - } - } + unsigned int rgba_mask = ~(visuals[i].red_mask | + visuals[i].green_mask | + visuals[i].blue_mask); + rgba_shifts[3] = ffs(rgba_mask) - 1; + rgba_sizes[3] = util_bitcount(rgba_mask); + dri2_conf = dri2_add_config(disp, config, config_count + 1, + surface_type, config_attrs, + rgba_shifts, rgba_sizes); + if (dri2_conf) + if (dri2_conf->base.ConfigID == config_count + 1) + config_count++; + } } xcb_depth_next(&d); diff --git a/src/egl/main/eglconfig.c b/src/egl/main/eglconfig.c index 0a95e8ee05d..b3362363664 100644 --- a/src/egl/main/eglconfig.c +++ b/src/egl/main/eglconfig.c @@ -258,6 +258,9 @@ static const struct { { EGL_COLOR_COMPONENT_TYPE_EXT, ATTRIB_TYPE_ENUM, ATTRIB_CRITERION_EXACT, EGL_COLOR_COMPONENT_TYPE_FIXED_EXT }, + { EGL_CONFIG_SELECT_GROUP_MESA, ATTRIB_TYPE_INTEGER, + ATTRIB_CRITERION_IGNORE, + 0 }, }; @@ -296,6 +299,8 @@ _eglValidateConfig(const _EGLConfig *conf, EGLBoolean for_matching) if (val > 1 || val < 0) valid = EGL_FALSE; break; + case EGL_CONFIG_SELECT_GROUP_MESA: + break; default: if (val < 0) valid = EGL_FALSE; @@ -608,6 +613,10 @@ _eglCompareConfigs(const _EGLConfig *conf1, const _EGLConfig *conf2, if (conf1 == conf2) return 0; + val1 = conf1->ConfigSelectGroup - conf2->ConfigSelectGroup; + if (val1) + return val1; + /* the enum values have the desired ordering */ STATIC_ASSERT(EGL_NONE < EGL_SLOW_CONFIG); STATIC_ASSERT(EGL_SLOW_CONFIG < EGL_NON_CONFORMANT_CONFIG); diff --git a/src/egl/main/eglconfig.h b/src/egl/main/eglconfig.h index 605289de536..064187ff1dd 100644 --- a/src/egl/main/eglconfig.h +++ b/src/egl/main/eglconfig.h @@ -89,6 +89,7 @@ struct _egl_config EGLint FramebufferTargetAndroid; EGLint RecordableAndroid; EGLint ComponentType; + EGLint ConfigSelectGroup; }; @@ -139,6 +140,7 @@ _eglOffsetOfConfig(EGLint attr) ATTRIB_MAP(EGL_FRAMEBUFFER_TARGET_ANDROID, FramebufferTargetAndroid); ATTRIB_MAP(EGL_RECORDABLE_ANDROID, RecordableAndroid); ATTRIB_MAP(EGL_COLOR_COMPONENT_TYPE_EXT, ComponentType); + ATTRIB_MAP(EGL_CONFIG_SELECT_GROUP_MESA, ConfigSelectGroup); #undef ATTRIB_MAP default: return -1; diff --git a/src/egl/main/eglglobals.c b/src/egl/main/eglglobals.c index 0d7270333ec..71d1fccf75f 100644 --- a/src/egl/main/eglglobals.c +++ b/src/egl/main/eglglobals.c @@ -70,7 +70,8 @@ struct _egl_global _eglGlobal = " EGL_EXT_device_query" " EGL_EXT_platform_base" " EGL_KHR_client_get_all_proc_addresses" - " EGL_KHR_debug", + " EGL_KHR_debug" + " EGL_MESA_config_select_group", .PlatformExtensionString = #ifdef HAVE_WAYLAND_PLATFORM diff --git a/src/mesa/drivers/dri/common/utils.c b/src/mesa/drivers/dri/common/utils.c index 0fdca2d9d84..2d57aef18f2 100644 --- a/src/mesa/drivers/dri/common/utils.c +++ b/src/mesa/drivers/dri/common/utils.c @@ -379,6 +379,7 @@ driCreateConfigs(mesa_format format, modes->yInverted = GL_TRUE; modes->sRGBCapable = is_srgb; modes->mutableRenderBuffer = mutable_render_buffer; + modes->configSelectGroup = 0; } } } @@ -468,6 +469,7 @@ static const struct { unsigned int attrib, offset; } attribMap[] = { __ATTRIB(__DRI_ATTRIB_YINVERTED, yInverted), __ATTRIB(__DRI_ATTRIB_FRAMEBUFFER_SRGB_CAPABLE, sRGBCapable), __ATTRIB(__DRI_ATTRIB_MUTABLE_RENDER_BUFFER, mutableRenderBuffer), + __ATTRIB(__DRI_ATTRIB_CONFIG_SELECT_GROUP, configSelectGroup), /* The struct field doesn't matter here, these are handled by the * switch in driGetConfigAttribIndex. We need them in the array diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h index ae93dff40da..2397ca6b74f 100644 --- a/src/mesa/main/mtypes.h +++ b/src/mesa/main/mtypes.h @@ -211,6 +211,9 @@ struct gl_config /* EGL_KHR_mutable_render_buffer */ GLuint mutableRenderBuffer; /* bool */ + + /* EGL_MESA_config_select_group */ + GLint configSelectGroup; }; -- 2.30.2