Skip to content

Commit c8489f0

Browse files
committed
refactor: Store things more directly in BufferImpl
1 parent d4bd48c commit c8489f0

9 files changed

Lines changed: 405 additions & 357 deletions

File tree

src/backends/cg.rs

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -261,24 +261,32 @@ impl<D: HasDisplayHandle, W: HasWindowHandle> SurfaceInterface<D, W> for CGImpl<
261261
fn buffer_mut(&mut self) -> Result<BufferImpl<'_, D, W>, SoftBufferError> {
262262
Ok(BufferImpl {
263263
buffer: util::PixelBuffer(vec![0; self.width * self.height]),
264-
imp: self,
264+
width: self.width,
265+
height: self.height,
266+
color_space: &self.color_space,
267+
layer: &mut self.layer,
268+
_phantom: PhantomData,
265269
})
266270
}
267271
}
268272

269273
#[derive(Debug)]
270274
pub struct BufferImpl<'a, D, W> {
271-
imp: &'a mut CGImpl<D, W>,
275+
width: usize,
276+
height: usize,
277+
color_space: &'a CGColorSpace,
272278
buffer: util::PixelBuffer,
279+
layer: &'a mut SendCALayer,
280+
_phantom: PhantomData<(D, W)>,
273281
}
274282

275283
impl<D: HasDisplayHandle, W: HasWindowHandle> BufferInterface for BufferImpl<'_, D, W> {
276284
fn width(&self) -> NonZeroU32 {
277-
NonZeroU32::new(self.imp.width as u32).unwrap()
285+
NonZeroU32::new(self.width as u32).unwrap()
278286
}
279287

280288
fn height(&self) -> NonZeroU32 {
281-
NonZeroU32::new(self.imp.height as u32).unwrap()
289+
NonZeroU32::new(self.height as u32).unwrap()
282290
}
283291

284292
#[inline]
@@ -333,12 +341,12 @@ impl<D: HasDisplayHandle, W: HasWindowHandle> BufferInterface for BufferImpl<'_,
333341

334342
let image = unsafe {
335343
CGImage::new(
336-
self.imp.width,
337-
self.imp.height,
344+
self.width,
345+
self.height,
338346
8,
339347
32,
340-
self.imp.width * 4,
341-
Some(&self.imp.color_space),
348+
self.width * 4,
349+
Some(self.color_space),
342350
bitmap_info,
343351
Some(&data_provider),
344352
ptr::null(),
@@ -355,7 +363,7 @@ impl<D: HasDisplayHandle, W: HasWindowHandle> BufferInterface for BufferImpl<'_,
355363
CATransaction::setDisableActions(true);
356364

357365
// SAFETY: The contents is `CGImage`, which is a valid class for `contents`.
358-
unsafe { self.imp.layer.setContents(Some(image.as_ref())) };
366+
unsafe { self.layer.setContents(Some(image.as_ref())) };
359367

360368
CATransaction::commit();
361369
Ok(())

src/backends/kms.rs

Lines changed: 34 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -21,23 +21,28 @@ use std::sync::Arc;
2121
use crate::backend_interface::*;
2222
use crate::error::{InitError, SoftBufferError, SwResultExt};
2323

24-
#[derive(Debug)]
25-
pub(crate) struct KmsDisplayImpl<D: ?Sized> {
26-
/// The underlying raw device file descriptor.
27-
fd: BorrowedFd<'static>,
28-
29-
/// Holds a reference to the display.
30-
_display: D,
24+
#[derive(Debug, Clone)]
25+
struct DrmDevice<'a> {
26+
/// The underlying raw display file descriptor.
27+
fd: BorrowedFd<'a>,
3128
}
3229

33-
impl<D: ?Sized> AsFd for KmsDisplayImpl<D> {
30+
impl AsFd for DrmDevice<'_> {
3431
fn as_fd(&self) -> BorrowedFd<'_> {
3532
self.fd
3633
}
3734
}
3835

39-
impl<D: ?Sized> Device for KmsDisplayImpl<D> {}
40-
impl<D: ?Sized> CtrlDevice for KmsDisplayImpl<D> {}
36+
impl Device for DrmDevice<'_> {}
37+
impl CtrlDevice for DrmDevice<'_> {}
38+
39+
#[derive(Debug)]
40+
pub(crate) struct KmsDisplayImpl<D: ?Sized> {
41+
device: DrmDevice<'static>,
42+
43+
/// Holds a reference to the display.
44+
_display: D,
45+
}
4146

4247
impl<D: HasDisplayHandle + ?Sized> ContextInterface<D> for Arc<KmsDisplayImpl<D>> {
4348
fn new(display: D) -> Result<Self, InitError<D>>
@@ -55,7 +60,7 @@ impl<D: HasDisplayHandle + ?Sized> ContextInterface<D> for Arc<KmsDisplayImpl<D>
5560
let fd = unsafe { BorrowedFd::borrow_raw(drm.fd) };
5661

5762
Ok(Arc::new(KmsDisplayImpl {
58-
fd,
63+
device: DrmDevice { fd },
5964
_display: display,
6065
}))
6166
}
@@ -106,17 +111,16 @@ pub(crate) struct BufferImpl<'a, D: ?Sized, W: ?Sized> {
106111
/// The current size.
107112
size: (NonZeroU32, NonZeroU32),
108113

109-
/// The display implementation.
110-
display: &'a KmsDisplayImpl<D>,
114+
/// The device file descriptor.
115+
device: DrmDevice<'a>,
111116

112117
/// Age of the front buffer.
113118
front_age: &'a mut u8,
114119

115120
/// Age of the back buffer.
116121
back_age: &'a mut u8,
117122

118-
/// Window reference.
119-
_window: PhantomData<&'a mut W>,
123+
_phantom: PhantomData<(&'a D, &'a W)>,
120124
}
121125

122126
impl<D: ?Sized + fmt::Debug, W: ?Sized + fmt::Debug> fmt::Debug for BufferImpl<'_, D, W> {
@@ -148,6 +152,8 @@ impl<D: HasDisplayHandle + ?Sized, W: HasWindowHandle> SurfaceInterface<D, W> fo
148152

149153
/// Create a new KMS backend.
150154
fn new(window: W, display: &Arc<KmsDisplayImpl<D>>) -> Result<Self, InitError<W>> {
155+
let device = &display.device;
156+
151157
// Make sure that the window handle is valid.
152158
let RawWindowHandle::Drm(drm) = window.window_handle()?.as_raw() else {
153159
return Err(InitError::Unsupported(window));
@@ -156,10 +162,10 @@ impl<D: HasDisplayHandle + ?Sized, W: HasWindowHandle> SurfaceInterface<D, W> fo
156162
NonZeroU32::new(drm.plane).ok_or(SoftBufferError::IncompleteWindowHandle)?;
157163
let plane_handle = plane::Handle::from(plane_handle);
158164

159-
let plane_info = display
165+
let plane_info = device
160166
.get_plane(plane_handle)
161167
.swbuf_err("failed to get plane info")?;
162-
let handles = display
168+
let handles = device
163169
.resource_handles()
164170
.swbuf_err("failed to get resource handles")?;
165171

@@ -178,7 +184,7 @@ impl<D: HasDisplayHandle + ?Sized, W: HasWindowHandle> SurfaceInterface<D, W> fo
178184
};
179185

180186
// Get info about the CRTC.
181-
display
187+
device
182188
.get_crtc(handle)
183189
.swbuf_err("failed to get CRTC info")?
184190
};
@@ -187,7 +193,7 @@ impl<D: HasDisplayHandle + ?Sized, W: HasWindowHandle> SurfaceInterface<D, W> fo
187193
let encoders = handles
188194
.encoders
189195
.iter()
190-
.flat_map(|handle| display.get_encoder(*handle))
196+
.flat_map(|handle| device.get_encoder(*handle))
191197
.filter(|encoder| encoder.crtc() == Some(crtc.handle()))
192198
.map(|encoder| encoder.handle())
193199
.collect::<HashSet<_>>();
@@ -196,7 +202,7 @@ impl<D: HasDisplayHandle + ?Sized, W: HasWindowHandle> SurfaceInterface<D, W> fo
196202
let connectors = handles
197203
.connectors
198204
.iter()
199-
.flat_map(|handle| display.get_connector(*handle, false))
205+
.flat_map(|handle| device.get_connector(*handle, false))
200206
.filter(|connector| {
201207
connector
202208
.current_encoder()
@@ -268,6 +274,7 @@ impl<D: HasDisplayHandle + ?Sized, W: HasWindowHandle> SurfaceInterface<D, W> fo
268274

269275
let mapping = self
270276
.display
277+
.device
271278
.map_dumb_buffer(&mut front_buffer.db)
272279
.swbuf_err("failed to map dumb buffer")?;
273280

@@ -277,10 +284,10 @@ impl<D: HasDisplayHandle + ?Sized, W: HasWindowHandle> SurfaceInterface<D, W> fo
277284
first_is_front: &mut set.first_is_front,
278285
front_fb,
279286
crtc_handle: self.crtc.handle(),
280-
display: &self.display,
287+
device: self.display.device.clone(),
281288
front_age,
282289
back_age,
283-
_window: PhantomData,
290+
_phantom: PhantomData,
284291
})
285292
}
286293
}
@@ -289,6 +296,7 @@ impl<D: ?Sized, W: ?Sized> Drop for KmsImpl<D, W> {
289296
fn drop(&mut self) {
290297
// Map the CRTC to the information that was there before.
291298
self.display
299+
.device
292300
.set_crtc(
293301
self.crtc.handle(),
294302
self.crtc.framebuffer(),
@@ -351,7 +359,7 @@ impl<D: ?Sized, W: ?Sized> BufferInterface for BufferImpl<'_, D, W> {
351359
// TODO: It would be nice to not have to heap-allocate the above rectangles if we know that
352360
// this is going to fail. Low hanging fruit PR: add a flag that's set to false if this
353361
// returns `ENOSYS` and check that before allocating the above and running this.
354-
match self.display.dirty_framebuffer(self.front_fb, &rectangles) {
362+
match self.device.dirty_framebuffer(self.front_fb, &rectangles) {
355363
Ok(()) => {}
356364
Err(e) if e.raw_os_error() == Some(rustix::io::Errno::NOSYS.raw_os_error()) => {}
357365
Err(e) => {
@@ -364,7 +372,7 @@ impl<D: ?Sized, W: ?Sized> BufferInterface for BufferImpl<'_, D, W> {
364372

365373
// Swap the buffers.
366374
// TODO: Use atomic commits here!
367-
self.display
375+
self.device
368376
.page_flip(self.crtc_handle, self.front_fb, PageFlipFlags::EVENT, None)
369377
.swbuf_err("failed to page flip")?;
370378

@@ -400,9 +408,11 @@ impl SharedBuffer {
400408
height: NonZeroU32,
401409
) -> Result<Self, SoftBufferError> {
402410
let db = display
411+
.device
403412
.create_dumb_buffer((width.get(), height.get()), DrmFourcc::Xrgb8888, 32)
404413
.swbuf_err("failed to create dumb buffer")?;
405414
let fb = display
415+
.device
406416
.add_framebuffer(&db, 24, 32)
407417
.swbuf_err("failed to add framebuffer")?;
408418

0 commit comments

Comments
 (0)