diff --git a/desktop/src/app.rs b/desktop/src/app.rs index c21df6f895..042395831a 100644 --- a/desktop/src/app.rs +++ b/desktop/src/app.rs @@ -6,7 +6,7 @@ use std::thread; use std::time::{Duration, Instant}; use winit::application::ApplicationHandler; use winit::dpi::{PhysicalPosition, PhysicalSize}; -use winit::event::{ButtonSource, ElementState, MouseButton, WindowEvent}; +use winit::event::{ButtonSource, ElementState, MouseButton, StartCause, WindowEvent}; use winit::event_loop::{ActiveEventLoop, ControlFlow, EventLoop}; use winit::window::WindowId; @@ -260,6 +260,9 @@ impl App { if let Some(render_state) = &mut self.render_state { render_state.set_overlays_scene(scene); } + if let Some(window) = &self.window { + window.request_redraw(); + } } DesktopFrontendMessage::PersistenceWriteDocument { id, document } => { self.persistent_data.write_document(id, document); @@ -632,10 +635,17 @@ impl ApplicationHandler for App { } } + fn new_events(&mut self, event_loop: &dyn ActiveEventLoop, cause: winit::event::StartCause) { + if let StartCause::ResumeTimeReached { .. } = cause + && let Some(window) = &self.window + { + window.request_redraw(); + } + } + fn about_to_wait(&mut self, event_loop: &dyn ActiveEventLoop) { // Set a timeout in case we miss any cef schedule requests - let timeout = Instant::now() + Duration::from_millis(10); - let wait_until = timeout.min(self.cef_schedule.unwrap_or(timeout)); + let mut wait_until = Instant::now() + Duration::from_millis(10); if let Some(schedule) = self.cef_schedule && schedule < Instant::now() { @@ -644,11 +654,9 @@ impl ApplicationHandler for App { for _ in 0..CEF_MESSAGE_LOOP_MAX_ITERATIONS { self.cef_context.work(); } + } else if let Some(cef_schedule) = self.cef_schedule { + wait_until = wait_until.min(cef_schedule); } - if let Some(window) = &self.window.as_ref() { - window.request_redraw(); - } - event_loop.set_control_flow(ControlFlow::WaitUntil(wait_until)); } } diff --git a/desktop/src/render/state.rs b/desktop/src/render/state.rs index 19b4b40247..81808cc7ca 100644 --- a/desktop/src/render/state.rs +++ b/desktop/src/render/state.rs @@ -23,6 +23,7 @@ pub(crate) struct RenderState { bind_group: Option, #[derivative(Debug = "ignore")] overlays_scene: Option, + surface_outdated: bool, } impl RenderState { @@ -186,6 +187,7 @@ impl RenderState { ui_texture: None, bind_group: None, overlays_scene: None, + surface_outdated: true, } } @@ -196,6 +198,7 @@ impl RenderState { self.desired_width = width; self.desired_height = height; + self.surface_outdated = true; if width > 0 && height > 0 && (self.config.width != width || self.config.height != height) { self.config.width = width; @@ -215,14 +218,17 @@ impl RenderState { } pub(crate) fn set_viewport_scale(&mut self, scale: [f32; 2]) { + self.surface_outdated = true; self.viewport_scale = scale; } pub(crate) fn set_viewport_offset(&mut self, offset: [f32; 2]) { + self.surface_outdated = true; self.viewport_offset = offset; } pub(crate) fn set_overlays_scene(&mut self, scene: vello::Scene) { + self.surface_outdated = true; self.overlays_scene = Some(scene); } @@ -241,6 +247,9 @@ impl RenderState { } pub(crate) fn render(&mut self, window: &Window) -> Result<(), RenderError> { + if !self.surface_outdated { + return Ok(()); + } let ui_scale = if let Some(ui_texture) = &self.ui_texture && (self.desired_width != ui_texture.width() || self.desired_height != ui_texture.height()) { @@ -302,11 +311,13 @@ impl RenderState { if ui_scale.is_some() { return Err(RenderError::OutdatedUITextureError); } + self.surface_outdated = false; Ok(()) } fn update_bindgroup(&mut self) { + self.surface_outdated = true; let viewport_texture_view = self.viewport_texture.as_ref().unwrap_or(&self.transparent_texture).create_view(&wgpu::TextureViewDescriptor::default()); let overlays_texture_view = self .overlays_texture