@@ -15,12 +15,12 @@ use graphite_editor::messages::prelude::*;
15
15
use std:: fs;
16
16
use std:: sync:: Arc ;
17
17
use std:: sync:: mpsc:: Sender ;
18
+ use std:: sync:: mpsc:: SyncSender ;
18
19
use std:: thread;
19
20
use std:: time:: Duration ;
20
21
use std:: time:: Instant ;
21
22
use winit:: application:: ApplicationHandler ;
22
23
use winit:: dpi:: PhysicalSize ;
23
- use winit:: event:: StartCause ;
24
24
use winit:: event:: WindowEvent ;
25
25
use winit:: event_loop:: ActiveEventLoop ;
26
26
use winit:: event_loop:: ControlFlow ;
@@ -41,10 +41,23 @@ pub(crate) struct WinitApp {
41
41
editor : Editor ,
42
42
last_ui_update : Instant ,
43
43
avg_frame_time : f32 ,
44
+ start_render_sender : SyncSender < ( ) > ,
44
45
}
45
46
46
47
impl WinitApp {
47
48
pub ( crate ) fn new ( cef_context : cef:: Context < cef:: Initialized > , window_size_sender : Sender < WindowSize > , wgpu_context : WgpuContext , event_loop_proxy : EventLoopProxy < CustomEvent > ) -> Self {
49
+ let rendering_loop_proxy = event_loop_proxy. clone ( ) ;
50
+ let ( start_render_sender, start_render_receiver) = std:: sync:: mpsc:: sync_channel ( 1 ) ;
51
+ std:: thread:: spawn ( move || {
52
+ loop {
53
+ let ( has_run, texture) = futures:: executor:: block_on ( graphite_editor:: node_graph_executor:: run_node_graph ( ) ) ;
54
+ if has_run {
55
+ let _ = rendering_loop_proxy. send_event ( CustomEvent :: NodeGraphRan ( texture. map ( |t| ( * t. texture ) . clone ( ) ) ) ) ;
56
+ }
57
+ let _ = start_render_receiver. recv ( ) ;
58
+ }
59
+ } ) ;
60
+
48
61
Self {
49
62
cef_context,
50
63
window : None ,
@@ -56,6 +69,7 @@ impl WinitApp {
56
69
editor : Editor :: new ( ) ,
57
70
last_ui_update : Instant :: now ( ) ,
58
71
avg_frame_time : 0. ,
72
+ start_render_sender,
59
73
}
60
74
}
61
75
@@ -153,23 +167,20 @@ impl ApplicationHandler<CustomEvent> for WinitApp {
153
167
// Set a timeout in case we miss any cef schedule requests
154
168
let timeout = Instant :: now ( ) + Duration :: from_millis ( 10 ) ;
155
169
let wait_until = timeout. min ( self . cef_schedule . unwrap_or ( timeout) ) ;
156
- self . cef_context . work ( ) ;
157
-
158
- event_loop. set_control_flow ( ControlFlow :: WaitUntil ( wait_until) ) ;
159
- }
160
-
161
- fn new_events ( & mut self , _event_loop : & ActiveEventLoop , cause : StartCause ) {
162
170
if let Some ( schedule) = self . cef_schedule
163
171
&& schedule < Instant :: now ( )
164
172
{
165
173
self . cef_schedule = None ;
166
- self . cef_context . work ( ) ;
167
- }
168
- if let StartCause :: ResumeTimeReached { .. } = cause {
169
- if let Some ( window) = & self . window {
170
- window. request_redraw ( ) ;
174
+ // Poll cef message loop multiple times to avoid message loop starvation
175
+ for _ in 0 ..10 {
176
+ self . cef_context . work ( ) ;
171
177
}
172
178
}
179
+ if let Some ( window) = & self . window . as_ref ( ) {
180
+ window. request_redraw ( ) ;
181
+ }
182
+
183
+ event_loop. set_control_flow ( ControlFlow :: WaitUntil ( wait_until) ) ;
173
184
}
174
185
175
186
fn resumed ( & mut self , event_loop : & ActiveEventLoop ) {
@@ -211,8 +222,9 @@ impl ApplicationHandler<CustomEvent> for WinitApp {
211
222
graphics_state. bind_ui_texture ( texture) ;
212
223
let elapsed = self . last_ui_update . elapsed ( ) . as_secs_f32 ( ) ;
213
224
self . last_ui_update = Instant :: now ( ) ;
214
- self . avg_frame_time = ( self . avg_frame_time * 3. + elapsed) / 4. ;
215
- println ! ( "ui fps: {:.2}" , 1. / self . avg_frame_time) ;
225
+ if elapsed < 0.5 {
226
+ self . avg_frame_time = ( self . avg_frame_time * 3. + elapsed) / 4. ;
227
+ }
216
228
}
217
229
if let Some ( window) = & self . window {
218
230
window. request_redraw ( ) ;
@@ -357,16 +369,18 @@ impl ApplicationHandler<CustomEvent> for WinitApp {
357
369
WindowEvent :: RedrawRequested => {
358
370
let Some ( ref mut graphics_state) = self . graphics_state else { return } ;
359
371
// Only rerender once we have a new ui texture to display
360
-
361
- match graphics_state. render ( ) {
362
- Ok ( _) => { }
363
- Err ( wgpu:: SurfaceError :: Lost ) => {
364
- tracing:: warn!( "lost surface" ) ;
365
- }
366
- Err ( wgpu:: SurfaceError :: OutOfMemory ) => {
367
- event_loop. exit ( ) ;
372
+ if let Some ( window) = & self . window {
373
+ match graphics_state. render ( window. as_ref ( ) ) {
374
+ Ok ( _) => { }
375
+ Err ( wgpu:: SurfaceError :: Lost ) => {
376
+ tracing:: warn!( "lost surface" ) ;
377
+ }
378
+ Err ( wgpu:: SurfaceError :: OutOfMemory ) => {
379
+ event_loop. exit ( ) ;
380
+ }
381
+ Err ( e) => tracing:: error!( "{:?}" , e) ,
368
382
}
369
- Err ( e ) => tracing :: error! ( "{:?}" , e ) ,
383
+ let _ = self . start_render_sender . try_send ( ( ) ) ;
370
384
}
371
385
}
372
386
_ => { }
0 commit comments