Bug Summary

File:cdk/cdkglcontext.c
Warning:line 283, column 11
This statement is never executed

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name cdkglcontext.c -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -fhalf-no-semantic-interposition -mframe-pointer=all -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fdebug-compilation-dir=/rootdir/cdk -fcoverage-compilation-dir=/rootdir/cdk -resource-dir /usr/lib/llvm-21/lib/clang/21 -D HAVE_CONFIG_H -I . -I .. -D G_LOG_DOMAIN="Cdk" -D G_LOG_USE_STRUCTURED=1 -D CDK_COMPILATION -I .. -I ../cdk -I .. -D G_ENABLE_DEBUG -D G_ENABLE_CONSISTENCY_CHECKS -D GLIB_MIN_REQUIRED_VERSION=GLIB_VERSION_2_66 -D GLIB_MAX_ALLOWED_VERSION=GLIB_VERSION_2_66 -I /usr/include/pango-1.0 -I /usr/include/harfbuzz -I /usr/local/include/gdk-pixbuf-2.0 -I /usr/include/x86_64-linux-gnu -I /usr/include/webp -I /usr/include/cairo -I /usr/include/gio-unix-2.0 -I /usr/include/glib-2.0 -I /usr/lib/x86_64-linux-gnu/glib-2.0/include -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/sysprof-6 -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/pixman-1 -I /usr/include/fribidi -D PIC -internal-isystem /usr/lib/llvm-21/lib/clang/21/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/15/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -ferror-limit 19 -fvisibility=hidden -fgnuc-version=4.2.1 -fskip-odr-check-in-gmf -analyzer-checker deadcode.DeadStores -analyzer-checker security.ArrayBound -analyzer-checker unix.cstring.NotNullTerminated -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /rootdir/html-report/2026-05-20-090151-45479-1 -x c cdkglcontext.c
1/* CDK - The GIMP Drawing Kit
2 *
3 * cdkglcontext.c: GL context abstraction
4 *
5 * Copyright © 2014 Emmanuele Bassi
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Library General Public
9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Library General Public License for more details.
16 *
17 * You should have received a copy of the GNU Library General Public
18 * License along with this library. If not, see <http://www.gnu.org/licenses/>.
19 */
20
21/**
22 * SECTION:cdkglcontext
23 * @Title: CdkGLContext
24 * @Short_description: OpenGL context
25 *
26 * #CdkGLContext is an object representing the platform-specific
27 * OpenGL drawing context.
28 *
29 * #CdkGLContexts are created for a #CdkWindow using
30 * cdk_window_create_gl_context(), and the context will match
31 * the #CdkVisual of the window.
32 *
33 * A #CdkGLContext is not tied to any particular normal framebuffer.
34 * For instance, it cannot draw to the #CdkWindow back buffer. The CDK
35 * repaint system is in full control of the painting to that. Instead,
36 * you can create render buffers or textures and use cdk_cairo_draw_from_gl()
37 * in the draw function of your widget to draw them. Then CDK will handle
38 * the integration of your rendering with that of other widgets.
39 *
40 * Support for #CdkGLContext is platform-specific, context creation
41 * can fail, returning %NULL context.
42 *
43 * A #CdkGLContext has to be made "current" in order to start using
44 * it, otherwise any OpenGL call will be ignored.
45 *
46 * ## Creating a new OpenGL context ##
47 *
48 * In order to create a new #CdkGLContext instance you need a
49 * #CdkWindow, which you typically get during the realize call
50 * of a widget.
51 *
52 * A #CdkGLContext is not realized until either cdk_gl_context_make_current(),
53 * or until it is realized using cdk_gl_context_realize(). It is possible to
54 * specify details of the GL context like the OpenGL version to be used, or
55 * whether the GL context should have extra state validation enabled after
56 * calling cdk_window_create_gl_context() by calling cdk_gl_context_realize().
57 * If the realization fails you have the option to change the settings of the
58 * #CdkGLContext and try again.
59 *
60 * ## Using a CdkGLContext ##
61 *
62 * You will need to make the #CdkGLContext the current context
63 * before issuing OpenGL calls; the system sends OpenGL commands to
64 * whichever context is current. It is possible to have multiple
65 * contexts, so you always need to ensure that the one which you
66 * want to draw with is the current one before issuing commands:
67 *
68 * |[<!-- language="C" -->
69 * cdk_gl_context_make_current (context);
70 * ]|
71 *
72 * You can now perform your drawing using OpenGL commands.
73 *
74 * You can check which #CdkGLContext is the current one by using
75 * cdk_gl_context_get_current(); you can also unset any #CdkGLContext
76 * that is currently set by calling cdk_gl_context_clear_current().
77 */
78
79#include "config.h"
80
81#include "cdkglcontextprivate.h"
82#include "cdkdisplayprivate.h"
83#include "cdkinternals.h"
84
85#include "cdkintl.h"
86#include "cdk-private.h"
87
88#include <epoxy/gl.h>
89
90typedef struct {
91 CdkDisplay *display;
92 CdkWindow *window;
93 CdkGLContext *shared_context;
94
95 int major;
96 int minor;
97 int gl_version;
98
99 guint realized : 1;
100 guint use_texture_rectangle : 1;
101 guint has_gl_framebuffer_blit : 1;
102 guint has_frame_terminator : 1;
103 guint has_unpack_subimage : 1;
104 guint extensions_checked : 1;
105 guint debug_enabled : 1;
106 guint forward_compatible : 1;
107 guint is_legacy : 1;
108
109 int use_es;
110
111 CdkGLContextPaintData *paint_data;
112} CdkGLContextPrivate;
113
114enum {
115 PROP_0,
116
117 PROP_DISPLAY,
118 PROP_WINDOW,
119 PROP_SHARED_CONTEXT,
120
121 LAST_PROP
122};
123
124static GParamSpec *obj_pspecs[LAST_PROP] = { NULL((void*)0), };
125
126G_DEFINE_QUARK (cdk-gl-error-quark, cdk_gl_error)GQuark cdk_gl_error_quark (void) { static GQuark q; if (q == 0
) q = g_quark_from_static_string ("cdk-gl-error-quark"); return
q; }
127
128G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (CdkGLContext, cdk_gl_context, G_TYPE_OBJECT)static void cdk_gl_context_init (CdkGLContext *self); static void
cdk_gl_context_class_init (CdkGLContextClass *klass); static
GType cdk_gl_context_get_type_once (void); static gpointer cdk_gl_context_parent_class
= ((void*)0); static gint CdkGLContext_private_offset; static
void cdk_gl_context_class_intern_init (gpointer klass) { cdk_gl_context_parent_class
= g_type_class_peek_parent (klass); if (CdkGLContext_private_offset
!= 0) g_type_class_adjust_private_offset (klass, &CdkGLContext_private_offset
); cdk_gl_context_class_init ((CdkGLContextClass*) klass); } __attribute__
((__unused__)) static inline gpointer cdk_gl_context_get_instance_private
(CdkGLContext *self) { return (((gpointer) ((guint8*) (self)
+ (glong) (CdkGLContext_private_offset)))); } GType cdk_gl_context_get_type
(void) { static GType static_g_define_type_id = 0; if ((__extension__
({ _Static_assert (sizeof *(&static_g_define_type_id) ==
sizeof (gpointer), "Expression evaluates to false"); (void) (
0 ? (gpointer) * (&static_g_define_type_id) : ((void*)0))
; (!(__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id
) == sizeof (gpointer), "Expression evaluates to false"); __typeof__
(*(&static_g_define_type_id)) gapg_temp_newval; __typeof__
((&static_g_define_type_id)) gapg_temp_atomic = (&static_g_define_type_id
); __atomic_load (gapg_temp_atomic, &gapg_temp_newval, 5)
; gapg_temp_newval; })) && g_once_init_enter_pointer (
&static_g_define_type_id)); })) ) { GType g_define_type_id
= cdk_gl_context_get_type_once (); (__extension__ ({ _Static_assert
(sizeof *(&static_g_define_type_id) == sizeof (gpointer)
, "Expression evaluates to false"); 0 ? (void) (*(&static_g_define_type_id
) = (g_define_type_id)) : (void) 0; g_once_init_leave_pointer
((&static_g_define_type_id), (gpointer) (guintptr) (g_define_type_id
)); })) ; } return static_g_define_type_id; } __attribute__ (
(__noinline__)) static GType cdk_gl_context_get_type_once (void
) { GType g_define_type_id = g_type_register_static_simple ((
(GType) ((20) << (2))), g_intern_static_string ("CdkGLContext"
), sizeof (CdkGLContextClass), (GClassInitFunc)(void (*)(void
)) cdk_gl_context_class_intern_init, sizeof (CdkGLContext), (
GInstanceInitFunc)(void (*)(void)) cdk_gl_context_init, (GTypeFlags
) G_TYPE_FLAG_ABSTRACT); { {{ CdkGLContext_private_offset = g_type_add_instance_private
(g_define_type_id, sizeof (CdkGLContextPrivate)); };} } return
g_define_type_id; }
129
130static GPrivate thread_current_context = G_PRIVATE_INIT (g_object_unref){ ((void*)0), (g_object_unref), { ((void*)0), ((void*)0) } };
131
132static void
133cdk_gl_context_dispose (GObject *gobject)
134{
135 CdkGLContext *context = CDK_GL_CONTEXT (gobject)((((CdkGLContext*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((gobject)), ((cdk_gl_context_get_type ()))))))
;
136 CdkGLContextPrivate *priv = cdk_gl_context_get_instance_private (context);
137 CdkGLContext *current;
138
139 current = g_private_get (&thread_current_context);
140 if (current == context)
141 g_private_replace (&thread_current_context, NULL((void*)0));
142
143 g_clear_object (&priv->display)do { _Static_assert (sizeof *((&priv->display)) == sizeof
(gpointer), "Expression evaluates to false"); __typeof__ (((
&priv->display))) _pp = ((&priv->display)); __typeof__
(*((&priv->display))) _ptr = *_pp; *_pp = ((void*)0);
if (_ptr) (g_object_unref) (_ptr); } while (0)
;
144 g_clear_object (&priv->window)do { _Static_assert (sizeof *((&priv->window)) == sizeof
(gpointer), "Expression evaluates to false"); __typeof__ (((
&priv->window))) _pp = ((&priv->window)); __typeof__
(*((&priv->window))) _ptr = *_pp; *_pp = ((void*)0); if
(_ptr) (g_object_unref) (_ptr); } while (0)
;
145 g_clear_object (&priv->shared_context)do { _Static_assert (sizeof *((&priv->shared_context))
== sizeof (gpointer), "Expression evaluates to false"); __typeof__
(((&priv->shared_context))) _pp = ((&priv->shared_context
)); __typeof__ (*((&priv->shared_context))) _ptr = *_pp
; *_pp = ((void*)0); if (_ptr) (g_object_unref) (_ptr); } while
(0)
;
146
147 G_OBJECT_CLASS (cdk_gl_context_parent_class)((((GObjectClass*) (void *) g_type_check_class_cast ((GTypeClass
*) ((cdk_gl_context_parent_class)), (((GType) ((20) << (
2))))))))
->dispose (gobject);
148}
149
150static void
151cdk_gl_context_finalize (GObject *gobject)
152{
153 CdkGLContext *context = CDK_GL_CONTEXT (gobject)((((CdkGLContext*) (void *) g_type_check_instance_cast ((GTypeInstance
*) ((gobject)), ((cdk_gl_context_get_type ()))))))
;
154 CdkGLContextPrivate *priv = cdk_gl_context_get_instance_private (context);
155
156 g_clear_pointer (&priv->paint_data, g_free)do { _Static_assert (sizeof *(&priv->paint_data) == sizeof
(gpointer), "Expression evaluates to false"); __typeof__ ((&
priv->paint_data)) _pp = (&priv->paint_data); __typeof__
(*(&priv->paint_data)) _ptr = *_pp; *_pp = ((void*)0)
; if (_ptr) (g_free) (_ptr); } while (0)
;
157 G_OBJECT_CLASS (cdk_gl_context_parent_class)((((GObjectClass*) (void *) g_type_check_class_cast ((GTypeClass
*) ((cdk_gl_context_parent_class)), (((GType) ((20) << (
2))))))))
->finalize (gobject);
158}
159
160static void
161cdk_gl_context_set_property (GObject *gobject,
162 guint prop_id,
163 const GValue *value,
164 GParamSpec *pspec)
165{
166 CdkGLContextPrivate *priv = cdk_gl_context_get_instance_private ((CdkGLContext *) gobject);
167
168 switch (prop_id)
169 {
170 case PROP_DISPLAY:
171 {
172 CdkDisplay *display = g_value_get_object (value);
173
174 if (display)
175 g_object_ref (display)((__typeof__ (display)) (g_object_ref) (display));
176
177 if (priv->display)
178 g_object_unref (priv->display);
179
180 priv->display = display;
181 }
182 break;
183
184 case PROP_WINDOW:
185 {
186 CdkWindow *window = g_value_get_object (value);
187
188 if (window)
189 g_object_ref (window)((__typeof__ (window)) (g_object_ref) (window));
190
191 if (priv->window)
192 g_object_unref (priv->window);
193
194 priv->window = window;
195 }
196 break;
197
198 case PROP_SHARED_CONTEXT:
199 {
200 CdkGLContext *context = g_value_get_object (value);
201
202 if (context != NULL((void*)0))
203 priv->shared_context = g_object_ref (context)((__typeof__ (context)) (g_object_ref) (context));
204 }
205 break;
206
207 default:
208 G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec)do { GObject *_glib__object = (GObject*) ((gobject)); GParamSpec
*_glib__pspec = (GParamSpec*) ((pspec)); guint _glib__property_id
= ((prop_id)); g_warning ("%s:%d: invalid %s id %u for \"%s\" of type '%s' in '%s'"
, "cdkglcontext.c", 208, ("property"), _glib__property_id, _glib__pspec
->name, g_type_name ((((((GTypeClass*) (((GTypeInstance*) (
_glib__pspec))->g_class))->g_type)))), (g_type_name (((
(((GTypeClass*) (((GTypeInstance*) (_glib__object))->g_class
))->g_type)))))); } while (0)
;
209 }
210}
211
212static void
213cdk_gl_context_get_property (GObject *gobject,
214 guint prop_id,
215 GValue *value,
216 GParamSpec *pspec)
217{
218 CdkGLContextPrivate *priv = cdk_gl_context_get_instance_private ((CdkGLContext *) gobject);
219
220 switch (prop_id)
221 {
222 case PROP_DISPLAY:
223 g_value_set_object (value, priv->display);
224 break;
225
226 case PROP_WINDOW:
227 g_value_set_object (value, priv->window);
228 break;
229
230 case PROP_SHARED_CONTEXT:
231 g_value_set_object (value, priv->shared_context);
232 break;
233
234 default:
235 G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec)do { GObject *_glib__object = (GObject*) ((gobject)); GParamSpec
*_glib__pspec = (GParamSpec*) ((pspec)); guint _glib__property_id
= ((prop_id)); g_warning ("%s:%d: invalid %s id %u for \"%s\" of type '%s' in '%s'"
, "cdkglcontext.c", 235, ("property"), _glib__property_id, _glib__pspec
->name, g_type_name ((((((GTypeClass*) (((GTypeInstance*) (
_glib__pspec))->g_class))->g_type)))), (g_type_name (((
(((GTypeClass*) (((GTypeInstance*) (_glib__object))->g_class
))->g_type)))))); } while (0)
;
236 }
237}
238
239void
240cdk_gl_context_upload_texture (CdkGLContext *context,
241 cairo_surface_t *image_surface,
242 int width,
243 int height,
244 guint texture_target)
245{
246 CdkGLContextPrivate *priv = cdk_gl_context_get_instance_private (context);
247
248 g_return_if_fail (CDK_IS_GL_CONTEXT (context))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((context)); GType __t = ((cdk_gl_context_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; })))))) { }
else { g_return_if_fail_warning ("Cdk", ((const char*) (__func__
)), "CDK_IS_GL_CONTEXT (context)"); return; } } while (0)
;
249
250 /* GL_UNPACK_ROW_LENGTH is available on desktop GL, OpenGL ES >= 3.0, or if
251 * the GL_EXT_unpack_subimage extension for OpenGL ES 2.0 is available
252 */
253 if (!priv->use_es ||
254 (priv->use_es && (priv->gl_version >= 30 || priv->has_unpack_subimage)))
255 {
256 glPixelStoreiepoxy_glPixelStorei (GL_UNPACK_ALIGNMENT0x0CF5, 4);
257 glPixelStoreiepoxy_glPixelStorei (GL_UNPACK_ROW_LENGTH0x0CF2, cairo_image_surface_get_stride (image_surface) / 4);
258
259 if (priv->use_es)
260 glTexImage2Depoxy_glTexImage2D (texture_target, 0, GL_RGBA0x1908, width, height, 0, GL_RGBA0x1908, GL_UNSIGNED_BYTE0x1401,
261 cairo_image_surface_get_data (image_surface));
262 else
263 glTexImage2Depoxy_glTexImage2D (texture_target, 0, GL_RGBA0x1908, width, height, 0, GL_BGRA0x80E1, GL_UNSIGNED_INT_8_8_8_8_REV0x8367,
264 cairo_image_surface_get_data (image_surface));
265
266 glPixelStoreiepoxy_glPixelStorei (GL_UNPACK_ROW_LENGTH0x0CF2, 0);
267 }
268 else
269 {
270 GLvoid *data = cairo_image_surface_get_data (image_surface);
271 int stride = cairo_image_surface_get_stride (image_surface);
272 int i;
273
274 if (priv->use_es)
275 {
276 glTexImage2Depoxy_glTexImage2D (texture_target, 0, GL_RGBA0x1908, width, height, 0, GL_RGBA0x1908, GL_UNSIGNED_BYTE0x1401, NULL((void*)0));
277
278 for (i = 0; i < height; i++)
279 glTexSubImage2Depoxy_glTexSubImage2D (texture_target, 0, 0, i, width, 1, GL_RGBA0x1908, GL_UNSIGNED_BYTE0x1401, (unsigned char*) data + (i * stride));
280 }
281 else
282 {
283 glTexImage2Depoxy_glTexImage2D (texture_target, 0, GL_RGBA0x1908, width, height, 0, GL_BGRA0x80E1, GL_UNSIGNED_INT_8_8_8_8_REV0x8367, NULL((void*)0));
This statement is never executed
284
285 for (i = 0; i < height; i++)
286 glTexSubImage2Depoxy_glTexSubImage2D (texture_target, 0, 0, i, width, 1, GL_BGRA0x80E1, GL_UNSIGNED_INT_8_8_8_8_REV0x8367, (unsigned char*) data + (i * stride));
287 }
288 }
289}
290
291static gboolean
292cdk_gl_context_real_realize (CdkGLContext *self G_GNUC_UNUSED__attribute__ ((__unused__)),
293 GError **error)
294{
295 g_set_error_literal (error, CDK_GL_ERROR(cdk_gl_error_quark ()), CDK_GL_ERROR_NOT_AVAILABLE,
296 "The current backend does not support OpenGL");
297
298 return FALSE(0);
299}
300
301static void
302cdk_gl_context_class_init (CdkGLContextClass *klass)
303{
304 GObjectClass *gobject_class = G_OBJECT_CLASS (klass)((((GObjectClass*) (void *) g_type_check_class_cast ((GTypeClass
*) ((klass)), (((GType) ((20) << (2))))))))
;
305
306 klass->realize = cdk_gl_context_real_realize;
307
308 /**
309 * CdkGLContext:display:
310 *
311 * The #CdkDisplay used to create the #CdkGLContext.
312 *
313 * Since: 3.16
314 */
315 obj_pspecs[PROP_DISPLAY] =
316 g_param_spec_object ("display",
317 P_("Display")dgettext("ctk30" "-properties","Display"),
318 P_("The CDK display used to create the GL context")dgettext("ctk30" "-properties","The CDK display used to create the GL context"
)
,
319 CDK_TYPE_DISPLAY(cdk_display_get_type ()),
320 G_PARAM_READWRITE |
321 G_PARAM_CONSTRUCT_ONLY |
322 G_PARAM_STATIC_STRINGS(G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB
)
);
323
324 /**
325 * CdkGLContext:window:
326 *
327 * The #CdkWindow the gl context is bound to.
328 *
329 * Since: 3.16
330 */
331 obj_pspecs[PROP_WINDOW] =
332 g_param_spec_object ("window",
333 P_("Window")dgettext("ctk30" "-properties","Window"),
334 P_("The CDK window bound to the GL context")dgettext("ctk30" "-properties","The CDK window bound to the GL context"
)
,
335 CDK_TYPE_WINDOW(cdk_window_get_type ()),
336 G_PARAM_READWRITE |
337 G_PARAM_CONSTRUCT_ONLY |
338 G_PARAM_STATIC_STRINGS(G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB
)
);
339
340 /**
341 * CdkGLContext:shared-context:
342 *
343 * The #CdkGLContext that this context is sharing data with, or %NULL
344 *
345 * Since: 3.16
346 */
347 obj_pspecs[PROP_SHARED_CONTEXT] =
348 g_param_spec_object ("shared-context",
349 P_("Shared context")dgettext("ctk30" "-properties","Shared context"),
350 P_("The GL context this context shares data with")dgettext("ctk30" "-properties","The GL context this context shares data with"
)
,
351 CDK_TYPE_GL_CONTEXT(cdk_gl_context_get_type ()),
352 G_PARAM_READWRITE |
353 G_PARAM_CONSTRUCT_ONLY |
354 G_PARAM_STATIC_STRINGS(G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB
)
);
355
356 gobject_class->set_property = cdk_gl_context_set_property;
357 gobject_class->get_property = cdk_gl_context_get_property;
358 gobject_class->dispose = cdk_gl_context_dispose;
359 gobject_class->finalize = cdk_gl_context_finalize;
360
361 g_object_class_install_properties (gobject_class, LAST_PROP, obj_pspecs);
362}
363
364static void
365cdk_gl_context_init (CdkGLContext *self)
366{
367 CdkGLContextPrivate *priv = cdk_gl_context_get_instance_private (self);
368
369 priv->use_es = -1;
370}
371
372/*< private >
373 * cdk_gl_context_end_frame:
374 * @context: a #CdkGLContext
375 * @painted: The area that has been redrawn this frame
376 * @damage: The area that we know is actually different from the last frame
377 *
378 * Copies the back buffer to the front buffer.
379 *
380 * This function may call `glFlush()` implicitly before returning; it
381 * is not recommended to call `glFlush()` explicitly before calling
382 * this function.
383 *
384 * Since: 3.16
385 */
386void
387cdk_gl_context_end_frame (CdkGLContext *context,
388 cairo_region_t *painted,
389 cairo_region_t *damage)
390{
391 g_return_if_fail (CDK_IS_GL_CONTEXT (context))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((context)); GType __t = ((cdk_gl_context_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; })))))) { }
else { g_return_if_fail_warning ("Cdk", ((const char*) (__func__
)), "CDK_IS_GL_CONTEXT (context)"); return; } } while (0)
;
392
393 CDK_GL_CONTEXT_GET_CLASS (context)((((CdkGLContextClass*) (((GTypeInstance*) ((context)))->g_class
))))
->end_frame (context, painted, damage);
394}
395
396CdkGLContextPaintData *
397cdk_gl_context_get_paint_data (CdkGLContext *context)
398{
399
400 CdkGLContextPrivate *priv = cdk_gl_context_get_instance_private (context);
401
402 if (priv->paint_data == NULL((void*)0))
403 {
404 priv->paint_data = g_new0 (CdkGLContextPaintData, 1)((CdkGLContextPaintData *) g_malloc0_n ((1), sizeof (CdkGLContextPaintData
)))
;
405 priv->paint_data->is_legacy = priv->is_legacy;
406 priv->paint_data->use_es = priv->use_es;
407 }
408
409 return priv->paint_data;
410}
411
412gboolean
413cdk_gl_context_use_texture_rectangle (CdkGLContext *context)
414{
415 CdkGLContextPrivate *priv = cdk_gl_context_get_instance_private (context);
416
417 return priv->use_texture_rectangle;
418}
419
420gboolean
421cdk_gl_context_has_framebuffer_blit (CdkGLContext *context)
422{
423 CdkGLContextPrivate *priv = cdk_gl_context_get_instance_private (context);
424
425 return priv->has_gl_framebuffer_blit;
426}
427
428gboolean
429cdk_gl_context_has_frame_terminator (CdkGLContext *context)
430{
431 CdkGLContextPrivate *priv = cdk_gl_context_get_instance_private (context);
432
433 return priv->has_frame_terminator;
434}
435
436gboolean
437cdk_gl_context_has_unpack_subimage (CdkGLContext *context)
438{
439 CdkGLContextPrivate *priv = cdk_gl_context_get_instance_private (context);
440
441 return priv->has_unpack_subimage;
442}
443
444/**
445 * cdk_gl_context_set_debug_enabled:
446 * @context: a #CdkGLContext
447 * @enabled: whether to enable debugging in the context
448 *
449 * Sets whether the #CdkGLContext should perform extra validations and
450 * run time checking. This is useful during development, but has
451 * additional overhead.
452 *
453 * The #CdkGLContext must not be realized or made current prior to
454 * calling this function.
455 *
456 * Since: 3.16
457 */
458void
459cdk_gl_context_set_debug_enabled (CdkGLContext *context,
460 gboolean enabled)
461{
462 CdkGLContextPrivate *priv = cdk_gl_context_get_instance_private (context);
463
464 g_return_if_fail (CDK_IS_GL_CONTEXT (context))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((context)); GType __t = ((cdk_gl_context_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; })))))) { }
else { g_return_if_fail_warning ("Cdk", ((const char*) (__func__
)), "CDK_IS_GL_CONTEXT (context)"); return; } } while (0)
;
465 g_return_if_fail (!priv->realized)do { if ((!priv->realized)) { } else { g_return_if_fail_warning
("Cdk", ((const char*) (__func__)), "!priv->realized"); return
; } } while (0)
;
466
467 enabled = !!enabled;
468
469 priv->debug_enabled = enabled;
470}
471
472/**
473 * cdk_gl_context_get_debug_enabled:
474 * @context: a #CdkGLContext
475 *
476 * Retrieves the value set using cdk_gl_context_set_debug_enabled().
477 *
478 * Returns: %TRUE if debugging is enabled
479 *
480 * Since: 3.16
481 */
482gboolean
483cdk_gl_context_get_debug_enabled (CdkGLContext *context)
484{
485 CdkGLContextPrivate *priv = cdk_gl_context_get_instance_private (context);
486
487 g_return_val_if_fail (CDK_IS_GL_CONTEXT (context), FALSE)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((context)); GType __t = ((cdk_gl_context_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; })))))) { }
else { g_return_if_fail_warning ("Cdk", ((const char*) (__func__
)), "CDK_IS_GL_CONTEXT (context)"); return ((0)); } } while (
0)
;
488
489 return priv->debug_enabled;
490}
491
492/**
493 * cdk_gl_context_set_forward_compatible:
494 * @context: a #CdkGLContext
495 * @compatible: whether the context should be forward compatible
496 *
497 * Sets whether the #CdkGLContext should be forward compatible.
498 *
499 * Forward compatibile contexts must not support OpenGL functionality that
500 * has been marked as deprecated in the requested version; non-forward
501 * compatible contexts, on the other hand, must support both deprecated and
502 * non deprecated functionality.
503 *
504 * The #CdkGLContext must not be realized or made current prior to calling
505 * this function.
506 *
507 * Since: 3.16
508 */
509void
510cdk_gl_context_set_forward_compatible (CdkGLContext *context,
511 gboolean compatible)
512{
513 CdkGLContextPrivate *priv = cdk_gl_context_get_instance_private (context);
514
515 g_return_if_fail (CDK_IS_GL_CONTEXT (context))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((context)); GType __t = ((cdk_gl_context_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; })))))) { }
else { g_return_if_fail_warning ("Cdk", ((const char*) (__func__
)), "CDK_IS_GL_CONTEXT (context)"); return; } } while (0)
;
516 g_return_if_fail (!priv->realized)do { if ((!priv->realized)) { } else { g_return_if_fail_warning
("Cdk", ((const char*) (__func__)), "!priv->realized"); return
; } } while (0)
;
517
518 compatible = !!compatible;
519
520 priv->forward_compatible = compatible;
521}
522
523/**
524 * cdk_gl_context_get_forward_compatible:
525 * @context: a #CdkGLContext
526 *
527 * Retrieves the value set using cdk_gl_context_set_forward_compatible().
528 *
529 * Returns: %TRUE if the context should be forward compatible
530 *
531 * Since: 3.16
532 */
533gboolean
534cdk_gl_context_get_forward_compatible (CdkGLContext *context)
535{
536 CdkGLContextPrivate *priv = cdk_gl_context_get_instance_private (context);
537
538 g_return_val_if_fail (CDK_IS_GL_CONTEXT (context), FALSE)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((context)); GType __t = ((cdk_gl_context_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; })))))) { }
else { g_return_if_fail_warning ("Cdk", ((const char*) (__func__
)), "CDK_IS_GL_CONTEXT (context)"); return ((0)); } } while (
0)
;
539
540 return priv->forward_compatible;
541}
542
543/**
544 * cdk_gl_context_set_required_version:
545 * @context: a #CdkGLContext
546 * @major: the major version to request
547 * @minor: the minor version to request
548 *
549 * Sets the major and minor version of OpenGL to request.
550 *
551 * Setting @major and @minor to zero will use the default values.
552 *
553 * The #CdkGLContext must not be realized or made current prior to calling
554 * this function.
555 *
556 * Since: 3.16
557 */
558void
559cdk_gl_context_set_required_version (CdkGLContext *context,
560 int major,
561 int minor)
562{
563 CdkGLContextPrivate *priv = cdk_gl_context_get_instance_private (context);
564 int version, min_ver;
565
566 g_return_if_fail (CDK_IS_GL_CONTEXT (context))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((context)); GType __t = ((cdk_gl_context_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; })))))) { }
else { g_return_if_fail_warning ("Cdk", ((const char*) (__func__
)), "CDK_IS_GL_CONTEXT (context)"); return; } } while (0)
;
567 g_return_if_fail (!priv->realized)do { if ((!priv->realized)) { } else { g_return_if_fail_warning
("Cdk", ((const char*) (__func__)), "!priv->realized"); return
; } } while (0)
;
568
569 /* this will take care of the default */
570 if (major == 0 && minor == 0)
571 {
572 priv->major = 0;
573 priv->minor = 0;
574 return;
575 }
576
577 /* Enforce a minimum context version number of 3.2 */
578 version = (major * 100) + minor;
579
580 if (priv->use_es > 0 || (_cdk_gl_flags & CDK_GL_GLES) != 0)
581 min_ver = 200;
582 else
583 min_ver = 302;
584
585 if (version < min_ver)
586 {
587 g_warning ("cdk_gl_context_set_required_version - GL context versions less than 3.2 are not supported.");
588 version = min_ver;
589 }
590 priv->major = version / 100;
591 priv->minor = version % 100;
592}
593
594/**
595 * cdk_gl_context_get_required_version:
596 * @context: a #CdkGLContext
597 * @major: (out) (nullable): return location for the major version to request
598 * @minor: (out) (nullable): return location for the minor version to request
599 *
600 * Retrieves the major and minor version requested by calling
601 * cdk_gl_context_set_required_version().
602 *
603 * Since: 3.16
604 */
605void
606cdk_gl_context_get_required_version (CdkGLContext *context,
607 int *major,
608 int *minor)
609{
610 CdkGLContextPrivate *priv = cdk_gl_context_get_instance_private (context);
611 int default_major, default_minor;
612 int maj, min;
613
614 g_return_if_fail (CDK_IS_GL_CONTEXT (context))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((context)); GType __t = ((cdk_gl_context_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; })))))) { }
else { g_return_if_fail_warning ("Cdk", ((const char*) (__func__
)), "CDK_IS_GL_CONTEXT (context)"); return; } } while (0)
;
615
616 if (priv->use_es > 0 || (_cdk_gl_flags & CDK_GL_GLES) != 0)
617 {
618 default_major = 2;
619 default_minor = 0;
620 }
621 else
622 {
623 default_major = 3;
624 default_minor = 2;
625 }
626
627 if (priv->major > 0)
628 maj = priv->major;
629 else
630 maj = default_major;
631
632 if (priv->minor > 0)
633 min = priv->minor;
634 else
635 min = default_minor;
636
637 if (major != NULL((void*)0))
638 *major = maj;
639 if (minor != NULL((void*)0))
640 *minor = min;
641}
642
643/**
644 * cdk_gl_context_is_legacy:
645 * @context: a #CdkGLContext
646 *
647 * Whether the #CdkGLContext is in legacy mode or not.
648 *
649 * The #CdkGLContext must be realized before calling this function.
650 *
651 * When realizing a GL context, CDK will try to use the OpenGL 3.2 core
652 * profile; this profile removes all the OpenGL API that was deprecated
653 * prior to the 3.2 version of the specification. If the realization is
654 * successful, this function will return %FALSE.
655 *
656 * If the underlying OpenGL implementation does not support core profiles,
657 * CDK will fall back to a pre-3.2 compatibility profile, and this function
658 * will return %TRUE.
659 *
660 * You can use the value returned by this function to decide which kind
661 * of OpenGL API to use, or whether to do extension discovery, or what
662 * kind of shader programs to load.
663 *
664 * Returns: %TRUE if the GL context is in legacy mode
665 *
666 * Since: 3.20
667 */
668gboolean
669cdk_gl_context_is_legacy (CdkGLContext *context)
670{
671 CdkGLContextPrivate *priv = cdk_gl_context_get_instance_private (context);
672
673 g_return_val_if_fail (CDK_IS_GL_CONTEXT (context), FALSE)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((context)); GType __t = ((cdk_gl_context_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; })))))) { }
else { g_return_if_fail_warning ("Cdk", ((const char*) (__func__
)), "CDK_IS_GL_CONTEXT (context)"); return ((0)); } } while (
0)
;
674 g_return_val_if_fail (priv->realized, FALSE)do { if ((priv->realized)) { } else { g_return_if_fail_warning
("Cdk", ((const char*) (__func__)), "priv->realized"); return
((0)); } } while (0)
;
675
676 return priv->is_legacy;
677}
678
679void
680cdk_gl_context_set_is_legacy (CdkGLContext *context,
681 gboolean is_legacy)
682{
683 CdkGLContextPrivate *priv = cdk_gl_context_get_instance_private (context);
684
685 priv->is_legacy = !!is_legacy;
686}
687
688/**
689 * cdk_gl_context_set_use_es:
690 * @context: a #CdkGLContext:
691 * @use_es: whether the context should use OpenGL ES instead of OpenGL,
692 * or -1 to allow auto-detection
693 *
694 * Requests that CDK create a OpenGL ES context instead of an OpenGL one,
695 * if the platform and windowing system allows it.
696 *
697 * The @context must not have been realized.
698 *
699 * By default, CDK will attempt to automatically detect whether the
700 * underlying GL implementation is OpenGL or OpenGL ES once the @context
701 * is realized.
702 *
703 * You should check the return value of cdk_gl_context_get_use_es() after
704 * calling cdk_gl_context_realize() to decide whether to use the OpenGL or
705 * OpenGL ES API, extensions, or shaders.
706 *
707 * Since: 3.22
708 */
709void
710cdk_gl_context_set_use_es (CdkGLContext *context,
711 int use_es)
712{
713 CdkGLContextPrivate *priv = cdk_gl_context_get_instance_private (context);
714
715 g_return_if_fail (CDK_IS_GL_CONTEXT (context))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((context)); GType __t = ((cdk_gl_context_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; })))))) { }
else { g_return_if_fail_warning ("Cdk", ((const char*) (__func__
)), "CDK_IS_GL_CONTEXT (context)"); return; } } while (0)
;
716 g_return_if_fail (!priv->realized)do { if ((!priv->realized)) { } else { g_return_if_fail_warning
("Cdk", ((const char*) (__func__)), "!priv->realized"); return
; } } while (0)
;
717
718 if (priv->use_es != use_es)
719 priv->use_es = use_es;
720}
721
722/**
723 * cdk_gl_context_get_use_es:
724 * @context: a #CdkGLContext
725 *
726 * Checks whether the @context is using an OpenGL or OpenGL ES profile.
727 *
728 * Returns: %TRUE if the #CdkGLContext is using an OpenGL ES profile
729 *
730 * Since: 3.22
731 */
732gboolean
733cdk_gl_context_get_use_es (CdkGLContext *context)
734{
735 CdkGLContextPrivate *priv = cdk_gl_context_get_instance_private (context);
736
737 g_return_val_if_fail (CDK_IS_GL_CONTEXT (context), FALSE)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((context)); GType __t = ((cdk_gl_context_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; })))))) { }
else { g_return_if_fail_warning ("Cdk", ((const char*) (__func__
)), "CDK_IS_GL_CONTEXT (context)"); return ((0)); } } while (
0)
;
738
739 if (!priv->realized)
740 return FALSE(0);
741
742 return priv->use_es > 0;
743}
744
745/**
746 * cdk_gl_context_realize:
747 * @context: a #CdkGLContext
748 * @error: return location for a #GError
749 *
750 * Realizes the given #CdkGLContext.
751 *
752 * It is safe to call this function on a realized #CdkGLContext.
753 *
754 * Returns: %TRUE if the context is realized
755 *
756 * Since: 3.16
757 */
758gboolean
759cdk_gl_context_realize (CdkGLContext *context,
760 GError **error)
761{
762 CdkGLContextPrivate *priv = cdk_gl_context_get_instance_private (context);
763
764 g_return_val_if_fail (CDK_IS_GL_CONTEXT (context), FALSE)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((context)); GType __t = ((cdk_gl_context_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; })))))) { }
else { g_return_if_fail_warning ("Cdk", ((const char*) (__func__
)), "CDK_IS_GL_CONTEXT (context)"); return ((0)); } } while (
0)
;
765
766 if (priv->realized)
767 return TRUE(!(0));
768
769 priv->realized = CDK_GL_CONTEXT_GET_CLASS (context)((((CdkGLContextClass*) (((GTypeInstance*) ((context)))->g_class
))))
->realize (context, error);
770
771 return priv->realized;
772}
773
774static void
775cdk_gl_context_check_extensions (CdkGLContext *context)
776{
777 CdkGLContextPrivate *priv = cdk_gl_context_get_instance_private (context);
778 gboolean has_npot, has_texture_rectangle;
779
780 if (!priv->realized)
781 return;
782
783 if (priv->extensions_checked)
784 return;
785
786 priv->gl_version = epoxy_gl_version ();
787
788 if (priv->use_es < 0)
789 priv->use_es = !epoxy_is_desktop_gl ();
790
791 if (priv->use_es)
792 {
793 has_npot = priv->gl_version >= 20;
794 has_texture_rectangle = FALSE(0);
795
796 /* This should check for GL_NV_framebuffer_blit as well - see extension at:
797 *
798 * https://www.khronos.org/registry/gles/extensions/NV/NV_framebuffer_blit.txt
799 *
800 * for ANGLE, we can enable bit blitting if we have the
801 * GL_ANGLE_framebuffer_blit extension
802 */
803 if (epoxy_has_gl_extension ("GL_ANGLE_framebuffer_blit"))
804 priv->has_gl_framebuffer_blit = TRUE(!(0));
805 else
806 priv->has_gl_framebuffer_blit = FALSE(0);
807
808 /* No OES version */
809 priv->has_frame_terminator = FALSE(0);
810
811 priv->has_unpack_subimage = epoxy_has_gl_extension ("GL_EXT_unpack_subimage");
812 }
813 else
814 {
815 has_npot = priv->gl_version >= 20 || epoxy_has_gl_extension ("GL_ARB_texture_non_power_of_two");
816 has_texture_rectangle = priv->gl_version >= 31 || epoxy_has_gl_extension ("GL_ARB_texture_rectangle");
817
818 priv->has_gl_framebuffer_blit = priv->gl_version >= 30 || epoxy_has_gl_extension ("GL_EXT_framebuffer_blit");
819 priv->has_frame_terminator = epoxy_has_gl_extension ("GL_GREMEDY_frame_terminator");
820 priv->has_unpack_subimage = TRUE(!(0));
821
822 /* We asked for a core profile, but we didn't get one, so we're in legacy mode */
823 if (priv->gl_version < 32)
824 priv->is_legacy = TRUE(!(0));
825 }
826
827 if (!priv->use_es && G_UNLIKELY (_cdk_gl_flags & CDK_GL_TEXTURE_RECTANGLE)(_cdk_gl_flags & CDK_GL_TEXTURE_RECTANGLE))
828 priv->use_texture_rectangle = TRUE(!(0));
829 else if (has_npot)
830 priv->use_texture_rectangle = FALSE(0);
831 else if (has_texture_rectangle)
832 priv->use_texture_rectangle = TRUE(!(0));
833 else
834 g_warning ("GL implementation doesn't support any form of non-power-of-two textures");
835
836 CDK_NOTE (OPENGL,do { if ((_cdk_debug_flags & CDK_DEBUG_OPENGL)) { g_message
("%s version: %d.%d (%s)\n" "* GLSL version: %s\n" "* Extensions checked:\n"
" - GL_ARB_texture_non_power_of_two: %s\n" " - GL_ARB_texture_rectangle: %s\n"
" - GL_EXT_framebuffer_blit: %s\n" " - GL_GREMEDY_frame_terminator: %s\n"
"* Using texture rectangle: %s", priv->use_es ? "OpenGL ES"
: "OpenGL", priv->gl_version / 10, priv->gl_version % 10
, priv->is_legacy ? "legacy" : "core", epoxy_glGetString (
0x8B8C), has_npot ? "yes" : "no", has_texture_rectangle ? "yes"
: "no", priv->has_gl_framebuffer_blit ? "yes" : "no", priv
->has_frame_terminator ? "yes" : "no", priv->use_texture_rectangle
? "yes" : "no"); }; } while (0)
837 g_message ("%s version: %d.%d (%s)\n"do { if ((_cdk_debug_flags & CDK_DEBUG_OPENGL)) { g_message
("%s version: %d.%d (%s)\n" "* GLSL version: %s\n" "* Extensions checked:\n"
" - GL_ARB_texture_non_power_of_two: %s\n" " - GL_ARB_texture_rectangle: %s\n"
" - GL_EXT_framebuffer_blit: %s\n" " - GL_GREMEDY_frame_terminator: %s\n"
"* Using texture rectangle: %s", priv->use_es ? "OpenGL ES"
: "OpenGL", priv->gl_version / 10, priv->gl_version % 10
, priv->is_legacy ? "legacy" : "core", epoxy_glGetString (
0x8B8C), has_npot ? "yes" : "no", has_texture_rectangle ? "yes"
: "no", priv->has_gl_framebuffer_blit ? "yes" : "no", priv
->has_frame_terminator ? "yes" : "no", priv->use_texture_rectangle
? "yes" : "no"); }; } while (0)
838 "* GLSL version: %s\n"do { if ((_cdk_debug_flags & CDK_DEBUG_OPENGL)) { g_message
("%s version: %d.%d (%s)\n" "* GLSL version: %s\n" "* Extensions checked:\n"
" - GL_ARB_texture_non_power_of_two: %s\n" " - GL_ARB_texture_rectangle: %s\n"
" - GL_EXT_framebuffer_blit: %s\n" " - GL_GREMEDY_frame_terminator: %s\n"
"* Using texture rectangle: %s", priv->use_es ? "OpenGL ES"
: "OpenGL", priv->gl_version / 10, priv->gl_version % 10
, priv->is_legacy ? "legacy" : "core", epoxy_glGetString (
0x8B8C), has_npot ? "yes" : "no", has_texture_rectangle ? "yes"
: "no", priv->has_gl_framebuffer_blit ? "yes" : "no", priv
->has_frame_terminator ? "yes" : "no", priv->use_texture_rectangle
? "yes" : "no"); }; } while (0)
839 "* Extensions checked:\n"do { if ((_cdk_debug_flags & CDK_DEBUG_OPENGL)) { g_message
("%s version: %d.%d (%s)\n" "* GLSL version: %s\n" "* Extensions checked:\n"
" - GL_ARB_texture_non_power_of_two: %s\n" " - GL_ARB_texture_rectangle: %s\n"
" - GL_EXT_framebuffer_blit: %s\n" " - GL_GREMEDY_frame_terminator: %s\n"
"* Using texture rectangle: %s", priv->use_es ? "OpenGL ES"
: "OpenGL", priv->gl_version / 10, priv->gl_version % 10
, priv->is_legacy ? "legacy" : "core", epoxy_glGetString (
0x8B8C), has_npot ? "yes" : "no", has_texture_rectangle ? "yes"
: "no", priv->has_gl_framebuffer_blit ? "yes" : "no", priv
->has_frame_terminator ? "yes" : "no", priv->use_texture_rectangle
? "yes" : "no"); }; } while (0)
840 " - GL_ARB_texture_non_power_of_two: %s\n"do { if ((_cdk_debug_flags & CDK_DEBUG_OPENGL)) { g_message
("%s version: %d.%d (%s)\n" "* GLSL version: %s\n" "* Extensions checked:\n"
" - GL_ARB_texture_non_power_of_two: %s\n" " - GL_ARB_texture_rectangle: %s\n"
" - GL_EXT_framebuffer_blit: %s\n" " - GL_GREMEDY_frame_terminator: %s\n"
"* Using texture rectangle: %s", priv->use_es ? "OpenGL ES"
: "OpenGL", priv->gl_version / 10, priv->gl_version % 10
, priv->is_legacy ? "legacy" : "core", epoxy_glGetString (
0x8B8C), has_npot ? "yes" : "no", has_texture_rectangle ? "yes"
: "no", priv->has_gl_framebuffer_blit ? "yes" : "no", priv
->has_frame_terminator ? "yes" : "no", priv->use_texture_rectangle
? "yes" : "no"); }; } while (0)
841 " - GL_ARB_texture_rectangle: %s\n"do { if ((_cdk_debug_flags & CDK_DEBUG_OPENGL)) { g_message
("%s version: %d.%d (%s)\n" "* GLSL version: %s\n" "* Extensions checked:\n"
" - GL_ARB_texture_non_power_of_two: %s\n" " - GL_ARB_texture_rectangle: %s\n"
" - GL_EXT_framebuffer_blit: %s\n" " - GL_GREMEDY_frame_terminator: %s\n"
"* Using texture rectangle: %s", priv->use_es ? "OpenGL ES"
: "OpenGL", priv->gl_version / 10, priv->gl_version % 10
, priv->is_legacy ? "legacy" : "core", epoxy_glGetString (
0x8B8C), has_npot ? "yes" : "no", has_texture_rectangle ? "yes"
: "no", priv->has_gl_framebuffer_blit ? "yes" : "no", priv
->has_frame_terminator ? "yes" : "no", priv->use_texture_rectangle
? "yes" : "no"); }; } while (0)
842 " - GL_EXT_framebuffer_blit: %s\n"do { if ((_cdk_debug_flags & CDK_DEBUG_OPENGL)) { g_message
("%s version: %d.%d (%s)\n" "* GLSL version: %s\n" "* Extensions checked:\n"
" - GL_ARB_texture_non_power_of_two: %s\n" " - GL_ARB_texture_rectangle: %s\n"
" - GL_EXT_framebuffer_blit: %s\n" " - GL_GREMEDY_frame_terminator: %s\n"
"* Using texture rectangle: %s", priv->use_es ? "OpenGL ES"
: "OpenGL", priv->gl_version / 10, priv->gl_version % 10
, priv->is_legacy ? "legacy" : "core", epoxy_glGetString (
0x8B8C), has_npot ? "yes" : "no", has_texture_rectangle ? "yes"
: "no", priv->has_gl_framebuffer_blit ? "yes" : "no", priv
->has_frame_terminator ? "yes" : "no", priv->use_texture_rectangle
? "yes" : "no"); }; } while (0)
843 " - GL_GREMEDY_frame_terminator: %s\n"do { if ((_cdk_debug_flags & CDK_DEBUG_OPENGL)) { g_message
("%s version: %d.%d (%s)\n" "* GLSL version: %s\n" "* Extensions checked:\n"
" - GL_ARB_texture_non_power_of_two: %s\n" " - GL_ARB_texture_rectangle: %s\n"
" - GL_EXT_framebuffer_blit: %s\n" " - GL_GREMEDY_frame_terminator: %s\n"
"* Using texture rectangle: %s", priv->use_es ? "OpenGL ES"
: "OpenGL", priv->gl_version / 10, priv->gl_version % 10
, priv->is_legacy ? "legacy" : "core", epoxy_glGetString (
0x8B8C), has_npot ? "yes" : "no", has_texture_rectangle ? "yes"
: "no", priv->has_gl_framebuffer_blit ? "yes" : "no", priv
->has_frame_terminator ? "yes" : "no", priv->use_texture_rectangle
? "yes" : "no"); }; } while (0)
844 "* Using texture rectangle: %s",do { if ((_cdk_debug_flags & CDK_DEBUG_OPENGL)) { g_message
("%s version: %d.%d (%s)\n" "* GLSL version: %s\n" "* Extensions checked:\n"
" - GL_ARB_texture_non_power_of_two: %s\n" " - GL_ARB_texture_rectangle: %s\n"
" - GL_EXT_framebuffer_blit: %s\n" " - GL_GREMEDY_frame_terminator: %s\n"
"* Using texture rectangle: %s", priv->use_es ? "OpenGL ES"
: "OpenGL", priv->gl_version / 10, priv->gl_version % 10
, priv->is_legacy ? "legacy" : "core", epoxy_glGetString (
0x8B8C), has_npot ? "yes" : "no", has_texture_rectangle ? "yes"
: "no", priv->has_gl_framebuffer_blit ? "yes" : "no", priv
->has_frame_terminator ? "yes" : "no", priv->use_texture_rectangle
? "yes" : "no"); }; } while (0)
845 priv->use_es ? "OpenGL ES" : "OpenGL",do { if ((_cdk_debug_flags & CDK_DEBUG_OPENGL)) { g_message
("%s version: %d.%d (%s)\n" "* GLSL version: %s\n" "* Extensions checked:\n"
" - GL_ARB_texture_non_power_of_two: %s\n" " - GL_ARB_texture_rectangle: %s\n"
" - GL_EXT_framebuffer_blit: %s\n" " - GL_GREMEDY_frame_terminator: %s\n"
"* Using texture rectangle: %s", priv->use_es ? "OpenGL ES"
: "OpenGL", priv->gl_version / 10, priv->gl_version % 10
, priv->is_legacy ? "legacy" : "core", epoxy_glGetString (
0x8B8C), has_npot ? "yes" : "no", has_texture_rectangle ? "yes"
: "no", priv->has_gl_framebuffer_blit ? "yes" : "no", priv
->has_frame_terminator ? "yes" : "no", priv->use_texture_rectangle
? "yes" : "no"); }; } while (0)
846 priv->gl_version / 10, priv->gl_version % 10,do { if ((_cdk_debug_flags & CDK_DEBUG_OPENGL)) { g_message
("%s version: %d.%d (%s)\n" "* GLSL version: %s\n" "* Extensions checked:\n"
" - GL_ARB_texture_non_power_of_two: %s\n" " - GL_ARB_texture_rectangle: %s\n"
" - GL_EXT_framebuffer_blit: %s\n" " - GL_GREMEDY_frame_terminator: %s\n"
"* Using texture rectangle: %s", priv->use_es ? "OpenGL ES"
: "OpenGL", priv->gl_version / 10, priv->gl_version % 10
, priv->is_legacy ? "legacy" : "core", epoxy_glGetString (
0x8B8C), has_npot ? "yes" : "no", has_texture_rectangle ? "yes"
: "no", priv->has_gl_framebuffer_blit ? "yes" : "no", priv
->has_frame_terminator ? "yes" : "no", priv->use_texture_rectangle
? "yes" : "no"); }; } while (0)
847 priv->is_legacy ? "legacy" : "core",do { if ((_cdk_debug_flags & CDK_DEBUG_OPENGL)) { g_message
("%s version: %d.%d (%s)\n" "* GLSL version: %s\n" "* Extensions checked:\n"
" - GL_ARB_texture_non_power_of_two: %s\n" " - GL_ARB_texture_rectangle: %s\n"
" - GL_EXT_framebuffer_blit: %s\n" " - GL_GREMEDY_frame_terminator: %s\n"
"* Using texture rectangle: %s", priv->use_es ? "OpenGL ES"
: "OpenGL", priv->gl_version / 10, priv->gl_version % 10
, priv->is_legacy ? "legacy" : "core", epoxy_glGetString (
0x8B8C), has_npot ? "yes" : "no", has_texture_rectangle ? "yes"
: "no", priv->has_gl_framebuffer_blit ? "yes" : "no", priv
->has_frame_terminator ? "yes" : "no", priv->use_texture_rectangle
? "yes" : "no"); }; } while (0)
848 glGetString (GL_SHADING_LANGUAGE_VERSION),do { if ((_cdk_debug_flags & CDK_DEBUG_OPENGL)) { g_message
("%s version: %d.%d (%s)\n" "* GLSL version: %s\n" "* Extensions checked:\n"
" - GL_ARB_texture_non_power_of_two: %s\n" " - GL_ARB_texture_rectangle: %s\n"
" - GL_EXT_framebuffer_blit: %s\n" " - GL_GREMEDY_frame_terminator: %s\n"
"* Using texture rectangle: %s", priv->use_es ? "OpenGL ES"
: "OpenGL", priv->gl_version / 10, priv->gl_version % 10
, priv->is_legacy ? "legacy" : "core", epoxy_glGetString (
0x8B8C), has_npot ? "yes" : "no", has_texture_rectangle ? "yes"
: "no", priv->has_gl_framebuffer_blit ? "yes" : "no", priv
->has_frame_terminator ? "yes" : "no", priv->use_texture_rectangle
? "yes" : "no"); }; } while (0)
849 has_npot ? "yes" : "no",do { if ((_cdk_debug_flags & CDK_DEBUG_OPENGL)) { g_message
("%s version: %d.%d (%s)\n" "* GLSL version: %s\n" "* Extensions checked:\n"
" - GL_ARB_texture_non_power_of_two: %s\n" " - GL_ARB_texture_rectangle: %s\n"
" - GL_EXT_framebuffer_blit: %s\n" " - GL_GREMEDY_frame_terminator: %s\n"
"* Using texture rectangle: %s", priv->use_es ? "OpenGL ES"
: "OpenGL", priv->gl_version / 10, priv->gl_version % 10
, priv->is_legacy ? "legacy" : "core", epoxy_glGetString (
0x8B8C), has_npot ? "yes" : "no", has_texture_rectangle ? "yes"
: "no", priv->has_gl_framebuffer_blit ? "yes" : "no", priv
->has_frame_terminator ? "yes" : "no", priv->use_texture_rectangle
? "yes" : "no"); }; } while (0)
850 has_texture_rectangle ? "yes" : "no",do { if ((_cdk_debug_flags & CDK_DEBUG_OPENGL)) { g_message
("%s version: %d.%d (%s)\n" "* GLSL version: %s\n" "* Extensions checked:\n"
" - GL_ARB_texture_non_power_of_two: %s\n" " - GL_ARB_texture_rectangle: %s\n"
" - GL_EXT_framebuffer_blit: %s\n" " - GL_GREMEDY_frame_terminator: %s\n"
"* Using texture rectangle: %s", priv->use_es ? "OpenGL ES"
: "OpenGL", priv->gl_version / 10, priv->gl_version % 10
, priv->is_legacy ? "legacy" : "core", epoxy_glGetString (
0x8B8C), has_npot ? "yes" : "no", has_texture_rectangle ? "yes"
: "no", priv->has_gl_framebuffer_blit ? "yes" : "no", priv
->has_frame_terminator ? "yes" : "no", priv->use_texture_rectangle
? "yes" : "no"); }; } while (0)
851 priv->has_gl_framebuffer_blit ? "yes" : "no",do { if ((_cdk_debug_flags & CDK_DEBUG_OPENGL)) { g_message
("%s version: %d.%d (%s)\n" "* GLSL version: %s\n" "* Extensions checked:\n"
" - GL_ARB_texture_non_power_of_two: %s\n" " - GL_ARB_texture_rectangle: %s\n"
" - GL_EXT_framebuffer_blit: %s\n" " - GL_GREMEDY_frame_terminator: %s\n"
"* Using texture rectangle: %s", priv->use_es ? "OpenGL ES"
: "OpenGL", priv->gl_version / 10, priv->gl_version % 10
, priv->is_legacy ? "legacy" : "core", epoxy_glGetString (
0x8B8C), has_npot ? "yes" : "no", has_texture_rectangle ? "yes"
: "no", priv->has_gl_framebuffer_blit ? "yes" : "no", priv
->has_frame_terminator ? "yes" : "no", priv->use_texture_rectangle
? "yes" : "no"); }; } while (0)
852 priv->has_frame_terminator ? "yes" : "no",do { if ((_cdk_debug_flags & CDK_DEBUG_OPENGL)) { g_message
("%s version: %d.%d (%s)\n" "* GLSL version: %s\n" "* Extensions checked:\n"
" - GL_ARB_texture_non_power_of_two: %s\n" " - GL_ARB_texture_rectangle: %s\n"
" - GL_EXT_framebuffer_blit: %s\n" " - GL_GREMEDY_frame_terminator: %s\n"
"* Using texture rectangle: %s", priv->use_es ? "OpenGL ES"
: "OpenGL", priv->gl_version / 10, priv->gl_version % 10
, priv->is_legacy ? "legacy" : "core", epoxy_glGetString (
0x8B8C), has_npot ? "yes" : "no", has_texture_rectangle ? "yes"
: "no", priv->has_gl_framebuffer_blit ? "yes" : "no", priv
->has_frame_terminator ? "yes" : "no", priv->use_texture_rectangle
? "yes" : "no"); }; } while (0)
853 priv->use_texture_rectangle ? "yes" : "no"))do { if ((_cdk_debug_flags & CDK_DEBUG_OPENGL)) { g_message
("%s version: %d.%d (%s)\n" "* GLSL version: %s\n" "* Extensions checked:\n"
" - GL_ARB_texture_non_power_of_two: %s\n" " - GL_ARB_texture_rectangle: %s\n"
" - GL_EXT_framebuffer_blit: %s\n" " - GL_GREMEDY_frame_terminator: %s\n"
"* Using texture rectangle: %s", priv->use_es ? "OpenGL ES"
: "OpenGL", priv->gl_version / 10, priv->gl_version % 10
, priv->is_legacy ? "legacy" : "core", epoxy_glGetString (
0x8B8C), has_npot ? "yes" : "no", has_texture_rectangle ? "yes"
: "no", priv->has_gl_framebuffer_blit ? "yes" : "no", priv
->has_frame_terminator ? "yes" : "no", priv->use_texture_rectangle
? "yes" : "no"); }; } while (0)
;
854
855 priv->extensions_checked = TRUE(!(0));
856}
857
858/**
859 * cdk_gl_context_make_current:
860 * @context: a #CdkGLContext
861 *
862 * Makes the @context the current one.
863 *
864 * Since: 3.16
865 */
866void
867cdk_gl_context_make_current (CdkGLContext *context)
868{
869 CdkGLContextPrivate *priv = cdk_gl_context_get_instance_private (context);
870 CdkGLContext *current;
871
872 g_return_if_fail (CDK_IS_GL_CONTEXT (context))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((context)); GType __t = ((cdk_gl_context_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; })))))) { }
else { g_return_if_fail_warning ("Cdk", ((const char*) (__func__
)), "CDK_IS_GL_CONTEXT (context)"); return; } } while (0)
;
873
874 current = g_private_get (&thread_current_context);
875 if (current == context)
876 return;
877
878 /* we need to realize the CdkGLContext if it wasn't explicitly realized */
879 if (!priv->realized)
880 {
881 GError *error = NULL((void*)0);
882
883 cdk_gl_context_realize (context, &error);
884 if (error != NULL((void*)0))
885 {
886 g_critical ("Could not realize the GL context: %s", error->message);
887 g_error_free (error);
888 return;
889 }
890 }
891
892 if (cdk_display_make_gl_context_current (priv->display, context))
893 {
894 g_private_replace (&thread_current_context, g_object_ref (context)((__typeof__ (context)) (g_object_ref) (context)));
895 cdk_gl_context_check_extensions (context);
896 }
897}
898
899/**
900 * cdk_gl_context_get_display:
901 * @context: a #CdkGLContext
902 *
903 * Retrieves the #CdkDisplay the @context is created for
904 *
905 * Returns: (nullable) (transfer none): a #CdkDisplay or %NULL
906 *
907 * Since: 3.16
908 */
909CdkDisplay *
910cdk_gl_context_get_display (CdkGLContext *context)
911{
912 CdkGLContextPrivate *priv = cdk_gl_context_get_instance_private (context);
913
914 g_return_val_if_fail (CDK_IS_GL_CONTEXT (context), NULL)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((context)); GType __t = ((cdk_gl_context_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; })))))) { }
else { g_return_if_fail_warning ("Cdk", ((const char*) (__func__
)), "CDK_IS_GL_CONTEXT (context)"); return (((void*)0)); } } while
(0)
;
915
916 return priv->display;
917}
918
919/**
920 * cdk_gl_context_get_window:
921 * @context: a #CdkGLContext
922 *
923 * Retrieves the #CdkWindow used by the @context.
924 *
925 * Returns: (nullable) (transfer none): a #CdkWindow or %NULL
926 *
927 * Since: 3.16
928 */
929CdkWindow *
930cdk_gl_context_get_window (CdkGLContext *context)
931{
932 CdkGLContextPrivate *priv = cdk_gl_context_get_instance_private (context);
933
934 g_return_val_if_fail (CDK_IS_GL_CONTEXT (context), NULL)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((context)); GType __t = ((cdk_gl_context_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; })))))) { }
else { g_return_if_fail_warning ("Cdk", ((const char*) (__func__
)), "CDK_IS_GL_CONTEXT (context)"); return (((void*)0)); } } while
(0)
;
935
936 return priv->window;
937}
938
939/**
940 * cdk_gl_context_get_shared_context:
941 * @context: a #CdkGLContext
942 *
943 * Retrieves the #CdkGLContext that this @context share data with.
944 *
945 * Returns: (nullable) (transfer none): a #CdkGLContext or %NULL
946 *
947 * Since: 3.16
948 */
949CdkGLContext *
950cdk_gl_context_get_shared_context (CdkGLContext *context)
951{
952 CdkGLContextPrivate *priv = cdk_gl_context_get_instance_private (context);
953
954 g_return_val_if_fail (CDK_IS_GL_CONTEXT (context), NULL)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((context)); GType __t = ((cdk_gl_context_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; })))))) { }
else { g_return_if_fail_warning ("Cdk", ((const char*) (__func__
)), "CDK_IS_GL_CONTEXT (context)"); return (((void*)0)); } } while
(0)
;
955
956 return priv->shared_context;
957}
958
959/**
960 * cdk_gl_context_get_version:
961 * @context: a #CdkGLContext
962 * @major: (out): return location for the major version
963 * @minor: (out): return location for the minor version
964 *
965 * Retrieves the OpenGL version of the @context.
966 *
967 * The @context must be realized prior to calling this function.
968 *
969 * Since: 3.16
970 */
971void
972cdk_gl_context_get_version (CdkGLContext *context,
973 int *major,
974 int *minor)
975{
976 CdkGLContextPrivate *priv = cdk_gl_context_get_instance_private (context);
977
978 g_return_if_fail (CDK_IS_GL_CONTEXT (context))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance
*) ((context)); GType __t = ((cdk_gl_context_get_type ())); gboolean
__r; if (!__inst) __r = (0); else if (__inst->g_class &&
__inst->g_class->g_type == __t) __r = (!(0)); else __r
= g_type_check_instance_is_a (__inst, __t); __r; })))))) { }
else { g_return_if_fail_warning ("Cdk", ((const char*) (__func__
)), "CDK_IS_GL_CONTEXT (context)"); return; } } while (0)
;
979 g_return_if_fail (priv->realized)do { if ((priv->realized)) { } else { g_return_if_fail_warning
("Cdk", ((const char*) (__func__)), "priv->realized"); return
; } } while (0)
;
980
981 if (major != NULL((void*)0))
982 *major = priv->gl_version / 10;
983 if (minor != NULL((void*)0))
984 *minor = priv->gl_version % 10;
985}
986
987/**
988 * cdk_gl_context_clear_current:
989 *
990 * Clears the current #CdkGLContext.
991 *
992 * Any OpenGL call after this function returns will be ignored
993 * until cdk_gl_context_make_current() is called.
994 *
995 * Since: 3.16
996 */
997void
998cdk_gl_context_clear_current (void)
999{
1000 CdkGLContext *current;
1001
1002 current = g_private_get (&thread_current_context);
1003 if (current != NULL((void*)0))
1004 {
1005 CdkGLContextPrivate *priv = cdk_gl_context_get_instance_private (current);
1006
1007 if (cdk_display_make_gl_context_current (priv->display, NULL((void*)0)))
1008 g_private_replace (&thread_current_context, NULL((void*)0));
1009 }
1010}
1011
1012/**
1013 * cdk_gl_context_get_current:
1014 *
1015 * Retrieves the current #CdkGLContext.
1016 *
1017 * Returns: (nullable) (transfer none): the current #CdkGLContext, or %NULL
1018 *
1019 * Since: 3.16
1020 */
1021CdkGLContext *
1022cdk_gl_context_get_current (void)
1023{
1024 CdkGLContext *current;
1025
1026 current = g_private_get (&thread_current_context);
1027
1028 return current;
1029}
1030
1031/**
1032 * cdk_gl_get_flags:
1033 *
1034 * Returns the currently active GL flags.
1035 *
1036 * Returns: the GL flags
1037 *
1038 * Since: 3.16
1039 */
1040CdkGLFlags
1041cdk_gl_get_flags (void)
1042{
1043 return _cdk_gl_flags;
1044}
1045
1046/**
1047 * cdk_gl_set_flags:
1048 * @flags: #CdkGLFlags to set
1049 *
1050 * Sets GL flags.
1051 *
1052 * Since: 3.16
1053 */
1054void
1055cdk_gl_set_flags (CdkGLFlags flags)
1056{
1057 _cdk_gl_flags = flags;
1058}