diff --git a/src/buffer_object.rs b/src/buffer_object.rs index 610851f..7584b7e 100644 --- a/src/buffer_object.rs +++ b/src/buffer_object.rs @@ -1,6 +1,6 @@ #![allow(clippy::unnecessary_cast)] -use crate::{AsRaw, Device, DeviceDestroyedError, Format, Modifier, Ptr, WeakPtr}; +use crate::{AsRaw, Format, Modifier, Ptr}; #[cfg(feature = "drm-support")] use drm::buffer::{Buffer as DrmBuffer, Handle, PlanarBuffer as DrmPlanarBuffer}; @@ -16,8 +16,9 @@ use std::slice; /// A GBM buffer object pub struct BufferObject { + // Declare `ffi` first so it is dropped before `_device` pub(crate) ffi: Ptr, - pub(crate) _device: WeakPtr, + pub(crate) _device: Ptr, pub(crate) _userdata: PhantomData, } @@ -26,12 +27,12 @@ impl fmt::Debug for BufferObject { f.debug_struct("BufferObject") .field("ptr", &format_args!("{:p}", self.ffi)) .field("device", &format_args!("{:p}", &self._device)) - .field("width", &self.width().unwrap_or(0)) - .field("height", &self.height().unwrap_or(0)) + .field("width", &self.width()) + .field("height", &self.height()) .field("offsets", &self.offsets()) - .field("stride", &self.stride().unwrap_or(0)) - .field("format", &self.format().ok()) - .field("modifier", &self.modifier().ok()) + .field("stride", &self.stride()) + .field("format", &self.format()) + .field("modifier", &self.modifier()) .finish() } } @@ -183,62 +184,49 @@ unsafe extern "C" fn destroy(_: *mut ffi::gbm_bo, ptr: *mut ::libc:: impl BufferObject { /// Get the width of the buffer object - pub fn width(&self) -> Result { - self._device.upgrade().ok_or(DeviceDestroyedError)?; - Ok(unsafe { ffi::gbm_bo_get_width(*self.ffi) }) + pub fn width(&self) -> u32 { + unsafe { ffi::gbm_bo_get_width(*self.ffi) } } /// Get the height of the buffer object - pub fn height(&self) -> Result { - self._device.upgrade().ok_or(DeviceDestroyedError)?; - Ok(unsafe { ffi::gbm_bo_get_height(*self.ffi) }) + pub fn height(&self) -> u32 { + unsafe { ffi::gbm_bo_get_height(*self.ffi) } } /// Get the stride of the buffer object - pub fn stride(&self) -> Result { - self._device.upgrade().ok_or(DeviceDestroyedError)?; - Ok(unsafe { ffi::gbm_bo_get_stride(*self.ffi) }) + pub fn stride(&self) -> u32 { + unsafe { ffi::gbm_bo_get_stride(*self.ffi) } } /// Get the stride of the buffer object - pub fn stride_for_plane(&self, plane: i32) -> Result { - self._device.upgrade().ok_or(DeviceDestroyedError)?; - Ok(unsafe { ffi::gbm_bo_get_stride_for_plane(*self.ffi, plane) }) + pub fn stride_for_plane(&self, plane: i32) -> u32 { + unsafe { ffi::gbm_bo_get_stride_for_plane(*self.ffi, plane) } } /// Get the format of the buffer object - pub fn format(&self) -> Result { - self._device.upgrade().ok_or(DeviceDestroyedError)?; - Ok( - Format::try_from(unsafe { ffi::gbm_bo_get_format(*self.ffi) }) - .expect("libgbm returned invalid buffer format"), - ) + pub fn format(&self) -> Format { + Format::try_from(unsafe { ffi::gbm_bo_get_format(*self.ffi) }) + .expect("libgbm returned invalid buffer format") } /// Get the bits per pixel of the buffer object - pub fn bpp(&self) -> Result { - self._device.upgrade().ok_or(DeviceDestroyedError)?; - Ok(unsafe { ffi::gbm_bo_get_bpp(*self.ffi) }) + pub fn bpp(&self) -> u32 { + unsafe { ffi::gbm_bo_get_bpp(*self.ffi) } } /// Get the offset for a plane of the buffer object - pub fn offset(&self, plane: i32) -> Result { - self._device.upgrade().ok_or(DeviceDestroyedError)?; - Ok(unsafe { ffi::gbm_bo_get_offset(*self.ffi, plane) }) + pub fn offset(&self, plane: i32) -> u32 { + unsafe { ffi::gbm_bo_get_offset(*self.ffi, plane) } } /// Get the plane count of the buffer object - pub fn plane_count(&self) -> Result { - self._device.upgrade().ok_or(DeviceDestroyedError)?; - Ok(unsafe { ffi::gbm_bo_get_plane_count(*self.ffi) as u32 }) + pub fn plane_count(&self) -> u32 { + unsafe { ffi::gbm_bo_get_plane_count(*self.ffi) as u32 } } /// Get the modifier of the buffer object - pub fn modifier(&self) -> Result { - self._device.upgrade().ok_or(DeviceDestroyedError)?; - Ok(Modifier::from(unsafe { - ffi::gbm_bo_get_modifier(*self.ffi) - })) + pub fn modifier(&self) -> Modifier { + Modifier::from(unsafe { ffi::gbm_bo_get_modifier(*self.ffi) }) } /// Get a DMA-BUF file descriptor for the buffer object @@ -247,13 +235,12 @@ impl BufferObject { /// handle for the buffer object. Each call to [`Self::fd()`] returns a new /// file descriptor and the caller is responsible for closing the file /// descriptor. - pub fn fd(&self) -> Result { - self._device.upgrade().ok_or(DeviceDestroyedError)?; + pub fn fd(&self) -> Result { unsafe { let fd = ffi::gbm_bo_get_fd(*self.ffi); if fd == -1 { - return Err(InvalidFdError.into()); + return Err(InvalidFdError); } Ok(OwnedFd::from_raw_fd(fd)) @@ -261,18 +248,16 @@ impl BufferObject { } /// Get the file descriptor of the gbm device of this buffer object - pub fn device_fd(&self) -> Result { - let device_ptr = self._device.upgrade().ok_or(DeviceDestroyedError)?; - Ok(unsafe { BorrowedFd::borrow_raw(ffi::gbm_device_get_fd(*device_ptr)) }) + pub fn device_fd(&self) -> BorrowedFd { + unsafe { BorrowedFd::borrow_raw(ffi::gbm_device_get_fd(*self._device)) } } /// Get the handle of the buffer object /// /// This is stored in the platform generic union [`BufferObjectHandle`] type. However /// the format of this handle is platform specific. - pub fn handle(&self) -> Result { - self._device.upgrade().ok_or(DeviceDestroyedError)?; - Ok(unsafe { ffi::gbm_bo_get_handle(*self.ffi) }) + pub fn handle(&self) -> BufferObjectHandle { + unsafe { ffi::gbm_bo_get_handle(*self.ffi) } } /// Get a DMA-BUF file descriptor for a plane of the buffer object @@ -281,13 +266,12 @@ impl BufferObject { /// handle for a plane of the buffer object. Each call to [`Self::fd_for_plane()`] /// returns a new file descriptor and the caller is responsible for closing /// the file descriptor. - pub fn fd_for_plane(&self, plane: i32) -> Result { - self._device.upgrade().ok_or(DeviceDestroyedError)?; + pub fn fd_for_plane(&self, plane: i32) -> Result { unsafe { let fd = ffi::gbm_bo_get_fd_for_plane(*self.ffi, plane); if fd == -1 { - return Err(InvalidFdError.into()); + return Err(InvalidFdError); } Ok(OwnedFd::from_raw_fd(fd)) @@ -298,33 +282,18 @@ impl BufferObject { /// /// This is stored in the platform generic union [`BufferObjectHandle`] type. However /// the format of this handle is platform specific. - pub fn handle_for_plane(&self, plane: i32) -> Result { - self._device.upgrade().ok_or(DeviceDestroyedError)?; - Ok(unsafe { ffi::gbm_bo_get_handle_for_plane(*self.ffi, plane) }) + pub fn handle_for_plane(&self, plane: i32) -> BufferObjectHandle { + unsafe { ffi::gbm_bo_get_handle_for_plane(*self.ffi, plane) } } /// Map a region of a GBM buffer object for cpu access /// /// This function maps a region of a GBM bo for cpu read access. - pub fn map<'a, D, F, S>( - &'a self, - device: &Device, - x: u32, - y: u32, - width: u32, - height: u32, - f: F, - ) -> Result, WrongDeviceError> + pub fn map<'a, D, F, S>(&'a self, x: u32, y: u32, width: u32, height: u32, f: F) -> IoResult where D: AsFd + 'static, F: FnOnce(&MappedBufferObject<'a, T>) -> S, { - let device_ref = self._device.upgrade().ok_or(WrongDeviceError)?; - if *device_ref != device.as_raw_mut() { - // not matching - return Err(WrongDeviceError); - } - unsafe { let mut data: *mut ::libc::c_void = ptr::null_mut(); let mut stride = 0; @@ -340,9 +309,9 @@ impl BufferObject { ); if ptr.is_null() { - Ok(Err(IoError::last_os_error())) + Err(IoError::last_os_error()) } else { - Ok(Ok(f(&MappedBufferObject { + Ok(f(&MappedBufferObject { bo: BORef::Ref(self), buffer: slice::from_raw_parts_mut(ptr as *mut _, (height * stride) as usize), data, @@ -351,7 +320,7 @@ impl BufferObject { width, x, y, - }))) + })) } } } @@ -361,23 +330,16 @@ impl BufferObject { /// This function maps a region of a GBM bo for cpu read/write access. pub fn map_mut<'a, D, F, S>( &'a mut self, - device: &Device, x: u32, y: u32, width: u32, height: u32, f: F, - ) -> Result, WrongDeviceError> + ) -> IoResult where D: AsFd + 'static, F: FnOnce(&mut MappedBufferObject<'a, T>) -> S, { - let device_ref = self._device.upgrade().ok_or(WrongDeviceError)?; - if *device_ref != device.as_raw_mut() { - // not matching - return Err(WrongDeviceError); - } - unsafe { let mut data: *mut ::libc::c_void = ptr::null_mut(); let mut stride = 0; @@ -393,9 +355,9 @@ impl BufferObject { ); if ptr.is_null() { - Ok(Err(IoError::last_os_error())) + Err(IoError::last_os_error()) } else { - Ok(Ok(f(&mut MappedBufferObject { + Ok(f(&mut MappedBufferObject { bo: BORef::Mut(self), buffer: slice::from_raw_parts_mut(ptr as *mut _, (height * stride) as usize), data, @@ -404,7 +366,7 @@ impl BufferObject { width, x, y, - }))) + })) } } } @@ -416,22 +378,20 @@ impl BufferObject { /// data is copied directly into the object and it's the responsibility /// of the caller to make sure the data represents valid pixel data, /// according to the width, height, stride and format of the buffer object. - pub fn write(&mut self, buffer: &[u8]) -> Result, DeviceDestroyedError> { - self._device.upgrade().ok_or(DeviceDestroyedError)?; + pub fn write(&mut self, buffer: &[u8]) -> IoResult<()> { let result = unsafe { ffi::gbm_bo_write(*self.ffi, buffer.as_ptr() as *const _, buffer.len() as _) }; if result != 0 { - Ok(Err(IoError::last_os_error())) + Err(IoError::last_os_error()) } else { - Ok(Ok(())) + Ok(()) } } /// Sets the userdata of the buffer object. /// /// If previously userdata was set, it is returned. - pub fn set_userdata(&mut self, userdata: T) -> Result, DeviceDestroyedError> { - self._device.upgrade().ok_or(DeviceDestroyedError)?; + pub fn set_userdata(&mut self, userdata: T) -> Option { let old = self.take_userdata(); let boxed = Box::new(userdata); @@ -447,57 +407,52 @@ impl BufferObject { } /// Clears the set userdata of the buffer object. - pub fn clear_userdata(&mut self) -> Result<(), DeviceDestroyedError> { - self._device.upgrade().ok_or(DeviceDestroyedError)?; + pub fn clear_userdata(&mut self) { let _ = self.take_userdata(); - Ok(()) } /// Returns a reference to set userdata, if any. - pub fn userdata(&self) -> Result, DeviceDestroyedError> { - self._device.upgrade().ok_or(DeviceDestroyedError)?; + pub fn userdata(&self) -> Option<&T> { let raw = unsafe { ffi::gbm_bo_get_user_data(*self.ffi) }; if raw.is_null() { - Ok(None) + None } else { - unsafe { Ok(Some(&*(raw as *mut T))) } + unsafe { Some(&*(raw as *mut T)) } } } /// Returns a mutable reference to set userdata, if any. - pub fn userdata_mut(&mut self) -> Result, DeviceDestroyedError> { - self._device.upgrade().ok_or(DeviceDestroyedError)?; + pub fn userdata_mut(&mut self) -> Option<&mut T> { let raw = unsafe { ffi::gbm_bo_get_user_data(*self.ffi) }; if raw.is_null() { - Ok(None) + None } else { - unsafe { Ok(Some(&mut *(raw as *mut T))) } + unsafe { Some(&mut *(raw as *mut T)) } } } /// Takes ownership of previously set userdata, if any. /// /// This removes the userdata from the buffer object. - pub fn take_userdata(&mut self) -> Result, DeviceDestroyedError> { - self._device.upgrade().ok_or(DeviceDestroyedError)?; + pub fn take_userdata(&mut self) -> Option { let raw = unsafe { ffi::gbm_bo_get_user_data(*self.ffi) }; if raw.is_null() { - Ok(None) + None } else { unsafe { let boxed = Box::from_raw(raw as *mut T); ffi::gbm_bo_set_user_data(*self.ffi, ptr::null_mut(), None); - Ok(Some(*boxed)) + Some(*boxed) } } } pub(crate) unsafe fn new( ffi: *mut ffi::gbm_bo, - device: WeakPtr, + device: Ptr, ) -> BufferObject { BufferObject { ffi: Ptr::::new(ffi, |ptr| ffi::gbm_bo_destroy(ptr)), @@ -507,23 +462,21 @@ impl BufferObject { } fn offsets(&self) -> [u32; 4] { - let num = self - .plane_count() - .expect("GbmDevice does not exist anymore"); + let num = self.plane_count(); [ - BufferObject::::offset(self, 0).unwrap(), + BufferObject::::offset(self, 0), if num > 1 { - BufferObject::::offset(self, 1).unwrap() + BufferObject::::offset(self, 1) } else { 0 }, if num > 2 { - BufferObject::::offset(self, 2).unwrap() + BufferObject::::offset(self, 2) } else { 0 }, if num > 3 { - BufferObject::::offset(self, 3).unwrap() + BufferObject::::offset(self, 3) } else { 0 }, @@ -540,64 +493,50 @@ impl AsRaw for BufferObject { #[cfg(feature = "drm-support")] impl DrmBuffer for BufferObject { fn size(&self) -> (u32, u32) { - ( - self.width().expect("GbmDevice does not exist anymore"), - self.height().expect("GbmDevice does not exist anymore"), - ) + (self.width(), self.height()) } fn format(&self) -> Format { - BufferObject::::format(self).expect("GbmDevice does not exist anymore") + BufferObject::::format(self) } fn pitch(&self) -> u32 { - self.stride().expect("GbmDevice does not exist anymore") + self.stride() } fn handle(&self) -> Handle { use std::num::NonZeroU32; - unsafe { - Handle::from(NonZeroU32::new_unchecked( - self.handle() - .expect("GbmDevice does not exist anymore") - .u32_, - )) - } + unsafe { Handle::from(NonZeroU32::new_unchecked(self.handle().u32_)) } } } #[cfg(feature = "drm-support")] impl DrmPlanarBuffer for BufferObject { fn size(&self) -> (u32, u32) { - ( - self.width().expect("GbmDevice does not exist anymore"), - self.height().expect("GbmDevice does not exist anymore"), - ) + (self.width(), self.height()) } fn format(&self) -> Format { - BufferObject::::format(self).expect("GbmDevice does not exist anymore") + BufferObject::::format(self) } fn modifier(&self) -> Option { - Some(BufferObject::::modifier(self).expect("GbmDevice does not exist anymore")) + Some(BufferObject::::modifier(self)) } fn pitches(&self) -> [u32; 4] { - let num = self - .plane_count() - .expect("GbmDevice does not exist anymore"); + let num = self.plane_count(); [ - BufferObject::::stride_for_plane(self, 0).unwrap(), + BufferObject::::stride_for_plane(self, 0), if num > 1 { - BufferObject::::stride_for_plane(self, 1).unwrap() + BufferObject::::stride_for_plane(self, 1) } else { 0 }, if num > 2 { - BufferObject::::stride_for_plane(self, 2).unwrap() + BufferObject::::stride_for_plane(self, 2) } else { 0 }, if num > 3 { - BufferObject::::stride_for_plane(self, 3).unwrap() + BufferObject::::stride_for_plane(self, 3) } else { 0 }, @@ -605,19 +544,17 @@ impl DrmPlanarBuffer for BufferObject { } fn handles(&self) -> [Option; 4] { use std::num::NonZeroU32; - let num = self - .plane_count() - .expect("GbmDevice does not exist anymore"); + let num = self.plane_count(); [ Some(unsafe { Handle::from(NonZeroU32::new_unchecked( - BufferObject::::handle_for_plane(self, 0).unwrap().u32_, + BufferObject::::handle_for_plane(self, 0).u32_, )) }), if num > 1 { Some(unsafe { Handle::from(NonZeroU32::new_unchecked( - BufferObject::::handle_for_plane(self, 1).unwrap().u32_, + BufferObject::::handle_for_plane(self, 1).u32_, )) }) } else { @@ -626,7 +563,7 @@ impl DrmPlanarBuffer for BufferObject { if num > 2 { Some(unsafe { Handle::from(NonZeroU32::new_unchecked( - BufferObject::::handle_for_plane(self, 2).unwrap().u32_, + BufferObject::::handle_for_plane(self, 2).u32_, )) }) } else { @@ -635,7 +572,7 @@ impl DrmPlanarBuffer for BufferObject { if num > 3 { Some(unsafe { Handle::from(NonZeroU32::new_unchecked( - BufferObject::::handle_for_plane(self, 3).unwrap().u32_, + BufferObject::::handle_for_plane(self, 3).u32_, )) }) } else { @@ -648,21 +585,6 @@ impl DrmPlanarBuffer for BufferObject { } } -#[derive(Debug, Clone, Copy, PartialEq, Eq)] -/// Thrown when the GBM device does not belong to the buffer object -pub struct WrongDeviceError; - -impl fmt::Display for WrongDeviceError { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!( - f, - "The gbm device specified is not the one this buffer object belongs to" - ) - } -} - -impl error::Error for WrongDeviceError {} - /// Thrown when the fd is invalid #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct InvalidFdError; @@ -674,42 +596,3 @@ impl fmt::Display for InvalidFdError { } impl error::Error for InvalidFdError {} - -/// Thrown when an error occurs during getting a bo fd -#[derive(Debug, Clone, Copy, PartialEq, Eq)] -pub enum FdError { - /// The underlying device has been destroyed - DeviceDestroyed(DeviceDestroyedError), - /// The operation returned an invalid fd - InvalidFd(InvalidFdError), -} - -impl From for FdError { - fn from(err: DeviceDestroyedError) -> Self { - FdError::DeviceDestroyed(err) - } -} - -impl From for FdError { - fn from(err: InvalidFdError) -> Self { - FdError::InvalidFd(err) - } -} - -impl fmt::Display for FdError { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - match self { - FdError::DeviceDestroyed(err) => err.fmt(f), - FdError::InvalidFd(err) => err.fmt(f), - } - } -} - -impl error::Error for FdError { - fn source(&self) -> Option<&(dyn error::Error + 'static)> { - match self { - FdError::DeviceDestroyed(err) => Some(err), - FdError::InvalidFd(err) => Some(err), - } - } -} diff --git a/src/device.rs b/src/device.rs index 9399ed9..e105e4e 100644 --- a/src/device.rs +++ b/src/device.rs @@ -2,7 +2,6 @@ use crate::{AsRaw, BufferObject, BufferObjectFlags, Format, Modifier, Ptr, Surfa use std::os::unix::io::{AsFd, AsRawFd, BorrowedFd}; -use std::error; use std::ffi::CStr; use std::fmt; use std::io::{Error as IoError, Result as IoResult}; @@ -134,7 +133,7 @@ impl Device { if ptr.is_null() { Err(IoError::last_os_error()) } else { - Ok(unsafe { Surface::new(ptr, self.ffi.downgrade()) }) + Ok(unsafe { Surface::new(ptr, self.ffi.clone()) }) } } @@ -160,7 +159,7 @@ impl Device { if ptr.is_null() { Err(IoError::last_os_error()) } else { - Ok(unsafe { Surface::new(ptr, self.ffi.downgrade()) }) + Ok(unsafe { Surface::new(ptr, self.ffi.clone()) }) } } @@ -188,7 +187,7 @@ impl Device { if ptr.is_null() { Err(IoError::last_os_error()) } else { - Ok(unsafe { Surface::new(ptr, self.ffi.downgrade()) }) + Ok(unsafe { Surface::new(ptr, self.ffi.clone()) }) } } @@ -205,7 +204,7 @@ impl Device { if ptr.is_null() { Err(IoError::last_os_error()) } else { - Ok(unsafe { BufferObject::new(ptr, self.ffi.downgrade()) }) + Ok(unsafe { BufferObject::new(ptr, self.ffi.clone()) }) } } @@ -231,7 +230,7 @@ impl Device { if ptr.is_null() { Err(IoError::last_os_error()) } else { - Ok(unsafe { BufferObject::new(ptr, self.ffi.downgrade()) }) + Ok(unsafe { BufferObject::new(ptr, self.ffi.clone()) }) } } @@ -259,7 +258,7 @@ impl Device { if ptr.is_null() { Err(IoError::last_os_error()) } else { - Ok(unsafe { BufferObject::new(ptr, self.ffi.downgrade()) }) + Ok(unsafe { BufferObject::new(ptr, self.ffi.clone()) }) } } @@ -290,7 +289,7 @@ impl Device { if ptr.is_null() { Err(IoError::last_os_error()) } else { - Ok(unsafe { BufferObject::new(ptr, self.ffi.downgrade()) }) + Ok(unsafe { BufferObject::new(ptr, self.ffi.clone()) }) } } @@ -322,7 +321,7 @@ impl Device { if ptr.is_null() { Err(IoError::last_os_error()) } else { - Ok(BufferObject::new(ptr, self.ffi.downgrade())) + Ok(BufferObject::new(ptr, self.ffi.clone())) } } @@ -362,7 +361,7 @@ impl Device { if ptr.is_null() { Err(IoError::last_os_error()) } else { - Ok(unsafe { BufferObject::new(ptr, self.ffi.downgrade()) }) + Ok(unsafe { BufferObject::new(ptr, self.ffi.clone()) }) } } @@ -410,7 +409,7 @@ impl Device { if ptr.is_null() { Err(IoError::last_os_error()) } else { - Ok(unsafe { BufferObject::new(ptr, self.ffi.downgrade()) }) + Ok(unsafe { BufferObject::new(ptr, self.ffi.clone()) }) } } } @@ -420,19 +419,3 @@ impl DrmDevice for Device {} #[cfg(feature = "drm-support")] impl DrmControlDevice for Device {} - -#[derive(Debug, Clone, Copy, PartialEq, Eq)] -/// Thrown when the underlying GBM device was already destroyed -pub struct DeviceDestroyedError; - -impl fmt::Display for DeviceDestroyedError { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "The underlying GBM device was already destroyed") - } -} - -impl error::Error for DeviceDestroyedError { - fn cause(&self) -> Option<&dyn error::Error> { - None - } -} diff --git a/src/lib.rs b/src/lib.rs index 968d3f4..0565126 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -113,7 +113,7 @@ pub use self::surface::*; pub use drm_fourcc::{DrmFourcc as Format, DrmModifier as Modifier}; use std::fmt; -use std::sync::{Arc, Weak}; +use std::sync::Arc; /// Trait for types that allow to obtain the underlying raw libinput pointer. pub trait AsRaw { @@ -146,10 +146,6 @@ impl Ptr { fn new(ptr: *mut T, destructor: F) -> Ptr { Ptr(Arc::new(PtrDrop(ptr, Some(Box::new(destructor))))) } - - fn downgrade(&self) -> WeakPtr { - WeakPtr(Arc::downgrade(&self.0)) - } } impl std::ops::Deref for Ptr { @@ -166,27 +162,6 @@ impl fmt::Pointer for Ptr { } } -#[derive(Clone)] -pub(crate) struct WeakPtr(Weak>); - -impl WeakPtr { - fn upgrade(&self) -> Option> { - self.0.upgrade().map(Ptr) - } -} - -impl fmt::Pointer for WeakPtr { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> { - match self.upgrade() { - Some(x) => fmt::Pointer::fmt(&x, f), - None => fmt::Pointer::fmt(&std::ptr::null::(), f), - } - } -} - -unsafe impl Send for WeakPtr where Ptr: Send {} -unsafe impl Sync for WeakPtr where Ptr: Sync {} - #[cfg(test)] mod test { use std::os::unix::io::OwnedFd; diff --git a/src/surface.rs b/src/surface.rs index d420cc2..1171f2d 100644 --- a/src/surface.rs +++ b/src/surface.rs @@ -1,12 +1,13 @@ -use crate::{AsRaw, BufferObject, DeviceDestroyedError, Ptr, WeakPtr}; +use crate::{AsRaw, BufferObject, Ptr}; use std::error; use std::fmt; use std::marker::PhantomData; /// A GBM rendering surface pub struct Surface { + // Declare `ffi` first so it is dropped before `_device` ffi: Ptr, - _device: WeakPtr, + _device: Ptr, _bo_userdata: PhantomData, } @@ -21,30 +22,15 @@ impl fmt::Debug for Surface { /// Errors that may happen when locking the front buffer #[derive(Debug, Clone, Copy, PartialEq, Eq)] -pub enum FrontBufferError { - /// An unknown error happened - Unknown, - /// Device was already released - Destroyed(DeviceDestroyedError), -} +pub struct FrontBufferError; impl fmt::Display for FrontBufferError { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - match *self { - FrontBufferError::Unknown => write!(f, "Unknown error"), - FrontBufferError::Destroyed(ref err) => write!(f, "Buffer was destroyed: {}", err), - } + write!(f, "Unknown error") } } -impl error::Error for FrontBufferError { - fn cause(&self) -> Option<&dyn error::Error> { - match *self { - FrontBufferError::Destroyed(ref err) => Some(err), - _ => None, - } - } -} +impl error::Error for FrontBufferError {} impl Surface { /// Return whether or not a surface has free (non-locked) buffers @@ -55,12 +41,7 @@ impl Surface { /// [have been locked](Self::lock_front_buffer()), /// the application must check for a free buffer before rendering. pub fn has_free_buffers(&self) -> bool { - let device = self._device.upgrade(); - if device.is_some() { - unsafe { ffi::gbm_surface_has_free_buffers(*self.ffi) != 0 } - } else { - false - } + unsafe { ffi::gbm_surface_has_free_buffers(*self.ffi) != 0 } } /// Lock the surface's current front buffer @@ -76,32 +57,25 @@ impl Surface { /// on the surface or two or more times after `eglSwapBuffers` is an /// error and may cause undefined behavior. pub unsafe fn lock_front_buffer(&self) -> Result, FrontBufferError> { - let device = self._device.upgrade(); - if device.is_some() { - let buffer_ptr = ffi::gbm_surface_lock_front_buffer(*self.ffi); - if !buffer_ptr.is_null() { - let surface_ptr = self.ffi.downgrade(); - let buffer = BufferObject { - ffi: Ptr::new(buffer_ptr, move |ptr| { - if let Some(surface) = surface_ptr.upgrade() { - ffi::gbm_surface_release_buffer(*surface, ptr); - } - }), - _device: self._device.clone(), - _userdata: std::marker::PhantomData, - }; - Ok(buffer) - } else { - Err(FrontBufferError::Unknown) - } + let buffer_ptr = ffi::gbm_surface_lock_front_buffer(*self.ffi); + if !buffer_ptr.is_null() { + let surface_ptr = self.ffi.clone(); + let buffer = BufferObject { + ffi: Ptr::new(buffer_ptr, move |ptr| { + ffi::gbm_surface_release_buffer(*surface_ptr, ptr); + }), + _device: self._device.clone(), + _userdata: std::marker::PhantomData, + }; + Ok(buffer) } else { - Err(FrontBufferError::Destroyed(DeviceDestroyedError)) + Err(FrontBufferError) } } pub(crate) unsafe fn new( ffi: *mut ffi::gbm_surface, - device: WeakPtr, + device: Ptr, ) -> Surface { Surface { ffi: Ptr::new(ffi, |ptr| ffi::gbm_surface_destroy(ptr)),