1use crate::{AsRaw, BufferObject, Gbm, Ptr};
2use std::{error, fmt, marker::PhantomData, sync::Arc};
3
4pub struct Surface<T: 'static> {
6 ffi: Ptr<ffi::gbm_surface>,
8 _device: Ptr<ffi::gbm_device>,
9 _bo_userdata: PhantomData<T>,
10 gbm: Arc<Gbm>,
11}
12
13impl<T: 'static> fmt::Debug for Surface<T> {
14 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
15 f.debug_struct("Surface")
16 .field("ptr", &format_args!("{:p}", &self.ffi))
17 .field("device", &format_args!("{:p}", &self._device))
18 .finish()
19 }
20}
21
22#[derive(Debug, Clone, Copy, PartialEq, Eq)]
24pub struct FrontBufferError;
25
26impl fmt::Display for FrontBufferError {
27 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
28 write!(f, "Unknown error")
29 }
30}
31
32impl error::Error for FrontBufferError {}
33
34impl<T: 'static> Surface<T> {
35 pub fn has_free_buffers(&self) -> bool {
43 unsafe { self.gbm.gbm_surface_has_free_buffers(*self.ffi) != 0 }
44 }
45
46 pub unsafe fn lock_front_buffer(&self) -> Result<BufferObject<T>, FrontBufferError> {
59 let buffer_ptr = self.gbm.gbm_surface_lock_front_buffer(*self.ffi);
60 if !buffer_ptr.is_null() {
61 let surface_ptr = self.ffi.clone();
62 let gbm_ = self.gbm.clone();
63 let buffer = BufferObject {
64 ffi: Ptr::new(buffer_ptr, move |ptr| {
65 gbm_.gbm_surface_release_buffer(*surface_ptr, ptr);
66 }),
67 _device: self._device.clone(),
68 _userdata: std::marker::PhantomData,
69 gbm: self.gbm.clone(),
70 };
71 Ok(buffer)
72 } else {
73 Err(FrontBufferError)
74 }
75 }
76
77 pub(crate) unsafe fn new(
78 ffi: *mut ffi::gbm_surface,
79 device: Ptr<ffi::gbm_device>,
80 gbm: Arc<Gbm>,
81 ) -> Surface<T> {
82 let gbm_ = gbm.clone();
83 Surface {
84 ffi: Ptr::new(ffi, move |ptr| gbm_.gbm_surface_destroy(ptr)),
85 _device: device,
86 _bo_userdata: PhantomData,
87 gbm,
88 }
89 }
90}
91
92impl<T: 'static> AsRaw<ffi::gbm_surface> for Surface<T> {
93 fn as_raw(&self) -> *const ffi::gbm_surface {
94 *self.ffi
95 }
96}