@@ -12,11 +12,11 @@ extern crate wgpu_hal as hal;
1212
1313#[ cfg( not( any( windows, target_arch = "wasm32" , target_os = "ios" ) ) ) ]
1414fn main ( ) {
15- use std:: ffi:: CString ;
15+ use std:: { ffi:: CString , num :: NonZeroU32 } ;
1616
1717 use glutin:: {
1818 config:: GlConfig as _,
19- context:: NotCurrentGlContext ,
19+ context:: { NotCurrentGlContext , PossiblyCurrentGlContext as _ } ,
2020 display:: { GetGlDisplay , GlDisplay } ,
2121 surface:: GlSurface as _,
2222 } ;
@@ -32,7 +32,7 @@ fn main() {
3232 //
3333 // XXX if you don't care about running on Android or so you can safely remove
3434 // this condition and always pass the window builder.
35- let todo_wgl_backend = true ; // cfg!(wgl_backend)
35+ let todo_wgl_backend = false ; // cfg!(wgl_backend)
3636 let window_builder = todo_wgl_backend. then ( || {
3737 winit:: window:: WindowBuilder :: new ( )
3838 . with_title ( "WGPU raw GLES example (press Escape to exit)" )
@@ -80,59 +80,16 @@ fn main() {
8080 . with_context_api ( glutin:: context:: ContextApi :: Gles ( None ) )
8181 . build ( raw_window_handle) ;
8282
83- // TODO: Wrap in Option
84- let mut not_current_gl_context = unsafe {
83+ let mut not_current_gl_context = Some ( unsafe {
8584 gl_display
8685 . create_context ( & gl_config, & context_attributes)
8786 . expect ( "failed to create context" )
88- } ;
89-
90- // TODO: For Android support this should happen inside Event::Resumed, and the inverse inside ::Suspended.
91- let window = window. take ( ) . unwrap_or_else ( || {
92- // let window_builder = winit::window::WindowBuilder::new()
93- // .with_title("WGPU raw GLES example (press Escape to exit)");
94- // glutin_winit::finalize_window(window_target, window_builder, &gl_config).unwrap()
95- panic ! ( )
9687 } ) ;
9788
98- let attrs = window. build_surface_attributes ( Default :: default ( ) ) ;
99- let gl_surface = unsafe {
100- gl_config
101- . display ( )
102- . create_window_surface ( & gl_config, & attrs)
103- . expect ( "Cannot create GL WindowSurface" )
104- } ;
105-
106- // Make it current.
107- // let gl_context = not_current_gl_context
108- // .take()
109- // .unwrap()
110- // .make_current(&gl_surface)
111- // .unwrap();
112- let gl_context = not_current_gl_context
113- . make_current ( & gl_surface)
114- . expect ( "GL context cannot be made current with WindowSurface" ) ;
115-
116- println ! ( "Hooking up to wgpu-hal" ) ;
117- let exposed = unsafe {
118- <hal:: api:: Gles as hal:: Api >:: Adapter :: new_external ( |name| {
119- // XXX: On WGL this should only be called after the context was made current
120- gl_config
121- . display ( )
122- . get_proc_address ( & CString :: new ( name) . expect ( name) )
123- } )
124- }
125- . expect ( "GL adapter can't be initialized" ) ;
89+ let mut state = None ;
12690
127- let inner_size = window. inner_size ( ) ;
128-
129- fill_screen ( & exposed, inner_size. width , inner_size. height ) ;
130-
131- // TODO: Swap in RedrawRequested
132- println ! ( "Showing the window" ) ;
133- gl_surface
134- . swap_buffers ( & gl_context)
135- . expect ( "Failed to swap buffers" ) ;
91+ // Only needs to be loaded once
92+ let mut exposed = None ;
13693
13794 event_loop
13895 . run ( move |event, window_target| {
@@ -158,6 +115,95 @@ fn main() {
158115 ..
159116 } ,
160117 } => window_target. exit ( ) ,
118+ Event :: Resumed => {
119+ let window = window. take ( ) . unwrap_or_else ( || {
120+ let window_builder = winit:: window:: WindowBuilder :: new ( )
121+ . with_title ( "WGPU raw GLES example (press Escape to exit)" ) ;
122+ glutin_winit:: finalize_window ( window_target, window_builder, & gl_config)
123+ . unwrap ( )
124+ } ) ;
125+
126+ let attrs = window. build_surface_attributes ( Default :: default ( ) ) ;
127+ let gl_surface = unsafe {
128+ gl_config
129+ . display ( )
130+ . create_window_surface ( & gl_config, & attrs)
131+ . expect ( "Cannot create GL WindowSurface" )
132+ } ;
133+
134+ // Make it current.
135+ let gl_context = not_current_gl_context
136+ . take ( )
137+ . unwrap ( )
138+ . make_current ( & gl_surface)
139+ . expect ( "GL context cannot be made current with WindowSurface" ) ;
140+
141+ // The context needs to be current for the Renderer to set up shaders and
142+ // buffers. It also performs function loading, which needs a current context on
143+ // WGL.
144+ println ! ( "Hooking up to wgpu-hal" ) ;
145+ exposed. get_or_insert_with ( || {
146+ unsafe {
147+ <hal:: api:: Gles as hal:: Api >:: Adapter :: new_external ( |name| {
148+ // XXX: On WGL this should only be called after the context was made current
149+ gl_config
150+ . display ( )
151+ . get_proc_address ( & CString :: new ( name) . expect ( name) )
152+ } )
153+ }
154+ . expect ( "GL adapter can't be initialized" )
155+ } ) ;
156+
157+ assert ! ( state. replace( ( gl_context, gl_surface, window) ) . is_none( ) ) ;
158+ }
159+ Event :: Suspended => {
160+ // This event is only raised on Android, where the backing NativeWindow for a GL
161+ // Surface can appear and disappear at any moment.
162+ println ! ( "Android window removed" ) ;
163+
164+ // Destroy the GL Surface and un-current the GL Context before ndk-glue releases
165+ // the window back to the system.
166+ let ( gl_context, ..) = state. take ( ) . unwrap ( ) ;
167+ assert ! ( not_current_gl_context
168+ . replace( gl_context. make_not_current( ) . unwrap( ) )
169+ . is_none( ) ) ;
170+ }
171+ Event :: WindowEvent {
172+ window_id : _,
173+ event : WindowEvent :: Resized ( size) ,
174+ } => {
175+ if size. width != 0 && size. height != 0 {
176+ // Some platforms like EGL require resizing GL surface to update the size
177+ // Notable platforms here are Wayland and macOS, other don't require it
178+ // and the function is no-op, but it's wise to resize it for portability
179+ // reasons.
180+ if let Some ( ( gl_context, gl_surface, _) ) = & state {
181+ gl_surface. resize (
182+ gl_context,
183+ NonZeroU32 :: new ( size. width ) . unwrap ( ) ,
184+ NonZeroU32 :: new ( size. height ) . unwrap ( ) ,
185+ ) ;
186+ // XXX: If there's a state for fill_screen(), this would need to be updated too.
187+ }
188+ }
189+ }
190+ Event :: WindowEvent {
191+ window_id : _,
192+ event : WindowEvent :: RedrawRequested ,
193+ } => {
194+ if let ( Some ( exposed) , Some ( ( gl_context, gl_surface, window) ) ) =
195+ ( & exposed, & state)
196+ {
197+ let inner_size = window. inner_size ( ) ;
198+
199+ fill_screen ( exposed, inner_size. width , inner_size. height ) ;
200+
201+ println ! ( "Showing the window" ) ;
202+ gl_surface
203+ . swap_buffers ( gl_context)
204+ . expect ( "Failed to swap buffers" ) ;
205+ }
206+ }
161207 _ => ( ) ,
162208 }
163209 } )
0 commit comments