[gtk/wip/otte/gleanup: 22/27] egl: Get Visual from EGL (XXX DOES NOT WORK XXX)
- From: Benjamin Otte <otte src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk/wip/otte/gleanup: 22/27] egl: Get Visual from EGL (XXX DOES NOT WORK XXX)
- Date: Wed, 30 Jun 2021 03:06:19 +0000 (UTC)
commit 11a2ac70be3191ff516c1e6ea629ea0b2dd9c68b
Author: Benjamin Otte <otte redhat com>
Date: Fri Jun 18 14:46:24 2021 +0200
egl: Get Visual from EGL (XXX DOES NOT WORK XXX)
Query the EGL_VISUAL_ID from the egl Config and select a config with the
matching Visual.
This is broiken because Mesa does not expose any 32bit X Visuals in any
EGL config, so we always end up with opaque Windows.
https://gitlab.freedesktop.org/mesa/mesa/-/issues/149
gdk/x11/gdkdisplay-x11.c | 2 +-
gdk/x11/gdkdisplay-x11.h | 3 --
gdk/x11/gdkglcontext-egl.c | 129 ++++++++++++++++++++++++++++++++++++++++++---
3 files changed, 122 insertions(+), 12 deletions(-)
---
diff --git a/gdk/x11/gdkdisplay-x11.c b/gdk/x11/gdkdisplay-x11.c
index 334f33eb6f..6e9a46ec12 100644
--- a/gdk/x11/gdkdisplay-x11.c
+++ b/gdk/x11/gdkdisplay-x11.c
@@ -1339,7 +1339,7 @@ set_sm_client_id (GdkDisplay *display,
gdk_x11_get_xatom_by_name_for_display (display, "SM_CLIENT_ID"));
}
-void
+static void
gdk_x11_display_query_default_visual (GdkX11Display *self,
Visual **out_visual,
int *out_depth)
diff --git a/gdk/x11/gdkdisplay-x11.h b/gdk/x11/gdkdisplay-x11.h
index 7ef252f0bd..977c4ac4ac 100644
--- a/gdk/x11/gdkdisplay-x11.h
+++ b/gdk/x11/gdkdisplay-x11.h
@@ -177,9 +177,6 @@ struct _GdkX11DisplayClass
const XEvent *event);
};
-void gdk_x11_display_query_default_visual (GdkX11Display *self,
- Visual **out_visual,
- int *out_depth);
void _gdk_x11_display_error_event (GdkDisplay *display,
XErrorEvent *error);
gsize gdk_x11_display_get_max_request_size (GdkDisplay *display);
diff --git a/gdk/x11/gdkglcontext-egl.c b/gdk/x11/gdkglcontext-egl.c
index 61cabceb16..5e48c74a96 100644
--- a/gdk/x11/gdkglcontext-egl.c
+++ b/gdk/x11/gdkglcontext-egl.c
@@ -101,14 +101,54 @@ gdk_x11_display_create_egl_display (GdkX11Display *self)
self->egl_display = eglGetDisplay ((EGLNativeDisplayType) dpy);
}
+static XVisualInfo *
+gdk_x11_display_get_visual_info_for_visual (GdkX11Display *self,
+ VisualID visualid)
+{
+ XVisualInfo template, *visinfo;
+ int nvisuals;
+
+ template.screen = self->screen->screen_num;
+ template.visualid = visualid;
+
+ visinfo = XGetVisualInfo (gdk_x11_display_get_xdisplay (GDK_DISPLAY (self)),
+ VisualScreenMask | VisualIDMask,
+ &template,
+ &nvisuals);
+ g_warn_if_fail (nvisuals == 1);
+
+ return visinfo;
+}
+
+static gboolean
+visual_is_rgba (XVisualInfo *visinfo)
+{
+ return
+ visinfo->depth == 32 &&
+ visinfo->visual->red_mask == 0xff0000 &&
+ visinfo->visual->green_mask == 0x00ff00 &&
+ visinfo->visual->blue_mask == 0x0000ff;
+}
+
#define MAX_EGL_ATTRS 30
static void
-gdk_x11_display_create_egl_config (GdkX11Display *display)
+gdk_x11_display_create_egl_config (GdkX11Display *display,
+ Visual **out_visual,
+ int *out_depth)
{
GdkX11Display *self = GDK_X11_DISPLAY (display);
EGLint attrs[MAX_EGL_ATTRS];
- EGLint count;
+ EGLConfig *configs;
+ EGLint count, alloced;
+ enum {
+ NO_VISUAL_FOUND,
+ WITH_MULTISAMPLING,
+ WITH_STENCIL_AND_DEPTH_BUFFER,
+ NO_ALPHA,
+ NO_ALPHA_VISUAL
+ } best_features;
+
int i = 0;
attrs[i++] = EGL_SURFACE_TYPE;
@@ -129,9 +169,84 @@ gdk_x11_display_create_egl_config (GdkX11Display *display)
attrs[i++] = EGL_NONE;
g_assert (i < MAX_EGL_ATTRS);
- /* Pick first valid configuration that the driver returns us */
- if (!eglChooseConfig (self->egl_display, attrs, &display->egl_config, 1, &count) && count >= 1)
- display->egl_config = NULL;
+ if (!eglChooseConfig (self->egl_display, attrs, NULL, -1, &alloced))
+ return;
+
+ configs = g_new (EGLConfig, alloced);
+ if (!eglChooseConfig (self->egl_display, attrs, configs, alloced, &count))
+ {
+ g_free (configs);
+ return;
+ }
+ g_warn_if_fail (alloced == count);
+
+ best_features = NO_VISUAL_FOUND;
+
+ for (i = 0; i < count; i++)
+ {
+ XVisualInfo *visinfo;
+ int tmp, visualid;
+
+ if (!eglGetConfigAttrib (self->egl_display, configs[i], EGL_NATIVE_VISUAL_ID, &visualid))
+ continue;
+
+ visinfo = gdk_x11_display_get_visual_info_for_visual (self, visualid);
+ if (visinfo == NULL)
+ continue;
+
+ if (!eglGetConfigAttrib (self->egl_display, configs[i], EGL_SAMPLE_BUFFERS, &tmp) || tmp != 0)
+ {
+ g_print ("config %u for visual 0x%lX has multisampling\n", i, visinfo->visualid);
+ if (best_features < WITH_MULTISAMPLING)
+ {
+ best_features = WITH_MULTISAMPLING;
+ *out_visual = visinfo->visual;
+ *out_depth = visinfo->depth;
+ self->egl_config = configs[i];
+ }
+ XFree (visinfo);
+ continue;
+ }
+
+ if (!eglGetConfigAttrib (self->egl_display, configs[i], EGL_DEPTH_SIZE, &tmp) || tmp != 0 ||
+ !eglGetConfigAttrib (self->egl_display, configs[i], EGL_STENCIL_SIZE, &tmp) || tmp != 0)
+ {
+ g_print ("config %u for visual 0x%lX has a stencil or depth buffer\n", i, visinfo->visualid);
+ if (best_features < WITH_STENCIL_AND_DEPTH_BUFFER)
+ {
+ best_features = WITH_STENCIL_AND_DEPTH_BUFFER;
+ *out_visual = visinfo->visual;
+ *out_depth = visinfo->depth;
+ self->egl_config = configs[i];
+ }
+ XFree (visinfo);
+ continue;
+ }
+
+ if (!visual_is_rgba (visinfo))
+ {
+ g_print ("config %u for visual 0x%lX has no RGBA Visual\n", i, visinfo->visualid);
+ if (best_features < NO_ALPHA_VISUAL)
+ {
+ best_features = NO_ALPHA_VISUAL;
+ *out_visual = visinfo->visual;
+ *out_depth = visinfo->depth;
+ self->egl_config = configs[i];
+ }
+ XFree (visinfo);
+ continue;
+ }
+
+ g_print ("config %u for visual 0x%lX is the perfect choice\n", i, visinfo->visualid);
+ /* everything is perfect */
+ *out_visual = visinfo->visual;
+ *out_depth = visinfo->depth;
+ self->egl_config = configs[i];
+ XFree (visinfo);
+ break;
+ }
+
+ g_free (configs);
}
#undef MAX_EGL_ATTRS
@@ -478,7 +593,7 @@ gdk_x11_display_init_egl (GdkX11Display *self,
return FALSE;
}
- gdk_x11_display_create_egl_config (self);
+ gdk_x11_display_create_egl_config (self, out_visual, out_depth);
if (self->egl_config == NULL)
{
eglTerminate (self->egl_display);
@@ -515,8 +630,6 @@ gdk_x11_display_init_egl (GdkX11Display *self,
self->has_egl_swap_buffers_with_damage ? "yes" : "no",
self->has_egl_surfaceless_context ? "yes" : "no"));
- gdk_x11_display_query_default_visual (self, out_visual, out_depth);
-
return TRUE;
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]