use alloc::sync::Weak;
use core::slice;
use super::{BufferObjectId, FramebufferId};
#[derive(Debug)]
pub struct DumbBufferRequest {
pub width: u32,
pub height: u32,
pub depth: u32,
pub bpp: u32,
}
#[derive(Debug)]
pub struct DumbBuffer {
pub(crate) ptr: *mut u8,
pub(crate) len: usize,
pub(crate) file: Weak<linux_io::File<crate::ioctl::DrmCardDevice>>,
pub(crate) width: u32,
pub(crate) height: u32,
pub(crate) bpp: u32,
pub(crate) pitch: u32,
pub(crate) fb_id: FramebufferId,
pub(crate) buffer_handle: BufferObjectId,
}
impl DumbBuffer {
pub fn buffer(&self) -> &[u8] {
unsafe { slice::from_raw_parts(self.ptr, self.len) }
}
pub fn buffer_mut(&mut self) -> &mut [u8] {
unsafe { slice::from_raw_parts_mut(self.ptr, self.len) }
}
pub fn width(&self) -> u32 {
self.width
}
pub fn height(&self) -> u32 {
self.height
}
pub fn pitch(&self) -> u32 {
self.pitch
}
pub fn bpp(&self) -> u32 {
self.bpp
}
pub fn framebuffer_id(&self) -> FramebufferId {
self.fb_id
}
pub fn pixel_idx(&self, x: u32, y: u32) -> Option<usize> {
if x >= self.width || y >= self.height {
return None;
}
Some((y as usize * self.pitch as usize) + (x as usize * (self.bpp / 8) as usize))
}
pub fn clear_to_zero(&mut self) {
unsafe { core::ptr::write_bytes(self.ptr, 0, self.len) }
}
}
impl Drop for DumbBuffer {
fn drop(&mut self) {
let _ = unsafe { linux_unsafe::munmap(self.ptr as *mut _, self.len) };
let Some(f) = self.file.upgrade() else {
return;
};
{
let mut fb_id = self.fb_id.0;
let _ = crate::drm_ioctl(f.as_ref(), crate::ioctl::DRM_IOCTL_MODE_RMFB, &mut fb_id);
}
{
let mut msg = crate::ioctl::DrmModeDestroyDumb::zeroed();
msg.handle = self.buffer_handle.0;
let _ = crate::drm_ioctl(
f.as_ref(),
crate::ioctl::DRM_IOCTL_MODE_DESTROY_DUMB,
&mut msg,
);
}
}
}