use std::sync::Arc;
use crate::GbmBuffer;
use crate::device::DeviceInner;
use crate::ffi::SurfacePtr;
pub(crate) struct SurfaceInner {
pub(crate) ptr: SurfacePtr,
pub(crate) device: Arc<DeviceInner>,
}
unsafe impl Send for SurfaceInner {}
unsafe impl Sync for SurfaceInner {}
impl Drop for SurfaceInner {
fn drop(&mut self) {
unsafe { (self.device.gbm.surface_destroy)(self.ptr) };
}
}
pub struct GbmSurface {
inner: Arc<SurfaceInner>,
}
impl std::fmt::Debug for GbmSurface {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("GbmSurface").finish_non_exhaustive()
}
}
impl GbmSurface {
pub(crate) fn adopt(ptr: SurfacePtr, device: Arc<DeviceInner>) -> Self {
Self {
inner: Arc::new(SurfaceInner { ptr, device }),
}
}
#[must_use]
pub fn has_free_buffers(&self) -> bool {
unsafe { (self.inner.device.gbm.surface_has_free_buffers)(self.inner.ptr) != 0 }
}
#[must_use]
pub unsafe fn lock_front_buffer(&self) -> Option<GbmBuffer> {
let ptr = unsafe { (self.inner.device.gbm.surface_lock_front_buffer)(self.inner.ptr) };
(!ptr.is_null()).then(|| GbmBuffer::locked(ptr, Arc::clone(&self.inner)))
}
#[must_use]
pub fn as_raw(&self) -> *mut std::ffi::c_void {
self.inner.ptr
}
}