gsk4/auto/renderer.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
5use crate::{ffi, RenderNode};
6use glib::{
7 prelude::*,
8 signal::{connect_raw, SignalHandlerId},
9 translate::*,
10};
11use std::boxed::Box as Box_;
12
13glib::wrapper! {
14 /// A class that renders a scene graph defined via a tree of
15 /// [`RenderNode`][crate::RenderNode] instances.
16 ///
17 /// Typically you will use a [`Renderer`][crate::Renderer] instance to repeatedly call
18 /// [`GskRendererExt::render()`][crate::prelude::GskRendererExt::render()] to update the contents of its associated
19 /// [`gdk::Surface`][crate::gdk::Surface].
20 ///
21 /// It is necessary to realize a [`Renderer`][crate::Renderer] instance using
22 /// [`GskRendererExt::realize()`][crate::prelude::GskRendererExt::realize()] before calling [`GskRendererExt::render()`][crate::prelude::GskRendererExt::render()],
23 /// in order to create the appropriate windowing system resources needed
24 /// to render the scene.
25 ///
26 /// This is an Abstract Base Class, you cannot instantiate it.
27 ///
28 /// ## Properties
29 ///
30 ///
31 /// #### `realized`
32 /// Whether the renderer has been associated with a surface or draw context.
33 ///
34 /// Readable
35 ///
36 ///
37 /// #### `surface`
38 /// The surface associated with renderer.
39 ///
40 /// Readable
41 ///
42 /// # Implements
43 ///
44 /// [`GskRendererExt`][trait@crate::prelude::GskRendererExt]
45 #[doc(alias = "GskRenderer")]
46 pub struct Renderer(Object<ffi::GskRenderer, ffi::GskRendererClass>);
47
48 match fn {
49 type_ => || ffi::gsk_renderer_get_type(),
50 }
51}
52
53impl Renderer {
54 pub const NONE: Option<&'static Renderer> = None;
55
56 /// Creates an appropriate [`Renderer`][crate::Renderer] instance for the given surface.
57 ///
58 /// If the `GSK_RENDERER` environment variable is set, GSK will
59 /// try that renderer first, before trying the backend-specific
60 /// default. The ultimate fallback is the cairo renderer.
61 ///
62 /// The renderer will be realized before it is returned.
63 /// ## `surface`
64 /// a surface
65 ///
66 /// # Returns
67 ///
68 /// the realized renderer
69 #[doc(alias = "gsk_renderer_new_for_surface")]
70 #[doc(alias = "new_for_surface")]
71 pub fn for_surface(surface: &gdk::Surface) -> Option<Renderer> {
72 assert_initialized_main_thread!();
73 unsafe { from_glib_full(ffi::gsk_renderer_new_for_surface(surface.to_glib_none().0)) }
74 }
75}
76
77mod sealed {
78 pub trait Sealed {}
79 impl<T: super::IsA<super::Renderer>> Sealed for T {}
80}
81
82/// Trait containing all [`struct@Renderer`] methods.
83///
84/// # Implementors
85///
86/// [`BroadwayRenderer`][struct@crate::BroadwayRenderer], [`CairoRenderer`][struct@crate::CairoRenderer], [`GLRenderer`][struct@crate::GLRenderer], [`NglRenderer`][struct@crate::NglRenderer], [`Renderer`][struct@crate::Renderer], [`VulkanRenderer`][struct@crate::VulkanRenderer]
87pub trait GskRendererExt: IsA<Renderer> + sealed::Sealed + 'static {
88 /// Retrieves the surface that the renderer is associated with.
89 ///
90 /// If the renderer has not been realized yet, `NULL` will be returned.
91 ///
92 /// # Returns
93 ///
94 /// the surface
95 #[doc(alias = "gsk_renderer_get_surface")]
96 #[doc(alias = "get_surface")]
97 fn surface(&self) -> Option<gdk::Surface> {
98 unsafe {
99 from_glib_none(ffi::gsk_renderer_get_surface(
100 self.as_ref().to_glib_none().0,
101 ))
102 }
103 }
104
105 /// Checks whether the renderer is realized or not.
106 ///
107 /// # Returns
108 ///
109 /// true if the renderer was realized, false otherwise
110 #[doc(alias = "gsk_renderer_is_realized")]
111 #[doc(alias = "realized")]
112 fn is_realized(&self) -> bool {
113 unsafe {
114 from_glib(ffi::gsk_renderer_is_realized(
115 self.as_ref().to_glib_none().0,
116 ))
117 }
118 }
119
120 /// Creates the resources needed by the renderer.
121 ///
122 /// Since GTK 4.6, the surface may be `NULL`, which allows using
123 /// renderers without having to create a surface. Since GTK 4.14,
124 /// it is recommended to use [`realize_for_display()`][Self::realize_for_display()]
125 /// for this case.
126 ///
127 /// Note that it is mandatory to call [`unrealize()`][Self::unrealize()]
128 /// before destroying the renderer.
129 /// ## `surface`
130 /// the surface that renderer will be used on
131 ///
132 /// # Returns
133 ///
134 /// whether the renderer was successfully realized
135 #[doc(alias = "gsk_renderer_realize")]
136 fn realize(&self, surface: Option<&gdk::Surface>) -> Result<(), glib::Error> {
137 unsafe {
138 let mut error = std::ptr::null_mut();
139 let is_ok = ffi::gsk_renderer_realize(
140 self.as_ref().to_glib_none().0,
141 surface.to_glib_none().0,
142 &mut error,
143 );
144 debug_assert_eq!(is_ok == glib::ffi::GFALSE, !error.is_null());
145 if error.is_null() {
146 Ok(())
147 } else {
148 Err(from_glib_full(error))
149 }
150 }
151 }
152
153 /// Creates the resources needed by the renderer.
154 ///
155 /// Note that it is mandatory to call [`unrealize()`][Self::unrealize()]
156 /// before destroying the renderer.
157 /// ## `display`
158 /// the display that the renderer will be used on
159 ///
160 /// # Returns
161 ///
162 /// whether the renderer was successfully realized
163 #[cfg(feature = "v4_14")]
164 #[cfg_attr(docsrs, doc(cfg(feature = "v4_14")))]
165 #[doc(alias = "gsk_renderer_realize_for_display")]
166 fn realize_for_display(&self, display: &gdk::Display) -> Result<(), glib::Error> {
167 unsafe {
168 let mut error = std::ptr::null_mut();
169 let is_ok = ffi::gsk_renderer_realize_for_display(
170 self.as_ref().to_glib_none().0,
171 display.to_glib_none().0,
172 &mut error,
173 );
174 debug_assert_eq!(is_ok == glib::ffi::GFALSE, !error.is_null());
175 if error.is_null() {
176 Ok(())
177 } else {
178 Err(from_glib_full(error))
179 }
180 }
181 }
182
183 /// Renders the scene graph, described by a tree of [`RenderNode`][crate::RenderNode] instances
184 /// to the renderer's surface, ensuring that the given region gets redrawn.
185 ///
186 /// If the renderer has no associated surface, this function does nothing.
187 ///
188 /// Renderers must ensure that changes of the contents given by the @root
189 /// node as well as the area given by @region are redrawn. They are however
190 /// free to not redraw any pixel outside of @region if they can guarantee that
191 /// it didn't change.
192 ///
193 /// The renderer will acquire a reference on the [`RenderNode`][crate::RenderNode] tree while
194 /// the rendering is in progress.
195 /// ## `root`
196 /// the render node to render
197 /// ## `region`
198 /// the [`cairo::Region`][crate::cairo::Region] that must be redrawn or `NULL`
199 /// for the whole surface
200 #[doc(alias = "gsk_renderer_render")]
201 fn render(&self, root: impl AsRef<RenderNode>, region: Option<&cairo::Region>) {
202 unsafe {
203 ffi::gsk_renderer_render(
204 self.as_ref().to_glib_none().0,
205 root.as_ref().to_glib_none().0,
206 region.to_glib_none().0,
207 );
208 }
209 }
210
211 /// Renders a scene graph, described by a tree of [`RenderNode`][crate::RenderNode] instances,
212 /// to a texture.
213 ///
214 /// The renderer will acquire a reference on the [`RenderNode`][crate::RenderNode] tree while
215 /// the rendering is in progress.
216 ///
217 /// If you want to apply any transformations to @root, you should put it into a
218 /// transform node and pass that node instead.
219 /// ## `root`
220 /// the render node to render
221 /// ## `viewport`
222 /// the section to draw or `NULL` to use @root's bounds
223 ///
224 /// # Returns
225 ///
226 /// a texture with the rendered contents of @root
227 #[doc(alias = "gsk_renderer_render_texture")]
228 fn render_texture(
229 &self,
230 root: impl AsRef<RenderNode>,
231 viewport: Option<&graphene::Rect>,
232 ) -> gdk::Texture {
233 unsafe {
234 from_glib_full(ffi::gsk_renderer_render_texture(
235 self.as_ref().to_glib_none().0,
236 root.as_ref().to_glib_none().0,
237 viewport.to_glib_none().0,
238 ))
239 }
240 }
241
242 /// Releases all the resources created by [`realize()`][Self::realize()].
243 #[doc(alias = "gsk_renderer_unrealize")]
244 fn unrealize(&self) {
245 unsafe {
246 ffi::gsk_renderer_unrealize(self.as_ref().to_glib_none().0);
247 }
248 }
249
250 #[doc(alias = "realized")]
251 fn connect_realized_notify<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
252 unsafe extern "C" fn notify_realized_trampoline<P: IsA<Renderer>, F: Fn(&P) + 'static>(
253 this: *mut ffi::GskRenderer,
254 _param_spec: glib::ffi::gpointer,
255 f: glib::ffi::gpointer,
256 ) {
257 let f: &F = &*(f as *const F);
258 f(Renderer::from_glib_borrow(this).unsafe_cast_ref())
259 }
260 unsafe {
261 let f: Box_<F> = Box_::new(f);
262 connect_raw(
263 self.as_ptr() as *mut _,
264 b"notify::realized\0".as_ptr() as *const _,
265 Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
266 notify_realized_trampoline::<Self, F> as *const (),
267 )),
268 Box_::into_raw(f),
269 )
270 }
271 }
272
273 #[doc(alias = "surface")]
274 fn connect_surface_notify<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
275 unsafe extern "C" fn notify_surface_trampoline<P: IsA<Renderer>, F: Fn(&P) + 'static>(
276 this: *mut ffi::GskRenderer,
277 _param_spec: glib::ffi::gpointer,
278 f: glib::ffi::gpointer,
279 ) {
280 let f: &F = &*(f as *const F);
281 f(Renderer::from_glib_borrow(this).unsafe_cast_ref())
282 }
283 unsafe {
284 let f: Box_<F> = Box_::new(f);
285 connect_raw(
286 self.as_ptr() as *mut _,
287 b"notify::surface\0".as_ptr() as *const _,
288 Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
289 notify_surface_trampoline::<Self, F> as *const (),
290 )),
291 Box_::into_raw(f),
292 )
293 }
294 }
295}
296
297impl<O: IsA<Renderer>> GskRendererExt for O {}