@@ -26,14 +26,23 @@ use crate::device::Device as DeviceAPI;
26
26
use crate :: { ContextID , Error , SurfaceAccess , SurfaceInfo , SurfaceType } ;
27
27
use euclid:: default:: Size2D ;
28
28
use fnv:: { FnvHashMap , FnvHashSet } ;
29
+ use glow as gl;
30
+ use glow:: Context as Gl ;
31
+ use glow:: HasContext ;
29
32
use log:: debug;
30
- use sparkle:: gl:: { self , GLuint , Gl } ;
31
33
use std:: collections:: hash_map:: Entry ;
32
34
use std:: fmt:: Debug ;
33
35
use std:: hash:: Hash ;
34
36
use std:: mem;
37
+ use std:: num:: NonZero ;
35
38
use std:: sync:: { Arc , Mutex , MutexGuard , RwLock , RwLockReadGuard , RwLockWriteGuard } ;
36
39
40
+ impl crate :: SurfaceInfo {
41
+ fn framebuffer ( & self ) -> Option < gl:: NativeFramebuffer > {
42
+ NonZero :: new ( self . framebuffer_object ) . map ( gl:: NativeFramebuffer )
43
+ }
44
+ }
45
+
37
46
// The data stored for each swap chain.
38
47
struct SwapChainData < Device : DeviceAPI > {
39
48
// The size of the back buffer
@@ -191,23 +200,25 @@ impl<Device: DeviceAPI> SwapChainData<Device> {
191
200
192
201
if let PreserveBuffer :: Yes ( gl) = preserve_buffer {
193
202
let front_info = device. surface_info ( & new_front_buffer) ;
194
- gl. bind_framebuffer ( gl:: READ_FRAMEBUFFER , front_info. framebuffer_object ) ;
195
- debug_assert_eq ! ( gl. get_error( ) , gl:: NO_ERROR ) ;
196
- gl. bind_framebuffer ( gl:: DRAW_FRAMEBUFFER , back_info. framebuffer_object ) ;
197
- debug_assert_eq ! ( gl. get_error( ) , gl:: NO_ERROR ) ;
198
- gl. blit_framebuffer (
199
- 0 ,
200
- 0 ,
201
- front_info. size . width ,
202
- front_info. size . height ,
203
- 0 ,
204
- 0 ,
205
- back_info. size . width ,
206
- back_info. size . height ,
207
- gl:: COLOR_BUFFER_BIT | gl:: DEPTH_BUFFER_BIT | gl:: STENCIL_BUFFER_BIT ,
208
- gl:: NEAREST ,
209
- ) ;
210
- debug_assert_eq ! ( gl. get_error( ) , gl:: NO_ERROR ) ;
203
+ unsafe {
204
+ gl. bind_framebuffer ( gl:: READ_FRAMEBUFFER , front_info. framebuffer ( ) ) ;
205
+ debug_assert_eq ! ( gl. get_error( ) , gl:: NO_ERROR ) ;
206
+ gl. bind_framebuffer ( gl:: DRAW_FRAMEBUFFER , back_info. framebuffer ( ) ) ;
207
+ debug_assert_eq ! ( gl. get_error( ) , gl:: NO_ERROR ) ;
208
+ gl. blit_framebuffer (
209
+ 0 ,
210
+ 0 ,
211
+ front_info. size . width ,
212
+ front_info. size . height ,
213
+ 0 ,
214
+ 0 ,
215
+ back_info. size . width ,
216
+ back_info. size . height ,
217
+ gl:: COLOR_BUFFER_BIT | gl:: DEPTH_BUFFER_BIT | gl:: STENCIL_BUFFER_BIT ,
218
+ gl:: NEAREST ,
219
+ ) ;
220
+ debug_assert_eq ! ( gl. get_error( ) , gl:: NO_ERROR ) ;
221
+ }
211
222
}
212
223
213
224
// Update the state
@@ -344,24 +355,25 @@ impl<Device: DeviceAPI> SwapChainData<Device> {
344
355
self . validate_context ( device, context) ?;
345
356
346
357
// Save the current GL state
347
- let mut bound_fbos = [ 0 , 0 ] ;
358
+ let draw_fbo;
359
+ let read_fbo;
348
360
let mut clear_color = [ 0. , 0. , 0. , 0. ] ;
349
361
let mut clear_depth = [ 0. ] ;
350
362
let mut clear_stencil = [ 0 ] ;
351
- let mut color_mask = [ 0 , 0 , 0 , 0 ] ;
352
- let mut depth_mask = [ 0 ] ;
363
+ let color_mask;
364
+ let depth_mask;
353
365
let mut stencil_mask = [ 0 ] ;
354
- let scissor_enabled = gl. is_enabled ( gl:: SCISSOR_TEST ) ;
355
- let rasterizer_enabled = gl. is_enabled ( gl:: RASTERIZER_DISCARD ) ;
366
+ let scissor_enabled = unsafe { gl. is_enabled ( gl:: SCISSOR_TEST ) } ;
367
+ let rasterizer_enabled = unsafe { gl. is_enabled ( gl:: RASTERIZER_DISCARD ) } ;
356
368
unsafe {
357
- gl. get_integer_v ( gl:: DRAW_FRAMEBUFFER_BINDING , & mut bound_fbos [ 0 .. ] ) ;
358
- gl. get_integer_v ( gl:: READ_FRAMEBUFFER_BINDING , & mut bound_fbos [ 1 .. ] ) ;
359
- gl. get_float_v ( gl:: COLOR_CLEAR_VALUE , & mut clear_color[ ..] ) ;
360
- gl. get_float_v ( gl:: DEPTH_CLEAR_VALUE , & mut clear_depth[ ..] ) ;
361
- gl. get_integer_v ( gl:: STENCIL_CLEAR_VALUE , & mut clear_stencil[ ..] ) ;
362
- gl. get_boolean_v ( gl:: DEPTH_WRITEMASK , & mut depth_mask [ .. ] ) ;
363
- gl. get_integer_v ( gl:: STENCIL_WRITEMASK , & mut stencil_mask[ ..] ) ;
364
- gl. get_boolean_v ( gl:: COLOR_WRITEMASK , & mut color_mask [ .. ] ) ;
369
+ draw_fbo = gl. get_parameter_framebuffer ( gl:: DRAW_FRAMEBUFFER_BINDING ) ;
370
+ read_fbo = gl. get_parameter_framebuffer ( gl:: READ_FRAMEBUFFER_BINDING ) ;
371
+ gl. get_parameter_f32_slice ( gl:: COLOR_CLEAR_VALUE , & mut clear_color[ ..] ) ;
372
+ gl. get_parameter_f32_slice ( gl:: DEPTH_CLEAR_VALUE , & mut clear_depth[ ..] ) ;
373
+ gl. get_parameter_i32_slice ( gl:: STENCIL_CLEAR_VALUE , & mut clear_stencil[ ..] ) ;
374
+ depth_mask = gl. get_parameter_bool ( gl:: DEPTH_WRITEMASK ) ;
375
+ gl. get_parameter_i32_slice ( gl:: STENCIL_WRITEMASK , & mut stencil_mask[ ..] ) ;
376
+ color_mask = gl. get_parameter_bool_array :: < 4 > ( gl:: COLOR_WRITEMASK ) ;
365
377
}
366
378
367
379
// Make the back buffer the current surface
@@ -386,18 +398,19 @@ impl<Device: DeviceAPI> SwapChainData<Device> {
386
398
. context_surface_info ( context)
387
399
. unwrap ( )
388
400
. unwrap ( )
389
- . framebuffer_object ;
390
- gl. bind_framebuffer ( gl:: FRAMEBUFFER , fbo) ;
391
- gl. clear_color ( color[ 0 ] , color[ 1 ] , color[ 2 ] , color[ 3 ] ) ;
392
- gl. clear_depth ( 1. ) ;
393
- gl. clear_stencil ( 0 ) ;
394
- gl. disable ( gl:: SCISSOR_TEST ) ;
395
- gl. disable ( gl:: RASTERIZER_DISCARD ) ;
396
- gl. depth_mask ( true ) ;
397
- gl. stencil_mask ( 0xFFFFFFFF ) ;
398
- gl. color_mask ( true , true , true , true ) ;
399
- gl. clear ( gl:: COLOR_BUFFER_BIT | gl:: DEPTH_BUFFER_BIT | gl:: STENCIL_BUFFER_BIT ) ;
400
-
401
+ . framebuffer ( ) ;
402
+ unsafe {
403
+ gl. bind_framebuffer ( gl:: FRAMEBUFFER , fbo) ;
404
+ gl. clear_color ( color[ 0 ] , color[ 1 ] , color[ 2 ] , color[ 3 ] ) ;
405
+ gl. clear_depth_f64 ( 1. ) ;
406
+ gl. clear_stencil ( 0 ) ;
407
+ gl. disable ( gl:: SCISSOR_TEST ) ;
408
+ gl. disable ( gl:: RASTERIZER_DISCARD ) ;
409
+ gl. depth_mask ( true ) ;
410
+ gl. stencil_mask ( 0xFFFFFFFF ) ;
411
+ gl. color_mask ( true , true , true , true ) ;
412
+ gl. clear ( gl:: COLOR_BUFFER_BIT | gl:: DEPTH_BUFFER_BIT | gl:: STENCIL_BUFFER_BIT ) ;
413
+ }
401
414
// Reattach the old surface
402
415
if let Some ( surface) = reattach {
403
416
let mut old_surface = device. unbind_surface_from_context ( context) ?. unwrap ( ) ;
@@ -412,29 +425,26 @@ impl<Device: DeviceAPI> SwapChainData<Device> {
412
425
}
413
426
414
427
// Restore the GL state
415
- gl. bind_framebuffer ( gl:: DRAW_FRAMEBUFFER , bound_fbos[ 0 ] as GLuint ) ;
416
- gl. bind_framebuffer ( gl:: READ_FRAMEBUFFER , bound_fbos[ 1 ] as GLuint ) ;
417
- gl. clear_color (
418
- clear_color[ 0 ] ,
419
- clear_color[ 1 ] ,
420
- clear_color[ 2 ] ,
421
- clear_color[ 3 ] ,
422
- ) ;
423
- gl. color_mask (
424
- color_mask[ 0 ] != 0 ,
425
- color_mask[ 1 ] != 0 ,
426
- color_mask[ 2 ] != 0 ,
427
- color_mask[ 3 ] != 0 ,
428
- ) ;
429
- gl. clear_depth ( clear_depth[ 0 ] as f64 ) ;
430
- gl. clear_stencil ( clear_stencil[ 0 ] ) ;
431
- gl. depth_mask ( depth_mask[ 0 ] != 0 ) ;
432
- gl. stencil_mask ( stencil_mask[ 0 ] as gl:: GLuint ) ;
433
- if scissor_enabled {
434
- gl. enable ( gl:: SCISSOR_TEST ) ;
435
- }
436
- if rasterizer_enabled {
437
- gl. enable ( gl:: RASTERIZER_DISCARD ) ;
428
+ unsafe {
429
+ gl. bind_framebuffer ( gl:: DRAW_FRAMEBUFFER , draw_fbo) ;
430
+ gl. bind_framebuffer ( gl:: READ_FRAMEBUFFER , read_fbo) ;
431
+ gl. clear_color (
432
+ clear_color[ 0 ] ,
433
+ clear_color[ 1 ] ,
434
+ clear_color[ 2 ] ,
435
+ clear_color[ 3 ] ,
436
+ ) ;
437
+ gl. color_mask ( color_mask[ 0 ] , color_mask[ 1 ] , color_mask[ 2 ] , color_mask[ 3 ] ) ;
438
+ gl. clear_depth_f64 ( clear_depth[ 0 ] as f64 ) ;
439
+ gl. clear_stencil ( clear_stencil[ 0 ] ) ;
440
+ gl. depth_mask ( depth_mask) ;
441
+ gl. stencil_mask ( stencil_mask[ 0 ] as _ ) ;
442
+ if scissor_enabled {
443
+ gl. enable ( gl:: SCISSOR_TEST ) ;
444
+ }
445
+ if rasterizer_enabled {
446
+ gl. enable ( gl:: RASTERIZER_DISCARD ) ;
447
+ }
438
448
}
439
449
440
450
Ok ( ( ) )
0 commit comments