Skip to content

Commit d5cc95a

Browse files
committed
BADHACK: Add BufferImpl::stride() getter for Android
1 parent 55d3f3e commit d5cc95a

File tree

8 files changed

+67
-1
lines changed

8 files changed

+67
-1
lines changed

examples/winit.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ pub(crate) fn run(event_loop: EventLoop<()>) {
4646
let red = x % 255;
4747
let green = y % 255;
4848
let blue = (x * y) % 255;
49-
let index = y as usize * width.get() as usize + x as usize;
49+
let index = y as usize * buffer.stride() as usize + x as usize;
5050
buffer[index] = blue | (green << 8) | (red << 16);
5151
}
5252
}

src/backend_dispatch.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,16 @@ macro_rules! make_dispatch {
153153
}
154154
}
155155

156+
#[inline]
157+
fn stride(&self) -> u32 {
158+
match self {
159+
$(
160+
$(#[$attr])*
161+
Self::$name(inner) => inner.stride(),
162+
)*
163+
}
164+
}
165+
156166
fn present(self) -> Result<(), SoftBufferError> {
157167
match self {
158168
$(

src/backend_interface.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ pub(crate) trait BufferInterface {
3838
fn pixels(&self) -> &[u32];
3939
fn pixels_mut(&mut self) -> &mut [u32];
4040
fn age(&self) -> u8;
41+
fn stride(&self) -> u32;
4142
fn present_with_damage(self, damage: &[Rect]) -> Result<(), SoftBufferError>;
4243
fn present(self) -> Result<(), SoftBufferError>;
4344
}

src/backends/android.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,12 @@ impl<'a, D: HasDisplayHandle + ?Sized, W: HasWindowHandle> BufferImpl<'a, D, W>
139139
}
140140
}
141141

142+
/// The number of _pixels_ that a line in the buffer takes in memory.
143+
#[inline]
144+
pub fn stride(&self) -> u32 {
145+
self.0.stride() as u32
146+
}
147+
142148
pub fn age(&self) -> u8 {
143149
todo!()
144150
}

src/backends/kms.rs

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,9 @@ pub(crate) struct BufferImpl<'a, D: ?Sized, W: ?Sized> {
105105
/// The current size.
106106
size: (NonZeroU32, NonZeroU32),
107107

108+
/// The current stride/pitch (length of a single row of pixels) in bytes.
109+
stride: NonZeroU32,
110+
108111
/// The display implementation.
109112
display: &'a KmsDisplayImpl<D>,
110113

@@ -243,6 +246,7 @@ impl<D: HasDisplayHandle + ?Sized, W: HasWindowHandle> SurfaceInterface<D, W> fo
243246
.expect("Must set size of surface before calling `buffer_mut()`");
244247

245248
let size = set.size();
249+
let stride = set.pitch();
246250

247251
let [first_buffer, second_buffer] = &mut set.buffers;
248252
let (front_buffer, back_buffer) = if set.first_is_front {
@@ -263,6 +267,7 @@ impl<D: HasDisplayHandle + ?Sized, W: HasWindowHandle> SurfaceInterface<D, W> fo
263267
Ok(BufferImpl {
264268
mapping,
265269
size,
270+
stride,
266271
first_is_front: &mut set.first_is_front,
267272
front_fb,
268273
crtc_handle: self.crtc.handle(),
@@ -300,6 +305,19 @@ impl<D: ?Sized, W: ?Sized> BufferInterface for BufferImpl<'_, D, W> {
300305
bytemuck::cast_slice_mut(self.mapping.as_mut())
301306
}
302307

308+
/// The number of _pixels_ that a line in the buffer takes in memory.
309+
#[inline]
310+
pub fn stride(&self) -> u32 {
311+
// TODO Return NonZeroU32?
312+
let bpp: u32 = todo!();
313+
assert_eq!(self.stride.get() & bpp, 0);
314+
// TODO: Since this may not always be a multiple of BPP, this API should return the size in
315+
// bytes... And then the user is left to mess around with `fn pixels()`. We'll need a helper
316+
// iterator accessor like:
317+
// https://docs.rs/ndk/latest/ndk/native_window/struct.NativeWindowBufferLockGuard.html#method.lines
318+
self.stride.get() / bpp
319+
}
320+
303321
#[inline]
304322
fn age(&self) -> u8 {
305323
*self.front_age
@@ -398,11 +416,20 @@ impl SharedBuffer {
398416
.and_then(|width| NonZeroU32::new(height).map(|height| (width, height)))
399417
.expect("buffer size is zero")
400418
}
419+
420+
pub(crate) fn pitch(&self) -> NonZeroU32 {
421+
NonZeroU32::new(self.db.pitch()).expect("Pitch (stride in bytes) is zero")
422+
}
401423
}
402424

403425
impl Buffers {
404426
/// Get the size of this buffer.
405427
pub(crate) fn size(&self) -> (NonZeroU32, NonZeroU32) {
406428
self.buffers[0].size()
407429
}
430+
431+
/// Get the pitch (stride) of this buffer.
432+
pub(crate) fn pitch(&self) -> NonZeroU32 {
433+
self.buffers[0].pitch()
434+
}
408435
}

src/backends/wayland/mod.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -243,6 +243,7 @@ impl<D: HasDisplayHandle + ?Sized, W: HasWindowHandle> SurfaceInterface<D, W>
243243
Ok(unsafe { buffer.buffers.as_mut().unwrap().1.mapped_mut() })
244244
})?,
245245
age,
246+
width: width.get() as u32,
246247
})
247248
}
248249
}
@@ -257,6 +258,7 @@ impl<D: ?Sized, W: ?Sized> Drop for WaylandImpl<D, W> {
257258
pub struct BufferImpl<'a, D: ?Sized, W> {
258259
stack: util::BorrowStack<'a, WaylandImpl<D, W>, [u32]>,
259260
age: u8,
261+
width: u32,
260262
}
261263

262264
impl<'a, D: HasDisplayHandle + ?Sized, W: HasWindowHandle> BufferInterface
@@ -276,6 +278,11 @@ impl<'a, D: HasDisplayHandle + ?Sized, W: HasWindowHandle> BufferInterface
276278
self.age
277279
}
278280

281+
#[inline]
282+
fn stride(&self) -> u32 {
283+
self.width
284+
}
285+
279286
fn present_with_damage(self, damage: &[Rect]) -> Result<(), SoftBufferError> {
280287
self.stack.into_container().present_with_damage(damage)
281288
}

src/backends/x11.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -405,6 +405,16 @@ impl<'a, D: HasDisplayHandle + ?Sized, W: HasWindowHandle + ?Sized> BufferInterf
405405
}
406406
}
407407

408+
#[inline]
409+
pub fn stride(&self) -> u32 {
410+
let (surface_width, _surface_height) = self
411+
.0
412+
.size
413+
.expect("Must set size of surface before calling `present_with_damage()`");
414+
415+
surface_width.get() as u32
416+
}
417+
408418
/// Push the buffer to the window.
409419
fn present_with_damage(self, damage: &[Rect]) -> Result<(), SoftBufferError> {
410420
let imp = self.0;

src/lib.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,11 @@ impl<'a, D: HasDisplayHandle, W: HasWindowHandle> Buffer<'a, D, W> {
211211
self.buffer_impl.age()
212212
}
213213

214+
/// The number of _pixels_ that a line in the buffer takes in memory.
215+
pub fn stride(&self) -> u32 {
216+
self.buffer_impl.stride()
217+
}
218+
214219
/// Presents buffer to the window.
215220
///
216221
/// # Platform dependent behavior

0 commit comments

Comments
 (0)