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