miru_gl/
lib.rs

1use std::fmt;
2use std::ops;
3use std::rc::Rc;
4
5#[allow(clippy::all)]
6mod gl {
7    include!(concat!(env!("OUT_DIR"), "/opengl-bindings.rs"));
8}
9
10pub use gl::*;
11
12mod miru {
13    include!(concat!(env!("OUT_DIR"), "/miru-pinned-opengl-version.rs"));
14}
15
16/// Wrapper around Gl type that should be used instead of [`Gl`][1].
17///
18/// This transparent wrapper allows to safely share and use OpenGL functions
19/// without risk of them being called before they're loaded.
20///
21/// \![`Send`][2] nature of [`Rc<T>`][3] also guarantees that context won't be
22/// transferred across thread boundaries, ensuring that functions of a context
23/// can only be called in the same thread they were loaded in.
24///
25/// [1]: struct.Gl.html
26/// [2]: https://doc.rust-lang.org/std/marker/trait.Send.html
27/// [3]: https://doc.rust-lang.org/std/rc/struct.Rc.html
28#[derive(Clone)]
29pub struct MiruGl {
30    inner: Rc<Gl>,
31}
32
33impl MiruGl {
34    /// Loads OpenGL functions and returns shared handle.
35    ///
36    /// # Examples
37    ///
38    /// ~~~ignore
39    /// // the supplied function must be of the type:
40    /// // `&fn(symbol: &'static str) -> *const std::ffi::c_void`
41    /// let gl = miru_gl::MiruGl::load_with(|symbol| window.get_proc_address(symbol) as *const _);
42    /// ~~~
43    #[cfg_attr(tarpaulin, skip)]
44    pub fn load_with<F>(loadfn: F) -> MiruGl
45    where
46        F: FnMut(&'static str) -> *const std::ffi::c_void,
47    {
48        MiruGl {
49            inner: Rc::new(Gl::load_with(loadfn)),
50        }
51    }
52
53    /// Returns OpenGL version used by Miru.
54    ///
55    /// # Examples
56    ///
57    /// ~~~ignore
58    /// let (major, minor) = gl.version();
59    /// ~~~
60    #[cfg_attr(tarpaulin, skip)]
61    pub fn version(&self) -> (u8, u8) {
62        miru::OPENGL_VERSION
63    }
64}
65
66impl fmt::Debug for MiruGl {
67    #[cfg_attr(tarpaulin, skip)]
68    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
69        let (major, minor) = self.version();
70        write!(
71            f,
72            "MiruGl: Shared OpenGL {}.{} (Core Profile) api handle",
73            major, minor
74        )
75    }
76}
77
78impl ops::Deref for MiruGl {
79    type Target = Gl;
80
81    #[cfg_attr(tarpaulin, skip)]
82    fn deref(&self) -> &Self::Target {
83        &self.inner
84    }
85}