cogl/auto/renderer.rs
1#![allow(
2 clippy::too_many_arguments,
3 clippy::let_and_return,
4 clippy::from_over_into
5)]
6
7use crate::{Driver, Object, OnscreenTemplate, Output, RendererConstraint, WinsysID};
8
9use glib::translate::*;
10use std::{fmt, ptr};
11
12glib_wrapper! {
13 pub struct Renderer(Object<ffi::CoglRenderer, RendererClass>) @extends Object;
14
15 match fn {
16 get_type => || ffi::cogl_renderer_get_gtype(),
17 }
18}
19
20impl Renderer {
21 /// Instantiates a new (unconnected) `Renderer` object. A
22 /// `Renderer` represents a means to render. It encapsulates the
23 /// selection of an underlying driver, such as OpenGL or OpenGL-ES and
24 /// a selection of a window system binding API such as GLX, or EGL or
25 /// WGL.
26 ///
27 /// While the renderer is unconnected it can be configured so that
28 /// applications may specify backend constraints, such as "must use
29 /// x11" for example via `Renderer::add_constraint`.
30 ///
31 /// There are also some platform specific configuration apis such
32 /// as `cogl_xlib_renderer_set_foreign_display` that may also be
33 /// used while the renderer is unconnected.
34 ///
35 /// Once the renderer has been configured, then it may (optionally) be
36 /// explicitly connected using `Renderer::connect` which allows
37 /// errors to be handled gracefully and potentially fallback
38 /// configurations can be tried out if there are initial failures.
39 ///
40 /// If a renderer is not explicitly connected then `Display::new`
41 /// will automatically connect the renderer for you. If you don't
42 /// have any code to deal with error/fallback situations then its fine
43 /// to just let Cogl do the connection for you.
44 ///
45 /// Once you have setup your renderer then the next step is to create a
46 /// `Display` using `Display::new`.
47 ///
48 /// `<note>`Many applications don't need to explicitly use
49 /// `Renderer::new` or `Display::new` and can just jump
50 /// straight to `Context::new` and pass a `None` display argument
51 /// so Cogl will automatically connect and setup a renderer and
52 /// display.`</note>`
53 ///
54 /// # Returns
55 ///
56 /// A newly created `Renderer`.
57 pub fn new() -> Renderer {
58 unsafe { from_glib_full(ffi::cogl_renderer_new()) }
59 }
60
61 /// This adds a renderer selection `constraint`.
62 ///
63 /// Applications should ideally minimize how many of these constraints they
64 /// depend on to ensure maximum portability.
65 /// ## `constraint`
66 /// A `RendererConstraint` to add
67 pub fn add_constraint(&self, constraint: RendererConstraint) {
68 unsafe {
69 ffi::cogl_renderer_add_constraint(self.to_glib_none().0, constraint.to_glib());
70 }
71 }
72
73 /// Tests if a given `onscreen_template` can be supported with the given
74 /// `self`.
75 /// ## `onscreen_template`
76 /// A `OnscreenTemplate`
77 ///
78 /// # Returns
79 ///
80 /// `true` if the `onscreen_template` can be supported,
81 /// else `false`.
82 pub fn check_onscreen_template(
83 &self,
84 onscreen_template: &OnscreenTemplate,
85 ) -> Result<bool, glib::Error> {
86 unsafe {
87 let mut error = ptr::null_mut();
88 let ret = ffi::cogl_renderer_check_onscreen_template(
89 self.to_glib_none().0,
90 onscreen_template.to_glib_none().0,
91 &mut error,
92 );
93 if error.is_null() {
94 Ok(ret == crate::TRUE)
95 } else {
96 Err(from_glib_full(error))
97 }
98 }
99 }
100
101 /// Connects the configured `self`. Renderer connection isn't a
102 /// very active process, it basically just means validating that
103 /// any given constraint criteria can be satisfied and that a
104 /// usable driver and window system backend can be found.
105 ///
106 /// # Returns
107 ///
108 /// `true` if there was no error while connecting the
109 /// given `self`. `false` if there was an error.
110 pub fn connect(&self) -> Result<bool, glib::Error> {
111 unsafe {
112 let mut error = ptr::null_mut();
113 let ret = ffi::cogl_renderer_connect(self.to_glib_none().0, &mut error);
114 if error.is_null() {
115 Ok(ret == crate::TRUE)
116 } else {
117 Err(from_glib_full(error))
118 }
119 }
120 }
121
122 /// Iterates all known display outputs for the given `self` and
123 /// passes a corresponding `Output` pointer to the given `callback`
124 /// for each one, along with the given `user_data`.
125 /// ## `callback`
126 /// A `CoglOutputCallback` to be called for
127 /// each display output
128 /// ## `user_data`
129 /// A user pointer to be passed to `callback`
130 pub fn foreach_output<P: FnMut(&Output)>(&self, callback: P) {
131 let callback_data: P = callback;
132 unsafe extern "C" fn callback_func<P: FnMut(&Output)>(
133 output: *mut ffi::CoglOutput,
134 user_data: glib_sys::gpointer,
135 ) {
136 let output = from_glib_borrow(output);
137 let callback: *mut P = user_data as *const _ as usize as *mut P;
138 (*callback)(&output);
139 }
140 let callback = Some(callback_func::<P> as _);
141 let super_callback0: &P = &callback_data;
142 unsafe {
143 ffi::cogl_renderer_foreach_output(
144 self.to_glib_none().0,
145 callback,
146 super_callback0 as *const _ as usize as *mut _,
147 );
148 }
149 }
150
151 /// Queries what underlying driver is being used by Cogl.
152 ///
153 /// This may only be called on a connected `Renderer`.
154 pub fn get_driver(&self) -> Driver {
155 unsafe { from_glib(ffi::cogl_renderer_get_driver(self.to_glib_none().0)) }
156 }
157
158 /// Queries how many texture units can be used from fragment programs
159 ///
160 /// # Returns
161 ///
162 /// the number of texture image units.
163 pub fn get_n_fragment_texture_units(&self) -> i32 {
164 unsafe { ffi::cogl_renderer_get_n_fragment_texture_units(self.to_glib_none().0) }
165 }
166
167 /// Queries which window system backend Cogl has chosen to use.
168 ///
169 /// This may only be called on a connected `Renderer`.
170 ///
171 /// # Returns
172 ///
173 /// The `WinsysID` corresponding to the chosen window
174 /// system backend.
175 pub fn get_winsys_id(&self) -> WinsysID {
176 unsafe { from_glib(ffi::cogl_renderer_get_winsys_id(self.to_glib_none().0)) }
177 }
178
179 /// This removes a renderer selection `constraint`.
180 ///
181 /// Applications should ideally minimize how many of these constraints they
182 /// depend on to ensure maximum portability.
183 /// ## `constraint`
184 /// A `RendererConstraint` to remove
185 pub fn remove_constraint(&self, constraint: RendererConstraint) {
186 unsafe {
187 ffi::cogl_renderer_remove_constraint(self.to_glib_none().0, constraint.to_glib());
188 }
189 }
190
191 /// Requests that Cogl should try to use a specific underlying driver
192 /// for rendering.
193 ///
194 /// If you select an unsupported driver then `Renderer::connect`
195 /// will fail and report an error. Most applications should not
196 /// explicitly select a driver and should rely on Cogl automatically
197 /// choosing the driver.
198 ///
199 /// This may only be called on an un-connected `Renderer`.
200 pub fn set_driver(&self, driver: Driver) {
201 unsafe {
202 ffi::cogl_renderer_set_driver(self.to_glib_none().0, driver.to_glib());
203 }
204 }
205
206 /// This allows you to explicitly select a winsys backend to use instead
207 /// of letting Cogl automatically select a backend.
208 ///
209 /// if you select an unsupported backend then `Renderer::connect`
210 /// will fail and report an error.
211 ///
212 /// This may only be called on an un-connected `Renderer`.
213 /// ## `winsys_id`
214 /// An ID of the winsys you explicitly want to use.
215 pub fn set_winsys_id(&self, winsys_id: WinsysID) {
216 unsafe {
217 ffi::cogl_renderer_set_winsys_id(self.to_glib_none().0, winsys_id.to_glib());
218 }
219 }
220}
221
222impl Default for Renderer {
223 fn default() -> Self {
224 Self::new()
225 }
226}
227
228impl fmt::Display for Renderer {
229 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
230 write!(f, "Renderer")
231 }
232}