#[cfg(feature = "glfw")]
use std::cell::{RefCell, Cell, Ref, RefMut};
use std::rc::Rc;
use std::os::raw::c_void;
use std::ops::Deref;
use glfw;
use glfw::Context;
use glium;
use glium::Frame;
use glium::backend::{Backend, Facade};
use errors::ProcessingErr;
pub struct GLFWBackend(Rc<RefCell<glfw::Window>>);
#[derive(Clone)]
pub struct Display {
context: Rc<glium::backend::Context>,
gl_window: Rc<RefCell<glfw::Window>>,
last_framebuffer_dimensions: Cell<(u32, u32)>,
}
impl Display {
pub fn new(gl_window: glfw::Window) -> Result<Self, ProcessingErr> {
let gl_window = Rc::new(RefCell::new(gl_window));
let glfw_backend = GLFWBackend(gl_window.clone());
let framebuffer_dimensions = glfw_backend.get_framebuffer_dimensions();
let context =
unsafe { glium::backend::Context::new(glfw_backend, true, Default::default()) };
Ok(Display {
gl_window: gl_window,
context: context.map_err(|e| ProcessingErr::ContextNoCreate(e))?,
last_framebuffer_dimensions: Cell::new(framebuffer_dimensions),
})
}
#[inline]
pub fn gl_window(&self) -> Ref<glfw::Window> {
self.gl_window.borrow()
}
#[inline]
pub fn gl_window_mut(&self) -> RefMut<glfw::Window> {
self.gl_window.borrow_mut()
}
#[inline]
pub fn draw(&self) -> Frame {
let (w, h) = self.context.get_framebuffer_dimensions();
if self.last_framebuffer_dimensions.get() != (w, h) {
self.last_framebuffer_dimensions.set((w, h));
self.gl_window.borrow_mut().set_size(w as i32, h as i32);
}
Frame::new(self.context.clone(), (w, h))
}
}
impl Deref for Display {
type Target = glium::backend::Context;
#[inline]
fn deref(&self) -> &glium::backend::Context {
&self.context
}
}
impl Facade for Display {
#[inline]
fn get_context(&self) -> &Rc<glium::backend::Context> {
&self.context
}
}
impl Deref for GLFWBackend {
type Target = Rc<RefCell<glfw::Window>>;
#[inline]
fn deref(&self) -> &Rc<RefCell<glfw::Window>> {
&self.0
}
}
unsafe impl glium::backend::Backend for GLFWBackend {
fn swap_buffers(&self) -> Result<(), glium::SwapBuffersError> {
Ok(self.0.borrow_mut().swap_buffers())
}
unsafe fn get_proc_address(&self, symbol: &str) -> *const c_void {
self.0.borrow_mut().get_proc_address(symbol) as *const _
}
fn get_framebuffer_dimensions(&self) -> (u32, u32) {
let (fbw, fbh) = self.0.borrow().get_framebuffer_size();
(fbw as u32, fbh as u32)
}
fn is_current(&self) -> bool {
self.0.borrow().is_current()
}
unsafe fn make_current(&self) {
self.0.borrow_mut().make_current();
}
}