[gtk+] x11: Create legacy GLX contexts
- From: Emmanuele Bassi <ebassi src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk+] x11: Create legacy GLX contexts
- Date: Wed, 7 Oct 2015 15:22:48 +0000 (UTC)
commit 18cae47e17522a37477988d7e88055f7dc467df5
Author: Emmanuele Bassi <ebassi gnome org>
Date: Tue Oct 6 18:59:35 2015 +0100
x11: Create legacy GLX contexts
If GLX has support for the GLX_ARB_create_context_profile extension,
then we use the GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB; if it does
not, we fall back to the old glXCreateNewContext() API.
We use the shared GdkGLContext to decide whether the GLX context should
use the legacy bit or not.
https://bugzilla.gnome.org/show_bug.cgi?id=756142
gdk/x11/gdkglcontext-x11.c | 100 ++++++++++++++++++++++++++++++++++++-------
1 files changed, 83 insertions(+), 17 deletions(-)
---
diff --git a/gdk/x11/gdkglcontext-x11.c b/gdk/x11/gdkglcontext-x11.c
index 139fae6..acbdd52 100644
--- a/gdk/x11/gdkglcontext-x11.c
+++ b/gdk/x11/gdkglcontext-x11.c
@@ -554,12 +554,13 @@ static GLXContext
create_gl3_context (GdkDisplay *display,
GLXFBConfig config,
GdkGLContext *share,
+ int profile,
int flags,
int major,
int minor)
{
int attrib_list[] = {
- GLX_CONTEXT_PROFILE_MASK_ARB, GLX_CONTEXT_CORE_PROFILE_BIT_ARB,
+ GLX_CONTEXT_PROFILE_MASK_ARB, profile,
GLX_CONTEXT_MAJOR_VERSION_ARB, major,
GLX_CONTEXT_MINOR_VERSION_ARB, minor,
GLX_CONTEXT_FLAGS_ARB, flags,
@@ -586,6 +587,31 @@ create_gl3_context (GdkDisplay *display,
return res;
}
+static GLXContext
+create_legacy_context (GdkDisplay *display,
+ GLXFBConfig config,
+ GdkGLContext *share)
+{
+ GdkX11GLContext *share_x11 = NULL;
+ GLXContext res;
+
+ if (share != NULL)
+ share_x11 = GDK_X11_GL_CONTEXT (share);
+
+ gdk_x11_display_error_trap_push (display);
+
+ res = glXCreateNewContext (gdk_x11_display_get_xdisplay (display),
+ config,
+ GLX_RGBA_TYPE,
+ share_x11 != NULL ? share_x11->glx_context : NULL,
+ TRUE);
+
+ if (gdk_x11_display_error_trap_pop (display))
+ return NULL;
+
+ return res;
+}
+
static gboolean
gdk_x11_gl_context_realize (GdkGLContext *context,
GError **error)
@@ -598,7 +624,7 @@ gdk_x11_gl_context_realize (GdkGLContext *context,
DrawableInfo *info;
GdkGLContext *share;
GdkWindow *window;
- gboolean debug_bit, compat_bit;
+ gboolean debug_bit, compat_bit, legacy_bit;
int major, minor, flags;
window = gdk_gl_context_get_window (context);
@@ -611,6 +637,16 @@ gdk_x11_gl_context_realize (GdkGLContext *context,
debug_bit = gdk_gl_context_get_debug_enabled (context);
compat_bit = gdk_gl_context_get_forward_compatible (context);
+ /* If there is no glXCreateContextAttribsARB() then we default to legacy */
+ legacy_bit = !GDK_X11_DISPLAY (display)->has_glx_create_context;
+
+ /* We cannot share legacy contexts with core profile ones, so the
+ * shared context is the one that decides if we're going to create
+ * a legacy context or not.
+ */
+ if (share != NULL && gdk_gl_context_is_legacy (share))
+ legacy_bit = TRUE;
+
flags = 0;
if (debug_bit)
flags |= GLX_CONTEXT_DEBUG_BIT_ARB;
@@ -618,15 +654,51 @@ gdk_x11_gl_context_realize (GdkGLContext *context,
flags |= GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB;
GDK_NOTE (OPENGL,
- g_print ("Creating core GLX context (version:%d.%d, debug:%s, forward:%s)\n",
+ g_print ("Creating core GLX context (version:%d.%d, debug:%s, forward:%s, legacy:%s)\n",
major, minor,
debug_bit ? "yes" : "no",
- compat_bit ? "yes" : "no"));
+ compat_bit ? "yes" : "no",
+ legacy_bit ? "yes" : "no"));
+
+ /* If we have access to GLX_ARB_create_context_profile then we can ask for
+ * a compatibility profile; if we don't, then we have to fall back to the
+ * old GLX 1.3 API.
+ */
+ if (legacy_bit && !GDK_X11_DISPLAY (display)->has_glx_create_context)
+ {
+ GDK_NOTE (OPENGL, g_print ("Creating legacy GL context on request\n"));
+ context_x11->glx_context = create_legacy_context (display, context_x11->glx_config, share);
+ }
+ else
+ {
+ int profile = legacy_bit ? GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB
+ : GLX_CONTEXT_CORE_PROFILE_BIT_ARB;
+
+ /* We need to tweak the version, otherwise we may end up requesting
+ * a compatibility context with a minimum version of 3.2, which is
+ * an error
+ */
+ if (legacy_bit)
+ {
+ major = 3;
+ minor = 0;
+ }
+
+ GDK_NOTE (OPENGL, g_print ("Creating GL3 context\n"));
+ context_x11->glx_context = create_gl3_context (display,
+ context_x11->glx_config,
+ share,
+ profile, flags, major, minor);
+
+ /* Fall back to legacy in case the GL3 context creation failed */
+ if (context_x11->glx_context == NULL)
+ {
+ GDK_NOTE (OPENGL, g_print ("Creating fallback legacy context\n"));
+ context_x11->glx_context = create_legacy_context (display, context_x11->glx_config, share);
+ legacy_bit = TRUE;
+ }
+ }
- context_x11->glx_context = create_gl3_context (display,
- context_x11->glx_config,
- share,
- flags, major, minor);
if (context_x11->glx_context == NULL)
{
g_set_error_literal (error, GDK_GL_ERROR,
@@ -635,6 +707,9 @@ gdk_x11_gl_context_realize (GdkGLContext *context,
return FALSE;
}
+ /* Ensure that any other context is created with a legacy bit set */
+ gdk_gl_context_set_is_legacy (context, legacy_bit);
+
xvisinfo = find_xvisinfo_for_fbconfig (display, context_x11->glx_config);
info = get_glx_drawable_info (window->impl_window);
@@ -1179,15 +1254,6 @@ gdk_x11_window_create_gl_context (GdkWindow *window,
return NULL;
}
- if (!GDK_X11_DISPLAY (display)->has_glx_create_context)
- {
- g_set_error_literal (error, GDK_GL_ERROR,
- GDK_GL_ERROR_UNSUPPORTED_PROFILE,
- _("The GLX_ARB_create_context_profile extension "
- "needed to create core profiles is not available"));
- return NULL;
- }
-
visual = gdk_window_get_visual (window);
if (!find_fbconfig_for_visual (display, visual, &config, error))
return NULL;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]