softbuffer/examples/winit.rs
Ian Douglas Scott edc5c76180 examples: Avoid dividing index to get x, y; calculate index from x, y
Division is more expensive than multiplication, and this doesn't seem to
be optimize away, so iterating over `(0..height)` and `(0..width)`
provides better performance.

It's good to have the example show the best way to write code using
softbuffer, and this helps when using examples as a benchmark. This will
also be needed if Softbuffer supports formats where `stride` isn't just
`width * pixel_size`, and needs alignment.
2023-04-11 12:21:50 -07:00

66 lines
2.1 KiB
Rust

use std::num::NonZeroU32;
use winit::event::{Event, WindowEvent};
use winit::event_loop::{ControlFlow, EventLoop};
use winit::window::WindowBuilder;
fn main() {
let event_loop = EventLoop::new();
let window = 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();
}
let context = unsafe { softbuffer::Context::new(&window) }.unwrap();
let mut surface = unsafe { softbuffer::Surface::new(&context, &window) }.unwrap();
event_loop.run(move |event, _, control_flow| {
*control_flow = ControlFlow::Wait;
match event {
Event::RedrawRequested(window_id) if window_id == window.id() => {
let (width, height) = {
let size = window.inner_size();
(size.width, size.height)
};
surface
.resize(
NonZeroU32::new(width).unwrap(),
NonZeroU32::new(height).unwrap(),
)
.unwrap();
let mut buffer = surface.buffer_mut().unwrap();
for y in 0..height {
for x in 0..width {
let red = x % 255;
let green = y % 255;
let blue = (x * y) % 255;
let index = y as usize * width as usize + x as usize;
buffer[index] = blue | (green << 8) | (red << 16);
}
}
buffer.present().unwrap();
}
Event::WindowEvent {
event: WindowEvent::CloseRequested,
window_id,
} if window_id == window.id() => {
*control_flow = ControlFlow::Exit;
}
_ => {}
}
});
}