From a2c37fd691d42726d8c95acd0e2375c8ec03d39d Mon Sep 17 00:00:00 2001 From: Mads Marquart Date: Thu, 5 Jun 2025 16:10:48 +0200 Subject: [PATCH 1/7] Add `Buffer::width` and `Buffer::height` --- CHANGELOG.md | 1 + src/backend_dispatch.rs | 20 ++++++++++++++++++++ src/backend_interface.rs | 2 ++ src/backends/android.rs | 8 ++++++++ src/backends/cg.rs | 8 ++++++++ src/backends/kms.rs | 8 ++++++++ src/backends/orbital.rs | 8 ++++++++ src/backends/wayland/mod.rs | 8 ++++++++ src/backends/web.rs | 16 ++++++++++++++++ src/backends/win32.rs | 8 ++++++++ src/backends/x11.rs | 8 ++++++++ src/lib.rs | 22 ++++++++++++++++++++++ 12 files changed, 117 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8669f2a4..04bc7106 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ - Update to `objc2` 0.6.0. - Bump MSRV to Rust 1.71. +- Added `Buffer::width` and `Buffer::height`. # 0.4.6 diff --git a/src/backend_dispatch.rs b/src/backend_dispatch.rs index a86832ea..bdb42db0 100644 --- a/src/backend_dispatch.rs +++ b/src/backend_dispatch.rs @@ -124,6 +124,26 @@ macro_rules! make_dispatch { } impl<'a, D: HasDisplayHandle, W: HasWindowHandle> BufferInterface for BufferDispatch<'a, D, W> { + #[inline] + fn width(&self) -> usize { + match self { + $( + $(#[$attr])* + Self::$name(inner) => inner.width(), + )* + } + } + + #[inline] + fn height(&self) -> usize { + match self { + $( + $(#[$attr])* + Self::$name(inner) => inner.height(), + )* + } + } + #[inline] fn pixels(&self) -> &[u32] { match self { diff --git a/src/backend_interface.rs b/src/backend_interface.rs index 13e3555c..4939dc96 100644 --- a/src/backend_interface.rs +++ b/src/backend_interface.rs @@ -35,6 +35,8 @@ pub(crate) trait SurfaceInterface usize; + fn height(&self) -> usize; fn pixels(&self) -> &[u32]; fn pixels_mut(&mut self) -> &mut [u32]; fn age(&self) -> u8; diff --git a/src/backends/android.rs b/src/backends/android.rs index a14aaefd..a3ae7524 100644 --- a/src/backends/android.rs +++ b/src/backends/android.rs @@ -123,6 +123,14 @@ pub struct BufferImpl<'a, D: ?Sized, W> { unsafe impl<'a, D, W> Send for BufferImpl<'a, D, W> {} impl<'a, D: HasDisplayHandle, W: HasWindowHandle> BufferInterface for BufferImpl<'a, D, W> { + fn width(&self) -> usize { + self.native_window_buffer.width() + } + + fn height(&self) -> usize { + self.native_window_buffer.height() + } + #[inline] fn pixels(&self) -> &[u32] { &self.buffer diff --git a/src/backends/cg.rs b/src/backends/cg.rs index ba6c17aa..677634d2 100644 --- a/src/backends/cg.rs +++ b/src/backends/cg.rs @@ -269,6 +269,14 @@ pub struct BufferImpl<'a, D, W> { } impl BufferInterface for BufferImpl<'_, D, W> { + fn width(&self) -> usize { + self.imp.width + } + + fn height(&self) -> usize { + self.imp.height + } + #[inline] fn pixels(&self) -> &[u32] { &self.buffer diff --git a/src/backends/kms.rs b/src/backends/kms.rs index 35ed5b8f..a2d63611 100644 --- a/src/backends/kms.rs +++ b/src/backends/kms.rs @@ -293,6 +293,14 @@ impl Drop for KmsImpl { } impl BufferInterface for BufferImpl<'_, D, W> { + fn width(&self) -> usize { + self.size.0.get() as usize + } + + fn height(&self) -> usize { + self.size.1.get() as usize + } + #[inline] fn pixels(&self) -> &[u32] { bytemuck::cast_slice(self.mapping.as_ref()) diff --git a/src/backends/orbital.rs b/src/backends/orbital.rs index d54683f1..c449e92c 100644 --- a/src/backends/orbital.rs +++ b/src/backends/orbital.rs @@ -191,6 +191,14 @@ pub struct BufferImpl<'a, D, W> { } impl BufferInterface for BufferImpl<'_, D, W> { + fn width(&self) -> usize { + self.imp.width as usize + } + + fn height(&self) -> usize { + self.imp.height as usize + } + #[inline] fn pixels(&self) -> &[u32] { match &self.pixels { diff --git a/src/backends/wayland/mod.rs b/src/backends/wayland/mod.rs index 000e553c..cdae0d83 100644 --- a/src/backends/wayland/mod.rs +++ b/src/backends/wayland/mod.rs @@ -263,6 +263,14 @@ pub struct BufferImpl<'a, D: ?Sized, W> { } impl BufferInterface for BufferImpl<'_, D, W> { + fn width(&self) -> usize { + self.stack.member().width + } + + fn height(&self) -> usize { + self.stack.member().height + } + #[inline] fn pixels(&self) -> &[u32] { self.stack.member() diff --git a/src/backends/web.rs b/src/backends/web.rs index 4eb8fe0c..64e35e47 100644 --- a/src/backends/web.rs +++ b/src/backends/web.rs @@ -377,6 +377,22 @@ pub struct BufferImpl<'a, D, W> { } impl BufferInterface for BufferImpl<'_, D, W> { + fn width(&self) -> usize { + self.imp + .size + .expect("must set size of surface before calling `width()` on the buffer") + .0 + .get() as usize + } + + fn height(&self) -> usize { + self.imp + .size + .expect("must set size of surface before calling `height()` on the buffer") + .1 + .get() as usize + } + fn pixels(&self) -> &[u32] { &self.imp.buffer } diff --git a/src/backends/win32.rs b/src/backends/win32.rs index 72dc6d0f..eda528cd 100644 --- a/src/backends/win32.rs +++ b/src/backends/win32.rs @@ -284,6 +284,14 @@ impl SurfaceInterface for Win32Im pub struct BufferImpl<'a, D, W>(&'a mut Win32Impl); impl BufferInterface for BufferImpl<'_, D, W> { + fn width(&self) -> usize { + self.0.buffer.as_ref().unwrap().width.get() as usize + } + + fn height(&self) -> usize { + self.0.buffer.as_ref().unwrap().height.get() as usize + } + #[inline] fn pixels(&self) -> &[u32] { self.0.buffer.as_ref().unwrap().pixels() diff --git a/src/backends/x11.rs b/src/backends/x11.rs index b4271f53..a141334b 100644 --- a/src/backends/x11.rs +++ b/src/backends/x11.rs @@ -388,6 +388,14 @@ pub struct BufferImpl<'a, D: ?Sized, W: ?Sized>(&'a mut X11Impl); impl BufferInterface for BufferImpl<'_, D, W> { + fn width(&self) -> usize { + self.0.size.unwrap().0.get() as usize + } + + fn height(&self) -> usize { + self.0.size.unwrap().1.get() as usize + } + #[inline] fn pixels(&self) -> &[u32] { // SAFETY: We called `finish_wait` on the buffer, so it is safe to call `buffer()`. diff --git a/src/lib.rs b/src/lib.rs index 2e25967e..ee085e1a 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -205,6 +205,28 @@ pub struct Buffer<'a, D, W> { } impl Buffer<'_, D, W> { + /// The amount of pixels wide the buffer is. + pub fn width(&self) -> usize { + let width = self.buffer_impl.width(); + debug_assert_eq!( + width * self.buffer_impl.height(), + self.len(), + "buffer must be sized correctly" + ); + width + } + + /// The amount of pixels tall the buffer is. + pub fn height(&self) -> usize { + let height = self.buffer_impl.height(); + debug_assert_eq!( + height * self.buffer_impl.width(), + self.len(), + "buffer must be sized correctly" + ); + height + } + /// `age` is the number of frames ago this buffer was last presented. So if the value is /// `1`, it is the same as the last frame, and if it is `2`, it is the same as the frame /// before that (for backends using double buffering). If the value is `0`, it is a new From f168182d4b0dc0bb08f8037260dbc34d14567f22 Mon Sep 17 00:00:00 2001 From: Mads Marquart Date: Thu, 5 Jun 2025 17:01:08 +0200 Subject: [PATCH 2/7] Update examples --- README.md | 25 +++++++++++-------------- examples/animation.rs | 25 +++++++++++-------------- examples/rectangle.rs | 25 +++++++++---------------- examples/winit.rs | 26 +++++++++++--------------- examples/winit_multithread.rs | 12 ++++++------ examples/winit_wrong_sized_buffer.rs | 15 +++++---------- 6 files changed, 53 insertions(+), 75 deletions(-) diff --git a/README.md b/README.md index c17e01fe..4b430a8a 100644 --- a/README.md +++ b/README.md @@ -101,26 +101,23 @@ fn main() { eprintln!("RedrawRequested fired before Resumed or after Suspended"); return; }; - let (width, height) = { - let size = window.inner_size(); - (size.width, size.height) - }; + let size = window.inner_size(); surface .resize( - NonZeroU32::new(width).unwrap(), - NonZeroU32::new(height).unwrap(), + NonZeroU32::new(size.width).unwrap(), + NonZeroU32::new(size.height).unwrap(), ) .unwrap(); let mut buffer = surface.buffer_mut().unwrap(); - for index in 0..(width * height) { - let y = index / width; - let x = index % width; - let red = x % 255; - let green = y % 255; - let blue = (x * y) % 255; - - buffer[index as usize] = blue | (green << 8) | (red << 16); + for index in 0..(buffer.width() * buffer.height()) { + let y = index / buffer.width(); + let x = index % buffer.width(); + let red = x as u32 % 255; + let green = y as u32 % 255; + let blue = (x as u32 * y as u32) % 255; + + buffer[index] = blue | (green << 8) | (red << 16); } buffer.present().unwrap(); diff --git a/examples/animation.rs b/examples/animation.rs index c075923e..c6d503a6 100644 --- a/examples/animation.rs +++ b/examples/animation.rs @@ -59,23 +59,20 @@ fn main() { return; }; - let size = window.inner_size(); - if let (Some(width), Some(height)) = - (NonZeroU32::new(size.width), NonZeroU32::new(size.height)) - { - let elapsed = start.elapsed().as_secs_f64() % 1.0; + let elapsed = start.elapsed().as_secs_f64() % 1.0; - if (width.get(), height.get()) != *old_size { - *old_size = (width.get(), height.get()); - *frames = pre_render_frames(width.get() as usize, height.get() as usize); - }; + let mut buffer = surface.buffer_mut().unwrap(); - let frame = &frames[((elapsed * 60.0).round() as usize).clamp(0, 59)]; - - let mut buffer = surface.buffer_mut().unwrap(); - buffer.copy_from_slice(frame); - buffer.present().unwrap(); + let size = (buffer.width(), buffer.height()); + if size != *old_size { + *old_size = size; + *frames = pre_render_frames(size.0, size.1); } + + let frame = &frames[((elapsed * 60.0).round() as usize).clamp(0, 59)]; + + buffer.copy_from_slice(frame); + buffer.present().unwrap(); } Event::AboutToWait => { window.request_redraw(); diff --git a/examples/rectangle.rs b/examples/rectangle.rs index b92f30b2..aba1a88e 100644 --- a/examples/rectangle.rs +++ b/examples/rectangle.rs @@ -1,3 +1,5 @@ +use raw_window_handle::{HasDisplayHandle, HasWindowHandle}; +use softbuffer::Buffer; use std::num::NonZeroU32; use winit::event::{ElementState, Event, KeyEvent, WindowEvent}; use winit::event_loop::{ControlFlow, EventLoop}; @@ -6,7 +8,9 @@ use winit::keyboard::{Key, NamedKey}; #[path = "utils/winit_app.rs"] mod winit_app; -fn redraw(buffer: &mut [u32], width: usize, height: usize, flag: bool) { +fn redraw(buffer: &mut Buffer<'_, impl HasDisplayHandle, impl HasWindowHandle>, flag: bool) { + let width = buffer.width(); + let height = buffer.height(); for y in 0..height { for x in 0..width { let value = if flag && x >= 100 && x < width - 100 && y >= 100 && y < height - 100 { @@ -71,21 +75,10 @@ fn main() { eprintln!("RedrawRequested fired before Resumed or after Suspended"); return; }; - // Grab the window's client area dimensions, and ensure they're valid - let size = window.inner_size(); - if let (Some(width), Some(height)) = - (NonZeroU32::new(size.width), NonZeroU32::new(size.height)) - { - // Draw something in the window - let mut buffer = surface.buffer_mut().unwrap(); - redraw( - &mut buffer, - width.get() as usize, - height.get() as usize, - *flag, - ); - buffer.present().unwrap(); - } + // Draw something in the window + let mut buffer = surface.buffer_mut().unwrap(); + redraw(&mut buffer, *flag); + buffer.present().unwrap(); } Event::WindowEvent { diff --git a/examples/winit.rs b/examples/winit.rs index 27a3cefb..a18d601b 100644 --- a/examples/winit.rs +++ b/examples/winit.rs @@ -49,23 +49,19 @@ pub(crate) fn entry(event_loop: EventLoop<()>) { eprintln!("RedrawRequested fired before Resumed or after Suspended"); return; }; - let size = window.inner_size(); - if let (Some(width), Some(height)) = - (NonZeroU32::new(size.width), NonZeroU32::new(size.height)) - { - let mut buffer = surface.buffer_mut().unwrap(); - for y in 0..height.get() { - for x in 0..width.get() { - 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; - buffer[index] = blue | (green << 8) | (red << 16); - } - } - buffer.present().unwrap(); + let mut buffer = surface.buffer_mut().unwrap(); + for y in 0..buffer.height() { + for x in 0..buffer.width() { + let red = x as u32 % 255; + let green = y as u32 % 255; + let blue = (x as u32 * y as u32) % 255; + let index = y * buffer.width() + x; + buffer[index] = blue | (green << 8) | (red << 16); + } } + + buffer.present().unwrap(); } Event::WindowEvent { event: diff --git a/examples/winit_multithread.rs b/examples/winit_multithread.rs index 03afcc56..140b0358 100644 --- a/examples/winit_multithread.rs +++ b/examples/winit_multithread.rs @@ -40,12 +40,12 @@ pub mod ex { surface.resize(width, height).unwrap(); let mut buffer = surface.buffer_mut().unwrap(); - for y in 0..height.get() { - for x in 0..width.get() { - 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; + for y in 0..buffer.height() { + for x in 0..buffer.width() { + let red = x as u32 % 255; + let green = y as u32 % 255; + let blue = (x as u32 * y as u32) % 255; + let index = y * buffer.width() + x; buffer[index] = blue | (green << 8) | (red << 16); } } diff --git a/examples/winit_wrong_sized_buffer.rs b/examples/winit_wrong_sized_buffer.rs index 0c58a116..febe7e0b 100644 --- a/examples/winit_wrong_sized_buffer.rs +++ b/examples/winit_wrong_sized_buffer.rs @@ -6,9 +6,6 @@ use winit::keyboard::{Key, NamedKey}; #[path = "utils/winit_app.rs"] mod winit_app; -const BUFFER_WIDTH: usize = 256; -const BUFFER_HEIGHT: usize = 128; - fn main() { let event_loop = EventLoop::new().unwrap(); @@ -24,10 +21,7 @@ fn main() { let mut surface = softbuffer::Surface::new(context, window.clone()).unwrap(); // Intentionally set the size of the surface to something different than the size of the window. surface - .resize( - NonZeroU32::new(BUFFER_WIDTH as u32).unwrap(), - NonZeroU32::new(BUFFER_HEIGHT as u32).unwrap(), - ) + .resize(NonZeroU32::new(256).unwrap(), NonZeroU32::new(128).unwrap()) .unwrap(); surface }, @@ -47,14 +41,15 @@ fn main() { }; let mut buffer = surface.buffer_mut().unwrap(); - for y in 0..BUFFER_HEIGHT { - for x in 0..BUFFER_WIDTH { + let width = buffer.width(); + for y in 0..buffer.height() { + for x in 0..width { let red = x as u32 % 255; let green = y as u32 % 255; let blue = (x as u32 * y as u32) % 255; let color = blue | (green << 8) | (red << 16); - buffer[y * BUFFER_WIDTH + x] = color; + buffer[y * width + x] = color; } } buffer.present().unwrap(); From 3f255f43208e88cee7b814d7b0b2eb194aaaac41 Mon Sep 17 00:00:00 2001 From: Mads Marquart Date: Thu, 5 Jun 2025 19:20:31 +0200 Subject: [PATCH 3/7] Finish Wayland impl --- src/backends/wayland/buffer.rs | 4 ++-- src/backends/wayland/mod.rs | 10 ++++++++-- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/src/backends/wayland/buffer.rs b/src/backends/wayland/buffer.rs index c4ebef0d..407dd742 100644 --- a/src/backends/wayland/buffer.rs +++ b/src/backends/wayland/buffer.rs @@ -74,8 +74,8 @@ pub(super) struct WaylandBuffer { pool: wl_shm_pool::WlShmPool, pool_size: i32, buffer: wl_buffer::WlBuffer, - width: i32, - height: i32, + pub width: i32, + pub height: i32, released: Arc, pub age: u8, } diff --git a/src/backends/wayland/mod.rs b/src/backends/wayland/mod.rs index cdae0d83..eabc7cef 100644 --- a/src/backends/wayland/mod.rs +++ b/src/backends/wayland/mod.rs @@ -240,11 +240,15 @@ impl SurfaceInterface )); }; + let width = self.buffers.as_mut().unwrap().1.width; + let height = self.buffers.as_mut().unwrap().1.height; let age = self.buffers.as_mut().unwrap().1.age; Ok(BufferImpl { stack: util::BorrowStack::new(self, |buffer| { Ok(unsafe { buffer.buffers.as_mut().unwrap().1.mapped_mut() }) })?, + width, + height, age, }) } @@ -259,16 +263,18 @@ impl Drop for WaylandImpl { pub struct BufferImpl<'a, D: ?Sized, W> { stack: util::BorrowStack<'a, WaylandImpl, [u32]>, + width: i32, + height: i32, age: u8, } impl BufferInterface for BufferImpl<'_, D, W> { fn width(&self) -> usize { - self.stack.member().width + self.width as usize } fn height(&self) -> usize { - self.stack.member().height + self.height as usize } #[inline] From a5f362ec023485d7ed0910cfad2357a8a8b28370 Mon Sep 17 00:00:00 2001 From: Mads Marquart Date: Sun, 23 Nov 2025 12:30:40 +0100 Subject: [PATCH 4/7] Improve changelog Co-authored-by: Marijn Suijten --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 04bc7106..5b299ef9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,7 @@ - Update to `objc2` 0.6.0. - Bump MSRV to Rust 1.71. -- Added `Buffer::width` and `Buffer::height`. +- Added `Buffer::width()` and `Buffer::height()` getters. # 0.4.6 From 590c0b24ed5464cb42852538c17d1cc42bd10d9e Mon Sep 17 00:00:00 2001 From: Mads Marquart Date: Sun, 23 Nov 2025 13:35:54 +0100 Subject: [PATCH 5/7] Use NonZeroU32 --- examples/animation.rs | 4 ++-- examples/fruit.rs | 4 ++-- examples/rectangle.rs | 6 +++--- examples/winit.rs | 8 ++++---- examples/winit_multithread.rs | 8 ++++---- examples/winit_wrong_sized_buffer.rs | 6 +++--- src/backend_dispatch.rs | 4 ++-- src/backend_interface.rs | 4 ++-- src/backends/android.rs | 8 ++++---- src/backends/cg.rs | 8 ++++---- src/backends/kms.rs | 8 ++++---- src/backends/orbital.rs | 8 ++++---- src/backends/wayland/mod.rs | 8 ++++---- src/backends/web.rs | 6 ++---- src/backends/win32.rs | 8 ++++---- src/backends/x11.rs | 8 ++++---- src/lib.rs | 8 ++++---- 17 files changed, 56 insertions(+), 58 deletions(-) diff --git a/examples/animation.rs b/examples/animation.rs index 6c408071..cfc41747 100644 --- a/examples/animation.rs +++ b/examples/animation.rs @@ -61,7 +61,7 @@ fn main() { let mut buffer = surface.buffer_mut().unwrap(); - let size = (buffer.width(), buffer.height()); + let size = (buffer.width().get(), buffer.height().get()); if size != *old_size { *old_size = size; *frames = pre_render_frames(size.0, size.1); @@ -94,7 +94,7 @@ fn main() { winit_app::run_app(event_loop, app); } -fn pre_render_frames(width: usize, height: usize) -> Vec> { +fn pre_render_frames(width: u32, height: u32) -> Vec> { let render = |frame_id| { let elapsed = ((frame_id as f64) / (60.0)) * 2.0 * PI; diff --git a/examples/fruit.rs b/examples/fruit.rs index 0bd9fc42..f07fce2d 100644 --- a/examples/fruit.rs +++ b/examples/fruit.rs @@ -50,14 +50,14 @@ fn main() { }; let mut buffer = surface.buffer_mut().unwrap(); - let width = fruit.width() as usize; + let width = fruit.width(); for (x, y, pixel) in fruit.pixels() { let red = pixel.0[0] as u32; let green = pixel.0[1] as u32; let blue = pixel.0[2] as u32; let color = blue | (green << 8) | (red << 16); - buffer[y as usize * width + x as usize] = color; + buffer[(y * width + x) as usize] = color; } buffer.present().unwrap(); diff --git a/examples/rectangle.rs b/examples/rectangle.rs index 223e4a4e..d8ca9c47 100644 --- a/examples/rectangle.rs +++ b/examples/rectangle.rs @@ -9,8 +9,8 @@ use winit::keyboard::{Key, NamedKey}; mod winit_app; fn redraw(buffer: &mut Buffer<'_, impl HasDisplayHandle, impl HasWindowHandle>, flag: bool) { - let width = buffer.width(); - let height = buffer.height(); + let width = buffer.width().get(); + let height = buffer.height().get(); for y in 0..height { for x in 0..width { let value = if flag && x >= 100 && x < width - 100 && y >= 100 && y < height - 100 { @@ -21,7 +21,7 @@ fn redraw(buffer: &mut Buffer<'_, impl HasDisplayHandle, impl HasWindowHandle>, let blue = (x & 0x3f) ^ (y & 0x3f); (blue | (green << 8) | (red << 16)) as u32 }; - buffer[y * width + x] = value; + buffer[(y * width + x) as usize] = value; } } } diff --git a/examples/winit.rs b/examples/winit.rs index 831b75e8..12112bde 100644 --- a/examples/winit.rs +++ b/examples/winit.rs @@ -45,13 +45,13 @@ pub(crate) fn entry(event_loop: EventLoop<()>) { }; let mut buffer = surface.buffer_mut().unwrap(); - for y in 0..buffer.height() { - for x in 0..buffer.width() { + for y in 0..buffer.height().get() { + for x in 0..buffer.width().get() { let red = x as u32 % 255; let green = y as u32 % 255; let blue = (x as u32 * y as u32) % 255; - let index = y * buffer.width() + x; - buffer[index] = blue | (green << 8) | (red << 16); + let index = y * buffer.width().get() + x; + buffer[index as usize] = blue | (green << 8) | (red << 16); } } diff --git a/examples/winit_multithread.rs b/examples/winit_multithread.rs index 1ee506f1..4a45724a 100644 --- a/examples/winit_multithread.rs +++ b/examples/winit_multithread.rs @@ -40,13 +40,13 @@ pub mod ex { surface.resize(width, height).unwrap(); let mut buffer = surface.buffer_mut().unwrap(); - for y in 0..buffer.height() { - for x in 0..buffer.width() { + for y in 0..buffer.height().get() { + for x in 0..buffer.width().get() { let red = x as u32 % 255; let green = y as u32 % 255; let blue = (x as u32 * y as u32) % 255; - let index = y * buffer.width() + x; - buffer[index] = blue | (green << 8) | (red << 16); + let index = y * buffer.width().get() + x; + buffer[index as usize] = blue | (green << 8) | (red << 16); } } diff --git a/examples/winit_wrong_sized_buffer.rs b/examples/winit_wrong_sized_buffer.rs index 29c51210..bb432173 100644 --- a/examples/winit_wrong_sized_buffer.rs +++ b/examples/winit_wrong_sized_buffer.rs @@ -36,15 +36,15 @@ fn main() { }; let mut buffer = surface.buffer_mut().unwrap(); - let width = buffer.width(); - for y in 0..buffer.height() { + let width = buffer.width().get(); + for y in 0..buffer.height().get() { for x in 0..width { let red = x as u32 % 255; let green = y as u32 % 255; let blue = (x as u32 * y as u32) % 255; let color = blue | (green << 8) | (red << 16); - buffer[y * width + x] = color; + buffer[(y * width + x) as usize] = color; } } buffer.present().unwrap(); diff --git a/src/backend_dispatch.rs b/src/backend_dispatch.rs index 00eea10d..5a34a7c5 100644 --- a/src/backend_dispatch.rs +++ b/src/backend_dispatch.rs @@ -126,7 +126,7 @@ macro_rules! make_dispatch { impl<'a, D: HasDisplayHandle, W: HasWindowHandle> BufferInterface for BufferDispatch<'a, D, W> { #[inline] - fn width(&self) -> usize { + fn width(&self) -> NonZeroU32 { match self { $( $(#[$attr])* @@ -136,7 +136,7 @@ macro_rules! make_dispatch { } #[inline] - fn height(&self) -> usize { + fn height(&self) -> NonZeroU32 { match self { $( $(#[$attr])* diff --git a/src/backend_interface.rs b/src/backend_interface.rs index 4939dc96..b6a56661 100644 --- a/src/backend_interface.rs +++ b/src/backend_interface.rs @@ -35,8 +35,8 @@ pub(crate) trait SurfaceInterface usize; - fn height(&self) -> usize; + fn width(&self) -> NonZeroU32; + fn height(&self) -> NonZeroU32; fn pixels(&self) -> &[u32]; fn pixels_mut(&mut self) -> &mut [u32]; fn age(&self) -> u8; diff --git a/src/backends/android.rs b/src/backends/android.rs index a3ae7524..916cde85 100644 --- a/src/backends/android.rs +++ b/src/backends/android.rs @@ -123,12 +123,12 @@ pub struct BufferImpl<'a, D: ?Sized, W> { unsafe impl<'a, D, W> Send for BufferImpl<'a, D, W> {} impl<'a, D: HasDisplayHandle, W: HasWindowHandle> BufferInterface for BufferImpl<'a, D, W> { - fn width(&self) -> usize { - self.native_window_buffer.width() + fn width(&self) -> NonZeroU32 { + NonZeroU32::new(self.native_window_buffer.width() as u32).unwrap() } - fn height(&self) -> usize { - self.native_window_buffer.height() + fn height(&self) -> NonZeroU32 { + NonZeroU32::new(self.native_window_buffer.height() as u32).unwrap() } #[inline] diff --git a/src/backends/cg.rs b/src/backends/cg.rs index c58b855b..6e8999d5 100644 --- a/src/backends/cg.rs +++ b/src/backends/cg.rs @@ -270,12 +270,12 @@ pub struct BufferImpl<'a, D, W> { } impl BufferInterface for BufferImpl<'_, D, W> { - fn width(&self) -> usize { - self.imp.width + fn width(&self) -> NonZeroU32 { + NonZeroU32::new(self.imp.width as u32).unwrap() } - fn height(&self) -> usize { - self.imp.height + fn height(&self) -> NonZeroU32 { + NonZeroU32::new(self.imp.height as u32).unwrap() } #[inline] diff --git a/src/backends/kms.rs b/src/backends/kms.rs index a2d63611..3008e8c2 100644 --- a/src/backends/kms.rs +++ b/src/backends/kms.rs @@ -293,12 +293,12 @@ impl Drop for KmsImpl { } impl BufferInterface for BufferImpl<'_, D, W> { - fn width(&self) -> usize { - self.size.0.get() as usize + fn width(&self) -> NonZeroU32 { + self.size.0 } - fn height(&self) -> usize { - self.size.1.get() as usize + fn height(&self) -> NonZeroU32 { + self.size.1 } #[inline] diff --git a/src/backends/orbital.rs b/src/backends/orbital.rs index c449e92c..cea6feb0 100644 --- a/src/backends/orbital.rs +++ b/src/backends/orbital.rs @@ -191,12 +191,12 @@ pub struct BufferImpl<'a, D, W> { } impl BufferInterface for BufferImpl<'_, D, W> { - fn width(&self) -> usize { - self.imp.width as usize + fn width(&self) -> NonZeroU32 { + NonZeroU32::new(self.imp.width as u32).unwrap() } - fn height(&self) -> usize { - self.imp.height as usize + fn height(&self) -> NonZeroU32 { + NonZeroU32::new(self.imp.height as u32).unwrap() } #[inline] diff --git a/src/backends/wayland/mod.rs b/src/backends/wayland/mod.rs index eabc7cef..d497484a 100644 --- a/src/backends/wayland/mod.rs +++ b/src/backends/wayland/mod.rs @@ -269,12 +269,12 @@ pub struct BufferImpl<'a, D: ?Sized, W> { } impl BufferInterface for BufferImpl<'_, D, W> { - fn width(&self) -> usize { - self.width as usize + fn width(&self) -> NonZeroU32 { + NonZeroU32::new(self.width as u32).unwrap() } - fn height(&self) -> usize { - self.height as usize + fn height(&self) -> NonZeroU32 { + NonZeroU32::new(self.height as usize as u32).unwrap() } #[inline] diff --git a/src/backends/web.rs b/src/backends/web.rs index c8467592..3b8efa19 100644 --- a/src/backends/web.rs +++ b/src/backends/web.rs @@ -378,20 +378,18 @@ pub struct BufferImpl<'a, D, W> { } impl BufferInterface for BufferImpl<'_, D, W> { - fn width(&self) -> usize { + fn width(&self) -> NonZeroU32 { self.imp .size .expect("must set size of surface before calling `width()` on the buffer") .0 - .get() as usize } - fn height(&self) -> usize { + fn height(&self) -> NonZeroU32 { self.imp .size .expect("must set size of surface before calling `height()` on the buffer") .1 - .get() as usize } fn pixels(&self) -> &[u32] { diff --git a/src/backends/win32.rs b/src/backends/win32.rs index eda528cd..3436f556 100644 --- a/src/backends/win32.rs +++ b/src/backends/win32.rs @@ -284,12 +284,12 @@ impl SurfaceInterface for Win32Im pub struct BufferImpl<'a, D, W>(&'a mut Win32Impl); impl BufferInterface for BufferImpl<'_, D, W> { - fn width(&self) -> usize { - self.0.buffer.as_ref().unwrap().width.get() as usize + fn width(&self) -> NonZeroU32 { + self.0.buffer.as_ref().unwrap().width.try_into().unwrap() } - fn height(&self) -> usize { - self.0.buffer.as_ref().unwrap().height.get() as usize + fn height(&self) -> NonZeroU32 { + self.0.buffer.as_ref().unwrap().height.try_into().unwrap() } #[inline] diff --git a/src/backends/x11.rs b/src/backends/x11.rs index a141334b..f1429711 100644 --- a/src/backends/x11.rs +++ b/src/backends/x11.rs @@ -388,12 +388,12 @@ pub struct BufferImpl<'a, D: ?Sized, W: ?Sized>(&'a mut X11Impl); impl BufferInterface for BufferImpl<'_, D, W> { - fn width(&self) -> usize { - self.0.size.unwrap().0.get() as usize + fn width(&self) -> NonZeroU32 { + self.0.size.unwrap().0.into() } - fn height(&self) -> usize { - self.0.size.unwrap().1.get() as usize + fn height(&self) -> NonZeroU32 { + self.0.size.unwrap().1.into() } #[inline] diff --git a/src/lib.rs b/src/lib.rs index 4950ad9c..03246c04 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -207,10 +207,10 @@ pub struct Buffer<'a, D, W> { impl Buffer<'_, D, W> { /// The amount of pixels wide the buffer is. - pub fn width(&self) -> usize { + pub fn width(&self) -> NonZeroU32 { let width = self.buffer_impl.width(); debug_assert_eq!( - width * self.buffer_impl.height(), + width.get() as usize * self.buffer_impl.height().get() as usize, self.len(), "buffer must be sized correctly" ); @@ -218,10 +218,10 @@ impl Buffer<'_, D, W> { } /// The amount of pixels tall the buffer is. - pub fn height(&self) -> usize { + pub fn height(&self) -> NonZeroU32 { let height = self.buffer_impl.height(); debug_assert_eq!( - height * self.buffer_impl.width(), + height.get() as usize * self.buffer_impl.width().get() as usize, self.len(), "buffer must be sized correctly" ); From eface090edf74f21ffa3fabc572c1dccd20aca92 Mon Sep 17 00:00:00 2001 From: Mads Marquart Date: Sun, 23 Nov 2025 13:40:04 +0100 Subject: [PATCH 6/7] Fix README example --- README.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 56337cbd..85faaaee 100644 --- a/README.md +++ b/README.md @@ -110,14 +110,14 @@ fn main() { .unwrap(); let mut buffer = surface.buffer_mut().unwrap(); - for index in 0..(buffer.width() * buffer.height()) { - let y = index / buffer.width(); - let x = index % buffer.width(); - let red = x as u32 % 255; - let green = y as u32 % 255; - let blue = (x as u32 * y as u32) % 255; - - buffer[index] = blue | (green << 8) | (red << 16); + for index in 0..(buffer.width().get() * buffer.height().get()) { + let y = index / buffer.width().get(); + let x = index % buffer.width().get(); + let red = x % 255; + let green = y % 255; + let blue = (x * y) % 255; + + buffer[index as usize] = blue | (green << 8) | (red << 16); } buffer.present().unwrap(); From cc92902e8d78cd0f54516ca0e90d88b3a1311d78 Mon Sep 17 00:00:00 2001 From: Mads Marquart Date: Sun, 23 Nov 2025 13:43:21 +0100 Subject: [PATCH 7/7] Remove redundant as u32 casts --- examples/rectangle.rs | 2 +- examples/winit.rs | 6 +++--- examples/winit_multithread.rs | 6 +++--- examples/winit_wrong_sized_buffer.rs | 6 +++--- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/examples/rectangle.rs b/examples/rectangle.rs index d8ca9c47..b6558666 100644 --- a/examples/rectangle.rs +++ b/examples/rectangle.rs @@ -19,7 +19,7 @@ fn redraw(buffer: &mut Buffer<'_, impl HasDisplayHandle, impl HasWindowHandle>, let red = (x & 0xff) ^ (y & 0xff); let green = (x & 0x7f) ^ (y & 0x7f); let blue = (x & 0x3f) ^ (y & 0x3f); - (blue | (green << 8) | (red << 16)) as u32 + blue | (green << 8) | (red << 16) }; buffer[(y * width + x) as usize] = value; } diff --git a/examples/winit.rs b/examples/winit.rs index 12112bde..044ae391 100644 --- a/examples/winit.rs +++ b/examples/winit.rs @@ -47,9 +47,9 @@ pub(crate) fn entry(event_loop: EventLoop<()>) { let mut buffer = surface.buffer_mut().unwrap(); for y in 0..buffer.height().get() { for x in 0..buffer.width().get() { - let red = x as u32 % 255; - let green = y as u32 % 255; - let blue = (x as u32 * y as u32) % 255; + let red = x % 255; + let green = y % 255; + let blue = (x * y) % 255; let index = y * buffer.width().get() + x; buffer[index as usize] = blue | (green << 8) | (red << 16); } diff --git a/examples/winit_multithread.rs b/examples/winit_multithread.rs index 4a45724a..36ae2b2c 100644 --- a/examples/winit_multithread.rs +++ b/examples/winit_multithread.rs @@ -42,9 +42,9 @@ pub mod ex { let mut buffer = surface.buffer_mut().unwrap(); for y in 0..buffer.height().get() { for x in 0..buffer.width().get() { - let red = x as u32 % 255; - let green = y as u32 % 255; - let blue = (x as u32 * y as u32) % 255; + let red = x % 255; + let green = y % 255; + let blue = (x * y) % 255; let index = y * buffer.width().get() + x; buffer[index as usize] = blue | (green << 8) | (red << 16); } diff --git a/examples/winit_wrong_sized_buffer.rs b/examples/winit_wrong_sized_buffer.rs index bb432173..ec74c652 100644 --- a/examples/winit_wrong_sized_buffer.rs +++ b/examples/winit_wrong_sized_buffer.rs @@ -39,9 +39,9 @@ fn main() { let width = buffer.width().get(); for y in 0..buffer.height().get() { for x in 0..width { - let red = x as u32 % 255; - let green = y as u32 % 255; - let blue = (x as u32 * y as u32) % 255; + let red = x % 255; + let green = y % 255; + let blue = (x * y) % 255; let color = blue | (green << 8) | (red << 16); buffer[(y * width + x) as usize] = color;