@@ -12,11 +12,11 @@ extern crate wgpu_hal as hal;
12
12
13
13
#[ cfg( not( any( windows, target_arch = "wasm32" ) ) ) ]
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
} ;
@@ -32,7 +32,7 @@ fn main() {
32
32
//
33
33
// XXX if you don't care about running on Android or so you can safely remove
34
34
// 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)
36
36
let window_builder = todo_wgl_backend. then ( || {
37
37
winit:: window:: WindowBuilder :: new ( )
38
38
. with_title ( "WGPU raw GLES example (press Escape to exit)" )
@@ -80,59 +80,16 @@ fn main() {
80
80
. with_context_api ( glutin:: context:: ContextApi :: Gles ( None ) )
81
81
. build ( raw_window_handle) ;
82
82
83
- // TODO: Wrap in Option
84
- let mut not_current_gl_context = unsafe {
83
+ let mut not_current_gl_context = Some ( unsafe {
85
84
gl_display
86
85
. create_context ( & gl_config, & context_attributes)
87
86
. 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 ! ( )
96
87
} ) ;
97
88
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 ;
126
90
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 ;
136
93
137
94
event_loop
138
95
. run ( move |event, window_target| {
@@ -158,6 +115,95 @@ fn main() {
158
115
..
159
116
} ,
160
117
} => 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
+ }
161
207
_ => ( ) ,
162
208
}
163
209
} )
0 commit comments