forked from AuroraMiddleware/gtk
egl: Unify contexts
Unify the X11 and Wayland EGL contexts. This is a bit ugly to implement, because I don't want to create an interface and I can't make them inherit from the same object, because one needs to inherit from X11GLContext and the other from WaylandGLContext. So we have to put the code in GdkGLContext and make sure non-EGL contexts can't accidentally run it. This is rather easy because we can just check for priv->egl_context != NULL.
This commit is contained in:
parent
03cc603093
commit
2ff1ea555f
@ -80,6 +80,7 @@
|
||||
#include "gdkdisplayprivate.h"
|
||||
#include "gdkintl.h"
|
||||
#include "gdkmemorytextureprivate.h"
|
||||
#include "gdkprofilerprivate.h"
|
||||
|
||||
#include "gdk-private.h"
|
||||
|
||||
@ -88,6 +89,9 @@
|
||||
#endif
|
||||
|
||||
#include <epoxy/gl.h>
|
||||
#ifdef HAVE_EGL
|
||||
#include <epoxy/egl.h>
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
int major;
|
||||
@ -107,6 +111,10 @@ typedef struct {
|
||||
int use_es;
|
||||
|
||||
int max_debug_label_length;
|
||||
|
||||
#ifdef HAVE_EGL
|
||||
EGLContext egl_context;
|
||||
#endif
|
||||
} GdkGLContextPrivate;
|
||||
|
||||
enum {
|
||||
@ -161,6 +169,24 @@ static void
|
||||
gdk_gl_context_dispose (GObject *gobject)
|
||||
{
|
||||
GdkGLContext *context = GDK_GL_CONTEXT (gobject);
|
||||
#ifdef HAVE_EGL
|
||||
GdkGLContextPrivate *priv = gdk_gl_context_get_instance_private (context);
|
||||
|
||||
if (priv->egl_context != NULL)
|
||||
{
|
||||
GdkSurface *surface = gdk_gl_context_get_surface (context);
|
||||
GdkDisplay *display = gdk_surface_get_display (surface);
|
||||
EGLDisplay *egl_display = gdk_display_get_egl_display (display);
|
||||
|
||||
if (eglGetCurrentContext () == priv->egl_context)
|
||||
eglMakeCurrent(egl_display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
|
||||
|
||||
GDK_DISPLAY_NOTE (display, OPENGL, g_message ("Destroying EGL context"));
|
||||
|
||||
eglDestroyContext (egl_display, priv->egl_context);
|
||||
priv->egl_context = NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
gdk_gl_context_clear_old_updated_area (context);
|
||||
|
||||
@ -320,20 +346,219 @@ gdk_gl_context_upload_texture (GdkGLContext *context,
|
||||
g_free (copy);
|
||||
}
|
||||
|
||||
#define N_EGL_ATTRS 16
|
||||
|
||||
static gboolean
|
||||
gdk_gl_context_real_realize (GdkGLContext *self,
|
||||
gdk_gl_context_real_realize (GdkGLContext *context,
|
||||
GError **error)
|
||||
{
|
||||
#if HAVE_EGL
|
||||
GdkGLContextPrivate *priv = gdk_gl_context_get_instance_private (context);
|
||||
GdkDisplay *display = gdk_gl_context_get_display (context);
|
||||
EGLDisplay egl_display = gdk_display_get_egl_display (display);
|
||||
|
||||
if (egl_display)
|
||||
{
|
||||
EGLConfig egl_config = gdk_display_get_egl_config (display);
|
||||
GdkGLContext *share = gdk_display_get_gl_context (display);
|
||||
GdkGLContextPrivate *share_priv = gdk_gl_context_get_instance_private (share);
|
||||
EGLContext ctx;
|
||||
EGLint context_attribs[N_EGL_ATTRS];
|
||||
int major, minor, flags;
|
||||
gboolean debug_bit, forward_bit, legacy_bit, use_es;
|
||||
int i = 0;
|
||||
G_GNUC_UNUSED gint64 start_time = GDK_PROFILER_CURRENT_TIME;
|
||||
|
||||
gdk_gl_context_get_required_version (context, &major, &minor);
|
||||
debug_bit = gdk_gl_context_get_debug_enabled (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));
|
||||
use_es = GDK_DISPLAY_DEBUG_CHECK (display, GL_GLES) ||
|
||||
(share != NULL && gdk_gl_context_get_use_es (share));
|
||||
|
||||
flags = 0;
|
||||
|
||||
if (debug_bit)
|
||||
flags |= EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR;
|
||||
if (forward_bit)
|
||||
flags |= EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR;
|
||||
|
||||
if (!use_es)
|
||||
{
|
||||
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
|
||||
? EGL_CONTEXT_OPENGL_COMPATIBILITY_PROFILE_BIT_KHR
|
||||
: EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT_KHR;
|
||||
|
||||
/* 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;
|
||||
}
|
||||
else
|
||||
{
|
||||
eglBindAPI (EGL_OPENGL_ES_API);
|
||||
|
||||
context_attribs[i++] = EGL_CONTEXT_CLIENT_VERSION;
|
||||
if (major == 3)
|
||||
context_attribs[i++] = 3;
|
||||
else
|
||||
context_attribs[i++] = 2;
|
||||
}
|
||||
|
||||
/* Specify the flags */
|
||||
context_attribs[i++] = EGL_CONTEXT_FLAGS_KHR;
|
||||
context_attribs[i++] = flags;
|
||||
|
||||
context_attribs[i++] = EGL_NONE;
|
||||
g_assert (i < N_EGL_ATTRS);
|
||||
|
||||
GDK_DISPLAY_NOTE (display, OPENGL,
|
||||
g_message ("Creating EGL context version %d.%d (debug:%s, forward:%s, legacy:%s, es:%s)",
|
||||
major, minor,
|
||||
debug_bit ? "yes" : "no",
|
||||
forward_bit ? "yes" : "no",
|
||||
legacy_bit ? "yes" : "no",
|
||||
use_es ? "yes" : "no"));
|
||||
|
||||
ctx = eglCreateContext (egl_display,
|
||||
egl_config,
|
||||
share != NULL ? share_priv->egl_context
|
||||
: EGL_NO_CONTEXT,
|
||||
context_attribs);
|
||||
|
||||
/* If context creation failed without the ES bit, let's try again with it */
|
||||
if (ctx == NULL)
|
||||
{
|
||||
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);
|
||||
|
||||
eglBindAPI (EGL_OPENGL_ES_API);
|
||||
|
||||
legacy_bit = FALSE;
|
||||
use_es = TRUE;
|
||||
|
||||
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)
|
||||
{
|
||||
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);
|
||||
|
||||
eglBindAPI (EGL_OPENGL_API);
|
||||
|
||||
legacy_bit = TRUE;
|
||||
use_es = FALSE;
|
||||
|
||||
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)
|
||||
{
|
||||
g_set_error_literal (error, GDK_GL_ERROR,
|
||||
GDK_GL_ERROR_NOT_AVAILABLE,
|
||||
_("Unable to create a GL context"));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
#endif
|
||||
|
||||
g_set_error_literal (error, GDK_GL_ERROR, GDK_GL_ERROR_NOT_AVAILABLE,
|
||||
"The current backend does not support OpenGL");
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
#undef N_EGL_ATTRS
|
||||
|
||||
static cairo_region_t *
|
||||
gdk_gl_context_real_get_damage (GdkGLContext *context)
|
||||
{
|
||||
GdkSurface *surface = gdk_draw_context_get_surface (GDK_DRAW_CONTEXT (context));
|
||||
#ifdef HAVE_EGL
|
||||
GdkGLContextPrivate *priv = gdk_gl_context_get_instance_private (context);
|
||||
GdkDisplay *display = gdk_draw_context_get_display (GDK_DRAW_CONTEXT (context));
|
||||
|
||||
if (priv->egl_context && display->have_egl_buffer_age)
|
||||
{
|
||||
EGLSurface egl_surface;
|
||||
int buffer_age = 0;
|
||||
egl_surface = gdk_surface_get_egl_surface (surface);
|
||||
gdk_gl_context_make_current (context);
|
||||
eglQuerySurface (gdk_display_get_egl_display (display), egl_surface,
|
||||
EGL_BUFFER_AGE_EXT, &buffer_age);
|
||||
|
||||
switch (buffer_age)
|
||||
{
|
||||
case 1:
|
||||
return cairo_region_create ();
|
||||
break;
|
||||
|
||||
case 2:
|
||||
if (context->old_updated_area[0])
|
||||
return cairo_region_copy (context->old_updated_area[0]);
|
||||
break;
|
||||
|
||||
case 3:
|
||||
if (context->old_updated_area[0] &&
|
||||
context->old_updated_area[1])
|
||||
{
|
||||
cairo_region_t *damage = cairo_region_copy (context->old_updated_area[0]);
|
||||
cairo_region_union (damage, context->old_updated_area[1]);
|
||||
return damage;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return cairo_region_create_rectangle (&(GdkRectangle) {
|
||||
0, 0,
|
||||
@ -354,6 +579,51 @@ gdk_gl_context_real_is_shared (GdkGLContext *self,
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gdk_gl_context_real_clear_current (GdkGLContext *context)
|
||||
{
|
||||
GdkDisplay *display = gdk_gl_context_get_display (context);
|
||||
#ifdef HAVE_EGL
|
||||
GdkGLContextPrivate *priv = gdk_gl_context_get_instance_private (context);
|
||||
|
||||
if (priv->egl_context == NULL)
|
||||
return FALSE;
|
||||
|
||||
return eglMakeCurrent (gdk_display_get_egl_display (display),
|
||||
EGL_NO_SURFACE,
|
||||
EGL_NO_SURFACE,
|
||||
EGL_NO_CONTEXT);
|
||||
#else
|
||||
return FALSE;
|
||||
#endif
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gdk_gl_context_real_make_current (GdkGLContext *context,
|
||||
gboolean surfaceless)
|
||||
{
|
||||
#ifdef HAVE_EGL
|
||||
GdkGLContextPrivate *priv = gdk_gl_context_get_instance_private (context);
|
||||
GdkDisplay *display = gdk_gl_context_get_display (context);
|
||||
EGLSurface egl_surface;
|
||||
|
||||
if (priv->egl_context == NULL)
|
||||
return FALSE;
|
||||
|
||||
if (!surfaceless)
|
||||
egl_surface = gdk_surface_get_egl_surface (gdk_gl_context_get_surface (context));
|
||||
else
|
||||
egl_surface = EGL_NO_SURFACE;
|
||||
|
||||
return eglMakeCurrent (gdk_display_get_egl_display (display),
|
||||
egl_surface,
|
||||
egl_surface,
|
||||
priv->egl_context);
|
||||
#else
|
||||
return FALSE;
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_gl_context_real_begin_frame (GdkDrawContext *draw_context,
|
||||
cairo_region_t *region)
|
||||
@ -392,6 +662,52 @@ static void
|
||||
gdk_gl_context_real_end_frame (GdkDrawContext *draw_context,
|
||||
cairo_region_t *painted)
|
||||
{
|
||||
#ifdef HAVE_EGL
|
||||
GdkGLContext *context = GDK_GL_CONTEXT (draw_context);
|
||||
GdkGLContextPrivate *priv = gdk_gl_context_get_instance_private (context);
|
||||
GdkSurface *surface = gdk_gl_context_get_surface (context);
|
||||
GdkDisplay *display = gdk_surface_get_display (surface);
|
||||
EGLSurface egl_surface;
|
||||
|
||||
if (priv->egl_context == NULL)
|
||||
return;
|
||||
|
||||
gdk_gl_context_make_current (context);
|
||||
|
||||
egl_surface = gdk_surface_get_egl_surface (surface);
|
||||
|
||||
gdk_profiler_add_mark (GDK_PROFILER_CURRENT_TIME, 0, "EGL", "swap buffers");
|
||||
|
||||
if (display->have_egl_swap_buffers_with_damage)
|
||||
{
|
||||
EGLint stack_rects[4 * 4]; /* 4 rects */
|
||||
EGLint *heap_rects = NULL;
|
||||
int i, j, n_rects = cairo_region_num_rectangles (painted);
|
||||
int surface_height = gdk_surface_get_height (surface);
|
||||
int scale = gdk_surface_get_scale_factor (surface);
|
||||
EGLint *rects;
|
||||
|
||||
if (n_rects < G_N_ELEMENTS (stack_rects) / 4)
|
||||
rects = (EGLint *)&stack_rects;
|
||||
else
|
||||
heap_rects = rects = g_new (EGLint, n_rects * 4);
|
||||
|
||||
for (i = 0, j = 0; i < n_rects; i++)
|
||||
{
|
||||
cairo_rectangle_int_t rect;
|
||||
|
||||
cairo_region_get_rectangle (painted, i, &rect);
|
||||
rects[j++] = rect.x * scale;
|
||||
rects[j++] = (surface_height - rect.height - rect.y) * scale;
|
||||
rects[j++] = rect.width * scale;
|
||||
rects[j++] = rect.height * scale;
|
||||
}
|
||||
eglSwapBuffersWithDamageEXT (gdk_display_get_egl_display (display), egl_surface, rects, n_rects);
|
||||
g_free (heap_rects);
|
||||
}
|
||||
else
|
||||
eglSwapBuffers (gdk_display_get_egl_display (display), egl_surface);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
@ -411,6 +727,8 @@ gdk_gl_context_class_init (GdkGLContextClass *klass)
|
||||
klass->realize = gdk_gl_context_real_realize;
|
||||
klass->get_damage = gdk_gl_context_real_get_damage;
|
||||
klass->is_shared = gdk_gl_context_real_is_shared;
|
||||
klass->make_current = gdk_gl_context_real_make_current;
|
||||
klass->clear_current = gdk_gl_context_real_clear_current;
|
||||
|
||||
draw_context_class->begin_frame = gdk_gl_context_real_begin_frame;
|
||||
draw_context_class->end_frame = gdk_gl_context_real_end_frame;
|
||||
@ -1357,3 +1675,4 @@ gdk_gl_backend_use (GdkGLBackend backend_type)
|
||||
|
||||
g_assert (the_gl_backend_type == backend_type);
|
||||
}
|
||||
|
||||
|
@ -133,7 +133,6 @@ gboolean gdk_gl_context_has_debug (GdkGLContext
|
||||
|
||||
gboolean gdk_gl_context_use_es_bgra (GdkGLContext *context);
|
||||
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GDK_GL_CONTEXT_PRIVATE_H__ */
|
||||
|
@ -45,239 +45,6 @@
|
||||
|
||||
G_DEFINE_TYPE (GdkWaylandGLContext, gdk_wayland_gl_context, GDK_TYPE_GL_CONTEXT)
|
||||
|
||||
static void gdk_wayland_gl_context_dispose (GObject *gobject);
|
||||
|
||||
#define N_EGL_ATTRS 16
|
||||
|
||||
static gboolean
|
||||
gdk_wayland_gl_context_realize (GdkGLContext *context,
|
||||
GError **error)
|
||||
{
|
||||
GdkWaylandGLContext *context_wayland = GDK_WAYLAND_GL_CONTEXT (context);
|
||||
GdkDisplay *display = gdk_gl_context_get_display (context);
|
||||
GdkGLContext *share = gdk_display_get_gl_context (display);
|
||||
EGLDisplay egl_display = gdk_display_get_egl_display (display);
|
||||
EGLConfig egl_config = gdk_display_get_egl_config (display);
|
||||
EGLContext ctx;
|
||||
EGLint context_attribs[N_EGL_ATTRS];
|
||||
int major, minor, flags;
|
||||
gboolean debug_bit, forward_bit, legacy_bit, use_es;
|
||||
int i = 0;
|
||||
G_GNUC_UNUSED gint64 start_time = GDK_PROFILER_CURRENT_TIME;
|
||||
|
||||
gdk_gl_context_get_required_version (context, &major, &minor);
|
||||
debug_bit = gdk_gl_context_get_debug_enabled (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));
|
||||
use_es = GDK_DISPLAY_DEBUG_CHECK (display, GL_GLES) ||
|
||||
(share != NULL && gdk_gl_context_get_use_es (share));
|
||||
|
||||
flags = 0;
|
||||
|
||||
if (debug_bit)
|
||||
flags |= EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR;
|
||||
if (forward_bit)
|
||||
flags |= EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR;
|
||||
|
||||
if (!use_es)
|
||||
{
|
||||
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
|
||||
? EGL_CONTEXT_OPENGL_COMPATIBILITY_PROFILE_BIT_KHR
|
||||
: EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT_KHR;
|
||||
|
||||
/* 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;
|
||||
}
|
||||
else
|
||||
{
|
||||
eglBindAPI (EGL_OPENGL_ES_API);
|
||||
|
||||
context_attribs[i++] = EGL_CONTEXT_CLIENT_VERSION;
|
||||
if (major == 3)
|
||||
context_attribs[i++] = 3;
|
||||
else
|
||||
context_attribs[i++] = 2;
|
||||
}
|
||||
|
||||
/* Specify the flags */
|
||||
context_attribs[i++] = EGL_CONTEXT_FLAGS_KHR;
|
||||
context_attribs[i++] = flags;
|
||||
|
||||
context_attribs[i++] = EGL_NONE;
|
||||
g_assert (i < N_EGL_ATTRS);
|
||||
|
||||
GDK_DISPLAY_NOTE (display, OPENGL,
|
||||
g_message ("Creating EGL context version %d.%d (debug:%s, forward:%s, legacy:%s, es:%s)",
|
||||
major, minor,
|
||||
debug_bit ? "yes" : "no",
|
||||
forward_bit ? "yes" : "no",
|
||||
legacy_bit ? "yes" : "no",
|
||||
use_es ? "yes" : "no"));
|
||||
|
||||
ctx = eglCreateContext (egl_display,
|
||||
egl_config,
|
||||
share != NULL ? GDK_WAYLAND_GL_CONTEXT (share)->egl_context
|
||||
: EGL_NO_CONTEXT,
|
||||
context_attribs);
|
||||
|
||||
/* If context creation failed without the ES bit, let's try again with it */
|
||||
if (ctx == NULL)
|
||||
{
|
||||
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);
|
||||
|
||||
eglBindAPI (EGL_OPENGL_ES_API);
|
||||
|
||||
legacy_bit = FALSE;
|
||||
use_es = TRUE;
|
||||
|
||||
GDK_DISPLAY_NOTE (display, OPENGL,
|
||||
g_message ("eglCreateContext failed, switching to OpenGL ES"));
|
||||
ctx = eglCreateContext (egl_display,
|
||||
egl_config,
|
||||
share != NULL ? GDK_WAYLAND_GL_CONTEXT (share)->egl_context
|
||||
: EGL_NO_CONTEXT,
|
||||
context_attribs);
|
||||
}
|
||||
|
||||
/* If context creation failed without the legacy bit, let's try again with it */
|
||||
if (ctx == NULL)
|
||||
{
|
||||
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);
|
||||
|
||||
eglBindAPI (EGL_OPENGL_API);
|
||||
|
||||
legacy_bit = TRUE;
|
||||
use_es = FALSE;
|
||||
|
||||
GDK_DISPLAY_NOTE (display, OPENGL,
|
||||
g_message ("eglCreateContext failed, switching to legacy"));
|
||||
ctx = eglCreateContext (egl_display,
|
||||
egl_config,
|
||||
share != NULL ? GDK_WAYLAND_GL_CONTEXT (share)->egl_context
|
||||
: EGL_NO_CONTEXT,
|
||||
context_attribs);
|
||||
}
|
||||
|
||||
if (ctx == NULL)
|
||||
{
|
||||
g_set_error_literal (error, GDK_GL_ERROR,
|
||||
GDK_GL_ERROR_NOT_AVAILABLE,
|
||||
_("Unable to create a GL context"));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
GDK_DISPLAY_NOTE (display, OPENGL, g_message ("Created EGL context[%p]", ctx));
|
||||
|
||||
context_wayland->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;
|
||||
}
|
||||
|
||||
static cairo_region_t *
|
||||
gdk_wayland_gl_context_get_damage (GdkGLContext *context)
|
||||
{
|
||||
GdkDisplay *display = gdk_draw_context_get_display (GDK_DRAW_CONTEXT (context));
|
||||
EGLSurface egl_surface;
|
||||
GdkSurface *surface = gdk_draw_context_get_surface (GDK_DRAW_CONTEXT (context));
|
||||
int buffer_age = 0;
|
||||
|
||||
if (display->have_egl_buffer_age)
|
||||
{
|
||||
egl_surface = gdk_surface_get_egl_surface (surface);
|
||||
gdk_gl_context_make_current (context);
|
||||
eglQuerySurface (gdk_display_get_egl_display (display), egl_surface,
|
||||
EGL_BUFFER_AGE_EXT, &buffer_age);
|
||||
|
||||
switch (buffer_age)
|
||||
{
|
||||
case 1:
|
||||
return cairo_region_create ();
|
||||
break;
|
||||
|
||||
case 2:
|
||||
if (context->old_updated_area[0])
|
||||
return cairo_region_copy (context->old_updated_area[0]);
|
||||
break;
|
||||
|
||||
case 3:
|
||||
if (context->old_updated_area[0] &&
|
||||
context->old_updated_area[1])
|
||||
{
|
||||
cairo_region_t *damage = cairo_region_copy (context->old_updated_area[0]);
|
||||
cairo_region_union (damage, context->old_updated_area[1]);
|
||||
return damage;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
return GDK_GL_CONTEXT_CLASS (gdk_wayland_gl_context_parent_class)->get_damage (context);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gdk_wayland_gl_context_clear_current (GdkGLContext *context)
|
||||
{
|
||||
GdkDisplay *display = gdk_gl_context_get_display (context);
|
||||
|
||||
return eglMakeCurrent (gdk_display_get_egl_display (display),
|
||||
EGL_NO_SURFACE,
|
||||
EGL_NO_SURFACE,
|
||||
EGL_NO_CONTEXT);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gdk_wayland_gl_context_make_current (GdkGLContext *context,
|
||||
gboolean surfaceless)
|
||||
{
|
||||
GdkWaylandGLContext *context_wayland = GDK_WAYLAND_GL_CONTEXT (context);
|
||||
GdkDisplay *display = gdk_gl_context_get_display (context);
|
||||
EGLSurface egl_surface;
|
||||
|
||||
if (!surfaceless)
|
||||
egl_surface = gdk_surface_get_egl_surface (gdk_gl_context_get_surface (context));
|
||||
else
|
||||
egl_surface = EGL_NO_SURFACE;
|
||||
|
||||
return eglMakeCurrent (gdk_display_get_egl_display (display),
|
||||
egl_surface,
|
||||
egl_surface,
|
||||
context_wayland->egl_context);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_wayland_gl_context_begin_frame (GdkDrawContext *draw_context,
|
||||
cairo_region_t *region)
|
||||
@ -293,49 +60,12 @@ static void
|
||||
gdk_wayland_gl_context_end_frame (GdkDrawContext *draw_context,
|
||||
cairo_region_t *painted)
|
||||
{
|
||||
GdkGLContext *context = GDK_GL_CONTEXT (draw_context);
|
||||
GdkSurface *surface = gdk_gl_context_get_surface (context);
|
||||
GdkDisplay *display = gdk_surface_get_display (surface);
|
||||
EGLSurface egl_surface;
|
||||
GdkSurface *surface = gdk_draw_context_get_surface (draw_context);
|
||||
|
||||
GDK_DRAW_CONTEXT_CLASS (gdk_wayland_gl_context_parent_class)->end_frame (draw_context, painted);
|
||||
|
||||
gdk_gl_context_make_current (context);
|
||||
|
||||
egl_surface = gdk_surface_get_egl_surface (surface);
|
||||
gdk_wayland_surface_sync (surface);
|
||||
gdk_wayland_surface_request_frame (surface);
|
||||
|
||||
gdk_profiler_add_mark (GDK_PROFILER_CURRENT_TIME, 0, "wayland", "swap buffers");
|
||||
if (display->have_egl_swap_buffers_with_damage)
|
||||
{
|
||||
EGLint stack_rects[4 * 4]; /* 4 rects */
|
||||
EGLint *heap_rects = NULL;
|
||||
int i, j, n_rects = cairo_region_num_rectangles (painted);
|
||||
int surface_height = gdk_surface_get_height (surface);
|
||||
int scale = gdk_surface_get_scale_factor (surface);
|
||||
EGLint *rects;
|
||||
|
||||
if (n_rects < G_N_ELEMENTS (stack_rects) / 4)
|
||||
rects = (EGLint *)&stack_rects;
|
||||
else
|
||||
heap_rects = rects = g_new (EGLint, n_rects * 4);
|
||||
|
||||
for (i = 0, j = 0; i < n_rects; i++)
|
||||
{
|
||||
cairo_rectangle_int_t rect;
|
||||
|
||||
cairo_region_get_rectangle (painted, i, &rect);
|
||||
rects[j++] = rect.x * scale;
|
||||
rects[j++] = (surface_height - rect.height - rect.y) * scale;
|
||||
rects[j++] = rect.width * scale;
|
||||
rects[j++] = rect.height * scale;
|
||||
}
|
||||
eglSwapBuffersWithDamageEXT (gdk_display_get_egl_display (display), egl_surface, rects, n_rects);
|
||||
g_free (heap_rects);
|
||||
}
|
||||
else
|
||||
eglSwapBuffers (gdk_display_get_egl_display (display), egl_surface);
|
||||
GDK_DRAW_CONTEXT_CLASS (gdk_wayland_gl_context_parent_class)->end_frame (draw_context, painted);
|
||||
|
||||
gdk_wayland_surface_notify_committed (surface);
|
||||
}
|
||||
@ -343,20 +73,12 @@ gdk_wayland_gl_context_end_frame (GdkDrawContext *draw_context,
|
||||
static void
|
||||
gdk_wayland_gl_context_class_init (GdkWaylandGLContextClass *klass)
|
||||
{
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
||||
GdkDrawContextClass *draw_context_class = GDK_DRAW_CONTEXT_CLASS (klass);
|
||||
GdkGLContextClass *context_class = GDK_GL_CONTEXT_CLASS (klass);
|
||||
|
||||
gobject_class->dispose = gdk_wayland_gl_context_dispose;
|
||||
|
||||
draw_context_class->begin_frame = gdk_wayland_gl_context_begin_frame;
|
||||
draw_context_class->end_frame = gdk_wayland_gl_context_end_frame;
|
||||
|
||||
context_class->realize = gdk_wayland_gl_context_realize;
|
||||
context_class->make_current = gdk_wayland_gl_context_make_current;
|
||||
context_class->clear_current = gdk_wayland_gl_context_clear_current;
|
||||
context_class->get_damage = gdk_wayland_gl_context_get_damage;
|
||||
|
||||
context_class->backend_type = GDK_GL_EGL;
|
||||
}
|
||||
|
||||
@ -401,27 +123,3 @@ gdk_wayland_display_init_gl (GdkDisplay *display,
|
||||
NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_wayland_gl_context_dispose (GObject *gobject)
|
||||
{
|
||||
GdkWaylandGLContext *context_wayland = GDK_WAYLAND_GL_CONTEXT (gobject);
|
||||
|
||||
if (context_wayland->egl_context != NULL)
|
||||
{
|
||||
GdkGLContext *context = GDK_GL_CONTEXT (gobject);
|
||||
GdkSurface *surface = gdk_gl_context_get_surface (context);
|
||||
GdkDisplay *display = gdk_surface_get_display (surface);
|
||||
EGLDisplay *egl_display = gdk_display_get_egl_display (display);
|
||||
|
||||
if (eglGetCurrentContext () == context_wayland->egl_context)
|
||||
eglMakeCurrent(egl_display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
|
||||
|
||||
GDK_DISPLAY_NOTE (display, OPENGL, g_message ("Destroying EGL context"));
|
||||
|
||||
eglDestroyContext (egl_display, context_wayland->egl_context);
|
||||
context_wayland->egl_context = NULL;
|
||||
}
|
||||
|
||||
G_OBJECT_CLASS (gdk_wayland_gl_context_parent_class)->dispose (gobject);
|
||||
}
|
||||
|
||||
|
@ -33,8 +33,6 @@ G_BEGIN_DECLS
|
||||
struct _GdkWaylandGLContext
|
||||
{
|
||||
GdkGLContext parent_instance;
|
||||
|
||||
EGLContext egl_context;
|
||||
};
|
||||
|
||||
struct _GdkWaylandGLContextClass
|
||||
|
@ -32,8 +32,6 @@ struct _GdkX11GLContextEGL
|
||||
{
|
||||
GdkX11GLContext parent_instance;
|
||||
|
||||
EGLContext egl_context;
|
||||
|
||||
guint do_frame_sync : 1;
|
||||
};
|
||||
|
||||
@ -70,66 +68,6 @@ gdk_x11_gl_context_egl_begin_frame (GdkDrawContext *draw_context,
|
||||
glDrawBuffers (1, (GLenum[1]) { GL_BACK });
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_x11_gl_context_egl_end_frame (GdkDrawContext *draw_context,
|
||||
cairo_region_t *painted)
|
||||
{
|
||||
GdkGLContext *context = GDK_GL_CONTEXT (draw_context);
|
||||
GdkSurface *surface = gdk_gl_context_get_surface (context);
|
||||
GdkDisplay *display = gdk_surface_get_display (surface);
|
||||
EGLSurface egl_surface;
|
||||
|
||||
GDK_DRAW_CONTEXT_CLASS (gdk_x11_gl_context_egl_parent_class)->end_frame (draw_context, painted);
|
||||
|
||||
gdk_gl_context_make_current (context);
|
||||
|
||||
egl_surface = gdk_surface_get_egl_surface (surface);
|
||||
|
||||
gdk_profiler_add_mark (GDK_PROFILER_CURRENT_TIME, 0, "x11", "swap buffers");
|
||||
if (display->have_egl_swap_buffers_with_damage)
|
||||
{
|
||||
int i, j, n_rects = cairo_region_num_rectangles (painted);
|
||||
int surface_height = gdk_surface_get_height (surface);
|
||||
int scale = gdk_surface_get_scale_factor (surface);
|
||||
EGLint stack_rects[4 * 4]; /* 4 rects */
|
||||
EGLint *heap_rects = NULL;
|
||||
EGLint *rects;
|
||||
|
||||
if (n_rects < G_N_ELEMENTS (stack_rects) / 4)
|
||||
rects = (EGLint *) &stack_rects;
|
||||
else
|
||||
rects = heap_rects = g_new (EGLint, n_rects * 4);
|
||||
|
||||
for (i = 0, j = 0; i < n_rects; i++)
|
||||
{
|
||||
cairo_rectangle_int_t rect;
|
||||
|
||||
cairo_region_get_rectangle (painted, i, &rect);
|
||||
|
||||
rects[j++] = rect.x * scale;
|
||||
rects[j++] = (surface_height - rect.height - rect.y) * scale;
|
||||
rects[j++] = rect.width * scale;
|
||||
rects[j++] = rect.height * scale;
|
||||
}
|
||||
|
||||
eglSwapBuffersWithDamageEXT (gdk_display_get_egl_display (display), egl_surface, rects, n_rects);
|
||||
g_free (heap_rects);
|
||||
}
|
||||
else
|
||||
eglSwapBuffers (gdk_display_get_egl_display (display), egl_surface);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gdk_x11_gl_context_egl_clear_current (GdkGLContext *context)
|
||||
{
|
||||
GdkDisplay *display = gdk_gl_context_get_display (context);
|
||||
|
||||
return eglMakeCurrent (gdk_display_get_egl_display (display),
|
||||
EGL_NO_SURFACE,
|
||||
EGL_NO_SURFACE,
|
||||
EGL_NO_CONTEXT);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gdk_x11_gl_context_egl_make_current (GdkGLContext *context,
|
||||
gboolean surfaceless)
|
||||
@ -137,31 +75,14 @@ gdk_x11_gl_context_egl_make_current (GdkGLContext *context,
|
||||
GdkX11GLContextEGL *self = GDK_X11_GL_CONTEXT_EGL (context);
|
||||
GdkDisplay *display = gdk_gl_context_get_display (context);
|
||||
EGLDisplay egl_display = gdk_display_get_egl_display (display);
|
||||
GdkSurface *surface;
|
||||
EGLSurface egl_surface;
|
||||
gboolean do_frame_sync = FALSE;
|
||||
|
||||
if (surfaceless)
|
||||
{
|
||||
return eglMakeCurrent (egl_display,
|
||||
EGL_NO_SURFACE,
|
||||
EGL_NO_SURFACE,
|
||||
self->egl_context);
|
||||
}
|
||||
|
||||
surface = gdk_gl_context_get_surface (context);
|
||||
egl_surface = gdk_surface_get_egl_surface (surface);
|
||||
|
||||
GDK_DISPLAY_NOTE (display, OPENGL,
|
||||
g_message ("Making EGL context %p current to surface %p",
|
||||
self->egl_context, egl_surface));
|
||||
|
||||
if (!eglMakeCurrent (gdk_display_get_egl_display (display),
|
||||
egl_surface,
|
||||
egl_surface,
|
||||
self->egl_context))
|
||||
if (!GDK_GL_CONTEXT_CLASS (gdk_x11_gl_context_egl_parent_class)->make_current (context, surfaceless))
|
||||
return FALSE;
|
||||
|
||||
if (surfaceless)
|
||||
return TRUE;
|
||||
|
||||
/* If the WM is compositing there is no particular need to delay
|
||||
* the swap when drawing on the offscreen, rendering to the screen
|
||||
* happens later anyway, and its up to the compositor to sync that
|
||||
@ -181,222 +102,17 @@ gdk_x11_gl_context_egl_make_current (GdkGLContext *context,
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static cairo_region_t *
|
||||
gdk_x11_gl_context_egl_get_damage (GdkGLContext *context)
|
||||
{
|
||||
GdkDisplay *display = gdk_draw_context_get_display (GDK_DRAW_CONTEXT (context));
|
||||
|
||||
if (display->have_egl_buffer_age)
|
||||
{
|
||||
GdkSurface *surface = gdk_draw_context_get_surface (GDK_DRAW_CONTEXT (context));
|
||||
EGLSurface egl_surface;
|
||||
int buffer_age = 0;
|
||||
|
||||
egl_surface = gdk_surface_get_egl_surface (surface);
|
||||
gdk_gl_context_make_current (context);
|
||||
|
||||
eglQuerySurface (gdk_display_get_egl_display (display),
|
||||
egl_surface,
|
||||
EGL_BUFFER_AGE_EXT,
|
||||
&buffer_age);
|
||||
|
||||
switch (buffer_age)
|
||||
{
|
||||
case 1:
|
||||
return cairo_region_create ();
|
||||
|
||||
case 2:
|
||||
if (context->old_updated_area[0])
|
||||
return cairo_region_copy (context->old_updated_area[0]);
|
||||
break;
|
||||
|
||||
case 3:
|
||||
if (context->old_updated_area[0] && context->old_updated_area[1])
|
||||
{
|
||||
cairo_region_t *damage = cairo_region_copy (context->old_updated_area[0]);
|
||||
cairo_region_union (damage, context->old_updated_area[1]);
|
||||
return damage;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return GDK_GL_CONTEXT_CLASS (gdk_x11_gl_context_egl_parent_class)->get_damage (context);
|
||||
}
|
||||
|
||||
#define N_EGL_ATTRS 16
|
||||
|
||||
static gboolean
|
||||
gdk_x11_gl_context_egl_realize (GdkGLContext *context,
|
||||
GError **error)
|
||||
{
|
||||
GdkDisplay *display;
|
||||
GdkX11GLContextEGL *context_egl;
|
||||
GdkGLContext *share;
|
||||
EGLDisplay egl_display;
|
||||
EGLConfig egl_config;
|
||||
gboolean debug_bit, forward_bit, legacy_bit, use_es;
|
||||
int major, minor, flags, i = 0;
|
||||
EGLint context_attrs[N_EGL_ATTRS];
|
||||
|
||||
display = gdk_gl_context_get_display (context);
|
||||
|
||||
context_egl = GDK_X11_GL_CONTEXT_EGL (context);
|
||||
share = gdk_display_get_gl_context (display);
|
||||
egl_display = gdk_display_get_egl_display (display),
|
||||
egl_config = gdk_display_get_egl_config (display),
|
||||
|
||||
gdk_gl_context_get_required_version (context, &major, &minor);
|
||||
debug_bit = gdk_gl_context_get_debug_enabled (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));
|
||||
use_es = GDK_DISPLAY_DEBUG_CHECK (display, GL_GLES) ||
|
||||
(share != NULL && gdk_gl_context_get_use_es (share));
|
||||
|
||||
flags = 0;
|
||||
if (debug_bit)
|
||||
flags |= EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR;
|
||||
if (forward_bit)
|
||||
flags |= EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR;
|
||||
|
||||
if (!use_es)
|
||||
{
|
||||
eglBindAPI (EGL_OPENGL_API);
|
||||
|
||||
/* We want a core profile, unless in legacy mode */
|
||||
context_attrs[i++] = EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR;
|
||||
context_attrs[i++] = legacy_bit
|
||||
? EGL_CONTEXT_OPENGL_COMPATIBILITY_PROFILE_BIT_KHR
|
||||
: EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT_KHR;
|
||||
|
||||
/* Specify the version */
|
||||
context_attrs[i++] = EGL_CONTEXT_MAJOR_VERSION_KHR;
|
||||
context_attrs[i++] = legacy_bit ? 3 : major;
|
||||
context_attrs[i++] = EGL_CONTEXT_MINOR_VERSION_KHR;
|
||||
context_attrs[i++] = legacy_bit ? 0 : minor;
|
||||
context_attrs[i++] = EGL_CONTEXT_FLAGS_KHR;
|
||||
}
|
||||
else
|
||||
{
|
||||
eglBindAPI (EGL_OPENGL_ES_API);
|
||||
|
||||
context_attrs[i++] = EGL_CONTEXT_CLIENT_VERSION;
|
||||
if (major == 3)
|
||||
context_attrs[i++] = 3;
|
||||
else
|
||||
context_attrs[i++] = 2;
|
||||
}
|
||||
|
||||
context_attrs[i++] = EGL_CONTEXT_FLAGS_KHR;
|
||||
context_attrs[i++] = flags;
|
||||
|
||||
context_attrs[i++] = EGL_NONE;
|
||||
g_assert (i < N_EGL_ATTRS);
|
||||
|
||||
GDK_DISPLAY_NOTE (display, OPENGL,
|
||||
g_message ("Creating EGL context version %d.%d (shared:%s, debug:%s, forward:%s, legacy:%s, es:%s)",
|
||||
major, minor,
|
||||
share != NULL ? "yes" : "no",
|
||||
debug_bit ? "yes" : "no",
|
||||
forward_bit ? "yes" : "no",
|
||||
legacy_bit ? "yes" : "no",
|
||||
use_es ? "yes" : "no"));
|
||||
|
||||
context_egl->egl_context =
|
||||
eglCreateContext (egl_display,
|
||||
egl_config,
|
||||
share != NULL
|
||||
? GDK_X11_GL_CONTEXT_EGL (share)->egl_context
|
||||
: EGL_NO_CONTEXT,
|
||||
context_attrs);
|
||||
|
||||
/* If we're not asking for a GLES context, and we don't have the legacy bit set
|
||||
* already, try again with a legacy context
|
||||
*/
|
||||
if (context_egl->egl_context == NULL && !use_es && !legacy_bit)
|
||||
{
|
||||
context_attrs[1] = EGL_CONTEXT_OPENGL_COMPATIBILITY_PROFILE_BIT_KHR;
|
||||
context_attrs[3] = 3;
|
||||
context_attrs[5] = 0;
|
||||
|
||||
legacy_bit = TRUE;
|
||||
use_es = FALSE;
|
||||
|
||||
GDK_NOTE (OPENGL,
|
||||
g_message ("Context creation failed; trying legacy EGL context"));
|
||||
|
||||
context_egl->egl_context =
|
||||
eglCreateContext (egl_display,
|
||||
egl_config,
|
||||
share != NULL
|
||||
? GDK_X11_GL_CONTEXT_EGL (share)->egl_context
|
||||
: EGL_NO_CONTEXT,
|
||||
context_attrs);
|
||||
}
|
||||
|
||||
if (context_egl->egl_context == NULL)
|
||||
{
|
||||
g_set_error_literal (error, GDK_GL_ERROR, GDK_GL_ERROR_NOT_AVAILABLE,
|
||||
_("Unable to create a GL context"));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
gdk_gl_context_set_is_legacy (context, legacy_bit);
|
||||
gdk_gl_context_set_use_es (context, use_es);
|
||||
|
||||
GDK_NOTE (OPENGL,
|
||||
g_message ("Realized EGL context[%p]",
|
||||
context_egl->egl_context));
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
#undef N_EGL_ATTRS
|
||||
|
||||
static void
|
||||
gdk_x11_gl_context_egl_dispose (GObject *gobject)
|
||||
{
|
||||
GdkX11GLContextEGL *context_egl = GDK_X11_GL_CONTEXT_EGL (gobject);
|
||||
|
||||
if (context_egl->egl_context != NULL)
|
||||
{
|
||||
GdkGLContext *context = GDK_GL_CONTEXT (gobject);
|
||||
GdkDisplay *display = gdk_gl_context_get_display (context);
|
||||
|
||||
/* Unset the current context if we're disposing it */
|
||||
if (eglGetCurrentContext () == context_egl->egl_context)
|
||||
eglMakeCurrent (gdk_display_get_egl_display (display), EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
|
||||
|
||||
GDK_NOTE (OPENGL, g_message ("Destroying EGL context"));
|
||||
eglDestroyContext (gdk_display_get_egl_display (display), context_egl->egl_context);
|
||||
context_egl->egl_context = NULL;
|
||||
}
|
||||
|
||||
G_OBJECT_CLASS (gdk_x11_gl_context_egl_parent_class)->dispose (gobject);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_x11_gl_context_egl_class_init (GdkX11GLContextEGLClass *klass)
|
||||
{
|
||||
GdkGLContextClass *context_class = GDK_GL_CONTEXT_CLASS (klass);
|
||||
GdkDrawContextClass *draw_context_class = GDK_DRAW_CONTEXT_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->make_current = gdk_x11_gl_context_egl_make_current;
|
||||
context_class->clear_current = gdk_x11_gl_context_egl_clear_current;
|
||||
context_class->get_damage = gdk_x11_gl_context_egl_get_damage;
|
||||
|
||||
draw_context_class->begin_frame = gdk_x11_gl_context_egl_begin_frame;
|
||||
draw_context_class->end_frame = gdk_x11_gl_context_egl_end_frame;
|
||||
|
||||
gobject_class->dispose = gdk_x11_gl_context_egl_dispose;
|
||||
}
|
||||
|
||||
static void
|
||||
|
Loading…
Reference in New Issue
Block a user