Validate width and height inputs (#162)

* Validate width and height inputs

- Fixes #157

* Add window size check to `imgui-winit` demo

- There is really nothing better that can be done in this case.
- The surface, buffer, and world sizes must all be non-zero.
- A zero-length surface would (previously) panic in `wgpu`.
- A zero-length buffer would panic with the new assertions.
- A zero-length world would cause a divide-by-zero panic when drawing.
This commit is contained in:
Jay Oster 2021-05-08 17:26:21 -07:00 committed by GitHub
parent f238814d12
commit cdcfe57868
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 20 additions and 7 deletions

View file

@ -100,13 +100,15 @@ fn main() -> Result<(), Error> {
// Resize the window // Resize the window
if let Some(size) = input.window_resized() { if let Some(size) = input.window_resized() {
// Resize the surface texture if size.width > 0 && size.height > 0 {
pixels.resize_surface(size.width, size.height); // Resize the surface texture
pixels.resize_surface(size.width, size.height);
// Resize the world // Resize the world
let LogicalSize { width, height } = size.to_logical(scale_factor); let LogicalSize { width, height } = size.to_logical(scale_factor);
world.resize(width, height); world.resize(width, height);
pixels.resize_buffer(width, height); pixels.resize_buffer(width, height);
}
} }
// Update internal state and request a redraw // Update internal state and request a redraw

View file

@ -203,7 +203,14 @@ impl Pixels {
/// ///
/// Call this method to change the virtual screen resolution. E.g. when you want your pixel /// Call this method to change the virtual screen resolution. E.g. when you want your pixel
/// buffer to be resized from `640x480` to `800x600`. /// buffer to be resized from `640x480` to `800x600`.
///
/// # Panics
///
/// Panics when `width` or `height` are 0.
pub fn resize_buffer(&mut self, width: u32, height: u32) { pub fn resize_buffer(&mut self, width: u32, height: u32) {
assert!(width > 0);
assert!(height > 0);
// Recreate the backing texture // Recreate the backing texture
let (scaling_matrix_inverse, texture_extent, texture, scaling_renderer, pixels_buffer_size) = let (scaling_matrix_inverse, texture_extent, texture, scaling_renderer, pixels_buffer_size) =
builder::create_backing_texture( builder::create_backing_texture(
@ -237,8 +244,12 @@ impl Pixels {
/// texture for non-integer scaling ratios. /// texture for non-integer scaling ratios.
/// ///
/// Call this method in response to a resize event from your window manager. The size expected /// Call this method in response to a resize event from your window manager. The size expected
/// is in physical pixel units. /// is in physical pixel units. Does nothing when `width` or `height` are 0.
pub fn resize_surface(&mut self, width: u32, height: u32) { pub fn resize_surface(&mut self, width: u32, height: u32) {
if width == 0 || height == 0 {
return;
}
// Update SurfaceTexture dimensions // Update SurfaceTexture dimensions
self.surface_size.width = width; self.surface_size.width = width;
self.surface_size.height = height; self.surface_size.height = height;