diff options
Diffstat (limited to 'src/api/osmesa')
-rw-r--r-- | src/api/osmesa/mod.rs | 75 |
1 files changed, 75 insertions, 0 deletions
diff --git a/src/api/osmesa/mod.rs b/src/api/osmesa/mod.rs new file mode 100644 index 0000000..585ce72 --- /dev/null +++ b/src/api/osmesa/mod.rs @@ -0,0 +1,75 @@ +#![cfg(all(any(target_os = "linux", target_os = "freebsd"), feature="headless"))] + +extern crate osmesa_sys; + +use BuilderAttribs; +use CreationError; +use CreationError::OsError; +use libc; +use std::{mem, ptr}; +use std::ffi::CString; + +pub struct OsMesaContext { + context: osmesa_sys::OSMesaContext, + buffer: Vec<u32>, + width: u32, + height: u32, +} + +impl OsMesaContext { + pub fn new(builder: BuilderAttribs) -> Result<OsMesaContext, CreationError> { + let dimensions = builder.dimensions.unwrap(); + + Ok(OsMesaContext { + width: dimensions.0, + height: dimensions.1, + buffer: ::std::iter::repeat(unsafe { mem::uninitialized() }) + .take((dimensions.0 * dimensions.1) as usize).collect(), + context: unsafe { + let ctxt = osmesa_sys::OSMesaCreateContext(0x1908, ptr::null_mut()); + if ctxt.is_null() { + return Err(OsError("OSMesaCreateContext failed".to_string())); + } + ctxt + } + }) + } + + pub unsafe fn make_current(&self) { + let ret = osmesa_sys::OSMesaMakeCurrent(self.context, + self.buffer.as_ptr() as *mut libc::c_void, + 0x1401, self.width as libc::c_int, self.height as libc::c_int); + + if ret == 0 { + panic!("OSMesaMakeCurrent failed") + } + } + + pub fn is_current(&self) -> bool { + unsafe { osmesa_sys::OSMesaGetCurrentContext() == self.context } + } + + pub fn get_proc_address(&self, addr: &str) -> *const () { + unsafe { + let c_str = CString::new(addr.as_bytes().to_vec()).unwrap(); + mem::transmute(osmesa_sys::OSMesaGetProcAddress(mem::transmute(c_str.as_ptr()))) + } + } + + /// See the docs in the crate root file. + pub fn get_api(&self) -> ::Api { + ::Api::OpenGl + } + + pub fn set_window_resize_callback(&mut self, _: Option<fn(u32, u32)>) { + } +} + +impl Drop for OsMesaContext { + fn drop(&mut self) { + unsafe { osmesa_sys::OSMesaDestroyContext(self.context) } + } +} + +unsafe impl Send for OsMesaContext {} +unsafe impl Sync for OsMesaContext {} |