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 | |
31 | struct _GdkX11GLContextEGL |
32 | { |
33 | GdkX11GLContext parent_instance; |
34 | |
35 | guint do_frame_sync : 1; |
36 | }; |
37 | |
38 | typedef struct _GdkX11GLContextClass GdkX11GLContextEGLClass; |
39 | |
40 | G_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 | */ |
54 | gpointer |
55 | gdk_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 | |
62 | static gboolean |
63 | gdk_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 | |
96 | static void |
97 | gdk_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 | |
106 | static void |
107 | gdk_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 | */ |
124 | gboolean |
125 | gdk_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 | |