Skip to content

Commit f36d455

Browse files
Desktop: Only rerender the UI if it has changed (#3688)
* Only rerender ui if it has changed * Don't immedeatly request new frame at the end of the event loop * Request redraw after ui update * Always request redraw after timeout * Fix setting control flow in all cases * Remove comment --------- Co-authored-by: Timon <me@timon.zip>
1 parent 2e29777 commit f36d455

File tree

2 files changed

+26
-7
lines changed

2 files changed

+26
-7
lines changed

desktop/src/app.rs

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use std::thread;
66
use std::time::{Duration, Instant};
77
use winit::application::ApplicationHandler;
88
use winit::dpi::{PhysicalPosition, PhysicalSize};
9-
use winit::event::{ButtonSource, ElementState, MouseButton, WindowEvent};
9+
use winit::event::{ButtonSource, ElementState, MouseButton, StartCause, WindowEvent};
1010
use winit::event_loop::{ActiveEventLoop, ControlFlow, EventLoop};
1111
use winit::window::WindowId;
1212

@@ -260,6 +260,9 @@ impl App {
260260
if let Some(render_state) = &mut self.render_state {
261261
render_state.set_overlays_scene(scene);
262262
}
263+
if let Some(window) = &self.window {
264+
window.request_redraw();
265+
}
263266
}
264267
DesktopFrontendMessage::PersistenceWriteDocument { id, document } => {
265268
self.persistent_data.write_document(id, document);
@@ -632,10 +635,17 @@ impl ApplicationHandler for App {
632635
}
633636
}
634637

638+
fn new_events(&mut self, event_loop: &dyn ActiveEventLoop, cause: winit::event::StartCause) {
639+
if let StartCause::ResumeTimeReached { .. } = cause
640+
&& let Some(window) = &self.window
641+
{
642+
window.request_redraw();
643+
}
644+
}
645+
635646
fn about_to_wait(&mut self, event_loop: &dyn ActiveEventLoop) {
636647
// Set a timeout in case we miss any cef schedule requests
637-
let timeout = Instant::now() + Duration::from_millis(10);
638-
let wait_until = timeout.min(self.cef_schedule.unwrap_or(timeout));
648+
let mut wait_until = Instant::now() + Duration::from_millis(10);
639649
if let Some(schedule) = self.cef_schedule
640650
&& schedule < Instant::now()
641651
{
@@ -644,11 +654,9 @@ impl ApplicationHandler for App {
644654
for _ in 0..CEF_MESSAGE_LOOP_MAX_ITERATIONS {
645655
self.cef_context.work();
646656
}
657+
} else if let Some(cef_schedule) = self.cef_schedule {
658+
wait_until = wait_until.min(cef_schedule);
647659
}
648-
if let Some(window) = &self.window.as_ref() {
649-
window.request_redraw();
650-
}
651-
652660
event_loop.set_control_flow(ControlFlow::WaitUntil(wait_until));
653661
}
654662
}

desktop/src/render/state.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ pub(crate) struct RenderState {
2323
bind_group: Option<wgpu::BindGroup>,
2424
#[derivative(Debug = "ignore")]
2525
overlays_scene: Option<vello::Scene>,
26+
surface_outdated: bool,
2627
}
2728

2829
impl RenderState {
@@ -186,6 +187,7 @@ impl RenderState {
186187
ui_texture: None,
187188
bind_group: None,
188189
overlays_scene: None,
190+
surface_outdated: true,
189191
}
190192
}
191193

@@ -196,6 +198,7 @@ impl RenderState {
196198

197199
self.desired_width = width;
198200
self.desired_height = height;
201+
self.surface_outdated = true;
199202

200203
if width > 0 && height > 0 && (self.config.width != width || self.config.height != height) {
201204
self.config.width = width;
@@ -215,14 +218,17 @@ impl RenderState {
215218
}
216219

217220
pub(crate) fn set_viewport_scale(&mut self, scale: [f32; 2]) {
221+
self.surface_outdated = true;
218222
self.viewport_scale = scale;
219223
}
220224

221225
pub(crate) fn set_viewport_offset(&mut self, offset: [f32; 2]) {
226+
self.surface_outdated = true;
222227
self.viewport_offset = offset;
223228
}
224229

225230
pub(crate) fn set_overlays_scene(&mut self, scene: vello::Scene) {
231+
self.surface_outdated = true;
226232
self.overlays_scene = Some(scene);
227233
}
228234

@@ -241,6 +247,9 @@ impl RenderState {
241247
}
242248

243249
pub(crate) fn render(&mut self, window: &Window) -> Result<(), RenderError> {
250+
if !self.surface_outdated {
251+
return Ok(());
252+
}
244253
let ui_scale = if let Some(ui_texture) = &self.ui_texture
245254
&& (self.desired_width != ui_texture.width() || self.desired_height != ui_texture.height())
246255
{
@@ -302,11 +311,13 @@ impl RenderState {
302311
if ui_scale.is_some() {
303312
return Err(RenderError::OutdatedUITextureError);
304313
}
314+
self.surface_outdated = false;
305315

306316
Ok(())
307317
}
308318

309319
fn update_bindgroup(&mut self) {
320+
self.surface_outdated = true;
310321
let viewport_texture_view = self.viewport_texture.as_ref().unwrap_or(&self.transparent_texture).create_view(&wgpu::TextureViewDescriptor::default());
311322
let overlays_texture_view = self
312323
.overlays_texture

0 commit comments

Comments
 (0)