11use crate :: CustomEvent ;
2- use crate :: WindowState ;
3- use crate :: WindowStateHandle ;
2+ use crate :: FrameBuffer ;
3+ use crate :: WindowSize ;
44use crate :: render:: GraphicsState ;
55use std:: sync:: Arc ;
6+ use std:: sync:: mpsc:: Sender ;
67use std:: time:: Duration ;
78use std:: time:: Instant ;
9+ use tracing:: instrument:: WithSubscriber ;
810use winit:: application:: ApplicationHandler ;
11+ use winit:: dpi:: PhysicalSize ;
912use winit:: event:: StartCause ;
1013use winit:: event:: WindowEvent ;
1114use winit:: event_loop:: ActiveEventLoop ;
@@ -16,31 +19,42 @@ use winit::window::WindowId;
1619use crate :: cef;
1720
1821pub ( crate ) struct WinitApp {
19- pub ( crate ) window_state : WindowStateHandle ,
2022 pub ( crate ) cef_context : cef:: Context < cef:: Initialized > ,
2123 pub ( crate ) window : Option < Arc < Window > > ,
2224 cef_schedule : Option < Instant > ,
25+ ui_dirty : bool ,
26+ ui_frame_buffer : Option < FrameBuffer > ,
27+ window_size_sender : Sender < WindowSize > ,
28+ _viewport_frame_buffer : Option < FrameBuffer > ,
29+ graphics_state : Option < GraphicsState > ,
2330}
2431
2532impl WinitApp {
26- pub ( crate ) fn new ( window_state : WindowStateHandle , cef_context : cef:: Context < cef:: Initialized > ) -> Self {
33+ pub ( crate ) fn new ( cef_context : cef:: Context < cef:: Initialized > , window_size_sender : Sender < WindowSize > ) -> Self {
2734 Self {
28- window_state,
2935 cef_context,
3036 window : None ,
3137 cef_schedule : Some ( Instant :: now ( ) ) ,
38+ _viewport_frame_buffer : None ,
39+ ui_frame_buffer : None ,
40+ ui_dirty : false ,
41+ graphics_state : None ,
42+ window_size_sender,
3243 }
3344 }
3445}
3546
3647impl ApplicationHandler < CustomEvent > for WinitApp {
3748 fn about_to_wait ( & mut self , event_loop : & ActiveEventLoop ) {
38- let timeout = Instant :: now ( ) + Duration :: from_millis ( 10 ) ;
49+ let timeout = Instant :: now ( ) + Duration :: from_millis ( 1000 ) ;
3950 let wait_until = timeout. min ( self . cef_schedule . unwrap_or ( timeout) ) ;
4051 event_loop. set_control_flow ( ControlFlow :: WaitUntil ( wait_until) ) ;
4152 }
4253
4354 fn new_events ( & mut self , _event_loop : & ActiveEventLoop , _cause : StartCause ) {
55+ if self . ui_frame_buffer . is_none ( ) {
56+ self . cef_context . work ( ) ;
57+ }
4458 if let Some ( schedule) = self . cef_schedule
4559 && schedule < Instant :: now ( )
4660 {
@@ -50,32 +64,31 @@ impl ApplicationHandler<CustomEvent> for WinitApp {
5064 }
5165
5266 fn resumed ( & mut self , event_loop : & ActiveEventLoop ) {
53- self . window_state
54- . with ( |s| {
55- if let WindowState { width : Some ( w) , height : Some ( h) , .. } = s {
56- let window = Arc :: new (
57- event_loop
58- . create_window (
59- Window :: default_attributes ( )
60- . with_title ( "CEF Offscreen Rendering" )
61- . with_inner_size ( winit:: dpi:: LogicalSize :: new ( * w as u32 , * h as u32 ) ) ,
62- )
63- . unwrap ( ) ,
64- ) ;
65- let graphics_state = pollster:: block_on ( GraphicsState :: new ( window. clone ( ) ) ) ;
67+ let window = Arc :: new (
68+ event_loop
69+ . create_window (
70+ Window :: default_attributes ( )
71+ . with_title ( "CEF Offscreen Rendering" )
72+ . with_inner_size ( winit:: dpi:: LogicalSize :: new ( 1200 , 800 ) ) ,
73+ )
74+ . unwrap ( ) ,
75+ ) ;
76+ let graphics_state = pollster:: block_on ( GraphicsState :: new ( window. clone ( ) ) ) ;
6677
67- self . window = Some ( window. clone ( ) ) ;
68- s . graphics_state = Some ( graphics_state) ;
78+ self . window = Some ( window) ;
79+ self . graphics_state = Some ( graphics_state) ;
6980
70- tracing:: info!( "Winit window created and ready" ) ;
71- }
72- } )
73- . unwrap ( ) ;
81+ tracing:: info!( "Winit window created and ready" ) ;
7482 }
7583
7684 fn user_event ( & mut self , _: & ActiveEventLoop , event : CustomEvent ) {
7785 match event {
78- CustomEvent :: UiUpdate => {
86+ CustomEvent :: UiUpdate ( frame_buffer) => {
87+ if let Some ( graphics_state) = self . graphics_state . as_mut ( ) {
88+ graphics_state. update_texture ( & frame_buffer) ;
89+ self . ui_dirty = true ;
90+ }
91+ self . ui_frame_buffer = Some ( frame_buffer) ;
7992 if let Some ( window) = & self . window {
8093 window. request_redraw ( ) ;
8194 }
@@ -94,58 +107,33 @@ impl ApplicationHandler<CustomEvent> for WinitApp {
94107 tracing:: info!( "The close button was pressed; stopping" ) ;
95108 event_loop. exit ( ) ;
96109 }
97- WindowEvent :: Resized ( physical_size) => {
98- self . window_state
99- . with ( |s| {
100- let width = physical_size. width as usize ;
101- let height = physical_size. height as usize ;
102- s. width = Some ( width) ;
103- s. height = Some ( height) ;
104- if let Some ( graphics_state) = & mut s. graphics_state {
105- graphics_state. resize ( width, height) ;
106- }
107- } )
108- . unwrap ( ) ;
110+ WindowEvent :: Resized ( PhysicalSize { width, height } ) => {
111+ let _ = self . window_size_sender . send ( WindowSize :: new ( width as usize , height as usize ) ) ;
109112 self . cef_context . notify_of_resize ( ) ;
110113 }
111114
112115 WindowEvent :: RedrawRequested => {
113- self . cef_context . work ( ) ;
116+ let Some ( ref mut graphics_state) = self . graphics_state else { return } ;
117+ // Only rerender once we have a new ui texture to display
118+ if self . ui_dirty {
119+ self . ui_dirty = false ;
114120
115- self . window_state
116- . with ( |s| {
117- if let WindowState {
118- width : Some ( width) ,
119- height : Some ( height) ,
120- graphics_state : Some ( graphics_state) ,
121- ui_frame_buffer : ui_fb,
122- ..
123- } = s
124- {
125- if let Some ( fb) = & * ui_fb {
126- graphics_state. update_texture ( fb) ;
127- if fb. width ( ) != * width && fb. height ( ) != * height {
128- graphics_state. resize ( * width, * height) ;
129- }
130- } else if let Some ( window) = & self . window {
131- window. request_redraw ( ) ;
132- }
133-
134- match graphics_state. render ( ) {
135- Ok ( _) => { }
136- Err ( wgpu:: SurfaceError :: Lost ) => {
137- graphics_state. resize ( * width, * height) ;
138- }
139- Err ( wgpu:: SurfaceError :: OutOfMemory ) => {
140- event_loop. exit ( ) ;
141- }
142- Err ( e) => tracing:: error!( "{:?}" , e) ,
143- }
121+ match graphics_state. render ( ) {
122+ Ok ( _) => { }
123+ Err ( wgpu:: SurfaceError :: Lost ) => {
124+ tracing:: warn!( "lost surface" ) ;
125+ }
126+ Err ( wgpu:: SurfaceError :: OutOfMemory ) => {
127+ event_loop. exit ( ) ;
144128 }
145- } )
146- . unwrap ( ) ;
129+ Err ( e) => tracing:: error!( "{:?}" , e) ,
130+ }
131+ }
147132 }
148133 _ => { }
149134 }
135+
136+ // Notify cef of possible input events
137+ self . cef_context . work ( ) ;
150138 }
151139}
0 commit comments