@@ -12,11 +12,11 @@ extern crate wgpu_hal as hal;
12
12
13
13
#[ cfg( not( any( windows, target_arch = "wasm32" , target_os = "ios" ) ) ) ]
14
14
fn main ( ) {
15
- use std:: ffi:: CString ;
15
+ use std:: { ffi:: CString , num :: NonZeroU32 } ;
16
16
17
17
use glutin:: {
18
18
config:: GlConfig as _,
19
- context:: NotCurrentGlContext ,
19
+ context:: { NotCurrentGlContext , PossiblyCurrentGlContext as _ } ,
20
20
display:: { GetGlDisplay , GlDisplay } ,
21
21
surface:: GlSurface as _,
22
22
} ;
@@ -76,59 +76,16 @@ fn main() {
76
76
. with_context_api ( glutin:: context:: ContextApi :: Gles ( None ) )
77
77
. build ( raw_window_handle) ;
78
78
79
- // TODO: Wrap in Option
80
- let mut not_current_gl_context = unsafe {
79
+ let mut not_current_gl_context = Some ( unsafe {
81
80
gl_display
82
81
. create_context ( & gl_config, & context_attributes)
83
82
. 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 ! ( )
92
83
} ) ;
93
84
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 ;
122
86
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 ;
132
89
133
90
event_loop
134
91
. run ( move |event, window_target| {
@@ -154,6 +111,95 @@ fn main() {
154
111
..
155
112
} ,
156
113
} => 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
+ }
157
203
_ => ( ) ,
158
204
}
159
205
} )
0 commit comments