1 use super::*;
2 
3 use slotmap::{new_key_type, SecondaryMap, SlotMap};
4 use std::cell::RefCell;
5 use std_web::unstable::TryInto;
6 use std_web::web::{window, TypedArray};
7 use webgl_stdweb::{
8     WebGL2RenderingContext, WebGLBuffer, WebGLFramebuffer, WebGLProgram, WebGLQuery,
9     WebGLRenderbuffer, WebGLRenderingContext, WebGLSampler, WebGLShader, WebGLSync, WebGLTexture,
10     WebGLTransformFeedback, WebGLUniformLocation, WebGLVertexArrayObject,
11     WebGLVertexArrayObjectOES,
12 };
13 
14 #[derive(Debug)]
15 enum RawRenderingContext {
16     WebGl1(WebGLRenderingContext),
17     WebGl2(WebGL2RenderingContext),
18 }
19 
20 #[derive(Debug)]
21 struct Extensions {
22     pub angle_instanced_arrays: Option<webgl_stdweb::ANGLE_instanced_arrays>,
23     pub ext_blend_minmax: Option<webgl_stdweb::EXT_blend_minmax>,
24     pub ext_color_buffer_float: Option<webgl_stdweb::EXT_color_buffer_float>,
25     pub ext_color_buffer_half_float: Option<webgl_stdweb::EXT_color_buffer_half_float>,
26     pub ext_disjoint_timer_query: Option<webgl_stdweb::EXT_disjoint_timer_query>,
27     pub ext_disjoint_timer_query_webgl2: Option<webgl_stdweb::EXT_disjoint_timer_query_webgl2>,
28     pub ext_float_blend: Option<webgl_stdweb::EXT_float_blend>,
29     pub ext_frag_depth: Option<webgl_stdweb::EXT_frag_depth>,
30     pub ext_srgb: Option<webgl_stdweb::EXT_sRGB>,
31     pub ext_shader_texture_lod: Option<webgl_stdweb::EXT_shader_texture_lod>,
32     pub ext_texture_compression_bptc: Option<webgl_stdweb::EXT_texture_compression_bptc>,
33     pub ext_texture_compression_rgtc: Option<webgl_stdweb::EXT_texture_compression_rgtc>,
34     pub ext_texture_filter_anisotropic: Option<webgl_stdweb::EXT_texture_filter_anisotropic>,
35     pub khr_parallel_shader_compile: Option<webgl_stdweb::KHR_parallel_shader_compile>,
36     pub oes_element_index_uint: Option<webgl_stdweb::OES_element_index_uint>,
37     pub oes_fbo_render_mipmap: Option<webgl_stdweb::OES_fbo_render_mipmap>,
38     pub oes_standard_derivatives: Option<webgl_stdweb::OES_standard_derivatives>,
39     pub oes_texture_float: Option<webgl_stdweb::OES_texture_float>,
40     pub oes_texture_float_linear: Option<webgl_stdweb::OES_texture_float_linear>,
41     pub oes_texture_half_float: Option<webgl_stdweb::OES_texture_half_float>,
42     pub oes_texture_half_float_linear: Option<webgl_stdweb::OES_texture_half_float_linear>,
43     pub oes_vertex_array_object: Option<webgl_stdweb::OES_vertex_array_object>,
44     pub webgl_color_buffer_float: Option<webgl_stdweb::WEBGL_color_buffer_float>,
45     pub webgl_compressed_texture_astc: Option<webgl_stdweb::WEBGL_compressed_texture_astc>,
46     pub webgl_compressed_texture_etc: Option<webgl_stdweb::WEBGL_compressed_texture_etc>,
47     pub webgl_compressed_texture_etc1: Option<webgl_stdweb::WEBGL_compressed_texture_etc1>,
48     pub webgl_compressed_texture_pvrtc: Option<webgl_stdweb::WEBGL_compressed_texture_pvrtc>,
49     pub webgl_compressed_texture_s3tc: Option<webgl_stdweb::WEBGL_compressed_texture_s3tc>,
50     pub webgl_compressed_texture_s3tc_srgb:
51         Option<webgl_stdweb::WEBGL_compressed_texture_s3tc_srgb>,
52     pub webgl_debug_renderer_info: Option<webgl_stdweb::WEBGL_debug_renderer_info>,
53     pub webgl_debug_shaders: Option<webgl_stdweb::WEBGL_debug_shaders>,
54     pub webgl_depth_texture: Option<webgl_stdweb::WEBGL_depth_texture>,
55     pub webgl_draw_buffers: Option<webgl_stdweb::WEBGL_draw_buffers>,
56     pub webgl_lose_context: Option<webgl_stdweb::WEBGL_lose_context>,
57     pub webgl_multiview: Option<webgl_stdweb::WEBGL_multiview>,
58     pub webgl_security_sensitive_resources:
59         Option<webgl_stdweb::WEBGL_security_sensitive_resources>,
60 }
61 
62 // Workaround for stable Rust
63 // See https://github.com/orlp/slotmap/blob/b5df4ac7ee8aa795668bf79ebf8929d2f39bec8e/src/lib.rs#L198
64 type SlotMapWithoutCopy<K, V> = (SlotMap<K, ()>, SecondaryMap<K, V>);
65 
66 type TrackedResource<K, V> = RefCell<SlotMapWithoutCopy<K, V>>;
67 
tracked_resource<K: slotmap::Key, V>() -> TrackedResource<K, V>68 fn tracked_resource<K: slotmap::Key, V>() -> TrackedResource<K, V> {
69     RefCell::new((SlotMap::with_key(), SecondaryMap::new()))
70 }
71 
72 #[derive(Debug)]
73 pub struct Context {
74     raw: RawRenderingContext,
75     extensions: Extensions,
76     shaders: TrackedResource<WebShaderKey, WebGLShader>,
77     programs: TrackedResource<WebProgramKey, WebGLProgram>,
78     buffers: TrackedResource<WebBufferKey, WebGLBuffer>,
79     vertex_arrays: TrackedResource<WebVertexArrayKey, WebGLVertexArrayObject>,
80     vertex_arrays_oes: TrackedResource<WebVertexArrayKey, WebGLVertexArrayObjectOES>,
81     textures: TrackedResource<WebTextureKey, WebGLTexture>,
82     samplers: TrackedResource<WebSamplerKey, WebGLSampler>,
83     fences: TrackedResource<WebFenceKey, WebGLSync>,
84     framebuffers: TrackedResource<WebFramebufferKey, WebGLFramebuffer>,
85     renderbuffers: TrackedResource<WebRenderbufferKey, WebGLRenderbuffer>,
86     queries: TrackedResource<WebQueryKey, WebGLQuery>,
87     transform_feedbacks: TrackedResource<WebTransformFeedbackKey, WebGLTransformFeedback>,
88 }
89 
90 impl Context {
from_webgl1_context(context: WebGLRenderingContext) -> Self91     pub fn from_webgl1_context(context: WebGLRenderingContext) -> Self {
92         let extensions = Extensions {
93             angle_instanced_arrays: context.get_extension::<webgl_stdweb::ANGLE_instanced_arrays>(),
94             ext_blend_minmax: context.get_extension::<webgl_stdweb::EXT_blend_minmax>(),
95             ext_color_buffer_float: context.get_extension::<webgl_stdweb::EXT_color_buffer_float>(),
96             ext_color_buffer_half_float: context
97                 .get_extension::<webgl_stdweb::EXT_color_buffer_half_float>(),
98             ext_disjoint_timer_query: context
99                 .get_extension::<webgl_stdweb::EXT_disjoint_timer_query>(),
100             ext_disjoint_timer_query_webgl2: context
101                 .get_extension::<webgl_stdweb::EXT_disjoint_timer_query_webgl2>(),
102             ext_float_blend: context.get_extension::<webgl_stdweb::EXT_float_blend>(),
103             ext_frag_depth: context.get_extension::<webgl_stdweb::EXT_frag_depth>(),
104             ext_srgb: context.get_extension::<webgl_stdweb::EXT_sRGB>(),
105             ext_shader_texture_lod: context.get_extension::<webgl_stdweb::EXT_shader_texture_lod>(),
106             ext_texture_compression_bptc: context
107                 .get_extension::<webgl_stdweb::EXT_texture_compression_bptc>(),
108             ext_texture_compression_rgtc: context
109                 .get_extension::<webgl_stdweb::EXT_texture_compression_rgtc>(),
110             ext_texture_filter_anisotropic: context
111                 .get_extension::<webgl_stdweb::EXT_texture_filter_anisotropic>(),
112             khr_parallel_shader_compile: context
113                 .get_extension::<webgl_stdweb::KHR_parallel_shader_compile>(),
114             oes_element_index_uint: context.get_extension::<webgl_stdweb::OES_element_index_uint>(),
115             oes_fbo_render_mipmap: context.get_extension::<webgl_stdweb::OES_fbo_render_mipmap>(),
116             oes_standard_derivatives: context
117                 .get_extension::<webgl_stdweb::OES_standard_derivatives>(),
118             oes_texture_float: context.get_extension::<webgl_stdweb::OES_texture_float>(),
119             oes_texture_float_linear: context
120                 .get_extension::<webgl_stdweb::OES_texture_float_linear>(),
121             oes_texture_half_float: context.get_extension::<webgl_stdweb::OES_texture_half_float>(),
122             oes_texture_half_float_linear: context
123                 .get_extension::<webgl_stdweb::OES_texture_half_float_linear>(),
124             oes_vertex_array_object: context
125                 .get_extension::<webgl_stdweb::OES_vertex_array_object>(),
126             webgl_color_buffer_float: context
127                 .get_extension::<webgl_stdweb::WEBGL_color_buffer_float>(),
128             webgl_compressed_texture_astc: context
129                 .get_extension::<webgl_stdweb::WEBGL_compressed_texture_astc>(),
130             webgl_compressed_texture_etc: context
131                 .get_extension::<webgl_stdweb::WEBGL_compressed_texture_etc>(),
132             webgl_compressed_texture_etc1: context
133                 .get_extension::<webgl_stdweb::WEBGL_compressed_texture_etc1>(),
134             webgl_compressed_texture_pvrtc: context
135                 .get_extension::<webgl_stdweb::WEBGL_compressed_texture_pvrtc>(),
136             webgl_compressed_texture_s3tc: context
137                 .get_extension::<webgl_stdweb::WEBGL_compressed_texture_s3tc>(),
138             webgl_compressed_texture_s3tc_srgb: context
139                 .get_extension::<webgl_stdweb::WEBGL_compressed_texture_s3tc_srgb>(
140             ),
141             webgl_debug_renderer_info: context
142                 .get_extension::<webgl_stdweb::WEBGL_debug_renderer_info>(),
143             webgl_debug_shaders: context.get_extension::<webgl_stdweb::WEBGL_debug_shaders>(),
144             webgl_depth_texture: context.get_extension::<webgl_stdweb::WEBGL_depth_texture>(),
145             webgl_draw_buffers: context.get_extension::<webgl_stdweb::WEBGL_draw_buffers>(),
146             webgl_lose_context: context.get_extension::<webgl_stdweb::WEBGL_lose_context>(),
147             webgl_multiview: context.get_extension::<webgl_stdweb::WEBGL_multiview>(),
148             webgl_security_sensitive_resources: context
149                 .get_extension::<webgl_stdweb::WEBGL_security_sensitive_resources>(
150             ),
151         };
152         Self {
153             raw: RawRenderingContext::WebGl1(context),
154             extensions,
155             shaders: tracked_resource(),
156             programs: tracked_resource(),
157             buffers: tracked_resource(),
158             vertex_arrays: tracked_resource(),
159             vertex_arrays_oes: tracked_resource(),
160             textures: tracked_resource(),
161             samplers: tracked_resource(),
162             fences: tracked_resource(),
163             framebuffers: tracked_resource(),
164             renderbuffers: tracked_resource(),
165             queries: tracked_resource(),
166             transform_feedbacks: tracked_resource(),
167         }
168     }
169 
from_webgl2_context(context: WebGL2RenderingContext) -> Self170     pub fn from_webgl2_context(context: WebGL2RenderingContext) -> Self {
171         let extensions = Extensions {
172             angle_instanced_arrays: context.get_extension::<webgl_stdweb::ANGLE_instanced_arrays>(),
173             ext_blend_minmax: context.get_extension::<webgl_stdweb::EXT_blend_minmax>(),
174             ext_color_buffer_float: context.get_extension::<webgl_stdweb::EXT_color_buffer_float>(),
175             ext_color_buffer_half_float: context
176                 .get_extension::<webgl_stdweb::EXT_color_buffer_half_float>(),
177             ext_disjoint_timer_query: context
178                 .get_extension::<webgl_stdweb::EXT_disjoint_timer_query>(),
179             ext_disjoint_timer_query_webgl2: context
180                 .get_extension::<webgl_stdweb::EXT_disjoint_timer_query_webgl2>(),
181             ext_float_blend: context.get_extension::<webgl_stdweb::EXT_float_blend>(),
182             ext_frag_depth: context.get_extension::<webgl_stdweb::EXT_frag_depth>(),
183             ext_srgb: context.get_extension::<webgl_stdweb::EXT_sRGB>(),
184             ext_shader_texture_lod: context.get_extension::<webgl_stdweb::EXT_shader_texture_lod>(),
185             ext_texture_compression_bptc: context
186                 .get_extension::<webgl_stdweb::EXT_texture_compression_bptc>(),
187             ext_texture_compression_rgtc: context
188                 .get_extension::<webgl_stdweb::EXT_texture_compression_rgtc>(),
189             ext_texture_filter_anisotropic: context
190                 .get_extension::<webgl_stdweb::EXT_texture_filter_anisotropic>(),
191             khr_parallel_shader_compile: context
192                 .get_extension::<webgl_stdweb::KHR_parallel_shader_compile>(),
193             oes_element_index_uint: context.get_extension::<webgl_stdweb::OES_element_index_uint>(),
194             oes_fbo_render_mipmap: context.get_extension::<webgl_stdweb::OES_fbo_render_mipmap>(),
195             oes_standard_derivatives: context
196                 .get_extension::<webgl_stdweb::OES_standard_derivatives>(),
197             oes_texture_float: context.get_extension::<webgl_stdweb::OES_texture_float>(),
198             oes_texture_float_linear: context
199                 .get_extension::<webgl_stdweb::OES_texture_float_linear>(),
200             oes_texture_half_float: context.get_extension::<webgl_stdweb::OES_texture_half_float>(),
201             oes_texture_half_float_linear: context
202                 .get_extension::<webgl_stdweb::OES_texture_half_float_linear>(),
203             oes_vertex_array_object: context
204                 .get_extension::<webgl_stdweb::OES_vertex_array_object>(),
205             webgl_color_buffer_float: context
206                 .get_extension::<webgl_stdweb::WEBGL_color_buffer_float>(),
207             webgl_compressed_texture_astc: context
208                 .get_extension::<webgl_stdweb::WEBGL_compressed_texture_astc>(),
209             webgl_compressed_texture_etc: context
210                 .get_extension::<webgl_stdweb::WEBGL_compressed_texture_etc>(),
211             webgl_compressed_texture_etc1: context
212                 .get_extension::<webgl_stdweb::WEBGL_compressed_texture_etc1>(),
213             webgl_compressed_texture_pvrtc: context
214                 .get_extension::<webgl_stdweb::WEBGL_compressed_texture_pvrtc>(),
215             webgl_compressed_texture_s3tc: context
216                 .get_extension::<webgl_stdweb::WEBGL_compressed_texture_s3tc>(),
217             webgl_compressed_texture_s3tc_srgb: context
218                 .get_extension::<webgl_stdweb::WEBGL_compressed_texture_s3tc_srgb>(
219             ),
220             webgl_debug_renderer_info: context
221                 .get_extension::<webgl_stdweb::WEBGL_debug_renderer_info>(),
222             webgl_debug_shaders: context.get_extension::<webgl_stdweb::WEBGL_debug_shaders>(),
223             webgl_depth_texture: context.get_extension::<webgl_stdweb::WEBGL_depth_texture>(),
224             webgl_draw_buffers: context.get_extension::<webgl_stdweb::WEBGL_draw_buffers>(),
225             webgl_lose_context: context.get_extension::<webgl_stdweb::WEBGL_lose_context>(),
226             webgl_multiview: context.get_extension::<webgl_stdweb::WEBGL_multiview>(),
227             webgl_security_sensitive_resources: context
228                 .get_extension::<webgl_stdweb::WEBGL_security_sensitive_resources>(
229             ),
230         };
231         Self {
232             raw: RawRenderingContext::WebGl2(context),
233             extensions,
234             shaders: tracked_resource(),
235             programs: tracked_resource(),
236             buffers: tracked_resource(),
237             vertex_arrays: tracked_resource(),
238             vertex_arrays_oes: tracked_resource(),
239             textures: tracked_resource(),
240             samplers: tracked_resource(),
241             fences: tracked_resource(),
242             framebuffers: tracked_resource(),
243             renderbuffers: tracked_resource(),
244             queries: tracked_resource(),
245             transform_feedbacks: tracked_resource(),
246         }
247     }
248 }
249 
250 new_key_type! { pub struct WebShaderKey; }
251 new_key_type! { pub struct WebProgramKey; }
252 new_key_type! { pub struct WebBufferKey; }
253 new_key_type! { pub struct WebVertexArrayKey; }
254 new_key_type! { pub struct WebTextureKey; }
255 new_key_type! { pub struct WebSamplerKey; }
256 new_key_type! { pub struct WebFenceKey; }
257 new_key_type! { pub struct WebFramebufferKey; }
258 new_key_type! { pub struct WebRenderbufferKey; }
259 new_key_type! { pub struct WebQueryKey; }
260 new_key_type! { pub struct WebTransformFeedbackKey; }
261 
262 impl HasContext for Context {
263     type Shader = WebShaderKey;
264     type Program = WebProgramKey;
265     type Buffer = WebBufferKey;
266     type VertexArray = WebVertexArrayKey;
267     type Texture = WebTextureKey;
268     type Sampler = WebSamplerKey;
269     type Fence = WebFenceKey;
270     type Framebuffer = WebFramebufferKey;
271     type Renderbuffer = WebRenderbufferKey;
272     type Query = WebQueryKey;
273     type UniformLocation = WebGLUniformLocation;
274     type TransformFeedback = WebTransformFeedbackKey;
275 
supports_debug(&self) -> bool276     fn supports_debug(&self) -> bool {
277         false
278     }
279 
create_framebuffer(&self) -> Result<Self::Framebuffer, String>280     unsafe fn create_framebuffer(&self) -> Result<Self::Framebuffer, String> {
281         let raw_framebuffer = match self.raw {
282             RawRenderingContext::WebGl1(ref gl) => gl.create_framebuffer(),
283             RawRenderingContext::WebGl2(ref gl) => gl.create_framebuffer(),
284         };
285 
286         match raw_framebuffer {
287             Some(s) => {
288                 let key = self.framebuffers.borrow_mut().0.insert(());
289                 self.framebuffers.borrow_mut().1.insert(key, s);
290                 Ok(key)
291             }
292             None => Err(String::from("Unable to create framebuffer object")),
293         }
294     }
295 
create_query(&self) -> Result<Self::Query, String>296     unsafe fn create_query(&self) -> Result<Self::Query, String> {
297         let raw_query = match self.raw {
298             RawRenderingContext::WebGl1(ref _gl) => {
299                 return Err(String::from("Query objects are not supported"));
300             }
301             RawRenderingContext::WebGl2(ref gl) => gl.create_query(),
302         };
303 
304         match raw_query {
305             Some(s) => {
306                 let key = self.queries.borrow_mut().0.insert(());
307                 self.queries.borrow_mut().1.insert(key, s);
308                 Ok(key)
309             }
310             None => Err(String::from("Unable to create query object")),
311         }
312     }
313 
create_renderbuffer(&self) -> Result<Self::Renderbuffer, String>314     unsafe fn create_renderbuffer(&self) -> Result<Self::Renderbuffer, String> {
315         let raw_renderbuffer = match self.raw {
316             RawRenderingContext::WebGl1(ref gl) => gl.create_renderbuffer(),
317             RawRenderingContext::WebGl2(ref gl) => gl.create_renderbuffer(),
318         };
319 
320         match raw_renderbuffer {
321             Some(s) => {
322                 let key = self.renderbuffers.borrow_mut().0.insert(());
323                 self.renderbuffers.borrow_mut().1.insert(key, s);
324                 Ok(key)
325             }
326             None => Err(String::from("Unable to create renderbuffer object")),
327         }
328     }
329 
create_sampler(&self) -> Result<Self::Sampler, String>330     unsafe fn create_sampler(&self) -> Result<Self::Sampler, String> {
331         let raw_sampler = match self.raw {
332             RawRenderingContext::WebGl1(ref _gl) => panic!("Sampler objects are not supported"),
333             RawRenderingContext::WebGl2(ref gl) => gl.create_sampler(),
334         };
335 
336         match raw_sampler {
337             Some(s) => {
338                 let key = self.samplers.borrow_mut().0.insert(());
339                 self.samplers.borrow_mut().1.insert(key, s);
340                 Ok(key)
341             }
342             None => Err(String::from("Unable to create sampler object")),
343         }
344     }
345 
create_shader(&self, shader_type: u32) -> Result<Self::Shader, String>346     unsafe fn create_shader(&self, shader_type: u32) -> Result<Self::Shader, String> {
347         let raw_shader = match self.raw {
348             RawRenderingContext::WebGl1(ref gl) => gl.create_shader(shader_type as u32),
349             RawRenderingContext::WebGl2(ref gl) => gl.create_shader(shader_type as u32),
350         };
351 
352         match raw_shader {
353             Some(s) => {
354                 let key = self.shaders.borrow_mut().0.insert(());
355                 self.shaders.borrow_mut().1.insert(key, s);
356                 Ok(key)
357             }
358             None => Err(String::from("Unable to create shader object")),
359         }
360     }
361 
create_texture(&self) -> Result<Self::Texture, String>362     unsafe fn create_texture(&self) -> Result<Self::Texture, String> {
363         let raw_texture = match self.raw {
364             RawRenderingContext::WebGl1(ref gl) => gl.create_texture(),
365             RawRenderingContext::WebGl2(ref gl) => gl.create_texture(),
366         };
367 
368         match raw_texture {
369             Some(t) => {
370                 let key = self.textures.borrow_mut().0.insert(());
371                 self.textures.borrow_mut().1.insert(key, t);
372                 Ok(key)
373             }
374             None => Err(String::from("Unable to create texture object")),
375         }
376     }
377 
delete_shader(&self, shader: Self::Shader)378     unsafe fn delete_shader(&self, shader: Self::Shader) {
379         let mut shaders = self.shaders.borrow_mut();
380         if let Some(ref s) = shaders.1.remove(shader) {
381             match self.raw {
382                 RawRenderingContext::WebGl1(ref gl) => gl.delete_shader(Some(s)),
383                 RawRenderingContext::WebGl2(ref gl) => gl.delete_shader(Some(s)),
384             }
385         }
386     }
387 
shader_source(&self, shader: Self::Shader, source: &str)388     unsafe fn shader_source(&self, shader: Self::Shader, source: &str) {
389         let shaders = self.shaders.borrow();
390         let raw_shader = shaders.1.get_unchecked(shader);
391         match self.raw {
392             RawRenderingContext::WebGl1(ref gl) => gl.shader_source(raw_shader, source),
393             RawRenderingContext::WebGl2(ref gl) => gl.shader_source(raw_shader, source),
394         }
395     }
396 
compile_shader(&self, shader: Self::Shader)397     unsafe fn compile_shader(&self, shader: Self::Shader) {
398         let shaders = self.shaders.borrow();
399         let raw_shader = shaders.1.get_unchecked(shader);
400         match self.raw {
401             RawRenderingContext::WebGl1(ref gl) => gl.compile_shader(raw_shader),
402             RawRenderingContext::WebGl2(ref gl) => gl.compile_shader(raw_shader),
403         }
404     }
405 
get_shader_compile_status(&self, shader: Self::Shader) -> bool406     unsafe fn get_shader_compile_status(&self, shader: Self::Shader) -> bool {
407         let shaders = self.shaders.borrow();
408         let raw_shader = shaders.1.get_unchecked(shader);
409         match self.raw {
410             RawRenderingContext::WebGl1(ref gl) => {
411                 gl.get_shader_parameter(raw_shader, COMPILE_STATUS)
412             }
413             RawRenderingContext::WebGl2(ref gl) => {
414                 gl.get_shader_parameter(raw_shader, COMPILE_STATUS)
415             }
416         }
417         .try_into()
418         .unwrap_or(false)
419     }
420 
get_shader_info_log(&self, shader: Self::Shader) -> String421     unsafe fn get_shader_info_log(&self, shader: Self::Shader) -> String {
422         let shaders = self.shaders.borrow();
423         let raw_shader = shaders.1.get_unchecked(shader);
424         match self.raw {
425             RawRenderingContext::WebGl1(ref gl) => gl.get_shader_info_log(raw_shader),
426             RawRenderingContext::WebGl2(ref gl) => gl.get_shader_info_log(raw_shader),
427         }
428         .unwrap_or_else(|| String::from(""))
429     }
430 
get_tex_image( &self, _target: u32, _level: i32, _format: u32, _ty: u32, _pixels: PixelPackData, )431     unsafe fn get_tex_image(
432         &self,
433         _target: u32,
434         _level: i32,
435         _format: u32,
436         _ty: u32,
437         _pixels: PixelPackData,
438     ) {
439         panic!("Get tex image is not supported");
440     }
441 
create_program(&self) -> Result<Self::Program, String>442     unsafe fn create_program(&self) -> Result<Self::Program, String> {
443         let raw_program = match self.raw {
444             RawRenderingContext::WebGl1(ref gl) => gl.create_program(),
445             RawRenderingContext::WebGl2(ref gl) => gl.create_program(),
446         };
447 
448         match raw_program {
449             Some(p) => {
450                 let key = self.programs.borrow_mut().0.insert(());
451                 self.programs.borrow_mut().1.insert(key, p);
452                 Ok(key)
453             }
454             None => Err(String::from("Unable to create program object")),
455         }
456     }
457 
delete_program(&self, program: Self::Program)458     unsafe fn delete_program(&self, program: Self::Program) {
459         let mut programs = self.programs.borrow_mut();
460         if let Some(ref p) = programs.1.remove(program) {
461             match self.raw {
462                 RawRenderingContext::WebGl1(ref gl) => gl.delete_program(Some(p)),
463                 RawRenderingContext::WebGl2(ref gl) => gl.delete_program(Some(p)),
464             }
465         }
466     }
467 
attach_shader(&self, program: Self::Program, shader: Self::Shader)468     unsafe fn attach_shader(&self, program: Self::Program, shader: Self::Shader) {
469         let programs = self.programs.borrow();
470         let shaders = self.shaders.borrow();
471         let raw_program = programs.1.get_unchecked(program);
472         let raw_shader = shaders.1.get_unchecked(shader);
473         match self.raw {
474             RawRenderingContext::WebGl1(ref gl) => gl.attach_shader(raw_program, raw_shader),
475             RawRenderingContext::WebGl2(ref gl) => gl.attach_shader(raw_program, raw_shader),
476         }
477     }
478 
detach_shader(&self, program: Self::Program, shader: Self::Shader)479     unsafe fn detach_shader(&self, program: Self::Program, shader: Self::Shader) {
480         let programs = self.programs.borrow();
481         let shaders = self.shaders.borrow();
482         let raw_program = programs.1.get_unchecked(program);
483         let raw_shader = shaders.1.get_unchecked(shader);
484         match self.raw {
485             RawRenderingContext::WebGl1(ref gl) => gl.detach_shader(raw_program, raw_shader),
486             RawRenderingContext::WebGl2(ref gl) => gl.detach_shader(raw_program, raw_shader),
487         }
488     }
489 
link_program(&self, program: Self::Program)490     unsafe fn link_program(&self, program: Self::Program) {
491         let programs = self.programs.borrow();
492         let raw_program = programs.1.get_unchecked(program);
493         match self.raw {
494             RawRenderingContext::WebGl1(ref gl) => gl.link_program(raw_program),
495             RawRenderingContext::WebGl2(ref gl) => gl.link_program(raw_program),
496         }
497     }
498 
get_program_link_status(&self, program: Self::Program) -> bool499     unsafe fn get_program_link_status(&self, program: Self::Program) -> bool {
500         let programs = self.programs.borrow();
501         let raw_program = programs.1.get_unchecked(program);
502         match self.raw {
503             RawRenderingContext::WebGl1(ref gl) => {
504                 gl.get_program_parameter(raw_program, LINK_STATUS)
505             }
506             RawRenderingContext::WebGl2(ref gl) => {
507                 gl.get_program_parameter(raw_program, LINK_STATUS)
508             }
509         }
510         .try_into()
511         .unwrap_or(false)
512     }
513 
get_program_info_log(&self, program: Self::Program) -> String514     unsafe fn get_program_info_log(&self, program: Self::Program) -> String {
515         let programs = self.programs.borrow();
516         let raw_program = programs.1.get_unchecked(program);
517         match self.raw {
518             RawRenderingContext::WebGl1(ref gl) => gl.get_program_info_log(raw_program),
519             RawRenderingContext::WebGl2(ref gl) => gl.get_program_info_log(raw_program),
520         }
521         .unwrap_or_else(|| String::from(""))
522     }
523 
get_active_uniforms(&self, program: Self::Program) -> u32524     unsafe fn get_active_uniforms(&self, program: Self::Program) -> u32 {
525         let programs = self.programs.borrow();
526         let raw_program = programs.1.get_unchecked(program);
527         match self.raw {
528             RawRenderingContext::WebGl1(ref gl) => {
529                 gl.get_program_parameter(raw_program, WebGLRenderingContext::ACTIVE_UNIFORMS)
530             }
531             RawRenderingContext::WebGl2(ref gl) => {
532                 gl.get_program_parameter(raw_program, WebGL2RenderingContext::ACTIVE_UNIFORMS)
533             }
534         }
535         .try_into()
536         .map(|v: f64| v as u32)
537         .unwrap_or(0)
538     }
539 
get_active_uniform( &self, program: Self::Program, index: u32, ) -> Option<ActiveUniform>540     unsafe fn get_active_uniform(
541         &self,
542         program: Self::Program,
543         index: u32,
544     ) -> Option<ActiveUniform> {
545         let programs = self.programs.borrow();
546         let raw_program = programs.1.get_unchecked(program);
547         match self.raw {
548             RawRenderingContext::WebGl1(ref gl) => {
549                 gl.get_active_uniform(raw_program, index)
550                     .map(|au| ActiveUniform {
551                         size: au.size(),
552                         utype: au.type_(),
553                         name: au.name(),
554                     })
555             }
556             RawRenderingContext::WebGl2(ref gl) => {
557                 gl.get_active_uniform(raw_program, index)
558                     .map(|au| ActiveUniform {
559                         size: au.size(),
560                         utype: au.type_(),
561                         name: au.name(),
562                     })
563             }
564         }
565     }
566 
use_program(&self, program: Option<Self::Program>)567     unsafe fn use_program(&self, program: Option<Self::Program>) {
568         let programs = self.programs.borrow();
569         let raw_program = program.map(|p| programs.1.get_unchecked(p));
570         match self.raw {
571             RawRenderingContext::WebGl1(ref gl) => gl.use_program(raw_program),
572             RawRenderingContext::WebGl2(ref gl) => gl.use_program(raw_program),
573         }
574     }
575 
create_buffer(&self) -> Result<Self::Buffer, String>576     unsafe fn create_buffer(&self) -> Result<Self::Buffer, String> {
577         let raw_buffer = match self.raw {
578             RawRenderingContext::WebGl1(ref gl) => gl.create_buffer(),
579             RawRenderingContext::WebGl2(ref gl) => gl.create_buffer(),
580         };
581 
582         match raw_buffer {
583             Some(p) => {
584                 let key = self.buffers.borrow_mut().0.insert(());
585                 self.buffers.borrow_mut().1.insert(key, p);
586                 Ok(key)
587             }
588             None => Err(String::from("Unable to create buffer object")),
589         }
590     }
591 
bind_buffer(&self, target: u32, buffer: Option<Self::Buffer>)592     unsafe fn bind_buffer(&self, target: u32, buffer: Option<Self::Buffer>) {
593         let buffers = self.buffers.borrow();
594         let raw_buffer = buffer.map(|b| buffers.1.get_unchecked(b));
595         match self.raw {
596             RawRenderingContext::WebGl1(ref gl) => gl.bind_buffer(target, raw_buffer),
597             RawRenderingContext::WebGl2(ref gl) => gl.bind_buffer(target, raw_buffer),
598         }
599     }
600 
bind_buffer_base(&self, target: u32, index: u32, buffer: Option<Self::Buffer>)601     unsafe fn bind_buffer_base(&self, target: u32, index: u32, buffer: Option<Self::Buffer>) {
602         let buffers = self.buffers.borrow();
603         let raw_buffer = buffer.map(|b| buffers.1.get_unchecked(b));
604         match self.raw {
605             RawRenderingContext::WebGl1(ref _gl) => {
606                 panic!("bind_buffer_base not supported on webgl1")
607             }
608             RawRenderingContext::WebGl2(ref gl) => gl.bind_buffer_base(target, index, raw_buffer),
609         }
610     }
611 
bind_buffer_range( &self, target: u32, index: u32, buffer: Option<Self::Buffer>, offset: i32, size: i32, )612     unsafe fn bind_buffer_range(
613         &self,
614         target: u32,
615         index: u32,
616         buffer: Option<Self::Buffer>,
617         offset: i32,
618         size: i32,
619     ) {
620         let buffers = self.buffers.borrow();
621         let raw_buffer = buffer.map(|b| buffers.1.get_unchecked(b));
622         match self.raw {
623             RawRenderingContext::WebGl1(ref _gl) => {
624                 panic!("bind_buffer_range not supported on webgl1");
625             }
626             RawRenderingContext::WebGl2(ref gl) => {
627                 gl.bind_buffer_range(target, index, raw_buffer, offset as i64, size as i64);
628             }
629         }
630     }
631 
bind_framebuffer(&self, target: u32, framebuffer: Option<Self::Framebuffer>)632     unsafe fn bind_framebuffer(&self, target: u32, framebuffer: Option<Self::Framebuffer>) {
633         let framebuffers = self.framebuffers.borrow();
634         let raw_framebuffer = framebuffer.map(|f| framebuffers.1.get_unchecked(f));
635         match self.raw {
636             RawRenderingContext::WebGl1(ref gl) => gl.bind_framebuffer(target, raw_framebuffer),
637             RawRenderingContext::WebGl2(ref gl) => gl.bind_framebuffer(target, raw_framebuffer),
638         }
639     }
640 
bind_renderbuffer(&self, target: u32, renderbuffer: Option<Self::Renderbuffer>)641     unsafe fn bind_renderbuffer(&self, target: u32, renderbuffer: Option<Self::Renderbuffer>) {
642         let renderbuffers = self.renderbuffers.borrow();
643         let raw_renderbuffer = renderbuffer.map(|r| renderbuffers.1.get_unchecked(r));
644         match self.raw {
645             RawRenderingContext::WebGl1(ref gl) => gl.bind_renderbuffer(target, raw_renderbuffer),
646             RawRenderingContext::WebGl2(ref gl) => gl.bind_renderbuffer(target, raw_renderbuffer),
647         }
648     }
649 
blit_framebuffer( &self, src_x0: i32, src_y0: i32, src_x1: i32, src_y1: i32, dst_x0: i32, dst_y0: i32, dst_x1: i32, dst_y1: i32, mask: u32, filter: u32, )650     unsafe fn blit_framebuffer(
651         &self,
652         src_x0: i32,
653         src_y0: i32,
654         src_x1: i32,
655         src_y1: i32,
656         dst_x0: i32,
657         dst_y0: i32,
658         dst_x1: i32,
659         dst_y1: i32,
660         mask: u32,
661         filter: u32,
662     ) {
663         match self.raw {
664             RawRenderingContext::WebGl1(ref _gl) => {
665                 panic!("framebuffer blitting usupported in webgl1")
666             }
667             RawRenderingContext::WebGl2(ref gl) => {
668                 gl.blit_framebuffer(
669                     src_x0, src_y0, src_x1, src_y1, dst_x0, dst_y0, dst_x1, dst_y1, mask, filter,
670                 );
671             }
672         }
673     }
674 
create_vertex_array(&self) -> Result<Self::VertexArray, String>675     unsafe fn create_vertex_array(&self) -> Result<Self::VertexArray, String> {
676         match self.raw {
677             RawRenderingContext::WebGl1(ref _gl) => {
678                 match &self.extensions.oes_vertex_array_object {
679                     Some(extension) => match extension.create_vertex_array_oes() {
680                         Some(va) => {
681                             let key = self.vertex_arrays_oes.borrow_mut().0.insert(());
682                             self.vertex_arrays_oes.borrow_mut().1.insert(key, va);
683                             Ok(key)
684                         }
685                         None => Err(String::from("Unable to create vertex array object")),
686                     },
687                     None => panic!("Vertex array objects are not supported"),
688                 }
689             }
690             RawRenderingContext::WebGl2(ref gl) => match gl.create_vertex_array() {
691                 Some(va) => {
692                     let key = self.vertex_arrays.borrow_mut().0.insert(());
693                     self.vertex_arrays.borrow_mut().1.insert(key, va);
694                     Ok(key)
695                 }
696                 None => Err(String::from("Unable to create vertex array object")),
697             },
698         }
699     }
700 
delete_vertex_array(&self, vertex_array: Self::VertexArray)701     unsafe fn delete_vertex_array(&self, vertex_array: Self::VertexArray) {
702         match self.raw {
703             RawRenderingContext::WebGl1(ref _gl) => {
704                 match &self.extensions.oes_vertex_array_object {
705                     Some(extension) => {
706                         let mut vertex_arrays_oes = self.vertex_arrays_oes.borrow_mut();
707                         extension.delete_vertex_array_oes(
708                             vertex_arrays_oes.1.remove(vertex_array).as_ref(),
709                         )
710                     }
711                     None => panic!("Vertex array objects are not supported"),
712                 }
713             }
714             RawRenderingContext::WebGl2(ref gl) => {
715                 let mut vertex_arrays = self.vertex_arrays.borrow_mut();
716                 gl.delete_vertex_array(vertex_arrays.1.remove(vertex_array).as_ref());
717             }
718         }
719     }
720 
bind_vertex_array(&self, vertex_array: Option<Self::VertexArray>)721     unsafe fn bind_vertex_array(&self, vertex_array: Option<Self::VertexArray>) {
722         match self.raw {
723             RawRenderingContext::WebGl1(ref _gl) => {
724                 match &self.extensions.oes_vertex_array_object {
725                     Some(extension) => {
726                         let vertex_arrays_oes = self.vertex_arrays_oes.borrow();
727                         let raw_vertex_array_oes =
728                             vertex_array.map(|va| vertex_arrays_oes.1.get_unchecked(va));
729                         extension.bind_vertex_array_oes(raw_vertex_array_oes);
730                     }
731                     None => panic!("Vertex array objects are not supported"),
732                 }
733             }
734             RawRenderingContext::WebGl2(ref gl) => {
735                 let vertex_arrays = self.vertex_arrays.borrow();
736                 let raw_vertex_array = vertex_array.map(|va| vertex_arrays.1.get_unchecked(va));
737                 gl.bind_vertex_array(raw_vertex_array);
738             }
739         }
740     }
741 
clear_color(&self, red: f32, green: f32, blue: f32, alpha: f32)742     unsafe fn clear_color(&self, red: f32, green: f32, blue: f32, alpha: f32) {
743         match self.raw {
744             RawRenderingContext::WebGl1(ref gl) => gl.clear_color(red, green, blue, alpha),
745             RawRenderingContext::WebGl2(ref gl) => gl.clear_color(red, green, blue, alpha),
746         }
747     }
748 
supports_f64_precision() -> bool749     unsafe fn supports_f64_precision() -> bool {
750         false
751     }
752 
clear_depth_f64(&self, _depth: f64)753     unsafe fn clear_depth_f64(&self, _depth: f64) {
754         panic!("64-bit float precision is not supported in WebGL");
755     }
756 
clear_depth_f32(&self, depth: f32)757     unsafe fn clear_depth_f32(&self, depth: f32) {
758         match self.raw {
759             RawRenderingContext::WebGl1(ref gl) => gl.clear_depth(depth),
760             RawRenderingContext::WebGl2(ref gl) => gl.clear_depth(depth),
761         }
762     }
763 
clear_stencil(&self, stencil: i32)764     unsafe fn clear_stencil(&self, stencil: i32) {
765         match self.raw {
766             RawRenderingContext::WebGl1(ref gl) => gl.clear_stencil(stencil),
767             RawRenderingContext::WebGl2(ref gl) => gl.clear_stencil(stencil),
768         }
769     }
770 
clear(&self, mask: u32)771     unsafe fn clear(&self, mask: u32) {
772         match self.raw {
773             RawRenderingContext::WebGl1(ref gl) => gl.clear(mask),
774             RawRenderingContext::WebGl2(ref gl) => gl.clear(mask),
775         }
776     }
777 
patch_parameter_i32(&self, _parameter: u32, _value: i32)778     unsafe fn patch_parameter_i32(&self, _parameter: u32, _value: i32) {
779         panic!("Patch parameter is not supported");
780     }
781 
pixel_store_i32(&self, parameter: u32, value: i32)782     unsafe fn pixel_store_i32(&self, parameter: u32, value: i32) {
783         match self.raw {
784             RawRenderingContext::WebGl1(ref gl) => gl.pixel_storei(parameter, value),
785             RawRenderingContext::WebGl2(ref gl) => gl.pixel_storei(parameter, value),
786         }
787     }
788 
pixel_store_bool(&self, parameter: u32, value: bool)789     unsafe fn pixel_store_bool(&self, parameter: u32, value: bool) {
790         match self.raw {
791             RawRenderingContext::WebGl1(ref gl) => gl.pixel_storei(parameter, value as i32),
792             RawRenderingContext::WebGl2(ref gl) => gl.pixel_storei(parameter, value as i32),
793         }
794     }
795 
bind_frag_data_location( &self, _program: Self::Program, _color_number: u32, _name: &str, )796     unsafe fn bind_frag_data_location(
797         &self,
798         _program: Self::Program,
799         _color_number: u32,
800         _name: &str,
801     ) {
802         panic!("Bind frag data location is not supported");
803     }
804 
buffer_data_size(&self, target: u32, size: i32, usage: u32)805     unsafe fn buffer_data_size(&self, target: u32, size: i32, usage: u32) {
806         match self.raw {
807             RawRenderingContext::WebGl1(ref gl) => gl.buffer_data(target, size as i64, usage),
808             RawRenderingContext::WebGl2(ref gl) => gl.buffer_data(target, size as i64, usage),
809         }
810     }
811 
buffer_data_u8_slice(&self, target: u32, data: &[u8], usage: u32)812     unsafe fn buffer_data_u8_slice(&self, target: u32, data: &[u8], usage: u32) {
813         match self.raw {
814             RawRenderingContext::WebGl1(ref gl) => {
815                 let array: TypedArray<u8> = data.into();
816                 gl.buffer_data_1(target, Some(&array.buffer()), usage)
817             }
818             RawRenderingContext::WebGl2(ref gl) => {
819                 gl.buffer_data_2(target, data, usage, 0, data.len() as u32)
820             }
821         }
822     }
823 
buffer_sub_data_u8_slice(&self, target: u32, offset: i32, src_data: &[u8])824     unsafe fn buffer_sub_data_u8_slice(&self, target: u32, offset: i32, src_data: &[u8]) {
825         match self.raw {
826             RawRenderingContext::WebGl1(ref gl) => {
827                 let array: TypedArray<u8> = src_data.into();
828                 gl.buffer_sub_data(target, offset as i64, &array.buffer())
829             }
830             RawRenderingContext::WebGl2(ref gl) => {
831                 gl.buffer_sub_data_1(target, offset as i64, src_data, 0, src_data.len() as u32)
832             }
833         }
834     }
835 
get_buffer_sub_data(&self, target: u32, offset: i32, dst_data: &mut [u8])836     unsafe fn get_buffer_sub_data(&self, target: u32, offset: i32, dst_data: &mut [u8]) {
837         match self.raw {
838             RawRenderingContext::WebGl1(ref _gl) => panic!("get_buffer_sub_data not supported"),
839             RawRenderingContext::WebGl2(ref gl) => gl.get_buffer_sub_data(
840                 target,
841                 offset as i64,
842                 dst_data as &[u8],
843                 0,
844                 dst_data.len() as u32,
845             ),
846         }
847     }
848 
buffer_storage(&self, _target: u32, _size: i32, _data: Option<&[u8]>, _flags: u32)849     unsafe fn buffer_storage(&self, _target: u32, _size: i32, _data: Option<&[u8]>, _flags: u32) {
850         panic!("Buffer storage is not supported");
851     }
852 
check_framebuffer_status(&self, target: u32) -> u32853     unsafe fn check_framebuffer_status(&self, target: u32) -> u32 {
854         match self.raw {
855             RawRenderingContext::WebGl1(ref gl) => gl.check_framebuffer_status(target),
856             RawRenderingContext::WebGl2(ref gl) => gl.check_framebuffer_status(target),
857         }
858     }
859 
clear_buffer_i32_slice(&self, target: u32, draw_buffer: u32, values: &mut [i32])860     unsafe fn clear_buffer_i32_slice(&self, target: u32, draw_buffer: u32, values: &mut [i32]) {
861         match self.raw {
862             RawRenderingContext::WebGl1(ref _gl) => {
863                 panic!("Clear buffer with `i32` slice is not supported");
864             }
865             RawRenderingContext::WebGl2(ref gl) => {
866                 gl.clear_bufferiv(target, draw_buffer as i32, values as &[i32], 0);
867             }
868         }
869     }
870 
clear_buffer_u32_slice(&self, target: u32, draw_buffer: u32, values: &mut [u32])871     unsafe fn clear_buffer_u32_slice(&self, target: u32, draw_buffer: u32, values: &mut [u32]) {
872         match self.raw {
873             RawRenderingContext::WebGl1(ref _gl) => {
874                 panic!("Clear buffer with `u32` slice is not supported")
875             }
876             RawRenderingContext::WebGl2(ref gl) => {
877                 gl.clear_bufferuiv(target, draw_buffer as i32, values as &[u32], 0)
878             }
879         }
880     }
881 
clear_buffer_f32_slice(&self, target: u32, draw_buffer: u32, values: &mut [f32])882     unsafe fn clear_buffer_f32_slice(&self, target: u32, draw_buffer: u32, values: &mut [f32]) {
883         match self.raw {
884             RawRenderingContext::WebGl1(ref _gl) => {
885                 panic!("Clear buffer with `f32` slice is not supported")
886             }
887             RawRenderingContext::WebGl2(ref gl) => {
888                 gl.clear_bufferfv(target, draw_buffer as i32, values as &[f32], 0)
889             }
890         }
891     }
892 
clear_buffer_depth_stencil( &self, target: u32, draw_buffer: u32, depth: f32, stencil: i32, )893     unsafe fn clear_buffer_depth_stencil(
894         &self,
895         target: u32,
896         draw_buffer: u32,
897         depth: f32,
898         stencil: i32,
899     ) {
900         match self.raw {
901             RawRenderingContext::WebGl1(ref _gl) => {
902                 panic!("Clear buffer depth stencil is not supported")
903             }
904             RawRenderingContext::WebGl2(ref gl) => {
905                 gl.clear_bufferfi(target, draw_buffer as i32, depth, stencil)
906             }
907         }
908     }
909 
client_wait_sync(&self, _fence: Self::Fence, _flags: u32, _timeout: i32) -> u32910     unsafe fn client_wait_sync(&self, _fence: Self::Fence, _flags: u32, _timeout: i32) -> u32 {
911         panic!("Client wait sync is not supported")
912     }
913 
copy_buffer_sub_data( &self, src_target: u32, dst_target: u32, src_offset: i32, dst_offset: i32, size: i32, )914     unsafe fn copy_buffer_sub_data(
915         &self,
916         src_target: u32,
917         dst_target: u32,
918         src_offset: i32,
919         dst_offset: i32,
920         size: i32,
921     ) {
922         match self.raw {
923             RawRenderingContext::WebGl1(ref _gl) => panic!("Copy buffer subdata is not supported"),
924             RawRenderingContext::WebGl2(ref gl) => gl.copy_buffer_sub_data(
925                 src_target,
926                 dst_target,
927                 src_offset as i64,
928                 dst_offset as i64,
929                 size as i64,
930             ),
931         }
932     }
933 
delete_buffer(&self, buffer: Self::Buffer)934     unsafe fn delete_buffer(&self, buffer: Self::Buffer) {
935         let mut buffers = self.buffers.borrow_mut();
936         if let Some(ref b) = buffers.1.remove(buffer) {
937             match self.raw {
938                 RawRenderingContext::WebGl1(ref gl) => gl.delete_buffer(Some(b)),
939                 RawRenderingContext::WebGl2(ref gl) => gl.delete_buffer(Some(b)),
940             }
941         }
942     }
943 
delete_framebuffer(&self, framebuffer: Self::Framebuffer)944     unsafe fn delete_framebuffer(&self, framebuffer: Self::Framebuffer) {
945         let mut framebuffers = self.framebuffers.borrow_mut();
946         if let Some(ref f) = framebuffers.1.remove(framebuffer) {
947             match self.raw {
948                 RawRenderingContext::WebGl1(ref gl) => gl.delete_framebuffer(Some(f)),
949                 RawRenderingContext::WebGl2(ref gl) => gl.delete_framebuffer(Some(f)),
950             }
951         }
952     }
953 
delete_query(&self, query: Self::Query)954     unsafe fn delete_query(&self, query: Self::Query) {
955         let mut queries = self.queries.borrow_mut();
956         if let Some(ref r) = queries.1.remove(query) {
957             match self.raw {
958                 RawRenderingContext::WebGl1(ref _gl) => panic!("Query objects are not supported"),
959                 RawRenderingContext::WebGl2(ref gl) => gl.delete_query(Some(r)),
960             }
961         }
962     }
963 
delete_renderbuffer(&self, renderbuffer: Self::Renderbuffer)964     unsafe fn delete_renderbuffer(&self, renderbuffer: Self::Renderbuffer) {
965         let mut renderbuffers = self.renderbuffers.borrow_mut();
966         if let Some(ref r) = renderbuffers.1.remove(renderbuffer) {
967             match self.raw {
968                 RawRenderingContext::WebGl1(ref gl) => gl.delete_renderbuffer(Some(r)),
969                 RawRenderingContext::WebGl2(ref gl) => gl.delete_renderbuffer(Some(r)),
970             }
971         }
972     }
973 
delete_sampler(&self, sampler: Self::Sampler)974     unsafe fn delete_sampler(&self, sampler: Self::Sampler) {
975         let mut samplers = self.samplers.borrow_mut();
976         if let Some(ref s) = samplers.1.remove(sampler) {
977             match self.raw {
978                 RawRenderingContext::WebGl1(ref _gl) => panic!("Samplers are not supported"),
979                 RawRenderingContext::WebGl2(ref gl) => gl.delete_sampler(Some(s)),
980             }
981         }
982     }
983 
delete_sync(&self, fence: Self::Fence)984     unsafe fn delete_sync(&self, fence: Self::Fence) {
985         let mut fences = self.fences.borrow_mut();
986         if let Some(ref f) = fences.1.remove(fence) {
987             match self.raw {
988                 RawRenderingContext::WebGl1(ref _gl) => panic!("Fences are not supported"),
989                 RawRenderingContext::WebGl2(ref gl) => gl.delete_sync(Some(f)),
990             }
991         }
992     }
993 
delete_texture(&self, texture: Self::Texture)994     unsafe fn delete_texture(&self, texture: Self::Texture) {
995         let mut textures = self.textures.borrow_mut();
996         if let Some(ref t) = textures.1.remove(texture) {
997             match self.raw {
998                 RawRenderingContext::WebGl1(ref gl) => gl.delete_texture(Some(t)),
999                 RawRenderingContext::WebGl2(ref gl) => gl.delete_texture(Some(t)),
1000             }
1001         }
1002     }
1003 
disable(&self, parameter: u32)1004     unsafe fn disable(&self, parameter: u32) {
1005         match self.raw {
1006             RawRenderingContext::WebGl1(ref gl) => gl.disable(parameter),
1007             RawRenderingContext::WebGl2(ref gl) => gl.disable(parameter),
1008         }
1009     }
1010 
disable_draw_buffer(&self, _parameter: u32, _draw_buffer: u32)1011     unsafe fn disable_draw_buffer(&self, _parameter: u32, _draw_buffer: u32) {
1012         panic!("Draw buffer disable is not supported");
1013     }
1014 
disable_vertex_attrib_array(&self, index: u32)1015     unsafe fn disable_vertex_attrib_array(&self, index: u32) {
1016         match self.raw {
1017             RawRenderingContext::WebGl1(ref gl) => gl.disable_vertex_attrib_array(index),
1018             RawRenderingContext::WebGl2(ref gl) => gl.disable_vertex_attrib_array(index),
1019         }
1020     }
1021 
dispatch_compute(&self, _groups_x: u32, _groups_y: u32, _groups_z: u32)1022     unsafe fn dispatch_compute(&self, _groups_x: u32, _groups_y: u32, _groups_z: u32) {
1023         panic!("Dispatch compute is not supported");
1024     }
1025 
dispatch_compute_indirect(&self, _offset: i32)1026     unsafe fn dispatch_compute_indirect(&self, _offset: i32) {
1027         panic!("Dispatch compute indirect is not supported");
1028     }
1029 
draw_arrays(&self, mode: u32, first: i32, count: i32)1030     unsafe fn draw_arrays(&self, mode: u32, first: i32, count: i32) {
1031         match self.raw {
1032             RawRenderingContext::WebGl1(ref gl) => gl.draw_arrays(mode as u32, first, count),
1033             RawRenderingContext::WebGl2(ref gl) => gl.draw_arrays(mode as u32, first, count),
1034         }
1035     }
1036 
draw_arrays_instanced(&self, mode: u32, first: i32, count: i32, instance_count: i32)1037     unsafe fn draw_arrays_instanced(&self, mode: u32, first: i32, count: i32, instance_count: i32) {
1038         match self.raw {
1039             RawRenderingContext::WebGl1(ref _gl) => match &self.extensions.angle_instanced_arrays {
1040                 Some(extension) => {
1041                     extension.draw_arrays_instanced_angle(mode as u32, first, count, instance_count)
1042                 }
1043                 None => panic!("Draw arrays instanced is not supported"),
1044             },
1045             RawRenderingContext::WebGl2(ref gl) => {
1046                 gl.draw_arrays_instanced(mode as u32, first, count, instance_count)
1047             }
1048         }
1049     }
1050 
draw_arrays_instanced_base_instance( &self, _mode: u32, _first: i32, _count: i32, _instance_count: i32, _base_instance: u32, )1051     unsafe fn draw_arrays_instanced_base_instance(
1052         &self,
1053         _mode: u32,
1054         _first: i32,
1055         _count: i32,
1056         _instance_count: i32,
1057         _base_instance: u32,
1058     ) {
1059         panic!("Draw arrays instanced base instance is not supported");
1060     }
1061 
draw_buffer(&self, draw_buffer: u32)1062     unsafe fn draw_buffer(&self, draw_buffer: u32) {
1063         match self.raw {
1064             RawRenderingContext::WebGl1(ref _gl) => {
1065                 panic!("draw_buffer not supported on webgl1");
1066             }
1067             RawRenderingContext::WebGl2(ref gl) => {
1068                 gl.draw_buffers(&[draw_buffer]);
1069             }
1070         }
1071     }
1072 
draw_buffers(&self, buffers: &[u32])1073     unsafe fn draw_buffers(&self, buffers: &[u32]) {
1074         match self.raw {
1075             RawRenderingContext::WebGl1(ref _gl) => {
1076                 panic!("draw_buffers not supported on webgl1");
1077             }
1078             RawRenderingContext::WebGl2(ref gl) => {
1079                 gl.draw_buffers(&buffers);
1080             }
1081         }
1082     }
1083 
draw_elements(&self, mode: u32, count: i32, element_type: u32, offset: i32)1084     unsafe fn draw_elements(&self, mode: u32, count: i32, element_type: u32, offset: i32) {
1085         match self.raw {
1086             RawRenderingContext::WebGl1(ref gl) => {
1087                 gl.draw_elements(mode as u32, count, element_type as u32, offset as i64);
1088             }
1089             RawRenderingContext::WebGl2(ref gl) => {
1090                 gl.draw_elements(mode as u32, count, element_type as u32, offset as i64);
1091             }
1092         }
1093     }
1094 
draw_elements_base_vertex( &self, _mode: u32, _count: i32, _element_type: u32, _offset: i32, _base_vertex: i32, )1095     unsafe fn draw_elements_base_vertex(
1096         &self,
1097         _mode: u32,
1098         _count: i32,
1099         _element_type: u32,
1100         _offset: i32,
1101         _base_vertex: i32,
1102     ) {
1103         panic!("Draw elements base vertex is not supported");
1104     }
1105 
draw_elements_instanced( &self, mode: u32, count: i32, element_type: u32, offset: i32, instance_count: i32, )1106     unsafe fn draw_elements_instanced(
1107         &self,
1108         mode: u32,
1109         count: i32,
1110         element_type: u32,
1111         offset: i32,
1112         instance_count: i32,
1113     ) {
1114         match self.raw {
1115             RawRenderingContext::WebGl1(ref _gl) => match &self.extensions.angle_instanced_arrays {
1116                 None => panic!("Draw elements instanced is not supported"),
1117                 Some(extension) => extension.draw_elements_instanced_angle(
1118                     mode as u32,
1119                     count,
1120                     element_type as u32,
1121                     offset as i64,
1122                     instance_count,
1123                 ),
1124             },
1125             RawRenderingContext::WebGl2(ref gl) => {
1126                 gl.draw_elements_instanced(
1127                     mode as u32,
1128                     count,
1129                     element_type as u32,
1130                     offset as i64,
1131                     instance_count,
1132                 );
1133             }
1134         }
1135     }
1136 
draw_elements_instanced_base_vertex( &self, _mode: u32, _count: i32, _element_type: u32, _offset: i32, _instance_count: i32, _base_vertex: i32, )1137     unsafe fn draw_elements_instanced_base_vertex(
1138         &self,
1139         _mode: u32,
1140         _count: i32,
1141         _element_type: u32,
1142         _offset: i32,
1143         _instance_count: i32,
1144         _base_vertex: i32,
1145     ) {
1146         panic!("Draw elements instanced base vertex is not supported");
1147     }
1148 
draw_elements_instanced_base_vertex_base_instance( &self, _mode: u32, _count: i32, _element_type: u32, _offset: i32, _instance_count: i32, _base_vertex: i32, _base_instance: u32, )1149     unsafe fn draw_elements_instanced_base_vertex_base_instance(
1150         &self,
1151         _mode: u32,
1152         _count: i32,
1153         _element_type: u32,
1154         _offset: i32,
1155         _instance_count: i32,
1156         _base_vertex: i32,
1157         _base_instance: u32,
1158     ) {
1159         panic!("Draw elements instanced base vertex base instance is not supported");
1160     }
1161 
enable(&self, parameter: u32)1162     unsafe fn enable(&self, parameter: u32) {
1163         match self.raw {
1164             RawRenderingContext::WebGl1(ref gl) => gl.enable(parameter),
1165             RawRenderingContext::WebGl2(ref gl) => gl.enable(parameter),
1166         }
1167     }
1168 
is_enabled(&self, parameter: u32) -> bool1169     unsafe fn is_enabled(&self, parameter: u32) -> bool {
1170         match self.raw {
1171             RawRenderingContext::WebGl1(ref gl) => gl.is_enabled(parameter),
1172             RawRenderingContext::WebGl2(ref gl) => gl.is_enabled(parameter),
1173         }
1174     }
1175 
enable_draw_buffer(&self, _parameter: u32, _draw_buffer: u32)1176     unsafe fn enable_draw_buffer(&self, _parameter: u32, _draw_buffer: u32) {
1177         panic!("Draw buffer enable is not supported");
1178     }
1179 
enable_vertex_attrib_array(&self, index: u32)1180     unsafe fn enable_vertex_attrib_array(&self, index: u32) {
1181         match self.raw {
1182             RawRenderingContext::WebGl1(ref gl) => gl.enable_vertex_attrib_array(index),
1183             RawRenderingContext::WebGl2(ref gl) => gl.enable_vertex_attrib_array(index),
1184         }
1185     }
1186 
flush(&self)1187     unsafe fn flush(&self) {
1188         match self.raw {
1189             RawRenderingContext::WebGl1(ref gl) => gl.flush(),
1190             RawRenderingContext::WebGl2(ref gl) => gl.flush(),
1191         }
1192     }
1193 
framebuffer_renderbuffer( &self, target: u32, attachment: u32, renderbuffer_target: u32, renderbuffer: Option<Self::Renderbuffer>, )1194     unsafe fn framebuffer_renderbuffer(
1195         &self,
1196         target: u32,
1197         attachment: u32,
1198         renderbuffer_target: u32,
1199         renderbuffer: Option<Self::Renderbuffer>,
1200     ) {
1201         let renderbuffers = self.renderbuffers.borrow();
1202         let raw_renderbuffer = renderbuffer.map(|r| renderbuffers.1.get_unchecked(r));
1203         match self.raw {
1204             RawRenderingContext::WebGl1(ref _gl) => {
1205                 panic!("Framebuffer renderbuffer is not supported");
1206             }
1207             RawRenderingContext::WebGl2(ref gl) => gl.framebuffer_renderbuffer(
1208                 target,
1209                 attachment,
1210                 renderbuffer_target,
1211                 raw_renderbuffer,
1212             ),
1213         }
1214     }
1215 
framebuffer_texture( &self, _target: u32, _attachment: u32, _texture: Option<Self::Texture>, _level: i32, )1216     unsafe fn framebuffer_texture(
1217         &self,
1218         _target: u32,
1219         _attachment: u32,
1220         _texture: Option<Self::Texture>,
1221         _level: i32,
1222     ) {
1223         panic!("Framebuffer texture is not supported");
1224     }
1225 
framebuffer_texture_2d( &self, target: u32, attachment: u32, texture_target: u32, texture: Option<Self::Texture>, level: i32, )1226     unsafe fn framebuffer_texture_2d(
1227         &self,
1228         target: u32,
1229         attachment: u32,
1230         texture_target: u32,
1231         texture: Option<Self::Texture>,
1232         level: i32,
1233     ) {
1234         let textures = self.textures.borrow();
1235         let raw_texture = texture.map(|t| textures.1.get_unchecked(t));
1236         match self.raw {
1237             RawRenderingContext::WebGl1(ref gl) => {
1238                 gl.framebuffer_texture2_d(target, attachment, texture_target, raw_texture, level);
1239             }
1240             RawRenderingContext::WebGl2(ref gl) => {
1241                 gl.framebuffer_texture2_d(target, attachment, texture_target, raw_texture, level);
1242             }
1243         }
1244     }
1245 
framebuffer_texture_3d( &self, _target: u32, _attachment: u32, _texture_target: u32, _texture: Option<Self::Texture>, _level: i32, _layer: i32, )1246     unsafe fn framebuffer_texture_3d(
1247         &self,
1248         _target: u32,
1249         _attachment: u32,
1250         _texture_target: u32,
1251         _texture: Option<Self::Texture>,
1252         _level: i32,
1253         _layer: i32,
1254     ) {
1255         panic!("Framebuffer texture 3D is not supported");
1256     }
1257 
framebuffer_texture_layer( &self, target: u32, attachment: u32, texture: Option<Self::Texture>, level: i32, layer: i32, )1258     unsafe fn framebuffer_texture_layer(
1259         &self,
1260         target: u32,
1261         attachment: u32,
1262         texture: Option<Self::Texture>,
1263         level: i32,
1264         layer: i32,
1265     ) {
1266         let textures = self.textures.borrow();
1267         let raw_texture = texture.map(|t| textures.1.get_unchecked(t));
1268         match self.raw {
1269             RawRenderingContext::WebGl1(ref _gl) => {
1270                 panic!("Framebuffer texture layer is not supported");
1271             }
1272             RawRenderingContext::WebGl2(ref gl) => {
1273                 gl.framebuffer_texture_layer(target, attachment, raw_texture, level, layer);
1274             }
1275         }
1276     }
1277 
front_face(&self, value: u32)1278     unsafe fn front_face(&self, value: u32) {
1279         match self.raw {
1280             RawRenderingContext::WebGl1(ref gl) => gl.front_face(value as u32),
1281             RawRenderingContext::WebGl2(ref gl) => gl.front_face(value as u32),
1282         }
1283     }
1284 
get_error(&self) -> u321285     unsafe fn get_error(&self) -> u32 {
1286         match self.raw {
1287             RawRenderingContext::WebGl1(ref gl) => gl.get_error(),
1288             RawRenderingContext::WebGl2(ref gl) => gl.get_error(),
1289         }
1290     }
1291 
get_tex_parameter_i32(&self, target: u32, parameter: u32) -> i321292     unsafe fn get_tex_parameter_i32(&self, target: u32, parameter: u32) -> i32 {
1293         match self.raw {
1294             RawRenderingContext::WebGl1(ref gl) => gl.get_tex_parameter(target, parameter),
1295             RawRenderingContext::WebGl2(ref gl) => gl.get_tex_parameter(target, parameter),
1296         }
1297         .try_into()
1298         .map(|v: f64| v as i32)
1299         // Errors will be caught by the browser or through `get_error`
1300         // so return a default instead
1301         .unwrap_or(0)
1302     }
1303 
get_buffer_parameter_i32(&self, target: u32, parameter: u32) -> i321304     unsafe fn get_buffer_parameter_i32(&self, target: u32, parameter: u32) -> i32 {
1305         match self.raw {
1306             RawRenderingContext::WebGl1(ref gl) => gl.get_buffer_parameter(target, parameter),
1307             RawRenderingContext::WebGl2(ref gl) => gl.get_buffer_parameter(target, parameter),
1308         }
1309         .try_into()
1310         .map(|v: f64| v as i32)
1311         // Errors will be caught by the browser or through `get_error`
1312         // so return a default instead
1313         .unwrap_or(0)
1314     }
1315 
get_parameter_i32(&self, parameter: u32) -> i321316     unsafe fn get_parameter_i32(&self, parameter: u32) -> i32 {
1317         match self.raw {
1318             RawRenderingContext::WebGl1(ref gl) => gl.get_parameter(parameter),
1319             RawRenderingContext::WebGl2(ref gl) => gl.get_parameter(parameter),
1320         }
1321         .try_into()
1322         .map(|v: f64| v as i32)
1323         // Errors will be caught by the browser or through `get_error`
1324         // so return a default instead
1325         .unwrap_or(0)
1326     }
1327 
get_parameter_indexed_i32(&self, parameter: u32, index: u32) -> i321328     unsafe fn get_parameter_indexed_i32(&self, parameter: u32, index: u32) -> i32 {
1329         match self.raw {
1330             RawRenderingContext::WebGl1(ref _gl) => {
1331                 panic!("Get parameter indexed is not supported")
1332             }
1333             RawRenderingContext::WebGl2(ref gl) => gl.get_indexed_parameter(parameter, index),
1334         }
1335         .try_into()
1336         .map(|v: f64| v as i32)
1337         // Errors will be caught by the browser or through `get_error`
1338         // so return a default instead
1339         .unwrap_or(0)
1340     }
1341 
get_parameter_indexed_string(&self, parameter: u32, index: u32) -> String1342     unsafe fn get_parameter_indexed_string(&self, parameter: u32, index: u32) -> String {
1343         match self.raw {
1344             RawRenderingContext::WebGl1(ref _gl) => {
1345                 panic!("Get parameter indexed is not supported")
1346             }
1347             RawRenderingContext::WebGl2(ref gl) => gl.get_indexed_parameter(parameter, index),
1348         }
1349         .try_into()
1350         // Errors will be caught by the browser or through `get_error`
1351         // so return a default instead
1352         .unwrap_or_else(|_| String::from(""))
1353     }
1354 
get_parameter_string(&self, parameter: u32) -> String1355     unsafe fn get_parameter_string(&self, parameter: u32) -> String {
1356         match self.raw {
1357             RawRenderingContext::WebGl1(ref gl) => gl.get_parameter(parameter),
1358             RawRenderingContext::WebGl2(ref gl) => gl.get_parameter(parameter),
1359         }
1360         .try_into()
1361         // Errors will be caught by the browser or through `get_error`
1362         // so return a default instead
1363         .unwrap_or_else(|_| String::from(""))
1364     }
1365 
get_uniform_location( &self, program: Self::Program, name: &str, ) -> Option<Self::UniformLocation>1366     unsafe fn get_uniform_location(
1367         &self,
1368         program: Self::Program,
1369         name: &str,
1370     ) -> Option<Self::UniformLocation> {
1371         let programs = self.programs.borrow();
1372         let raw_program = programs.1.get_unchecked(program);
1373         match self.raw {
1374             RawRenderingContext::WebGl1(ref gl) => gl.get_uniform_location(raw_program, name),
1375             RawRenderingContext::WebGl2(ref gl) => gl.get_uniform_location(raw_program, name),
1376         }
1377     }
1378 
get_attrib_location(&self, program: Self::Program, name: &str) -> Option<u32>1379     unsafe fn get_attrib_location(&self, program: Self::Program, name: &str) -> Option<u32> {
1380         let programs = self.programs.borrow();
1381         let raw_program = programs.1.get_unchecked(program);
1382         let attrib_location = match self.raw {
1383             RawRenderingContext::WebGl1(ref gl) => gl.get_attrib_location(raw_program, name),
1384             RawRenderingContext::WebGl2(ref gl) => gl.get_attrib_location(raw_program, name),
1385         };
1386         if attrib_location < 0 {
1387             None
1388         } else {
1389             Some(attrib_location as u32)
1390         }
1391     }
1392 
bind_attrib_location(&self, program: Self::Program, index: u32, name: &str)1393     unsafe fn bind_attrib_location(&self, program: Self::Program, index: u32, name: &str) {
1394         let programs = self.programs.borrow();
1395         let raw_program = programs.1.get_unchecked(program);
1396         match self.raw {
1397             RawRenderingContext::WebGl1(ref gl) => {
1398                 gl.bind_attrib_location(raw_program, index, name)
1399             }
1400             RawRenderingContext::WebGl2(ref gl) => {
1401                 gl.bind_attrib_location(raw_program, index, name)
1402             }
1403         }
1404     }
1405 
get_active_attributes(&self, program: Self::Program) -> u321406     unsafe fn get_active_attributes(&self, program: Self::Program) -> u32 {
1407         let programs = self.programs.borrow();
1408         let raw_program = programs.1.get_unchecked(program);
1409         match self.raw {
1410             RawRenderingContext::WebGl1(ref gl) => {
1411                 gl.get_program_parameter(raw_program, WebGLRenderingContext::ACTIVE_ATTRIBUTES)
1412             }
1413             RawRenderingContext::WebGl2(ref gl) => {
1414                 gl.get_program_parameter(raw_program, WebGL2RenderingContext::ACTIVE_ATTRIBUTES)
1415             }
1416         }
1417         .try_into()
1418         .map(|v: f64| v as u32)
1419         .unwrap_or(0)
1420     }
1421 
get_active_attribute( &self, program: Self::Program, index: u32, ) -> Option<ActiveAttribute>1422     unsafe fn get_active_attribute(
1423         &self,
1424         program: Self::Program,
1425         index: u32,
1426     ) -> Option<ActiveAttribute> {
1427         let programs = self.programs.borrow();
1428         let raw_program = programs.1.get_unchecked(program);
1429         match self.raw {
1430             RawRenderingContext::WebGl1(ref gl) => {
1431                 gl.get_active_attrib(raw_program, index)
1432                     .map(|au| ActiveAttribute {
1433                         size: au.size(),
1434                         atype: au.type_(),
1435                         name: au.name(),
1436                     })
1437             }
1438             RawRenderingContext::WebGl2(ref gl) => {
1439                 gl.get_active_attrib(raw_program, index)
1440                     .map(|au| ActiveAttribute {
1441                         size: au.size(),
1442                         atype: au.type_(),
1443                         name: au.name(),
1444                     })
1445             }
1446         }
1447     }
1448 
get_sync_status(&self, fence: Self::Fence) -> u321449     unsafe fn get_sync_status(&self, fence: Self::Fence) -> u32 {
1450         let fences = self.fences.borrow();
1451         let raw_fence = fences.1.get_unchecked(fence);
1452         match self.raw {
1453             RawRenderingContext::WebGl1(ref _gl) => panic!("Sync is not supported"),
1454             RawRenderingContext::WebGl2(ref gl) => gl
1455                 .get_sync_parameter(raw_fence, SYNC_STATUS)
1456                 .try_into()
1457                 .map(|v: f64| v as u32)
1458                 .unwrap_or(UNSIGNALED),
1459         }
1460     }
1461 
is_sync(&self, fence: Self::Fence) -> bool1462     unsafe fn is_sync(&self, fence: Self::Fence) -> bool {
1463         let fences = self.fences.borrow();
1464         let raw_fence = fences.1.get_unchecked(fence);
1465         match self.raw {
1466             RawRenderingContext::WebGl1(ref _gl) => panic!("Sync is not supported"),
1467             RawRenderingContext::WebGl2(ref gl) => gl.is_sync(Some(raw_fence)),
1468         }
1469     }
1470 
renderbuffer_storage( &self, target: u32, internal_format: u32, width: i32, height: i32, )1471     unsafe fn renderbuffer_storage(
1472         &self,
1473         target: u32,
1474         internal_format: u32,
1475         width: i32,
1476         height: i32,
1477     ) {
1478         match self.raw {
1479             RawRenderingContext::WebGl1(ref gl) => {
1480                 gl.renderbuffer_storage(target, internal_format, width, height);
1481             }
1482             RawRenderingContext::WebGl2(ref gl) => {
1483                 gl.renderbuffer_storage(target, internal_format, width, height);
1484             }
1485         }
1486     }
1487 
renderbuffer_storage_multisample( &self, target: u32, samples: i32, internal_format: u32, width: i32, height: i32, )1488     unsafe fn renderbuffer_storage_multisample(
1489         &self,
1490         target: u32,
1491         samples: i32,
1492         internal_format: u32,
1493         width: i32,
1494         height: i32,
1495     ) {
1496         match self.raw {
1497             RawRenderingContext::WebGl1(ref _gl) => {
1498                 panic!("Renderbuffer storage multisample is not supported");
1499             }
1500             RawRenderingContext::WebGl2(ref gl) => {
1501                 gl.renderbuffer_storage_multisample(
1502                     target,
1503                     samples,
1504                     internal_format,
1505                     width,
1506                     height,
1507                 );
1508             }
1509         }
1510     }
1511 
sampler_parameter_f32(&self, sampler: Self::Sampler, name: u32, value: f32)1512     unsafe fn sampler_parameter_f32(&self, sampler: Self::Sampler, name: u32, value: f32) {
1513         let samplers = self.samplers.borrow();
1514         let raw_sampler = samplers.1.get_unchecked(sampler);
1515         match self.raw {
1516             RawRenderingContext::WebGl1(ref _gl) => {
1517                 panic!("Samper parameter for `f32` is not supported")
1518             }
1519             RawRenderingContext::WebGl2(ref gl) => {
1520                 gl.sampler_parameterf(raw_sampler, name, value);
1521             }
1522         }
1523     }
1524 
sampler_parameter_f32_slice( &self, _sampler: Self::Sampler, _name: u32, _value: &mut [f32], )1525     unsafe fn sampler_parameter_f32_slice(
1526         &self,
1527         _sampler: Self::Sampler,
1528         _name: u32,
1529         _value: &mut [f32],
1530     ) {
1531         panic!("Sampler parameter for `f32` slice is not supported");
1532     }
1533 
sampler_parameter_i32(&self, sampler: Self::Sampler, name: u32, value: i32)1534     unsafe fn sampler_parameter_i32(&self, sampler: Self::Sampler, name: u32, value: i32) {
1535         let samplers = self.samplers.borrow();
1536         let raw_sampler = samplers.1.get_unchecked(sampler);
1537         match self.raw {
1538             RawRenderingContext::WebGl1(ref _gl) => {
1539                 panic!("Samper parameter for `i32` is not supported")
1540             }
1541             RawRenderingContext::WebGl2(ref gl) => {
1542                 gl.sampler_parameteri(raw_sampler, name, value);
1543             }
1544         }
1545     }
1546 
generate_mipmap(&self, target: u32)1547     unsafe fn generate_mipmap(&self, target: u32) {
1548         match self.raw {
1549             RawRenderingContext::WebGl1(ref gl) => {
1550                 gl.generate_mipmap(target);
1551             }
1552             RawRenderingContext::WebGl2(ref gl) => {
1553                 gl.generate_mipmap(target);
1554             }
1555         }
1556     }
1557 
tex_image_1d( &self, _target: u32, _level: i32, _internal_format: i32, _width: i32, _border: i32, _format: u32, _ty: u32, _pixels: Option<&[u8]>, )1558     unsafe fn tex_image_1d(
1559         &self,
1560         _target: u32,
1561         _level: i32,
1562         _internal_format: i32,
1563         _width: i32,
1564         _border: i32,
1565         _format: u32,
1566         _ty: u32,
1567         _pixels: Option<&[u8]>,
1568     ) {
1569         panic!("Tex image 1D is not supported");
1570     }
1571 
tex_image_2d( &self, target: u32, level: i32, internal_format: i32, width: i32, height: i32, border: i32, format: u32, ty: u32, pixels: Option<&[u8]>, )1572     unsafe fn tex_image_2d(
1573         &self,
1574         target: u32,
1575         level: i32,
1576         internal_format: i32,
1577         width: i32,
1578         height: i32,
1579         border: i32,
1580         format: u32,
1581         ty: u32,
1582         pixels: Option<&[u8]>,
1583     ) {
1584         use std::mem::size_of;
1585         use std::slice::from_raw_parts;
1586 
1587         macro_rules! apply_tex_image2_d {
1588             ($pixels: ident) => {
1589                 match self.raw {
1590                     RawRenderingContext::WebGl1(ref gl) => gl.tex_image2_d(
1591                         target,
1592                         level,
1593                         internal_format,
1594                         width,
1595                         height,
1596                         border,
1597                         format,
1598                         ty,
1599                         $pixels,
1600                     ),
1601                     RawRenderingContext::WebGl2(ref gl) => gl.tex_image2_d(
1602                         target,
1603                         level,
1604                         internal_format,
1605                         width,
1606                         height,
1607                         border,
1608                         format,
1609                         ty,
1610                         $pixels,
1611                     ),
1612                 }
1613             };
1614         }
1615 
1616         match ty {
1617             BYTE => {
1618                 let pixels = pixels.map(|bytes| {
1619                     from_raw_parts(bytes.as_ptr() as *const i8, bytes.len() / size_of::<i8>())
1620                 });
1621                 apply_tex_image2_d!(pixels)
1622             }
1623 
1624             SHORT => {
1625                 let pixels = pixels.map(|bytes| {
1626                     from_raw_parts(bytes.as_ptr() as *const i16, bytes.len() / size_of::<i16>())
1627                 });
1628                 apply_tex_image2_d!(pixels)
1629             }
1630 
1631             UNSIGNED_SHORT
1632             | UNSIGNED_SHORT_5_6_5
1633             | UNSIGNED_SHORT_5_5_5_1
1634             | UNSIGNED_SHORT_4_4_4_4
1635             | HALF_FLOAT => {
1636                 let pixels = pixels.map(|bytes| {
1637                     from_raw_parts(bytes.as_ptr() as *const u16, bytes.len() / size_of::<u16>())
1638                 });
1639                 apply_tex_image2_d!(pixels)
1640             }
1641 
1642             INT => {
1643                 let pixels = pixels.map(|bytes| {
1644                     from_raw_parts(bytes.as_ptr() as *const i32, bytes.len() / size_of::<i32>())
1645                 });
1646                 apply_tex_image2_d!(pixels)
1647             }
1648 
1649             UNSIGNED_INT
1650             | UNSIGNED_INT_5_9_9_9_REV
1651             | UNSIGNED_INT_2_10_10_10_REV
1652             | UNSIGNED_INT_10F_11F_11F_REV
1653             | UNSIGNED_INT_24_8 => {
1654                 let pixels = pixels.map(|bytes| {
1655                     from_raw_parts(bytes.as_ptr() as *const u32, bytes.len() / size_of::<u32>())
1656                 });
1657                 apply_tex_image2_d!(pixels)
1658             }
1659 
1660             FLOAT => {
1661                 let pixels = pixels.map(|bytes| {
1662                     from_raw_parts(bytes.as_ptr() as *const f32, bytes.len() / size_of::<f32>())
1663                 });
1664                 apply_tex_image2_d!(pixels)
1665             }
1666 
1667             UNSIGNED_BYTE | _ => apply_tex_image2_d!(pixels),
1668         }
1669     }
1670 
tex_image_3d( &self, target: u32, level: i32, internal_format: i32, width: i32, height: i32, depth: i32, border: i32, format: u32, ty: u32, pixels: Option<&[u8]>, )1671     unsafe fn tex_image_3d(
1672         &self,
1673         target: u32,
1674         level: i32,
1675         internal_format: i32,
1676         width: i32,
1677         height: i32,
1678         depth: i32,
1679         border: i32,
1680         format: u32,
1681         ty: u32,
1682         pixels: Option<&[u8]>,
1683     ) {
1684         match self.raw {
1685             RawRenderingContext::WebGl1(ref _gl) => panic!("3d textures are not supported"),
1686             RawRenderingContext::WebGl2(ref gl) => gl.tex_image3_d_1(
1687                 target,
1688                 level,
1689                 internal_format,
1690                 width,
1691                 height,
1692                 depth,
1693                 border,
1694                 format,
1695                 ty,
1696                 pixels,
1697             ),
1698         }
1699     }
1700 
tex_storage_1d( &self, _target: u32, _levels: i32, _internal_format: u32, _width: i32, )1701     unsafe fn tex_storage_1d(
1702         &self,
1703         _target: u32,
1704         _levels: i32,
1705         _internal_format: u32,
1706         _width: i32,
1707     ) {
1708         panic!("Tex storage 1D is not supported");
1709     }
1710 
tex_storage_2d( &self, target: u32, levels: i32, internal_format: u32, width: i32, height: i32, )1711     unsafe fn tex_storage_2d(
1712         &self,
1713         target: u32,
1714         levels: i32,
1715         internal_format: u32,
1716         width: i32,
1717         height: i32,
1718     ) {
1719         match self.raw {
1720             RawRenderingContext::WebGl1(ref _gl) => panic!("Tex storage 2D is not supported"),
1721             RawRenderingContext::WebGl2(ref gl) => {
1722                 gl.tex_storage2_d(target, levels, internal_format, width, height);
1723             }
1724         }
1725     }
1726 
tex_storage_3d( &self, target: u32, levels: i32, internal_format: u32, width: i32, height: i32, depth: i32, )1727     unsafe fn tex_storage_3d(
1728         &self,
1729         target: u32,
1730         levels: i32,
1731         internal_format: u32,
1732         width: i32,
1733         height: i32,
1734         depth: i32,
1735     ) {
1736         match self.raw {
1737             RawRenderingContext::WebGl1(ref _gl) => panic!("Tex storage 3D is not supported"),
1738             RawRenderingContext::WebGl2(ref gl) => {
1739                 gl.tex_storage3_d(target, levels, internal_format, width, height, depth);
1740             }
1741         }
1742     }
1743 
uniform_1_i32(&self, uniform_location: Option<&Self::UniformLocation>, x: i32)1744     unsafe fn uniform_1_i32(&self, uniform_location: Option<&Self::UniformLocation>, x: i32) {
1745         match self.raw {
1746             RawRenderingContext::WebGl1(ref gl) => gl.uniform1i(uniform_location, x),
1747             RawRenderingContext::WebGl2(ref gl) => gl.uniform1i(uniform_location, x),
1748         }
1749     }
1750 
uniform_2_i32( &self, uniform_location: Option<&Self::UniformLocation>, x: i32, y: i32, )1751     unsafe fn uniform_2_i32(
1752         &self,
1753         uniform_location: Option<&Self::UniformLocation>,
1754         x: i32,
1755         y: i32,
1756     ) {
1757         match self.raw {
1758             RawRenderingContext::WebGl1(ref gl) => gl.uniform2i(uniform_location, x, y),
1759             RawRenderingContext::WebGl2(ref gl) => gl.uniform2i(uniform_location, x, y),
1760         }
1761     }
1762 
uniform_3_i32( &self, uniform_location: Option<&Self::UniformLocation>, x: i32, y: i32, z: i32, )1763     unsafe fn uniform_3_i32(
1764         &self,
1765         uniform_location: Option<&Self::UniformLocation>,
1766         x: i32,
1767         y: i32,
1768         z: i32,
1769     ) {
1770         match self.raw {
1771             RawRenderingContext::WebGl1(ref gl) => gl.uniform3i(uniform_location, x, y, z),
1772             RawRenderingContext::WebGl2(ref gl) => gl.uniform3i(uniform_location, x, y, z),
1773         }
1774     }
1775 
uniform_4_i32( &self, uniform_location: Option<&Self::UniformLocation>, x: i32, y: i32, z: i32, w: i32, )1776     unsafe fn uniform_4_i32(
1777         &self,
1778         uniform_location: Option<&Self::UniformLocation>,
1779         x: i32,
1780         y: i32,
1781         z: i32,
1782         w: i32,
1783     ) {
1784         match self.raw {
1785             RawRenderingContext::WebGl1(ref gl) => gl.uniform4i(uniform_location, x, y, z, w),
1786             RawRenderingContext::WebGl2(ref gl) => gl.uniform4i(uniform_location, x, y, z, w),
1787         }
1788     }
1789 
uniform_1_i32_slice( &self, uniform_location: Option<&Self::UniformLocation>, v: &[i32], )1790     unsafe fn uniform_1_i32_slice(
1791         &self,
1792         uniform_location: Option<&Self::UniformLocation>,
1793         v: &[i32],
1794     ) {
1795         match self.raw {
1796             RawRenderingContext::WebGl1(ref gl) => gl.uniform1iv(uniform_location, &v[..]),
1797             RawRenderingContext::WebGl2(ref gl) => gl.uniform1iv_1(uniform_location, &v[..]),
1798         }
1799     }
1800 
uniform_2_i32_slice( &self, uniform_location: Option<&Self::UniformLocation>, v: &[i32], )1801     unsafe fn uniform_2_i32_slice(
1802         &self,
1803         uniform_location: Option<&Self::UniformLocation>,
1804         v: &[i32],
1805     ) {
1806         match self.raw {
1807             RawRenderingContext::WebGl1(ref gl) => gl.uniform2iv(uniform_location, &v[..]),
1808             RawRenderingContext::WebGl2(ref gl) => gl.uniform2iv_1(uniform_location, &v[..]),
1809         }
1810     }
1811 
uniform_3_i32_slice( &self, uniform_location: Option<&Self::UniformLocation>, v: &[i32], )1812     unsafe fn uniform_3_i32_slice(
1813         &self,
1814         uniform_location: Option<&Self::UniformLocation>,
1815         v: &[i32],
1816     ) {
1817         match self.raw {
1818             RawRenderingContext::WebGl1(ref gl) => gl.uniform3iv(uniform_location, &v[..]),
1819             RawRenderingContext::WebGl2(ref gl) => gl.uniform3iv_1(uniform_location, &v[..]),
1820         }
1821     }
1822 
uniform_4_i32_slice( &self, uniform_location: Option<&Self::UniformLocation>, v: &[i32], )1823     unsafe fn uniform_4_i32_slice(
1824         &self,
1825         uniform_location: Option<&Self::UniformLocation>,
1826         v: &[i32],
1827     ) {
1828         match self.raw {
1829             RawRenderingContext::WebGl1(ref gl) => gl.uniform4iv(uniform_location, &v[..]),
1830             RawRenderingContext::WebGl2(ref gl) => gl.uniform4iv_1(uniform_location, &v[..]),
1831         }
1832     }
1833 
uniform_1_u32(&self, uniform_location: Option<&Self::UniformLocation>, x: u32)1834     unsafe fn uniform_1_u32(&self, uniform_location: Option<&Self::UniformLocation>, x: u32) {
1835         match self.raw {
1836             RawRenderingContext::WebGl1(ref _gl) => panic!("Unsigned uniforms are not supported"),
1837             RawRenderingContext::WebGl2(ref gl) => gl.uniform1ui(uniform_location, x),
1838         }
1839     }
1840 
uniform_2_u32( &self, uniform_location: Option<&Self::UniformLocation>, x: u32, y: u32, )1841     unsafe fn uniform_2_u32(
1842         &self,
1843         uniform_location: Option<&Self::UniformLocation>,
1844         x: u32,
1845         y: u32,
1846     ) {
1847         match self.raw {
1848             RawRenderingContext::WebGl1(ref _gl) => panic!("Unsigned uniforms are not supported"),
1849             RawRenderingContext::WebGl2(ref gl) => gl.uniform2ui(uniform_location, x, y),
1850         }
1851     }
1852 
uniform_3_u32( &self, uniform_location: Option<&Self::UniformLocation>, x: u32, y: u32, z: u32, )1853     unsafe fn uniform_3_u32(
1854         &self,
1855         uniform_location: Option<&Self::UniformLocation>,
1856         x: u32,
1857         y: u32,
1858         z: u32,
1859     ) {
1860         match self.raw {
1861             RawRenderingContext::WebGl1(ref _gl) => panic!("Unsigned uniforms are not supported"),
1862             RawRenderingContext::WebGl2(ref gl) => gl.uniform3ui(uniform_location, x, y, z),
1863         }
1864     }
1865 
uniform_4_u32( &self, uniform_location: Option<&Self::UniformLocation>, x: u32, y: u32, z: u32, w: u32, )1866     unsafe fn uniform_4_u32(
1867         &self,
1868         uniform_location: Option<&Self::UniformLocation>,
1869         x: u32,
1870         y: u32,
1871         z: u32,
1872         w: u32,
1873     ) {
1874         match self.raw {
1875             RawRenderingContext::WebGl1(ref _gl) => panic!("Unsigned uniforms are not supported"),
1876             RawRenderingContext::WebGl2(ref gl) => gl.uniform4ui(uniform_location, x, y, z, w),
1877         }
1878     }
1879 
uniform_1_u32_slice( &self, uniform_location: Option<&Self::UniformLocation>, v: &[u32], )1880     unsafe fn uniform_1_u32_slice(
1881         &self,
1882         uniform_location: Option<&Self::UniformLocation>,
1883         v: &[u32],
1884     ) {
1885         match self.raw {
1886             RawRenderingContext::WebGl1(ref _gl) => {
1887                 panic!("Unsigned uniforms are not supported");
1888             }
1889             RawRenderingContext::WebGl2(ref gl) => {
1890                 gl.uniform1uiv(uniform_location, &v[..], 0, v.len() as u32)
1891             }
1892         }
1893     }
1894 
uniform_2_u32_slice( &self, uniform_location: Option<&Self::UniformLocation>, v: &[u32], )1895     unsafe fn uniform_2_u32_slice(
1896         &self,
1897         uniform_location: Option<&Self::UniformLocation>,
1898         v: &[u32],
1899     ) {
1900         match self.raw {
1901             RawRenderingContext::WebGl1(ref _gl) => {
1902                 panic!("Unsigned uniforms are not supported");
1903             }
1904             RawRenderingContext::WebGl2(ref gl) => {
1905                 gl.uniform2uiv(uniform_location, &v[..], 0, v.len() as u32)
1906             }
1907         }
1908     }
1909 
uniform_3_u32_slice( &self, uniform_location: Option<&Self::UniformLocation>, v: &[u32], )1910     unsafe fn uniform_3_u32_slice(
1911         &self,
1912         uniform_location: Option<&Self::UniformLocation>,
1913         v: &[u32],
1914     ) {
1915         match self.raw {
1916             RawRenderingContext::WebGl1(ref _gl) => {
1917                 panic!("Unsigned uniforms are not supported");
1918             }
1919             RawRenderingContext::WebGl2(ref gl) => {
1920                 gl.uniform3uiv(uniform_location, &v[..], 0, v.len() as u32)
1921             }
1922         }
1923     }
1924 
uniform_4_u32_slice( &self, uniform_location: Option<&Self::UniformLocation>, v: &[u32], )1925     unsafe fn uniform_4_u32_slice(
1926         &self,
1927         uniform_location: Option<&Self::UniformLocation>,
1928         v: &[u32],
1929     ) {
1930         match self.raw {
1931             RawRenderingContext::WebGl1(ref _gl) => {
1932                 panic!("Unsigned uniforms are not supported");
1933             }
1934             RawRenderingContext::WebGl2(ref gl) => {
1935                 gl.uniform4uiv(uniform_location, &v[..], 0, v.len() as u32)
1936             }
1937         }
1938     }
1939 
uniform_1_f32(&self, uniform_location: Option<&Self::UniformLocation>, x: f32)1940     unsafe fn uniform_1_f32(&self, uniform_location: Option<&Self::UniformLocation>, x: f32) {
1941         match self.raw {
1942             RawRenderingContext::WebGl1(ref gl) => gl.uniform1f(uniform_location, x),
1943             RawRenderingContext::WebGl2(ref gl) => gl.uniform1f(uniform_location, x),
1944         }
1945     }
1946 
uniform_2_f32( &self, uniform_location: Option<&Self::UniformLocation>, x: f32, y: f32, )1947     unsafe fn uniform_2_f32(
1948         &self,
1949         uniform_location: Option<&Self::UniformLocation>,
1950         x: f32,
1951         y: f32,
1952     ) {
1953         match self.raw {
1954             RawRenderingContext::WebGl1(ref gl) => gl.uniform2f(uniform_location, x, y),
1955             RawRenderingContext::WebGl2(ref gl) => gl.uniform2f(uniform_location, x, y),
1956         }
1957     }
1958 
uniform_3_f32( &self, uniform_location: Option<&Self::UniformLocation>, x: f32, y: f32, z: f32, )1959     unsafe fn uniform_3_f32(
1960         &self,
1961         uniform_location: Option<&Self::UniformLocation>,
1962         x: f32,
1963         y: f32,
1964         z: f32,
1965     ) {
1966         match self.raw {
1967             RawRenderingContext::WebGl1(ref gl) => gl.uniform3f(uniform_location, x, y, z),
1968             RawRenderingContext::WebGl2(ref gl) => gl.uniform3f(uniform_location, x, y, z),
1969         }
1970     }
1971 
uniform_4_f32( &self, uniform_location: Option<&Self::UniformLocation>, x: f32, y: f32, z: f32, w: f32, )1972     unsafe fn uniform_4_f32(
1973         &self,
1974         uniform_location: Option<&Self::UniformLocation>,
1975         x: f32,
1976         y: f32,
1977         z: f32,
1978         w: f32,
1979     ) {
1980         match self.raw {
1981             RawRenderingContext::WebGl1(ref gl) => gl.uniform4f(uniform_location, x, y, z, w),
1982             RawRenderingContext::WebGl2(ref gl) => gl.uniform4f(uniform_location, x, y, z, w),
1983         }
1984     }
1985 
uniform_1_f32_slice( &self, uniform_location: Option<&Self::UniformLocation>, v: &[f32], )1986     unsafe fn uniform_1_f32_slice(
1987         &self,
1988         uniform_location: Option<&Self::UniformLocation>,
1989         v: &[f32],
1990     ) {
1991         match self.raw {
1992             RawRenderingContext::WebGl1(ref gl) => gl.uniform1fv(uniform_location, &v[..]),
1993             RawRenderingContext::WebGl2(ref gl) => gl.uniform1fv_1(uniform_location, &v[..]),
1994         }
1995     }
1996 
uniform_2_f32_slice( &self, uniform_location: Option<&Self::UniformLocation>, v: &[f32], )1997     unsafe fn uniform_2_f32_slice(
1998         &self,
1999         uniform_location: Option<&Self::UniformLocation>,
2000         v: &[f32],
2001     ) {
2002         match self.raw {
2003             RawRenderingContext::WebGl1(ref gl) => gl.uniform2fv(uniform_location, &v[..]),
2004             RawRenderingContext::WebGl2(ref gl) => gl.uniform2fv_1(uniform_location, &v[..]),
2005         }
2006     }
2007 
uniform_3_f32_slice( &self, uniform_location: Option<&Self::UniformLocation>, v: &[f32], )2008     unsafe fn uniform_3_f32_slice(
2009         &self,
2010         uniform_location: Option<&Self::UniformLocation>,
2011         v: &[f32],
2012     ) {
2013         match self.raw {
2014             RawRenderingContext::WebGl1(ref gl) => gl.uniform3fv(uniform_location, &v[..]),
2015             RawRenderingContext::WebGl2(ref gl) => gl.uniform3fv_1(uniform_location, &v[..]),
2016         }
2017     }
2018 
uniform_4_f32_slice( &self, uniform_location: Option<&Self::UniformLocation>, v: &[f32], )2019     unsafe fn uniform_4_f32_slice(
2020         &self,
2021         uniform_location: Option<&Self::UniformLocation>,
2022         v: &[f32],
2023     ) {
2024         match self.raw {
2025             RawRenderingContext::WebGl1(ref gl) => gl.uniform4fv(uniform_location, &v[..]),
2026             RawRenderingContext::WebGl2(ref gl) => gl.uniform4fv_1(uniform_location, &v[..]),
2027         }
2028     }
2029 
uniform_matrix_2_f32_slice( &self, uniform_location: Option<&Self::UniformLocation>, transpose: bool, v: &[f32], )2030     unsafe fn uniform_matrix_2_f32_slice(
2031         &self,
2032         uniform_location: Option<&Self::UniformLocation>,
2033         transpose: bool,
2034         v: &[f32],
2035     ) {
2036         match self.raw {
2037             RawRenderingContext::WebGl1(ref gl) => {
2038                 gl.uniform_matrix2fv(uniform_location, transpose, &v[..])
2039             }
2040             RawRenderingContext::WebGl2(ref gl) => {
2041                 gl.uniform_matrix2fv_1(uniform_location, transpose, &v[..])
2042             }
2043         }
2044     }
2045 
uniform_matrix_3_f32_slice( &self, uniform_location: Option<&Self::UniformLocation>, transpose: bool, v: &[f32], )2046     unsafe fn uniform_matrix_3_f32_slice(
2047         &self,
2048         uniform_location: Option<&Self::UniformLocation>,
2049         transpose: bool,
2050         v: &[f32],
2051     ) {
2052         match self.raw {
2053             RawRenderingContext::WebGl1(ref gl) => {
2054                 gl.uniform_matrix3fv(uniform_location, transpose, &v[..])
2055             }
2056             RawRenderingContext::WebGl2(ref gl) => {
2057                 gl.uniform_matrix3fv_1(uniform_location, transpose, &v[..])
2058             }
2059         }
2060     }
2061 
uniform_matrix_4_f32_slice( &self, uniform_location: Option<&Self::UniformLocation>, transpose: bool, v: &[f32], )2062     unsafe fn uniform_matrix_4_f32_slice(
2063         &self,
2064         uniform_location: Option<&Self::UniformLocation>,
2065         transpose: bool,
2066         v: &[f32],
2067     ) {
2068         match self.raw {
2069             RawRenderingContext::WebGl1(ref gl) => {
2070                 gl.uniform_matrix4fv(uniform_location, transpose, &v[..])
2071             }
2072             RawRenderingContext::WebGl2(ref gl) => {
2073                 gl.uniform_matrix4fv_1(uniform_location, transpose, &v[..])
2074             }
2075         }
2076     }
2077 
unmap_buffer(&self, _target: u32)2078     unsafe fn unmap_buffer(&self, _target: u32) {
2079         panic!("Unmap buffer is not supported");
2080     }
2081 
cull_face(&self, value: u32)2082     unsafe fn cull_face(&self, value: u32) {
2083         match self.raw {
2084             RawRenderingContext::WebGl1(ref gl) => gl.cull_face(value as u32),
2085             RawRenderingContext::WebGl2(ref gl) => gl.cull_face(value as u32),
2086         }
2087     }
2088 
color_mask(&self, red: bool, green: bool, blue: bool, alpha: bool)2089     unsafe fn color_mask(&self, red: bool, green: bool, blue: bool, alpha: bool) {
2090         match self.raw {
2091             RawRenderingContext::WebGl1(ref gl) => gl.color_mask(red, green, blue, alpha),
2092             RawRenderingContext::WebGl2(ref gl) => gl.color_mask(red, green, blue, alpha),
2093         }
2094     }
2095 
color_mask_draw_buffer( &self, _draw_buffer: u32, _red: bool, _green: bool, _blue: bool, _alpha: bool, )2096     unsafe fn color_mask_draw_buffer(
2097         &self,
2098         _draw_buffer: u32,
2099         _red: bool,
2100         _green: bool,
2101         _blue: bool,
2102         _alpha: bool,
2103     ) {
2104         panic!("Draw buffer color masks are not supported");
2105     }
2106 
depth_mask(&self, value: bool)2107     unsafe fn depth_mask(&self, value: bool) {
2108         match self.raw {
2109             RawRenderingContext::WebGl1(ref gl) => gl.depth_mask(value),
2110             RawRenderingContext::WebGl2(ref gl) => gl.depth_mask(value),
2111         }
2112     }
2113 
blend_color(&self, red: f32, green: f32, blue: f32, alpha: f32)2114     unsafe fn blend_color(&self, red: f32, green: f32, blue: f32, alpha: f32) {
2115         match self.raw {
2116             RawRenderingContext::WebGl1(ref gl) => gl.blend_color(red, green, blue, alpha),
2117             RawRenderingContext::WebGl2(ref gl) => gl.blend_color(red, green, blue, alpha),
2118         }
2119     }
2120 
line_width(&self, width: f32)2121     unsafe fn line_width(&self, width: f32) {
2122         match self.raw {
2123             RawRenderingContext::WebGl1(ref gl) => gl.line_width(width),
2124             RawRenderingContext::WebGl2(ref gl) => gl.line_width(width),
2125         }
2126     }
2127 
map_buffer_range( &self, _target: u32, _offset: i32, _length: i32, _access: u32, ) -> *mut u82128     unsafe fn map_buffer_range(
2129         &self,
2130         _target: u32,
2131         _offset: i32,
2132         _length: i32,
2133         _access: u32,
2134     ) -> *mut u8 {
2135         panic!("Map buffer range is not supported")
2136     }
2137 
flush_mapped_buffer_range(&self, _target: u32, _offset: i32, _length: i32)2138     unsafe fn flush_mapped_buffer_range(&self, _target: u32, _offset: i32, _length: i32) {
2139         panic!("Flush mapped buffer range is not supported")
2140     }
2141 
invalidate_buffer_sub_data(&self, _target: u32, _offset: i32, _length: i32)2142     unsafe fn invalidate_buffer_sub_data(&self, _target: u32, _offset: i32, _length: i32) {
2143         panic!("Invalidate buffer sub data is not supported")
2144     }
2145 
invalidate_framebuffer(&self, target: u32, attachments: &[u32])2146     unsafe fn invalidate_framebuffer(&self, target: u32, attachments: &[u32]) {
2147         match self.raw {
2148             RawRenderingContext::WebGl1(ref _gl) => {
2149                 panic!("Invalidate framebuffer is not supported");
2150             }
2151             RawRenderingContext::WebGl2(ref gl) => {
2152                 gl.invalidate_framebuffer(target, attachments);
2153             }
2154         }
2155     }
2156 
polygon_offset(&self, factor: f32, units: f32)2157     unsafe fn polygon_offset(&self, factor: f32, units: f32) {
2158         match self.raw {
2159             RawRenderingContext::WebGl1(ref gl) => gl.polygon_offset(factor, units),
2160             RawRenderingContext::WebGl2(ref gl) => gl.polygon_offset(factor, units),
2161         }
2162     }
2163 
polygon_mode(&self, _face: u32, mode: u32)2164     unsafe fn polygon_mode(&self, _face: u32, mode: u32) {
2165         if mode != FILL {
2166             panic!("Polygon mode other than FILL is not supported");
2167         }
2168     }
2169 
finish(&self)2170     unsafe fn finish(&self) {
2171         match self.raw {
2172             RawRenderingContext::WebGl1(ref gl) => gl.finish(),
2173             RawRenderingContext::WebGl2(ref gl) => gl.finish(),
2174         }
2175     }
2176 
bind_texture(&self, target: u32, texture: Option<Self::Texture>)2177     unsafe fn bind_texture(&self, target: u32, texture: Option<Self::Texture>) {
2178         let textures = self.textures.borrow();
2179         let raw_texture = texture.map(|t| textures.1.get_unchecked(t));
2180         match self.raw {
2181             RawRenderingContext::WebGl1(ref gl) => gl.bind_texture(target, raw_texture),
2182             RawRenderingContext::WebGl2(ref gl) => gl.bind_texture(target, raw_texture),
2183         }
2184     }
2185 
bind_sampler(&self, unit: u32, sampler: Option<Self::Sampler>)2186     unsafe fn bind_sampler(&self, unit: u32, sampler: Option<Self::Sampler>) {
2187         let samplers = self.samplers.borrow();
2188         let raw_sampler = sampler.map(|s| samplers.1.get_unchecked(s));
2189         match self.raw {
2190             RawRenderingContext::WebGl1(ref _gl) => panic!("Bind sampler is not supported"),
2191             RawRenderingContext::WebGl2(ref gl) => gl.bind_sampler(unit, raw_sampler),
2192         }
2193     }
2194 
active_texture(&self, unit: u32)2195     unsafe fn active_texture(&self, unit: u32) {
2196         match self.raw {
2197             RawRenderingContext::WebGl1(ref gl) => gl.active_texture(unit),
2198             RawRenderingContext::WebGl2(ref gl) => gl.active_texture(unit),
2199         }
2200     }
2201 
fence_sync(&self, condition: u32, flags: u32) -> Result<Self::Fence, String>2202     unsafe fn fence_sync(&self, condition: u32, flags: u32) -> Result<Self::Fence, String> {
2203         let raw_fence = match self.raw {
2204             RawRenderingContext::WebGl1(ref _gl) => panic!("Fences are not supported"),
2205             RawRenderingContext::WebGl2(ref gl) => gl.fence_sync(condition as u32, flags),
2206         };
2207         match raw_fence {
2208             Some(f) => {
2209                 let key = self.fences.borrow_mut().0.insert(());
2210                 self.fences.borrow_mut().1.insert(key, f);
2211                 Ok(key)
2212             }
2213             None => Err(String::from("Unable to create fence object")),
2214         }
2215     }
2216 
tex_parameter_f32(&self, target: u32, parameter: u32, value: f32)2217     unsafe fn tex_parameter_f32(&self, target: u32, parameter: u32, value: f32) {
2218         match self.raw {
2219             RawRenderingContext::WebGl1(ref gl) => gl.tex_parameterf(target, parameter, value),
2220             RawRenderingContext::WebGl2(ref gl) => gl.tex_parameterf(target, parameter, value),
2221         }
2222     }
2223 
tex_parameter_i32(&self, target: u32, parameter: u32, value: i32)2224     unsafe fn tex_parameter_i32(&self, target: u32, parameter: u32, value: i32) {
2225         match self.raw {
2226             RawRenderingContext::WebGl1(ref gl) => gl.tex_parameteri(target, parameter, value),
2227             RawRenderingContext::WebGl2(ref gl) => gl.tex_parameteri(target, parameter, value),
2228         }
2229     }
2230 
tex_parameter_f32_slice(&self, _target: u32, _parameter: u32, _values: &[f32])2231     unsafe fn tex_parameter_f32_slice(&self, _target: u32, _parameter: u32, _values: &[f32]) {
2232         // Blocked by https://github.com/rustwasm/wasm-bindgen/issues/1038
2233         panic!("Texture parameters for `&[f32]` are not supported yet");
2234     }
2235 
tex_parameter_i32_slice(&self, _target: u32, _parameter: u32, _values: &[i32])2236     unsafe fn tex_parameter_i32_slice(&self, _target: u32, _parameter: u32, _values: &[i32]) {
2237         panic!("Texture parameters for `&[i32]` are not supported yet");
2238     }
2239 
tex_sub_image_2d( &self, target: u32, level: i32, x_offset: i32, y_offset: i32, width: i32, height: i32, format: u32, ty: u32, pixels: PixelUnpackData, )2240     unsafe fn tex_sub_image_2d(
2241         &self,
2242         target: u32,
2243         level: i32,
2244         x_offset: i32,
2245         y_offset: i32,
2246         width: i32,
2247         height: i32,
2248         format: u32,
2249         ty: u32,
2250         pixels: PixelUnpackData,
2251     ) {
2252         match self.raw {
2253             RawRenderingContext::WebGl1(ref gl) => match pixels {
2254                 PixelUnpackData::BufferOffset(_) => {
2255                     panic!("Sub image 2D pixel buffer offset is not supported")
2256                 }
2257                 PixelUnpackData::Slice(slice) => gl.tex_sub_image2_d(
2258                     target,
2259                     level,
2260                     x_offset,
2261                     y_offset,
2262                     width,
2263                     height,
2264                     format,
2265                     ty,
2266                     Some(slice),
2267                 ),
2268             },
2269             RawRenderingContext::WebGl2(ref gl) => match pixels {
2270                 PixelUnpackData::BufferOffset(offset) => gl.tex_sub_image2_d_2(
2271                     target,
2272                     level,
2273                     x_offset,
2274                     y_offset,
2275                     width,
2276                     height,
2277                     format,
2278                     ty,
2279                     offset as i64,
2280                 ),
2281                 PixelUnpackData::Slice(slice) => gl.tex_sub_image2_d_3(
2282                     target,
2283                     level,
2284                     x_offset,
2285                     y_offset,
2286                     width,
2287                     height,
2288                     format,
2289                     ty,
2290                     Some(slice),
2291                 ),
2292             },
2293         }
2294     }
2295 
tex_sub_image_3d( &self, target: u32, level: i32, x_offset: i32, y_offset: i32, z_offset: i32, width: i32, height: i32, depth: i32, format: u32, ty: u32, pixels: PixelUnpackData, )2296     unsafe fn tex_sub_image_3d(
2297         &self,
2298         target: u32,
2299         level: i32,
2300         x_offset: i32,
2301         y_offset: i32,
2302         z_offset: i32,
2303         width: i32,
2304         height: i32,
2305         depth: i32,
2306         format: u32,
2307         ty: u32,
2308         pixels: PixelUnpackData,
2309     ) {
2310         match self.raw {
2311             RawRenderingContext::WebGl1(ref _gl) => {
2312                 panic!("Sub image 3D is not supported");
2313             }
2314             RawRenderingContext::WebGl2(ref gl) => match pixels {
2315                 PixelUnpackData::BufferOffset(offset) => gl.tex_sub_image3_d(
2316                     target,
2317                     level,
2318                     x_offset,
2319                     y_offset,
2320                     z_offset,
2321                     width,
2322                     height,
2323                     depth,
2324                     format,
2325                     ty,
2326                     offset as i64,
2327                 ),
2328                 PixelUnpackData::Slice(slice) => gl.tex_sub_image3_d_1(
2329                     target, level, x_offset, y_offset, z_offset, width, height, depth, format, ty,
2330                     slice,
2331                 ),
2332             },
2333         }
2334     }
2335 
depth_func(&self, func: u32)2336     unsafe fn depth_func(&self, func: u32) {
2337         match self.raw {
2338             RawRenderingContext::WebGl1(ref gl) => gl.depth_func(func as u32),
2339             RawRenderingContext::WebGl2(ref gl) => gl.depth_func(func as u32),
2340         }
2341     }
2342 
depth_range_f32(&self, near: f32, far: f32)2343     unsafe fn depth_range_f32(&self, near: f32, far: f32) {
2344         match self.raw {
2345             RawRenderingContext::WebGl1(ref gl) => gl.depth_range(near, far),
2346             RawRenderingContext::WebGl2(ref gl) => gl.depth_range(near, far),
2347         }
2348     }
2349 
depth_range_f64(&self, _near: f64, _far: f64)2350     unsafe fn depth_range_f64(&self, _near: f64, _far: f64) {
2351         panic!("Depth range with 64-bit float values is not supported");
2352     }
2353 
depth_range_f64_slice(&self, _first: u32, _count: i32, _values: &[[f64; 2]])2354     unsafe fn depth_range_f64_slice(&self, _first: u32, _count: i32, _values: &[[f64; 2]]) {
2355         panic!("Depth range with 64-bit float slices is not supported");
2356     }
2357 
scissor(&self, x: i32, y: i32, width: i32, height: i32)2358     unsafe fn scissor(&self, x: i32, y: i32, width: i32, height: i32) {
2359         match self.raw {
2360             RawRenderingContext::WebGl1(ref gl) => gl.scissor(x, y, width, height),
2361             RawRenderingContext::WebGl2(ref gl) => gl.scissor(x, y, width, height),
2362         }
2363     }
2364 
scissor_slice(&self, _first: u32, _count: i32, _scissors: &[[i32; 4]])2365     unsafe fn scissor_slice(&self, _first: u32, _count: i32, _scissors: &[[i32; 4]]) {
2366         panic!("Scissor slice is not supported");
2367     }
2368 
vertex_attrib_divisor(&self, index: u32, divisor: u32)2369     unsafe fn vertex_attrib_divisor(&self, index: u32, divisor: u32) {
2370         match self.raw {
2371             RawRenderingContext::WebGl1(ref _gl) => match &self.extensions.angle_instanced_arrays {
2372                 None => panic!("Vertex attrib divisor is not supported"),
2373                 Some(extension) => extension.vertex_attrib_divisor_angle(index, divisor),
2374             },
2375             RawRenderingContext::WebGl2(ref gl) => gl.vertex_attrib_divisor(index, divisor),
2376         }
2377     }
2378 
vertex_attrib_pointer_f32( &self, index: u32, size: i32, data_type: u32, normalized: bool, stride: i32, offset: i32, )2379     unsafe fn vertex_attrib_pointer_f32(
2380         &self,
2381         index: u32,
2382         size: i32,
2383         data_type: u32,
2384         normalized: bool,
2385         stride: i32,
2386         offset: i32,
2387     ) {
2388         match self.raw {
2389             RawRenderingContext::WebGl1(ref gl) => {
2390                 gl.vertex_attrib_pointer(index, size, data_type, normalized, stride, offset as i64)
2391             }
2392             RawRenderingContext::WebGl2(ref gl) => {
2393                 gl.vertex_attrib_pointer(index, size, data_type, normalized, stride, offset as i64)
2394             }
2395         }
2396     }
2397 
vertex_attrib_pointer_i32( &self, index: u32, size: i32, data_type: u32, stride: i32, offset: i32, )2398     unsafe fn vertex_attrib_pointer_i32(
2399         &self,
2400         index: u32,
2401         size: i32,
2402         data_type: u32,
2403         stride: i32,
2404         offset: i32,
2405     ) {
2406         match self.raw {
2407             RawRenderingContext::WebGl1(ref _gl) => {
2408                 panic!("Integer vertex attrib pointer is not supported")
2409             }
2410             RawRenderingContext::WebGl2(ref gl) => {
2411                 gl.vertex_attrib_i_pointer(index, size, data_type, stride, offset as i64)
2412             }
2413         }
2414     }
2415 
vertex_attrib_pointer_f64( &self, _index: u32, _size: i32, _data_type: u32, _stride: i32, _offset: i32, )2416     unsafe fn vertex_attrib_pointer_f64(
2417         &self,
2418         _index: u32,
2419         _size: i32,
2420         _data_type: u32,
2421         _stride: i32,
2422         _offset: i32,
2423     ) {
2424         panic!("64-bit float precision is not supported in WebGL");
2425     }
2426 
viewport(&self, x: i32, y: i32, width: i32, height: i32)2427     unsafe fn viewport(&self, x: i32, y: i32, width: i32, height: i32) {
2428         match self.raw {
2429             RawRenderingContext::WebGl1(ref gl) => gl.viewport(x, y, width, height),
2430             RawRenderingContext::WebGl2(ref gl) => gl.viewport(x, y, width, height),
2431         }
2432     }
2433 
viewport_f32_slice(&self, _first: u32, _count: i32, _values: &[[f32; 4]])2434     unsafe fn viewport_f32_slice(&self, _first: u32, _count: i32, _values: &[[f32; 4]]) {
2435         panic!("Viewport `f32` slice is not supported");
2436     }
2437 
blend_func(&self, src: u32, dst: u32)2438     unsafe fn blend_func(&self, src: u32, dst: u32) {
2439         match self.raw {
2440             RawRenderingContext::WebGl1(ref gl) => gl.blend_func(src as u32, dst as u32),
2441             RawRenderingContext::WebGl2(ref gl) => gl.blend_func(src as u32, dst as u32),
2442         }
2443     }
2444 
blend_func_draw_buffer(&self, _draw_buffer: u32, _src: u32, _dst: u32)2445     unsafe fn blend_func_draw_buffer(&self, _draw_buffer: u32, _src: u32, _dst: u32) {
2446         panic!("Draw buffer blend func is not supported");
2447     }
2448 
blend_func_separate( &self, src_rgb: u32, dst_rgb: u32, src_alpha: u32, dst_alpha: u32, )2449     unsafe fn blend_func_separate(
2450         &self,
2451         src_rgb: u32,
2452         dst_rgb: u32,
2453         src_alpha: u32,
2454         dst_alpha: u32,
2455     ) {
2456         match self.raw {
2457             RawRenderingContext::WebGl1(ref gl) => gl.blend_func_separate(
2458                 src_rgb as u32,
2459                 dst_rgb as u32,
2460                 src_alpha as u32,
2461                 dst_alpha as u32,
2462             ),
2463             RawRenderingContext::WebGl2(ref gl) => gl.blend_func_separate(
2464                 src_rgb as u32,
2465                 dst_rgb as u32,
2466                 src_alpha as u32,
2467                 dst_alpha as u32,
2468             ),
2469         }
2470     }
2471 
blend_func_separate_draw_buffer( &self, _draw_buffer: u32, _src_rgb: u32, _dst_rgb: u32, _src_alpha: u32, _dst_alpha: u32, )2472     unsafe fn blend_func_separate_draw_buffer(
2473         &self,
2474         _draw_buffer: u32,
2475         _src_rgb: u32,
2476         _dst_rgb: u32,
2477         _src_alpha: u32,
2478         _dst_alpha: u32,
2479     ) {
2480         panic!("Draw buffer blend func separate is not supported");
2481     }
2482 
blend_equation(&self, mode: u32)2483     unsafe fn blend_equation(&self, mode: u32) {
2484         match self.raw {
2485             RawRenderingContext::WebGl1(ref gl) => gl.blend_equation(mode as u32),
2486             RawRenderingContext::WebGl2(ref gl) => gl.blend_equation(mode as u32),
2487         }
2488     }
2489 
blend_equation_draw_buffer(&self, _draw_buffer: u32, _mode: u32)2490     unsafe fn blend_equation_draw_buffer(&self, _draw_buffer: u32, _mode: u32) {
2491         panic!("Draw buffer blend equation is not supported");
2492     }
2493 
blend_equation_separate(&self, mode_rgb: u32, mode_alpha: u32)2494     unsafe fn blend_equation_separate(&self, mode_rgb: u32, mode_alpha: u32) {
2495         match self.raw {
2496             RawRenderingContext::WebGl1(ref gl) => {
2497                 gl.blend_equation_separate(mode_rgb as u32, mode_alpha as u32)
2498             }
2499             RawRenderingContext::WebGl2(ref gl) => {
2500                 gl.blend_equation_separate(mode_rgb as u32, mode_alpha as u32)
2501             }
2502         }
2503     }
2504 
blend_equation_separate_draw_buffer( &self, _draw_buffer: u32, _mode_rgb: u32, _mode_alpha: u32, )2505     unsafe fn blend_equation_separate_draw_buffer(
2506         &self,
2507         _draw_buffer: u32,
2508         _mode_rgb: u32,
2509         _mode_alpha: u32,
2510     ) {
2511         panic!("Draw buffer blend equation separate is not supported");
2512     }
2513 
stencil_func(&self, func: u32, reference: i32, mask: u32)2514     unsafe fn stencil_func(&self, func: u32, reference: i32, mask: u32) {
2515         match self.raw {
2516             RawRenderingContext::WebGl1(ref gl) => gl.stencil_func(func as u32, reference, mask),
2517             RawRenderingContext::WebGl2(ref gl) => gl.stencil_func(func as u32, reference, mask),
2518         }
2519     }
2520 
stencil_func_separate(&self, face: u32, func: u32, reference: i32, mask: u32)2521     unsafe fn stencil_func_separate(&self, face: u32, func: u32, reference: i32, mask: u32) {
2522         match self.raw {
2523             RawRenderingContext::WebGl1(ref gl) => {
2524                 gl.stencil_func_separate(face as u32, func as u32, reference, mask)
2525             }
2526             RawRenderingContext::WebGl2(ref gl) => {
2527                 gl.stencil_func_separate(face as u32, func as u32, reference, mask)
2528             }
2529         }
2530     }
2531 
stencil_mask(&self, mask: u32)2532     unsafe fn stencil_mask(&self, mask: u32) {
2533         match self.raw {
2534             RawRenderingContext::WebGl1(ref gl) => gl.stencil_mask(mask),
2535             RawRenderingContext::WebGl2(ref gl) => gl.stencil_mask(mask),
2536         }
2537     }
2538 
stencil_mask_separate(&self, face: u32, mask: u32)2539     unsafe fn stencil_mask_separate(&self, face: u32, mask: u32) {
2540         match self.raw {
2541             RawRenderingContext::WebGl1(ref gl) => gl.stencil_mask_separate(face as u32, mask),
2542             RawRenderingContext::WebGl2(ref gl) => gl.stencil_mask_separate(face as u32, mask),
2543         }
2544     }
2545 
stencil_op(&self, stencil_fail: u32, depth_fail: u32, pass: u32)2546     unsafe fn stencil_op(&self, stencil_fail: u32, depth_fail: u32, pass: u32) {
2547         match self.raw {
2548             RawRenderingContext::WebGl1(ref gl) => {
2549                 gl.stencil_op(stencil_fail as u32, depth_fail as u32, pass as u32)
2550             }
2551             RawRenderingContext::WebGl2(ref gl) => {
2552                 gl.stencil_op(stencil_fail as u32, depth_fail as u32, pass as u32)
2553             }
2554         }
2555     }
2556 
stencil_op_separate(&self, face: u32, stencil_fail: u32, depth_fail: u32, pass: u32)2557     unsafe fn stencil_op_separate(&self, face: u32, stencil_fail: u32, depth_fail: u32, pass: u32) {
2558         match self.raw {
2559             RawRenderingContext::WebGl1(ref gl) => gl.stencil_op_separate(
2560                 face as u32,
2561                 stencil_fail as u32,
2562                 depth_fail as u32,
2563                 pass as u32,
2564             ),
2565             RawRenderingContext::WebGl2(ref gl) => gl.stencil_op_separate(
2566                 face as u32,
2567                 stencil_fail as u32,
2568                 depth_fail as u32,
2569                 pass as u32,
2570             ),
2571         }
2572     }
2573 
debug_message_control( &self, _source: u32, _msg_type: u32, _severity: u32, _ids: &[u32], _enabled: bool, )2574     unsafe fn debug_message_control(
2575         &self,
2576         _source: u32,
2577         _msg_type: u32,
2578         _severity: u32,
2579         _ids: &[u32],
2580         _enabled: bool,
2581     ) {
2582         panic!("WebGL does not support the KHR_debug extension.")
2583     }
2584 
debug_message_insert<S>( &self, _source: u32, _msg_type: u32, _id: u32, _severity: u32, _msg: S, ) where S: AsRef<str>,2585     unsafe fn debug_message_insert<S>(
2586         &self,
2587         _source: u32,
2588         _msg_type: u32,
2589         _id: u32,
2590         _severity: u32,
2591         _msg: S,
2592     ) where
2593         S: AsRef<str>,
2594     {
2595         panic!("WebGL does not support the KHR_debug extension.")
2596     }
2597 
debug_message_callback<F>(&self, _callback: F) where F: FnMut(u32, u32, u32, u32, &str),2598     unsafe fn debug_message_callback<F>(&self, _callback: F)
2599     where
2600         F: FnMut(u32, u32, u32, u32, &str),
2601     {
2602         panic!("WebGL does not support the KHR_debug extension.")
2603     }
2604 
get_debug_message_log(&self, _count: u32) -> Vec<DebugMessageLogEntry>2605     unsafe fn get_debug_message_log(&self, _count: u32) -> Vec<DebugMessageLogEntry> {
2606         panic!("WebGL does not support the KHR_debug extension.")
2607     }
2608 
push_debug_group<S>(&self, _source: u32, _id: u32, _message: S) where S: AsRef<str>,2609     unsafe fn push_debug_group<S>(&self, _source: u32, _id: u32, _message: S)
2610     where
2611         S: AsRef<str>,
2612     {
2613         panic!("WebGL does not support the KHR_debug extension.")
2614     }
2615 
pop_debug_group(&self)2616     unsafe fn pop_debug_group(&self) {
2617         panic!("WebGL does not support the KHR_debug extension.")
2618     }
2619 
object_label<S>(&self, _identifier: u32, _name: u32, _label: Option<S>) where S: AsRef<str>,2620     unsafe fn object_label<S>(&self, _identifier: u32, _name: u32, _label: Option<S>)
2621     where
2622         S: AsRef<str>,
2623     {
2624         panic!("WebGL does not support the KHR_debug extension.")
2625     }
2626 
get_object_label(&self, _identifier: u32, _name: u32) -> String2627     unsafe fn get_object_label(&self, _identifier: u32, _name: u32) -> String {
2628         panic!("WebGL does not support the KHR_debug extension.")
2629     }
2630 
object_ptr_label<S>(&self, _sync: Self::Fence, _label: Option<S>) where S: AsRef<str>,2631     unsafe fn object_ptr_label<S>(&self, _sync: Self::Fence, _label: Option<S>)
2632     where
2633         S: AsRef<str>,
2634     {
2635         panic!("WebGL does not support the KHR_debug extension.")
2636     }
2637 
get_object_ptr_label(&self, _sync: Self::Fence) -> String2638     unsafe fn get_object_ptr_label(&self, _sync: Self::Fence) -> String {
2639         panic!("WebGL does not support the KHR_debug extension.")
2640     }
2641 
get_uniform_block_index(&self, program: Self::Program, name: &str) -> Option<u32>2642     unsafe fn get_uniform_block_index(&self, program: Self::Program, name: &str) -> Option<u32> {
2643         let programs = self.programs.borrow();
2644         let raw_program = programs.1.get_unchecked(program);
2645         let index = match self.raw {
2646             RawRenderingContext::WebGl1(ref _gl) => panic!("Uniform blocks are not supported"),
2647             RawRenderingContext::WebGl2(ref gl) => gl.get_uniform_block_index(raw_program, name),
2648         };
2649         if index == INVALID_INDEX {
2650             None
2651         } else {
2652             Some(index)
2653         }
2654     }
2655 
uniform_block_binding(&self, program: Self::Program, index: u32, binding: u32)2656     unsafe fn uniform_block_binding(&self, program: Self::Program, index: u32, binding: u32) {
2657         match self.raw {
2658             RawRenderingContext::WebGl1(ref _gl) => {
2659                 panic!("Uniform buffer bindings are not supported")
2660             }
2661             RawRenderingContext::WebGl2(ref gl) => {
2662                 let programs = self.programs.borrow();
2663                 let raw_program = programs.1.get_unchecked(program);
2664                 gl.uniform_block_binding(raw_program, index, binding);
2665             }
2666         }
2667     }
2668 
get_shader_storage_block_index( &self, _program: Self::Program, _name: &str, ) -> Option<u32>2669     unsafe fn get_shader_storage_block_index(
2670         &self,
2671         _program: Self::Program,
2672         _name: &str,
2673     ) -> Option<u32> {
2674         panic!("Shader Storage Buffers are not supported by webgl")
2675     }
2676 
shader_storage_block_binding( &self, _program: Self::Program, _index: u32, _binding: u32, )2677     unsafe fn shader_storage_block_binding(
2678         &self,
2679         _program: Self::Program,
2680         _index: u32,
2681         _binding: u32,
2682     ) {
2683         panic!("Shader Storage Buffers are not supported by webgl")
2684     }
2685 
read_buffer(&self, src: u32)2686     unsafe fn read_buffer(&self, src: u32) {
2687         match self.raw {
2688             RawRenderingContext::WebGl1(..) => panic!("read_buffer is not supported by WebGL1"),
2689             RawRenderingContext::WebGl2(ref gl) => gl.read_buffer(src),
2690         }
2691     }
2692 
read_pixels( &self, x: i32, y: i32, width: i32, height: i32, format: u32, gltype: u32, pixels: PixelPackData, )2693     unsafe fn read_pixels(
2694         &self,
2695         x: i32,
2696         y: i32,
2697         width: i32,
2698         height: i32,
2699         format: u32,
2700         gltype: u32,
2701         pixels: PixelPackData,
2702     ) {
2703         let data = match pixels {
2704             PixelPackData::BufferOffset(_) => {
2705                 panic!("Read pixels into buffer offset is not supported")
2706             }
2707             // This is likely UB: passing an immutable slice to the Web. See
2708             // https://github.com/brendanzab/gl-rs/issues/525
2709             PixelPackData::Slice(slice) => Some(&*slice),
2710         };
2711         match self.raw {
2712             RawRenderingContext::WebGl1(ref gl) => {
2713                 gl.read_pixels(x, y, width, height, format, gltype, data)
2714             }
2715             RawRenderingContext::WebGl2(ref gl) => {
2716                 gl.read_pixels(x, y, width, height, format, gltype, data)
2717             }
2718         }
2719     }
2720 
get_uniform_i32( &self, program: Self::Program, location: &Self::UniformLocation, v: &mut [i32], )2721     unsafe fn get_uniform_i32(
2722         &self,
2723         program: Self::Program,
2724         location: &Self::UniformLocation,
2725         v: &mut [i32],
2726     ) {
2727         let programs = self.programs.borrow();
2728         let raw_program = programs.1.get_unchecked(program);
2729         let value = match self.raw {
2730             RawRenderingContext::WebGl1(ref gl) => gl.get_uniform(&raw_program, location),
2731             RawRenderingContext::WebGl2(ref gl) => gl.get_uniform(&raw_program, location),
2732         };
2733         if let Some(value_reference) = value.as_reference() {
2734             if let Ok(value) = TryInto::<std_web::web::TypedArray<i32>>::try_into(value_reference) {
2735                 let value: Vec<_> = value.into();
2736                 v.copy_from_slice(&value);
2737             }
2738         } else if let Ok(value) = TryInto::<i32>::try_into(value) {
2739             v[0] = value;
2740         }
2741     }
2742 
get_uniform_f32( &self, program: Self::Program, location: &Self::UniformLocation, v: &mut [f32], )2743     unsafe fn get_uniform_f32(
2744         &self,
2745         program: Self::Program,
2746         location: &Self::UniformLocation,
2747         v: &mut [f32],
2748     ) {
2749         let programs = self.programs.borrow();
2750         let raw_program = programs.1.get_unchecked(program);
2751         let value = match self.raw {
2752             RawRenderingContext::WebGl1(ref gl) => gl.get_uniform(&raw_program, location),
2753             RawRenderingContext::WebGl2(ref gl) => gl.get_uniform(&raw_program, location),
2754         };
2755         if let Some(value_reference) = value.as_reference() {
2756             if let Ok(value) = TryInto::<std_web::web::TypedArray<f32>>::try_into(value_reference) {
2757                 let value: Vec<_> = value.into();
2758                 v.copy_from_slice(&value);
2759             }
2760         } else if let Ok(value) = TryInto::<f64>::try_into(value) {
2761             v[0] = value as f32;
2762         }
2763     }
2764 
begin_query(&self, target: u32, query: Self::Query)2765     unsafe fn begin_query(&self, target: u32, query: Self::Query) {
2766         let queries = self.queries.borrow();
2767         let raw_query = queries.1.get_unchecked(query);
2768         match self.raw {
2769             RawRenderingContext::WebGl1(ref _gl) => panic!("Query objects are not supported"),
2770             RawRenderingContext::WebGl2(ref gl) => gl.begin_query(target, raw_query),
2771         }
2772     }
2773 
end_query(&self, target: u32)2774     unsafe fn end_query(&self, target: u32) {
2775         match self.raw {
2776             RawRenderingContext::WebGl1(ref _gl) => panic!("Query objects are not supported"),
2777             RawRenderingContext::WebGl2(ref gl) => gl.end_query(target),
2778         }
2779     }
2780 
get_query_parameter_u32(&self, query: Self::Query, parameter: u32) -> u322781     unsafe fn get_query_parameter_u32(&self, query: Self::Query, parameter: u32) -> u32 {
2782         let queries = self.queries.borrow();
2783         let raw_query = queries.1.get_unchecked(query);
2784         match self.raw {
2785             RawRenderingContext::WebGl1(ref _gl) => panic!("Query objects are not supported"),
2786             RawRenderingContext::WebGl2(ref gl) => gl
2787                 .get_query_parameter(raw_query, parameter)
2788                 .try_into()
2789                 .map(|v: f64| v as u32)
2790                 .unwrap_or(0),
2791         }
2792     }
2793 
create_transform_feedback(&self) -> Result<Self::TransformFeedback, String>2794     unsafe fn create_transform_feedback(&self) -> Result<Self::TransformFeedback, String> {
2795         let raw_transform_feedback = match self.raw {
2796             RawRenderingContext::WebGl1(ref _gl) => {
2797                 panic!("TransformFeedback objects are not supported")
2798             }
2799             RawRenderingContext::WebGl2(ref gl) => gl.create_transform_feedback(),
2800         };
2801 
2802         match raw_transform_feedback {
2803             Some(t) => {
2804                 let key = self.transform_feedbacks.borrow_mut().0.insert(());
2805                 self.transform_feedbacks.borrow_mut().1.insert(key, t);
2806                 Ok(key)
2807             }
2808             None => Err(String::from("Unable to create TransformFeedback object")),
2809         }
2810     }
2811 
delete_transform_feedback(&self, transform_feedback: Self::TransformFeedback)2812     unsafe fn delete_transform_feedback(&self, transform_feedback: Self::TransformFeedback) {
2813         let mut transform_feedbacks = self.transform_feedbacks.borrow_mut();
2814         if let Some(ref t) = transform_feedbacks.1.remove(transform_feedback) {
2815             match self.raw {
2816                 RawRenderingContext::WebGl1(ref _gl) => {
2817                     panic!("TransformFeedback objects are not supported")
2818                 }
2819                 RawRenderingContext::WebGl2(ref gl) => gl.delete_transform_feedback(Some(t)),
2820             }
2821         }
2822     }
2823 
bind_transform_feedback( &self, target: u32, transform_feedback: Option<Self::TransformFeedback>, )2824     unsafe fn bind_transform_feedback(
2825         &self,
2826         target: u32,
2827         transform_feedback: Option<Self::TransformFeedback>,
2828     ) {
2829         let transform_feedbacks = self.transform_feedbacks.borrow();
2830         let raw_transform_feedback =
2831             transform_feedback.map(|tf| transform_feedbacks.1.get_unchecked(tf));
2832         match self.raw {
2833             RawRenderingContext::WebGl1(ref _gl) => {
2834                 panic!("TransformFeedback objects are not supported")
2835             }
2836             RawRenderingContext::WebGl2(ref gl) => {
2837                 gl.bind_transform_feedback(target, raw_transform_feedback)
2838             }
2839         }
2840     }
2841 
begin_transform_feedback(&self, primitive_mode: u32)2842     unsafe fn begin_transform_feedback(&self, primitive_mode: u32) {
2843         match self.raw {
2844             RawRenderingContext::WebGl1(ref _gl) => {
2845                 panic!("TransformFeedback objects are not supported")
2846             }
2847             RawRenderingContext::WebGl2(ref gl) => gl.begin_transform_feedback(primitive_mode),
2848         }
2849     }
2850 
end_transform_feedback(&self)2851     unsafe fn end_transform_feedback(&self) {
2852         match self.raw {
2853             RawRenderingContext::WebGl1(ref _gl) => {
2854                 panic!("TransformFeedback objects are not supported")
2855             }
2856             RawRenderingContext::WebGl2(ref gl) => gl.end_transform_feedback(),
2857         }
2858     }
2859 
pause_transform_feedback(&self)2860     unsafe fn pause_transform_feedback(&self) {
2861         match self.raw {
2862             RawRenderingContext::WebGl1(ref _gl) => {
2863                 panic!("TransformFeedback objects are not supported")
2864             }
2865             RawRenderingContext::WebGl2(ref gl) => gl.pause_transform_feedback(),
2866         }
2867     }
2868 
resume_transform_feedback(&self)2869     unsafe fn resume_transform_feedback(&self) {
2870         match self.raw {
2871             RawRenderingContext::WebGl1(ref _gl) => {
2872                 panic!("TransformFeedback objects are not supported")
2873             }
2874             RawRenderingContext::WebGl2(ref gl) => gl.resume_transform_feedback(),
2875         }
2876     }
2877 
transform_feedback_varyings( &self, program: Self::Program, varyings: &[&str], buffer_mode: u32, )2878     unsafe fn transform_feedback_varyings(
2879         &self,
2880         program: Self::Program,
2881         varyings: &[&str],
2882         buffer_mode: u32,
2883     ) {
2884         let programs = self.programs.borrow();
2885         let raw_program = programs.1.get_unchecked(program);
2886         match self.raw {
2887             RawRenderingContext::WebGl1(ref _gl) => {
2888                 panic!("TransformFeedback objects are not supported")
2889             }
2890             RawRenderingContext::WebGl2(ref gl) => {
2891                 gl.transform_feedback_varyings(raw_program, varyings, buffer_mode)
2892             }
2893         }
2894     }
2895 
get_transform_feedback_varying( &self, program: Self::Program, index: u32, ) -> Option<ActiveTransformFeedback>2896     unsafe fn get_transform_feedback_varying(
2897         &self,
2898         program: Self::Program,
2899         index: u32,
2900     ) -> Option<ActiveTransformFeedback> {
2901         let programs = self.programs.borrow();
2902         let raw_program = programs.1.get_unchecked(program);
2903         match self.raw {
2904             RawRenderingContext::WebGl1(ref _gl) => {
2905                 panic!("TransformFeedback objects are not supported")
2906             }
2907             RawRenderingContext::WebGl2(ref gl) => gl
2908                 .get_transform_feedback_varying(raw_program, index)
2909                 .map(|info| ActiveTransformFeedback {
2910                     size: info.size(),
2911                     tftype: info.type_(),
2912                     name: info.name(),
2913                 }),
2914         }
2915     }
2916 }
2917 
2918 pub struct RenderLoop;
2919 
2920 impl RenderLoop {
from_request_animation_frame() -> Self2921     pub fn from_request_animation_frame() -> Self {
2922         RenderLoop
2923     }
2924 }
2925 
2926 impl HasRenderLoop for RenderLoop {
2927     type Window = ();
2928 
run<F: FnMut(&mut bool) + 'static>(&self, callback: F)2929     fn run<F: FnMut(&mut bool) + 'static>(&self, callback: F) {
2930         fn callback_loop<F: FnMut(&mut bool) + 'static>(mut callback: F) {
2931             let mut running = true;
2932             callback(&mut running);
2933             if running {
2934                 window().request_animation_frame(move |_| callback_loop(callback));
2935             }
2936         }
2937 
2938         callback_loop(callback);
2939     }
2940 }
2941