diff --git a/src/backend/glium.rs b/src/backend/glium.rs index 26eefd9..2105eed 100644 --- a/src/backend/glium.rs +++ b/src/backend/glium.rs @@ -1,9 +1,15 @@ -use backend::graphics::egl::{EGLGraphicsBackend, SwapBuffersError}; -use glium::SwapBuffersError as GliumSwapBuffersError; -use glium::backend::Backend; +//! Glium compatibility module +use backend::graphics::egl::{EGLGraphicsBackend, SwapBuffersError}; +use glium::Frame; +use glium::SwapBuffersError as GliumSwapBuffersError; +use glium::backend::{Backend, Context}; +use glium::debug::DebugCallbackBehavior; +use std::ops::Deref; use std::os::raw::c_void; +use std::rc::Rc; + impl From for GliumSwapBuffersError { fn from(error: SwapBuffersError) -> Self { match error { @@ -13,19 +19,61 @@ impl From for GliumSwapBuffersError { } } -pub struct GliumGraphicBackend(T); - -pub trait IntoGlium: EGLGraphicsBackend + Sized { - fn into_glium(self) -> GliumGraphicBackend; +/// Wrapper to expose `glium` compatibility +pub struct GliumGraphicsBackend { + context: Rc, + backend: Rc>, } -impl IntoGlium for T { - fn into_glium(self) -> GliumGraphicBackend { - GliumGraphicBackend(self) +struct InternalBackend(T); + +impl GliumGraphicsBackend { + fn new(backend: T) -> GliumGraphicsBackend { + let internal = Rc::new(InternalBackend(backend)); + + GliumGraphicsBackend { + // cannot fail + context: unsafe { + Context::new::<_, ()>(internal.clone(), false, DebugCallbackBehavior::default()).unwrap() + }, + backend: internal, + } + } + + /// Start drawing on the backbuffer. + /// + /// This function returns a `Frame`, which can be used to draw on it. When the `Frame` is + /// destroyed, the buffers are swapped. + /// + /// Note that destroying a `Frame` is immediate, even if vsync is enabled. + #[inline] + pub fn draw(&self) -> Frame { + Frame::new(self.context.clone(), + self.backend.get_framebuffer_dimensions()) } } -unsafe impl Backend for GliumGraphicBackend { +impl Deref for GliumGraphicsBackend { + type Target = Context; + + fn deref(&self) -> &Context { + &self.context + } +} + +/// Converter trait to expose `glium` compatibility for all `EGLGraphicsBackend`s +pub trait IntoGlium: EGLGraphicsBackend + Sized { + /// Wrap the given `EGLGraphicsBackend` to a `GliumGraphicBackend` + fn into_glium(self) -> GliumGraphicsBackend; +} + +impl IntoGlium for T { + fn into_glium(self) -> GliumGraphicsBackend { + GliumGraphicsBackend::new(self) + } +} + +unsafe impl Backend for InternalBackend { fn swap_buffers(&self) -> Result<(), GliumSwapBuffersError> { self.0.swap_buffers().map_err(Into::into) }