1/* GDK - The GIMP Drawing Kit
2 *
3 * gdkglcontext-egl.c: EGL-X11 specific wrappers
4 *
5 * SPDX-FileCopyrightText: 2014 Emmanuele Bassi
6 * SPDX-FileCopyrightText: 2021 GNOME Foundation
7 *
8 * SPDX-License-Identifier: LGPL-2.1-or-later
9 */
10
11#include "config.h"
12
13#include "gdkglcontext-x11.h"
14#include "gdkdisplay-x11.h"
15#include "gdkprivate-x11.h"
16#include "gdkscreen-x11.h"
17
18#include "gdkx11display.h"
19#include "gdkx11glcontext.h"
20#include "gdkx11screen.h"
21#include "gdkx11property.h"
22#include <X11/Xatom.h>
23
24#include "gdkprofilerprivate.h"
25#include "gdkintl.h"
26
27#include <cairo-xlib.h>
28
29#include <epoxy/egl.h>
30
31struct _GdkX11GLContextEGL
32{
33 GdkX11GLContext parent_instance;
34
35 guint do_frame_sync : 1;
36};
37
38typedef struct _GdkX11GLContextClass GdkX11GLContextEGLClass;
39
40G_DEFINE_TYPE (GdkX11GLContextEGL, gdk_x11_gl_context_egl, GDK_TYPE_X11_GL_CONTEXT)
41
42/**
43 * gdk_x11_display_get_egl_display:
44 * @display: (type GdkX11Display): an X11 display
45 *
46 * Retrieves the EGL display connection object for the given GDK display.
47 *
48 * This function returns `NULL` if GDK is using GLX.
49 *
50 * Returns: (nullable): the EGL display object
51 *
52 * Since: 4.4
53 */
54gpointer
55gdk_x11_display_get_egl_display (GdkDisplay *display)
56{
57 g_return_val_if_fail (GDK_IS_X11_DISPLAY (display), NULL);
58
59 return gdk_display_get_egl_display (display);
60}
61
62static gboolean
63gdk_x11_gl_context_egl_make_current (GdkGLContext *context,
64 gboolean surfaceless)
65{
66 GdkX11GLContextEGL *self = GDK_X11_GL_CONTEXT_EGL (context);
67 GdkDisplay *display = gdk_gl_context_get_display (context);
68 EGLDisplay egl_display = gdk_display_get_egl_display (display);
69 gboolean do_frame_sync = FALSE;
70
71 if (!GDK_GL_CONTEXT_CLASS (gdk_x11_gl_context_egl_parent_class)->make_current (context, surfaceless))
72 return FALSE;
73
74 if (surfaceless)
75 return TRUE;
76
77 /* If the WM is compositing there is no particular need to delay
78 * the swap when drawing on the offscreen, rendering to the screen
79 * happens later anyway, and its up to the compositor to sync that
80 * to the vblank. */
81 do_frame_sync = ! gdk_display_is_composited (display);
82
83 if (do_frame_sync != self->do_frame_sync)
84 {
85 self->do_frame_sync = do_frame_sync;
86
87 if (do_frame_sync)
88 eglSwapInterval (egl_display, 1);
89 else
90 eglSwapInterval (egl_display, 0);
91 }
92
93 return TRUE;
94}
95
96static void
97gdk_x11_gl_context_egl_class_init (GdkX11GLContextEGLClass *klass)
98{
99 GdkGLContextClass *context_class = GDK_GL_CONTEXT_CLASS (klass);
100
101 context_class->backend_type = GDK_GL_EGL;
102
103 context_class->make_current = gdk_x11_gl_context_egl_make_current;
104}
105
106static void
107gdk_x11_gl_context_egl_init (GdkX11GLContextEGL *self)
108{
109 self->do_frame_sync = TRUE;
110}
111
112/**
113 * gdk_x11_display_get_egl_version:
114 * @display: (type GdkX11Display): a `GdkDisplay`
115 * @major: (out): return location for the EGL major version
116 * @minor: (out): return location for the EGL minor version
117 *
118 * Retrieves the version of the EGL implementation.
119 *
120 * Returns: %TRUE if EGL is available
121 *
122 * Since: 4.4
123 */
124gboolean
125gdk_x11_display_get_egl_version (GdkDisplay *display,
126 int *major,
127 int *minor)
128{
129 g_return_val_if_fail (GDK_IS_DISPLAY (display), FALSE);
130
131 if (!GDK_IS_X11_DISPLAY (display))
132 return FALSE;
133
134 GdkX11Display *display_x11 = GDK_X11_DISPLAY (display);
135
136 if (gdk_display_get_egl_display (display) == NULL)
137 return FALSE;
138
139 if (major != NULL)
140 *major = display_x11->egl_version / 10;
141 if (minor != NULL)
142 *minor = display_x11->egl_version % 10;
143
144 return TRUE;
145}
146

source code of gtk/gdk/x11/gdkglcontext-egl.c