gdk4/auto/
gl_context.rs

1// This file was generated by gir (https://github.com/gtk-rs/gir)
2// from gir-files (https://github.com/gtk-rs/gir-files)
3// DO NOT EDIT
4#![allow(deprecated)]
5
6#[cfg(feature = "v4_6")]
7#[cfg_attr(docsrs, doc(cfg(feature = "v4_6")))]
8use crate::GLAPI;
9use crate::{ffi, Display, DrawContext, Surface};
10#[cfg(feature = "v4_6")]
11#[cfg_attr(docsrs, doc(cfg(feature = "v4_6")))]
12use glib::signal::{connect_raw, SignalHandlerId};
13use glib::{prelude::*, translate::*};
14#[cfg(feature = "v4_6")]
15#[cfg_attr(docsrs, doc(cfg(feature = "v4_6")))]
16use std::boxed::Box as Box_;
17
18glib::wrapper! {
19    /// Represents a platform-specific OpenGL draw context.
20    ///
21    /// [`GLContext`][crate::GLContext]s are created for a surface using
22    /// [`SurfaceExt::create_gl_context()`][crate::prelude::SurfaceExt::create_gl_context()], and the context will match
23    /// the characteristics of the surface.
24    ///
25    /// A [`GLContext`][crate::GLContext] is not tied to any particular normal framebuffer.
26    /// For instance, it cannot draw to the surface back buffer. The GDK
27    /// repaint system is in full control of the painting to that. Instead,
28    /// you can create render buffers or textures and use [`draw_from_gl()`][crate::draw_from_gl()]
29    /// in the draw function of your widget to draw them. Then GDK will handle
30    /// the integration of your rendering with that of other widgets.
31    ///
32    /// Support for [`GLContext`][crate::GLContext] is platform-specific and context creation
33    /// can fail, returning [`None`] context.
34    ///
35    /// A [`GLContext`][crate::GLContext] has to be made "current" in order to start using
36    /// it, otherwise any OpenGL call will be ignored.
37    ///
38    /// ## Creating a new OpenGL context
39    ///
40    /// In order to create a new [`GLContext`][crate::GLContext] instance you need a [`Surface`][crate::Surface],
41    /// which you typically get during the realize call of a widget.
42    ///
43    /// A [`GLContext`][crate::GLContext] is not realized until either [`GLContextExt::make_current()`][crate::prelude::GLContextExt::make_current()]
44    /// or [`GLContextExt::realize()`][crate::prelude::GLContextExt::realize()] is called. It is possible to specify
45    /// details of the GL context like the OpenGL version to be used, or whether
46    /// the GL context should have extra state validation enabled after calling
47    /// [`SurfaceExt::create_gl_context()`][crate::prelude::SurfaceExt::create_gl_context()] by calling [`GLContextExt::realize()`][crate::prelude::GLContextExt::realize()].
48    /// If the realization fails you have the option to change the settings of
49    /// the [`GLContext`][crate::GLContext] and try again.
50    ///
51    /// ## Using a GdkGLContext
52    ///
53    /// You will need to make the [`GLContext`][crate::GLContext] the current context before issuing
54    /// OpenGL calls; the system sends OpenGL commands to whichever context is current.
55    /// It is possible to have multiple contexts, so you always need to ensure that
56    /// the one which you want to draw with is the current one before issuing commands:
57    ///
58    /// **⚠️ The following code is in c ⚠️**
59    ///
60    /// ```c
61    /// gdk_gl_context_make_current (context);
62    /// ```
63    ///
64    /// You can now perform your drawing using OpenGL commands.
65    ///
66    /// You can check which [`GLContext`][crate::GLContext] is the current one by using
67    /// [`current()`][Self::current()]; you can also unset any [`GLContext`][crate::GLContext]
68    /// that is currently set by calling [`clear_current()`][Self::clear_current()].
69    ///
70    /// This is an Abstract Base Class, you cannot instantiate it.
71    ///
72    /// ## Properties
73    ///
74    ///
75    /// #### `allowed-apis`
76    ///  The allowed APIs.
77    ///
78    /// Readable | Writeable
79    ///
80    ///
81    /// #### `api`
82    ///  The API currently in use.
83    ///
84    /// Readable
85    ///
86    ///
87    /// #### `shared-context`
88    ///  Always [`None`]
89    ///
90    /// As many contexts can share data now and no single shared context exists
91    /// anymore, this function has been deprecated and now always returns [`None`].
92    ///
93    /// Readable | Writeable | Construct Only
94    /// <details><summary><h4>DrawContext</h4></summary>
95    ///
96    ///
97    /// #### `display`
98    ///  The [`Display`][crate::Display] used to create the [`DrawContext`][crate::DrawContext].
99    ///
100    /// Readable | Writeable | Construct Only
101    ///
102    ///
103    /// #### `surface`
104    ///  The [`Surface`][crate::Surface] the context is bound to.
105    ///
106    /// Readable | Writeable | Construct Only
107    /// </details>
108    ///
109    /// # Implements
110    ///
111    /// [`GLContextExt`][trait@crate::prelude::GLContextExt], [`DrawContextExt`][trait@crate::prelude::DrawContextExt], [`DrawContextExtManual`][trait@crate::prelude::DrawContextExtManual]
112    #[doc(alias = "GdkGLContext")]
113    pub struct GLContext(Object<ffi::GdkGLContext>) @extends DrawContext;
114
115    match fn {
116        type_ => || ffi::gdk_gl_context_get_type(),
117    }
118}
119
120impl GLContext {
121    pub const NONE: Option<&'static GLContext> = None;
122
123    /// Clears the current [`GLContext`][crate::GLContext].
124    ///
125    /// Any OpenGL call after this function returns will be ignored
126    /// until [`GLContextExt::make_current()`][crate::prelude::GLContextExt::make_current()] is called.
127    #[doc(alias = "gdk_gl_context_clear_current")]
128    pub fn clear_current() {
129        assert_initialized_main_thread!();
130        unsafe {
131            ffi::gdk_gl_context_clear_current();
132        }
133    }
134
135    /// Retrieves the current [`GLContext`][crate::GLContext].
136    ///
137    /// # Returns
138    ///
139    /// the current [`GLContext`][crate::GLContext]
140    #[doc(alias = "gdk_gl_context_get_current")]
141    #[doc(alias = "get_current")]
142    pub fn current() -> Option<GLContext> {
143        assert_initialized_main_thread!();
144        unsafe { from_glib_none(ffi::gdk_gl_context_get_current()) }
145    }
146}
147
148/// Trait containing all [`struct@GLContext`] methods.
149///
150/// # Implementors
151///
152/// [`GLContext`][struct@crate::GLContext]
153pub trait GLContextExt: IsA<GLContext> + 'static {
154    /// Gets the allowed APIs set via gdk_gl_context_set_allowed_apis().
155    ///
156    /// # Returns
157    ///
158    /// the allowed APIs
159    #[cfg(feature = "v4_6")]
160    #[cfg_attr(docsrs, doc(cfg(feature = "v4_6")))]
161    #[doc(alias = "gdk_gl_context_get_allowed_apis")]
162    #[doc(alias = "get_allowed_apis")]
163    #[doc(alias = "allowed-apis")]
164    fn allowed_apis(&self) -> GLAPI {
165        unsafe {
166            from_glib(ffi::gdk_gl_context_get_allowed_apis(
167                self.as_ref().to_glib_none().0,
168            ))
169        }
170    }
171
172    /// Gets the API currently in use.
173    ///
174    /// If the renderer has not been realized yet, 0 is returned.
175    ///
176    /// # Returns
177    ///
178    /// the currently used API
179    #[cfg(feature = "v4_6")]
180    #[cfg_attr(docsrs, doc(cfg(feature = "v4_6")))]
181    #[doc(alias = "gdk_gl_context_get_api")]
182    #[doc(alias = "get_api")]
183    fn api(&self) -> GLAPI {
184        unsafe { from_glib(ffi::gdk_gl_context_get_api(self.as_ref().to_glib_none().0)) }
185    }
186
187    /// Retrieves whether the context is doing extra validations and runtime checking.
188    ///
189    /// See [`set_debug_enabled()`][Self::set_debug_enabled()].
190    ///
191    /// # Returns
192    ///
193    /// [`true`] if debugging is enabled
194    #[doc(alias = "gdk_gl_context_get_debug_enabled")]
195    #[doc(alias = "get_debug_enabled")]
196    fn is_debug_enabled(&self) -> bool {
197        unsafe {
198            from_glib(ffi::gdk_gl_context_get_debug_enabled(
199                self.as_ref().to_glib_none().0,
200            ))
201        }
202    }
203
204    /// Retrieves the display the @self is created for
205    ///
206    /// # Returns
207    ///
208    /// a [`Display`][crate::Display]
209    #[doc(alias = "gdk_gl_context_get_display")]
210    #[doc(alias = "get_display")]
211    fn display(&self) -> Option<Display> {
212        unsafe {
213            from_glib_none(ffi::gdk_gl_context_get_display(
214                self.as_ref().to_glib_none().0,
215            ))
216        }
217    }
218
219    /// Retrieves whether the context is forward-compatible.
220    ///
221    /// See [`set_forward_compatible()`][Self::set_forward_compatible()].
222    ///
223    /// # Returns
224    ///
225    /// [`true`] if the context should be forward-compatible
226    #[doc(alias = "gdk_gl_context_get_forward_compatible")]
227    #[doc(alias = "get_forward_compatible")]
228    fn is_forward_compatible(&self) -> bool {
229        unsafe {
230            from_glib(ffi::gdk_gl_context_get_forward_compatible(
231                self.as_ref().to_glib_none().0,
232            ))
233        }
234    }
235
236    /// Retrieves required OpenGL version set as a requirement for the @self
237    /// realization. It will not change even if a greater OpenGL version is supported
238    /// and used after the @self is realized. See
239    /// [`version()`][Self::version()] for the real version in use.
240    ///
241    /// See [`set_required_version()`][Self::set_required_version()].
242    ///
243    /// # Returns
244    ///
245    ///
246    /// ## `major`
247    /// return location for the major version to request
248    ///
249    /// ## `minor`
250    /// return location for the minor version to request
251    #[doc(alias = "gdk_gl_context_get_required_version")]
252    #[doc(alias = "get_required_version")]
253    fn required_version(&self) -> (i32, i32) {
254        unsafe {
255            let mut major = std::mem::MaybeUninit::uninit();
256            let mut minor = std::mem::MaybeUninit::uninit();
257            ffi::gdk_gl_context_get_required_version(
258                self.as_ref().to_glib_none().0,
259                major.as_mut_ptr(),
260                minor.as_mut_ptr(),
261            );
262            (major.assume_init(), minor.assume_init())
263        }
264    }
265
266    /// Used to retrieves the [`GLContext`][crate::GLContext] that this @self share data with.
267    ///
268    /// As many contexts can share data now and no single shared context exists
269    /// anymore, this function has been deprecated and now always returns [`None`].
270    ///
271    /// # Deprecated since 4.4
272    ///
273    /// Use [`is_shared()`][Self::is_shared()] to check if contexts
274    ///   can be shared.
275    ///
276    /// # Returns
277    ///
278    /// [`None`]
279    #[cfg_attr(feature = "v4_4", deprecated = "Since 4.4")]
280    #[allow(deprecated)]
281    #[doc(alias = "gdk_gl_context_get_shared_context")]
282    #[doc(alias = "get_shared_context")]
283    #[doc(alias = "shared-context")]
284    #[must_use]
285    fn shared_context(&self) -> Option<GLContext> {
286        unsafe {
287            from_glib_none(ffi::gdk_gl_context_get_shared_context(
288                self.as_ref().to_glib_none().0,
289            ))
290        }
291    }
292
293    /// Retrieves the surface used by the @self.
294    ///
295    /// # Returns
296    ///
297    /// a [`Surface`][crate::Surface]
298    #[doc(alias = "gdk_gl_context_get_surface")]
299    #[doc(alias = "get_surface")]
300    fn surface(&self) -> Option<Surface> {
301        unsafe {
302            from_glib_none(ffi::gdk_gl_context_get_surface(
303                self.as_ref().to_glib_none().0,
304            ))
305        }
306    }
307
308    /// Checks whether the @self is using an OpenGL or OpenGL ES profile.
309    ///
310    /// # Returns
311    ///
312    /// [`true`] if the [`GLContext`][crate::GLContext] is using an OpenGL ES profile;
313    /// [`false`] if other profile is in use of if the @self has not yet
314    /// been realized.
315    #[doc(alias = "gdk_gl_context_get_use_es")]
316    #[doc(alias = "get_use_es")]
317    fn uses_es(&self) -> bool {
318        unsafe {
319            from_glib(ffi::gdk_gl_context_get_use_es(
320                self.as_ref().to_glib_none().0,
321            ))
322        }
323    }
324
325    /// Retrieves the OpenGL version of the @self.
326    ///
327    /// The @self must be realized prior to calling this function.
328    ///
329    /// # Returns
330    ///
331    ///
332    /// ## `major`
333    /// return location for the major version
334    ///
335    /// ## `minor`
336    /// return location for the minor version
337    #[doc(alias = "gdk_gl_context_get_version")]
338    #[doc(alias = "get_version")]
339    fn version(&self) -> (i32, i32) {
340        unsafe {
341            let mut major = std::mem::MaybeUninit::uninit();
342            let mut minor = std::mem::MaybeUninit::uninit();
343            ffi::gdk_gl_context_get_version(
344                self.as_ref().to_glib_none().0,
345                major.as_mut_ptr(),
346                minor.as_mut_ptr(),
347            );
348            (major.assume_init(), minor.assume_init())
349        }
350    }
351
352    /// Whether the [`GLContext`][crate::GLContext] is in legacy mode or not.
353    ///
354    /// The [`GLContext`][crate::GLContext] must be realized before calling this function.
355    ///
356    /// When realizing a GL context, GDK will try to use the OpenGL 3.2 core
357    /// profile; this profile removes all the OpenGL API that was deprecated
358    /// prior to the 3.2 version of the specification. If the realization is
359    /// successful, this function will return [`false`].
360    ///
361    /// If the underlying OpenGL implementation does not support core profiles,
362    /// GDK will fall back to a pre-3.2 compatibility profile, and this function
363    /// will return [`true`].
364    ///
365    /// You can use the value returned by this function to decide which kind
366    /// of OpenGL API to use, or whether to do extension discovery, or what
367    /// kind of shader programs to load.
368    ///
369    /// # Returns
370    ///
371    /// [`true`] if the GL context is in legacy mode
372    #[doc(alias = "gdk_gl_context_is_legacy")]
373    fn is_legacy(&self) -> bool {
374        unsafe {
375            from_glib(ffi::gdk_gl_context_is_legacy(
376                self.as_ref().to_glib_none().0,
377            ))
378        }
379    }
380
381    /// Checks if the two GL contexts can share resources.
382    ///
383    /// When they can, the texture IDs from @other can be used in @self. This
384    /// is particularly useful when passing [`GLTexture`][crate::GLTexture] objects between
385    /// different contexts.
386    ///
387    /// Contexts created for the same display with the same properties will
388    /// always be compatible, even if they are created for different surfaces.
389    /// For other contexts it depends on the GL backend.
390    ///
391    /// Both contexts must be realized for this check to succeed. If either one
392    /// is not, this function will return [`false`].
393    /// ## `other`
394    /// the [`GLContext`][crate::GLContext] that should be compatible with @self
395    ///
396    /// # Returns
397    ///
398    /// [`true`] if the two GL contexts are compatible.
399    #[cfg(feature = "v4_4")]
400    #[cfg_attr(docsrs, doc(cfg(feature = "v4_4")))]
401    #[doc(alias = "gdk_gl_context_is_shared")]
402    fn is_shared(&self, other: &impl IsA<GLContext>) -> bool {
403        unsafe {
404            from_glib(ffi::gdk_gl_context_is_shared(
405                self.as_ref().to_glib_none().0,
406                other.as_ref().to_glib_none().0,
407            ))
408        }
409    }
410
411    /// Makes the @self the current one.
412    #[doc(alias = "gdk_gl_context_make_current")]
413    fn make_current(&self) {
414        unsafe {
415            ffi::gdk_gl_context_make_current(self.as_ref().to_glib_none().0);
416        }
417    }
418
419    /// Realizes the given [`GLContext`][crate::GLContext].
420    ///
421    /// It is safe to call this function on a realized [`GLContext`][crate::GLContext].
422    ///
423    /// # Returns
424    ///
425    /// [`true`] if the context is realized
426    #[doc(alias = "gdk_gl_context_realize")]
427    fn realize(&self) -> Result<(), glib::Error> {
428        unsafe {
429            let mut error = std::ptr::null_mut();
430            let is_ok = ffi::gdk_gl_context_realize(self.as_ref().to_glib_none().0, &mut error);
431            debug_assert_eq!(is_ok == glib::ffi::GFALSE, !error.is_null());
432            if error.is_null() {
433                Ok(())
434            } else {
435                Err(from_glib_full(error))
436            }
437        }
438    }
439
440    /// Sets the allowed APIs. When gdk_gl_context_realize() is called, only the
441    /// allowed APIs will be tried. If you set this to 0, realizing will always fail.
442    ///
443    /// If you set it on a realized context, the property will not have any effect.
444    /// It is only relevant during gdk_gl_context_realize().
445    ///
446    /// By default, all APIs are allowed.
447    /// ## `apis`
448    /// the allowed APIs
449    #[cfg(feature = "v4_6")]
450    #[cfg_attr(docsrs, doc(cfg(feature = "v4_6")))]
451    #[doc(alias = "gdk_gl_context_set_allowed_apis")]
452    #[doc(alias = "allowed-apis")]
453    fn set_allowed_apis(&self, apis: GLAPI) {
454        unsafe {
455            ffi::gdk_gl_context_set_allowed_apis(self.as_ref().to_glib_none().0, apis.into_glib());
456        }
457    }
458
459    /// Sets whether the [`GLContext`][crate::GLContext] should perform extra validations and
460    /// runtime checking.
461    ///
462    /// This is useful during development, but has additional overhead.
463    ///
464    /// The [`GLContext`][crate::GLContext] must not be realized or made current prior to
465    /// calling this function.
466    /// ## `enabled`
467    /// whether to enable debugging in the context
468    #[doc(alias = "gdk_gl_context_set_debug_enabled")]
469    fn set_debug_enabled(&self, enabled: bool) {
470        unsafe {
471            ffi::gdk_gl_context_set_debug_enabled(
472                self.as_ref().to_glib_none().0,
473                enabled.into_glib(),
474            );
475        }
476    }
477
478    /// Sets whether the [`GLContext`][crate::GLContext] should be forward-compatible.
479    ///
480    /// Forward-compatible contexts must not support OpenGL functionality that
481    /// has been marked as deprecated in the requested version; non-forward
482    /// compatible contexts, on the other hand, must support both deprecated and
483    /// non deprecated functionality.
484    ///
485    /// The [`GLContext`][crate::GLContext] must not be realized or made current prior to calling
486    /// this function.
487    /// ## `compatible`
488    /// whether the context should be forward-compatible
489    #[doc(alias = "gdk_gl_context_set_forward_compatible")]
490    fn set_forward_compatible(&self, compatible: bool) {
491        unsafe {
492            ffi::gdk_gl_context_set_forward_compatible(
493                self.as_ref().to_glib_none().0,
494                compatible.into_glib(),
495            );
496        }
497    }
498
499    /// Sets the major and minor version of OpenGL to request.
500    ///
501    /// Setting @major and @minor to zero will use the default values.
502    ///
503    /// Setting @major and @minor lower than the minimum versions required
504    /// by GTK will result in the context choosing the minimum version.
505    ///
506    /// The @self must not be realized or made current prior to calling
507    /// this function.
508    /// ## `major`
509    /// the major version to request
510    /// ## `minor`
511    /// the minor version to request
512    #[doc(alias = "gdk_gl_context_set_required_version")]
513    fn set_required_version(&self, major: i32, minor: i32) {
514        unsafe {
515            ffi::gdk_gl_context_set_required_version(self.as_ref().to_glib_none().0, major, minor);
516        }
517    }
518
519    /// Requests that GDK create an OpenGL ES context instead of an OpenGL one.
520    ///
521    /// Not all platforms support OpenGL ES.
522    ///
523    /// The @self must not have been realized.
524    ///
525    /// By default, GDK will attempt to automatically detect whether the
526    /// underlying GL implementation is OpenGL or OpenGL ES once the @self
527    /// is realized.
528    ///
529    /// You should check the return value of [`uses_es()`][Self::uses_es()]
530    /// after calling [`realize()`][Self::realize()] to decide whether to use
531    /// the OpenGL or OpenGL ES API, extensions, or shaders.
532    /// ## `use_es`
533    /// whether the context should use OpenGL ES instead of OpenGL,
534    ///   or -1 to allow auto-detection
535    #[doc(alias = "gdk_gl_context_set_use_es")]
536    fn set_use_es(&self, use_es: i32) {
537        unsafe {
538            ffi::gdk_gl_context_set_use_es(self.as_ref().to_glib_none().0, use_es);
539        }
540    }
541
542    #[cfg(feature = "v4_6")]
543    #[cfg_attr(docsrs, doc(cfg(feature = "v4_6")))]
544    #[doc(alias = "allowed-apis")]
545    fn connect_allowed_apis_notify<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
546        unsafe extern "C" fn notify_allowed_apis_trampoline<
547            P: IsA<GLContext>,
548            F: Fn(&P) + 'static,
549        >(
550            this: *mut ffi::GdkGLContext,
551            _param_spec: glib::ffi::gpointer,
552            f: glib::ffi::gpointer,
553        ) {
554            let f: &F = &*(f as *const F);
555            f(GLContext::from_glib_borrow(this).unsafe_cast_ref())
556        }
557        unsafe {
558            let f: Box_<F> = Box_::new(f);
559            connect_raw(
560                self.as_ptr() as *mut _,
561                c"notify::allowed-apis".as_ptr() as *const _,
562                Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
563                    notify_allowed_apis_trampoline::<Self, F> as *const (),
564                )),
565                Box_::into_raw(f),
566            )
567        }
568    }
569
570    #[cfg(feature = "v4_6")]
571    #[cfg_attr(docsrs, doc(cfg(feature = "v4_6")))]
572    #[doc(alias = "api")]
573    fn connect_api_notify<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
574        unsafe extern "C" fn notify_api_trampoline<P: IsA<GLContext>, F: Fn(&P) + 'static>(
575            this: *mut ffi::GdkGLContext,
576            _param_spec: glib::ffi::gpointer,
577            f: glib::ffi::gpointer,
578        ) {
579            let f: &F = &*(f as *const F);
580            f(GLContext::from_glib_borrow(this).unsafe_cast_ref())
581        }
582        unsafe {
583            let f: Box_<F> = Box_::new(f);
584            connect_raw(
585                self.as_ptr() as *mut _,
586                c"notify::api".as_ptr() as *const _,
587                Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
588                    notify_api_trampoline::<Self, F> as *const (),
589                )),
590                Box_::into_raw(f),
591            )
592        }
593    }
594}
595
596impl<O: IsA<GLContext>> GLContextExt for O {}