int minor;
int gl_version;
- guint realized : 1;
guint has_khr_debug : 1;
guint use_khr_debug : 1;
guint has_unpack_subimage : 1;
guint is_legacy : 1;
GdkGLAPI allowed_apis;
- int use_es;
+ GdkGLAPI api;
int max_debug_label_length;
g_return_if_fail (GDK_IS_GL_CONTEXT (context));
if (!gdk_memory_format_gl_format (data_format,
- priv->use_es,
+ gdk_gl_context_get_use_es (context),
&gl_internalformat,
&gl_format,
&gl_type))
data = copy;
data_format = GDK_MEMORY_R8G8B8A8_PREMULTIPLIED;
if (!gdk_memory_format_gl_format (data_format,
- priv->use_es,
+ gdk_gl_context_get_use_es (context),
&gl_internalformat,
&gl_format,
&gl_type))
glTexImage2D (texture_target, 0, gl_internalformat, width, height, 0, gl_format, gl_type, data);
glPixelStorei (GL_UNPACK_ALIGNMENT, 4);
}
- else if ((!priv->use_es ||
- (priv->use_es && (priv->gl_version >= 30 || priv->has_unpack_subimage))))
+ else if ((!gdk_gl_context_get_use_es (context) ||
+ (priv->gl_version >= 30 || priv->has_unpack_subimage)))
{
glPixelStorei (GL_UNPACK_ROW_LENGTH, stride / bpp);
#define N_EGL_ATTRS 16
-static gboolean
+static GdkGLAPI
gdk_gl_context_real_realize (GdkGLContext *context,
GError **error)
{
EGLContext ctx;
EGLint context_attribs[N_EGL_ATTRS];
int major, minor, flags;
- gboolean debug_bit, forward_bit, legacy_bit, use_es;
+ gboolean debug_bit, forward_bit, legacy_bit;
+ GdkGLAPI api;
int i = 0;
G_GNUC_UNUSED gint64 start_time = GDK_PROFILER_CURRENT_TIME;
forward_bit = gdk_gl_context_get_forward_compatible (context);
legacy_bit = GDK_DISPLAY_DEBUG_CHECK (display, GL_LEGACY) ||
(share != NULL && gdk_gl_context_is_legacy (share));
- use_es = GDK_DISPLAY_DEBUG_CHECK (display, GL_GLES) ||
- (share != NULL && gdk_gl_context_get_use_es (share));
if (display->have_egl_no_config_context)
egl_config = NULL;
if (forward_bit)
flags |= EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR;
- if (!use_es && eglBindAPI (EGL_OPENGL_API))
+ if (gdk_gl_context_is_api_allowed (context, GDK_GL_API_GL, NULL) &&
+ eglBindAPI (EGL_OPENGL_API))
{
/* We want a core profile, unless in legacy mode */
context_attribs[i++] = EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR;
context_attribs[i++] = legacy_bit ? 3 : major;
context_attribs[i++] = EGL_CONTEXT_MINOR_VERSION_KHR;
context_attribs[i++] = legacy_bit ? 0 : minor;
+ api = GDK_GL_API_GL;
}
- else if (eglBindAPI (EGL_OPENGL_ES_API))
+ else if (gdk_gl_context_is_api_allowed (context, GDK_GL_API_GLES, NULL) &&
+ eglBindAPI (EGL_OPENGL_ES_API))
{
context_attribs[i++] = EGL_CONTEXT_CLIENT_VERSION;
if (major == 3)
context_attribs[i++] = 3;
else
context_attribs[i++] = 2;
+ api = GDK_GL_API_GLES;
}
else
{
g_set_error_literal (error, GDK_GL_ERROR, GDK_GL_ERROR_NOT_AVAILABLE,
- _("The EGL implementation supports neither OpenGL nor GLES"));
- return FALSE;
+ _("The EGL implementation does not support any allowed APIs"));
+ return 0;
}
/* Specify the flags */
debug_bit ? "yes" : "no",
forward_bit ? "yes" : "no",
legacy_bit ? "yes" : "no",
- use_es ? "yes" : "no"));
+ api == GDK_GL_API_GLES ? "yes" : "no"));
ctx = eglCreateContext (egl_display,
egl_config,
context_attribs);
/* If context creation failed without the ES bit, let's try again with it */
- if (ctx == NULL && eglBindAPI (EGL_OPENGL_ES_API))
+ if (ctx == NULL && gdk_gl_context_is_api_allowed (context, GDK_GL_API_GLES, NULL) && eglBindAPI (EGL_OPENGL_ES_API))
{
i = 0;
context_attribs[i++] = EGL_CONTEXT_MAJOR_VERSION;
g_assert (i < N_EGL_ATTRS);
legacy_bit = FALSE;
- use_es = TRUE;
+ api = GDK_GL_API_GLES;
GDK_DISPLAY_NOTE (display, OPENGL,
g_message ("eglCreateContext failed, switching to OpenGLĀ ES"));
}
/* If context creation failed without the legacy bit, let's try again with it */
- if (ctx == NULL && eglBindAPI (EGL_OPENGL_API))
+ if (ctx == NULL && gdk_gl_context_is_api_allowed (context, GDK_GL_API_GL, NULL) && eglBindAPI (EGL_OPENGL_API))
{
i = 0;
context_attribs[i++] = EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR;
g_assert (i < N_EGL_ATTRS);
legacy_bit = TRUE;
- use_es = FALSE;
+ api = GDK_GL_API_GL;
GDK_DISPLAY_NOTE (display, OPENGL,
g_message ("eglCreateContext failed, switching to legacy"));
g_set_error_literal (error, GDK_GL_ERROR,
GDK_GL_ERROR_NOT_AVAILABLE,
_("Unable to create a GL context"));
- return FALSE;
+ return 0;
}
GDK_DISPLAY_NOTE (display, OPENGL, g_message ("Created EGL context[%p]", ctx));
priv->egl_context = ctx;
gdk_gl_context_set_is_legacy (context, legacy_bit);
- gdk_gl_context_set_use_es (context, use_es);
gdk_profiler_end_mark (start_time, "realize GdkWaylandGLContext", NULL);
- return TRUE;
+ return api;
}
#endif
g_set_error_literal (error, GDK_GL_ERROR, GDK_GL_ERROR_NOT_AVAILABLE,
_("The current backend does not support OpenGL"));
- return FALSE;
+ return 0;
}
#undef N_EGL_ATTRS
return priv->has_unpack_subimage;
}
+static gboolean
+gdk_gl_context_is_realized (GdkGLContext *context)
+{
+ GdkGLContextPrivate *priv = gdk_gl_context_get_instance_private (context);
+
+ return priv->api != 0;
+}
+
/**
* gdk_gl_context_set_debug_enabled:
* @context: a `GdkGLContext`
GdkGLContextPrivate *priv = gdk_gl_context_get_instance_private (context);
g_return_if_fail (GDK_IS_GL_CONTEXT (context));
- g_return_if_fail (!priv->realized);
+ g_return_if_fail (gdk_gl_context_is_realized (context));
enabled = !!enabled;
GdkGLContextPrivate *priv = gdk_gl_context_get_instance_private (context);
g_return_if_fail (GDK_IS_GL_CONTEXT (context));
- g_return_if_fail (!priv->realized);
+ g_return_if_fail (gdk_gl_context_is_realized (context));
compatible = !!compatible;
#endif
g_return_if_fail (GDK_IS_GL_CONTEXT (context));
- g_return_if_fail (!priv->realized);
+ g_return_if_fail (gdk_gl_context_is_realized (context));
/* this will take care of the default */
if (major == 0 && minor == 0)
/* Enforce a minimum context version number of 3.2 for desktop GL,
* and 2.0 for GLES
*/
- if (priv->use_es > 0 || force_gles)
+ if (gdk_gl_context_get_use_es (context) || force_gles)
min_ver = 200;
else
min_ver = 302;
* enforce a context version number of 3.2 for desktop GL,
* and 2.0 for GLES
*/
- if (priv->use_es > 0 || force_gles)
+ if (gdk_gl_context_get_use_es (context) || force_gles)
{
default_major = 2;
default_minor = 0;
GdkGLContextPrivate *priv = gdk_gl_context_get_instance_private (context);
g_return_val_if_fail (GDK_IS_GL_CONTEXT (context), FALSE);
- g_return_val_if_fail (priv->realized, FALSE);
+ g_return_val_if_fail (gdk_gl_context_is_realized (context), FALSE);
return priv->is_legacy;
}
gdk_gl_context_is_shared (GdkGLContext *self,
GdkGLContext *other)
{
- GdkGLContextPrivate *priv = gdk_gl_context_get_instance_private (self);
- GdkGLContextPrivate *priv_other = gdk_gl_context_get_instance_private (other);
-
g_return_val_if_fail (GDK_IS_GL_CONTEXT (self), FALSE);
g_return_val_if_fail (GDK_IS_GL_CONTEXT (other), FALSE);
- if (!priv->realized || !priv_other->realized)
+ if (!gdk_gl_context_is_realized (self) ||
+ !gdk_gl_context_is_realized (other))
return FALSE;
return GDK_GL_CONTEXT_GET_CLASS (self)->is_shared (self, other);
return priv->allowed_apis;
}
+gboolean
+gdk_gl_context_is_api_allowed (GdkGLContext *self,
+ GdkGLAPI api,
+ GError **error)
+{
+ GdkGLContextPrivate *priv = gdk_gl_context_get_instance_private (self);
+
+ if (GDK_DISPLAY_DEBUG_CHECK (gdk_gl_context_get_display (self), GL_GLES))
+ {
+ if (!(api & GDK_GL_API_GLES))
+ {
+ g_set_error_literal (error, GDK_GL_ERROR, GDK_GL_ERROR_NOT_AVAILABLE,
+ _("Anything but OpenGL ES disabled via GDK_DEBUG"));
+ return FALSE;
+ }
+ }
+
+ if (priv->allowed_apis & api)
+ return TRUE;
+
+ g_set_error (error, GDK_GL_ERROR, GDK_GL_ERROR_NOT_AVAILABLE,
+ _("Application does not support %s API"),
+ api == GDK_GL_API_GL ? "OpenGL" : "OpenGL ES");
+
+ return FALSE;
+}
+
/**
* gdk_gl_context_set_use_es:
* @context: a `GdkGLContext`
* You should check the return value of [method@Gdk.GLContext.get_use_es]
* after calling [method@Gdk.GLContext.realize] to decide whether to use
* the OpenGL or OpenGL ES API, extensions, or shaders.
- *
- * Deprecated: 4.6: Use gdk_gl_context_set_allowed_apis() instead.
*/
void
gdk_gl_context_set_use_es (GdkGLContext *context,
int use_es)
{
- GdkGLContextPrivate *priv = gdk_gl_context_get_instance_private (context);
-
g_return_if_fail (GDK_IS_GL_CONTEXT (context));
- g_return_if_fail (!priv->realized);
+ g_return_if_fail (gdk_gl_context_is_realized (context));
switch (use_es)
{
g_return_val_if_fail (GDK_IS_GL_CONTEXT (context), FALSE);
- if (!priv->realized)
- return FALSE;
-
- return priv->use_es > 0;
+ return priv->api == GDK_GL_API_GLES;
}
static void APIENTRY
g_return_val_if_fail (GDK_IS_GL_CONTEXT (context), FALSE);
- if (priv->realized)
+ if (priv->api)
return TRUE;
- priv->realized = GDK_GL_CONTEXT_GET_CLASS (context)->realize (context, error);
+ priv->api = GDK_GL_CONTEXT_GET_CLASS (context)->realize (context, error);
- return priv->realized;
+ return priv->api;
}
static void
GdkDisplay *display;
#endif
- if (!priv->realized)
+ if (!gdk_gl_context_is_realized (context))
return;
if (priv->extensions_checked)
priv->gl_version = epoxy_gl_version ();
- if (priv->use_es < 0)
- priv->use_es = !epoxy_is_desktop_gl ();
-
priv->has_debug_output = epoxy_has_gl_extension ("GL_ARB_debug_output") ||
epoxy_has_gl_extension ("GL_KHR_debug");
glDebugMessageCallback (gl_debug_message_callback, NULL);
}
- if (priv->use_es)
+ if (gdk_gl_context_get_use_es (context))
{
priv->has_unpack_subimage = epoxy_has_gl_extension ("GL_EXT_unpack_subimage");
priv->has_khr_debug = epoxy_has_gl_extension ("GL_KHR_debug");
"* Extensions checked:\n"
" - GL_KHR_debug: %s\n"
" - GL_EXT_unpack_subimage: %s",
- priv->use_es ? "OpenGL ES" : "OpenGL",
+ gdk_gl_context_get_use_es (context) ? "OpenGL ES" : "OpenGL",
priv->gl_version / 10, priv->gl_version % 10,
priv->is_legacy ? "legacy" : "core",
glGetString (GL_SHADING_LANGUAGE_VERSION),
void
gdk_gl_context_make_current (GdkGLContext *context)
{
- GdkGLContextPrivate *priv = gdk_gl_context_get_instance_private (context);
MaskedContext *current, *masked_context;
gboolean surfaceless;
return;
/* we need to realize the GdkGLContext if it wasn't explicitly realized */
- if (!priv->realized)
+ if (!gdk_gl_context_is_realized (context))
{
GError *error = NULL;
GdkGLContextPrivate *priv = gdk_gl_context_get_instance_private (context);
g_return_if_fail (GDK_IS_GL_CONTEXT (context));
- g_return_if_fail (priv->realized);
+ g_return_if_fail (gdk_gl_context_is_realized (context));
if (major != NULL)
*major = priv->gl_version / 10;
}
#endif
-static gboolean
+static GdkGLAPI
gdk_x11_gl_context_glx_realize (GdkGLContext *context,
GError **error)
{
Display *dpy;
GdkSurface *surface;
GdkGLContext *share;
- gboolean debug_bit, compat_bit, legacy_bit, es_bit;
+ gboolean debug_bit, compat_bit, legacy_bit;
int major, minor, flags;
+ GdkGLAPI api = 0;
display = gdk_gl_context_get_display (context);
dpy = gdk_x11_display_get_xdisplay (display);
/* If there is no glXCreateContextAttribsARB() then we default to legacy */
legacy_bit = !display_x11->has_glx_create_context || GDK_DISPLAY_DEBUG_CHECK (display, GL_LEGACY);
- es_bit = (GDK_DISPLAY_DEBUG_CHECK (display, GL_GLES) || (share != NULL && gdk_gl_context_get_use_es (share))) &&
- (display_x11->has_glx_create_context && display_x11->has_glx_create_es2_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.
flags |= GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB;
GDK_DISPLAY_NOTE (display, OPENGL,
- g_message ("Creating GLX context (GL version:%d.%d, debug:%s, forward:%s, legacy:%s, es:%s)",
+ g_message ("Creating GLX context (GL version:%d.%d, debug:%s, forward:%s, legacy:%s, GL:%s, GLES:%s)",
major, minor,
debug_bit ? "yes" : "no",
compat_bit ? "yes" : "no",
legacy_bit ? "yes" : "no",
- es_bit ? "yes" : "no"));
+ gdk_gl_context_is_api_allowed (context, GDK_GL_API_GL, NULL) ? "yes" : "no",
+ gdk_gl_context_is_api_allowed (context, GDK_GL_API_GLES, NULL) ? "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
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);
+ /* do it below */
}
else
{
- int profile;
+ if (gdk_gl_context_is_api_allowed (context, GDK_GL_API_GL, NULL))
+ {
+ int profile = legacy_bit ? GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB
+ : GLX_CONTEXT_CORE_PROFILE_BIT_ARB;
- if (es_bit)
- profile = GLX_CONTEXT_ES2_PROFILE_BIT_EXT;
- else
- 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;
+ }
- /* 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_DISPLAY_NOTE (display, OPENGL, g_message ("Creating GL3 context"));
+ context_glx->glx_context = create_gl3_context (display,
+ display_x11->glx_config,
+ share,
+ profile,
+ flags, major, minor);
+ api = GDK_GL_API_GL;
}
- GDK_DISPLAY_NOTE (display, OPENGL, g_message ("Creating GL3 context"));
- context_glx->glx_context = create_gl3_context (display,
- display_x11->glx_config,
- share,
- profile, flags, major, minor);
-
- /* Fall back to legacy in case the GL3 context creation failed */
- if (context_glx->glx_context == NULL)
+ if (context_glx->glx_context == NULL && !legacy_bit &&
+ gdk_gl_context_is_api_allowed (context, GDK_GL_API_GLES, 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);
- legacy_bit = TRUE;
- es_bit = FALSE;
+ GDK_DISPLAY_NOTE (display, OPENGL, g_message ("Creating GL3 GLES context"));
+ context_glx->glx_context = create_gl3_context (display,
+ display_x11->glx_config,
+ share,
+ GLX_CONTEXT_ES2_PROFILE_BIT_EXT,
+ flags, major, minor);
+ api = GDK_GL_API_GLES;
}
}
+ /* Fall back to legacy in case the GL3 context creation failed */
+ if (context_glx->glx_context == NULL &&
+ gdk_gl_context_is_api_allowed (context, GDK_GL_API_GL, 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);
+ legacy_bit = TRUE;
+ api = GDK_GL_API_GL;
+ }
+
if (context_glx->glx_context == NULL)
{
g_set_error_literal (error, GDK_GL_ERROR,
GDK_GL_ERROR_NOT_AVAILABLE,
_("Unable to create a GL context"));
- return FALSE;
+ return 0;
}
/* Ensure that any other context is created with a legacy bit set */
gdk_gl_context_set_is_legacy (context, legacy_bit);
- /* Ensure that any other context is created with an ES bit set */
- gdk_gl_context_set_use_es (context, es_bit);
-
GDK_DISPLAY_NOTE (display, OPENGL,
g_message ("Realized GLX context[%p], %s, version: %d.%d",
context_glx->glx_context,
}
#endif
- return TRUE;
+ return api;
}
static void