From 3e41353783732b2b124609b2b8d96e37ac4e108c Mon Sep 17 00:00:00 2001 From: Marijn Suijten Date: Fri, 16 Jun 2023 19:46:31 +0200 Subject: [PATCH] BADHACK: Add `BufferImpl::stride()` getter for Android --- examples/winit.rs | 2 +- src/android.rs | 5 +++++ src/kms.rs | 20 ++++++++++++++++++++ src/lib.rs | 14 ++++++++++++++ src/wayland/mod.rs | 7 +++++++ src/x11.rs | 10 ++++++++++ 6 files changed, 57 insertions(+), 1 deletion(-) diff --git a/examples/winit.rs b/examples/winit.rs index b01eba3..0560bec 100644 --- a/examples/winit.rs +++ b/examples/winit.rs @@ -63,7 +63,7 @@ pub(crate) fn run(event_loop: EventLoop<()>) { let red = x % 255; let green = y % 255; let blue = (x * y) % 255; - let index = y as usize * width.get() as usize + x as usize; + let index = y as usize * buffer.stride() as usize + x as usize; buffer[index] = blue | (green << 8) | (red << 16); } } diff --git a/src/android.rs b/src/android.rs index 18e7c96..7a61ce8 100644 --- a/src/android.rs +++ b/src/android.rs @@ -130,6 +130,11 @@ impl<'a, D: HasDisplayHandle + ?Sized, W: HasWindowHandle> BufferImpl<'a, D, W> } } + #[inline] + pub fn stride(&self) -> u32 { + self.0.stride() as u32 + } + pub fn age(&self) -> u8 { todo!() } diff --git a/src/kms.rs b/src/kms.rs index b9d4724..7adeaa0 100644 --- a/src/kms.rs +++ b/src/kms.rs @@ -107,6 +107,9 @@ pub(crate) struct BufferImpl<'a, D: ?Sized, W: ?Sized> { /// The current size. size: (NonZeroU32, NonZeroU32), + /// The current stride/pitch (length of a single row of pixels) in bytes. + stride: NonZeroU32, + /// The display implementation. display: &'a KmsDisplayImpl, @@ -244,6 +247,7 @@ impl KmsImpl { .expect("Must set size of surface before calling `buffer_mut()`"); let size = set.size(); + let stride = set.pitch(); let [first_buffer, second_buffer] = &mut set.buffers; let (front_buffer, back_buffer) = if set.first_is_front { @@ -264,6 +268,7 @@ impl KmsImpl { Ok(BufferImpl { mapping, size, + stride, first_is_front: &mut set.first_is_front, front_fb, crtc_handle: self.crtc.handle(), @@ -304,6 +309,12 @@ impl BufferImpl<'_, D, W> { bytemuck::cast_slice_mut(self.mapping.as_mut()) } + #[inline] + pub fn stride(&self) -> u32 { + // TODO Return NonZeroU32? + self.stride.get() + } + #[inline] pub fn age(&self) -> u8 { *self.front_age @@ -403,6 +414,10 @@ impl SharedBuffer { .and_then(|width| NonZeroU32::new(height).map(|height| (width, height))) .expect("buffer size is zero") } + + pub(crate) fn pitch(&self) -> NonZeroU32 { + NonZeroU32::new(self.db.pitch()).expect("Pitch (stride in bytes) is zero") + } } impl Buffers { @@ -410,4 +425,9 @@ impl Buffers { pub(crate) fn size(&self) -> (NonZeroU32, NonZeroU32) { self.buffers[0].size() } + + /// Get the pitch (stride) of this buffer. + pub(crate) fn pitch(&self) -> NonZeroU32 { + self.buffers[0].pitch() + } } diff --git a/src/lib.rs b/src/lib.rs index f33195d..eb43883 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -153,6 +153,15 @@ macro_rules! make_dispatch { } } + pub fn stride(&self) -> u32 { + match self { + $( + $(#[$attr])* + Self::$name(inner) => inner.stride(), + )* + } + } + pub fn present(self) -> Result<(), SoftBufferError> { match self { $( @@ -413,6 +422,11 @@ impl<'a, D: HasDisplayHandle, W: HasWindowHandle> Buffer<'a, D, W> { self.buffer_impl.age() } + /// Stride in pixels + pub fn stride(&self) -> u32 { + self.buffer_impl.stride() + } + /// Presents buffer to the window. /// /// # Platform dependent behavior diff --git a/src/wayland/mod.rs b/src/wayland/mod.rs index bd4c80d..bee669f 100644 --- a/src/wayland/mod.rs +++ b/src/wayland/mod.rs @@ -168,6 +168,7 @@ impl WaylandImpl { Ok(unsafe { buffer.buffers.as_mut().unwrap().1.mapped_mut() }) })?, age, + width: width.get() as u32, }) } @@ -238,6 +239,7 @@ impl Drop for WaylandImpl { pub struct BufferImpl<'a, D: ?Sized, W> { stack: util::BorrowStack<'a, WaylandImpl, [u32]>, age: u8, + width: u32, } impl<'a, D: HasDisplayHandle + ?Sized, W: HasWindowHandle> BufferImpl<'a, D, W> { @@ -255,6 +257,11 @@ impl<'a, D: HasDisplayHandle + ?Sized, W: HasWindowHandle> BufferImpl<'a, D, W> self.age } + #[inline] + pub fn stride(&self) -> u32 { + self.width + } + pub fn present_with_damage(self, damage: &[Rect]) -> Result<(), SoftBufferError> { self.stack.into_container().present_with_damage(damage) } diff --git a/src/x11.rs b/src/x11.rs index 521d634..88b0ab7 100644 --- a/src/x11.rs +++ b/src/x11.rs @@ -384,6 +384,16 @@ impl<'a, D: HasDisplayHandle + ?Sized, W: HasWindowHandle + ?Sized> BufferImpl<' } } + #[inline] + pub fn stride(&self) -> u32 { + let (surface_width, _surface_height) = self + .0 + .size + .expect("Must set size of surface before calling `present_with_damage()`"); + + surface_width.get() as u32 + } + /// Push the buffer to the window. pub fn present_with_damage(self, damage: &[Rect]) -> Result<(), SoftBufferError> { let imp = self.0;