mirror of
https://gitlab.gnome.org/GNOME/gtk.git
synced 2025-01-14 06:10:21 +00:00
2ff1ea555f
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.
158 lines
4.0 KiB
C
158 lines
4.0 KiB
C
/* GDK - The GIMP Drawing Kit
|
|
*
|
|
* gdkglcontext-egl.c: EGL-X11 specific wrappers
|
|
*
|
|
* SPDX-FileCopyrightText: 2014 Emmanuele Bassi
|
|
* SPDX-FileCopyrightText: 2021 GNOME Foundation
|
|
*
|
|
* SPDX-License-Identifier: LGPL-2.1-or-later
|
|
*/
|
|
|
|
#include "config.h"
|
|
|
|
#include "gdkglcontext-x11.h"
|
|
#include "gdkdisplay-x11.h"
|
|
#include "gdkprivate-x11.h"
|
|
#include "gdkscreen-x11.h"
|
|
|
|
#include "gdkx11display.h"
|
|
#include "gdkx11glcontext.h"
|
|
#include "gdkx11screen.h"
|
|
#include "gdkx11property.h"
|
|
#include <X11/Xatom.h>
|
|
|
|
#include "gdkprofilerprivate.h"
|
|
#include "gdkintl.h"
|
|
|
|
#include <cairo-xlib.h>
|
|
|
|
#include <epoxy/egl.h>
|
|
|
|
struct _GdkX11GLContextEGL
|
|
{
|
|
GdkX11GLContext parent_instance;
|
|
|
|
guint do_frame_sync : 1;
|
|
};
|
|
|
|
typedef struct _GdkX11GLContextClass GdkX11GLContextEGLClass;
|
|
|
|
G_DEFINE_TYPE (GdkX11GLContextEGL, gdk_x11_gl_context_egl, GDK_TYPE_X11_GL_CONTEXT)
|
|
|
|
/**
|
|
* gdk_x11_display_get_egl_display:
|
|
* @display: (type GdkX11Display): an X11 display
|
|
*
|
|
* Retrieves the EGL display connection object for the given GDK display.
|
|
*
|
|
* This function returns `NULL` if GDK is using GLX.
|
|
*
|
|
* Returns: (nullable): the EGL display object
|
|
*
|
|
* Since: 4.4
|
|
*/
|
|
gpointer
|
|
gdk_x11_display_get_egl_display (GdkDisplay *display)
|
|
{
|
|
g_return_val_if_fail (GDK_IS_X11_DISPLAY (display), NULL);
|
|
|
|
return gdk_display_get_egl_display (display);
|
|
}
|
|
|
|
static void
|
|
gdk_x11_gl_context_egl_begin_frame (GdkDrawContext *draw_context,
|
|
cairo_region_t *region)
|
|
{
|
|
GDK_DRAW_CONTEXT_CLASS (gdk_x11_gl_context_egl_parent_class)->begin_frame (draw_context, region);
|
|
|
|
glDrawBuffers (1, (GLenum[1]) { GL_BACK });
|
|
}
|
|
|
|
static gboolean
|
|
gdk_x11_gl_context_egl_make_current (GdkGLContext *context,
|
|
gboolean surfaceless)
|
|
{
|
|
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);
|
|
gboolean do_frame_sync = FALSE;
|
|
|
|
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
|
|
* to the vblank. */
|
|
do_frame_sync = ! gdk_display_is_composited (display);
|
|
|
|
if (do_frame_sync != self->do_frame_sync)
|
|
{
|
|
self->do_frame_sync = do_frame_sync;
|
|
|
|
if (do_frame_sync)
|
|
eglSwapInterval (egl_display, 1);
|
|
else
|
|
eglSwapInterval (egl_display, 0);
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
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);
|
|
|
|
context_class->backend_type = GDK_GL_EGL;
|
|
|
|
context_class->make_current = gdk_x11_gl_context_egl_make_current;
|
|
|
|
draw_context_class->begin_frame = gdk_x11_gl_context_egl_begin_frame;
|
|
}
|
|
|
|
static void
|
|
gdk_x11_gl_context_egl_init (GdkX11GLContextEGL *self)
|
|
{
|
|
self->do_frame_sync = TRUE;
|
|
}
|
|
|
|
/**
|
|
* gdk_x11_display_get_egl_version:
|
|
* @display: (type GdkX11Display): a `GdkDisplay`
|
|
* @major: (out): return location for the EGL major version
|
|
* @minor: (out): return location for the EGL minor version
|
|
*
|
|
* Retrieves the version of the EGL implementation.
|
|
*
|
|
* Returns: %TRUE if EGL is available
|
|
*
|
|
* Since: 4.4
|
|
*/
|
|
gboolean
|
|
gdk_x11_display_get_egl_version (GdkDisplay *display,
|
|
int *major,
|
|
int *minor)
|
|
{
|
|
g_return_val_if_fail (GDK_IS_DISPLAY (display), FALSE);
|
|
|
|
if (!GDK_IS_X11_DISPLAY (display))
|
|
return FALSE;
|
|
|
|
GdkX11Display *display_x11 = GDK_X11_DISPLAY (display);
|
|
|
|
if (gdk_display_get_egl_display (display) == NULL)
|
|
return FALSE;
|
|
|
|
if (major != NULL)
|
|
*major = display_x11->egl_version / 10;
|
|
if (minor != NULL)
|
|
*minor = display_x11->egl_version % 10;
|
|
|
|
return TRUE;
|
|
}
|