[gtk/wip/otte/gleanup: 57/73] gdk: Add GdkDisplay::init_gl vfunc
- From: Chun-wei Fan <fanchunwei src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk/wip/otte/gleanup: 57/73] gdk: Add GdkDisplay::init_gl vfunc
- Date: Wed, 14 Jul 2021 04:21:52 +0000 (UTC)
commit f41b396c11197a10b303e85c1040b3a7de8223cb
Author: Benjamin Otte <otte redhat com>
Date: Mon Jul 5 01:57:03 2021 +0200
gdk: Add GdkDisplay::init_gl vfunc
The vfunc is called to initialize GL and it returns a "base" context
that GDK then uses as the context all others are shared with. So the GL
context share tree now looks like:
+ context from init_gl
- context1
- context2
...
So this is a flat tree now, the complexity is gone.
The only caveat is that backends now need to create a GL context when
initializing GL so some refactoring was needed.
Two new functions have been added:
* gdk_display_prepare_gl()
This is public API and can be used to ensure that GL has been
initialized or if not, retrieve an error to display (or debug-print).
* gdk_display_get_gl_context()
This is a private function to retrieve the base context from
init_gl(). It replaces gdk_surface_get_shared_data_context().
gdk/gdkdisplay.c | 135 +++++++++++++++++++++++++++++--
gdk/gdkdisplay.h | 4 +
gdk/gdkdisplayprivate.h | 3 +
gdk/gdksurface.c | 51 +-----------
gdk/gdksurfaceprivate.h | 1 -
gdk/macos/gdkmacosdisplay.c | 8 ++
gdk/macos/gdkmacosglcontext-private.h | 7 +-
gdk/macos/gdkmacosglcontext.c | 19 ++---
gdk/macos/gdkmacossurface.c | 3 +-
gdk/wayland/gdkdisplay-wayland.c | 1 +
gdk/wayland/gdkglcontext-wayland.c | 39 ++++-----
gdk/wayland/gdkglcontext-wayland.h | 4 +-
gdk/win32/gdkglcontext-win32.c | 8 +-
gdk/x11/gdkdisplay-x11.c | 145 +++++++++++++++++++---------------
gdk/x11/gdkglcontext-egl.c | 17 ++--
gdk/x11/gdkglcontext-glx.c | 16 ++--
gdk/x11/gdkglcontext-x11.c | 8 +-
gdk/x11/gdkglcontext-x11.h | 2 +-
gsk/ngl/gsknglrenderer.c | 4 +-
19 files changed, 285 insertions(+), 190 deletions(-)
---
diff --git a/gdk/gdkdisplay.c b/gdk/gdkdisplay.c
index dbe8c4cf82..5891bbe5f0 100644
--- a/gdk/gdkdisplay.c
+++ b/gdk/gdkdisplay.c
@@ -80,6 +80,13 @@ enum {
typedef struct _GdkDisplayPrivate GdkDisplayPrivate;
struct _GdkDisplayPrivate {
+ /* The base context that all other contexts inherit from.
+ * This context is never exposed to public API and is
+ * allowed to have a %NULL surface.
+ */
+ GdkGLContext *gl_context;
+ GError *gl_error;
+
guint rgba : 1;
guint composited : 1;
guint input_shapes : 1;
@@ -129,10 +136,14 @@ gdk_display_real_make_default (GdkDisplay *display)
{
}
-static void
-gdk_display_real_opened (GdkDisplay *display)
+static GdkGLContext *
+gdk_display_default_init_gl (GdkDisplay *display,
+ GError **error)
{
- _gdk_display_manager_add_display (gdk_display_manager_get (), display);
+ g_set_error_literal (error, GDK_GL_ERROR, GDK_GL_ERROR_NOT_AVAILABLE,
+ _("The current backend does not support OpenGL"));
+
+ return NULL;
}
static GdkSeat *
@@ -144,6 +155,12 @@ gdk_display_real_get_default_seat (GdkDisplay *display)
return display->seats->data;
}
+static void
+gdk_display_real_opened (GdkDisplay *display)
+{
+ _gdk_display_manager_add_display (gdk_display_manager_get (), display);
+}
+
static void
gdk_display_class_init (GdkDisplayClass *class)
{
@@ -153,10 +170,11 @@ gdk_display_class_init (GdkDisplayClass *class)
object_class->dispose = gdk_display_dispose;
object_class->get_property = gdk_display_get_property;
- class->get_app_launch_context = gdk_display_real_get_app_launch_context;
- class->opened = gdk_display_real_opened;
class->make_default = gdk_display_real_make_default;
+ class->get_app_launch_context = gdk_display_real_get_app_launch_context;
+ class->init_gl = gdk_display_default_init_gl;
class->get_default_seat = gdk_display_real_get_default_seat;
+ class->opened = gdk_display_real_opened;
/**
* GdkDisplay:composited: (attributes org.gtk.Property.get=gdk_display_is_composited)
@@ -327,11 +345,15 @@ static void
gdk_display_dispose (GObject *object)
{
GdkDisplay *display = GDK_DISPLAY (object);
+ GdkDisplayPrivate *priv = gdk_display_get_instance_private (display);
_gdk_display_manager_remove_display (gdk_display_manager_get (), display);
g_queue_clear (&display->queued_events);
+ g_clear_object (&priv->gl_context);
+ g_clear_error (&priv->gl_error);
+
G_OBJECT_CLASS (gdk_display_parent_class)->dispose (object);
}
@@ -1173,6 +1195,109 @@ gdk_display_get_keymap (GdkDisplay *display)
return GDK_DISPLAY_GET_CLASS (display)->get_keymap (display);
}
+static void
+gdk_display_init_gl (GdkDisplay *self)
+{
+ GdkDisplayPrivate *priv = gdk_display_get_instance_private (self);
+ GdkGLContext *context;
+
+ if (GDK_DISPLAY_DEBUG_CHECK (self, GL_DISABLE))
+ {
+ g_set_error_literal (&priv->gl_error, GDK_GL_ERROR,
+ GDK_GL_ERROR_NOT_AVAILABLE,
+ _("GL support disabled via GDK_DEBUG"));
+ return;
+ }
+
+ context = GDK_DISPLAY_GET_CLASS (self)->init_gl (self, &priv->gl_error);
+ if (context == NULL)
+ return;
+
+ if (!gdk_gl_context_realize (context, &priv->gl_error))
+ {
+ g_object_unref (context);
+ return;
+ }
+
+ /* Only assign after realize, so GdkGLContext::realize() can use
+ * gdk_display_get_gl_context() == NULL to differentiate between
+ * the display's context and any other context.
+ */
+ priv->gl_context = context;
+}
+
+/**
+ * gdk_display_prepare_gl:
+ * @self: a `GdkDisplay`
+ * @error: return location for a `GError`
+ *
+ * Checks that OpenGL is available for @self and ensures that it is
+ * properly initialized.
+ * When this fails, an @error will be set describing the error and this
+ * function returns %FALSE.
+ *
+ * Note that even if this function succeeds, creating a `GdkGLContext`
+ * may still fail.
+ *
+ * This function is idempotent. Calling it multiple times will just
+ * return the same value or error.
+ *
+ * You never need to call this function, GDK will call it automatically
+ * as needed. But you can use it as a check when setting up code that
+ * might make use of OpenGL.
+ *
+ * Returns: %TRUE if the display supports OpenGL
+ *
+ * Since: 4.4
+ **/
+gboolean
+gdk_display_prepare_gl (GdkDisplay *self,
+ GError **error)
+{
+ GdkDisplayPrivate *priv = gdk_display_get_instance_private (self);
+
+ g_return_val_if_fail (GDK_IS_DISPLAY (self), FALSE);
+ g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
+
+ for (;;)
+ {
+ if (priv->gl_context)
+ return TRUE;
+
+ if (priv->gl_error != NULL)
+ {
+ if (error)
+ *error = g_error_copy (priv->gl_error);
+ return FALSE;
+ }
+
+ gdk_display_init_gl (self);
+
+ /* try again */
+ }
+}
+
+/*< private >
+ * gdk_display_get_gl_context:
+ * @self: the `GdkDisplay`
+ *
+ * Gets the GL context returned from [vfunc@Gdk.Display.init_gl]
+ * previously.
+ *
+ * If that function has not been called yet or did fail, %NULL is
+ * returned.
+ * Call [method@Gdk.Display.prepare_gl] to avoid this.
+ *
+ * Returns: The `GdkGLContext`
+ */
+GdkGLContext *
+gdk_display_get_gl_context (GdkDisplay *self)
+{
+ GdkDisplayPrivate *priv = gdk_display_get_instance_private (self);
+
+ return priv->gl_context;
+}
+
/*< private >
* gdk_display_make_gl_context_current:
* @display: a `GdkDisplay`
diff --git a/gdk/gdkdisplay.h b/gdk/gdkdisplay.h
index 97d8e7eee6..9fabac6b50 100644
--- a/gdk/gdkdisplay.h
+++ b/gdk/gdkdisplay.h
@@ -68,6 +68,10 @@ gboolean gdk_display_is_rgba (GdkDisplay *display);
GDK_AVAILABLE_IN_ALL
gboolean gdk_display_supports_input_shapes (GdkDisplay *display);
+GDK_AVAILABLE_IN_4_4
+gboolean gdk_display_prepare_gl (GdkDisplay *self,
+ GError **error);
+
GDK_AVAILABLE_IN_ALL
GdkDisplay *gdk_display_get_default (void);
diff --git a/gdk/gdkdisplayprivate.h b/gdk/gdkdisplayprivate.h
index 4aa99c30dd..a2913b50e9 100644
--- a/gdk/gdkdisplayprivate.h
+++ b/gdk/gdkdisplayprivate.h
@@ -140,6 +140,8 @@ struct _GdkDisplayClass
GdkKeymap * (*get_keymap) (GdkDisplay *display);
+ GdkGLContext * (*init_gl) (GdkDisplay *display,
+ GError **error);
gboolean (*make_gl_context_current) (GdkDisplay *display,
GdkGLContext *context);
@@ -206,6 +208,7 @@ GdkSurface * gdk_display_create_surface (GdkDisplay *display
int width,
int height);
+GdkGLContext * gdk_display_get_gl_context (GdkDisplay *display);
gboolean gdk_display_make_gl_context_current (GdkDisplay *display,
GdkGLContext *context);
diff --git a/gdk/gdksurface.c b/gdk/gdksurface.c
index 8f562f7d1c..274ad99345 100644
--- a/gdk/gdksurface.c
+++ b/gdk/gdksurface.c
@@ -1065,59 +1065,14 @@ gdk_surface_get_mapped (GdkSurface *surface)
return GDK_SURFACE_IS_MAPPED (surface);
}
-GdkGLContext *
-gdk_surface_get_shared_data_gl_context (GdkSurface *surface)
-{
- static int in_shared_data_creation;
- GdkDisplay *display;
- GdkGLContext *context;
-
- if (in_shared_data_creation)
- return NULL;
-
- in_shared_data_creation = 1;
-
- display = gdk_surface_get_display (surface);
- context = (GdkGLContext *)g_object_get_data (G_OBJECT (display), "gdk-gl-shared-data-context");
- if (context == NULL)
- {
- GError *error = NULL;
- context = GDK_SURFACE_GET_CLASS (surface)->create_gl_context (surface, FALSE, NULL, &error);
- if (context == NULL)
- {
- g_warning ("Failed to create shared context: %s", error->message);
- g_clear_error (&error);
- }
-
- gdk_gl_context_realize (context, &error);
- if (context == NULL)
- {
- g_warning ("Failed to realize shared context: %s", error->message);
- g_clear_error (&error);
- }
-
-
- g_object_set_data (G_OBJECT (display), "gdk-gl-shared-data-context", context);
- }
-
- in_shared_data_creation = 0;
-
- return context;
-}
-
GdkGLContext *
gdk_surface_get_paint_gl_context (GdkSurface *surface,
- GError **error)
+ GError **error)
{
GError *internal_error = NULL;
- if (GDK_DISPLAY_DEBUG_CHECK (surface->display, GL_DISABLE))
- {
- g_set_error_literal (error, GDK_GL_ERROR,
- GDK_GL_ERROR_NOT_AVAILABLE,
- _("GL support disabled via GDK_DEBUG"));
- return NULL;
- }
+ if (!gdk_display_prepare_gl (surface->display, error))
+ return NULL;
if (surface->gl_paint_context == NULL)
{
diff --git a/gdk/gdksurfaceprivate.h b/gdk/gdksurfaceprivate.h
index 90f5bcba2d..c29827c34e 100644
--- a/gdk/gdksurfaceprivate.h
+++ b/gdk/gdksurfaceprivate.h
@@ -266,7 +266,6 @@ void _gdk_surface_update_size (GdkSurface *surface);
GdkGLContext * gdk_surface_get_paint_gl_context (GdkSurface *surface,
GError **error);
-GdkGLContext * gdk_surface_get_shared_data_gl_context (GdkSurface *surface);
gboolean gdk_surface_handle_event (GdkEvent *event);
GdkSeat * gdk_surface_get_seat_from_event (GdkSurface *surface,
diff --git a/gdk/macos/gdkmacosdisplay.c b/gdk/macos/gdkmacosdisplay.c
index 20041ac076..351ff574fd 100644
--- a/gdk/macos/gdkmacosdisplay.c
+++ b/gdk/macos/gdkmacosdisplay.c
@@ -637,6 +637,13 @@ gdk_macos_display_load_clipboard (GdkMacosDisplay *self)
GDK_DISPLAY (self)->clipboard = _gdk_macos_clipboard_new (self);
}
+static GdkGLContext *
+gdk_macos_display_init_gl (GdkDisplay *display,
+ GError **error)
+{
+ return _gdk_macos_gl_context_new (display, NULL, FALSE, NULL, error);
+}
+
static gboolean
gdk_macos_display_make_gl_context_current (GdkDisplay *display,
GdkGLContext *gl_context)
@@ -695,6 +702,7 @@ gdk_macos_display_class_init (GdkMacosDisplayClass *klass)
display_class->get_name = gdk_macos_display_get_name;
display_class->get_setting = gdk_macos_display_get_setting;
display_class->has_pending = gdk_macos_display_has_pending;
+ display_class->init_gl = gdk_macos_display_init_gl;
display_class->make_gl_context_current = gdk_macos_display_make_gl_context_current;
display_class->notify_startup_complete = gdk_macos_display_notify_startup_complete;
display_class->queue_events = gdk_macos_display_queue_events;
diff --git a/gdk/macos/gdkmacosglcontext-private.h b/gdk/macos/gdkmacosglcontext-private.h
index 97d209b6f7..8d5eea931c 100644
--- a/gdk/macos/gdkmacosglcontext-private.h
+++ b/gdk/macos/gdkmacosglcontext-private.h
@@ -19,12 +19,14 @@
#ifndef __GDK_MACOS_GL_CONTEXT_PRIVATE_H__
#define __GDK_MACOS_GL_CONTEXT_PRIVATE_H__
+#include "gdkmacosglcontext.h"
+
#include "gdkglcontextprivate.h"
#include "gdkdisplayprivate.h"
#include "gdksurface.h"
#include "gdkinternals.h"
-#include "gdkmacosglcontext.h"
+#include "gdkmacosdisplay.h"
#include "gdkmacossurface.h"
#import <OpenGL/OpenGL.h>
@@ -55,7 +57,8 @@ struct _GdkMacosGLContextClass
GdkGLContextClass parent_class;
};
-GdkGLContext *_gdk_macos_gl_context_new (GdkMacosSurface *surface,
+GdkGLContext *_gdk_macos_gl_context_new (GdkMacosDisplay *display,
+ GdkMacosSurface *surface,
gboolean attached,
GdkGLContext *share,
GError **error);
diff --git a/gdk/macos/gdkmacosglcontext.c b/gdk/macos/gdkmacosglcontext.c
index e4ef4abcb1..66f767c19d 100644
--- a/gdk/macos/gdkmacosglcontext.c
+++ b/gdk/macos/gdkmacosglcontext.c
@@ -170,12 +170,12 @@ gdk_macos_gl_context_real_realize (GdkGLContext *context,
{
GdkMacosGLContext *self = (GdkMacosGLContext *)context;
GdkSurface *surface;
+ GdkDisplay *display;
NSOpenGLContext *shared_gl_context = nil;
NSOpenGLContext *gl_context;
NSOpenGLPixelFormat *pixelFormat;
CGLContextObj cgl_context;
GdkGLContext *shared;
- GdkGLContext *shared_data;
NSOpenGLContext *existing;
GLint sync_to_framerate = 1;
GLint validate = 0;
@@ -192,21 +192,16 @@ gdk_macos_gl_context_real_realize (GdkGLContext *context,
gdk_gl_context_get_required_version (context, &major, &minor);
surface = gdk_draw_context_get_surface (GDK_DRAW_CONTEXT (context));
- shared = gdk_gl_context_get_shared_context (context);
- shared_data = gdk_surface_get_shared_data_gl_context (surface);
+ display = gdk_gl_context_get_display (context);
+ shared = gdk_display_get_gl_context (display);
if (shared != NULL)
{
if (!(shared_gl_context = get_ns_open_gl_context (GDK_MACOS_GL_CONTEXT (shared), error)))
return FALSE;
}
- else if (shared_data != NULL)
- {
- if (!(shared_gl_context = get_ns_open_gl_context (GDK_MACOS_GL_CONTEXT (shared_data), error)))
- return FALSE;
- }
- GDK_DISPLAY_NOTE (gdk_draw_context_get_display (GDK_DRAW_CONTEXT (context)),
+ GDK_DISPLAY_NOTE (display,
OPENGL,
g_message ("Creating NSOpenGLContext (version %d.%d)",
major, minor));
@@ -253,7 +248,7 @@ gdk_macos_gl_context_real_realize (GdkGLContext *context,
GLint renderer_id = 0;
[gl_context getValues:&renderer_id forParameter:NSOpenGLContextParameterCurrentRendererID];
- GDK_DISPLAY_NOTE (gdk_draw_context_get_display (GDK_DRAW_CONTEXT (context)),
+ GDK_DISPLAY_NOTE (display,
OPENGL,
g_message ("Created NSOpenGLContext[%p] using %s",
gl_context,
@@ -479,7 +474,8 @@ gdk_macos_gl_context_init (GdkMacosGLContext *self)
}
GdkGLContext *
-_gdk_macos_gl_context_new (GdkMacosSurface *surface,
+_gdk_macos_gl_context_new (GdkMacosDisplay *display,
+ GdkMacosSurface *surface,
gboolean attached,
GdkGLContext *share,
GError **error)
@@ -490,6 +486,7 @@ _gdk_macos_gl_context_new (GdkMacosSurface *surface,
g_return_val_if_fail (!share || GDK_IS_MACOS_GL_CONTEXT (share), NULL);
context = g_object_new (GDK_TYPE_MACOS_GL_CONTEXT,
+ "display", display,
"surface", surface,
"shared-context", share,
NULL);
diff --git a/gdk/macos/gdkmacossurface.c b/gdk/macos/gdkmacossurface.c
index 9a1f73835b..aa8df2f35e 100644
--- a/gdk/macos/gdkmacossurface.c
+++ b/gdk/macos/gdkmacossurface.c
@@ -369,7 +369,8 @@ gdk_macos_surface_create_gl_context (GdkSurface *surface,
g_assert (GDK_IS_MACOS_SURFACE (self));
g_assert (!share || GDK_IS_GL_CONTEXT (share));
- return _gdk_macos_gl_context_new (self, attached, share, error);
+ return _gdk_macos_gl_context_new ((GdkMacosDisplay *) gdk_surface_get_display (surface),
+ self, attached, share, error);
}
static void
diff --git a/gdk/wayland/gdkdisplay-wayland.c b/gdk/wayland/gdkdisplay-wayland.c
index c27b165594..5d2d3826ae 100644
--- a/gdk/wayland/gdkdisplay-wayland.c
+++ b/gdk/wayland/gdkdisplay-wayland.c
@@ -969,6 +969,7 @@ gdk_wayland_display_class_init (GdkWaylandDisplayClass *class)
display_class->create_surface = _gdk_wayland_display_create_surface;
display_class->get_keymap = _gdk_wayland_display_get_keymap;
+ display_class->init_gl = gdk_wayland_display_init_gl;
display_class->make_gl_context_current = gdk_wayland_display_make_gl_context_current;
display_class->get_monitors = gdk_wayland_display_get_monitors;
diff --git a/gdk/wayland/gdkglcontext-wayland.c b/gdk/wayland/gdkglcontext-wayland.c
index 3e8e8bf6f4..23e0105802 100644
--- a/gdk/wayland/gdkglcontext-wayland.c
+++ b/gdk/wayland/gdkglcontext-wayland.c
@@ -55,8 +55,7 @@ gdk_wayland_gl_context_realize (GdkGLContext *context,
{
GdkWaylandGLContext *context_wayland = GDK_WAYLAND_GL_CONTEXT (context);
GdkDisplay *display = gdk_gl_context_get_display (context);
- GdkGLContext *share = gdk_gl_context_get_shared_context (context);
- GdkGLContext *shared_data_context = gdk_surface_get_shared_data_gl_context (gdk_gl_context_get_surface
(context));
+ GdkGLContext *share = gdk_display_get_gl_context (display);
GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (display);
EGLContext ctx;
EGLint context_attribs[N_EGL_ATTRS];
@@ -124,8 +123,7 @@ gdk_wayland_gl_context_realize (GdkGLContext *context,
ctx = eglCreateContext (display_wayland->egl_display,
display_wayland->egl_config,
share != NULL ? GDK_WAYLAND_GL_CONTEXT (share)->egl_context
- : shared_data_context != NULL ? GDK_WAYLAND_GL_CONTEXT
(shared_data_context)->egl_context
- : EGL_NO_CONTEXT,
+ : EGL_NO_CONTEXT,
context_attribs);
/* If context creation failed without the ES bit, let's try again with it */
@@ -151,8 +149,7 @@ gdk_wayland_gl_context_realize (GdkGLContext *context,
ctx = eglCreateContext (display_wayland->egl_display,
display_wayland->egl_config,
share != NULL ? GDK_WAYLAND_GL_CONTEXT (share)->egl_context
- : shared_data_context != NULL ? GDK_WAYLAND_GL_CONTEXT
(shared_data_context)->egl_context
- : EGL_NO_CONTEXT,
+ : EGL_NO_CONTEXT,
context_attribs);
}
@@ -181,8 +178,7 @@ gdk_wayland_gl_context_realize (GdkGLContext *context,
ctx = eglCreateContext (display_wayland->egl_display,
display_wayland->egl_config,
share != NULL ? GDK_WAYLAND_GL_CONTEXT (share)->egl_context
- : shared_data_context != NULL ? GDK_WAYLAND_GL_CONTEXT
(shared_data_context)->egl_context
- : EGL_NO_CONTEXT,
+ : EGL_NO_CONTEXT,
context_attribs);
}
@@ -346,7 +342,7 @@ gdk_wayland_display_get_egl_display (GdkDisplay *display)
g_return_val_if_fail (GDK_IS_WAYLAND_DISPLAY (display), NULL);
- if (!gdk_wayland_display_init_gl (display, NULL))
+ if (!gdk_display_prepare_gl (display, NULL))
return NULL;
display_wayland = GDK_WAYLAND_DISPLAY (display);
@@ -428,7 +424,7 @@ get_eglconfig (EGLDisplay dpy)
#undef MAX_EGL_ATTRS
-gboolean
+GdkGLContext *
gdk_wayland_display_init_gl (GdkDisplay *display,
GError **error)
{
@@ -436,16 +432,13 @@ gdk_wayland_display_init_gl (GdkDisplay *display,
EGLint major, minor;
EGLDisplay dpy;
- if (display_wayland->egl_display)
- return TRUE;
-
dpy = get_egl_display (display_wayland);
if (dpy == NULL)
{
g_set_error_literal (error, GDK_GL_ERROR,
GDK_GL_ERROR_NOT_AVAILABLE,
_("Failed to create EGL display"));
- return FALSE;
+ return NULL;
}
if (!eglInitialize (dpy, &major, &minor))
@@ -453,7 +446,7 @@ gdk_wayland_display_init_gl (GdkDisplay *display,
g_set_error_literal (error, GDK_GL_ERROR,
GDK_GL_ERROR_NOT_AVAILABLE,
_("Could not initialize EGL display"));
- return FALSE;
+ return NULL;
}
if (!eglBindAPI (EGL_OPENGL_API))
@@ -462,7 +455,7 @@ gdk_wayland_display_init_gl (GdkDisplay *display,
g_set_error_literal (error, GDK_GL_ERROR,
GDK_GL_ERROR_NOT_AVAILABLE,
_("No GL implementation is available"));
- return FALSE;
+ return NULL;
}
if (!epoxy_has_egl_extension (dpy, "EGL_KHR_create_context"))
@@ -471,7 +464,7 @@ gdk_wayland_display_init_gl (GdkDisplay *display,
g_set_error_literal (error, GDK_GL_ERROR,
GDK_GL_ERROR_UNSUPPORTED_PROFILE,
_("Core GL is not available on EGL implementation"));
- return FALSE;
+ return NULL;
}
display_wayland->egl_config = get_eglconfig (dpy);
@@ -481,7 +474,7 @@ gdk_wayland_display_init_gl (GdkDisplay *display,
g_set_error_literal (error, GDK_GL_ERROR,
GDK_GL_ERROR_UNSUPPORTED_FORMAT,
_("No available configurations for the given pixel format"));
- return FALSE;
+ return NULL;
}
display_wayland->egl_display = dpy;
@@ -511,21 +504,19 @@ gdk_wayland_display_init_gl (GdkDisplay *display,
eglQueryString (dpy, EGL_CLIENT_APIS),
eglQueryString (dpy, EGL_EXTENSIONS)));
- return TRUE;
+ return g_object_new (GDK_TYPE_WAYLAND_GL_CONTEXT,
+ "display", display,
+ NULL);
}
GdkGLContext *
-gdk_wayland_surface_create_gl_context (GdkSurface *surface,
+gdk_wayland_surface_create_gl_context (GdkSurface *surface,
gboolean attached,
GdkGLContext *share,
GError **error)
{
- GdkDisplay *display = gdk_surface_get_display (surface);
GdkWaylandGLContext *context;
- if (!gdk_wayland_display_init_gl (display, error))
- return NULL;
-
context = g_object_new (GDK_TYPE_WAYLAND_GL_CONTEXT,
"surface", surface,
"shared-context", share,
diff --git a/gdk/wayland/gdkglcontext-wayland.h b/gdk/wayland/gdkglcontext-wayland.h
index 6e75a4bffd..d939a4ad39 100644
--- a/gdk/wayland/gdkglcontext-wayland.h
+++ b/gdk/wayland/gdkglcontext-wayland.h
@@ -44,9 +44,9 @@ struct _GdkWaylandGLContextClass
GdkGLContextClass parent_class;
};
-gboolean gdk_wayland_display_init_gl (GdkDisplay *display,
+GdkGLContext * gdk_wayland_display_init_gl (GdkDisplay *display,
GError **error);
-GdkGLContext * gdk_wayland_surface_create_gl_context (GdkSurface *surface,
+GdkGLContext * gdk_wayland_surface_create_gl_context (GdkSurface *surface,
gboolean attach,
GdkGLContext *share,
GError **error);
diff --git a/gdk/win32/gdkglcontext-win32.c b/gdk/win32/gdkglcontext-win32.c
index b3c0d8ad2b..66adbb858e 100644
--- a/gdk/win32/gdkglcontext-win32.c
+++ b/gdk/win32/gdkglcontext-win32.c
@@ -910,8 +910,6 @@ static gboolean
gdk_win32_gl_context_realize (GdkGLContext *context,
GError **error)
{
- GdkGLContext *share = gdk_gl_context_get_shared_context (context);
- GdkGLContext *shared_data_context;
GdkWin32GLContext *context_win32 = GDK_WIN32_GL_CONTEXT (context);
gboolean debug_bit, compat_bit, legacy_bit;
@@ -926,11 +924,11 @@ gdk_win32_gl_context_realize (GdkGLContext *context,
GdkWin32Surface *impl = GDK_WIN32_SURFACE (surface);
GdkDisplay *display = gdk_surface_get_display (surface);
GdkWin32Display *win32_display = GDK_WIN32_DISPLAY (display);
+ GdkGLContext *share = gdk_display_get_gl_context (display);
gdk_gl_context_get_required_version (context, &major, &minor);
debug_bit = gdk_gl_context_get_debug_enabled (context);
compat_bit = gdk_gl_context_get_forward_compatible (context);
- shared_data_context = gdk_surface_get_shared_data_gl_context (surface);
/*
* A legacy context cannot be shared with core profile ones, so this means we
@@ -980,7 +978,7 @@ gdk_win32_gl_context_realize (GdkGLContext *context,
legacy_bit ? "yes" : "no"));
hglrc = _create_gl_context (context_win32->gl_hdc,
- share ? share : shared_data_context,
+ share,
flags,
major,
minor,
@@ -1022,7 +1020,7 @@ gdk_win32_gl_context_realize (GdkGLContext *context,
ctx = _create_egl_context (win32_display->egl_disp,
context_win32->egl_config,
- share ? share : shared_data_context,
+ share,
flags,
major,
minor,
diff --git a/gdk/x11/gdkdisplay-x11.c b/gdk/x11/gdkdisplay-x11.c
index 9441ed1417..0b838c25dd 100644
--- a/gdk/x11/gdkdisplay-x11.c
+++ b/gdk/x11/gdkdisplay-x11.c
@@ -1339,40 +1339,6 @@ set_sm_client_id (GdkDisplay *display,
gdk_x11_get_xatom_by_name_for_display (display, "SM_CLIENT_ID"));
}
-static void
-gdk_x11_display_query_default_visual (GdkX11Display *self,
- Visual **out_visual,
- int *out_depth)
-{
- XVisualInfo template, *visinfo;
- int n_visuals;
- Display *dpy;
-
- dpy = gdk_x11_display_get_xdisplay (GDK_DISPLAY (self));
-
- template.screen = self->screen->screen_num;
- template.depth = 32;
- template.red_mask = 0xff0000;
- template.green_mask = 0x00ff00;
- template.blue_mask = 0x0000ff;
-
- visinfo = XGetVisualInfo (dpy,
- VisualScreenMask | VisualDepthMask
- | VisualRedMaskMask | VisualGreenMaskMask | VisualBlueMaskMask,
- &template,
- &n_visuals);
- if (visinfo != NULL)
- {
- *out_visual = visinfo[0].visual;
- *out_depth = visinfo[0].depth;
- XFree (visinfo);
- return;
- }
-
- *out_visual = DefaultVisual (dpy, self->screen->screen_num);
- *out_depth = DefaultDepth (dpy, self->screen->screen_num);
-}
-
/**
* gdk_x11_display_open:
* @display_name: (nullable): name of the X display.
@@ -1443,36 +1409,11 @@ gdk_x11_display_open (const char *display_name)
/* If GL is available we want to pick better default/rgba visuals,
* as we care about GLX details such as alpha/depth/stencil depth,
* stereo and double buffering
+ *
+ * Note that this also sets up the leader surface while creating the inital
+ * GL context.
*/
- if (!gdk_x11_display_init_gl (display_x11, &display_x11->window_visual, &display_x11->window_depth,
&display_x11->gl_error))
- gdk_x11_display_query_default_visual (display_x11, &display_x11->window_visual,
&display_x11->window_depth);
-
- display_x11->window_colormap = XCreateColormap (xdisplay,
- DefaultRootWindow (xdisplay),
- display_x11->window_visual,
- AllocNone);
- gdk_display_set_rgba (display, display_x11->window_depth == 32);
-
- /* We need to initialize events after we have the screen
- * structures in places
- */
- _gdk_x11_xsettings_init (GDK_X11_SCREEN (display_x11->screen));
-
- display_x11->device_manager = _gdk_x11_device_manager_new (display);
-
- gdk_event_init (display);
-
- display_x11->leader_gdk_surface =
- _gdk_x11_display_create_surface (display,
- GDK_SURFACE_TEMP,
- NULL,
- -100, -100, 1, 1);
-
- (_gdk_x11_surface_get_toplevel (display_x11->leader_gdk_surface))->is_leader = TRUE;
-
- display_x11->leader_window = GDK_SURFACE_XID (display_x11->leader_gdk_surface);
-
- display_x11->leader_window_title_set = FALSE;
+ gdk_display_prepare_gl (display, NULL);
#ifdef HAVE_XFIXES
if (XFixesQueryExtension (display_x11->xdisplay,
@@ -2896,6 +2837,83 @@ gdk_boolean_handled_accumulator (GSignalInvocationHint *ihint,
return continue_emission;
}
+static void
+gdk_x11_display_query_default_visual (GdkX11Display *self,
+ Visual **out_visual,
+ int *out_depth)
+{
+ XVisualInfo template, *visinfo;
+ int n_visuals;
+ Display *dpy;
+
+ dpy = gdk_x11_display_get_xdisplay (GDK_DISPLAY (self));
+
+ template.screen = self->screen->screen_num;
+ template.depth = 32;
+ template.red_mask = 0xff0000;
+ template.green_mask = 0x00ff00;
+ template.blue_mask = 0x0000ff;
+
+ visinfo = XGetVisualInfo (dpy,
+ VisualScreenMask | VisualDepthMask
+ | VisualRedMaskMask | VisualGreenMaskMask | VisualBlueMaskMask,
+ &template,
+ &n_visuals);
+ if (visinfo != NULL)
+ {
+ *out_visual = visinfo[0].visual;
+ *out_depth = visinfo[0].depth;
+ XFree (visinfo);
+ return;
+ }
+
+ *out_visual = DefaultVisual (dpy, self->screen->screen_num);
+ *out_depth = DefaultDepth (dpy, self->screen->screen_num);
+}
+
+static GdkGLContext *
+gdk_x11_display_init_gl (GdkDisplay *display,
+ GError **error)
+{
+ GdkX11Display *display_x11 = GDK_X11_DISPLAY (display);
+ Display *xdisplay = gdk_x11_display_get_xdisplay (display);
+ gboolean have_gl;
+
+ have_gl = gdk_x11_display_init_gl_backend (display_x11, &display_x11->window_visual,
&display_x11->window_depth, error);
+ if (!have_gl)
+ gdk_x11_display_query_default_visual (display_x11, &display_x11->window_visual,
&display_x11->window_depth);
+
+ display_x11->window_colormap = XCreateColormap (xdisplay,
+ DefaultRootWindow (xdisplay),
+ display_x11->window_visual,
+ AllocNone);
+ gdk_display_set_rgba (display, display_x11->window_depth == 32);
+
+ /* We need to initialize events after we have the screen
+ * structures in places
+ */
+ _gdk_x11_xsettings_init (GDK_X11_SCREEN (display_x11->screen));
+
+ display_x11->device_manager = _gdk_x11_device_manager_new (display);
+
+ gdk_event_init (display);
+
+ display_x11->leader_gdk_surface =
+ _gdk_x11_display_create_surface (display,
+ GDK_SURFACE_TEMP,
+ NULL,
+ -100, -100, 1, 1);
+
+ (_gdk_x11_surface_get_toplevel (display_x11->leader_gdk_surface))->is_leader = TRUE;
+ display_x11->leader_window = GDK_SURFACE_XID (display_x11->leader_gdk_surface);
+ display_x11->leader_window_title_set = FALSE;
+
+ if (!have_gl)
+ return NULL;
+
+ return gdk_x11_surface_create_gl_context (display_x11->leader_gdk_surface, FALSE, NULL, error);
+}
+
static void
gdk_x11_display_class_init (GdkX11DisplayClass * class)
{
@@ -2926,6 +2944,7 @@ gdk_x11_display_class_init (GdkX11DisplayClass * class)
display_class->create_surface = _gdk_x11_display_create_surface;
display_class->get_keymap = gdk_x11_display_get_keymap;
+ display_class->init_gl = gdk_x11_display_init_gl;
display_class->make_gl_context_current = gdk_x11_display_make_gl_context_current;
display_class->get_default_seat = gdk_x11_display_get_default_seat;
diff --git a/gdk/x11/gdkglcontext-egl.c b/gdk/x11/gdkglcontext-egl.c
index 56a17168b1..271e77c2f2 100644
--- a/gdk/x11/gdkglcontext-egl.c
+++ b/gdk/x11/gdkglcontext-egl.c
@@ -423,19 +423,16 @@ gdk_x11_gl_context_egl_realize (GdkGLContext *context,
GdkX11Display *display_x11;
GdkDisplay *display;
GdkX11GLContextEGL *context_egl;
- GdkGLContext *share, *shared_data_context;
- GdkSurface *surface;
+ GdkGLContext *share;
gboolean debug_bit, forward_bit, legacy_bit, use_es;
int major, minor, i = 0;
EGLint context_attrs[N_EGL_ATTRS];
- surface = gdk_gl_context_get_surface (context);
- display = gdk_surface_get_display (surface);
+ display = gdk_gl_context_get_display (context);
context_egl = GDK_X11_GL_CONTEXT_EGL (context);
display_x11 = GDK_X11_DISPLAY (display);
- share = gdk_gl_context_get_shared_context (context);
- shared_data_context = gdk_surface_get_shared_data_gl_context (surface);
+ share = gdk_display_get_gl_context (display);
gdk_gl_context_get_required_version (context, &major, &minor);
debug_bit = gdk_gl_context_get_debug_enabled (context);
@@ -503,9 +500,7 @@ gdk_x11_gl_context_egl_realize (GdkGLContext *context,
display_x11->egl_config,
share != NULL
? GDK_X11_GL_CONTEXT_EGL (share)->egl_context
- : shared_data_context != NULL
- ? GDK_X11_GL_CONTEXT_EGL (shared_data_context)->egl_context
- : EGL_NO_CONTEXT,
+ : EGL_NO_CONTEXT,
context_attrs);
/* If we're not asking for a GLES context, and we don't have the legacy bit set
@@ -528,9 +523,7 @@ gdk_x11_gl_context_egl_realize (GdkGLContext *context,
display_x11->egl_config,
share != NULL
? GDK_X11_GL_CONTEXT_EGL (share)->egl_context
- : shared_data_context != NULL
- ? GDK_X11_GL_CONTEXT_EGL (shared_data_context)->egl_context
- : EGL_NO_CONTEXT,
+ : EGL_NO_CONTEXT,
context_attrs);
}
diff --git a/gdk/x11/gdkglcontext-glx.c b/gdk/x11/gdkglcontext-glx.c
index c6bd867361..cc68137aab 100644
--- a/gdk/x11/gdkglcontext-glx.c
+++ b/gdk/x11/gdkglcontext-glx.c
@@ -503,20 +503,18 @@ gdk_x11_gl_context_glx_realize (GdkGLContext *context,
GdkDisplay *display;
GdkX11GLContextGLX *context_glx;
Display *dpy;
+ GdkSurface *surface;
DrawableInfo *info;
GdkGLContext *share;
- GdkGLContext *shared_data_context;
- GdkSurface *surface;
gboolean debug_bit, compat_bit, legacy_bit, es_bit;
int major, minor, flags;
- surface = gdk_gl_context_get_surface (context);
- display = gdk_surface_get_display (surface);
+ display = gdk_gl_context_get_display (context);
dpy = gdk_x11_display_get_xdisplay (display);
context_glx = GDK_X11_GL_CONTEXT_GLX (context);
display_x11 = GDK_X11_DISPLAY (display);
- share = gdk_gl_context_get_shared_context (context);
- shared_data_context = gdk_surface_get_shared_data_gl_context (surface);
+ share = gdk_display_get_gl_context (display);
+ surface = gdk_gl_context_get_surface (context);
gdk_gl_context_get_required_version (context, &major, &minor);
debug_bit = gdk_gl_context_get_debug_enabled (context);
@@ -556,7 +554,7 @@ gdk_x11_gl_context_glx_realize (GdkGLContext *context,
if (legacy_bit && !GDK_X11_DISPLAY (display)->has_glx_create_context)
{
GDK_DISPLAY_NOTE (display, OPENGL, g_message ("Creating legacy GL context on request"));
- context_glx->glx_context = create_legacy_context (display, display_x11->glx_config, share ? share :
shared_data_context);
+ context_glx->glx_context = create_legacy_context (display, display_x11->glx_config, share);
}
else
{
@@ -581,14 +579,14 @@ gdk_x11_gl_context_glx_realize (GdkGLContext *context,
GDK_DISPLAY_NOTE (display, OPENGL, g_message ("Creating GL3 context"));
context_glx->glx_context = create_gl3_context (display,
display_x11->glx_config,
- share ? share : shared_data_context,
+ share,
profile, flags, major, minor);
/* Fall back to legacy in case the GL3 context creation failed */
if (context_glx->glx_context == NULL)
{
GDK_DISPLAY_NOTE (display, OPENGL, g_message ("Creating fallback legacy context"));
- context_glx->glx_context = create_legacy_context (display, display_x11->glx_config, share ? share
: shared_data_context);
+ context_glx->glx_context = create_legacy_context (display, display_x11->glx_config, share);
legacy_bit = TRUE;
es_bit = FALSE;
}
diff --git a/gdk/x11/gdkglcontext-x11.c b/gdk/x11/gdkglcontext-x11.c
index c74a994c70..3585367596 100644
--- a/gdk/x11/gdkglcontext-x11.c
+++ b/gdk/x11/gdkglcontext-x11.c
@@ -103,10 +103,10 @@ gdk_x11_display_make_gl_context_current (GdkDisplay *display,
}
gboolean
-gdk_x11_display_init_gl (GdkX11Display *self,
- Visual **out_visual,
- int *out_depth,
- GError **error)
+gdk_x11_display_init_gl_backend (GdkX11Display *self,
+ Visual **out_visual,
+ int *out_depth,
+ GError **error)
{
GdkDisplay *display G_GNUC_UNUSED = GDK_DISPLAY (self);
diff --git a/gdk/x11/gdkglcontext-x11.h b/gdk/x11/gdkglcontext-x11.h
index 5cc2ebf5d6..e62a4795d7 100644
--- a/gdk/x11/gdkglcontext-x11.h
+++ b/gdk/x11/gdkglcontext-x11.h
@@ -59,7 +59,7 @@ struct _GdkX11GLContextClass
void (* bind_for_frame_fence) (GdkX11GLContext *self);
};
-gboolean gdk_x11_display_init_gl (GdkX11Display *self,
+gboolean gdk_x11_display_init_gl_backend (GdkX11Display *self,
Visual **out_visual,
int *out_depth,
GError **error);
diff --git a/gsk/ngl/gsknglrenderer.c b/gsk/ngl/gsknglrenderer.c
index e343479abd..c84f112047 100644
--- a/gsk/ngl/gsknglrenderer.c
+++ b/gsk/ngl/gsknglrenderer.c
@@ -21,7 +21,7 @@
#include "config.h"
#include <gdk/gdkprofilerprivate.h>
-#include <gdk/gdksurfaceprivate.h>
+#include <gdk/gdkdisplayprivate.h>
#include <gsk/gskdebugprivate.h>
#include <gsk/gskrendererprivate.h>
@@ -105,7 +105,7 @@ gsk_ngl_renderer_realize (GskRenderer *renderer,
!gdk_gl_context_realize (context, error))
goto failure;
- if (!(shared_context = gdk_surface_get_shared_data_gl_context (surface)))
+ if (!(shared_context = gdk_display_get_gl_context (gdk_surface_get_display (surface))))
{
g_set_error (error,
GDK_GL_ERROR,
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]