diff --git a/src/control/dumbbuffer.rs b/src/control/dumbbuffer.rs index d0d0dd20..3d626703 100644 --- a/src/control/dumbbuffer.rs +++ b/src/control/dumbbuffer.rs @@ -4,106 +4,22 @@ //! Memory-supported, slow, but easy & cross-platform buffer implementation //! -use ffi; -use result::*; -use control; use buffer; #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] /// Slow, but generic `Buffer` implementation pub struct DumbBuffer { - size: (u32, u32), - length: usize, - format: buffer::PixelFormat, - pitch: u32, - handle: buffer::Id, + pub(crate) size: (u32, u32), + pub(crate) length: usize, + pub(crate) format: buffer::format::PixelFormat, + pub(crate) pitch: u32, + pub(crate) handle: buffer::Handle, } /// Mapping of a dumbbuffer pub struct DumbMapping<'a> { - _phantom: ::std::marker::PhantomData<&'a ()>, - map: &'a mut [u8], -} - -impl DumbBuffer { - /// Create a new dumb buffer with a given size and pixel format - pub fn create_from_device( - device: &T, - size: (u32, u32), - format: buffer::PixelFormat, - ) -> Result - 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) - } - - /// Free the memory resources of a dumb buffer - pub fn destroy(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(()) - } - - /// Map the buffer for access - pub fn map<'a, T>(&'a mut self, device: &T) -> Result> - 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::ProtFlags::PROT_READ | mman::ProtFlags::PROT_WRITE; - let flags = mman::MapFlags::MAP_SHARED; - let length = self.length; - let fd = device.as_raw_fd(); - let offset = raw.offset as i64; - unsafe { 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) - } + pub(crate) _phantom: core::marker::PhantomData<&'a ()>, + pub(crate) map: &'a mut [u8], } impl<'a> AsMut<[u8]> for DumbMapping<'a> { @@ -126,13 +42,13 @@ impl buffer::Buffer for DumbBuffer { fn size(&self) -> (u32, u32) { self.size } - fn format(&self) -> buffer::PixelFormat { + fn format(&self) -> buffer::format::PixelFormat { self.format } fn pitch(&self) -> u32 { self.pitch } - fn handle(&self) -> buffer::Id { + fn handle(&self) -> buffer::Handle { self.handle } } diff --git a/src/control/mod.rs b/src/control/mod.rs index b229fff5..0fb45d30 100644 --- a/src/control/mod.rs +++ b/src/control/mod.rs @@ -33,12 +33,14 @@ use drm_ffi::result::SystemError; pub mod connector; pub mod crtc; +pub mod dumbbuffer; pub mod encoder; pub mod framebuffer; pub mod plane; pub mod property; +use self::dumbbuffer::*; use buffer; use std::mem; @@ -443,6 +445,55 @@ pub trait Device: super::Device { let _info = drm_ffi::gem::close(self.as_raw_fd(), handle.into())?; Ok(()) } + + /// Create a new dumb buffer with a given size and pixel format + fn create_dumb_buffer( + &self, + size: (u32, u32), + format: buffer::format::PixelFormat, + ) -> Result { + let info = drm_ffi::mode::dumbbuffer::create(self.as_raw_fd(), size.0, size.1, format.bpp(), 0)?; + + let dumb = DumbBuffer { + size: (info.width, info.height), + length: info.size as usize, + format: format, + pitch: info.pitch, + handle: unsafe { mem::transmute(info.handle) }, + }; + + Ok(dumb) + } + + /// Free the memory resources of a dumb buffer + fn destroy_dumb_buffer(&self, buffer: DumbBuffer) -> Result<(), SystemError> { + let _info = drm_ffi::mode::dumbbuffer::destroy(self.as_raw_fd(), buffer.handle.into())?; + + Ok(()) + } + + /// Map the buffer for access + fn map_dumb_buffer<'a>(&self, buffer: &'a mut DumbBuffer) -> Result, SystemError> { + let info = drm_ffi::mode::dumbbuffer::map(self.as_raw_fd(), buffer.handle.into(), 0, 0)?; + + let map = { + use ::nix::sys::mman; + let addr = core::ptr::null_mut(); + let prot = mman::ProtFlags::PROT_READ | mman::ProtFlags::PROT_WRITE; + let flags = mman::MapFlags::MAP_SHARED; + let length = buffer.length; + let fd = self.as_raw_fd(); + let offset = info.offset as i64; + unsafe { 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 _, buffer.length) }, + }; + + Ok(mapping) + } } /// The set of [ResourceHandles](ResourceHandle.t.html) that a diff --git a/src/lib.rs b/src/lib.rs index 11f1fdf2..276b6b54 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -33,6 +33,8 @@ extern crate core; extern crate drm_ffi; +extern crate nix; + pub(crate) mod util; pub mod control;