linux_drm/modeset/
buffer.rs1use alloc::sync::Weak;
2use core::slice;
3
4use super::{BufferObjectId, FramebufferId};
5
6#[derive(Debug)]
7pub struct DumbBufferRequest {
8 pub width: u32,
9 pub height: u32,
10 pub depth: u32,
11 pub bpp: u32,
12}
13
14#[derive(Debug)]
15pub struct DumbBuffer {
16 pub(crate) ptr: *mut u8,
17 pub(crate) len: usize,
18 pub(crate) file: Weak<linux_io::File<crate::ioctl::DrmCardDevice>>,
19 pub(crate) width: u32,
20 pub(crate) height: u32,
21 pub(crate) bpp: u32,
22 pub(crate) pitch: u32,
23 pub(crate) fb_id: FramebufferId,
24 pub(crate) buffer_handle: BufferObjectId,
25}
26
27impl DumbBuffer {
28 pub fn buffer(&self) -> &[u8] {
29 unsafe { slice::from_raw_parts(self.ptr, self.len) }
30 }
31
32 pub fn buffer_mut(&mut self) -> &mut [u8] {
33 unsafe { slice::from_raw_parts_mut(self.ptr, self.len) }
34 }
35
36 pub fn width(&self) -> u32 {
37 self.width
38 }
39
40 pub fn height(&self) -> u32 {
41 self.height
42 }
43
44 pub fn pitch(&self) -> u32 {
45 self.pitch
46 }
47
48 pub fn bpp(&self) -> u32 {
49 self.bpp
50 }
51
52 pub fn framebuffer_id(&self) -> FramebufferId {
53 self.fb_id
54 }
55
56 pub fn pixel_idx(&self, x: u32, y: u32) -> Option<usize> {
57 if x >= self.width || y >= self.height {
58 return None;
59 }
60 Some((y as usize * self.pitch as usize) + (x as usize * (self.bpp / 8) as usize))
61 }
62
63 pub fn clear_to_zero(&mut self) {
64 unsafe { core::ptr::write_bytes(self.ptr, 0, self.len) }
65 }
66}
67
68impl Drop for DumbBuffer {
69 fn drop(&mut self) {
70 let _ = unsafe { linux_unsafe::munmap(self.ptr as *mut _, self.len) };
71
72 let Some(f) = self.file.upgrade() else {
76 return;
77 };
78 {
79 let mut fb_id = self.fb_id.0;
80 let _ = crate::drm_ioctl(f.as_ref(), crate::ioctl::DRM_IOCTL_MODE_RMFB, &mut fb_id);
81 }
82 {
83 let mut msg = crate::ioctl::DrmModeDestroyDumb::zeroed();
84 msg.handle = self.buffer_handle.0;
85 let _ = crate::drm_ioctl(
86 f.as_ref(),
87 crate::ioctl::DRM_IOCTL_MODE_DESTROY_DUMB,
88 &mut msg,
89 );
90 }
91 }
92}