From 55bcaa8527335c4b5e9b2672f0d85dc621f0b1f1 Mon Sep 17 00:00:00 2001 From: Vladyslav Batyrenko Date: Sat, 24 Apr 2021 14:28:49 +0300 Subject: [PATCH] Fix crashes related to invalid scissor or window size (#18) Co-authored-by: Stephan Buys --- src/egui_node.rs | 27 ++++++++++++++++++++------- src/systems.rs | 19 +++++++++++-------- 2 files changed, 31 insertions(+), 15 deletions(-) diff --git a/src/egui_node.rs b/src/egui_node.rs index 960762f33..11d49b342 100644 --- a/src/egui_node.rs +++ b/src/egui_node.rs @@ -152,7 +152,7 @@ impl EguiNode { struct DrawCommand { vertices_count: usize, texture_handle: Option>, - clipping_zone: egui::Rect, + clipping_zone: (u32, u32, u32, u32), // x, y, w, h } impl Node for EguiNode { @@ -227,7 +227,19 @@ impl Node for EguiNode { let mut draw_commands = Vec::new(); let mut index_offset = 0; + let scale_factor = window_size.scale_factor * egui_settings.scale_factor as f32; for egui::ClippedMesh(rect, triangles) in &egui_paint_jobs { + let (x, y, w, h) = ( + (rect.min.x * scale_factor).round() as u32, + (rect.min.y * scale_factor).round() as u32, + (rect.width() * scale_factor).round() as u32, + (rect.height() * scale_factor).round() as u32, + ); + + if w < 1 || h < 1 { + continue; + } + let texture_handle = egui_context .egui_textures .get(&triangles.texture_id) @@ -254,10 +266,12 @@ impl Node for EguiNode { index_buffer.extend_from_slice(indices_with_offset.as_slice().as_bytes()); index_offset += triangles.vertices.len() as u32; + let x_viewport_clamp = (x + w).saturating_sub(window_size.physical_width as u32); + let y_viewport_clamp = (y + h).saturating_sub(window_size.physical_height as u32); draw_commands.push(DrawCommand { vertices_count: triangles.indices.len(), texture_handle, - clipping_zone: *rect, + clipping_zone: (x, y, w - x_viewport_clamp, h - y_viewport_clamp), }); } @@ -309,12 +323,11 @@ impl Node for EguiNode { None, ); - let scale_factor = window_size.scale_factor * egui_settings.scale_factor as f32; render_pass.set_scissor_rect( - (draw_command.clipping_zone.min.x * scale_factor) as u32, - (draw_command.clipping_zone.min.y * scale_factor) as u32, - (draw_command.clipping_zone.width() * scale_factor) as u32, - (draw_command.clipping_zone.height() * scale_factor) as u32, + draw_command.clipping_zone.0, + draw_command.clipping_zone.1, + draw_command.clipping_zone.2, + draw_command.clipping_zone.3, ); render_pass.draw_indexed( vertex_offset..(vertex_offset + draw_command.vertices_count as u32), diff --git a/src/systems.rs b/src/systems.rs index a64d3620a..34819e0be 100644 --- a/src/systems.rs +++ b/src/systems.rs @@ -71,17 +71,20 @@ pub fn process_input( window.physical_height() as f32, window.scale_factor() as f32, ); + let width = window_size.physical_width + / window_size.scale_factor + / egui_settings.scale_factor as f32; + let height = window_size.physical_height + / window_size.scale_factor + / egui_settings.scale_factor as f32; + + if width < 1.0 || height < 1.0 { + continue; + } egui_input.raw_input.screen_rect = Some(egui::Rect::from_min_max( egui::pos2(0.0, 0.0), - egui::pos2( - window_size.physical_width - / window_size.scale_factor - / egui_settings.scale_factor as f32, - window_size.physical_height - / window_size.scale_factor - / egui_settings.scale_factor as f32, - ), + egui::pos2(width, height), )); egui_input.raw_input.pixels_per_point =