forked from AuroraMiddleware/gtk
glcontext: Refactor realize function, fix interaction with shared context
This commit is contained in:
parent
f4f0daa113
commit
549a2b4c86
@ -255,83 +255,83 @@ gdk_gl_context_get_property (GObject *object,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#define N_EGL_ATTRS 16
|
#define N_EGL_ATTRS 16
|
||||||
|
|
||||||
|
#ifdef HAVE_EGL
|
||||||
|
static inline EGLenum
|
||||||
|
gdk_api_to_egl_api (GdkGLAPI api)
|
||||||
|
{
|
||||||
|
switch (api)
|
||||||
|
{
|
||||||
|
case GDK_GL_API_GLES:
|
||||||
|
return EGL_OPENGL_ES_API;
|
||||||
|
case GDK_GL_API_GL:
|
||||||
|
default:
|
||||||
|
return EGL_OPENGL_API;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static GdkGLAPI
|
static GdkGLAPI
|
||||||
gdk_gl_context_realize_egl (GdkGLContext *context,
|
gdk_gl_context_create_egl_context (GdkGLContext *context,
|
||||||
GError **error)
|
GdkGLAPI api,
|
||||||
|
gboolean legacy)
|
||||||
{
|
{
|
||||||
GdkGLContextPrivate *priv = gdk_gl_context_get_instance_private (context);
|
GdkGLContextPrivate *priv = gdk_gl_context_get_instance_private (context);
|
||||||
GdkDisplay *display = gdk_gl_context_get_display (context);
|
GdkDisplay *display = gdk_gl_context_get_display (context);
|
||||||
EGLDisplay egl_display = gdk_display_get_egl_display (display);
|
EGLDisplay egl_display = gdk_display_get_egl_display (display);
|
||||||
|
|
||||||
EGLConfig egl_config;
|
|
||||||
GdkGLContext *share = gdk_display_get_gl_context (display);
|
GdkGLContext *share = gdk_display_get_gl_context (display);
|
||||||
GdkGLContextPrivate *share_priv = gdk_gl_context_get_instance_private (share);
|
GdkGLContextPrivate *share_priv = gdk_gl_context_get_instance_private (share);
|
||||||
|
EGLConfig egl_config;
|
||||||
EGLContext ctx;
|
EGLContext ctx;
|
||||||
EGLint context_attribs[N_EGL_ATTRS];
|
EGLint context_attribs[N_EGL_ATTRS], i = 0, flags = 0;
|
||||||
int major, minor, flags;
|
gboolean debug_bit, forward_bit;
|
||||||
gboolean debug_bit, forward_bit, legacy_bit;
|
int min_major, min_minor, major = 0, minor = 0;
|
||||||
GdkGLAPI api;
|
|
||||||
int i = 0;
|
|
||||||
G_GNUC_UNUSED gint64 start_time = GDK_PROFILER_CURRENT_TIME;
|
G_GNUC_UNUSED gint64 start_time = GDK_PROFILER_CURRENT_TIME;
|
||||||
|
|
||||||
if (share != NULL)
|
if (!gdk_gl_context_is_api_allowed (context, api, NULL))
|
||||||
gdk_gl_context_get_required_version (share, &major, &minor);
|
return 0;
|
||||||
else
|
|
||||||
gdk_gl_context_get_required_version (context, &major, &minor);
|
/* We will use the default version matching the context status
|
||||||
|
* unless the user requested a version which makes sense */
|
||||||
|
gdk_gl_context_get_matching_version (api, legacy,
|
||||||
|
display->have_egl_win32_libangle,
|
||||||
|
&min_major, &min_minor);
|
||||||
|
gdk_gl_context_get_clipped_version (context,
|
||||||
|
min_major, min_minor,
|
||||||
|
&major, &minor);
|
||||||
|
|
||||||
|
if (!eglBindAPI (gdk_api_to_egl_api (api)))
|
||||||
|
return 0;
|
||||||
|
|
||||||
debug_bit = gdk_gl_context_get_debug_enabled (context);
|
debug_bit = gdk_gl_context_get_debug_enabled (context);
|
||||||
forward_bit = gdk_gl_context_get_forward_compatible (context);
|
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));
|
|
||||||
|
|
||||||
if (display->have_egl_no_config_context)
|
if (display->have_egl_no_config_context)
|
||||||
egl_config = NULL;
|
egl_config = NULL;
|
||||||
else
|
else
|
||||||
egl_config = gdk_display_get_egl_config (display);
|
egl_config = gdk_display_get_egl_config (display);
|
||||||
|
|
||||||
flags = 0;
|
|
||||||
|
|
||||||
if (debug_bit)
|
if (debug_bit)
|
||||||
flags |= EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR;
|
flags |= EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR;
|
||||||
if (forward_bit)
|
if (forward_bit)
|
||||||
flags |= EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR;
|
flags |= EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR;
|
||||||
|
|
||||||
if (gdk_gl_context_is_api_allowed (context, GDK_GL_API_GL, NULL) &&
|
if (api == GDK_GL_API_GL)
|
||||||
eglBindAPI (EGL_OPENGL_API))
|
|
||||||
{
|
{
|
||||||
/* We want a core profile, unless in legacy mode */
|
/* We want a core profile, unless in legacy mode */
|
||||||
context_attribs[i++] = EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR;
|
context_attribs[i++] = EGL_CONTEXT_OPENGL_PROFILE_MASK;
|
||||||
context_attribs[i++] = legacy_bit
|
context_attribs[i++] = legacy
|
||||||
? EGL_CONTEXT_OPENGL_COMPATIBILITY_PROFILE_BIT_KHR
|
? EGL_CONTEXT_OPENGL_COMPATIBILITY_PROFILE_BIT
|
||||||
: EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT_KHR;
|
: EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT;
|
||||||
|
|
||||||
/* Specify the version */
|
|
||||||
context_attribs[i++] = EGL_CONTEXT_MAJOR_VERSION_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 (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 does not support any allowed APIs"));
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Specify the flags */
|
if (legacy || api == GDK_GL_API_GLES)
|
||||||
|
flags &= ~EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR;
|
||||||
|
|
||||||
|
context_attribs[i++] = EGL_CONTEXT_MAJOR_VERSION;
|
||||||
|
context_attribs[i++] = major;
|
||||||
|
context_attribs[i++] = EGL_CONTEXT_MINOR_VERSION;
|
||||||
|
context_attribs[i++] = minor;
|
||||||
context_attribs[i++] = EGL_CONTEXT_FLAGS_KHR;
|
context_attribs[i++] = EGL_CONTEXT_FLAGS_KHR;
|
||||||
context_attribs[i++] = flags;
|
context_attribs[i++] = flags;
|
||||||
|
|
||||||
@ -343,91 +343,82 @@ gdk_gl_context_realize_egl (GdkGLContext *context,
|
|||||||
major, minor,
|
major, minor,
|
||||||
debug_bit ? "yes" : "no",
|
debug_bit ? "yes" : "no",
|
||||||
forward_bit ? "yes" : "no",
|
forward_bit ? "yes" : "no",
|
||||||
legacy_bit ? "yes" : "no",
|
legacy ? "yes" : "no",
|
||||||
api == GDK_GL_API_GLES ? "yes" : "no"));
|
api == GDK_GL_API_GLES ? "yes" : "no"));
|
||||||
|
|
||||||
ctx = eglCreateContext (egl_display,
|
ctx = eglCreateContext (egl_display,
|
||||||
egl_config,
|
egl_config,
|
||||||
share != NULL ? share_priv->egl_context
|
share ? share_priv->egl_context : EGL_NO_CONTEXT,
|
||||||
: EGL_NO_CONTEXT,
|
|
||||||
context_attribs);
|
context_attribs);
|
||||||
|
|
||||||
/* If context creation failed without the ES bit, let's try again with it */
|
|
||||||
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;
|
|
||||||
context_attribs[i++] = 2;
|
|
||||||
context_attribs[i++] = EGL_CONTEXT_MINOR_VERSION;
|
|
||||||
context_attribs[i++] = 0;
|
|
||||||
context_attribs[i++] = EGL_CONTEXT_FLAGS_KHR;
|
|
||||||
context_attribs[i++] = flags & ~EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR;
|
|
||||||
context_attribs[i++] = EGL_NONE;
|
|
||||||
g_assert (i < N_EGL_ATTRS);
|
|
||||||
|
|
||||||
legacy_bit = FALSE;
|
|
||||||
api = GDK_GL_API_GLES;
|
|
||||||
|
|
||||||
GDK_DISPLAY_NOTE (display, OPENGL,
|
|
||||||
g_message ("eglCreateContext failed, switching to OpenGL ES"));
|
|
||||||
ctx = eglCreateContext (egl_display,
|
|
||||||
egl_config,
|
|
||||||
share != NULL ? share_priv->egl_context
|
|
||||||
: EGL_NO_CONTEXT,
|
|
||||||
context_attribs);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* If context creation failed without the legacy bit, let's try again with it */
|
|
||||||
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;
|
|
||||||
context_attribs[i++] = EGL_CONTEXT_OPENGL_COMPATIBILITY_PROFILE_BIT_KHR;
|
|
||||||
context_attribs[i++] = EGL_CONTEXT_MAJOR_VERSION;
|
|
||||||
context_attribs[i++] = 3;
|
|
||||||
context_attribs[i++] = EGL_CONTEXT_MINOR_VERSION;
|
|
||||||
context_attribs[i++] = 0;
|
|
||||||
context_attribs[i++] = EGL_CONTEXT_FLAGS_KHR;
|
|
||||||
context_attribs[i++] = flags & ~EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR;
|
|
||||||
context_attribs[i++] = EGL_NONE;
|
|
||||||
g_assert (i < N_EGL_ATTRS);
|
|
||||||
|
|
||||||
legacy_bit = TRUE;
|
|
||||||
api = GDK_GL_API_GL;
|
|
||||||
|
|
||||||
GDK_DISPLAY_NOTE (display, OPENGL,
|
|
||||||
g_message ("eglCreateContext failed, switching to legacy"));
|
|
||||||
ctx = eglCreateContext (egl_display,
|
|
||||||
egl_config,
|
|
||||||
share != NULL ? share_priv->egl_context
|
|
||||||
: EGL_NO_CONTEXT,
|
|
||||||
context_attribs);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ctx == NULL)
|
if (ctx == NULL)
|
||||||
{
|
|
||||||
g_set_error_literal (error, GDK_GL_ERROR,
|
|
||||||
GDK_GL_ERROR_NOT_AVAILABLE,
|
|
||||||
_("Unable to create a GL context"));
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
|
||||||
|
|
||||||
GDK_DISPLAY_NOTE (display, OPENGL, g_message ("Created EGL context[%p]", ctx));
|
GDK_DISPLAY_NOTE (display, OPENGL, g_message ("Created EGL context[%p]", ctx));
|
||||||
|
|
||||||
priv->egl_context = ctx;
|
priv->egl_context = ctx;
|
||||||
|
gdk_gl_context_set_is_legacy (context, legacy);
|
||||||
gdk_gl_context_set_is_legacy (context, legacy_bit);
|
|
||||||
|
|
||||||
if (epoxy_has_egl_extension (egl_display, "EGL_KHR_swap_buffers_with_damage"))
|
if (epoxy_has_egl_extension (egl_display, "EGL_KHR_swap_buffers_with_damage"))
|
||||||
priv->eglSwapBuffersWithDamage = (gpointer)epoxy_eglGetProcAddress ("eglSwapBuffersWithDamageKHR");
|
priv->eglSwapBuffersWithDamage = (gpointer) epoxy_eglGetProcAddress ("eglSwapBuffersWithDamageKHR");
|
||||||
else if (epoxy_has_egl_extension (egl_display, "EGL_EXT_swap_buffers_with_damage"))
|
else if (epoxy_has_egl_extension (egl_display, "EGL_EXT_swap_buffers_with_damage"))
|
||||||
priv->eglSwapBuffersWithDamage = (gpointer)epoxy_eglGetProcAddress ("eglSwapBuffersWithDamageEXT");
|
priv->eglSwapBuffersWithDamage = (gpointer) epoxy_eglGetProcAddress ("eglSwapBuffersWithDamageEXT");
|
||||||
|
|
||||||
gdk_profiler_end_mark (start_time, "realize GdkWaylandGLContext", NULL);
|
gdk_profiler_end_mark (start_time, "realize GdkWaylandGLContext", NULL);
|
||||||
|
|
||||||
return api;
|
return api;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static GdkGLAPI
|
||||||
|
gdk_gl_context_realize_egl (GdkGLContext *context,
|
||||||
|
GError **error)
|
||||||
|
{
|
||||||
|
GdkDisplay *display = gdk_gl_context_get_display (context);
|
||||||
|
GdkGLContext *share = gdk_display_get_gl_context (display);
|
||||||
|
GdkGLAPI api, preferred_api;
|
||||||
|
gboolean prefer_legacy;
|
||||||
|
|
||||||
|
if (share && gdk_gl_context_is_api_allowed (context,
|
||||||
|
gdk_gl_context_get_api (share),
|
||||||
|
NULL))
|
||||||
|
preferred_api = gdk_gl_context_get_api (share);
|
||||||
|
else if (gdk_gl_context_is_api_allowed (context, GDK_GL_API_GL, NULL))
|
||||||
|
preferred_api = GDK_GL_API_GL;
|
||||||
|
else if (gdk_gl_context_is_api_allowed (context, GDK_GL_API_GLES, NULL))
|
||||||
|
preferred_api = GDK_GL_API_GLES;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
g_set_error_literal (error, GDK_GL_ERROR,
|
||||||
|
GDK_GL_ERROR_NOT_AVAILABLE,
|
||||||
|
_("No GL API allowed."));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
prefer_legacy = (GDK_DISPLAY_DEBUG_CHECK (display, GL_LEGACY) ||
|
||||||
|
(share != NULL && gdk_gl_context_is_legacy (share)));
|
||||||
|
|
||||||
|
if (preferred_api == GDK_GL_API_GL)
|
||||||
|
{
|
||||||
|
if ((api = gdk_gl_context_create_egl_context (context, GDK_GL_API_GL, prefer_legacy)) ||
|
||||||
|
(api = gdk_gl_context_create_egl_context (context, GDK_GL_API_GLES, FALSE)) ||
|
||||||
|
(api = gdk_gl_context_create_egl_context (context, GDK_GL_API_GL, TRUE)))
|
||||||
|
return api;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if ((api = gdk_gl_context_create_egl_context (context, GDK_GL_API_GLES, FALSE)) ||
|
||||||
|
(api = gdk_gl_context_create_egl_context (context, GDK_GL_API_GL, prefer_legacy)) ||
|
||||||
|
(api = gdk_gl_context_create_egl_context (context, GDK_GL_API_GL, TRUE)))
|
||||||
|
return api;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_set_error_literal (error, GDK_GL_ERROR,
|
||||||
|
GDK_GL_ERROR_NOT_AVAILABLE,
|
||||||
|
_("Unable to create a GL context"));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif /* HAVE_EGL */
|
||||||
|
|
||||||
static GdkGLAPI
|
static GdkGLAPI
|
||||||
gdk_gl_context_default_realize (GdkGLContext *context,
|
gdk_gl_context_default_realize (GdkGLContext *context,
|
||||||
GError **error)
|
GError **error)
|
||||||
@ -966,6 +957,48 @@ gdk_gl_context_get_forward_compatible (GdkGLContext *context)
|
|||||||
return priv->forward_compatible;
|
return priv->forward_compatible;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
gdk_gl_context_get_matching_version (GdkGLAPI api,
|
||||||
|
gboolean legacy,
|
||||||
|
gboolean win32_libangle,
|
||||||
|
int *major,
|
||||||
|
int *minor)
|
||||||
|
{
|
||||||
|
int maj, min;
|
||||||
|
|
||||||
|
if (api == GDK_GL_API_GL)
|
||||||
|
{
|
||||||
|
if (legacy)
|
||||||
|
{
|
||||||
|
maj = GDK_GL_MIN_GL_LEGACY_VERSION_MAJOR;
|
||||||
|
min = GDK_GL_MIN_GL_LEGACY_VERSION_MINOR;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
maj = GDK_GL_MIN_GL_VERSION_MAJOR;
|
||||||
|
min = GDK_GL_MIN_GL_VERSION_MINOR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (win32_libangle)
|
||||||
|
{
|
||||||
|
maj = GDK_GL_MIN_GLES_WIN32_ANGLE_VERSION_MAJOR;
|
||||||
|
min = GDK_GL_MIN_GLES_WIN32_ANGLE_VERSION_MINOR;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
maj = GDK_GL_MIN_GLES_VERSION_MAJOR;
|
||||||
|
min = GDK_GL_MIN_GLES_VERSION_MINOR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (major != NULL)
|
||||||
|
*major = maj;
|
||||||
|
if (minor != NULL)
|
||||||
|
*minor = min;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* gdk_gl_context_set_required_version:
|
* gdk_gl_context_set_required_version:
|
||||||
* @context: a `GdkGLContext`
|
* @context: a `GdkGLContext`
|
||||||
|
@ -33,6 +33,22 @@ 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)
|
||||||
|
|
||||||
|
/* Minimum OpenGL versions supported by GTK.
|
||||||
|
* Backends should make sure to never create a context of a previous version.
|
||||||
|
*
|
||||||
|
* The macros refer to OpenGL; OpenGL with OPENGL_COMPATIBILITY_PROFILE_BIT as
|
||||||
|
* OPENGL_PROFILE_MASK; OpenGL ES; and OpenGL ES win32 Angle implementation,
|
||||||
|
* respectively
|
||||||
|
*/
|
||||||
|
#define GDK_GL_MIN_GL_VERSION_MAJOR (3)
|
||||||
|
#define GDK_GL_MIN_GL_VERSION_MINOR (2)
|
||||||
|
#define GDK_GL_MIN_GL_LEGACY_VERSION_MAJOR (3)
|
||||||
|
#define GDK_GL_MIN_GL_LEGACY_VERSION_MINOR (0)
|
||||||
|
#define GDK_GL_MIN_GLES_VERSION_MAJOR (2)
|
||||||
|
#define GDK_GL_MIN_GLES_VERSION_MINOR (0)
|
||||||
|
#define GDK_GL_MIN_GLES_WIN32_ANGLE_VERSION_MAJOR (3)
|
||||||
|
#define GDK_GL_MIN_GLES_WIN32_ANGLE_VERSION_MINOR (0)
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
GDK_GL_NONE = 0,
|
GDK_GL_NONE = 0,
|
||||||
GDK_GL_EGL,
|
GDK_GL_EGL,
|
||||||
@ -122,6 +138,11 @@ void gdk_gl_context_get_clipped_version (GdkGLContext
|
|||||||
int min_minor,
|
int min_minor,
|
||||||
int *major,
|
int *major,
|
||||||
int *minor);
|
int *minor);
|
||||||
|
void gdk_gl_context_get_matching_version (GdkGLAPI api,
|
||||||
|
gboolean legacy,
|
||||||
|
gboolean win32_libangle,
|
||||||
|
int *major,
|
||||||
|
int *minor);
|
||||||
|
|
||||||
gboolean gdk_gl_context_has_unpack_subimage (GdkGLContext *context);
|
gboolean gdk_gl_context_has_unpack_subimage (GdkGLContext *context);
|
||||||
void gdk_gl_context_push_debug_group (GdkGLContext *context,
|
void gdk_gl_context_push_debug_group (GdkGLContext *context,
|
||||||
|
Loading…
Reference in New Issue
Block a user