use ffi;
use result::*;
use control;
use buffer;
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
pub struct DumbBuffer {
size: (u32, u32),
length: usize,
format: buffer::PixelFormat,
pitch: u32,
handle: buffer::Id,
}
pub struct DumbMapping<'a> {
_phantom: ::std::marker::PhantomData<&'a ()>,
map: &'a mut [u8],
}
impl DumbBuffer {
pub fn create_from_device<T>(
device: &T,
size: (u32, u32),
format: buffer::PixelFormat,
) -> Result<Self>
where
T: control::Device,
{
let mut raw: ffi::drm_mode_create_dumb = Default::default();
raw.width = size.0;
raw.height = size.1;
raw.bpp = try!(
format
.bpp()
.ok_or(Error::from_kind(ErrorKind::UnsupportedPixelFormat))
) as u32;
unsafe {
try!(ffi::ioctl_mode_create_dumb(device.as_raw_fd(), &mut raw));
}
let dumb = Self {
size: (raw.width, raw.height),
length: raw.size as usize,
format: format,
pitch: raw.pitch,
handle: buffer::Id::from_raw(raw.handle),
};
Ok(dumb)
}
pub fn destroy<T>(self, device: &T) -> Result<()>
where
T: control::Device,
{
let mut raw: ffi::drm_mode_destroy_dumb = Default::default();
raw.handle = self.handle.as_raw();
unsafe {
try!(ffi::ioctl_mode_destroy_dumb(device.as_raw_fd(), &mut raw));
}
Ok(())
}
pub fn map<'a, T>(&'a mut self, device: &T) -> Result<DumbMapping<'a>>
where
T: control::Device,
{
let mut raw: ffi::drm_mode_map_dumb = Default::default();
raw.handle = self.handle.as_raw();
unsafe {
try!(ffi::ioctl_mode_map_dumb(device.as_raw_fd(), &mut raw));
}
let map = {
use nix::sys::mman;
let addr = ::std::ptr::null_mut();
let prot = mman::PROT_READ | mman::PROT_WRITE;
let flags = mman::MAP_SHARED;
let length = self.length;
let fd = device.as_raw_fd();
let offset = raw.offset as i64;
try!(mman::mmap(addr, length, prot, flags, fd, offset))
};
let mapping = DumbMapping {
_phantom: ::std::marker::PhantomData,
map: unsafe { ::std::slice::from_raw_parts_mut(map as *mut _, self.length) },
};
Ok(mapping)
}
}
impl<'a> AsMut<[u8]> for DumbMapping<'a> {
fn as_mut(&mut self) -> &mut [u8] {
self.map
}
}
impl<'a> Drop for DumbMapping<'a> {
fn drop(&mut self) {
use nix::sys::mman;
mman::munmap(self.map.as_mut_ptr() as *mut _, self.map.len()).expect("Unmap failed");
}
}
impl buffer::Buffer for DumbBuffer {
fn size(&self) -> (u32, u32) {
self.size
}
fn format(&self) -> buffer::PixelFormat {
self.format
}
fn pitch(&self) -> u32 {
self.pitch
}
fn handle(&self) -> buffer::Id {
self.handle
}
}