diff --git a/CHANGELOG.md b/CHANGELOG.md index 0000bd9b..fdc0d3aa 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ - Added `Buffer::pixel_rows()` for iterating over rows of the buffer data. - Added `Buffer::pixels_iter()` for iterating over each pixel with its associated `x`/`y` coordinate. - Added `Buffer::byte_stride()` for pixel buffers whose rows are aligned and may contain padding bytes at the end. Prefer to use the above helpers instead of accessing pixel data directly. +- Renamed `Surface::buffer_mut()` to `Surface::next_buffer()`. - **Breaking:** Add `Pixel` struct, and use that for pixels instead of `u32`. - **Breaking:** The pixel format is now target-dependent. Access `PixelFormat::default()` to see which format is used on the current platform. - **Breaking:** Removed generic type parameters `D` and `W` from `Buffer<'_>` struct. diff --git a/Cargo.toml b/Cargo.toml index 1aff3950..ac0c4c8d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -167,7 +167,7 @@ name = "winit_multithread_android" crate-type = ["cdylib"] [[bench]] -name = "buffer_mut" +name = "buffer" harness = false [dev-dependencies] diff --git a/README.md b/README.md index ab68abf1..779ec89b 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,7 @@ To use Softbuffer, first create a window using `winit`, `sdl3`, or any other cra [`raw_window_handle::HasWindowHandle`]. Next, you create a [`Context`] and [`Surface`] from that window, and can now call -[`Surface::buffer_mut()`] to get a [`Buffer`] that you can draw into. Once you're done drawing, call +[`Surface::next_buffer()`] to get a [`Buffer`] that you can draw into. Once you're done drawing, call [`Buffer::present()`] to show the buffer on the window. Note that Softbuffer only provides the `&mut [...]` buffer, it does not provide any rendering @@ -117,7 +117,7 @@ fn main() { ) .unwrap(); - let mut buffer = surface.buffer_mut().unwrap(); + let mut buffer = surface.next_buffer().unwrap(); for (x, y, pixel) in buffer.pixels_iter() { let red = (x % 255) as u8; let green = (y % 255) as u8; diff --git a/benches/buffer_mut.rs b/benches/buffer.rs similarity index 87% rename from benches/buffer_mut.rs rename to benches/buffer.rs index 38c74a94..3c0a01b9 100644 --- a/benches/buffer_mut.rs +++ b/benches/buffer.rs @@ -5,7 +5,7 @@ all(target_vendor = "apple", not(target_os = "macos")), target_os = "redox" )))] -fn buffer_mut(c: &mut criterion::Criterion) { +fn buffer(c: &mut criterion::Criterion) { use criterion::black_box; use softbuffer::{Context, Pixel, Surface}; use std::num::NonZeroU32; @@ -34,14 +34,14 @@ fn buffer_mut(c: &mut criterion::Criterion) { ) .unwrap(); - c.bench_function("buffer_mut()", |b| { + c.bench_function("next_buffer()", |b| { b.iter(|| { - black_box(surface.buffer_mut().unwrap()); + black_box(surface.next_buffer().unwrap()); }); }); c.bench_function("pixels()", |b| { - let mut buffer = surface.buffer_mut().unwrap(); + let mut buffer = surface.next_buffer().unwrap(); b.iter(|| { let pixels: &mut [Pixel] = buffer.pixels(); black_box(pixels); @@ -49,7 +49,7 @@ fn buffer_mut(c: &mut criterion::Criterion) { }); c.bench_function("fill pixels", |b| { - let mut buffer = surface.buffer_mut().unwrap(); + let mut buffer = surface.next_buffer().unwrap(); b.iter(|| { let buffer = black_box(&mut buffer); buffer.pixels().fill(Pixel::default()); @@ -57,7 +57,7 @@ fn buffer_mut(c: &mut criterion::Criterion) { }); c.bench_function("render pixels_iter", |b| { - let mut buffer = surface.buffer_mut().unwrap(); + let mut buffer = surface.next_buffer().unwrap(); b.iter(|| { let buffer = black_box(&mut buffer); for (x, y, pixel) in buffer.pixels_iter() { @@ -78,7 +78,7 @@ fn buffer_mut(c: &mut criterion::Criterion) { all(target_vendor = "apple", not(target_os = "macos")), target_os = "redox" )))] -criterion::criterion_group!(benches, buffer_mut); +criterion::criterion_group!(benches, buffer); #[cfg(not(any( target_family = "wasm", diff --git a/examples/animation.rs b/examples/animation.rs index 7ae3b6c8..b4f94f7b 100644 --- a/examples/animation.rs +++ b/examples/animation.rs @@ -59,7 +59,7 @@ fn main() { let elapsed = start.elapsed().as_secs_f64() % 1.0; - let mut buffer = surface.buffer_mut().unwrap(); + let mut buffer = surface.next_buffer().unwrap(); let size = (buffer.width().get(), buffer.height().get()); if size != *old_size { diff --git a/examples/drm.rs b/examples/drm.rs index 17b77980..e33bd340 100644 --- a/examples/drm.rs +++ b/examples/drm.rs @@ -127,7 +127,7 @@ mod imple { tracing::info!("Drawing tick {tick}"); // Start drawing. - let mut buffer = surface.buffer_mut()?; + let mut buffer = surface.next_buffer()?; draw_to_buffer(buffer.pixels(), tick); buffer.present()?; diff --git a/examples/fruit.rs b/examples/fruit.rs index 4b36bc1b..f3840fc2 100644 --- a/examples/fruit.rs +++ b/examples/fruit.rs @@ -51,7 +51,7 @@ fn main() { return; }; - let mut buffer = surface.buffer_mut().unwrap(); + let mut buffer = surface.next_buffer().unwrap(); let stride = buffer.byte_stride().get() / 4; for (x, y, pixel) in fruit.pixels() { let pixel = Pixel::new_rgb(pixel.0[0], pixel.0[1], pixel.0[2]); diff --git a/examples/libxcb.rs b/examples/libxcb.rs index f84ac2c6..23ebf585 100644 --- a/examples/libxcb.rs +++ b/examples/libxcb.rs @@ -122,7 +122,7 @@ mod example { NonZeroU32::new(height.into()).unwrap(), ) .unwrap(); - let mut buffer = surface.buffer_mut().unwrap(); + let mut buffer = surface.next_buffer().unwrap(); buffer.pixels().fill(Pixel::new_rgb(0xff, 0, 0)); buffer.present().unwrap(); } diff --git a/examples/raytracing/main.rs b/examples/raytracing/main.rs index 2d8115a4..f95e81b4 100644 --- a/examples/raytracing/main.rs +++ b/examples/raytracing/main.rs @@ -68,7 +68,7 @@ fn main() { game.update(); - let mut buffer = surface.buffer_mut().unwrap(); + let mut buffer = surface.next_buffer().unwrap(); game.draw(&mut buffer, window.scale_factor() as f32); buffer.present().unwrap(); window.request_redraw(); diff --git a/examples/rectangle.rs b/examples/rectangle.rs index 69e4e4fe..5ba7061b 100644 --- a/examples/rectangle.rs +++ b/examples/rectangle.rs @@ -68,7 +68,7 @@ fn main() { return; }; // Draw something in the window - let mut buffer = surface.buffer_mut().unwrap(); + let mut buffer = surface.next_buffer().unwrap(); redraw(&mut buffer, *flag); buffer.present().unwrap(); } diff --git a/examples/winit.rs b/examples/winit.rs index 61c0066e..187f6ee9 100644 --- a/examples/winit.rs +++ b/examples/winit.rs @@ -46,7 +46,7 @@ pub(crate) fn entry(event_loop: EventLoop<()>) { return; }; - let mut buffer = surface.buffer_mut().unwrap(); + let mut buffer = surface.next_buffer().unwrap(); for (x, y, pixel) in buffer.pixels_iter() { let red = x % 255; let green = y % 255; diff --git a/examples/winit_multithread.rs b/examples/winit_multithread.rs index f0d56524..cb3c35d2 100644 --- a/examples/winit_multithread.rs +++ b/examples/winit_multithread.rs @@ -32,7 +32,7 @@ pub mod ex { tracing::info!("resizing..."); surface.resize(width, height).unwrap(); - let mut buffer = surface.buffer_mut().unwrap(); + let mut buffer = surface.next_buffer().unwrap(); for (x, y, pixel) in buffer.pixels_iter() { let red = x % 255; let green = y % 255; diff --git a/examples/winit_wrong_sized_buffer.rs b/examples/winit_wrong_sized_buffer.rs index 253b19f9..6c0805fb 100644 --- a/examples/winit_wrong_sized_buffer.rs +++ b/examples/winit_wrong_sized_buffer.rs @@ -37,7 +37,7 @@ fn main() { return; }; - let mut buffer = surface.buffer_mut().unwrap(); + let mut buffer = surface.next_buffer().unwrap(); for (x, y, pixel) in buffer.pixels_iter() { let red = x % 255; let green = y % 255; diff --git a/src/backend_dispatch.rs b/src/backend_dispatch.rs index 69008815..8abd80c8 100644 --- a/src/backend_dispatch.rs +++ b/src/backend_dispatch.rs @@ -108,11 +108,11 @@ macro_rules! make_dispatch { } } - fn buffer_mut(&mut self) -> Result, SoftBufferError> { + fn next_buffer(&mut self) -> Result, SoftBufferError> { match self { $( $(#[$attr])* - Self::$name(inner) => Ok(BufferDispatch::$name(inner.buffer_mut()?)), + Self::$name(inner) => Ok(BufferDispatch::$name(inner.next_buffer()?)), )* } } diff --git a/src/backend_interface.rs b/src/backend_interface.rs index 54eac73c..564d19d9 100644 --- a/src/backend_interface.rs +++ b/src/backend_interface.rs @@ -26,8 +26,8 @@ pub(crate) trait SurfaceInterface &W; /// Resize the internal buffer to the given width and height. fn resize(&mut self, width: NonZeroU32, height: NonZeroU32) -> Result<(), SoftBufferError>; - /// Get a mutable reference to the buffer. - fn buffer_mut(&mut self) -> Result, SoftBufferError>; + /// Get the next buffer to render into. + fn next_buffer(&mut self) -> Result, SoftBufferError>; /// Fetch the buffer from the window. fn fetch(&mut self) -> Result, SoftBufferError> { Err(SoftBufferError::Unimplemented) diff --git a/src/backends/android.rs b/src/backends/android.rs index 75e5bf90..980d570e 100644 --- a/src/backends/android.rs +++ b/src/backends/android.rs @@ -76,7 +76,7 @@ impl SurfaceInterface for Android }) } - fn buffer_mut(&mut self) -> Result, SoftBufferError> { + fn next_buffer(&mut self) -> Result, SoftBufferError> { let native_window_buffer = self.native_window.lock(None).map_err(|err| { SoftBufferError::PlatformError( Some("Failed to lock ANativeWindow".to_owned()), diff --git a/src/backends/cg.rs b/src/backends/cg.rs index c49d6d43..d3ab0472 100644 --- a/src/backends/cg.rs +++ b/src/backends/cg.rs @@ -258,7 +258,7 @@ impl SurfaceInterface for CGImpl< Ok(()) } - fn buffer_mut(&mut self) -> Result, SoftBufferError> { + fn next_buffer(&mut self) -> Result, SoftBufferError> { let buffer_size = util::byte_stride(self.width as u32) as usize * self.height / 4; Ok(BufferImpl { buffer: util::PixelBuffer(vec![Pixel::default(); buffer_size]), diff --git a/src/backends/kms.rs b/src/backends/kms.rs index e8bb1dec..33ecb2f5 100644 --- a/src/backends/kms.rs +++ b/src/backends/kms.rs @@ -252,12 +252,12 @@ impl SurfaceInterface fo } */ - fn buffer_mut(&mut self) -> Result, SoftBufferError> { + fn next_buffer(&mut self) -> Result, SoftBufferError> { // Map the dumb buffer. let set = self .buffer .as_mut() - .expect("Must set size of surface before calling `buffer_mut()`"); + .expect("Must set size of surface before calling `next_buffer()`"); let size = set.size(); diff --git a/src/backends/orbital.rs b/src/backends/orbital.rs index 801c4a50..7faf8fe0 100644 --- a/src/backends/orbital.rs +++ b/src/backends/orbital.rs @@ -112,7 +112,7 @@ impl SurfaceInterface for Orbital Ok(()) } - fn buffer_mut(&mut self) -> Result, SoftBufferError> { + fn next_buffer(&mut self) -> Result, SoftBufferError> { let (window_width, window_height) = window_size(self.window_fd()); let pixels = if self.width as usize == window_width && self.height as usize == window_height { diff --git a/src/backends/wayland/mod.rs b/src/backends/wayland/mod.rs index 408fc2f3..0e771f02 100644 --- a/src/backends/wayland/mod.rs +++ b/src/backends/wayland/mod.rs @@ -154,10 +154,10 @@ impl SurfaceInterface Ok(()) } - fn buffer_mut(&mut self) -> Result, SoftBufferError> { + fn next_buffer(&mut self) -> Result, SoftBufferError> { let (width, height) = self .size - .expect("Must set size of surface before calling `buffer_mut()`"); + .expect("Must set size of surface before calling `next_buffer()`"); if let Some((_front, back)) = &mut self.buffers { // Block if back buffer not released yet diff --git a/src/backends/web.rs b/src/backends/web.rs index 3733fdd3..2fc3b267 100644 --- a/src/backends/web.rs +++ b/src/backends/web.rs @@ -181,7 +181,7 @@ impl SurfaceInterface for WebImpl Ok(()) } - fn buffer_mut(&mut self) -> Result, SoftBufferError> { + fn next_buffer(&mut self) -> Result, SoftBufferError> { Ok(BufferImpl { canvas: &self.canvas, buffer: &mut self.buffer, diff --git a/src/backends/win32.rs b/src/backends/win32.rs index 88066057..b5873b17 100644 --- a/src/backends/win32.rs +++ b/src/backends/win32.rs @@ -220,11 +220,11 @@ impl SurfaceInterface for Win32Im Ok(()) } - fn buffer_mut(&mut self) -> Result, SoftBufferError> { + fn next_buffer(&mut self) -> Result, SoftBufferError> { let buffer = self .buffer .as_mut() - .expect("Must set size of surface before calling `buffer_mut()`"); + .expect("Must set size of surface before calling `next_buffer()`"); Ok(BufferImpl { window: &self.window, diff --git a/src/backends/x11.rs b/src/backends/x11.rs index 8a7365ae..cc3f7a64 100644 --- a/src/backends/x11.rs +++ b/src/backends/x11.rs @@ -344,13 +344,13 @@ impl SurfaceInterface fo Ok(()) } - fn buffer_mut(&mut self) -> Result, SoftBufferError> { - tracing::trace!("buffer_mut: window={:X}", self.window); + fn next_buffer(&mut self) -> Result, SoftBufferError> { + tracing::trace!("next_buffer: window={:X}", self.window); // Finish waiting on the previous `shm::PutImage` request, if any. self.buffer.finish_wait(self.display.connection())?; - // We can now safely call `buffer_mut` on the buffer. + // We can now safely call `next_buffer` on the buffer. Ok(BufferImpl { connection: self.display.connection(), window: self.window, @@ -433,8 +433,8 @@ impl BufferInterface for BufferImpl<'_> { #[inline] fn pixels_mut(&mut self) -> &mut [Pixel] { - // SAFETY: We called `finish_wait` on the buffer, so it is safe to call `buffer_mut`. - unsafe { self.buffer.buffer_mut() } + // SAFETY: We called `finish_wait` on the buffer. + unsafe { self.buffer.as_mut() } } fn age(&self) -> u8 { @@ -569,7 +569,7 @@ impl Buffer { /// /// `finish_wait()` must be called in between `shm::PutImage` requests and this function. #[inline] - unsafe fn buffer_mut(&mut self) -> &mut [Pixel] { + unsafe fn as_mut(&mut self) -> &mut [Pixel] { match self { Buffer::Shm(ref mut shm) => unsafe { shm.as_mut() }, Buffer::Wire(wire) => wire, diff --git a/src/lib.rs b/src/lib.rs index 83caa7f0..7f3973ee 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -115,7 +115,7 @@ impl Surface { self.surface_impl.window() } - /// Set the size of the buffer that will be returned by [`Surface::buffer_mut`]. + /// Set the size of the buffer that will be returned by [`Surface::next_buffer()`]. /// /// If the size of the buffer does not match the size of the window, the buffer is drawn /// in the upper-left corner of the window. It is recommended in most production use cases @@ -153,8 +153,8 @@ impl Surface { /// - On DRM/KMS, there is no reliable and sound way to wait for the page flip to happen from within /// `softbuffer`. Therefore it is the responsibility of the user to wait for the page flip before /// sending another frame. - pub fn buffer_mut(&mut self) -> Result, SoftBufferError> { - let mut buffer_impl = self.surface_impl.buffer_mut()?; + pub fn next_buffer(&mut self) -> Result, SoftBufferError> { + let mut buffer_impl = self.surface_impl.next_buffer()?; debug_assert_eq!( buffer_impl.byte_stride().get() % 4, @@ -176,6 +176,12 @@ impl Surface { _marker: PhantomData, }) } + + /// Rename to [`Surface::next_buffer()`]. + #[deprecated = "renamed to `next_buffer()`"] + pub fn buffer_mut(&mut self) -> Result, SoftBufferError> { + self.next_buffer() + } } impl AsRef for Surface { @@ -369,7 +375,7 @@ impl Buffer<'_> { /// /// # let buffer: softbuffer::Buffer<'_> = todo!(); /// # #[cfg(false)] - /// let buffer = surface.buffer_mut(); + /// let buffer = surface.next_buffer(); /// /// let width = buffer.width().get(); /// let height = buffer.height().get();