3
3
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
4
4
5
5
use crate :: SurfmanGL ;
6
- use sparkle :: gl;
7
- use sparkle :: gl :: GLuint ;
8
- use sparkle :: gl :: Gl ;
6
+ use glow as gl;
7
+ use glow :: Context as Gl ;
8
+ use glow :: HasContext ;
9
9
use std:: collections:: HashMap ;
10
+ use std:: num:: NonZero ;
10
11
use surfman:: Device as SurfmanDevice ;
11
12
use webxr_api:: ContextId ;
12
13
use webxr_api:: GLContexts ;
13
14
use webxr_api:: LayerId ;
14
15
16
+ pub ( crate ) fn framebuffer ( framebuffer : u32 ) -> Option < gl:: NativeFramebuffer > {
17
+ NonZero :: new ( framebuffer) . map ( gl:: NativeFramebuffer )
18
+ }
19
+
15
20
// A utility to clear a color texture and optional depth/stencil texture
16
21
pub ( crate ) struct GlClearer {
17
- fbos : HashMap < ( LayerId , GLuint , Option < GLuint > ) , GLuint > ,
22
+ fbos : HashMap <
23
+ (
24
+ LayerId ,
25
+ Option < gl:: NativeTexture > ,
26
+ Option < gl:: NativeTexture > ,
27
+ ) ,
28
+ Option < gl:: NativeFramebuffer > ,
29
+ > ,
18
30
should_reverse_winding : bool ,
19
31
}
20
32
@@ -31,10 +43,10 @@ impl GlClearer {
31
43
& mut self ,
32
44
gl : & Gl ,
33
45
layer_id : LayerId ,
34
- color : GLuint ,
35
- color_target : GLuint ,
36
- depth_stencil : Option < GLuint > ,
37
- ) -> GLuint {
46
+ color : Option < gl :: NativeTexture > ,
47
+ color_target : u32 ,
48
+ depth_stencil : Option < gl :: NativeTexture > ,
49
+ ) -> Option < gl :: NativeFramebuffer > {
38
50
let should_reverse_winding = self . should_reverse_winding ;
39
51
* self
40
52
. fbos
@@ -43,41 +55,41 @@ impl GlClearer {
43
55
// Save the current GL state
44
56
let mut bound_fbos = [ 0 , 0 ] ;
45
57
unsafe {
46
- gl. get_integer_v ( gl:: DRAW_FRAMEBUFFER_BINDING , & mut bound_fbos[ 0 ..] ) ;
47
- gl. get_integer_v ( gl:: READ_FRAMEBUFFER_BINDING , & mut bound_fbos[ 1 ..] ) ;
48
- }
58
+ gl. get_parameter_i32_slice ( gl:: DRAW_FRAMEBUFFER_BINDING , & mut bound_fbos[ 0 ..] ) ;
59
+ gl. get_parameter_i32_slice ( gl:: READ_FRAMEBUFFER_BINDING , & mut bound_fbos[ 1 ..] ) ;
49
60
50
- // Generate and set attachments of a new FBO
51
- let fbo = gl. gen_framebuffers ( 1 ) [ 0 ] ;
61
+ // Generate and set attachments of a new FBO
62
+ let fbo = gl. create_framebuffer ( ) . ok ( ) ;
52
63
53
- gl. bind_framebuffer ( gl:: FRAMEBUFFER , fbo) ;
54
- gl. framebuffer_texture_2d (
55
- gl:: FRAMEBUFFER ,
56
- gl:: COLOR_ATTACHMENT0 ,
57
- color_target,
58
- color,
59
- 0 ,
60
- ) ;
61
- gl. framebuffer_texture_2d (
62
- gl:: FRAMEBUFFER ,
63
- gl:: DEPTH_STENCIL_ATTACHMENT ,
64
- gl:: TEXTURE_2D ,
65
- depth_stencil. unwrap_or ( 0 ) ,
66
- 0 ,
67
- ) ;
64
+ gl. bind_framebuffer ( gl:: FRAMEBUFFER , fbo) ;
65
+ gl. framebuffer_texture_2d (
66
+ gl:: FRAMEBUFFER ,
67
+ gl:: COLOR_ATTACHMENT0 ,
68
+ color_target,
69
+ color,
70
+ 0 ,
71
+ ) ;
72
+ gl. framebuffer_texture_2d (
73
+ gl:: FRAMEBUFFER ,
74
+ gl:: DEPTH_STENCIL_ATTACHMENT ,
75
+ gl:: TEXTURE_2D ,
76
+ depth_stencil,
77
+ 0 ,
78
+ ) ;
68
79
69
- // Necessary if using an OpenXR runtime that does not support mutable FOV,
70
- // as flipping the projection matrix necessitates reversing the winding order.
71
- if should_reverse_winding {
72
- gl. front_face ( gl:: CW ) ;
73
- }
80
+ // Necessary if using an OpenXR runtime that does not support mutable FOV,
81
+ // as flipping the projection matrix necessitates reversing the winding order.
82
+ if should_reverse_winding {
83
+ gl. front_face ( gl:: CW ) ;
84
+ }
74
85
75
- // Restore the GL state
76
- gl. bind_framebuffer ( gl:: DRAW_FRAMEBUFFER , bound_fbos[ 0 ] as GLuint ) ;
77
- gl. bind_framebuffer ( gl:: READ_FRAMEBUFFER , bound_fbos[ 1 ] as GLuint ) ;
78
- debug_assert_eq ! ( gl. get_error( ) , gl:: NO_ERROR ) ;
86
+ // Restore the GL state
87
+ gl. bind_framebuffer ( gl:: DRAW_FRAMEBUFFER , framebuffer ( bound_fbos[ 0 ] as _ ) ) ;
88
+ gl. bind_framebuffer ( gl:: READ_FRAMEBUFFER , framebuffer ( bound_fbos[ 1 ] as _ ) ) ;
89
+ debug_assert_eq ! ( gl. get_error( ) , gl:: NO_ERROR ) ;
79
90
80
- fbo
91
+ fbo
92
+ }
81
93
} )
82
94
}
83
95
@@ -87,75 +99,70 @@ impl GlClearer {
87
99
contexts : & mut dyn GLContexts < SurfmanGL > ,
88
100
context_id : ContextId ,
89
101
layer_id : LayerId ,
90
- color : GLuint ,
91
- color_target : GLuint ,
92
- depth_stencil : Option < GLuint > ,
102
+ color : Option < glow :: NativeTexture > ,
103
+ color_target : u32 ,
104
+ depth_stencil : Option < glow :: NativeTexture > ,
93
105
) {
94
106
let gl = match contexts. bindings ( device, context_id) {
95
107
None => return ,
96
108
Some ( gl) => gl,
97
109
} ;
98
110
let fbo = self . fbo ( gl, layer_id, color, color_target, depth_stencil) ;
99
-
100
- // Save the current GL state
101
- let mut bound_fbos = [ 0 , 0 ] ;
102
- let mut clear_color = [ 0. , 0. , 0. , 0. ] ;
103
- let mut clear_depth = [ 0. ] ;
104
- let mut clear_stencil = [ 0 ] ;
105
- let mut color_mask = [ 0 , 0 , 0 , 0 ] ;
106
- let mut depth_mask = [ 0 ] ;
107
- let mut stencil_mask = [ 0 ] ;
108
- let scissor_enabled = gl. is_enabled ( gl:: SCISSOR_TEST ) ;
109
- let rasterizer_enabled = gl. is_enabled ( gl:: RASTERIZER_DISCARD ) ;
110
111
unsafe {
111
- gl. get_integer_v ( gl:: DRAW_FRAMEBUFFER_BINDING , & mut bound_fbos[ 0 ..] ) ;
112
- gl. get_integer_v ( gl:: READ_FRAMEBUFFER_BINDING , & mut bound_fbos[ 1 ..] ) ;
113
- gl. get_float_v ( gl:: COLOR_CLEAR_VALUE , & mut clear_color[ ..] ) ;
114
- gl. get_float_v ( gl:: DEPTH_CLEAR_VALUE , & mut clear_depth[ ..] ) ;
115
- gl. get_integer_v ( gl:: STENCIL_CLEAR_VALUE , & mut clear_stencil[ ..] ) ;
116
- gl. get_boolean_v ( gl:: DEPTH_WRITEMASK , & mut depth_mask[ ..] ) ;
117
- gl. get_integer_v ( gl:: STENCIL_WRITEMASK , & mut stencil_mask[ ..] ) ;
118
- gl. get_boolean_v ( gl:: COLOR_WRITEMASK , & mut color_mask[ ..] ) ;
119
- }
112
+ // Save the current GL state
113
+ let mut bound_fbos = [ 0 , 0 ] ;
114
+ let mut clear_color = [ 0. , 0. , 0. , 0. ] ;
115
+ let mut clear_depth = [ 0. ] ;
116
+ let mut clear_stencil = [ 0 ] ;
117
+ let color_mask;
118
+ let depth_mask;
119
+ let mut stencil_mask = [ 0 ] ;
120
+ let scissor_enabled = gl. is_enabled ( gl:: SCISSOR_TEST ) ;
121
+ let rasterizer_enabled = gl. is_enabled ( gl:: RASTERIZER_DISCARD ) ;
120
122
121
- // Clear it
122
- gl. bind_framebuffer ( gl:: FRAMEBUFFER , fbo) ;
123
- gl. clear_color ( 0. , 0. , 0. , 1. ) ;
124
- gl. clear_depth ( 1. ) ;
125
- gl. clear_stencil ( 0 ) ;
126
- gl. disable ( gl:: SCISSOR_TEST ) ;
127
- gl. disable ( gl:: RASTERIZER_DISCARD ) ;
128
- gl. depth_mask ( true ) ;
129
- gl. stencil_mask ( 0xFFFFFFFF ) ;
130
- gl. color_mask ( true , true , true , true ) ;
131
- gl. clear ( gl:: COLOR_BUFFER_BIT | gl:: DEPTH_BUFFER_BIT | gl:: STENCIL_BUFFER_BIT ) ;
123
+ gl. get_parameter_i32_slice ( gl:: DRAW_FRAMEBUFFER_BINDING , & mut bound_fbos[ 0 ..] ) ;
124
+ gl. get_parameter_i32_slice ( gl:: READ_FRAMEBUFFER_BINDING , & mut bound_fbos[ 1 ..] ) ;
125
+ gl. get_parameter_f32_slice ( gl:: COLOR_CLEAR_VALUE , & mut clear_color[ ..] ) ;
126
+ gl. get_parameter_f32_slice ( gl:: DEPTH_CLEAR_VALUE , & mut clear_depth[ ..] ) ;
127
+ gl. get_parameter_i32_slice ( gl:: STENCIL_CLEAR_VALUE , & mut clear_stencil[ ..] ) ;
128
+ depth_mask = gl. get_parameter_bool ( gl:: DEPTH_WRITEMASK ) ;
129
+ gl. get_parameter_i32_slice ( gl:: STENCIL_WRITEMASK , & mut stencil_mask[ ..] ) ;
130
+ color_mask = gl. get_parameter_bool_array :: < 4 > ( gl:: COLOR_WRITEMASK ) ;
132
131
133
- // Restore the GL state
134
- gl. bind_framebuffer ( gl:: DRAW_FRAMEBUFFER , bound_fbos[ 0 ] as GLuint ) ;
135
- gl. bind_framebuffer ( gl:: READ_FRAMEBUFFER , bound_fbos[ 1 ] as GLuint ) ;
136
- gl. clear_color (
137
- clear_color[ 0 ] ,
138
- clear_color[ 1 ] ,
139
- clear_color[ 2 ] ,
140
- clear_color[ 3 ] ,
141
- ) ;
142
- gl. color_mask (
143
- color_mask[ 0 ] != 0 ,
144
- color_mask[ 1 ] != 0 ,
145
- color_mask[ 2 ] != 0 ,
146
- color_mask[ 3 ] != 0 ,
147
- ) ;
148
- gl. clear_depth ( clear_depth[ 0 ] as f64 ) ;
149
- gl. clear_stencil ( clear_stencil[ 0 ] ) ;
150
- gl. depth_mask ( depth_mask[ 0 ] != 0 ) ;
151
- gl. stencil_mask ( stencil_mask[ 0 ] as gl:: GLuint ) ;
152
- if scissor_enabled {
153
- gl. enable ( gl:: SCISSOR_TEST ) ;
154
- }
155
- if rasterizer_enabled {
156
- gl. enable ( gl:: RASTERIZER_DISCARD ) ;
132
+ // Clear it
133
+ gl. bind_framebuffer ( gl:: FRAMEBUFFER , fbo) ;
134
+ gl. clear_color ( 0. , 0. , 0. , 1. ) ;
135
+ gl. clear_depth ( 1. ) ;
136
+ gl. clear_stencil ( 0 ) ;
137
+ gl. disable ( gl:: SCISSOR_TEST ) ;
138
+ gl. disable ( gl:: RASTERIZER_DISCARD ) ;
139
+ gl. depth_mask ( true ) ;
140
+ gl. stencil_mask ( 0xFFFFFFFF ) ;
141
+ gl. color_mask ( true , true , true , true ) ;
142
+ gl. clear ( gl:: COLOR_BUFFER_BIT | gl:: DEPTH_BUFFER_BIT | gl:: STENCIL_BUFFER_BIT ) ;
143
+
144
+ // Restore the GL state
145
+ gl. bind_framebuffer ( gl:: DRAW_FRAMEBUFFER , framebuffer ( bound_fbos[ 0 ] as _ ) ) ;
146
+ gl. bind_framebuffer ( gl:: READ_FRAMEBUFFER , framebuffer ( bound_fbos[ 1 ] as _ ) ) ;
147
+ gl. clear_color (
148
+ clear_color[ 0 ] ,
149
+ clear_color[ 1 ] ,
150
+ clear_color[ 2 ] ,
151
+ clear_color[ 3 ] ,
152
+ ) ;
153
+ gl. color_mask ( color_mask[ 0 ] , color_mask[ 1 ] , color_mask[ 2 ] , color_mask[ 3 ] ) ;
154
+ gl. clear_depth ( clear_depth[ 0 ] as f64 ) ;
155
+ gl. clear_stencil ( clear_stencil[ 0 ] ) ;
156
+ gl. depth_mask ( depth_mask) ;
157
+ gl. stencil_mask ( stencil_mask[ 0 ] as _ ) ;
158
+ if scissor_enabled {
159
+ gl. enable ( gl:: SCISSOR_TEST ) ;
160
+ }
161
+ if rasterizer_enabled {
162
+ gl. enable ( gl:: RASTERIZER_DISCARD ) ;
163
+ }
164
+ debug_assert_eq ! ( gl. get_error( ) , gl:: NO_ERROR ) ;
157
165
}
158
- debug_assert_eq ! ( gl. get_error( ) , gl:: NO_ERROR ) ;
159
166
}
160
167
161
168
pub ( crate ) fn destroy_layer (
@@ -173,7 +180,9 @@ impl GlClearer {
173
180
if layer_id != other_id {
174
181
true
175
182
} else {
176
- gl. delete_framebuffers ( & [ fbo] ) ;
183
+ if let Some ( fbo) = fbo {
184
+ unsafe { gl. delete_framebuffer ( fbo) } ;
185
+ }
177
186
false
178
187
}
179
188
} )
0 commit comments