mirror of
https://gitlab.gnome.org/GNOME/gtk.git
synced 2025-01-13 05:50:10 +00:00
gdk: Make sure only one GL backend is used
Creative people managed to create an X11 display and a Wayland display at once, thereby getting EGL and GLX involved in a fight to the death over the ownership of the glFoo() symbolspace. A way to force such a fight with available tools here is (on Wayland) running something like: GTK_INSPECTOR_DISPLAY=:1 GTK_DEBUG=interactive gtk4-demo Related: xdg-desktop-portal-gnome#5
This commit is contained in:
parent
d7db3f1546
commit
23acc993cc
@ -1233,6 +1233,8 @@ gdk_display_init_gl (GdkDisplay *self)
|
|||||||
*/
|
*/
|
||||||
priv->gl_context = context;
|
priv->gl_context = context;
|
||||||
|
|
||||||
|
gdk_gl_backend_use (GDK_GL_CONTEXT_GET_CLASS (context)->backend_type);
|
||||||
|
|
||||||
gdk_profiler_end_mark (before, "initialize OpenGL", NULL);
|
gdk_profiler_end_mark (before, "initialize OpenGL", NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -75,11 +75,13 @@
|
|||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
|
||||||
#include "gdkglcontextprivate.h"
|
#include "gdkglcontextprivate.h"
|
||||||
#include "gdkdisplayprivate.h"
|
|
||||||
#include "gdkmemorytextureprivate.h"
|
|
||||||
#include "gdkinternals.h"
|
|
||||||
|
|
||||||
|
#include "gdkdebug.h"
|
||||||
|
#include "gdkdisplayprivate.h"
|
||||||
|
#include "gdkinternals.h"
|
||||||
#include "gdkintl.h"
|
#include "gdkintl.h"
|
||||||
|
#include "gdkmemorytextureprivate.h"
|
||||||
|
|
||||||
#include "gdk-private.h"
|
#include "gdk-private.h"
|
||||||
|
|
||||||
#ifdef GDK_WINDOWING_WIN32
|
#ifdef GDK_WINDOWING_WIN32
|
||||||
@ -1354,3 +1356,68 @@ gdk_gl_context_use_es_bgra (GdkGLContext *context)
|
|||||||
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static GdkGLBackend the_gl_backend_type = GDK_GL_NONE;
|
||||||
|
|
||||||
|
static const char *gl_backend_names[] = {
|
||||||
|
[GDK_GL_NONE] = "No GL (You should never read this)",
|
||||||
|
[GDK_GL_EGL] = "EGL",
|
||||||
|
[GDK_GL_GLX] = "X11 GLX",
|
||||||
|
[GDK_GL_WGL] = "Windows WGL",
|
||||||
|
[GDK_GL_CGL] = "Apple CGL"
|
||||||
|
};
|
||||||
|
|
||||||
|
/*<private>
|
||||||
|
* gdk_gl_backend_can_be_used:
|
||||||
|
* @backend_type: Type of backend to check
|
||||||
|
* @error: Return location for an error
|
||||||
|
*
|
||||||
|
* Checks if this backend type can be used. When multiple displays
|
||||||
|
* are opened that use different GL backends, conflicts can arise,
|
||||||
|
* so this function checks that all displays use compatible GL
|
||||||
|
* backends.
|
||||||
|
*
|
||||||
|
* Returns: %TRUE if the backend can still be used
|
||||||
|
*/
|
||||||
|
gboolean
|
||||||
|
gdk_gl_backend_can_be_used (GdkGLBackend backend_type,
|
||||||
|
GError **error)
|
||||||
|
{
|
||||||
|
if (the_gl_backend_type == GDK_GL_NONE ||
|
||||||
|
the_gl_backend_type == backend_type)
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
g_set_error (error, GDK_GL_ERROR, GDK_GL_ERROR_NOT_AVAILABLE,
|
||||||
|
/* translators: This is about OpenGL backend names, like
|
||||||
|
* "Trying to use X11 GLX, but EGL is already in use" */
|
||||||
|
_("Trying to use %s, but %s is already in use"),
|
||||||
|
gl_backend_names[backend_type],
|
||||||
|
gl_backend_names[the_gl_backend_type]);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*<private>
|
||||||
|
* gdk_gl_backend_use:
|
||||||
|
* @backend_type: Type of backend
|
||||||
|
*
|
||||||
|
* Ensures that the backend in use is the given one. If another backend
|
||||||
|
* is already in use, this function will abort the program. It should
|
||||||
|
* have previously checked via gdk_gl_backend_can_be_used().
|
||||||
|
**/
|
||||||
|
void
|
||||||
|
gdk_gl_backend_use (GdkGLBackend backend_type)
|
||||||
|
{
|
||||||
|
/* Check that the context class is properly initializing its backend type */
|
||||||
|
g_assert (backend_type != GDK_GL_NONE);
|
||||||
|
|
||||||
|
if (the_gl_backend_type == GDK_GL_NONE)
|
||||||
|
{
|
||||||
|
the_gl_backend_type = backend_type;
|
||||||
|
/* This is important!!!11eleven
|
||||||
|
* (But really: How do I print a message in 2 categories?) */
|
||||||
|
GDK_NOTE (OPENGL, g_print ("Using OpenGL backend %s\n", gl_backend_names[the_gl_backend_type]));
|
||||||
|
GDK_NOTE (MISC, g_message ("Using Opengl backend %s", gl_backend_names[the_gl_backend_type]));
|
||||||
|
}
|
||||||
|
|
||||||
|
g_assert (the_gl_backend_type == backend_type);
|
||||||
|
}
|
||||||
|
@ -34,6 +34,14 @@ G_BEGIN_DECLS
|
|||||||
#define GDK_EGL_MIN_VERSION_MAJOR (1)
|
#define GDK_EGL_MIN_VERSION_MAJOR (1)
|
||||||
#define GDK_EGL_MIN_VERSION_MINOR (4)
|
#define GDK_EGL_MIN_VERSION_MINOR (4)
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
GDK_GL_NONE = 0,
|
||||||
|
GDK_GL_EGL,
|
||||||
|
GDK_GL_GLX,
|
||||||
|
GDK_GL_WGL,
|
||||||
|
GDK_GL_CGL
|
||||||
|
} GdkGLBackend;
|
||||||
|
|
||||||
#define GDK_GL_CONTEXT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GDK_TYPE_GL_CONTEXT, GdkGLContextClass))
|
#define GDK_GL_CONTEXT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GDK_TYPE_GL_CONTEXT, GdkGLContextClass))
|
||||||
#define GDK_IS_GL_CONTEXT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GDK_TYPE_GL_CONTEXT))
|
#define GDK_IS_GL_CONTEXT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GDK_TYPE_GL_CONTEXT))
|
||||||
#define GDK_GL_CONTEXT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GDK_TYPE_GL_CONTEXT, GdkGLContextClass))
|
#define GDK_GL_CONTEXT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GDK_TYPE_GL_CONTEXT, GdkGLContextClass))
|
||||||
@ -52,6 +60,8 @@ struct _GdkGLContextClass
|
|||||||
{
|
{
|
||||||
GdkDrawContextClass parent_class;
|
GdkDrawContextClass parent_class;
|
||||||
|
|
||||||
|
GdkGLBackend backend_type;
|
||||||
|
|
||||||
gboolean (* realize) (GdkGLContext *context,
|
gboolean (* realize) (GdkGLContext *context,
|
||||||
GError **error);
|
GError **error);
|
||||||
|
|
||||||
@ -86,6 +96,10 @@ typedef struct {
|
|||||||
guint use_es : 1;
|
guint use_es : 1;
|
||||||
} GdkGLContextPaintData;
|
} GdkGLContextPaintData;
|
||||||
|
|
||||||
|
gboolean gdk_gl_backend_can_be_used (GdkGLBackend backend_type,
|
||||||
|
GError **error);
|
||||||
|
void gdk_gl_backend_use (GdkGLBackend backend_type);
|
||||||
|
|
||||||
GdkGLContext * gdk_gl_context_new_for_surface (GdkSurface *surface);
|
GdkGLContext * gdk_gl_context_new_for_surface (GdkSurface *surface);
|
||||||
|
|
||||||
void gdk_gl_context_set_is_legacy (GdkGLContext *context,
|
void gdk_gl_context_set_is_legacy (GdkGLContext *context,
|
||||||
|
@ -641,6 +641,9 @@ static GdkGLContext *
|
|||||||
gdk_macos_display_init_gl (GdkDisplay *display,
|
gdk_macos_display_init_gl (GdkDisplay *display,
|
||||||
GError **error)
|
GError **error)
|
||||||
{
|
{
|
||||||
|
if (!gdk_gl_backend_can_be_used (GDK_GL_CGL, error))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
return g_object_new (GDK_TYPE_MACOS_GL_CONTEXT,
|
return g_object_new (GDK_TYPE_MACOS_GL_CONTEXT,
|
||||||
"display", display,
|
"display", display,
|
||||||
NULL);
|
NULL);
|
||||||
|
@ -515,6 +515,8 @@ gdk_macos_gl_context_class_init (GdkMacosGLContextClass *klass)
|
|||||||
|
|
||||||
gl_class->get_damage = gdk_macos_gl_context_get_damage;
|
gl_class->get_damage = gdk_macos_gl_context_get_damage;
|
||||||
gl_class->realize = gdk_macos_gl_context_real_realize;
|
gl_class->realize = gdk_macos_gl_context_real_realize;
|
||||||
|
|
||||||
|
gl_class->backend_type = GDK_GL_CGL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -358,6 +358,8 @@ gdk_wayland_gl_context_class_init (GdkWaylandGLContextClass *klass)
|
|||||||
context_class->make_current = gdk_wayland_gl_context_make_current;
|
context_class->make_current = gdk_wayland_gl_context_make_current;
|
||||||
context_class->clear_current = gdk_wayland_gl_context_clear_current;
|
context_class->clear_current = gdk_wayland_gl_context_clear_current;
|
||||||
context_class->get_damage = gdk_wayland_gl_context_get_damage;
|
context_class->get_damage = gdk_wayland_gl_context_get_damage;
|
||||||
|
|
||||||
|
context_class->backend_type = GDK_GL_EGL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -475,6 +477,9 @@ gdk_wayland_display_init_gl (GdkDisplay *display,
|
|||||||
G_GNUC_UNUSED gint64 start_time = GDK_PROFILER_CURRENT_TIME;
|
G_GNUC_UNUSED gint64 start_time = GDK_PROFILER_CURRENT_TIME;
|
||||||
G_GNUC_UNUSED gint64 start_time2;
|
G_GNUC_UNUSED gint64 start_time2;
|
||||||
|
|
||||||
|
if (!gdk_gl_backend_can_be_used (GDK_GL_EGL, error))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
if (!epoxy_has_egl ())
|
if (!epoxy_has_egl ())
|
||||||
{
|
{
|
||||||
gboolean sandboxed = gdk_running_in_sandbox ();
|
gboolean sandboxed = gdk_running_in_sandbox ();
|
||||||
|
@ -256,6 +256,9 @@ gdk_win32_display_init_egl (GdkDisplay *display,
|
|||||||
int best_idx = 0;
|
int best_idx = 0;
|
||||||
EGLDisplay egl_disp;
|
EGLDisplay egl_disp;
|
||||||
|
|
||||||
|
if (!gdk_gl_backend_can_be_used (GDK_GL_EGL, error))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
if (display_win32->egl_disp != EGL_NO_DISPLAY)
|
if (display_win32->egl_disp != EGL_NO_DISPLAY)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
@ -488,6 +491,8 @@ gdk_win32_gl_context_egl_class_init (GdkWin32GLContextClass *klass)
|
|||||||
GdkDrawContextClass *draw_context_class = GDK_DRAW_CONTEXT_CLASS(klass);
|
GdkDrawContextClass *draw_context_class = GDK_DRAW_CONTEXT_CLASS(klass);
|
||||||
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
||||||
|
|
||||||
|
context_class->backend_type = GDK_GL_EGL;
|
||||||
|
|
||||||
context_class->realize = gdk_win32_gl_context_egl_realize;
|
context_class->realize = gdk_win32_gl_context_egl_realize;
|
||||||
context_class->make_current = gdk_win32_gl_context_egl_make_current;
|
context_class->make_current = gdk_win32_gl_context_egl_make_current;
|
||||||
context_class->clear_current = gdk_win32_gl_context_egl_clear_current;
|
context_class->clear_current = gdk_win32_gl_context_egl_clear_current;
|
||||||
|
@ -265,6 +265,9 @@ gdk_win32_display_init_wgl (GdkDisplay *display,
|
|||||||
GdkWin32Display *display_win32 = GDK_WIN32_DISPLAY (display);
|
GdkWin32Display *display_win32 = GDK_WIN32_DISPLAY (display);
|
||||||
HDC hdc;
|
HDC hdc;
|
||||||
|
|
||||||
|
if (!gdk_gl_backend_can_be_used (GDK_GL_WGL, error))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
if (display_win32->wgl_pixel_format != 0)
|
if (display_win32->wgl_pixel_format != 0)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
@ -697,6 +700,8 @@ gdk_win32_gl_context_wgl_class_init (GdkWin32GLContextWGLClass *klass)
|
|||||||
GdkDrawContextClass *draw_context_class = GDK_DRAW_CONTEXT_CLASS (klass);
|
GdkDrawContextClass *draw_context_class = GDK_DRAW_CONTEXT_CLASS (klass);
|
||||||
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
||||||
|
|
||||||
|
context_class->backend_type = GDK_GL_WGL;
|
||||||
|
|
||||||
context_class->realize = gdk_win32_gl_context_wgl_realize;
|
context_class->realize = gdk_win32_gl_context_wgl_realize;
|
||||||
context_class->make_current = gdk_win32_gl_context_wgl_make_current;
|
context_class->make_current = gdk_win32_gl_context_wgl_make_current;
|
||||||
context_class->clear_current = gdk_win32_gl_context_wgl_clear_current;
|
context_class->clear_current = gdk_win32_gl_context_wgl_clear_current;
|
||||||
|
@ -642,6 +642,8 @@ gdk_x11_gl_context_egl_class_init (GdkX11GLContextEGLClass *klass)
|
|||||||
GdkDrawContextClass *draw_context_class = GDK_DRAW_CONTEXT_CLASS (klass);
|
GdkDrawContextClass *draw_context_class = GDK_DRAW_CONTEXT_CLASS (klass);
|
||||||
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
||||||
|
|
||||||
|
context_class->backend_type = GDK_GL_EGL;
|
||||||
|
|
||||||
context_class->realize = gdk_x11_gl_context_egl_realize;
|
context_class->realize = gdk_x11_gl_context_egl_realize;
|
||||||
context_class->make_current = gdk_x11_gl_context_egl_make_current;
|
context_class->make_current = gdk_x11_gl_context_egl_make_current;
|
||||||
context_class->clear_current = gdk_x11_gl_context_egl_clear_current;
|
context_class->clear_current = gdk_x11_gl_context_egl_clear_current;
|
||||||
@ -670,6 +672,9 @@ gdk_x11_display_init_egl (GdkX11Display *self,
|
|||||||
Display *dpy;
|
Display *dpy;
|
||||||
int major, minor;
|
int major, minor;
|
||||||
|
|
||||||
|
if (!gdk_gl_backend_can_be_used (GDK_GL_EGL, error))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
dpy = gdk_x11_display_get_xdisplay (display);
|
dpy = gdk_x11_display_get_xdisplay (display);
|
||||||
|
|
||||||
if (!epoxy_has_egl ())
|
if (!epoxy_has_egl ())
|
||||||
|
@ -692,6 +692,8 @@ gdk_x11_gl_context_glx_class_init (GdkX11GLContextGLXClass *klass)
|
|||||||
GdkDrawContextClass *draw_context_class = GDK_DRAW_CONTEXT_CLASS (klass);
|
GdkDrawContextClass *draw_context_class = GDK_DRAW_CONTEXT_CLASS (klass);
|
||||||
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
||||||
|
|
||||||
|
context_class->backend_type = GDK_GL_GLX;
|
||||||
|
|
||||||
context_class->realize = gdk_x11_gl_context_glx_realize;
|
context_class->realize = gdk_x11_gl_context_glx_realize;
|
||||||
context_class->make_current = gdk_x11_gl_context_glx_make_current;
|
context_class->make_current = gdk_x11_gl_context_glx_make_current;
|
||||||
context_class->clear_current = gdk_x11_gl_context_glx_clear_current;
|
context_class->clear_current = gdk_x11_gl_context_glx_clear_current;
|
||||||
@ -905,6 +907,9 @@ gdk_x11_display_init_glx (GdkX11Display *display_x11,
|
|||||||
Display *dpy;
|
Display *dpy;
|
||||||
int screen_num;
|
int screen_num;
|
||||||
|
|
||||||
|
if (!gdk_gl_backend_can_be_used (GDK_GL_GLX, error))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
dpy = gdk_x11_display_get_xdisplay (display);
|
dpy = gdk_x11_display_get_xdisplay (display);
|
||||||
|
|
||||||
if (!epoxy_has_glx (dpy))
|
if (!epoxy_has_glx (dpy))
|
||||||
|
Loading…
Reference in New Issue
Block a user