mirror of
https://gitlab.gnome.org/GNOME/gtk.git
synced 2024-11-09 18:30:08 +00:00
gl: Move vfunc
Instead of Display::make_gl_context_current() we now have GLContext::clear_current() GLContext::make_current() This fits better with the backends (we can actually implement clearCurrent on macOS now) and makes it easier to implement different GL backends for backends (like EGL/GLX on X11). We also pass a surfaceless boolean to make_current() so the calling code can decide if a surface needs to be bound or not, because the backends were all doing whatever, which was very counterproductive.
This commit is contained in:
parent
15ed1a329e
commit
9f1d6e1f44
@ -1298,21 +1298,6 @@ gdk_display_get_gl_context (GdkDisplay *self)
|
||||
return priv->gl_context;
|
||||
}
|
||||
|
||||
/*< private >
|
||||
* gdk_display_make_gl_context_current:
|
||||
* @display: a `GdkDisplay`
|
||||
* @context: (optional): a `GdkGLContext`
|
||||
*
|
||||
* Makes the given @context the current GL context, or unsets
|
||||
* the current GL context if @context is %NULL.
|
||||
*/
|
||||
gboolean
|
||||
gdk_display_make_gl_context_current (GdkDisplay *display,
|
||||
GdkGLContext *context)
|
||||
{
|
||||
return GDK_DISPLAY_GET_CLASS (display)->make_gl_context_current (display, context);
|
||||
}
|
||||
|
||||
GdkDebugFlags
|
||||
gdk_display_get_debug_flags (GdkDisplay *display)
|
||||
{
|
||||
|
@ -142,8 +142,6 @@ struct _GdkDisplayClass
|
||||
|
||||
GdkGLContext * (*init_gl) (GdkDisplay *display,
|
||||
GError **error);
|
||||
gboolean (*make_gl_context_current) (GdkDisplay *display,
|
||||
GdkGLContext *context);
|
||||
|
||||
GdkSeat * (*get_default_seat) (GdkDisplay *display);
|
||||
|
||||
@ -209,8 +207,6 @@ GdkSurface * gdk_display_create_surface (GdkDisplay *display
|
||||
int height);
|
||||
|
||||
GdkGLContext * gdk_display_get_gl_context (GdkDisplay *display);
|
||||
gboolean gdk_display_make_gl_context_current (GdkDisplay *display,
|
||||
GdkGLContext *context);
|
||||
|
||||
void gdk_display_set_rgba (GdkDisplay *display,
|
||||
gboolean rgba);
|
||||
|
@ -128,9 +128,10 @@ G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (GdkGLContext, gdk_gl_context, GDK_TYPE_DRAW
|
||||
typedef struct _MaskedContext MaskedContext;
|
||||
|
||||
static inline MaskedContext *
|
||||
mask_context (GdkGLContext *context)
|
||||
mask_context (GdkGLContext *context,
|
||||
gboolean surfaceless)
|
||||
{
|
||||
return (MaskedContext *) GSIZE_TO_POINTER (GPOINTER_TO_SIZE (context) | (gdk_draw_context_is_in_frame (GDK_DRAW_CONTEXT (context)) ? 1 : 0));
|
||||
return (MaskedContext *) GSIZE_TO_POINTER (GPOINTER_TO_SIZE (context) | (surfaceless ? 1 : 0));
|
||||
}
|
||||
|
||||
static inline GdkGLContext *
|
||||
@ -1138,10 +1139,12 @@ gdk_gl_context_make_current (GdkGLContext *context)
|
||||
{
|
||||
GdkGLContextPrivate *priv = gdk_gl_context_get_instance_private (context);
|
||||
MaskedContext *current, *masked_context;
|
||||
gboolean surfaceless;
|
||||
|
||||
g_return_if_fail (GDK_IS_GL_CONTEXT (context));
|
||||
|
||||
masked_context = mask_context (context);
|
||||
surfaceless = !gdk_draw_context_is_in_frame (GDK_DRAW_CONTEXT (context));
|
||||
masked_context = mask_context (context, surfaceless);
|
||||
|
||||
current = g_private_get (&thread_current_context);
|
||||
if (current == masked_context)
|
||||
@ -1161,12 +1164,15 @@ gdk_gl_context_make_current (GdkGLContext *context)
|
||||
}
|
||||
}
|
||||
|
||||
if (gdk_display_make_gl_context_current (gdk_draw_context_get_display (GDK_DRAW_CONTEXT (context)), context))
|
||||
if (!GDK_GL_CONTEXT_GET_CLASS (context)->make_current (context, surfaceless))
|
||||
{
|
||||
g_object_ref (context);
|
||||
g_private_replace (&thread_current_context, masked_context);
|
||||
gdk_gl_context_check_extensions (context);
|
||||
g_warning ("gdk_gl_context_make_current() failed");
|
||||
return;
|
||||
}
|
||||
|
||||
g_object_ref (context);
|
||||
g_private_replace (&thread_current_context, masked_context);
|
||||
gdk_gl_context_check_extensions (context);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1265,8 +1271,9 @@ gdk_gl_context_clear_current (void)
|
||||
current = g_private_get (&thread_current_context);
|
||||
if (current != NULL)
|
||||
{
|
||||
GdkGLContext *current_context = unmask_context (current);
|
||||
if (gdk_display_make_gl_context_current (gdk_draw_context_get_display (GDK_DRAW_CONTEXT (current_context)), NULL))
|
||||
GdkGLContext *context = unmask_context (current);
|
||||
|
||||
if (GDK_GL_CONTEXT_GET_CLASS (context)->clear_current (context))
|
||||
g_private_replace (&thread_current_context, NULL);
|
||||
}
|
||||
}
|
||||
|
@ -55,6 +55,9 @@ struct _GdkGLContextClass
|
||||
gboolean (* realize) (GdkGLContext *context,
|
||||
GError **error);
|
||||
|
||||
gboolean (* make_current) (GdkGLContext *context,
|
||||
gboolean surfaceless);
|
||||
gboolean (* clear_current) (GdkGLContext *context);
|
||||
cairo_region_t * (* get_damage) (GdkGLContext *context);
|
||||
|
||||
gboolean (* is_shared) (GdkGLContext *self,
|
||||
|
@ -644,19 +644,6 @@ gdk_macos_display_init_gl (GdkDisplay *display,
|
||||
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)
|
||||
{
|
||||
g_assert (GDK_IS_MACOS_DISPLAY (display));
|
||||
g_assert (!gl_context || GDK_IS_MACOS_GL_CONTEXT (gl_context));
|
||||
|
||||
if (gl_context == NULL)
|
||||
return FALSE;
|
||||
|
||||
return _gdk_macos_gl_context_make_current (GDK_MACOS_GL_CONTEXT (gl_context));
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_macos_display_finalize (GObject *object)
|
||||
{
|
||||
@ -703,7 +690,6 @@ gdk_macos_display_class_init (GdkMacosDisplayClass *klass)
|
||||
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;
|
||||
display_class->sync = gdk_macos_display_sync;
|
||||
|
@ -62,7 +62,6 @@ GdkGLContext *_gdk_macos_gl_context_new (GdkMacosDisplay *display,
|
||||
gboolean attached,
|
||||
GdkGLContext *share,
|
||||
GError **error);
|
||||
gboolean _gdk_macos_gl_context_make_current (GdkMacosGLContext *self);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
@ -403,6 +403,57 @@ gdk_macos_gl_context_surface_resized (GdkDrawContext *draw_context)
|
||||
g_clear_pointer (&self->damage, cairo_region_destroy);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gdk_macos_gl_context_clear_current (GdkGLContext *context)
|
||||
{
|
||||
GdkMacosGLContext *self = GDK_MACOS_GL_CONTEXT (context);
|
||||
NSOpenGLContext *current;
|
||||
|
||||
g_return_val_if_fail (GDK_IS_MACOS_GL_CONTEXT (self), FALSE);
|
||||
|
||||
current = [NSOpenGLContext currentContext];
|
||||
|
||||
if (self->gl_context == current)
|
||||
{
|
||||
/* The OpenGL mac programming guide suggests that glFlush() is called
|
||||
* before switching current contexts to ensure that the drawing commands
|
||||
* are submitted.
|
||||
*/
|
||||
if (current != NULL)
|
||||
glFlush ();
|
||||
|
||||
[NSOpenGLContext clearCurrentContext];
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gdk_macos_gl_context_make_current (GdkGLContext *context,
|
||||
gboolean surfaceless)
|
||||
{
|
||||
GdkMacosGLContext *self = GDK_MACOS_GL_CONTEXT (context);
|
||||
NSOpenGLContext *current;
|
||||
|
||||
g_return_val_if_fail (GDK_IS_MACOS_GL_CONTEXT (self), FALSE);
|
||||
|
||||
current = [NSOpenGLContext currentContext];
|
||||
|
||||
if (self->gl_context != current)
|
||||
{
|
||||
/* The OpenGL mac programming guide suggests that glFlush() is called
|
||||
* before switching current contexts to ensure that the drawing commands
|
||||
* are submitted.
|
||||
*/
|
||||
if (current != NULL)
|
||||
glFlush ();
|
||||
|
||||
[self->gl_context makeCurrentContext];
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static cairo_region_t *
|
||||
gdk_macos_gl_context_get_damage (GdkGLContext *context)
|
||||
{
|
||||
@ -494,31 +545,4 @@ _gdk_macos_gl_context_new (GdkMacosDisplay *display,
|
||||
return GDK_GL_CONTEXT (context);
|
||||
}
|
||||
|
||||
gboolean
|
||||
_gdk_macos_gl_context_make_current (GdkMacosGLContext *self)
|
||||
{
|
||||
NSOpenGLContext *current;
|
||||
|
||||
g_return_val_if_fail (GDK_IS_MACOS_GL_CONTEXT (self), FALSE);
|
||||
|
||||
if (self->gl_context == NULL)
|
||||
return FALSE;
|
||||
|
||||
current = [NSOpenGLContext currentContext];
|
||||
|
||||
if (self->gl_context != current)
|
||||
{
|
||||
/* The OpenGL mac programming guide suggests that glFlush() is called
|
||||
* before switching current contexts to ensure that the drawing commands
|
||||
* are submitted.
|
||||
*/
|
||||
if (current != NULL)
|
||||
glFlush ();
|
||||
|
||||
[self->gl_context makeCurrentContext];
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
G_GNUC_END_IGNORE_DEPRECATIONS
|
||||
|
@ -970,7 +970,6 @@ gdk_wayland_display_class_init (GdkWaylandDisplayClass *class)
|
||||
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;
|
||||
display_class->get_monitor_at_surface = gdk_wayland_display_get_monitor_at_surface;
|
||||
|
@ -245,6 +245,37 @@ gdk_wayland_gl_context_get_damage (GdkGLContext *context)
|
||||
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);
|
||||
GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (display);
|
||||
|
||||
return eglMakeCurrent (display_wayland->egl_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);
|
||||
GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (display);
|
||||
EGLSurface egl_surface;
|
||||
|
||||
if (!surfaceless)
|
||||
egl_surface = gdk_wayland_surface_get_egl_surface (gdk_gl_context_get_surface (context));
|
||||
else
|
||||
egl_surface = EGL_NO_SURFACE;
|
||||
|
||||
return eglMakeCurrent (display_wayland->egl_display,
|
||||
egl_surface,
|
||||
egl_surface,
|
||||
context_wayland->egl_context);
|
||||
}
|
||||
static void
|
||||
gdk_wayland_gl_context_end_frame (GdkDrawContext *draw_context,
|
||||
cairo_region_t *painted)
|
||||
@ -309,6 +340,8 @@ gdk_wayland_gl_context_class_init (GdkWaylandGLContextClass *klass)
|
||||
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;
|
||||
}
|
||||
|
||||
@ -556,36 +589,3 @@ gdk_wayland_gl_context_dispose (GObject *gobject)
|
||||
G_OBJECT_CLASS (gdk_wayland_gl_context_parent_class)->dispose (gobject);
|
||||
}
|
||||
|
||||
gboolean
|
||||
gdk_wayland_display_make_gl_context_current (GdkDisplay *display,
|
||||
GdkGLContext *context)
|
||||
{
|
||||
GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (display);
|
||||
GdkWaylandGLContext *context_wayland;
|
||||
GdkSurface *surface;
|
||||
EGLSurface egl_surface;
|
||||
|
||||
if (context == NULL)
|
||||
{
|
||||
eglMakeCurrent(display_wayland->egl_display, EGL_NO_SURFACE, EGL_NO_SURFACE,
|
||||
EGL_NO_CONTEXT);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
context_wayland = GDK_WAYLAND_GL_CONTEXT (context);
|
||||
surface = gdk_gl_context_get_surface (context);
|
||||
|
||||
if (gdk_draw_context_is_in_frame (GDK_DRAW_CONTEXT (context)))
|
||||
egl_surface = gdk_wayland_surface_get_egl_surface (surface);
|
||||
else
|
||||
egl_surface = EGL_NO_SURFACE;
|
||||
|
||||
if (!eglMakeCurrent (display_wayland->egl_display, egl_surface,
|
||||
egl_surface, context_wayland->egl_context))
|
||||
{
|
||||
g_warning ("eglMakeCurrent failed");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
@ -47,8 +47,6 @@ GdkGLContext * gdk_wayland_display_init_gl (GdkDisplay
|
||||
GError **error);
|
||||
GdkGLContext * gdk_wayland_surface_create_gl_context (GdkSurface *surface,
|
||||
GError **error);
|
||||
gboolean gdk_wayland_display_make_gl_context_current (GdkDisplay *display,
|
||||
GdkGLContext *context);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
@ -1165,7 +1165,6 @@ gdk_win32_display_class_init (GdkWin32DisplayClass *klass)
|
||||
display_class->create_surface = _gdk_win32_display_create_surface;
|
||||
|
||||
display_class->get_keymap = _gdk_win32_display_get_keymap;
|
||||
display_class->make_gl_context_current = _gdk_win32_display_make_gl_context_current;
|
||||
|
||||
display_class->get_monitors = gdk_win32_display_get_monitors;
|
||||
|
||||
|
@ -1046,6 +1046,95 @@ gdk_win32_gl_context_realize (GdkGLContext *context,
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gdk_win32_gl_context_clear_current (GdkGLContext *context)
|
||||
{
|
||||
GdkDisplay *display = gdk_gl_context_get_display (context);
|
||||
GdkWin32Display *display_win32 = GDK_WIN32_DISPLAY (display);
|
||||
|
||||
#ifdef GDK_WIN32_ENABLE_EGL
|
||||
if (display_win32->egl_disp != EGL_NO_DISPLAY)
|
||||
return eglMakeCurrent (display_win32->egl_disp,
|
||||
EGL_NO_SURFACE,
|
||||
EGL_NO_SURFACE,
|
||||
EGL_NO_CONTEXT);
|
||||
else
|
||||
#endif
|
||||
return wglMakeCurrent (NULL, NULL);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gdk_win32_gl_context_make_current (GdkGLContext *context,
|
||||
gboolean surfaceless)
|
||||
{
|
||||
GdkWin32GLContext *context_win32 = GDK_WIN32_GL_CONTEXT (context);
|
||||
GdkDisplay *display = gdk_gl_context_get_display (context);
|
||||
GdkWin32Display *display_win32 = GDK_WIN32_DISPLAY (display);
|
||||
GdkSurface *surface;
|
||||
|
||||
gboolean do_frame_sync = FALSE;
|
||||
|
||||
if (!gdk_gl_context_get_use_es (context))
|
||||
{
|
||||
if (!wglMakeCurrent (context_win32->gl_hdc, context_win32->hglrc))
|
||||
return FALSE;
|
||||
|
||||
if (!surfaceless && display_win32->hasWglEXTSwapControl)
|
||||
{
|
||||
surface = gdk_gl_context_get_surface (context);
|
||||
|
||||
/* If there 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
|
||||
* to the vblank. */
|
||||
display = gdk_surface_get_display (surface);
|
||||
do_frame_sync = ! gdk_display_is_composited (display);
|
||||
|
||||
if (do_frame_sync != context_win32->do_frame_sync)
|
||||
{
|
||||
context_win32->do_frame_sync = do_frame_sync;
|
||||
|
||||
if (do_frame_sync)
|
||||
wglSwapIntervalEXT (1);
|
||||
else
|
||||
wglSwapIntervalEXT (0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef GDK_WIN32_ENABLE_EGL
|
||||
else
|
||||
{
|
||||
EGLSurface egl_surface;
|
||||
|
||||
surface = gdk_gl_context_get_surface (context);
|
||||
|
||||
if (!surfaceless)
|
||||
egl_surface = _gdk_win32_surface_get_egl_surface (surface, context_win32->egl_config, FALSE);
|
||||
else
|
||||
{
|
||||
if (display_win32->hasEglSurfacelessContext)
|
||||
egl_surface = EGL_NO_SURFACE;
|
||||
else
|
||||
egl_surface = _gdk_win32_surface_get_egl_surface (surface, context_win32->egl_config, TRUE);
|
||||
}
|
||||
|
||||
if (!eglMakeCurrent (display_win32->egl_disp,
|
||||
egl_surface,
|
||||
egl_surface,
|
||||
context_win32->egl_context))
|
||||
return FALSE;
|
||||
|
||||
if (display_win32->egl_min_swap_interval == 0)
|
||||
eglSwapInterval (display_win32->egl_disp, 0);
|
||||
else
|
||||
g_debug ("Can't disable GL swap interval");
|
||||
}
|
||||
#endif
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_win32_gl_context_class_init (GdkWin32GLContextClass *klass)
|
||||
{
|
||||
@ -1115,102 +1204,6 @@ _gdk_win32_surface_create_gl_context (GdkSurface *surface,
|
||||
return GDK_GL_CONTEXT (context);
|
||||
}
|
||||
|
||||
gboolean
|
||||
_gdk_win32_display_make_gl_context_current (GdkDisplay *display,
|
||||
GdkGLContext *context)
|
||||
{
|
||||
GdkWin32GLContext *context_win32;
|
||||
GdkWin32Display *display_win32 = GDK_WIN32_DISPLAY (display);
|
||||
GdkSurface *surface;
|
||||
|
||||
gboolean do_frame_sync = FALSE;
|
||||
|
||||
if (context == NULL)
|
||||
{
|
||||
#ifdef GDK_WIN32_ENABLE_EGL
|
||||
if (display_win32->egl_disp != EGL_NO_DISPLAY)
|
||||
eglMakeCurrent(display_win32->egl_disp,
|
||||
EGL_NO_SURFACE,
|
||||
EGL_NO_SURFACE,
|
||||
EGL_NO_CONTEXT);
|
||||
else
|
||||
#endif
|
||||
wglMakeCurrent(NULL, NULL);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
context_win32 = GDK_WIN32_GL_CONTEXT (context);
|
||||
|
||||
if (!gdk_gl_context_get_use_es (context))
|
||||
{
|
||||
if (!wglMakeCurrent (context_win32->gl_hdc, context_win32->hglrc))
|
||||
{
|
||||
GDK_NOTE (OPENGL,
|
||||
g_print ("Making WGL context current failed\n"));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (gdk_draw_context_is_in_frame (GDK_DRAW_CONTEXT (context)) &&
|
||||
display_win32->hasWglEXTSwapControl)
|
||||
{
|
||||
surface = gdk_gl_context_get_surface (context);
|
||||
|
||||
/* If there 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
|
||||
* to the vblank. */
|
||||
display = gdk_surface_get_display (surface);
|
||||
do_frame_sync = ! gdk_display_is_composited (display);
|
||||
|
||||
if (do_frame_sync != context_win32->do_frame_sync)
|
||||
{
|
||||
context_win32->do_frame_sync = do_frame_sync;
|
||||
|
||||
if (do_frame_sync)
|
||||
wglSwapIntervalEXT (1);
|
||||
else
|
||||
wglSwapIntervalEXT (0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef GDK_WIN32_ENABLE_EGL
|
||||
else
|
||||
{
|
||||
EGLSurface egl_surface;
|
||||
|
||||
surface = gdk_gl_context_get_surface (context);
|
||||
|
||||
if (gdk_draw_context_is_in_frame (GDK_DRAW_CONTEXT (context)))
|
||||
egl_surface = _gdk_win32_surface_get_egl_surface (surface, context_win32->egl_config, FALSE);
|
||||
else
|
||||
{
|
||||
if (display_win32->hasEglSurfacelessContext)
|
||||
egl_surface = EGL_NO_SURFACE;
|
||||
else
|
||||
egl_surface = _gdk_win32_surface_get_egl_surface (surface, context_win32->egl_config, TRUE);
|
||||
}
|
||||
|
||||
if (!eglMakeCurrent (display_win32->egl_disp,
|
||||
egl_surface,
|
||||
egl_surface,
|
||||
context_win32->egl_context))
|
||||
{
|
||||
g_warning ("eglMakeCurrent failed");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (display_win32->egl_min_swap_interval == 0)
|
||||
eglSwapInterval (display_win32->egl_disp, 0);
|
||||
else
|
||||
g_debug ("Can't disable GL swap interval");
|
||||
}
|
||||
#endif
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_win32_display_get_wgl_version:
|
||||
* @display: a `GdkDisplay`
|
||||
|
@ -63,9 +63,6 @@ GdkGLContext *
|
||||
_gdk_win32_surface_create_gl_context (GdkSurface *window,
|
||||
GError **error);
|
||||
|
||||
gboolean
|
||||
_gdk_win32_display_make_gl_context_current (GdkDisplay *display,
|
||||
GdkGLContext *context);
|
||||
void
|
||||
_gdk_win32_surface_invalidate_egl_framebuffer (GdkSurface *surface);
|
||||
|
||||
|
@ -2923,7 +2923,6 @@ gdk_x11_display_class_init (GdkX11DisplayClass * class)
|
||||
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;
|
||||
|
||||
|
@ -360,6 +360,70 @@ gdk_x11_gl_context_egl_end_frame (GdkDrawContext *draw_context,
|
||||
eglSwapBuffers (display_x11->egl_display, egl_surface);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gdk_x11_gl_context_egl_clear_current (GdkGLContext *context)
|
||||
{
|
||||
GdkDisplay *display = gdk_gl_context_get_display (context);
|
||||
GdkX11Display *display_x11 = GDK_X11_DISPLAY (display);
|
||||
|
||||
return eglMakeCurrent (display_x11->egl_display,
|
||||
EGL_NO_SURFACE,
|
||||
EGL_NO_SURFACE,
|
||||
EGL_NO_CONTEXT);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gdk_x11_gl_context_egl_make_current (GdkGLContext *context,
|
||||
gboolean surfaceless)
|
||||
{
|
||||
GdkX11GLContextEGL *context_egl = GDK_X11_GL_CONTEXT_EGL (context);
|
||||
GdkX11GLContext *context_x11 = GDK_X11_GL_CONTEXT (context);
|
||||
GdkDisplay *display = gdk_gl_context_get_display (context);
|
||||
GdkX11Display *display_x11 = GDK_X11_DISPLAY (display);
|
||||
GdkSurface *surface;
|
||||
EGLSurface egl_surface;
|
||||
gboolean do_frame_sync = FALSE;
|
||||
|
||||
if (surfaceless)
|
||||
{
|
||||
return eglMakeCurrent (display_x11->egl_display,
|
||||
EGL_NO_SURFACE,
|
||||
EGL_NO_SURFACE,
|
||||
context_egl->egl_context);
|
||||
}
|
||||
|
||||
surface = gdk_gl_context_get_surface (context);
|
||||
egl_surface = gdk_x11_surface_get_egl_surface (surface);
|
||||
|
||||
GDK_DISPLAY_NOTE (display, OPENGL,
|
||||
g_message ("Making EGL context %p current to surface %p",
|
||||
context_egl->egl_context, egl_surface));
|
||||
|
||||
if (!eglMakeCurrent (display_x11->egl_display,
|
||||
egl_surface,
|
||||
egl_surface,
|
||||
context_egl->egl_context))
|
||||
return FALSE;
|
||||
|
||||
/* 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
|
||||
* to the vblank. */
|
||||
do_frame_sync = ! gdk_display_is_composited (display);
|
||||
|
||||
if (do_frame_sync != context_x11->do_frame_sync)
|
||||
{
|
||||
context_x11->do_frame_sync = do_frame_sync;
|
||||
|
||||
if (do_frame_sync)
|
||||
eglSwapInterval (display_x11->egl_display, 1);
|
||||
else
|
||||
eglSwapInterval (display_x11->egl_display, 0);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static cairo_region_t *
|
||||
gdk_x11_gl_context_egl_get_damage (GdkGLContext *context)
|
||||
{
|
||||
@ -569,6 +633,8 @@ gdk_x11_gl_context_egl_class_init (GdkX11GLContextEGLClass *klass)
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
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->end_frame = gdk_x11_gl_context_egl_end_frame;
|
||||
@ -689,71 +755,6 @@ gdk_x11_gl_context_egl_new (GdkSurface *surface,
|
||||
return GDK_X11_GL_CONTEXT (context);
|
||||
}
|
||||
|
||||
gboolean
|
||||
gdk_x11_gl_context_egl_make_current (GdkDisplay *display,
|
||||
GdkGLContext *context)
|
||||
{
|
||||
GdkX11GLContextEGL *context_egl = GDK_X11_GL_CONTEXT_EGL (context);
|
||||
GdkX11GLContext *context_x11 = GDK_X11_GL_CONTEXT (context);
|
||||
GdkX11Display *display_x11 = GDK_X11_DISPLAY (display);
|
||||
GdkSurface *surface;
|
||||
EGLSurface egl_surface;
|
||||
|
||||
if (context == NULL)
|
||||
{
|
||||
eglMakeCurrent (display_x11->egl_display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if (context_egl->egl_context == NULL)
|
||||
{
|
||||
g_critical ("No EGL context associated to the GdkGLContext; you must "
|
||||
"call gdk_gl_context_realize() first.");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
surface = gdk_gl_context_get_surface (context);
|
||||
|
||||
if (gdk_draw_context_is_in_frame (GDK_DRAW_CONTEXT (context)))
|
||||
egl_surface = gdk_x11_surface_get_egl_surface (surface);
|
||||
else
|
||||
egl_surface = EGL_NO_SURFACE;
|
||||
|
||||
GDK_DISPLAY_NOTE (display, OPENGL,
|
||||
g_message ("Making EGL context %p current to surface %p",
|
||||
context_egl->egl_context, egl_surface));
|
||||
|
||||
if (!eglMakeCurrent (display_x11->egl_display, egl_surface, egl_surface, context_egl->egl_context))
|
||||
{
|
||||
GDK_DISPLAY_NOTE (display, OPENGL,
|
||||
g_message ("Making EGL context current failed"));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (gdk_draw_context_is_in_frame (GDK_DRAW_CONTEXT (context)))
|
||||
{
|
||||
gboolean do_frame_sync = FALSE;
|
||||
|
||||
/* 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
|
||||
* to the vblank. */
|
||||
do_frame_sync = ! gdk_display_is_composited (display);
|
||||
|
||||
if (do_frame_sync != context_x11->do_frame_sync)
|
||||
{
|
||||
context_x11->do_frame_sync = do_frame_sync;
|
||||
|
||||
if (do_frame_sync)
|
||||
eglSwapInterval (display_x11->egl_display, 1);
|
||||
else
|
||||
eglSwapInterval (display_x11->egl_display, 0);
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_x11_display_get_egl_version:
|
||||
* @display: (type GdkX11Display): a `GdkDisplay`
|
||||
|
@ -229,6 +229,66 @@ gdk_x11_gl_context_glx_end_frame (GdkDrawContext *draw_context,
|
||||
glXGetVideoSyncSGI (&info->last_frame_counter);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gdk_x11_gl_context_glx_clear_current (GdkGLContext *context)
|
||||
{
|
||||
GdkDisplay *display = gdk_gl_context_get_display (context);
|
||||
Display *dpy = gdk_x11_display_get_xdisplay (display);
|
||||
|
||||
glXMakeContextCurrent (dpy, None, None, NULL);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gdk_x11_gl_context_glx_make_current (GdkGLContext *context,
|
||||
gboolean surfaceless)
|
||||
|
||||
{
|
||||
GdkX11GLContext *context_x11 = GDK_X11_GL_CONTEXT (context);
|
||||
GdkX11GLContextGLX *context_glx = GDK_X11_GL_CONTEXT_GLX (context);
|
||||
GdkDisplay *display = gdk_gl_context_get_display (context);
|
||||
Display *dpy = gdk_x11_display_get_xdisplay (display);
|
||||
gboolean do_frame_sync = FALSE;
|
||||
GdkSurface *surface;
|
||||
GLXWindow drawable;
|
||||
|
||||
drawable = gdk_x11_gl_context_glx_get_drawable (context_glx);
|
||||
|
||||
if (!surfaceless)
|
||||
surface = gdk_gl_context_get_surface (context);
|
||||
else
|
||||
surface = GDK_X11_DISPLAY (display)->leader_gdk_surface;
|
||||
drawable = gdk_x11_surface_get_glx_drawable (surface);
|
||||
|
||||
GDK_DISPLAY_NOTE (display, OPENGL,
|
||||
g_message ("Making GLX context %p current to drawable %lu",
|
||||
context, (unsigned long) drawable));
|
||||
|
||||
if (!glXMakeContextCurrent (dpy, drawable, drawable, context_glx->glx_context))
|
||||
return FALSE;
|
||||
|
||||
if (!surfaceless && GDK_X11_DISPLAY (display)->has_glx_swap_interval)
|
||||
{
|
||||
/* 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
|
||||
* to the vblank. */
|
||||
do_frame_sync = ! gdk_display_is_composited (display);
|
||||
|
||||
if (do_frame_sync != context_x11->do_frame_sync)
|
||||
{
|
||||
context_x11->do_frame_sync = do_frame_sync;
|
||||
|
||||
if (do_frame_sync)
|
||||
glXSwapIntervalSGI (1);
|
||||
else
|
||||
glXSwapIntervalSGI (0);
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static cairo_region_t *
|
||||
gdk_x11_gl_context_glx_get_damage (GdkGLContext *context)
|
||||
{
|
||||
@ -675,6 +735,8 @@ gdk_x11_gl_context_glx_class_init (GdkX11GLContextGLXClass *klass)
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
context_class->realize = gdk_x11_gl_context_glx_realize;
|
||||
context_class->make_current = gdk_x11_gl_context_glx_make_current;
|
||||
context_class->clear_current = gdk_x11_gl_context_glx_clear_current;
|
||||
context_class->get_damage = gdk_x11_gl_context_glx_get_damage;
|
||||
|
||||
draw_context_class->end_frame = gdk_x11_gl_context_glx_end_frame;
|
||||
@ -841,67 +903,6 @@ gdk_x11_gl_context_glx_new (GdkSurface *surface,
|
||||
return GDK_X11_GL_CONTEXT (context);
|
||||
}
|
||||
|
||||
gboolean
|
||||
gdk_x11_gl_context_glx_make_current (GdkDisplay *display,
|
||||
GdkGLContext *context)
|
||||
{
|
||||
GdkX11GLContextGLX *context_glx;
|
||||
GdkX11GLContext *context_x11;
|
||||
Display *dpy = gdk_x11_display_get_xdisplay (display);
|
||||
gboolean do_frame_sync = FALSE;
|
||||
GLXWindow drawable;
|
||||
|
||||
if (context == NULL)
|
||||
{
|
||||
glXMakeContextCurrent (dpy, None, None, NULL);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
context_glx = GDK_X11_GL_CONTEXT_GLX (context);
|
||||
if (context_glx->glx_context == NULL)
|
||||
{
|
||||
g_critical ("No GLX context associated to the GdkGLContext; you must "
|
||||
"call gdk_gl_context_realize() first.");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
context_x11 = GDK_X11_GL_CONTEXT (context);
|
||||
drawable = gdk_x11_gl_context_glx_get_drawable (context_glx);
|
||||
|
||||
GDK_DISPLAY_NOTE (display, OPENGL,
|
||||
g_message ("Making GLX context %p current to drawable %lu",
|
||||
context, (unsigned long) drawable));
|
||||
|
||||
if (!glXMakeContextCurrent (dpy, drawable, drawable, context_glx->glx_context))
|
||||
{
|
||||
GDK_DISPLAY_NOTE (display, OPENGL,
|
||||
g_message ("Making GLX context current failed"));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (gdk_draw_context_is_in_frame (GDK_DRAW_CONTEXT (context)) &&
|
||||
GDK_X11_DISPLAY (display)->has_glx_swap_interval)
|
||||
{
|
||||
/* 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
|
||||
* to the vblank. */
|
||||
do_frame_sync = ! gdk_display_is_composited (display);
|
||||
|
||||
if (do_frame_sync != context_x11->do_frame_sync)
|
||||
{
|
||||
context_x11->do_frame_sync = do_frame_sync;
|
||||
|
||||
if (do_frame_sync)
|
||||
glXSwapIntervalSGI (1);
|
||||
else
|
||||
glXSwapIntervalSGI (0);
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_x11_display_get_glx_version:
|
||||
* @display: (type GdkX11Display): a `GdkDisplay`
|
||||
|
@ -82,22 +82,6 @@ gdk_x11_surface_create_gl_context (GdkSurface *surface,
|
||||
return GDK_GL_CONTEXT (context);
|
||||
}
|
||||
|
||||
gboolean
|
||||
gdk_x11_display_make_gl_context_current (GdkDisplay *display,
|
||||
GdkGLContext *context)
|
||||
{
|
||||
GdkX11Display *display_x11 = GDK_X11_DISPLAY (display);
|
||||
|
||||
if (display_x11->egl_display)
|
||||
return gdk_x11_gl_context_egl_make_current (display, context);
|
||||
else if (display_x11->glx_config)
|
||||
return gdk_x11_gl_context_glx_make_current (display, context);
|
||||
else
|
||||
g_assert_not_reached ();
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
gboolean
|
||||
gdk_x11_display_init_gl_backend (GdkX11Display *self,
|
||||
Visual **out_visual,
|
||||
|
@ -65,8 +65,6 @@ gboolean gdk_x11_display_init_gl_backend (GdkX11Display *
|
||||
|
||||
GdkGLContext * gdk_x11_surface_create_gl_context (GdkSurface *window,
|
||||
GError **error);
|
||||
gboolean gdk_x11_display_make_gl_context_current (GdkDisplay *display,
|
||||
GdkGLContext *context);
|
||||
|
||||
/* GLX */
|
||||
#define GDK_TYPE_X11_GL_CONTEXT_GLX (gdk_x11_gl_context_glx_get_type())
|
||||
@ -84,8 +82,6 @@ void gdk_x11_surface_destroy_glx_drawable (GdkX11Surface *
|
||||
GType gdk_x11_gl_context_glx_get_type (void) G_GNUC_CONST;
|
||||
GdkX11GLContext * gdk_x11_gl_context_glx_new (GdkSurface *surface,
|
||||
GError **error);
|
||||
gboolean gdk_x11_gl_context_glx_make_current (GdkDisplay *display,
|
||||
GdkGLContext *context);
|
||||
|
||||
|
||||
/* EGL */
|
||||
@ -105,8 +101,6 @@ void gdk_x11_surface_destroy_egl_surface (GdkX11Surface *
|
||||
GType gdk_x11_gl_context_egl_get_type (void) G_GNUC_CONST;
|
||||
GdkX11GLContext * gdk_x11_gl_context_egl_new (GdkSurface *surface,
|
||||
GError **error);
|
||||
gboolean gdk_x11_gl_context_egl_make_current (GdkDisplay *display,
|
||||
GdkGLContext *context);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user