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