@@ -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 } ;
@@ -76,59 +76,16 @@ fn main() {
7676 . with_context_api ( glutin:: context:: ContextApi :: Gles ( None ) )
7777 . build ( raw_window_handle) ;
7878
79- // TODO: Wrap in Option
80- let mut not_current_gl_context = unsafe {
79+ let mut not_current_gl_context = Some ( unsafe {
8180 gl_display
8281 . create_context ( & gl_config, & context_attributes)
8382 . expect ( "failed to create context" )
84- } ;
85-
86- // TODO: For Android support this should happen inside Event::Resumed, and the inverse inside ::Suspended.
87- let window = window. take ( ) . unwrap_or_else ( || {
88- // let window_builder = winit::window::WindowBuilder::new()
89- // .with_title("WGPU raw GLES example (press Escape to exit)");
90- // glutin_winit::finalize_window(window_target, window_builder, &gl_config).unwrap()
91- panic ! ( )
9283 } ) ;
9384
94- let attrs = window. build_surface_attributes ( Default :: default ( ) ) ;
95- let gl_surface = unsafe {
96- gl_config
97- . display ( )
98- . create_window_surface ( & gl_config, & attrs)
99- . expect ( "Cannot create GL WindowSurface" )
100- } ;
101-
102- // Make it current.
103- // let gl_context = not_current_gl_context
104- // .take()
105- // .unwrap()
106- // .make_current(&gl_surface)
107- // .unwrap();
108- let gl_context = not_current_gl_context
109- . make_current ( & gl_surface)
110- . expect ( "GL context cannot be made current with WindowSurface" ) ;
111-
112- println ! ( "Hooking up to wgpu-hal" ) ;
113- let exposed = unsafe {
114- <hal:: api:: Gles as hal:: Api >:: Adapter :: new_external ( |name| {
115- // XXX: On WGL this should only be called after the context was made current
116- gl_config
117- . display ( )
118- . get_proc_address ( & CString :: new ( name) . expect ( name) )
119- } )
120- }
121- . expect ( "GL adapter can't be initialized" ) ;
85+ let mut state = None ;
12286
123- let inner_size = window. inner_size ( ) ;
124-
125- fill_screen ( & exposed, inner_size. width , inner_size. height ) ;
126-
127- // TODO: Swap in RedrawRequested
128- println ! ( "Showing the window" ) ;
129- gl_surface
130- . swap_buffers ( & gl_context)
131- . expect ( "Failed to swap buffers" ) ;
87+ // Only needs to be loaded once
88+ let mut exposed = None ;
13289
13390 event_loop
13491 . run ( move |event, window_target| {
@@ -154,6 +111,95 @@ fn main() {
154111 ..
155112 } ,
156113 } => window_target. exit ( ) ,
114+ Event :: Resumed => {
115+ let window = window. take ( ) . unwrap_or_else ( || {
116+ let window_builder = winit:: window:: WindowBuilder :: new ( )
117+ . with_title ( "WGPU raw GLES example (press Escape to exit)" ) ;
118+ glutin_winit:: finalize_window ( window_target, window_builder, & gl_config)
119+ . unwrap ( )
120+ } ) ;
121+
122+ let attrs = window. build_surface_attributes ( Default :: default ( ) ) ;
123+ let gl_surface = unsafe {
124+ gl_config
125+ . display ( )
126+ . create_window_surface ( & gl_config, & attrs)
127+ . expect ( "Cannot create GL WindowSurface" )
128+ } ;
129+
130+ // Make it current.
131+ let gl_context = not_current_gl_context
132+ . take ( )
133+ . unwrap ( )
134+ . make_current ( & gl_surface)
135+ . expect ( "GL context cannot be made current with WindowSurface" ) ;
136+
137+ // The context needs to be current for the Renderer to set up shaders and
138+ // buffers. It also performs function loading, which needs a current context on
139+ // WGL.
140+ println ! ( "Hooking up to wgpu-hal" ) ;
141+ exposed. get_or_insert_with ( || {
142+ unsafe {
143+ <hal:: api:: Gles as hal:: Api >:: Adapter :: new_external ( |name| {
144+ // XXX: On WGL this should only be called after the context was made current
145+ gl_config
146+ . display ( )
147+ . get_proc_address ( & CString :: new ( name) . expect ( name) )
148+ } )
149+ }
150+ . expect ( "GL adapter can't be initialized" )
151+ } ) ;
152+
153+ assert ! ( state. replace( ( gl_context, gl_surface, window) ) . is_none( ) ) ;
154+ }
155+ Event :: Suspended => {
156+ // This event is only raised on Android, where the backing NativeWindow for a GL
157+ // Surface can appear and disappear at any moment.
158+ println ! ( "Android window removed" ) ;
159+
160+ // Destroy the GL Surface and un-current the GL Context before ndk-glue releases
161+ // the window back to the system.
162+ let ( gl_context, ..) = state. take ( ) . unwrap ( ) ;
163+ assert ! ( not_current_gl_context
164+ . replace( gl_context. make_not_current( ) . unwrap( ) )
165+ . is_none( ) ) ;
166+ }
167+ Event :: WindowEvent {
168+ window_id : _,
169+ event : WindowEvent :: Resized ( size) ,
170+ } => {
171+ if size. width != 0 && size. height != 0 {
172+ // Some platforms like EGL require resizing GL surface to update the size
173+ // Notable platforms here are Wayland and macOS, other don't require it
174+ // and the function is no-op, but it's wise to resize it for portability
175+ // reasons.
176+ if let Some ( ( gl_context, gl_surface, _) ) = & state {
177+ gl_surface. resize (
178+ gl_context,
179+ NonZeroU32 :: new ( size. width ) . unwrap ( ) ,
180+ NonZeroU32 :: new ( size. height ) . unwrap ( ) ,
181+ ) ;
182+ // XXX: If there's a state for fill_screen(), this would need to be updated too.
183+ }
184+ }
185+ }
186+ Event :: WindowEvent {
187+ window_id : _,
188+ event : WindowEvent :: RedrawRequested ,
189+ } => {
190+ if let ( Some ( exposed) , Some ( ( gl_context, gl_surface, window) ) ) =
191+ ( & exposed, & state)
192+ {
193+ let inner_size = window. inner_size ( ) ;
194+
195+ fill_screen ( exposed, inner_size. width , inner_size. height ) ;
196+
197+ println ! ( "Showing the window" ) ;
198+ gl_surface
199+ . swap_buffers ( gl_context)
200+ . expect ( "Failed to swap buffers" ) ;
201+ }
202+ }
157203 _ => ( ) ,
158204 }
159205 } )
0 commit comments