@@ -3,7 +3,7 @@ use metal::*;
3
3
use winit:: {
4
4
event:: { Event , WindowEvent } ,
5
5
event_loop:: { ControlFlow , EventLoop } ,
6
- platform :: macos :: WindowExtMacOS ,
6
+ raw_window_handle :: { HasWindowHandle , RawWindowHandle } ,
7
7
} ;
8
8
9
9
use cocoa:: { appkit:: NSView , base:: id as cocoa_id} ;
@@ -33,7 +33,7 @@ pub struct AAPLVertex {
33
33
34
34
fn main ( ) {
35
35
// Create a window for viewing the content
36
- let event_loop = EventLoop :: new ( ) ;
36
+ let event_loop = EventLoop :: new ( ) . unwrap ( ) ;
37
37
let size = winit:: dpi:: LogicalSize :: new ( 800 , 600 ) ;
38
38
39
39
let window = winit:: window:: WindowBuilder :: new ( )
@@ -100,9 +100,11 @@ fn main() {
100
100
layer. set_presents_with_transaction ( false ) ;
101
101
102
102
unsafe {
103
- let view = window. ns_view ( ) as cocoa_id ;
104
- view. setWantsLayer ( YES ) ;
105
- view. setLayer ( mem:: transmute ( layer. as_ref ( ) ) ) ;
103
+ if let Ok ( RawWindowHandle :: AppKit ( rw) ) = window. window_handle ( ) . map ( |wh| wh. as_raw ( ) ) {
104
+ let view = rw. ns_view . as_ptr ( ) as cocoa_id ;
105
+ view. setWantsLayer ( YES ) ;
106
+ view. setLayer ( mem:: transmute ( layer. as_ref ( ) ) ) ;
107
+ }
106
108
}
107
109
108
110
let draw_size = window. inner_size ( ) ;
@@ -119,80 +121,87 @@ fn main() {
119
121
)
120
122
} ;
121
123
122
- event_loop. run ( move |event, _, control_flow| {
123
- autoreleasepool ( || {
124
- // ControlFlow::Wait pauses the event loop if no events are available to process.
125
- // This is ideal for non-game applications that only update in response to user
126
- // input, and uses significantly less power/CPU time than ControlFlow::Poll.
127
- * control_flow = ControlFlow :: Wait ;
128
-
129
- match event {
130
- Event :: WindowEvent {
131
- event : WindowEvent :: CloseRequested ,
132
- ..
133
- } => {
134
- println ! ( "The close button was pressed; stopping" ) ;
135
- * control_flow = ControlFlow :: Exit
136
- }
137
- Event :: MainEventsCleared => {
138
- // Queue a RedrawRequested event.
139
- window. request_redraw ( ) ;
140
- }
141
- Event :: RedrawRequested ( _) => {
142
- // It's preferrable to render in this event rather than in MainEventsCleared, since
143
- // rendering in here allows the program to gracefully handle redraws requested
144
- // by the OS.
145
- let drawable = match layer. next_drawable ( ) {
146
- Some ( drawable) => drawable,
147
- None => return ,
148
- } ;
149
-
150
- // Create a new command buffer for each render pass to the current drawable
151
- let command_buffer = command_queue. new_command_buffer ( ) ;
152
-
153
- // Obtain a renderPassDescriptor generated from the view's drawable textures.
154
- let render_pass_descriptor = RenderPassDescriptor :: new ( ) ;
155
- handle_render_pass_color_attachment (
156
- & render_pass_descriptor,
157
- drawable. texture ( ) ,
158
- ) ;
159
- handle_render_pass_sample_buffer_attachment (
160
- & render_pass_descriptor,
161
- & counter_sample_buffer,
162
- ) ;
163
-
164
- // Create a render command encoder.
165
- let encoder =
166
- command_buffer. new_render_command_encoder ( & render_pass_descriptor) ;
167
- encoder. set_render_pipeline_state ( & pipeline_state) ;
168
- // Pass in the parameter data.
169
- encoder. set_vertex_buffer ( 0 , Some ( & vbuf) , 0 ) ;
170
- // Draw the triangles which will eventually form the circle.
171
- encoder. draw_primitives ( MTLPrimitiveType :: TriangleStrip , 0 , 1080 ) ;
172
- encoder. end_encoding ( ) ;
173
-
174
- resolve_samples_into_buffer (
175
- & command_buffer,
176
- & counter_sample_buffer,
177
- & destination_buffer,
178
- ) ;
179
-
180
- // Schedule a present once the framebuffer is complete using the current drawable.
181
- command_buffer. present_drawable ( & drawable) ;
182
-
183
- // Finalize rendering here & push the command buffer to the GPU.
184
- command_buffer. commit ( ) ;
185
- command_buffer. wait_until_completed ( ) ;
186
-
187
- let mut cpu_end = 0 ;
188
- let mut gpu_end = 0 ;
189
- device. sample_timestamps ( & mut cpu_end, & mut gpu_end) ;
190
- handle_timestamps ( & destination_buffer, cpu_start, cpu_end, gpu_start, gpu_end) ;
124
+ event_loop
125
+ . run ( move |event, event_loop| {
126
+ autoreleasepool ( || {
127
+ // ControlFlow::Wait pauses the event loop if no events are available to process.
128
+ // This is ideal for non-game applications that only update in response to user
129
+ // input, and uses significantly less power/CPU time than ControlFlow::Poll.
130
+ event_loop. set_control_flow ( ControlFlow :: Wait ) ;
131
+
132
+ match event {
133
+ Event :: AboutToWait => window. request_redraw ( ) ,
134
+ Event :: WindowEvent { event, .. } => {
135
+ match event {
136
+ WindowEvent :: CloseRequested => {
137
+ println ! ( "The close button was pressed; stopping" ) ;
138
+ event_loop. exit ( ) ;
139
+ }
140
+ WindowEvent :: RedrawRequested => {
141
+ // It's preferrable to render in this event rather than in MainEventsCleared, since
142
+ // rendering in here allows the program to gracefully handle redraws requested
143
+ // by the OS.
144
+ let drawable = match layer. next_drawable ( ) {
145
+ Some ( drawable) => drawable,
146
+ None => return ,
147
+ } ;
148
+
149
+ // Create a new command buffer for each render pass to the current drawable
150
+ let command_buffer = command_queue. new_command_buffer ( ) ;
151
+
152
+ // Obtain a renderPassDescriptor generated from the view's drawable textures.
153
+ let render_pass_descriptor = RenderPassDescriptor :: new ( ) ;
154
+ handle_render_pass_color_attachment (
155
+ & render_pass_descriptor,
156
+ drawable. texture ( ) ,
157
+ ) ;
158
+ handle_render_pass_sample_buffer_attachment (
159
+ & render_pass_descriptor,
160
+ & counter_sample_buffer,
161
+ ) ;
162
+
163
+ // Create a render command encoder.
164
+ let encoder = command_buffer
165
+ . new_render_command_encoder ( & render_pass_descriptor) ;
166
+ encoder. set_render_pipeline_state ( & pipeline_state) ;
167
+ // Pass in the parameter data.
168
+ encoder. set_vertex_buffer ( 0 , Some ( & vbuf) , 0 ) ;
169
+ // Draw the triangles which will eventually form the circle.
170
+ encoder. draw_primitives ( MTLPrimitiveType :: TriangleStrip , 0 , 1080 ) ;
171
+ encoder. end_encoding ( ) ;
172
+
173
+ resolve_samples_into_buffer (
174
+ & command_buffer,
175
+ & counter_sample_buffer,
176
+ & destination_buffer,
177
+ ) ;
178
+
179
+ // Schedule a present once the framebuffer is complete using the current drawable.
180
+ command_buffer. present_drawable ( & drawable) ;
181
+
182
+ // Finalize rendering here & push the command buffer to the GPU.
183
+ command_buffer. commit ( ) ;
184
+ command_buffer. wait_until_completed ( ) ;
185
+
186
+ let mut cpu_end = 0 ;
187
+ let mut gpu_end = 0 ;
188
+ device. sample_timestamps ( & mut cpu_end, & mut gpu_end) ;
189
+ handle_timestamps (
190
+ & destination_buffer,
191
+ cpu_start,
192
+ cpu_end,
193
+ gpu_start,
194
+ gpu_end,
195
+ ) ;
196
+ }
197
+ _ => ( ) ,
198
+ }
199
+ }
200
+ _ => ( ) ,
191
201
}
192
- _ => ( ) ,
193
- }
194
- } ) ;
195
- } ) ;
202
+ } ) ;
203
+ } )
204
+ . unwrap ( ) ;
196
205
}
197
206
198
207
// If we want to draw a circle, we need to draw it out of the three primitive
0 commit comments