diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index abd30a2..db67202 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -25,25 +25,13 @@ jobs: - name: Run Typos run: typos - miri-tests: - runs-on: ubuntu-latest - needs: fmt - steps: - - uses: actions/checkout@v4 - - uses: hecrj/setup-rust-action@v2 - with: - rust-version: nightly - components: miri - - name: Run tests with miri - run: cargo +nightly miri test - tests: name: Tests needs: fmt strategy: fail-fast: false matrix: - rust_version: ['1.65.0', stable, nightly] + rust_version: ['1.70.0', stable, nightly] platform: - { target: x86_64-pc-windows-msvc, os: windows-latest, } - { target: i686-pc-windows-msvc, os: windows-latest, } @@ -98,7 +86,7 @@ jobs: run: sudo apt-get install gcc-multilib - name: Pin deps that break MSRV - if: matrix.rust_version == '1.65.0' + if: matrix.rust_version == '1.70.0' run: | cargo update -p exr --precise 1.71.0 cargo update -p ahash --precise 0.8.7 diff --git a/CHANGELOG.md b/CHANGELOG.md index 78d5ab5..cb1eda1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,7 @@ # Unreleased +- Bump MSRV to 1.70.0. + # 0.4.2 - Add the ability to get the underlying window handle. (#193) diff --git a/Cargo.toml b/Cargo.toml index 4c11de1..e433f4b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,7 +10,7 @@ repository = "https://github.com/rust-windowing/softbuffer" keywords = ["framebuffer", "windowing"] categories = ["game-development", "graphics", "gui", "multimedia", "rendering"] exclude = ["examples"] -rust-version = "1.65.0" +rust-version = "1.70.0" [[bench]] name = "buffer_mut" @@ -78,9 +78,8 @@ cfg_aliases = "0.2.0" [dev-dependencies] colorous = "1.0.12" criterion = { version = "0.4.0", default-features = false, features = ["cargo_bench_support"] } -instant = "0.1.12" -winit = "0.29.2" -winit-test = "0.1.0" +web-time = "1.0.0" +winit = "0.30.0" [dev-dependencies.image] version = "0.24.6" @@ -104,11 +103,6 @@ members = [ "run-wasm", ] -[[test]] -name = "present_and_fetch" -path = "tests/present_and_fetch.rs" -harness = false - [package.metadata.docs.rs] all-features = true rustdoc-args = ["--cfg", "docsrs"] diff --git a/README.md b/README.md index da9adb1..169b958 100644 --- a/README.md +++ b/README.md @@ -62,15 +62,24 @@ use std::num::NonZeroU32; use std::rc::Rc; use winit::event::{Event, WindowEvent}; use winit::event_loop::{ControlFlow, EventLoop}; -use winit::window::WindowBuilder; +use winit::window::Window; + +include!("../examples/utils/winit_app.rs"); fn main() { let event_loop = EventLoop::new().unwrap(); - let window = Rc::new(WindowBuilder::new().build(&event_loop).unwrap()); - let context = softbuffer::Context::new(window.clone()).unwrap(); - let mut surface = softbuffer::Surface::new(&context, window.clone()).unwrap(); - event_loop.run(move |event, elwt| { + let mut app = winit_app::WinitAppBuilder::with_init(|elwt| { + let window = { + let window = elwt.create_window(Window::default_attributes()); + Rc::new(window.unwrap()) + }; + let context = softbuffer::Context::new(window.clone()).unwrap(); + let surface = softbuffer::Surface::new(&context, window.clone()).unwrap(); + + (window, surface) + }).with_event_handler(|state, event, elwt| { + let (window, surface) = state; elwt.set_control_flow(ControlFlow::Wait); match event { @@ -107,7 +116,9 @@ fn main() { } _ => {} } - }).unwrap(); + }); + + event_loop.run_app(&mut app).unwrap(); } ``` diff --git a/benches/buffer_mut.rs b/benches/buffer_mut.rs index b2a29cd..beaea99 100644 --- a/benches/buffer_mut.rs +++ b/benches/buffer_mut.rs @@ -1,3 +1,5 @@ +#![allow(deprecated)] // TODO + use criterion::{criterion_group, criterion_main, Criterion}; fn buffer_mut(c: &mut Criterion) { @@ -16,9 +18,8 @@ fn buffer_mut(c: &mut Criterion) { use winit::platform::run_on_demand::EventLoopExtRunOnDemand; let mut evl = winit::event_loop::EventLoop::new().unwrap(); - let window = winit::window::WindowBuilder::new() - .with_visible(false) - .build(&evl) + let window = evl + .create_window(winit::window::Window::default_attributes().with_visible(false)) .unwrap(); evl.run_on_demand(move |ev, elwt| { diff --git a/build.rs b/build.rs index 63c5f02..9f046eb 100644 --- a/build.rs +++ b/build.rs @@ -1,4 +1,9 @@ fn main() { + println!("cargo:rustc-check-cfg=cfg(free_unix)"); + println!("cargo:rustc-check-cfg=cfg(kms_platform)"); + println!("cargo:rustc-check-cfg=cfg(x11_platform)"); + println!("cargo:rustc-check-cfg=cfg(wayland_platform)"); + cfg_aliases::cfg_aliases! { free_unix: { all(unix, not(any(target_vendor = "apple", target_os = "android", target_os = "redox"))) }, kms_platform: { all(feature = "kms", free_unix, not(target_arch = "wasm32")) }, diff --git a/examples/animation.rs b/examples/animation.rs index 5782b0f..7c2e22c 100644 --- a/examples/animation.rs +++ b/examples/animation.rs @@ -1,89 +1,81 @@ -use instant::Instant; #[cfg(not(target_arch = "wasm32"))] use rayon::prelude::*; use std::f64::consts::PI; use std::num::NonZeroU32; -use std::rc::Rc; +use web_time::Instant; use winit::event::{Event, KeyEvent, WindowEvent}; use winit::event_loop::{ControlFlow, EventLoop}; use winit::keyboard::{Key, NamedKey}; -use winit::window::WindowBuilder; + +include!("./utils/winit_app.rs"); fn main() { let event_loop = EventLoop::new().unwrap(); - let window = Rc::new(WindowBuilder::new().build(&event_loop).unwrap()); + let start = Instant::now(); - #[cfg(target_arch = "wasm32")] - { - use winit::platform::web::WindowExtWebSys; + let app = winit_app::WinitAppBuilder::with_init(|event_loop| { + let window = winit_app::make_window(event_loop, |w| w); - web_sys::window() - .unwrap() - .document() - .unwrap() - .body() - .unwrap() - .append_child(&window.canvas().unwrap()) - .unwrap(); - } + let context = softbuffer::Context::new(window.clone()).unwrap(); + let surface = softbuffer::Surface::new(&context, window.clone()).unwrap(); - let context = softbuffer::Context::new(window.clone()).unwrap(); - let mut surface = softbuffer::Surface::new(&context, window.clone()).unwrap(); + let old_size = (0, 0); + let frames = pre_render_frames(0, 0); - let mut old_size = (0, 0); - let mut frames = pre_render_frames(0, 0); + (window, surface, old_size, frames) + }) + .with_event_handler(move |state, event, elwt| { + let (window, surface, old_size, frames) = state; - let start = Instant::now(); - event_loop - .run(move |event, elwt| { - elwt.set_control_flow(ControlFlow::Poll); - - match event { - Event::WindowEvent { - window_id, - event: WindowEvent::RedrawRequested, - } if window_id == window.id() => { - if let (Some(width), Some(height)) = { - let size = window.inner_size(); - (NonZeroU32::new(size.width), NonZeroU32::new(size.height)) - } { - 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 frame = &frames[((elapsed * 60.0).round() as usize).clamp(0, 59)]; - - surface.resize(width, height).unwrap(); - let mut buffer = surface.buffer_mut().unwrap(); - buffer.copy_from_slice(frame); - buffer.present().unwrap(); - } - } - Event::AboutToWait => { - window.request_redraw(); - } - Event::WindowEvent { - event: - WindowEvent::CloseRequested - | WindowEvent::KeyboardInput { - event: - KeyEvent { - logical_key: Key::Named(NamedKey::Escape), - .. - }, - .. - }, - window_id, - } if window_id == window.id() => { - elwt.exit(); + elwt.set_control_flow(ControlFlow::Poll); + + match event { + Event::WindowEvent { + window_id, + event: WindowEvent::RedrawRequested, + } if window_id == window.id() => { + if let (Some(width), Some(height)) = { + let size = window.inner_size(); + (NonZeroU32::new(size.width), NonZeroU32::new(size.height)) + } { + 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 frame = &frames[((elapsed * 60.0).round() as usize).clamp(0, 59)]; + + surface.resize(width, height).unwrap(); + let mut buffer = surface.buffer_mut().unwrap(); + buffer.copy_from_slice(frame); + buffer.present().unwrap(); } - _ => {} } - }) - .unwrap(); + Event::AboutToWait => { + window.request_redraw(); + } + Event::WindowEvent { + event: + WindowEvent::CloseRequested + | WindowEvent::KeyboardInput { + event: + KeyEvent { + logical_key: Key::Named(NamedKey::Escape), + .. + }, + .. + }, + window_id, + } if window_id == window.id() => { + elwt.exit(); + } + _ => {} + } + }); + + winit_app::run_app(event_loop, app); } fn pre_render_frames(width: usize, height: usize) -> Vec> { diff --git a/examples/fruit.rs b/examples/fruit.rs index 10ae107..6109216 100644 --- a/examples/fruit.rs +++ b/examples/fruit.rs @@ -1,86 +1,75 @@ use image::GenericImageView; use std::num::NonZeroU32; -use std::rc::Rc; use winit::event::{Event, KeyEvent, WindowEvent}; use winit::event_loop::{ControlFlow, EventLoop}; use winit::keyboard::{Key, NamedKey}; -use winit::window::WindowBuilder; + +include!("utils/winit_app.rs"); fn main() { //see fruit.jpg.license for the license of fruit.jpg let fruit = image::load_from_memory(include_bytes!("fruit.jpg")).unwrap(); + let (width, height) = (fruit.width(), fruit.height()); let event_loop = EventLoop::new().unwrap(); - let window = Rc::new( - WindowBuilder::new() - .with_inner_size(winit::dpi::PhysicalSize::new(fruit.width(), fruit.height())) - .build(&event_loop) - .unwrap(), - ); - - #[cfg(target_arch = "wasm32")] - { - use winit::platform::web::WindowExtWebSys; - web_sys::window() - .unwrap() - .document() - .unwrap() - .body() - .unwrap() - .append_child(&window.canvas().unwrap()) - .unwrap(); - } + let app = winit_app::WinitAppBuilder::with_init(move |elwt| { + let window = winit_app::make_window(elwt, |w| { + w.with_inner_size(winit::dpi::PhysicalSize::new(width, height)) + }); - let context = softbuffer::Context::new(window.clone()).unwrap(); - let mut surface = softbuffer::Surface::new(&context, window.clone()).unwrap(); + let context = softbuffer::Context::new(window.clone()).unwrap(); + let surface = softbuffer::Surface::new(&context, window.clone()).unwrap(); - event_loop - .run(move |event, elwt| { - elwt.set_control_flow(ControlFlow::Wait); + (window, surface) + }) + .with_event_handler(move |state, event, elwt| { + let (window, surface) = state; + elwt.set_control_flow(ControlFlow::Wait); - match event { - Event::WindowEvent { - window_id, - event: WindowEvent::RedrawRequested, - } if window_id == window.id() => { - surface - .resize( - NonZeroU32::new(fruit.width()).unwrap(), - NonZeroU32::new(fruit.height()).unwrap(), - ) - .unwrap(); + match event { + Event::WindowEvent { + window_id, + event: WindowEvent::RedrawRequested, + } if window_id == window.id() => { + surface + .resize( + NonZeroU32::new(fruit.width()).unwrap(), + NonZeroU32::new(fruit.height()).unwrap(), + ) + .unwrap(); - let mut buffer = surface.buffer_mut().unwrap(); - let width = fruit.width() as usize; - 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 mut buffer = surface.buffer_mut().unwrap(); + let width = fruit.width() as usize; + 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.present().unwrap(); - } - Event::WindowEvent { - event: - WindowEvent::CloseRequested - | WindowEvent::KeyboardInput { - event: - KeyEvent { - logical_key: Key::Named(NamedKey::Escape), - .. - }, - .. - }, - window_id, - } if window_id == window.id() => { - elwt.exit(); + let color = blue | (green << 8) | (red << 16); + buffer[y as usize * width + x as usize] = color; } - _ => {} + + buffer.present().unwrap(); + } + Event::WindowEvent { + event: + WindowEvent::CloseRequested + | WindowEvent::KeyboardInput { + event: + KeyEvent { + logical_key: Key::Named(NamedKey::Escape), + .. + }, + .. + }, + window_id, + } if window_id == window.id() => { + elwt.exit(); } - }) - .unwrap(); + _ => {} + } + }); + + winit_app::run_app(event_loop, app); } diff --git a/examples/rectangle.rs b/examples/rectangle.rs index b7060af..76d1556 100644 --- a/examples/rectangle.rs +++ b/examples/rectangle.rs @@ -1,9 +1,9 @@ use std::num::NonZeroU32; -use std::rc::Rc; use winit::event::{ElementState, Event, KeyEvent, WindowEvent}; use winit::event_loop::{ControlFlow, EventLoop}; use winit::keyboard::{Key, NamedKey}; -use winit::window::WindowBuilder; + +include!("utils/winit_app.rs"); fn redraw(buffer: &mut [u32], width: usize, height: usize, flag: bool) { for y in 0..height { @@ -24,97 +24,85 @@ fn redraw(buffer: &mut [u32], width: usize, height: usize, flag: bool) { fn main() { let event_loop = EventLoop::new().unwrap(); - let window = Rc::new( - WindowBuilder::new() - .with_title("Press space to show/hide a rectangle") - .build(&event_loop) - .unwrap(), - ); - - #[cfg(target_arch = "wasm32")] - { - use winit::platform::web::WindowExtWebSys; - - web_sys::window() - .unwrap() - .document() - .unwrap() - .body() - .unwrap() - .append_child(&window.canvas().unwrap()) - .unwrap(); - } + let app = winit_app::WinitAppBuilder::with_init(|elwt| { + let window = winit_app::make_window(elwt, |w| { + w.with_title("Press space to show/hide a rectangle") + }); - let context = softbuffer::Context::new(window.clone()).unwrap(); - let mut surface = softbuffer::Surface::new(&context, window.clone()).unwrap(); + let context = softbuffer::Context::new(window.clone()).unwrap(); + let surface = softbuffer::Surface::new(&context, window.clone()).unwrap(); - let mut flag = false; + let flag = false; - event_loop - .run(move |event, elwt| { - elwt.set_control_flow(ControlFlow::Wait); + (window, surface, flag) + }) + .with_event_handler(|state, event, elwt| { + let (window, surface, flag) = state; - match event { - Event::WindowEvent { - window_id, - event: WindowEvent::RedrawRequested, - } if window_id == window.id() => { - // Grab the window's client area dimensions - if let (Some(width), Some(height)) = { - let size = window.inner_size(); - (NonZeroU32::new(size.width), NonZeroU32::new(size.height)) - } { - // Resize surface if needed - surface.resize(width, height).unwrap(); + elwt.set_control_flow(ControlFlow::Wait); - // 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(); - } - } + match event { + Event::WindowEvent { + window_id, + event: WindowEvent::RedrawRequested, + } if window_id == window.id() => { + // Grab the window's client area dimensions + if let (Some(width), Some(height)) = { + let size = window.inner_size(); + (NonZeroU32::new(size.width), NonZeroU32::new(size.height)) + } { + // Resize surface if needed + surface.resize(width, height).unwrap(); - Event::WindowEvent { - event: - WindowEvent::CloseRequested - | WindowEvent::KeyboardInput { - event: - KeyEvent { - logical_key: Key::Named(NamedKey::Escape), - .. - }, - .. - }, - window_id, - } if window_id == window.id() => { - elwt.exit(); + // 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(); } + } - Event::WindowEvent { - event: - WindowEvent::KeyboardInput { - event: - KeyEvent { - state: ElementState::Pressed, - logical_key: Key::Named(NamedKey::Space), - .. - }, - .. - }, - window_id, - } if window_id == window.id() => { - // Flip the rectangle flag and request a redraw to show the changed image - flag = !flag; - window.request_redraw(); - } + Event::WindowEvent { + event: + WindowEvent::CloseRequested + | WindowEvent::KeyboardInput { + event: + KeyEvent { + logical_key: Key::Named(NamedKey::Escape), + .. + }, + .. + }, + window_id, + } if window_id == window.id() => { + elwt.exit(); + } - _ => {} + Event::WindowEvent { + event: + WindowEvent::KeyboardInput { + event: + KeyEvent { + state: ElementState::Pressed, + logical_key: Key::Named(NamedKey::Space), + .. + }, + .. + }, + window_id, + } if window_id == window.id() => { + // Flip the rectangle flag and request a redraw to show the changed image + *flag = !*flag; + window.request_redraw(); } - }) - .unwrap(); + + _ => {} + } + }); + + winit_app::run_app(event_loop, app); } diff --git a/examples/utils/winit_app.rs b/examples/utils/winit_app.rs new file mode 100644 index 0000000..6e45d88 --- /dev/null +++ b/examples/utils/winit_app.rs @@ -0,0 +1,121 @@ +/// Common boilerplate for setting up a winit application. +mod winit_app { + use std::marker::PhantomData; + use std::rc::Rc; + + use winit::application::ApplicationHandler; + use winit::event::{Event, WindowEvent}; + use winit::event_loop::{EventLoop, ActiveEventLoop}; + use winit::window::{WindowAttributes, WindowId, Window}; + + /// Run a Winit application. + #[allow(unused_mut)] + pub(crate) fn run_app(event_loop: EventLoop<()>, mut app: impl ApplicationHandler<()> + 'static) { + #[cfg(not(any(target_arch = "wasm32", target_arch = "wasm64")))] + event_loop.run_app(&mut app).unwrap(); + + #[cfg(any(target_arch = "wasm32", target_arch = "wasm64"))] + winit::platform::web::EventLoopExtWebSys::spawn_app(event_loop, app); + } + + /// Create a window from a set of window attributes. + pub(crate) fn make_window(elwt: &ActiveEventLoop, f: impl FnOnce(WindowAttributes) -> WindowAttributes) -> Rc { + let attributes = f(WindowAttributes::default()); + #[cfg(target_arch = "wasm32")] + let attributes = winit::platform::web::WindowAttributesExtWebSys::with_append( + attributes, + true + ); + let window = elwt.create_window(attributes); + Rc::new(window.unwrap()) + } + + /// Easily constructable winit application. + pub(crate) struct WinitApp { + /// Closure to initialize state. + init: Init, + + /// Closure to run on window events. + event: Handler, + + /// Contained state. + state: Option + } + + /// Builder that makes it so we don't have to name `T`. + pub(crate) struct WinitAppBuilder { + /// Closure to initialize state. + init: Init, + + /// Eat the type parameter. + _marker: PhantomData>, + } + + impl WinitAppBuilder + where Init: FnMut(&ActiveEventLoop) -> T, + { + /// Create with an "init" closure. + pub(crate) fn with_init(init: Init) -> Self { + Self { + init, + _marker: PhantomData + } + } + + /// Build a new application. + pub(crate) fn with_event_handler(self, handler: F) -> WinitApp + where F: FnMut(&mut T, Event<()>, &ActiveEventLoop) + { + WinitApp::new(self.init, handler) + } + } + + impl WinitApp + where Init: FnMut(&ActiveEventLoop) -> T, + Handler: FnMut(&mut T, Event<()>, &ActiveEventLoop) + { + /// Create a new application. + pub(crate) fn new(init: Init, event: Handler) -> Self { + Self { + init, + event, + state: None + } + } + } + + impl ApplicationHandler for WinitApp + where Init: FnMut(&ActiveEventLoop) -> T, + Handler: FnMut(&mut T, Event<()>, &ActiveEventLoop) { + + fn resumed(&mut self, el: &ActiveEventLoop) { + debug_assert!(self.state.is_none()); + self.state = Some((self.init)(el)); + } + + fn suspended(&mut self, _event_loop: &ActiveEventLoop) { + let state = self.state.take(); + debug_assert!(state.is_some()); + drop(state); + } + + fn window_event( + &mut self, + event_loop: &ActiveEventLoop, + window_id: WindowId, + event: WindowEvent, + ) { + let state = self.state.as_mut().unwrap(); + (self.event)(state, Event::WindowEvent { + window_id, + event + }, event_loop); + } + + fn about_to_wait(&mut self, event_loop: &ActiveEventLoop) { + if let Some(state) = self.state.as_mut() { + (self.event)(state, Event::AboutToWait, event_loop); + } + } + } +} diff --git a/examples/winit.rs b/examples/winit.rs index 7c903e2..4bff0b3 100644 --- a/examples/winit.rs +++ b/examples/winit.rs @@ -1,77 +1,68 @@ use std::num::NonZeroU32; -use std::rc::Rc; use winit::event::{Event, KeyEvent, WindowEvent}; use winit::event_loop::{ControlFlow, EventLoop}; use winit::keyboard::{Key, NamedKey}; -use winit::window::WindowBuilder; + +include!("utils/winit_app.rs"); fn main() { let event_loop = EventLoop::new().unwrap(); - let window = Rc::new(WindowBuilder::new().build(&event_loop).unwrap()); - - #[cfg(target_arch = "wasm32")] - { - use winit::platform::web::WindowExtWebSys; - web_sys::window() - .unwrap() - .document() - .unwrap() - .body() - .unwrap() - .append_child(&window.canvas().unwrap()) - .unwrap(); - } + let app = winit_app::WinitAppBuilder::with_init(|elwt| { + let window = winit_app::make_window(elwt, |w| w); - let context = softbuffer::Context::new(window.clone()).unwrap(); - let mut surface = softbuffer::Surface::new(&context, window.clone()).unwrap(); + let context = softbuffer::Context::new(window.clone()).unwrap(); + let surface = softbuffer::Surface::new(&context, window.clone()).unwrap(); - event_loop - .run(move |event, elwt| { - elwt.set_control_flow(ControlFlow::Wait); + (window, surface) + }) + .with_event_handler(|state, event, elwt| { + let (window, surface) = state; + elwt.set_control_flow(ControlFlow::Wait); - match event { - Event::WindowEvent { - window_id, - event: WindowEvent::RedrawRequested, - } if window_id == window.id() => { - if let (Some(width), Some(height)) = { - let size = window.inner_size(); - (NonZeroU32::new(size.width), NonZeroU32::new(size.height)) - } { - surface.resize(width, height).unwrap(); + match event { + Event::WindowEvent { + window_id, + event: WindowEvent::RedrawRequested, + } if window_id == window.id() => { + if let (Some(width), Some(height)) = { + let size = window.inner_size(); + (NonZeroU32::new(size.width), NonZeroU32::new(size.height)) + } { + 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; - buffer[index] = blue | (green << 8) | (red << 16); - } + 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(); } + + buffer.present().unwrap(); } - Event::WindowEvent { - event: - WindowEvent::CloseRequested - | WindowEvent::KeyboardInput { - event: - KeyEvent { - logical_key: Key::Named(NamedKey::Escape), - .. - }, - .. - }, - window_id, - } if window_id == window.id() => { - elwt.exit(); - } - _ => {} } - }) - .unwrap(); + Event::WindowEvent { + event: + WindowEvent::CloseRequested + | WindowEvent::KeyboardInput { + event: + KeyEvent { + logical_key: Key::Named(NamedKey::Escape), + .. + }, + .. + }, + window_id, + } if window_id == window.id() => { + elwt.exit(); + } + _ => {} + } + }); + + winit_app::run_app(event_loop, app); } diff --git a/examples/winit_wrong_sized_buffer.rs b/examples/winit_wrong_sized_buffer.rs index 99f5944..3aa222d 100644 --- a/examples/winit_wrong_sized_buffer.rs +++ b/examples/winit_wrong_sized_buffer.rs @@ -1,80 +1,71 @@ use std::num::NonZeroU32; -use std::rc::Rc; use winit::event::{Event, KeyEvent, WindowEvent}; use winit::event_loop::{ControlFlow, EventLoop}; use winit::keyboard::{Key, NamedKey}; -use winit::window::WindowBuilder; + +include!("utils/winit_app.rs"); const BUFFER_WIDTH: usize = 256; const BUFFER_HEIGHT: usize = 128; fn main() { let event_loop = EventLoop::new().unwrap(); - let window = Rc::new(WindowBuilder::new().build(&event_loop).unwrap()); - - #[cfg(target_arch = "wasm32")] - { - use winit::platform::web::WindowExtWebSys; - web_sys::window() - .unwrap() - .document() - .unwrap() - .body() - .unwrap() - .append_child(&window.canvas().unwrap()) - .unwrap(); - } + let app = winit_app::WinitAppBuilder::with_init(|elwt| { + let window = winit_app::make_window(elwt, |w| w); - let context = softbuffer::Context::new(window.clone()).unwrap(); - let mut surface = softbuffer::Surface::new(&context, window.clone()).unwrap(); + let context = softbuffer::Context::new(window.clone()).unwrap(); + let surface = softbuffer::Surface::new(&context, window.clone()).unwrap(); - event_loop - .run(move |event, elwt| { - elwt.set_control_flow(ControlFlow::Wait); + (window, surface) + }) + .with_event_handler(|state, event, elwt| { + let (window, surface) = state; + elwt.set_control_flow(ControlFlow::Wait); - match event { - Event::WindowEvent { - window_id, - event: WindowEvent::RedrawRequested, - } if window_id == window.id() => { - surface - .resize( - NonZeroU32::new(BUFFER_WIDTH as u32).unwrap(), - NonZeroU32::new(BUFFER_HEIGHT as u32).unwrap(), - ) - .unwrap(); + match event { + Event::WindowEvent { + window_id, + event: WindowEvent::RedrawRequested, + } if window_id == window.id() => { + surface + .resize( + NonZeroU32::new(BUFFER_WIDTH as u32).unwrap(), + NonZeroU32::new(BUFFER_HEIGHT as u32).unwrap(), + ) + .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 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 color = blue | (green << 8) | (red << 16); - buffer[y * BUFFER_WIDTH + x] = color; - } + let color = blue | (green << 8) | (red << 16); + buffer[y * BUFFER_WIDTH + x] = color; } - buffer.present().unwrap(); - } - Event::WindowEvent { - event: - WindowEvent::CloseRequested - | WindowEvent::KeyboardInput { - event: - KeyEvent { - logical_key: Key::Named(NamedKey::Escape), - .. - }, - .. - }, - window_id, - } if window_id == window.id() => { - elwt.exit(); } - _ => {} + buffer.present().unwrap(); } - }) - .unwrap(); + Event::WindowEvent { + event: + WindowEvent::CloseRequested + | WindowEvent::KeyboardInput { + event: + KeyEvent { + logical_key: Key::Named(NamedKey::Escape), + .. + }, + .. + }, + window_id, + } if window_id == window.id() => { + elwt.exit(); + } + _ => {} + } + }); + + winit_app::run_app(event_loop, app); } diff --git a/tests/present_and_fetch.rs b/tests/present_and_fetch.rs deleted file mode 100644 index 9e87c04..0000000 --- a/tests/present_and_fetch.rs +++ /dev/null @@ -1,61 +0,0 @@ -// TODO: Once winit is updated again, restore this test. -/* -use softbuffer::{Context, Surface}; -use std::num::NonZeroU32; -use winit::event_loop::EventLoopWindowTarget; - -fn all_red(elwt: &EventLoopWindowTarget<()>) { - let window = winit::window::WindowBuilder::new() - .with_title("all_red") - .build(elwt) - .unwrap(); - - #[cfg(target_arch = "wasm32")] - { - use winit::platform::web::WindowExtWebSys; - - web_sys::window() - .unwrap() - .document() - .unwrap() - .body() - .unwrap() - .append_child(&window.canvas()) - .unwrap(); - } - - // winit does not wait for the window to be mapped... sigh - #[cfg(not(target_arch = "wasm32"))] - std::thread::sleep(std::time::Duration::from_millis(1)); - - let context = Context::new(elwt).unwrap(); - let mut surface = Surface::new(&context, &window).unwrap(); - let size = window.inner_size(); - - // Set the size of the surface to the size of the window. - surface - .resize( - NonZeroU32::new(size.width).unwrap(), - NonZeroU32::new(size.height).unwrap(), - ) - .unwrap(); - - // Set all pixels to red. - let mut buffer = surface.buffer_mut().unwrap(); - buffer.fill(0x00FF0000); - buffer.present().unwrap(); - - // Check that all pixels are red. - let screen_contents = match surface.fetch() { - Err(softbuffer::SoftBufferError::Unimplemented) => return, - cont => cont.unwrap(), - }; - for pixel in screen_contents.iter() { - assert_eq!(*pixel, 0x00FF0000); - } -} - -winit_test::main!(all_red); -*/ - -fn main() {}