1 use super::*;
2 
3 use js_sys::{self, Array};
4 use slotmap::{new_key_type, SlotMap};
5 use std::cell::RefCell;
6 use web_sys::{
7     self, HtmlCanvasElement, HtmlImageElement, ImageBitmap, WebGl2RenderingContext, WebGlBuffer,
8     WebGlFramebuffer, WebGlProgram, WebGlQuery, WebGlRenderbuffer, WebGlRenderingContext,
9     WebGlSampler, WebGlShader, WebGlSync, WebGlTexture, WebGlTransformFeedback,
10     WebGlUniformLocation, WebGlVertexArrayObject,
11 };
12 
13 #[derive(Debug)]
14 enum RawRenderingContext {
15     WebGl1(WebGlRenderingContext),
16     WebGl2(WebGl2RenderingContext),
17 }
18 
19 #[derive(Debug)]
20 struct Extensions {
21     pub angle_instanced_arrays: Option<web_sys::AngleInstancedArrays>,
22     pub ext_blend_minmax: Option<web_sys::ExtBlendMinmax>,
23     pub ext_color_buffer_float: Option<web_sys::ExtColorBufferFloat>,
24     pub ext_color_buffer_half_float: Option<web_sys::ExtColorBufferHalfFloat>,
25     pub ext_disjoint_timer_query: Option<web_sys::ExtDisjointTimerQuery>,
26     pub ext_disjoint_timer_query_webgl2: Option<()>,
27     pub ext_float_blend: Option<()>,
28     pub ext_frag_depth: Option<web_sys::ExtFragDepth>,
29     pub ext_shader_texture_lod: Option<web_sys::ExtShaderTextureLod>,
30     pub ext_srgb: Option<web_sys::ExtSRgb>,
31     pub ext_texture_compression_bptc: Option<()>,
32     pub ext_texture_compression_rgtc: Option<()>,
33     pub ext_texture_filter_anisotropic: Option<web_sys::ExtTextureFilterAnisotropic>,
34     pub khr_parallel_shader_compile: Option<()>,
35     pub oes_element_index_uint: Option<web_sys::OesElementIndexUint>,
36     pub oes_fbo_render_mipmap: Option<()>,
37     pub oes_standard_derivatives: Option<web_sys::OesStandardDerivatives>,
38     pub oes_texture_float: Option<web_sys::OesTextureFloat>,
39     pub oes_texture_float_linear: Option<web_sys::OesTextureFloatLinear>,
40     pub oes_texture_half_float: Option<web_sys::OesTextureHalfFloat>,
41     pub oes_texture_half_float_linear: Option<web_sys::OesTextureHalfFloatLinear>,
42     pub oes_vertex_array_object: Option<web_sys::OesVertexArrayObject>,
43     pub ovr_multiview2: Option<()>,
44     pub webgl_color_buffer_float: Option<web_sys::WebglColorBufferFloat>,
45     pub webgl_compressed_texture_astc: Option<web_sys::WebglCompressedTextureAstc>,
46     pub webgl_compressed_texture_etc: Option<web_sys::WebglCompressedTextureEtc>,
47     pub webgl_compressed_texture_etc1: Option<web_sys::WebglCompressedTextureEtc1>,
48     pub webgl_compressed_texture_pvrtc: Option<web_sys::WebglCompressedTexturePvrtc>,
49     pub webgl_compressed_texture_s3tc: Option<web_sys::WebglCompressedTextureS3tc>,
50     pub webgl_compressed_texture_s3tc_srgb: Option<web_sys::WebglCompressedTextureS3tcSrgb>,
51     pub webgl_debug_renderer_info: Option<web_sys::WebglDebugRendererInfo>,
52     pub webgl_debug_shaders: Option<web_sys::WebglDebugShaders>,
53     pub webgl_depth_texture: Option<web_sys::WebglDepthTexture>,
54     pub webgl_draw_buffers: Option<web_sys::WebglDrawBuffers>,
55     pub webgl_lose_context: Option<web_sys::WebglLoseContext>,
56 }
57 
58 type TrackedResource<K, V> = RefCell<SlotMap<K, V>>;
59 
tracked_resource<K: slotmap::Key, V>() -> TrackedResource<K, V>60 fn tracked_resource<K: slotmap::Key, V>() -> TrackedResource<K, V> {
61     RefCell::new(SlotMap::with_key())
62 }
63 
64 #[derive(Debug)]
65 pub struct Context {
66     raw: RawRenderingContext,
67     extensions: Extensions,
68     version: Version,
69     supported_extensions: HashSet<String>,
70     shaders: TrackedResource<WebShaderKey, WebGlShader>,
71     programs: TrackedResource<WebProgramKey, WebGlProgram>,
72     buffers: TrackedResource<WebBufferKey, WebGlBuffer>,
73     vertex_arrays: TrackedResource<WebVertexArrayKey, WebGlVertexArrayObject>,
74     textures: TrackedResource<WebTextureKey, WebGlTexture>,
75     samplers: TrackedResource<WebSamplerKey, WebGlSampler>,
76     fences: TrackedResource<WebFenceKey, WebGlSync>,
77     framebuffers: TrackedResource<WebFramebufferKey, WebGlFramebuffer>,
78     renderbuffers: TrackedResource<WebRenderbufferKey, WebGlRenderbuffer>,
79     queries: TrackedResource<WebQueryKey, WebGlQuery>,
80     transform_feedbacks: TrackedResource<WebTransformFeedbackKey, WebGlTransformFeedback>,
81 }
82 
83 // bindgen's gl context don't share an interface so a macro is used to deduplicate a bunch of code here
84 macro_rules! build_extensions {
85     ($context:ident, $context_type:ty) => {{
86         fn get_extension<T>(context: &$context_type, name: &str) -> Option<T>
87         where
88             T: wasm_bindgen::JsCast,
89         {
90             use wasm_bindgen::JsCast;
91             // `unchecked_into` is used here because WebGL extensions aren't actually JS classes
92             // these objects are duck-type representations of the actual Rust classes
93             // https://github.com/rustwasm/wasm-bindgen/pull/1449
94             context
95                 .get_extension(name)
96                 .ok()
97                 .and_then(|maybe_ext| maybe_ext.map(|ext| ext.unchecked_into::<T>()))
98         }
99 
100         fn get_extension_no_object(context: &$context_type, name: &str) -> Option<()> {
101             context
102                 .get_extension(name)
103                 .ok()
104                 .and_then(|maybe_ext| maybe_ext.map(|_| ()))
105         }
106 
107         let extensions = Extensions {
108             angle_instanced_arrays: get_extension::<web_sys::AngleInstancedArrays>(
109                 &$context,
110                 "ANGLE_instanced_arrays",
111             ),
112             ext_blend_minmax: get_extension::<web_sys::ExtBlendMinmax>(
113                 &$context,
114                 "EXT_blend_minmax",
115             ),
116             ext_color_buffer_float: get_extension::<web_sys::ExtColorBufferFloat>(
117                 &$context,
118                 "EXT_color_buffer_float",
119             ),
120             ext_color_buffer_half_float: get_extension::<web_sys::ExtColorBufferHalfFloat>(
121                 &$context,
122                 "EXT_color_buffer_half_float",
123             ),
124             ext_disjoint_timer_query: get_extension::<web_sys::ExtDisjointTimerQuery>(
125                 &$context,
126                 "EXT_disjoint_timer_query",
127             ),
128             ext_disjoint_timer_query_webgl2: get_extension_no_object(
129                 &$context,
130                 "EXT_disjoint_timer_query_webgl2",
131             ),
132             ext_float_blend: get_extension_no_object(&$context, "EXT_float_blend"),
133             ext_frag_depth: get_extension::<web_sys::ExtFragDepth>(&$context, "EXT_frag_depth"),
134             ext_shader_texture_lod: get_extension::<web_sys::ExtShaderTextureLod>(
135                 &$context,
136                 "EXT_shader_texture_lod",
137             ),
138             ext_srgb: get_extension::<web_sys::ExtSRgb>(&$context, "EXT_sRGB"),
139             ext_texture_compression_bptc: get_extension_no_object(
140                 &$context,
141                 "EXT_texture_compression_bptc",
142             ),
143             ext_texture_compression_rgtc: get_extension_no_object(
144                 &$context,
145                 "EXT_texture_compression_rgtc",
146             ),
147             ext_texture_filter_anisotropic: get_extension::<web_sys::ExtTextureFilterAnisotropic>(
148                 &$context,
149                 "EXT_texture_filter_anisotropic",
150             ),
151             khr_parallel_shader_compile: get_extension_no_object(
152                 &$context,
153                 "KHR_parallel_shader_compile",
154             ),
155             oes_element_index_uint: get_extension::<web_sys::OesElementIndexUint>(
156                 &$context,
157                 "OES_element_index_uint",
158             ),
159             oes_fbo_render_mipmap: get_extension_no_object(&$context, "OES_fbo_render_mipmap"),
160             oes_standard_derivatives: get_extension::<web_sys::OesStandardDerivatives>(
161                 &$context,
162                 "OES_standard_derivatives",
163             ),
164             oes_texture_float: get_extension::<web_sys::OesTextureFloat>(
165                 &$context,
166                 "OES_texture_float",
167             ),
168             oes_texture_float_linear: get_extension::<web_sys::OesTextureFloatLinear>(
169                 &$context,
170                 "OES_texture_float_linear",
171             ),
172             oes_texture_half_float: get_extension::<web_sys::OesTextureHalfFloat>(
173                 &$context,
174                 "OES_texture_half_float",
175             ),
176             oes_texture_half_float_linear: get_extension::<web_sys::OesTextureHalfFloatLinear>(
177                 &$context,
178                 "OES_texture_half_float_linear",
179             ),
180             oes_vertex_array_object: get_extension::<web_sys::OesVertexArrayObject>(
181                 &$context,
182                 "OES_vertex_array_object",
183             ),
184             ovr_multiview2: get_extension_no_object(&$context, "OVR_multiview2"),
185             webgl_color_buffer_float: get_extension::<web_sys::WebglColorBufferFloat>(
186                 &$context,
187                 "WEBGL_color_buffer_float",
188             ),
189             webgl_compressed_texture_astc: get_extension::<web_sys::WebglCompressedTextureAstc>(
190                 &$context,
191                 "WEBGL_compressed_texture_astc",
192             ),
193             webgl_compressed_texture_etc: get_extension::<web_sys::WebglCompressedTextureEtc>(
194                 &$context,
195                 "WEBGL_compressed_texture_etc",
196             ),
197             webgl_compressed_texture_etc1: get_extension::<web_sys::WebglCompressedTextureEtc1>(
198                 &$context,
199                 "WEBGL_compressed_texture_etc1",
200             ),
201             webgl_compressed_texture_pvrtc: get_extension::<web_sys::WebglCompressedTexturePvrtc>(
202                 &$context,
203                 "WEBGL_compressed_texture_pvrtc",
204             ),
205             webgl_compressed_texture_s3tc: get_extension::<web_sys::WebglCompressedTextureS3tc>(
206                 &$context,
207                 "WEBGL_compressed_texture_s3tc",
208             ),
209             webgl_compressed_texture_s3tc_srgb: get_extension::<
210                 web_sys::WebglCompressedTextureS3tcSrgb,
211             >(
212                 &$context, "WEBGL_compressed_texture_s3tc_srgb"
213             ),
214             webgl_debug_renderer_info: get_extension::<web_sys::WebglDebugRendererInfo>(
215                 &$context,
216                 "WEBGL_debug_renderer_info",
217             ),
218             webgl_debug_shaders: get_extension::<web_sys::WebglDebugShaders>(
219                 &$context,
220                 "WEBGL_debug_shaders",
221             ),
222             webgl_depth_texture: get_extension::<web_sys::WebglDepthTexture>(
223                 &$context,
224                 "WEBGL_depth_texture",
225             ),
226             webgl_draw_buffers: get_extension::<web_sys::WebglDrawBuffers>(
227                 &$context,
228                 "WEBGL_draw_buffers",
229             ),
230             webgl_lose_context: get_extension::<web_sys::WebglLoseContext>(
231                 &$context,
232                 "WEBGL_lose_context",
233             ),
234         };
235 
236         let supported_extensions = $context
237             .get_supported_extensions()
238             .unwrap()
239             .iter()
240             .map(|val| val.as_string().unwrap())
241             .collect::<HashSet<String>>();
242 
243         (extensions, supported_extensions)
244     }};
245 }
246 
247 impl Context {
from_webgl1_context(context: WebGlRenderingContext) -> Self248     pub fn from_webgl1_context(context: WebGlRenderingContext) -> Self {
249         let (extensions, supported_extensions) = build_extensions!(context, WebGlRenderingContext);
250 
251         // Retrieve and parse `GL_VERSION`
252         let raw_string = context.get_parameter(VERSION).unwrap().as_string().unwrap();
253         let version = Version::parse(&raw_string).unwrap();
254 
255         Self {
256             raw: RawRenderingContext::WebGl1(context),
257             extensions,
258             supported_extensions,
259             version,
260             shaders: tracked_resource(),
261             programs: tracked_resource(),
262             buffers: tracked_resource(),
263             vertex_arrays: tracked_resource(),
264             textures: tracked_resource(),
265             samplers: tracked_resource(),
266             fences: tracked_resource(),
267             framebuffers: tracked_resource(),
268             renderbuffers: tracked_resource(),
269             queries: tracked_resource(),
270             transform_feedbacks: tracked_resource(),
271         }
272     }
273 
from_webgl2_context(context: WebGl2RenderingContext) -> Self274     pub fn from_webgl2_context(context: WebGl2RenderingContext) -> Self {
275         let (extensions, supported_extensions) = build_extensions!(context, WebGl2RenderingContext);
276 
277         // Retrieve and parse `GL_VERSION`
278         let raw_string = context.get_parameter(VERSION).unwrap().as_string().unwrap();
279         let version = Version::parse(&raw_string).unwrap();
280 
281         Self {
282             raw: RawRenderingContext::WebGl2(context),
283             extensions,
284             supported_extensions,
285             version,
286             shaders: tracked_resource(),
287             programs: tracked_resource(),
288             buffers: tracked_resource(),
289             vertex_arrays: tracked_resource(),
290             textures: tracked_resource(),
291             samplers: tracked_resource(),
292             fences: tracked_resource(),
293             framebuffers: tracked_resource(),
294             renderbuffers: tracked_resource(),
295             queries: tracked_resource(),
296             transform_feedbacks: tracked_resource(),
297         }
298     }
299 
tex_image_2d_with_html_image( &self, target: u32, level: i32, internal_format: i32, format: u32, ty: u32, image: &HtmlImageElement, )300     pub unsafe fn tex_image_2d_with_html_image(
301         &self,
302         target: u32,
303         level: i32,
304         internal_format: i32,
305         format: u32,
306         ty: u32,
307         image: &HtmlImageElement,
308     ) {
309         match self.raw {
310             RawRenderingContext::WebGl1(ref gl) => {
311                 // TODO: Handle return value?
312                 gl.tex_image_2d_with_u32_and_u32_and_image(
313                     target,
314                     level,
315                     internal_format,
316                     format,
317                     ty,
318                     image,
319                 )
320                 .unwrap();
321             }
322             RawRenderingContext::WebGl2(ref gl) => {
323                 // TODO: Handle return value?
324                 gl.tex_image_2d_with_u32_and_u32_and_html_image_element(
325                     target,
326                     level,
327                     internal_format,
328                     format,
329                     ty,
330                     image,
331                 )
332                 .unwrap();
333             }
334         }
335     }
336 
tex_image_2d_with_image_bitmap( &self, target: u32, level: i32, internal_format: i32, format: u32, ty: u32, pixels: &ImageBitmap, )337     pub unsafe fn tex_image_2d_with_image_bitmap(
338         &self,
339         target: u32,
340         level: i32,
341         internal_format: i32,
342         format: u32,
343         ty: u32,
344         pixels: &ImageBitmap,
345     ) {
346         match self.raw {
347             RawRenderingContext::WebGl1(ref gl) => {
348                 // TODO: Handle return value?
349                 gl.tex_image_2d_with_u32_and_u32_and_image_bitmap(
350                     target,
351                     level,
352                     internal_format,
353                     format,
354                     ty,
355                     pixels,
356                 )
357                 .unwrap();
358             }
359             RawRenderingContext::WebGl2(ref gl) => {
360                 // TODO: Handle return value?
361                 gl.tex_image_2d_with_u32_and_u32_and_image_bitmap(
362                     target,
363                     level,
364                     internal_format,
365                     format,
366                     ty,
367                     pixels,
368                 )
369                 .unwrap();
370             }
371         }
372     }
373 
tex_image_2d_with_html_canvas( &self, target: u32, level: i32, internal_format: i32, format: u32, ty: u32, canvas: &HtmlCanvasElement, )374     pub unsafe fn tex_image_2d_with_html_canvas(
375         &self,
376         target: u32,
377         level: i32,
378         internal_format: i32,
379         format: u32,
380         ty: u32,
381         canvas: &HtmlCanvasElement,
382     ) {
383         match self.raw {
384             RawRenderingContext::WebGl1(ref gl) => {
385                 // TODO: Handle return value?
386                 gl.tex_image_2d_with_u32_and_u32_and_canvas(
387                     target,
388                     level,
389                     internal_format,
390                     format,
391                     ty,
392                     canvas,
393                 )
394                 .unwrap();
395             }
396             RawRenderingContext::WebGl2(ref gl) => {
397                 // TODO: Handle return value?
398                 gl.tex_image_2d_with_u32_and_u32_and_html_canvas_element(
399                     target,
400                     level,
401                     internal_format,
402                     format,
403                     ty,
404                     canvas,
405                 )
406                 .unwrap();
407             }
408         }
409     }
410 
tex_sub_image_2d_with_html_image( &self, target: u32, level: i32, x_offset: i32, y_offset: i32, format: u32, ty: u32, image: &HtmlImageElement, )411     pub unsafe fn tex_sub_image_2d_with_html_image(
412         &self,
413         target: u32,
414         level: i32,
415         x_offset: i32,
416         y_offset: i32,
417         format: u32,
418         ty: u32,
419         image: &HtmlImageElement,
420     ) {
421         match self.raw {
422             RawRenderingContext::WebGl1(ref gl) => {
423                 gl.tex_sub_image_2d_with_u32_and_u32_and_image(
424                     target, level, x_offset, y_offset, format, ty, image,
425                 )
426                 .unwrap(); // TODO: Handle return value?
427             }
428             RawRenderingContext::WebGl2(ref gl) => {
429                 gl.tex_sub_image_2d_with_u32_and_u32_and_html_image_element(
430                     target, level, x_offset, y_offset, format, ty, image,
431                 )
432                 .unwrap(); // TODO: Handle return value?
433             }
434         }
435     }
436 }
437 
438 new_key_type! { pub struct WebShaderKey; }
439 new_key_type! { pub struct WebProgramKey; }
440 new_key_type! { pub struct WebBufferKey; }
441 new_key_type! { pub struct WebVertexArrayKey; }
442 new_key_type! { pub struct WebTextureKey; }
443 new_key_type! { pub struct WebSamplerKey; }
444 new_key_type! { pub struct WebFenceKey; }
445 new_key_type! { pub struct WebFramebufferKey; }
446 new_key_type! { pub struct WebRenderbufferKey; }
447 new_key_type! { pub struct WebQueryKey; }
448 new_key_type! { pub struct WebTransformFeedbackKey; }
449 
450 impl HasContext for Context {
451     type Shader = WebShaderKey;
452     type Program = WebProgramKey;
453     type Buffer = WebBufferKey;
454     type VertexArray = WebVertexArrayKey;
455     type Texture = WebTextureKey;
456     type Sampler = WebSamplerKey;
457     type Fence = WebFenceKey;
458     type Framebuffer = WebFramebufferKey;
459     type Renderbuffer = WebRenderbufferKey;
460     type Query = WebQueryKey;
461     type UniformLocation = WebGlUniformLocation;
462     type TransformFeedback = WebTransformFeedbackKey;
463 
supported_extensions(&self) -> &HashSet<String>464     fn supported_extensions(&self) -> &HashSet<String> {
465         &self.supported_extensions
466     }
467 
supports_debug(&self) -> bool468     fn supports_debug(&self) -> bool {
469         false
470     }
471 
version(&self) -> &Version472     fn version(&self) -> &Version {
473         &self.version
474     }
475 
create_framebuffer(&self) -> Result<Self::Framebuffer, String>476     unsafe fn create_framebuffer(&self) -> Result<Self::Framebuffer, String> {
477         let raw_framebuffer = match self.raw {
478             RawRenderingContext::WebGl1(ref gl) => gl.create_framebuffer(),
479             RawRenderingContext::WebGl2(ref gl) => gl.create_framebuffer(),
480         };
481 
482         match raw_framebuffer {
483             Some(s) => {
484                 let key = self.framebuffers.borrow_mut().insert(s);
485                 Ok(key)
486             }
487             None => Err(String::from("Unable to create framebuffer object")),
488         }
489     }
490 
is_framebuffer(&self, framebuffer: Self::Framebuffer) -> bool491     unsafe fn is_framebuffer(&self, framebuffer: Self::Framebuffer) -> bool {
492         let framebuffers = self.framebuffers.borrow_mut();
493         if let Some(ref f) = framebuffers.get(framebuffer) {
494             match self.raw {
495                 RawRenderingContext::WebGl1(ref gl) => gl.is_framebuffer(Some(f)),
496                 RawRenderingContext::WebGl2(ref gl) => gl.is_framebuffer(Some(f)),
497             }
498         } else {
499             false
500         }
501     }
502 
create_query(&self) -> Result<Self::Query, String>503     unsafe fn create_query(&self) -> Result<Self::Query, String> {
504         let raw_query = match self.raw {
505             RawRenderingContext::WebGl1(ref _gl) => {
506                 return Err(String::from("Query objects are not supported"));
507             }
508             RawRenderingContext::WebGl2(ref gl) => gl.create_query(),
509         };
510 
511         match raw_query {
512             Some(s) => {
513                 let key = self.queries.borrow_mut().insert(s);
514                 Ok(key)
515             }
516             None => Err(String::from("Unable to create query object")),
517         }
518     }
519 
create_renderbuffer(&self) -> Result<Self::Renderbuffer, String>520     unsafe fn create_renderbuffer(&self) -> Result<Self::Renderbuffer, String> {
521         let raw_renderbuffer = match self.raw {
522             RawRenderingContext::WebGl1(ref gl) => gl.create_renderbuffer(),
523             RawRenderingContext::WebGl2(ref gl) => gl.create_renderbuffer(),
524         };
525 
526         match raw_renderbuffer {
527             Some(s) => {
528                 let key = self.renderbuffers.borrow_mut().insert(s);
529                 Ok(key)
530             }
531             None => Err(String::from("Unable to create renderbuffer object")),
532         }
533     }
534 
is_renderbuffer(&self, renderbuffer: Self::Renderbuffer) -> bool535     unsafe fn is_renderbuffer(&self, renderbuffer: Self::Renderbuffer) -> bool {
536         let renderbuffers = self.renderbuffers.borrow_mut();
537         if let Some(ref r) = renderbuffers.get(renderbuffer) {
538             match self.raw {
539                 RawRenderingContext::WebGl1(ref gl) => gl.is_renderbuffer(Some(r)),
540                 RawRenderingContext::WebGl2(ref gl) => gl.is_renderbuffer(Some(r)),
541             }
542         } else {
543             false
544         }
545     }
546 
create_sampler(&self) -> Result<Self::Sampler, String>547     unsafe fn create_sampler(&self) -> Result<Self::Sampler, String> {
548         let raw_sampler = match self.raw {
549             RawRenderingContext::WebGl1(ref _gl) => panic!("Sampler objects are not supported"),
550             RawRenderingContext::WebGl2(ref gl) => gl.create_sampler(),
551         };
552 
553         match raw_sampler {
554             Some(s) => {
555                 let key = self.samplers.borrow_mut().insert(s);
556                 Ok(key)
557             }
558             None => Err(String::from("Unable to create sampler object")),
559         }
560     }
561 
create_shader(&self, shader_type: u32) -> Result<Self::Shader, String>562     unsafe fn create_shader(&self, shader_type: u32) -> Result<Self::Shader, String> {
563         let raw_shader = match self.raw {
564             RawRenderingContext::WebGl1(ref gl) => gl.create_shader(shader_type as u32),
565             RawRenderingContext::WebGl2(ref gl) => gl.create_shader(shader_type as u32),
566         };
567 
568         match raw_shader {
569             Some(s) => {
570                 let key = self.shaders.borrow_mut().insert(s);
571                 Ok(key)
572             }
573             None => Err(String::from("Unable to create shader object")),
574         }
575     }
576 
is_shader(&self, shader: Self::Shader) -> bool577     unsafe fn is_shader(&self, shader: Self::Shader) -> bool {
578         let shaders = self.shaders.borrow_mut();
579         if let Some(ref s) = shaders.get(shader) {
580             match self.raw {
581                 RawRenderingContext::WebGl1(ref gl) => gl.is_shader(Some(s)),
582                 RawRenderingContext::WebGl2(ref gl) => gl.is_shader(Some(s)),
583             }
584         } else {
585             false
586         }
587     }
588 
create_texture(&self) -> Result<Self::Texture, String>589     unsafe fn create_texture(&self) -> Result<Self::Texture, String> {
590         let raw_texture = match self.raw {
591             RawRenderingContext::WebGl1(ref gl) => gl.create_texture(),
592             RawRenderingContext::WebGl2(ref gl) => gl.create_texture(),
593         };
594 
595         match raw_texture {
596             Some(t) => {
597                 let key = self.textures.borrow_mut().insert(t);
598                 Ok(key)
599             }
600             None => Err(String::from("Unable to create texture object")),
601         }
602     }
603 
is_texture(&self, texture: Self::Texture) -> bool604     unsafe fn is_texture(&self, texture: Self::Texture) -> bool {
605         let textures = self.textures.borrow_mut();
606         if let Some(ref t) = textures.get(texture) {
607             match self.raw {
608                 RawRenderingContext::WebGl1(ref gl) => gl.is_texture(Some(t)),
609                 RawRenderingContext::WebGl2(ref gl) => gl.is_texture(Some(t)),
610             }
611         } else {
612             false
613         }
614     }
615 
delete_shader(&self, shader: Self::Shader)616     unsafe fn delete_shader(&self, shader: Self::Shader) {
617         let mut shaders = self.shaders.borrow_mut();
618         if let Some(ref s) = shaders.remove(shader) {
619             match self.raw {
620                 RawRenderingContext::WebGl1(ref gl) => gl.delete_shader(Some(s)),
621                 RawRenderingContext::WebGl2(ref gl) => gl.delete_shader(Some(s)),
622             }
623         }
624     }
625 
shader_source(&self, shader: Self::Shader, source: &str)626     unsafe fn shader_source(&self, shader: Self::Shader, source: &str) {
627         let shaders = self.shaders.borrow();
628         let raw_shader = shaders.get_unchecked(shader);
629         match self.raw {
630             RawRenderingContext::WebGl1(ref gl) => gl.shader_source(raw_shader, source),
631             RawRenderingContext::WebGl2(ref gl) => gl.shader_source(raw_shader, source),
632         }
633     }
634 
compile_shader(&self, shader: Self::Shader)635     unsafe fn compile_shader(&self, shader: Self::Shader) {
636         let shaders = self.shaders.borrow();
637         let raw_shader = shaders.get_unchecked(shader);
638         match self.raw {
639             RawRenderingContext::WebGl1(ref gl) => gl.compile_shader(raw_shader),
640             RawRenderingContext::WebGl2(ref gl) => gl.compile_shader(raw_shader),
641         }
642     }
643 
get_shader_compile_status(&self, shader: Self::Shader) -> bool644     unsafe fn get_shader_compile_status(&self, shader: Self::Shader) -> bool {
645         let shaders = self.shaders.borrow();
646         let raw_shader = shaders.get_unchecked(shader);
647         match self.raw {
648             RawRenderingContext::WebGl1(ref gl) => {
649                 gl.get_shader_parameter(raw_shader, COMPILE_STATUS)
650             }
651             RawRenderingContext::WebGl2(ref gl) => {
652                 gl.get_shader_parameter(raw_shader, COMPILE_STATUS)
653             }
654         }
655         .as_bool()
656         .unwrap_or(false)
657     }
658 
get_shader_info_log(&self, shader: Self::Shader) -> String659     unsafe fn get_shader_info_log(&self, shader: Self::Shader) -> String {
660         let shaders = self.shaders.borrow();
661         let raw_shader = shaders.get_unchecked(shader);
662         match self.raw {
663             RawRenderingContext::WebGl1(ref gl) => gl.get_shader_info_log(raw_shader),
664             RawRenderingContext::WebGl2(ref gl) => gl.get_shader_info_log(raw_shader),
665         }
666         .unwrap_or_else(|| String::from(""))
667     }
668 
get_tex_image( &self, _target: u32, _level: i32, _format: u32, _ty: u32, _pixels: PixelPackData, )669     unsafe fn get_tex_image(
670         &self,
671         _target: u32,
672         _level: i32,
673         _format: u32,
674         _ty: u32,
675         _pixels: PixelPackData,
676     ) {
677         panic!("Get tex image is not supported");
678     }
679 
create_program(&self) -> Result<Self::Program, String>680     unsafe fn create_program(&self) -> Result<Self::Program, String> {
681         let raw_program = match self.raw {
682             RawRenderingContext::WebGl1(ref gl) => gl.create_program(),
683             RawRenderingContext::WebGl2(ref gl) => gl.create_program(),
684         };
685 
686         match raw_program {
687             Some(p) => {
688                 let key = self.programs.borrow_mut().insert(p);
689                 Ok(key)
690             }
691             None => Err(String::from("Unable to create program object")),
692         }
693     }
694 
is_program(&self, program: Self::Program) -> bool695     unsafe fn is_program(&self, program: Self::Program) -> bool {
696         let programs = self.programs.borrow_mut();
697         if let Some(ref p) = programs.get(program) {
698             match self.raw {
699                 RawRenderingContext::WebGl1(ref gl) => gl.is_program(Some(p)),
700                 RawRenderingContext::WebGl2(ref gl) => gl.is_program(Some(p)),
701             }
702         } else {
703             false
704         }
705     }
706 
delete_program(&self, program: Self::Program)707     unsafe fn delete_program(&self, program: Self::Program) {
708         let mut programs = self.programs.borrow_mut();
709         if let Some(ref p) = programs.remove(program) {
710             match self.raw {
711                 RawRenderingContext::WebGl1(ref gl) => gl.delete_program(Some(p)),
712                 RawRenderingContext::WebGl2(ref gl) => gl.delete_program(Some(p)),
713             }
714         }
715     }
716 
attach_shader(&self, program: Self::Program, shader: Self::Shader)717     unsafe fn attach_shader(&self, program: Self::Program, shader: Self::Shader) {
718         let programs = self.programs.borrow();
719         let shaders = self.shaders.borrow();
720         let raw_program = programs.get_unchecked(program);
721         let raw_shader = shaders.get_unchecked(shader);
722         match self.raw {
723             RawRenderingContext::WebGl1(ref gl) => gl.attach_shader(raw_program, raw_shader),
724             RawRenderingContext::WebGl2(ref gl) => gl.attach_shader(raw_program, raw_shader),
725         }
726     }
727 
detach_shader(&self, program: Self::Program, shader: Self::Shader)728     unsafe fn detach_shader(&self, program: Self::Program, shader: Self::Shader) {
729         let programs = self.programs.borrow();
730         let shaders = self.shaders.borrow();
731         let raw_program = programs.get_unchecked(program);
732         let raw_shader = shaders.get_unchecked(shader);
733         match self.raw {
734             RawRenderingContext::WebGl1(ref gl) => gl.detach_shader(raw_program, raw_shader),
735             RawRenderingContext::WebGl2(ref gl) => gl.detach_shader(raw_program, raw_shader),
736         }
737     }
738 
link_program(&self, program: Self::Program)739     unsafe fn link_program(&self, program: Self::Program) {
740         let programs = self.programs.borrow();
741         let raw_program = programs.get_unchecked(program);
742         match self.raw {
743             RawRenderingContext::WebGl1(ref gl) => gl.link_program(raw_program),
744             RawRenderingContext::WebGl2(ref gl) => gl.link_program(raw_program),
745         }
746     }
747 
get_program_link_status(&self, program: Self::Program) -> bool748     unsafe fn get_program_link_status(&self, program: Self::Program) -> bool {
749         let programs = self.programs.borrow();
750         let raw_program = programs.get_unchecked(program);
751         match self.raw {
752             RawRenderingContext::WebGl1(ref gl) => {
753                 gl.get_program_parameter(raw_program, LINK_STATUS)
754             }
755             RawRenderingContext::WebGl2(ref gl) => {
756                 gl.get_program_parameter(raw_program, LINK_STATUS)
757             }
758         }
759         .as_bool()
760         .unwrap_or(false)
761     }
762 
get_program_info_log(&self, program: Self::Program) -> String763     unsafe fn get_program_info_log(&self, program: Self::Program) -> String {
764         let programs = self.programs.borrow();
765         let raw_program = programs.get_unchecked(program);
766         match self.raw {
767             RawRenderingContext::WebGl1(ref gl) => gl.get_program_info_log(raw_program),
768             RawRenderingContext::WebGl2(ref gl) => gl.get_program_info_log(raw_program),
769         }
770         .unwrap_or_else(|| String::from(""))
771     }
772 
get_active_uniforms(&self, program: Self::Program) -> u32773     unsafe fn get_active_uniforms(&self, program: Self::Program) -> u32 {
774         let programs = self.programs.borrow();
775         let raw_program = programs.get_unchecked(program);
776         match self.raw {
777             RawRenderingContext::WebGl1(ref gl) => {
778                 gl.get_program_parameter(raw_program, WebGlRenderingContext::ACTIVE_UNIFORMS)
779             }
780             RawRenderingContext::WebGl2(ref gl) => {
781                 gl.get_program_parameter(raw_program, WebGl2RenderingContext::ACTIVE_UNIFORMS)
782             }
783         }
784         .as_f64()
785         .map(|v| v as u32)
786         .unwrap_or(0)
787     }
788 
get_active_uniform( &self, program: Self::Program, index: u32, ) -> Option<ActiveUniform>789     unsafe fn get_active_uniform(
790         &self,
791         program: Self::Program,
792         index: u32,
793     ) -> Option<ActiveUniform> {
794         let programs = self.programs.borrow();
795         let raw_program = programs.get_unchecked(program);
796         match self.raw {
797             RawRenderingContext::WebGl1(ref gl) => {
798                 gl.get_active_uniform(raw_program, index)
799                     .map(|au| ActiveUniform {
800                         size: au.size(),
801                         utype: au.type_(),
802                         name: au.name(),
803                     })
804             }
805             RawRenderingContext::WebGl2(ref gl) => {
806                 gl.get_active_uniform(raw_program, index)
807                     .map(|au| ActiveUniform {
808                         size: au.size(),
809                         utype: au.type_(),
810                         name: au.name(),
811                     })
812             }
813         }
814     }
815 
use_program(&self, program: Option<Self::Program>)816     unsafe fn use_program(&self, program: Option<Self::Program>) {
817         let programs = self.programs.borrow();
818         let raw_program = program.map(|p| programs.get_unchecked(p));
819         match self.raw {
820             RawRenderingContext::WebGl1(ref gl) => gl.use_program(raw_program),
821             RawRenderingContext::WebGl2(ref gl) => gl.use_program(raw_program),
822         }
823     }
824 
create_buffer(&self) -> Result<Self::Buffer, String>825     unsafe fn create_buffer(&self) -> Result<Self::Buffer, String> {
826         let raw_buffer = match self.raw {
827             RawRenderingContext::WebGl1(ref gl) => gl.create_buffer(),
828             RawRenderingContext::WebGl2(ref gl) => gl.create_buffer(),
829         };
830 
831         match raw_buffer {
832             Some(p) => {
833                 let key = self.buffers.borrow_mut().insert(p);
834                 Ok(key)
835             }
836             None => Err(String::from("Unable to create buffer object")),
837         }
838     }
839 
is_buffer(&self, buffer: Self::Buffer) -> bool840     unsafe fn is_buffer(&self, buffer: Self::Buffer) -> bool {
841         let buffers = self.buffers.borrow_mut();
842         if let Some(ref b) = buffers.get(buffer) {
843             match self.raw {
844                 RawRenderingContext::WebGl1(ref gl) => gl.is_buffer(Some(b)),
845                 RawRenderingContext::WebGl2(ref gl) => gl.is_buffer(Some(b)),
846             }
847         } else {
848             false
849         }
850     }
851 
bind_buffer(&self, target: u32, buffer: Option<Self::Buffer>)852     unsafe fn bind_buffer(&self, target: u32, buffer: Option<Self::Buffer>) {
853         let buffers = self.buffers.borrow();
854         let raw_buffer = buffer.map(|b| buffers.get_unchecked(b));
855         match self.raw {
856             RawRenderingContext::WebGl1(ref gl) => gl.bind_buffer(target, raw_buffer),
857             RawRenderingContext::WebGl2(ref gl) => gl.bind_buffer(target, raw_buffer),
858         }
859     }
860 
bind_buffer_base(&self, target: u32, index: u32, buffer: Option<Self::Buffer>)861     unsafe fn bind_buffer_base(&self, target: u32, index: u32, buffer: Option<Self::Buffer>) {
862         let buffers = self.buffers.borrow();
863         let raw_buffer = buffer.map(|b| buffers.get_unchecked(b));
864         match self.raw {
865             RawRenderingContext::WebGl1(ref _gl) => {
866                 panic!("bind_buffer_base not supported on webgl1")
867             }
868             RawRenderingContext::WebGl2(ref gl) => gl.bind_buffer_base(target, index, raw_buffer),
869         }
870     }
871 
bind_buffer_range( &self, target: u32, index: u32, buffer: Option<Self::Buffer>, offset: i32, size: i32, )872     unsafe fn bind_buffer_range(
873         &self,
874         target: u32,
875         index: u32,
876         buffer: Option<Self::Buffer>,
877         offset: i32,
878         size: i32,
879     ) {
880         let buffers = self.buffers.borrow();
881         let raw_buffer = buffer.map(|b| buffers.get_unchecked(b));
882         match self.raw {
883             RawRenderingContext::WebGl1(ref _gl) => {
884                 panic!("bind_buffer_range not supported on webgl1");
885             }
886             RawRenderingContext::WebGl2(ref gl) => {
887                 gl.bind_buffer_range_with_i32_and_i32(target, index, raw_buffer, offset, size);
888             }
889         }
890     }
891 
bind_vertex_buffer( &self, _binding_index: u32, _buffer: Option<Buffer>, _offset: i32, _stride: i32, )892     unsafe fn bind_vertex_buffer(
893         &self,
894         _binding_index: u32,
895         _buffer: Option<Buffer>,
896         _offset: i32,
897         _stride: i32,
898     ) {
899         panic!("Bind vertex buffer is not supported")
900     }
901 
bind_framebuffer(&self, target: u32, framebuffer: Option<Self::Framebuffer>)902     unsafe fn bind_framebuffer(&self, target: u32, framebuffer: Option<Self::Framebuffer>) {
903         let framebuffers = self.framebuffers.borrow();
904         let raw_framebuffer = framebuffer.map(|f| framebuffers.get_unchecked(f));
905         match self.raw {
906             RawRenderingContext::WebGl1(ref gl) => gl.bind_framebuffer(target, raw_framebuffer),
907             RawRenderingContext::WebGl2(ref gl) => gl.bind_framebuffer(target, raw_framebuffer),
908         }
909     }
910 
bind_renderbuffer(&self, target: u32, renderbuffer: Option<Self::Renderbuffer>)911     unsafe fn bind_renderbuffer(&self, target: u32, renderbuffer: Option<Self::Renderbuffer>) {
912         let renderbuffers = self.renderbuffers.borrow();
913         let raw_renderbuffer = renderbuffer.map(|r| renderbuffers.get_unchecked(r));
914         match self.raw {
915             RawRenderingContext::WebGl1(ref gl) => gl.bind_renderbuffer(target, raw_renderbuffer),
916             RawRenderingContext::WebGl2(ref gl) => gl.bind_renderbuffer(target, raw_renderbuffer),
917         }
918     }
919 
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, )920     unsafe fn blit_framebuffer(
921         &self,
922         src_x0: i32,
923         src_y0: i32,
924         src_x1: i32,
925         src_y1: i32,
926         dst_x0: i32,
927         dst_y0: i32,
928         dst_x1: i32,
929         dst_y1: i32,
930         mask: u32,
931         filter: u32,
932     ) {
933         match self.raw {
934             RawRenderingContext::WebGl1(ref _gl) => {
935                 panic!("framebuffer blitting usupported in webgl1")
936             }
937             RawRenderingContext::WebGl2(ref gl) => {
938                 gl.blit_framebuffer(
939                     src_x0, src_y0, src_x1, src_y1, dst_x0, dst_y0, dst_x1, dst_y1, mask, filter,
940                 );
941             }
942         }
943     }
944 
create_vertex_array(&self) -> Result<Self::VertexArray, String>945     unsafe fn create_vertex_array(&self) -> Result<Self::VertexArray, String> {
946         let raw_vertex_array = match self.raw {
947             RawRenderingContext::WebGl1(ref _gl) => {
948                 match &self.extensions.oes_vertex_array_object {
949                     Some(extension) => extension.create_vertex_array_oes(),
950                     None => panic!("Vertex array objects are not supported"),
951                 }
952             }
953             RawRenderingContext::WebGl2(ref gl) => gl.create_vertex_array(),
954         };
955 
956         match raw_vertex_array {
957             Some(va) => {
958                 let key = self.vertex_arrays.borrow_mut().insert(va);
959                 Ok(key)
960             }
961             None => Err(String::from("Unable to create vertex array object")),
962         }
963     }
964 
delete_vertex_array(&self, vertex_array: Self::VertexArray)965     unsafe fn delete_vertex_array(&self, vertex_array: Self::VertexArray) {
966         let mut vertex_arrays = self.vertex_arrays.borrow_mut();
967         if let Some(ref va) = vertex_arrays.remove(vertex_array) {
968             match self.raw {
969                 RawRenderingContext::WebGl1(ref _gl) => {
970                     match &self.extensions.oes_vertex_array_object {
971                         Some(extension) => extension.delete_vertex_array_oes(Some(va)),
972                         None => panic!("Vertex array objects are not supported"),
973                     }
974                 }
975                 RawRenderingContext::WebGl2(ref gl) => gl.delete_vertex_array(Some(va)),
976             }
977         }
978     }
979 
bind_vertex_array(&self, vertex_array: Option<Self::VertexArray>)980     unsafe fn bind_vertex_array(&self, vertex_array: Option<Self::VertexArray>) {
981         let vertex_arrays = self.vertex_arrays.borrow();
982         let raw_vertex_array = vertex_array.map(|va| vertex_arrays.get_unchecked(va));
983         match self.raw {
984             RawRenderingContext::WebGl1(ref _gl) => {
985                 match &self.extensions.oes_vertex_array_object {
986                     Some(extension) => extension.bind_vertex_array_oes(raw_vertex_array),
987                     None => panic!("Vertex array objects are not supported"),
988                 }
989             }
990             RawRenderingContext::WebGl2(ref gl) => gl.bind_vertex_array(raw_vertex_array),
991         }
992     }
993 
clear_color(&self, red: f32, green: f32, blue: f32, alpha: f32)994     unsafe fn clear_color(&self, red: f32, green: f32, blue: f32, alpha: f32) {
995         match self.raw {
996             RawRenderingContext::WebGl1(ref gl) => gl.clear_color(red, green, blue, alpha),
997             RawRenderingContext::WebGl2(ref gl) => gl.clear_color(red, green, blue, alpha),
998         }
999     }
1000 
supports_f64_precision() -> bool1001     unsafe fn supports_f64_precision() -> bool {
1002         false
1003     }
1004 
clear_depth_f64(&self, _depth: f64)1005     unsafe fn clear_depth_f64(&self, _depth: f64) {
1006         panic!("64-bit float precision is not supported in WebGL");
1007     }
1008 
clear_depth_f32(&self, depth: f32)1009     unsafe fn clear_depth_f32(&self, depth: f32) {
1010         match self.raw {
1011             RawRenderingContext::WebGl1(ref gl) => gl.clear_depth(depth),
1012             RawRenderingContext::WebGl2(ref gl) => gl.clear_depth(depth),
1013         }
1014     }
1015 
clear_stencil(&self, stencil: i32)1016     unsafe fn clear_stencil(&self, stencil: i32) {
1017         match self.raw {
1018             RawRenderingContext::WebGl1(ref gl) => gl.clear_stencil(stencil),
1019             RawRenderingContext::WebGl2(ref gl) => gl.clear_stencil(stencil),
1020         }
1021     }
1022 
clear(&self, mask: u32)1023     unsafe fn clear(&self, mask: u32) {
1024         match self.raw {
1025             RawRenderingContext::WebGl1(ref gl) => gl.clear(mask),
1026             RawRenderingContext::WebGl2(ref gl) => gl.clear(mask),
1027         }
1028     }
1029 
patch_parameter_i32(&self, _parameter: u32, _value: i32)1030     unsafe fn patch_parameter_i32(&self, _parameter: u32, _value: i32) {
1031         panic!("Patch parameter is not supported");
1032     }
1033 
pixel_store_i32(&self, parameter: u32, value: i32)1034     unsafe fn pixel_store_i32(&self, parameter: u32, value: i32) {
1035         match self.raw {
1036             RawRenderingContext::WebGl1(ref gl) => gl.pixel_storei(parameter, value),
1037             RawRenderingContext::WebGl2(ref gl) => gl.pixel_storei(parameter, value),
1038         }
1039     }
1040 
pixel_store_bool(&self, parameter: u32, value: bool)1041     unsafe fn pixel_store_bool(&self, parameter: u32, value: bool) {
1042         match self.raw {
1043             RawRenderingContext::WebGl1(ref gl) => gl.pixel_storei(parameter, value as i32),
1044             RawRenderingContext::WebGl2(ref gl) => gl.pixel_storei(parameter, value as i32),
1045         }
1046     }
1047 
bind_frag_data_location( &self, _program: Self::Program, _color_number: u32, _name: &str, )1048     unsafe fn bind_frag_data_location(
1049         &self,
1050         _program: Self::Program,
1051         _color_number: u32,
1052         _name: &str,
1053     ) {
1054         panic!("Bind frag data location is not supported");
1055     }
1056 
buffer_data_size(&self, target: u32, size: i32, usage: u32)1057     unsafe fn buffer_data_size(&self, target: u32, size: i32, usage: u32) {
1058         match self.raw {
1059             RawRenderingContext::WebGl1(ref gl) => gl.buffer_data_with_i32(target, size, usage),
1060             RawRenderingContext::WebGl2(ref gl) => gl.buffer_data_with_i32(target, size, usage),
1061         }
1062     }
1063 
buffer_data_u8_slice(&self, target: u32, data: &[u8], usage: u32)1064     unsafe fn buffer_data_u8_slice(&self, target: u32, data: &[u8], usage: u32) {
1065         match self.raw {
1066             RawRenderingContext::WebGl1(ref gl) => {
1067                 let array = js_sys::Uint8Array::view(data);
1068                 gl.buffer_data_with_array_buffer_view(target, &array, usage);
1069             }
1070             RawRenderingContext::WebGl2(ref gl) => {
1071                 let array = js_sys::Uint8Array::view(data);
1072                 gl.buffer_data_with_array_buffer_view(target, &array, usage);
1073             }
1074         }
1075     }
1076 
buffer_sub_data_u8_slice(&self, target: u32, offset: i32, src_data: &[u8])1077     unsafe fn buffer_sub_data_u8_slice(&self, target: u32, offset: i32, src_data: &[u8]) {
1078         match self.raw {
1079             RawRenderingContext::WebGl1(ref gl) => {
1080                 let array = js_sys::Uint8Array::view(src_data);
1081                 gl.buffer_sub_data_with_i32_and_array_buffer_view(target, offset, &array);
1082             }
1083             RawRenderingContext::WebGl2(ref gl) => {
1084                 let array = js_sys::Uint8Array::view(src_data);
1085                 gl.buffer_sub_data_with_i32_and_array_buffer_view(target, offset, &array);
1086             }
1087         }
1088     }
1089 
get_buffer_sub_data(&self, target: u32, offset: i32, dst_data: &mut [u8])1090     unsafe fn get_buffer_sub_data(&self, target: u32, offset: i32, dst_data: &mut [u8]) {
1091         match self.raw {
1092             RawRenderingContext::WebGl1(ref _gl) => panic!("get_buffer_sub_data not supported"),
1093             RawRenderingContext::WebGl2(ref gl) => {
1094                 let array = js_sys::Uint8Array::view(dst_data);
1095                 gl.get_buffer_sub_data_with_i32_and_array_buffer_view(target, offset, &array);
1096             }
1097         }
1098     }
1099 
buffer_storage(&self, _target: u32, _size: i32, _data: Option<&[u8]>, _flags: u32)1100     unsafe fn buffer_storage(&self, _target: u32, _size: i32, _data: Option<&[u8]>, _flags: u32) {
1101         panic!("Buffer storage is not supported");
1102     }
1103 
check_framebuffer_status(&self, target: u32) -> u321104     unsafe fn check_framebuffer_status(&self, target: u32) -> u32 {
1105         match self.raw {
1106             RawRenderingContext::WebGl1(ref gl) => gl.check_framebuffer_status(target),
1107             RawRenderingContext::WebGl2(ref gl) => gl.check_framebuffer_status(target),
1108         }
1109     }
1110 
clear_buffer_i32_slice(&self, target: u32, draw_buffer: u32, values: &[i32])1111     unsafe fn clear_buffer_i32_slice(&self, target: u32, draw_buffer: u32, values: &[i32]) {
1112         match self.raw {
1113             RawRenderingContext::WebGl1(ref _gl) => {
1114                 panic!("Clear buffer with `i32` slice is not supported");
1115             }
1116             RawRenderingContext::WebGl2(ref gl) => {
1117                 gl.clear_bufferiv_with_i32_array(target, draw_buffer as i32, values);
1118             }
1119         }
1120     }
1121 
clear_buffer_u32_slice(&self, target: u32, draw_buffer: u32, values: &[u32])1122     unsafe fn clear_buffer_u32_slice(&self, target: u32, draw_buffer: u32, values: &[u32]) {
1123         match self.raw {
1124             RawRenderingContext::WebGl1(ref _gl) => {
1125                 panic!("Clear buffer with `u32` slice is not supported")
1126             }
1127             RawRenderingContext::WebGl2(ref gl) => {
1128                 gl.clear_bufferuiv_with_u32_array(target, draw_buffer as i32, values)
1129             }
1130         }
1131     }
1132 
clear_buffer_f32_slice(&self, target: u32, draw_buffer: u32, values: &[f32])1133     unsafe fn clear_buffer_f32_slice(&self, target: u32, draw_buffer: u32, values: &[f32]) {
1134         match self.raw {
1135             RawRenderingContext::WebGl1(ref _gl) => {
1136                 panic!("Clear buffer with `f32` slice is not supported")
1137             }
1138             RawRenderingContext::WebGl2(ref gl) => {
1139                 gl.clear_bufferfv_with_f32_array(target, draw_buffer as i32, values)
1140             }
1141         }
1142     }
1143 
clear_buffer_depth_stencil( &self, target: u32, draw_buffer: u32, depth: f32, stencil: i32, )1144     unsafe fn clear_buffer_depth_stencil(
1145         &self,
1146         target: u32,
1147         draw_buffer: u32,
1148         depth: f32,
1149         stencil: i32,
1150     ) {
1151         match self.raw {
1152             RawRenderingContext::WebGl1(ref _gl) => {
1153                 panic!("Clear buffer depth stencil is not supported")
1154             }
1155             RawRenderingContext::WebGl2(ref gl) => {
1156                 gl.clear_bufferfi(target, draw_buffer as i32, depth, stencil)
1157             }
1158         }
1159     }
1160 
client_wait_sync(&self, fence: Self::Fence, flags: u32, timeout: i32) -> u321161     unsafe fn client_wait_sync(&self, fence: Self::Fence, flags: u32, timeout: i32) -> u32 {
1162         let fences = self.fences.borrow();
1163         let raw_fence = fences.get_unchecked(fence);
1164         match self.raw {
1165             RawRenderingContext::WebGl1(ref _gl) => panic!("Client wait sync is not supported"),
1166             RawRenderingContext::WebGl2(ref gl) => {
1167                 gl.client_wait_sync_with_u32(raw_fence, flags, timeout as u32)
1168             }
1169         }
1170     }
1171 
wait_sync(&self, fence: Self::Fence, flags: u32, timeout: u64)1172     unsafe fn wait_sync(&self, fence: Self::Fence, flags: u32, timeout: u64) {
1173         let fences = self.fences.borrow();
1174         let raw_fence = fences.get_unchecked(fence);
1175         match self.raw {
1176             RawRenderingContext::WebGl1(ref _gl) => panic!("Wait sync is not supported"),
1177             RawRenderingContext::WebGl2(ref gl) => {
1178                 gl.wait_sync_with_i32(raw_fence, flags, timeout as i32)
1179             }
1180         }
1181     }
1182 
copy_buffer_sub_data( &self, src_target: u32, dst_target: u32, src_offset: i32, dst_offset: i32, size: i32, )1183     unsafe fn copy_buffer_sub_data(
1184         &self,
1185         src_target: u32,
1186         dst_target: u32,
1187         src_offset: i32,
1188         dst_offset: i32,
1189         size: i32,
1190     ) {
1191         match self.raw {
1192             RawRenderingContext::WebGl1(ref _gl) => panic!("Copy buffer subdata is not supported"),
1193             RawRenderingContext::WebGl2(ref gl) => gl
1194                 .copy_buffer_sub_data_with_i32_and_i32_and_i32(
1195                     src_target, dst_target, src_offset, dst_offset, size,
1196                 ),
1197         }
1198     }
1199 
copy_tex_image_2d( &self, target: u32, level: i32, internal_format: u32, x: i32, y: i32, width: i32, height: i32, border: i32, )1200     unsafe fn copy_tex_image_2d(
1201         &self,
1202         target: u32,
1203         level: i32,
1204         internal_format: u32,
1205         x: i32,
1206         y: i32,
1207         width: i32,
1208         height: i32,
1209         border: i32,
1210     ) {
1211         match self.raw {
1212             RawRenderingContext::WebGl1(ref gl) => {
1213                 gl.copy_tex_image_2d(target, level, internal_format, x, y, width, height, border);
1214             }
1215             RawRenderingContext::WebGl2(ref gl) => {
1216                 gl.copy_tex_image_2d(target, level, internal_format, x, y, width, height, border);
1217             }
1218         }
1219     }
1220 
copy_tex_sub_image_2d( &self, target: u32, level: i32, x_offset: i32, y_offset: i32, x: i32, y: i32, width: i32, height: i32, )1221     unsafe fn copy_tex_sub_image_2d(
1222         &self,
1223         target: u32,
1224         level: i32,
1225         x_offset: i32,
1226         y_offset: i32,
1227         x: i32,
1228         y: i32,
1229         width: i32,
1230         height: i32,
1231     ) {
1232         match self.raw {
1233             RawRenderingContext::WebGl1(ref gl) => {
1234                 gl.copy_tex_sub_image_2d(target, level, x_offset, y_offset, x, y, width, height);
1235             }
1236             RawRenderingContext::WebGl2(ref gl) => {
1237                 gl.copy_tex_sub_image_2d(target, level, x_offset, y_offset, x, y, width, height);
1238             }
1239         }
1240     }
1241 
copy_tex_sub_image_3d( &self, target: u32, level: i32, x_offset: i32, y_offset: i32, z_offset: i32, x: i32, y: i32, width: i32, height: i32, )1242     unsafe fn copy_tex_sub_image_3d(
1243         &self,
1244         target: u32,
1245         level: i32,
1246         x_offset: i32,
1247         y_offset: i32,
1248         z_offset: i32,
1249         x: i32,
1250         y: i32,
1251         width: i32,
1252         height: i32,
1253     ) {
1254         match self.raw {
1255             RawRenderingContext::WebGl1(ref _gl) => {
1256                 panic!("Copy tex subimage 3D is not supported");
1257             }
1258             RawRenderingContext::WebGl2(ref gl) => {
1259                 gl.copy_tex_sub_image_3d(
1260                     target, level, x_offset, y_offset, z_offset, x, y, width, height,
1261                 );
1262             }
1263         }
1264     }
1265 
delete_buffer(&self, buffer: Self::Buffer)1266     unsafe fn delete_buffer(&self, buffer: Self::Buffer) {
1267         let mut buffers = self.buffers.borrow_mut();
1268         if let Some(ref b) = buffers.remove(buffer) {
1269             match self.raw {
1270                 RawRenderingContext::WebGl1(ref gl) => gl.delete_buffer(Some(b)),
1271                 RawRenderingContext::WebGl2(ref gl) => gl.delete_buffer(Some(b)),
1272             }
1273         }
1274     }
1275 
delete_framebuffer(&self, framebuffer: Self::Framebuffer)1276     unsafe fn delete_framebuffer(&self, framebuffer: Self::Framebuffer) {
1277         let mut framebuffers = self.framebuffers.borrow_mut();
1278         if let Some(ref f) = framebuffers.remove(framebuffer) {
1279             match self.raw {
1280                 RawRenderingContext::WebGl1(ref gl) => gl.delete_framebuffer(Some(f)),
1281                 RawRenderingContext::WebGl2(ref gl) => gl.delete_framebuffer(Some(f)),
1282             }
1283         }
1284     }
1285 
delete_query(&self, query: Self::Query)1286     unsafe fn delete_query(&self, query: Self::Query) {
1287         let mut queries = self.queries.borrow_mut();
1288         if let Some(ref r) = queries.remove(query) {
1289             match self.raw {
1290                 RawRenderingContext::WebGl1(ref _gl) => panic!("Query objects are not supported"),
1291                 RawRenderingContext::WebGl2(ref gl) => gl.delete_query(Some(r)),
1292             }
1293         }
1294     }
1295 
delete_renderbuffer(&self, renderbuffer: Self::Renderbuffer)1296     unsafe fn delete_renderbuffer(&self, renderbuffer: Self::Renderbuffer) {
1297         let mut renderbuffers = self.renderbuffers.borrow_mut();
1298         if let Some(ref r) = renderbuffers.remove(renderbuffer) {
1299             match self.raw {
1300                 RawRenderingContext::WebGl1(ref gl) => gl.delete_renderbuffer(Some(r)),
1301                 RawRenderingContext::WebGl2(ref gl) => gl.delete_renderbuffer(Some(r)),
1302             }
1303         }
1304     }
1305 
delete_sampler(&self, sampler: Self::Sampler)1306     unsafe fn delete_sampler(&self, sampler: Self::Sampler) {
1307         let mut samplers = self.samplers.borrow_mut();
1308         if let Some(ref s) = samplers.remove(sampler) {
1309             match self.raw {
1310                 RawRenderingContext::WebGl1(ref _gl) => panic!("Samplers are not supported"),
1311                 RawRenderingContext::WebGl2(ref gl) => gl.delete_sampler(Some(s)),
1312             }
1313         }
1314     }
1315 
delete_sync(&self, fence: Self::Fence)1316     unsafe fn delete_sync(&self, fence: Self::Fence) {
1317         let mut fences = self.fences.borrow_mut();
1318         if let Some(ref f) = fences.remove(fence) {
1319             match self.raw {
1320                 RawRenderingContext::WebGl1(ref _gl) => panic!("Fences are not supported"),
1321                 RawRenderingContext::WebGl2(ref gl) => gl.delete_sync(Some(f)),
1322             }
1323         }
1324     }
1325 
delete_texture(&self, texture: Self::Texture)1326     unsafe fn delete_texture(&self, texture: Self::Texture) {
1327         let mut textures = self.textures.borrow_mut();
1328         if let Some(ref t) = textures.remove(texture) {
1329             match self.raw {
1330                 RawRenderingContext::WebGl1(ref gl) => gl.delete_texture(Some(t)),
1331                 RawRenderingContext::WebGl2(ref gl) => gl.delete_texture(Some(t)),
1332             }
1333         }
1334     }
1335 
disable(&self, parameter: u32)1336     unsafe fn disable(&self, parameter: u32) {
1337         match self.raw {
1338             RawRenderingContext::WebGl1(ref gl) => gl.disable(parameter),
1339             RawRenderingContext::WebGl2(ref gl) => gl.disable(parameter),
1340         }
1341     }
1342 
disable_draw_buffer(&self, _parameter: u32, _draw_buffer: u32)1343     unsafe fn disable_draw_buffer(&self, _parameter: u32, _draw_buffer: u32) {
1344         panic!("Draw buffer disable is not supported");
1345     }
1346 
disable_vertex_attrib_array(&self, index: u32)1347     unsafe fn disable_vertex_attrib_array(&self, index: u32) {
1348         match self.raw {
1349             RawRenderingContext::WebGl1(ref gl) => gl.disable_vertex_attrib_array(index),
1350             RawRenderingContext::WebGl2(ref gl) => gl.disable_vertex_attrib_array(index),
1351         }
1352     }
1353 
dispatch_compute(&self, _groups_x: u32, _groups_y: u32, _groups_z: u32)1354     unsafe fn dispatch_compute(&self, _groups_x: u32, _groups_y: u32, _groups_z: u32) {
1355         panic!("Dispatch compute is not supported");
1356     }
1357 
dispatch_compute_indirect(&self, _offset: i32)1358     unsafe fn dispatch_compute_indirect(&self, _offset: i32) {
1359         panic!("Dispatch compute indirect is not supported");
1360     }
1361 
draw_arrays(&self, mode: u32, first: i32, count: i32)1362     unsafe fn draw_arrays(&self, mode: u32, first: i32, count: i32) {
1363         match self.raw {
1364             RawRenderingContext::WebGl1(ref gl) => gl.draw_arrays(mode as u32, first, count),
1365             RawRenderingContext::WebGl2(ref gl) => gl.draw_arrays(mode as u32, first, count),
1366         }
1367     }
1368 
draw_arrays_instanced(&self, mode: u32, first: i32, count: i32, instance_count: i32)1369     unsafe fn draw_arrays_instanced(&self, mode: u32, first: i32, count: i32, instance_count: i32) {
1370         match self.raw {
1371             RawRenderingContext::WebGl1(ref _gl) => match &self.extensions.angle_instanced_arrays {
1372                 Some(extension) => {
1373                     extension.draw_arrays_instanced_angle(mode as u32, first, count, instance_count)
1374                 }
1375                 None => panic!("Draw arrays instanced is not supported"),
1376             },
1377             RawRenderingContext::WebGl2(ref gl) => {
1378                 gl.draw_arrays_instanced(mode as u32, first, count, instance_count)
1379             }
1380         }
1381     }
1382 
draw_arrays_instanced_base_instance( &self, _mode: u32, _first: i32, _count: i32, _instance_count: i32, _base_instance: u32, )1383     unsafe fn draw_arrays_instanced_base_instance(
1384         &self,
1385         _mode: u32,
1386         _first: i32,
1387         _count: i32,
1388         _instance_count: i32,
1389         _base_instance: u32,
1390     ) {
1391         panic!("Draw arrays instanced base instance is not supported");
1392     }
1393 
draw_arrays_indirect_offset(&self, _mode: u32, _offset: i32)1394     unsafe fn draw_arrays_indirect_offset(&self, _mode: u32, _offset: i32) {
1395         panic!("Draw arrays indirect is not supported");
1396     }
1397 
draw_buffer(&self, draw_buffer: u32)1398     unsafe fn draw_buffer(&self, draw_buffer: u32) {
1399         match self.raw {
1400             RawRenderingContext::WebGl1(ref _gl) => {
1401                 if let Some(ext) = &self.extensions.webgl_draw_buffers {
1402                     ext.draw_buffers_webgl(&Array::of1(&draw_buffer.into()))
1403                 } else {
1404                     panic!("webgl1 WEBGL_draw_buffers extension not available");
1405                 }
1406             }
1407             RawRenderingContext::WebGl2(ref gl) => {
1408                 gl.draw_buffers(&Array::of1(&draw_buffer.into()));
1409             }
1410         }
1411     }
1412 
draw_buffers(&self, buffers: &[u32])1413     unsafe fn draw_buffers(&self, buffers: &[u32]) {
1414         match self.raw {
1415             RawRenderingContext::WebGl1(ref _gl) => {
1416                 if let Some(ext) = &self.extensions.webgl_draw_buffers {
1417                     let js_buffers = Array::new();
1418                     for &b in buffers {
1419                         js_buffers.push(&b.into());
1420                     }
1421                     ext.draw_buffers_webgl(&Array::of1(&js_buffers))
1422                 } else {
1423                     panic!("webgl1 WEBGL_draw_buffers extension not available");
1424                 }
1425             }
1426             RawRenderingContext::WebGl2(ref gl) => {
1427                 let js_buffers = Array::new();
1428                 for &b in buffers {
1429                     js_buffers.push(&b.into());
1430                 }
1431                 gl.draw_buffers(&js_buffers);
1432             }
1433         }
1434     }
1435 
draw_elements(&self, mode: u32, count: i32, element_type: u32, offset: i32)1436     unsafe fn draw_elements(&self, mode: u32, count: i32, element_type: u32, offset: i32) {
1437         match self.raw {
1438             RawRenderingContext::WebGl1(ref gl) => {
1439                 gl.draw_elements_with_i32(mode as u32, count, element_type as u32, offset);
1440             }
1441             RawRenderingContext::WebGl2(ref gl) => {
1442                 gl.draw_elements_with_i32(mode as u32, count, element_type as u32, offset);
1443             }
1444         }
1445     }
1446 
draw_elements_base_vertex( &self, _mode: u32, _count: i32, _element_type: u32, _offset: i32, _base_vertex: i32, )1447     unsafe fn draw_elements_base_vertex(
1448         &self,
1449         _mode: u32,
1450         _count: i32,
1451         _element_type: u32,
1452         _offset: i32,
1453         _base_vertex: i32,
1454     ) {
1455         panic!("Draw elements base vertex is not supported");
1456     }
1457 
draw_elements_instanced( &self, mode: u32, count: i32, element_type: u32, offset: i32, instance_count: i32, )1458     unsafe fn draw_elements_instanced(
1459         &self,
1460         mode: u32,
1461         count: i32,
1462         element_type: u32,
1463         offset: i32,
1464         instance_count: i32,
1465     ) {
1466         match self.raw {
1467             RawRenderingContext::WebGl1(ref _gl) => match &self.extensions.angle_instanced_arrays {
1468                 None => panic!("Draw elements instanced is not supported"),
1469                 Some(extension) => extension.draw_elements_instanced_angle_with_i32(
1470                     mode as u32,
1471                     count,
1472                     element_type as u32,
1473                     offset,
1474                     instance_count,
1475                 ),
1476             },
1477             RawRenderingContext::WebGl2(ref gl) => {
1478                 gl.draw_elements_instanced_with_i32(
1479                     mode as u32,
1480                     count,
1481                     element_type as u32,
1482                     offset,
1483                     instance_count,
1484                 );
1485             }
1486         }
1487     }
1488 
draw_elements_instanced_base_vertex( &self, _mode: u32, _count: i32, _element_type: u32, _offset: i32, _instance_count: i32, _base_vertex: i32, )1489     unsafe fn draw_elements_instanced_base_vertex(
1490         &self,
1491         _mode: u32,
1492         _count: i32,
1493         _element_type: u32,
1494         _offset: i32,
1495         _instance_count: i32,
1496         _base_vertex: i32,
1497     ) {
1498         panic!("Draw elements instanced base vertex is not supported");
1499     }
1500 
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, )1501     unsafe fn draw_elements_instanced_base_vertex_base_instance(
1502         &self,
1503         _mode: u32,
1504         _count: i32,
1505         _element_type: u32,
1506         _offset: i32,
1507         _instance_count: i32,
1508         _base_vertex: i32,
1509         _base_instance: u32,
1510     ) {
1511         panic!("Draw elements instanced base vertex base instance is not supported");
1512     }
1513 
draw_elements_indirect_offset(&self, _mode: u32, _element_type: u32, _offset: i32)1514     unsafe fn draw_elements_indirect_offset(&self, _mode: u32, _element_type: u32, _offset: i32) {
1515         panic!("Draw elements indirect is not supported");
1516     }
1517 
enable(&self, parameter: u32)1518     unsafe fn enable(&self, parameter: u32) {
1519         match self.raw {
1520             RawRenderingContext::WebGl1(ref gl) => gl.enable(parameter),
1521             RawRenderingContext::WebGl2(ref gl) => gl.enable(parameter),
1522         }
1523     }
1524 
is_enabled(&self, parameter: u32) -> bool1525     unsafe fn is_enabled(&self, parameter: u32) -> bool {
1526         match self.raw {
1527             RawRenderingContext::WebGl1(ref gl) => gl.is_enabled(parameter),
1528             RawRenderingContext::WebGl2(ref gl) => gl.is_enabled(parameter),
1529         }
1530     }
1531 
enable_draw_buffer(&self, _parameter: u32, _draw_buffer: u32)1532     unsafe fn enable_draw_buffer(&self, _parameter: u32, _draw_buffer: u32) {
1533         panic!("Draw buffer enable is not supported");
1534     }
1535 
enable_vertex_attrib_array(&self, index: u32)1536     unsafe fn enable_vertex_attrib_array(&self, index: u32) {
1537         match self.raw {
1538             RawRenderingContext::WebGl1(ref gl) => gl.enable_vertex_attrib_array(index),
1539             RawRenderingContext::WebGl2(ref gl) => gl.enable_vertex_attrib_array(index),
1540         }
1541     }
1542 
flush(&self)1543     unsafe fn flush(&self) {
1544         match self.raw {
1545             RawRenderingContext::WebGl1(ref gl) => gl.flush(),
1546             RawRenderingContext::WebGl2(ref gl) => gl.flush(),
1547         }
1548     }
1549 
framebuffer_renderbuffer( &self, target: u32, attachment: u32, renderbuffer_target: u32, renderbuffer: Option<Self::Renderbuffer>, )1550     unsafe fn framebuffer_renderbuffer(
1551         &self,
1552         target: u32,
1553         attachment: u32,
1554         renderbuffer_target: u32,
1555         renderbuffer: Option<Self::Renderbuffer>,
1556     ) {
1557         let renderbuffers = self.renderbuffers.borrow();
1558         let raw_renderbuffer = renderbuffer.map(|r| renderbuffers.get_unchecked(r));
1559         match self.raw {
1560             RawRenderingContext::WebGl1(ref gl) => gl.framebuffer_renderbuffer(
1561                 target,
1562                 attachment,
1563                 renderbuffer_target,
1564                 raw_renderbuffer,
1565             ),
1566             RawRenderingContext::WebGl2(ref gl) => gl.framebuffer_renderbuffer(
1567                 target,
1568                 attachment,
1569                 renderbuffer_target,
1570                 raw_renderbuffer,
1571             ),
1572         }
1573     }
1574 
framebuffer_texture( &self, _target: u32, _attachment: u32, _texture: Option<Self::Texture>, _level: i32, )1575     unsafe fn framebuffer_texture(
1576         &self,
1577         _target: u32,
1578         _attachment: u32,
1579         _texture: Option<Self::Texture>,
1580         _level: i32,
1581     ) {
1582         panic!("Framebuffer texture is not supported");
1583     }
1584 
framebuffer_texture_2d( &self, target: u32, attachment: u32, texture_target: u32, texture: Option<Self::Texture>, level: i32, )1585     unsafe fn framebuffer_texture_2d(
1586         &self,
1587         target: u32,
1588         attachment: u32,
1589         texture_target: u32,
1590         texture: Option<Self::Texture>,
1591         level: i32,
1592     ) {
1593         let textures = self.textures.borrow();
1594         let raw_texture = texture.map(|t| textures.get_unchecked(t));
1595         match self.raw {
1596             RawRenderingContext::WebGl1(ref gl) => {
1597                 gl.framebuffer_texture_2d(target, attachment, texture_target, raw_texture, level);
1598             }
1599             RawRenderingContext::WebGl2(ref gl) => {
1600                 gl.framebuffer_texture_2d(target, attachment, texture_target, raw_texture, level);
1601             }
1602         }
1603     }
1604 
framebuffer_texture_3d( &self, _target: u32, _attachment: u32, _texture_target: u32, _texture: Option<Self::Texture>, _level: i32, _layer: i32, )1605     unsafe fn framebuffer_texture_3d(
1606         &self,
1607         _target: u32,
1608         _attachment: u32,
1609         _texture_target: u32,
1610         _texture: Option<Self::Texture>,
1611         _level: i32,
1612         _layer: i32,
1613     ) {
1614         panic!("Framebuffer texture 3D is not supported");
1615     }
1616 
framebuffer_texture_layer( &self, target: u32, attachment: u32, texture: Option<Self::Texture>, level: i32, layer: i32, )1617     unsafe fn framebuffer_texture_layer(
1618         &self,
1619         target: u32,
1620         attachment: u32,
1621         texture: Option<Self::Texture>,
1622         level: i32,
1623         layer: i32,
1624     ) {
1625         let textures = self.textures.borrow();
1626         let raw_texture = texture.map(|t| textures.get_unchecked(t));
1627         match self.raw {
1628             RawRenderingContext::WebGl1(ref _gl) => {
1629                 panic!("Framebuffer texture layer is not supported");
1630             }
1631             RawRenderingContext::WebGl2(ref gl) => {
1632                 gl.framebuffer_texture_layer(target, attachment, raw_texture, level, layer);
1633             }
1634         }
1635     }
1636 
front_face(&self, value: u32)1637     unsafe fn front_face(&self, value: u32) {
1638         match self.raw {
1639             RawRenderingContext::WebGl1(ref gl) => gl.front_face(value as u32),
1640             RawRenderingContext::WebGl2(ref gl) => gl.front_face(value as u32),
1641         }
1642     }
1643 
get_error(&self) -> u321644     unsafe fn get_error(&self) -> u32 {
1645         match self.raw {
1646             RawRenderingContext::WebGl1(ref gl) => gl.get_error(),
1647             RawRenderingContext::WebGl2(ref gl) => gl.get_error(),
1648         }
1649     }
1650 
get_tex_parameter_i32(&self, target: u32, parameter: u32) -> i321651     unsafe fn get_tex_parameter_i32(&self, target: u32, parameter: u32) -> i32 {
1652         match self.raw {
1653             RawRenderingContext::WebGl1(ref gl) => gl.get_tex_parameter(target, parameter),
1654             RawRenderingContext::WebGl2(ref gl) => gl.get_tex_parameter(target, parameter),
1655         }
1656         .as_f64()
1657         .map(|v| v as i32)
1658         // Errors will be caught by the browser or through `get_error`
1659         // so return a default instead
1660         .unwrap_or(0)
1661     }
1662 
get_buffer_parameter_i32(&self, target: u32, parameter: u32) -> i321663     unsafe fn get_buffer_parameter_i32(&self, target: u32, parameter: u32) -> i32 {
1664         match self.raw {
1665             RawRenderingContext::WebGl1(ref gl) => gl.get_buffer_parameter(target, parameter),
1666             RawRenderingContext::WebGl2(ref gl) => gl.get_buffer_parameter(target, parameter),
1667         }
1668         .as_f64()
1669         .map(|v| v as i32)
1670         // Errors will be caught by the browser or through `get_error`
1671         // so return a default instead
1672         .unwrap_or(0)
1673     }
1674 
get_parameter_i32(&self, parameter: u32) -> i321675     unsafe fn get_parameter_i32(&self, parameter: u32) -> i32 {
1676         match self.raw {
1677             RawRenderingContext::WebGl1(ref gl) => gl.get_parameter(parameter),
1678             RawRenderingContext::WebGl2(ref gl) => gl.get_parameter(parameter),
1679         }
1680         .unwrap()
1681         .as_f64()
1682         .map(|v| v as i32)
1683         // Errors will be caught by the browser or through `get_error`
1684         // so return a default instead
1685         .unwrap_or(0)
1686     }
1687 
get_parameter_i32_slice(&self, parameter: u32, v: &mut [i32])1688     unsafe fn get_parameter_i32_slice(&self, parameter: u32, v: &mut [i32]) {
1689         let value = match self.raw {
1690             RawRenderingContext::WebGl1(ref gl) => gl.get_parameter(parameter),
1691             RawRenderingContext::WebGl2(ref gl) => gl.get_parameter(parameter),
1692         }
1693         .unwrap();
1694         use wasm_bindgen::JsCast;
1695         if let Some(value) = value.as_f64() {
1696             v[0] = value as i32;
1697         } else if let Some(values) = value.dyn_ref::<js_sys::Int32Array>() {
1698             values.copy_to(v)
1699         }
1700     }
1701 
get_parameter_f32(&self, parameter: u32) -> f321702     unsafe fn get_parameter_f32(&self, parameter: u32) -> f32 {
1703         match self.raw {
1704             RawRenderingContext::WebGl1(ref gl) => gl.get_parameter(parameter),
1705             RawRenderingContext::WebGl2(ref gl) => gl.get_parameter(parameter),
1706         }
1707         .unwrap()
1708         .as_f64()
1709         .map(|v| v as f32)
1710         // Errors will be caught by the browser or through `get_error`
1711         // so return a default instead
1712         .unwrap_or(0.0)
1713     }
1714 
get_parameter_f32_slice(&self, parameter: u32, v: &mut [f32])1715     unsafe fn get_parameter_f32_slice(&self, parameter: u32, v: &mut [f32]) {
1716         let value = match self.raw {
1717             RawRenderingContext::WebGl1(ref gl) => gl.get_parameter(parameter),
1718             RawRenderingContext::WebGl2(ref gl) => gl.get_parameter(parameter),
1719         }
1720         .unwrap();
1721         use wasm_bindgen::JsCast;
1722         if let Some(value) = value.as_f64() {
1723             v[0] = value as f32;
1724         } else if let Some(values) = value.dyn_ref::<js_sys::Float32Array>() {
1725             values.copy_to(v)
1726         }
1727     }
1728 
get_parameter_indexed_i32(&self, parameter: u32, index: u32) -> i321729     unsafe fn get_parameter_indexed_i32(&self, parameter: u32, index: u32) -> i32 {
1730         match self.raw {
1731             RawRenderingContext::WebGl1(ref _gl) => {
1732                 panic!("Get parameter indexed is not supported")
1733             }
1734             RawRenderingContext::WebGl2(ref gl) => gl.get_indexed_parameter(parameter, index),
1735         }
1736         .unwrap()
1737         .as_f64()
1738         .map(|v| v as i32)
1739         // Errors will be caught by the browser or through `get_error`
1740         // so return a default instead
1741         .unwrap_or(0)
1742     }
1743 
get_parameter_indexed_string(&self, parameter: u32, index: u32) -> String1744     unsafe fn get_parameter_indexed_string(&self, parameter: u32, index: u32) -> String {
1745         match self.raw {
1746             RawRenderingContext::WebGl1(ref _gl) => {
1747                 panic!("Get parameter indexed is not supported")
1748             }
1749             RawRenderingContext::WebGl2(ref gl) => gl.get_indexed_parameter(parameter, index),
1750         }
1751         .unwrap()
1752         .as_string()
1753         // Errors will be caught by the browser or through `get_error`
1754         // so return a default instead
1755         .unwrap_or_else(|| String::from(""))
1756     }
1757 
get_parameter_string(&self, parameter: u32) -> String1758     unsafe fn get_parameter_string(&self, parameter: u32) -> String {
1759         match self.raw {
1760             RawRenderingContext::WebGl1(ref gl) => gl.get_parameter(parameter),
1761             RawRenderingContext::WebGl2(ref gl) => gl.get_parameter(parameter),
1762         }
1763         .unwrap()
1764         .as_string()
1765         // Errors will be caught by the browser or through `get_error`
1766         // so return a default instead
1767         .unwrap_or_else(|| String::from(""))
1768     }
1769 
get_uniform_location( &self, program: Self::Program, name: &str, ) -> Option<Self::UniformLocation>1770     unsafe fn get_uniform_location(
1771         &self,
1772         program: Self::Program,
1773         name: &str,
1774     ) -> Option<Self::UniformLocation> {
1775         let programs = self.programs.borrow();
1776         let raw_program = programs.get_unchecked(program);
1777         match self.raw {
1778             RawRenderingContext::WebGl1(ref gl) => gl.get_uniform_location(raw_program, name),
1779             RawRenderingContext::WebGl2(ref gl) => gl.get_uniform_location(raw_program, name),
1780         }
1781     }
1782 
get_attrib_location(&self, program: Self::Program, name: &str) -> Option<u32>1783     unsafe fn get_attrib_location(&self, program: Self::Program, name: &str) -> Option<u32> {
1784         let programs = self.programs.borrow();
1785         let raw_program = programs.get_unchecked(program);
1786         let attrib_location = match self.raw {
1787             RawRenderingContext::WebGl1(ref gl) => gl.get_attrib_location(raw_program, name),
1788             RawRenderingContext::WebGl2(ref gl) => gl.get_attrib_location(raw_program, name),
1789         };
1790         if attrib_location < 0 {
1791             None
1792         } else {
1793             Some(attrib_location as u32)
1794         }
1795     }
1796 
bind_attrib_location(&self, program: Self::Program, index: u32, name: &str)1797     unsafe fn bind_attrib_location(&self, program: Self::Program, index: u32, name: &str) {
1798         let programs = self.programs.borrow();
1799         let raw_program = programs.get_unchecked(program);
1800         match self.raw {
1801             RawRenderingContext::WebGl1(ref gl) => {
1802                 gl.bind_attrib_location(raw_program, index, name)
1803             }
1804             RawRenderingContext::WebGl2(ref gl) => {
1805                 gl.bind_attrib_location(raw_program, index, name)
1806             }
1807         }
1808     }
1809 
get_active_attributes(&self, program: Self::Program) -> u321810     unsafe fn get_active_attributes(&self, program: Self::Program) -> u32 {
1811         let programs = self.programs.borrow();
1812         let raw_program = programs.get_unchecked(program);
1813         match self.raw {
1814             RawRenderingContext::WebGl1(ref gl) => {
1815                 gl.get_program_parameter(raw_program, WebGlRenderingContext::ACTIVE_ATTRIBUTES)
1816             }
1817             RawRenderingContext::WebGl2(ref gl) => {
1818                 gl.get_program_parameter(raw_program, WebGl2RenderingContext::ACTIVE_ATTRIBUTES)
1819             }
1820         }
1821         .as_f64()
1822         .map(|v| v as u32)
1823         .unwrap_or(0)
1824     }
1825 
get_active_attribute( &self, program: Self::Program, index: u32, ) -> Option<ActiveAttribute>1826     unsafe fn get_active_attribute(
1827         &self,
1828         program: Self::Program,
1829         index: u32,
1830     ) -> Option<ActiveAttribute> {
1831         let programs = self.programs.borrow();
1832         let raw_program = programs.get_unchecked(program);
1833         match self.raw {
1834             RawRenderingContext::WebGl1(ref gl) => {
1835                 gl.get_active_attrib(raw_program, index)
1836                     .map(|au| ActiveAttribute {
1837                         size: au.size(),
1838                         atype: au.type_(),
1839                         name: au.name(),
1840                     })
1841             }
1842             RawRenderingContext::WebGl2(ref gl) => {
1843                 gl.get_active_attrib(raw_program, index)
1844                     .map(|au| ActiveAttribute {
1845                         size: au.size(),
1846                         atype: au.type_(),
1847                         name: au.name(),
1848                     })
1849             }
1850         }
1851     }
1852 
get_sync_status(&self, fence: Self::Fence) -> u321853     unsafe fn get_sync_status(&self, fence: Self::Fence) -> u32 {
1854         let fences = self.fences.borrow();
1855         let raw_fence = fences.get_unchecked(fence);
1856         match self.raw {
1857             RawRenderingContext::WebGl1(ref _gl) => panic!("Sync is not supported"),
1858             RawRenderingContext::WebGl2(ref gl) => gl
1859                 .get_sync_parameter(raw_fence, SYNC_STATUS)
1860                 .as_f64()
1861                 .map(|v| v as u32)
1862                 .unwrap_or(UNSIGNALED),
1863         }
1864     }
1865 
is_sync(&self, fence: Self::Fence) -> bool1866     unsafe fn is_sync(&self, fence: Self::Fence) -> bool {
1867         let fences = self.fences.borrow();
1868         let raw_fence = fences.get_unchecked(fence);
1869         match self.raw {
1870             RawRenderingContext::WebGl1(ref _gl) => panic!("Sync is not supported"),
1871             RawRenderingContext::WebGl2(ref gl) => gl.is_sync(Some(raw_fence)),
1872         }
1873     }
1874 
renderbuffer_storage( &self, target: u32, internal_format: u32, width: i32, height: i32, )1875     unsafe fn renderbuffer_storage(
1876         &self,
1877         target: u32,
1878         internal_format: u32,
1879         width: i32,
1880         height: i32,
1881     ) {
1882         match self.raw {
1883             RawRenderingContext::WebGl1(ref gl) => {
1884                 gl.renderbuffer_storage(target, internal_format, width, height);
1885             }
1886             RawRenderingContext::WebGl2(ref gl) => {
1887                 gl.renderbuffer_storage(target, internal_format, width, height);
1888             }
1889         }
1890     }
1891 
renderbuffer_storage_multisample( &self, target: u32, samples: i32, internal_format: u32, width: i32, height: i32, )1892     unsafe fn renderbuffer_storage_multisample(
1893         &self,
1894         target: u32,
1895         samples: i32,
1896         internal_format: u32,
1897         width: i32,
1898         height: i32,
1899     ) {
1900         match self.raw {
1901             RawRenderingContext::WebGl1(ref _gl) => {
1902                 panic!("Renderbuffer storage multisample is not supported");
1903             }
1904             RawRenderingContext::WebGl2(ref gl) => {
1905                 gl.renderbuffer_storage_multisample(
1906                     target,
1907                     samples,
1908                     internal_format,
1909                     width,
1910                     height,
1911                 );
1912             }
1913         }
1914     }
1915 
sampler_parameter_f32(&self, sampler: Self::Sampler, name: u32, value: f32)1916     unsafe fn sampler_parameter_f32(&self, sampler: Self::Sampler, name: u32, value: f32) {
1917         let samplers = self.samplers.borrow();
1918         let raw_sampler = samplers.get_unchecked(sampler);
1919         match self.raw {
1920             RawRenderingContext::WebGl1(ref _gl) => {
1921                 panic!("Samper parameter for `f32` is not supported")
1922             }
1923             RawRenderingContext::WebGl2(ref gl) => {
1924                 gl.sampler_parameterf(raw_sampler, name, value);
1925             }
1926         }
1927     }
1928 
sampler_parameter_f32_slice( &self, _sampler: Self::Sampler, _name: u32, _value: &[f32], )1929     unsafe fn sampler_parameter_f32_slice(
1930         &self,
1931         _sampler: Self::Sampler,
1932         _name: u32,
1933         _value: &[f32],
1934     ) {
1935         panic!("Sampler parameter for `f32` slice is not supported");
1936     }
1937 
sampler_parameter_i32(&self, sampler: Self::Sampler, name: u32, value: i32)1938     unsafe fn sampler_parameter_i32(&self, sampler: Self::Sampler, name: u32, value: i32) {
1939         let samplers = self.samplers.borrow();
1940         let raw_sampler = samplers.get_unchecked(sampler);
1941         match self.raw {
1942             RawRenderingContext::WebGl1(ref _gl) => {
1943                 panic!("Samper parameter for `i32` is not supported")
1944             }
1945             RawRenderingContext::WebGl2(ref gl) => {
1946                 gl.sampler_parameteri(raw_sampler, name, value);
1947             }
1948         }
1949     }
1950 
generate_mipmap(&self, target: u32)1951     unsafe fn generate_mipmap(&self, target: u32) {
1952         match self.raw {
1953             RawRenderingContext::WebGl1(ref gl) => {
1954                 gl.generate_mipmap(target);
1955             }
1956             RawRenderingContext::WebGl2(ref gl) => {
1957                 gl.generate_mipmap(target);
1958             }
1959         }
1960     }
1961 
tex_image_1d( &self, _target: u32, _level: i32, _internal_format: i32, _width: i32, _border: i32, _format: u32, _ty: u32, _pixels: Option<&[u8]>, )1962     unsafe fn tex_image_1d(
1963         &self,
1964         _target: u32,
1965         _level: i32,
1966         _internal_format: i32,
1967         _width: i32,
1968         _border: i32,
1969         _format: u32,
1970         _ty: u32,
1971         _pixels: Option<&[u8]>,
1972     ) {
1973         panic!("Tex image 1D is not supported");
1974     }
1975 
compressed_tex_image_1d( &self, _target: u32, _level: i32, _internal_format: i32, _width: i32, _border: i32, _image_size: i32, _pixels: &[u8], )1976     unsafe fn compressed_tex_image_1d(
1977         &self,
1978         _target: u32,
1979         _level: i32,
1980         _internal_format: i32,
1981         _width: i32,
1982         _border: i32,
1983         _image_size: i32,
1984         _pixels: &[u8],
1985     ) {
1986         panic!("Compressed tex image 1D is not supported");
1987     }
1988 
tex_image_2d( &self, target: u32, level: i32, internal_format: i32, width: i32, height: i32, border: i32, format: u32, ty: u32, pixels: Option<&[u8]>, )1989     unsafe fn tex_image_2d(
1990         &self,
1991         target: u32,
1992         level: i32,
1993         internal_format: i32,
1994         width: i32,
1995         height: i32,
1996         border: i32,
1997         format: u32,
1998         ty: u32,
1999         pixels: Option<&[u8]>,
2000     ) {
2001         let pixels = pixels.map(|bytes| texture_data_view(ty, bytes));
2002         match self.raw {
2003             RawRenderingContext::WebGl1(ref gl) => {
2004                 // TODO: Handle return value?
2005                 gl.tex_image_2d_with_i32_and_i32_and_i32_and_format_and_type_and_opt_array_buffer_view(
2006                     target,
2007                     level,
2008                     internal_format,
2009                     width,
2010                     height,
2011                     border,
2012                     format,
2013                     ty,
2014                     pixels.as_ref(),
2015                 )
2016                 .unwrap();
2017             }
2018             RawRenderingContext::WebGl2(ref gl) => {
2019                 // TODO: Handle return value?
2020                 gl.tex_image_2d_with_i32_and_i32_and_i32_and_format_and_type_and_opt_array_buffer_view(
2021                     target,
2022                     level,
2023                     internal_format,
2024                     width,
2025                     height,
2026                     border,
2027                     format,
2028                     ty,
2029                     pixels.as_ref(),
2030                 )
2031                 .unwrap();
2032             }
2033         }
2034     }
2035 
tex_image_2d_multisample( &self, _target: u32, _samples: i32, _internal_format: i32, _width: i32, _height: i32, _fixed_sample_locations: bool, )2036     unsafe fn tex_image_2d_multisample(
2037         &self,
2038         _target: u32,
2039         _samples: i32,
2040         _internal_format: i32,
2041         _width: i32,
2042         _height: i32,
2043         _fixed_sample_locations: bool,
2044     ) {
2045         panic!("Tex image 2D multisample is not supported");
2046     }
2047 
compressed_tex_image_2d( &self, target: u32, level: i32, internal_format: i32, width: i32, height: i32, border: i32, _image_size: i32, pixels: &[u8], )2048     unsafe fn compressed_tex_image_2d(
2049         &self,
2050         target: u32,
2051         level: i32,
2052         internal_format: i32,
2053         width: i32,
2054         height: i32,
2055         border: i32,
2056         _image_size: i32,
2057         pixels: &[u8],
2058     ) {
2059         let src_data = js_sys::Uint8Array::view(pixels);
2060         match self.raw {
2061             RawRenderingContext::WebGl1(ref gl) => gl
2062                 .compressed_tex_image_2d_with_array_buffer_view(
2063                     target,
2064                     level,
2065                     internal_format as u32,
2066                     width,
2067                     height,
2068                     border,
2069                     &src_data,
2070                 ),
2071             RawRenderingContext::WebGl2(ref gl) => gl
2072                 .compressed_tex_image_2d_with_array_buffer_view(
2073                     target,
2074                     level,
2075                     internal_format as u32,
2076                     width,
2077                     height,
2078                     border,
2079                     &src_data,
2080                 ),
2081         }
2082     }
2083 
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]>, )2084     unsafe fn tex_image_3d(
2085         &self,
2086         target: u32,
2087         level: i32,
2088         internal_format: i32,
2089         width: i32,
2090         height: i32,
2091         depth: i32,
2092         border: i32,
2093         format: u32,
2094         ty: u32,
2095         pixels: Option<&[u8]>,
2096     ) {
2097         match self.raw {
2098             RawRenderingContext::WebGl1(ref _gl) => panic!("3d textures are not supported"),
2099             RawRenderingContext::WebGl2(ref gl) => {
2100                 let pixels = pixels.map(|bytes| texture_data_view(ty, bytes));
2101                 // TODO: Handle return value?
2102                 gl.tex_image_3d_with_opt_array_buffer_view(
2103                     target,
2104                     level,
2105                     internal_format,
2106                     width,
2107                     height,
2108                     depth,
2109                     border,
2110                     format,
2111                     ty,
2112                     pixels.as_ref(),
2113                 )
2114                 .unwrap();
2115             }
2116         }
2117     }
2118 
compressed_tex_image_3d( &self, target: u32, level: i32, internal_format: i32, width: i32, height: i32, depth: i32, border: i32, _image_size: i32, pixels: &[u8], )2119     unsafe fn compressed_tex_image_3d(
2120         &self,
2121         target: u32,
2122         level: i32,
2123         internal_format: i32,
2124         width: i32,
2125         height: i32,
2126         depth: i32,
2127         border: i32,
2128         _image_size: i32,
2129         pixels: &[u8],
2130     ) {
2131         let src_data = js_sys::Uint8Array::view(pixels);
2132         match self.raw {
2133             RawRenderingContext::WebGl1(_) => {
2134                 panic!("Compressed 3D textures are not supported.")
2135             }
2136             RawRenderingContext::WebGl2(ref gl) => gl
2137                 .compressed_tex_image_3d_with_array_buffer_view(
2138                     target,
2139                     level,
2140                     internal_format as u32,
2141                     width,
2142                     height,
2143                     depth,
2144                     border,
2145                     &src_data,
2146                 ),
2147         }
2148     }
2149 
tex_storage_1d( &self, _target: u32, _levels: i32, _internal_format: u32, _width: i32, )2150     unsafe fn tex_storage_1d(
2151         &self,
2152         _target: u32,
2153         _levels: i32,
2154         _internal_format: u32,
2155         _width: i32,
2156     ) {
2157         panic!("Tex storage 1D is not supported");
2158     }
2159 
tex_storage_2d( &self, target: u32, levels: i32, internal_format: u32, width: i32, height: i32, )2160     unsafe fn tex_storage_2d(
2161         &self,
2162         target: u32,
2163         levels: i32,
2164         internal_format: u32,
2165         width: i32,
2166         height: i32,
2167     ) {
2168         match self.raw {
2169             RawRenderingContext::WebGl1(ref _gl) => panic!("Tex storage 2D is not supported"),
2170             RawRenderingContext::WebGl2(ref gl) => {
2171                 gl.tex_storage_2d(target, levels, internal_format, width, height);
2172             }
2173         }
2174     }
2175 
tex_storage_2d_multisample( &self, _target: u32, _samples: i32, _internal_format: u32, _width: i32, _height: i32, _fixed_sample_locations: bool, )2176     unsafe fn tex_storage_2d_multisample(
2177         &self,
2178         _target: u32,
2179         _samples: i32,
2180         _internal_format: u32,
2181         _width: i32,
2182         _height: i32,
2183         _fixed_sample_locations: bool,
2184     ) {
2185         panic!("Tex storage 2D multisample is not supported");
2186     }
2187 
tex_storage_3d( &self, target: u32, levels: i32, internal_format: u32, width: i32, height: i32, depth: i32, )2188     unsafe fn tex_storage_3d(
2189         &self,
2190         target: u32,
2191         levels: i32,
2192         internal_format: u32,
2193         width: i32,
2194         height: i32,
2195         depth: i32,
2196     ) {
2197         match self.raw {
2198             RawRenderingContext::WebGl1(ref _gl) => panic!("Tex storage 3D is not supported"),
2199             RawRenderingContext::WebGl2(ref gl) => {
2200                 gl.tex_storage_3d(target, levels, internal_format, width, height, depth);
2201             }
2202         }
2203     }
2204 
uniform_1_i32(&self, uniform_location: Option<&Self::UniformLocation>, x: i32)2205     unsafe fn uniform_1_i32(&self, uniform_location: Option<&Self::UniformLocation>, x: i32) {
2206         match self.raw {
2207             RawRenderingContext::WebGl1(ref gl) => gl.uniform1i(uniform_location, x),
2208             RawRenderingContext::WebGl2(ref gl) => gl.uniform1i(uniform_location, x),
2209         }
2210     }
2211 
uniform_2_i32( &self, uniform_location: Option<&Self::UniformLocation>, x: i32, y: i32, )2212     unsafe fn uniform_2_i32(
2213         &self,
2214         uniform_location: Option<&Self::UniformLocation>,
2215         x: i32,
2216         y: i32,
2217     ) {
2218         match self.raw {
2219             RawRenderingContext::WebGl1(ref gl) => gl.uniform2i(uniform_location, x, y),
2220             RawRenderingContext::WebGl2(ref gl) => gl.uniform2i(uniform_location, x, y),
2221         }
2222     }
2223 
uniform_3_i32( &self, uniform_location: Option<&Self::UniformLocation>, x: i32, y: i32, z: i32, )2224     unsafe fn uniform_3_i32(
2225         &self,
2226         uniform_location: Option<&Self::UniformLocation>,
2227         x: i32,
2228         y: i32,
2229         z: i32,
2230     ) {
2231         match self.raw {
2232             RawRenderingContext::WebGl1(ref gl) => gl.uniform3i(uniform_location, x, y, z),
2233             RawRenderingContext::WebGl2(ref gl) => gl.uniform3i(uniform_location, x, y, z),
2234         }
2235     }
2236 
uniform_4_i32( &self, uniform_location: Option<&Self::UniformLocation>, x: i32, y: i32, z: i32, w: i32, )2237     unsafe fn uniform_4_i32(
2238         &self,
2239         uniform_location: Option<&Self::UniformLocation>,
2240         x: i32,
2241         y: i32,
2242         z: i32,
2243         w: i32,
2244     ) {
2245         match self.raw {
2246             RawRenderingContext::WebGl1(ref gl) => gl.uniform4i(uniform_location, x, y, z, w),
2247             RawRenderingContext::WebGl2(ref gl) => gl.uniform4i(uniform_location, x, y, z, w),
2248         }
2249     }
2250 
uniform_1_i32_slice( &self, uniform_location: Option<&Self::UniformLocation>, v: &[i32], )2251     unsafe fn uniform_1_i32_slice(
2252         &self,
2253         uniform_location: Option<&Self::UniformLocation>,
2254         v: &[i32],
2255     ) {
2256         match self.raw {
2257             RawRenderingContext::WebGl1(ref gl) => {
2258                 gl.uniform1iv_with_i32_array(uniform_location, v)
2259             }
2260             RawRenderingContext::WebGl2(ref gl) => {
2261                 gl.uniform1iv_with_i32_array(uniform_location, v)
2262             }
2263         }
2264     }
2265 
uniform_2_i32_slice( &self, uniform_location: Option<&Self::UniformLocation>, v: &[i32], )2266     unsafe fn uniform_2_i32_slice(
2267         &self,
2268         uniform_location: Option<&Self::UniformLocation>,
2269         v: &[i32],
2270     ) {
2271         match self.raw {
2272             RawRenderingContext::WebGl1(ref gl) => {
2273                 gl.uniform2iv_with_i32_array(uniform_location, v)
2274             }
2275             RawRenderingContext::WebGl2(ref gl) => {
2276                 gl.uniform2iv_with_i32_array(uniform_location, v)
2277             }
2278         }
2279     }
2280 
uniform_3_i32_slice( &self, uniform_location: Option<&Self::UniformLocation>, v: &[i32], )2281     unsafe fn uniform_3_i32_slice(
2282         &self,
2283         uniform_location: Option<&Self::UniformLocation>,
2284         v: &[i32],
2285     ) {
2286         match self.raw {
2287             RawRenderingContext::WebGl1(ref gl) => {
2288                 gl.uniform3iv_with_i32_array(uniform_location, v)
2289             }
2290             RawRenderingContext::WebGl2(ref gl) => {
2291                 gl.uniform3iv_with_i32_array(uniform_location, v)
2292             }
2293         }
2294     }
2295 
uniform_4_i32_slice( &self, uniform_location: Option<&Self::UniformLocation>, v: &[i32], )2296     unsafe fn uniform_4_i32_slice(
2297         &self,
2298         uniform_location: Option<&Self::UniformLocation>,
2299         v: &[i32],
2300     ) {
2301         match self.raw {
2302             RawRenderingContext::WebGl1(ref gl) => {
2303                 gl.uniform4iv_with_i32_array(uniform_location, v)
2304             }
2305             RawRenderingContext::WebGl2(ref gl) => {
2306                 gl.uniform4iv_with_i32_array(uniform_location, v)
2307             }
2308         }
2309     }
2310 
uniform_1_u32(&self, uniform_location: Option<&Self::UniformLocation>, x: u32)2311     unsafe fn uniform_1_u32(&self, uniform_location: Option<&Self::UniformLocation>, x: u32) {
2312         match self.raw {
2313             RawRenderingContext::WebGl1(ref _gl) => panic!("Unsigned uniforms are not supported"),
2314             RawRenderingContext::WebGl2(ref gl) => gl.uniform1ui(uniform_location, x),
2315         }
2316     }
2317 
uniform_2_u32( &self, uniform_location: Option<&Self::UniformLocation>, x: u32, y: u32, )2318     unsafe fn uniform_2_u32(
2319         &self,
2320         uniform_location: Option<&Self::UniformLocation>,
2321         x: u32,
2322         y: u32,
2323     ) {
2324         match self.raw {
2325             RawRenderingContext::WebGl1(ref _gl) => panic!("Unsigned uniforms are not supported"),
2326             RawRenderingContext::WebGl2(ref gl) => gl.uniform2ui(uniform_location, x, y),
2327         }
2328     }
2329 
uniform_3_u32( &self, uniform_location: Option<&Self::UniformLocation>, x: u32, y: u32, z: u32, )2330     unsafe fn uniform_3_u32(
2331         &self,
2332         uniform_location: Option<&Self::UniformLocation>,
2333         x: u32,
2334         y: u32,
2335         z: u32,
2336     ) {
2337         match self.raw {
2338             RawRenderingContext::WebGl1(ref _gl) => panic!("Unsigned uniforms are not supported"),
2339             RawRenderingContext::WebGl2(ref gl) => gl.uniform3ui(uniform_location, x, y, z),
2340         }
2341     }
2342 
uniform_4_u32( &self, uniform_location: Option<&Self::UniformLocation>, x: u32, y: u32, z: u32, w: u32, )2343     unsafe fn uniform_4_u32(
2344         &self,
2345         uniform_location: Option<&Self::UniformLocation>,
2346         x: u32,
2347         y: u32,
2348         z: u32,
2349         w: u32,
2350     ) {
2351         match self.raw {
2352             RawRenderingContext::WebGl1(ref _gl) => panic!("Unsigned uniforms are not supported"),
2353             RawRenderingContext::WebGl2(ref gl) => gl.uniform4ui(uniform_location, x, y, z, w),
2354         }
2355     }
2356 
uniform_1_u32_slice( &self, uniform_location: Option<&Self::UniformLocation>, v: &[u32], )2357     unsafe fn uniform_1_u32_slice(
2358         &self,
2359         uniform_location: Option<&Self::UniformLocation>,
2360         v: &[u32],
2361     ) {
2362         match self.raw {
2363             RawRenderingContext::WebGl1(ref _gl) => {
2364                 panic!("Unsigned uniforms are not supported");
2365             }
2366             RawRenderingContext::WebGl2(ref gl) => {
2367                 gl.uniform1uiv_with_u32_array(uniform_location, v)
2368             }
2369         }
2370     }
2371 
uniform_2_u32_slice( &self, uniform_location: Option<&Self::UniformLocation>, v: &[u32], )2372     unsafe fn uniform_2_u32_slice(
2373         &self,
2374         uniform_location: Option<&Self::UniformLocation>,
2375         v: &[u32],
2376     ) {
2377         match self.raw {
2378             RawRenderingContext::WebGl1(ref _gl) => {
2379                 panic!("Unsigned uniforms are not supported");
2380             }
2381             RawRenderingContext::WebGl2(ref gl) => {
2382                 gl.uniform2uiv_with_u32_array(uniform_location, v)
2383             }
2384         }
2385     }
2386 
uniform_3_u32_slice( &self, uniform_location: Option<&Self::UniformLocation>, v: &[u32], )2387     unsafe fn uniform_3_u32_slice(
2388         &self,
2389         uniform_location: Option<&Self::UniformLocation>,
2390         v: &[u32],
2391     ) {
2392         match self.raw {
2393             RawRenderingContext::WebGl1(ref _gl) => {
2394                 panic!("Unsigned uniforms are not supported");
2395             }
2396             RawRenderingContext::WebGl2(ref gl) => {
2397                 gl.uniform3uiv_with_u32_array(uniform_location, v)
2398             }
2399         }
2400     }
2401 
uniform_4_u32_slice( &self, uniform_location: Option<&Self::UniformLocation>, v: &[u32], )2402     unsafe fn uniform_4_u32_slice(
2403         &self,
2404         uniform_location: Option<&Self::UniformLocation>,
2405         v: &[u32],
2406     ) {
2407         match self.raw {
2408             RawRenderingContext::WebGl1(ref _gl) => {
2409                 panic!("Unsigned uniforms are not supported");
2410             }
2411             RawRenderingContext::WebGl2(ref gl) => {
2412                 gl.uniform4uiv_with_u32_array(uniform_location, v)
2413             }
2414         }
2415     }
2416 
uniform_1_f32(&self, uniform_location: Option<&Self::UniformLocation>, x: f32)2417     unsafe fn uniform_1_f32(&self, uniform_location: Option<&Self::UniformLocation>, x: f32) {
2418         match self.raw {
2419             RawRenderingContext::WebGl1(ref gl) => gl.uniform1f(uniform_location, x),
2420             RawRenderingContext::WebGl2(ref gl) => gl.uniform1f(uniform_location, x),
2421         }
2422     }
2423 
uniform_2_f32( &self, uniform_location: Option<&Self::UniformLocation>, x: f32, y: f32, )2424     unsafe fn uniform_2_f32(
2425         &self,
2426         uniform_location: Option<&Self::UniformLocation>,
2427         x: f32,
2428         y: f32,
2429     ) {
2430         match self.raw {
2431             RawRenderingContext::WebGl1(ref gl) => gl.uniform2f(uniform_location, x, y),
2432             RawRenderingContext::WebGl2(ref gl) => gl.uniform2f(uniform_location, x, y),
2433         }
2434     }
2435 
uniform_3_f32( &self, uniform_location: Option<&Self::UniformLocation>, x: f32, y: f32, z: f32, )2436     unsafe fn uniform_3_f32(
2437         &self,
2438         uniform_location: Option<&Self::UniformLocation>,
2439         x: f32,
2440         y: f32,
2441         z: f32,
2442     ) {
2443         match self.raw {
2444             RawRenderingContext::WebGl1(ref gl) => gl.uniform3f(uniform_location, x, y, z),
2445             RawRenderingContext::WebGl2(ref gl) => gl.uniform3f(uniform_location, x, y, z),
2446         }
2447     }
2448 
uniform_4_f32( &self, uniform_location: Option<&Self::UniformLocation>, x: f32, y: f32, z: f32, w: f32, )2449     unsafe fn uniform_4_f32(
2450         &self,
2451         uniform_location: Option<&Self::UniformLocation>,
2452         x: f32,
2453         y: f32,
2454         z: f32,
2455         w: f32,
2456     ) {
2457         match self.raw {
2458             RawRenderingContext::WebGl1(ref gl) => gl.uniform4f(uniform_location, x, y, z, w),
2459             RawRenderingContext::WebGl2(ref gl) => gl.uniform4f(uniform_location, x, y, z, w),
2460         }
2461     }
2462 
uniform_1_f32_slice( &self, uniform_location: Option<&Self::UniformLocation>, v: &[f32], )2463     unsafe fn uniform_1_f32_slice(
2464         &self,
2465         uniform_location: Option<&Self::UniformLocation>,
2466         v: &[f32],
2467     ) {
2468         match self.raw {
2469             RawRenderingContext::WebGl1(ref gl) => {
2470                 gl.uniform1fv_with_f32_array(uniform_location, v)
2471             }
2472             RawRenderingContext::WebGl2(ref gl) => {
2473                 gl.uniform1fv_with_f32_array(uniform_location, v)
2474             }
2475         }
2476     }
2477 
uniform_2_f32_slice( &self, uniform_location: Option<&Self::UniformLocation>, v: &[f32], )2478     unsafe fn uniform_2_f32_slice(
2479         &self,
2480         uniform_location: Option<&Self::UniformLocation>,
2481         v: &[f32],
2482     ) {
2483         match self.raw {
2484             RawRenderingContext::WebGl1(ref gl) => {
2485                 gl.uniform2fv_with_f32_array(uniform_location, v)
2486             }
2487             RawRenderingContext::WebGl2(ref gl) => {
2488                 gl.uniform2fv_with_f32_array(uniform_location, v)
2489             }
2490         }
2491     }
2492 
uniform_3_f32_slice( &self, uniform_location: Option<&Self::UniformLocation>, v: &[f32], )2493     unsafe fn uniform_3_f32_slice(
2494         &self,
2495         uniform_location: Option<&Self::UniformLocation>,
2496         v: &[f32],
2497     ) {
2498         match self.raw {
2499             RawRenderingContext::WebGl1(ref gl) => {
2500                 gl.uniform3fv_with_f32_array(uniform_location, v)
2501             }
2502             RawRenderingContext::WebGl2(ref gl) => {
2503                 gl.uniform3fv_with_f32_array(uniform_location, v)
2504             }
2505         }
2506     }
2507 
uniform_4_f32_slice( &self, uniform_location: Option<&Self::UniformLocation>, v: &[f32], )2508     unsafe fn uniform_4_f32_slice(
2509         &self,
2510         uniform_location: Option<&Self::UniformLocation>,
2511         v: &[f32],
2512     ) {
2513         match self.raw {
2514             RawRenderingContext::WebGl1(ref gl) => {
2515                 gl.uniform4fv_with_f32_array(uniform_location, v)
2516             }
2517             RawRenderingContext::WebGl2(ref gl) => {
2518                 gl.uniform4fv_with_f32_array(uniform_location, v)
2519             }
2520         }
2521     }
2522 
uniform_matrix_2_f32_slice( &self, uniform_location: Option<&Self::UniformLocation>, transpose: bool, v: &[f32], )2523     unsafe fn uniform_matrix_2_f32_slice(
2524         &self,
2525         uniform_location: Option<&Self::UniformLocation>,
2526         transpose: bool,
2527         v: &[f32],
2528     ) {
2529         match self.raw {
2530             RawRenderingContext::WebGl1(ref gl) => {
2531                 gl.uniform_matrix2fv_with_f32_array(uniform_location, transpose, v)
2532             }
2533             RawRenderingContext::WebGl2(ref gl) => {
2534                 gl.uniform_matrix2fv_with_f32_array(uniform_location, transpose, v)
2535             }
2536         }
2537     }
2538 
uniform_matrix_3_f32_slice( &self, uniform_location: Option<&Self::UniformLocation>, transpose: bool, v: &[f32], )2539     unsafe fn uniform_matrix_3_f32_slice(
2540         &self,
2541         uniform_location: Option<&Self::UniformLocation>,
2542         transpose: bool,
2543         v: &[f32],
2544     ) {
2545         match self.raw {
2546             RawRenderingContext::WebGl1(ref gl) => {
2547                 gl.uniform_matrix3fv_with_f32_array(uniform_location, transpose, v)
2548             }
2549             RawRenderingContext::WebGl2(ref gl) => {
2550                 gl.uniform_matrix3fv_with_f32_array(uniform_location, transpose, v)
2551             }
2552         }
2553     }
2554 
uniform_matrix_4_f32_slice( &self, uniform_location: Option<&Self::UniformLocation>, transpose: bool, v: &[f32], )2555     unsafe fn uniform_matrix_4_f32_slice(
2556         &self,
2557         uniform_location: Option<&Self::UniformLocation>,
2558         transpose: bool,
2559         v: &[f32],
2560     ) {
2561         match self.raw {
2562             RawRenderingContext::WebGl1(ref gl) => {
2563                 gl.uniform_matrix4fv_with_f32_array(uniform_location, transpose, v)
2564             }
2565             RawRenderingContext::WebGl2(ref gl) => {
2566                 gl.uniform_matrix4fv_with_f32_array(uniform_location, transpose, v)
2567             }
2568         }
2569     }
2570 
unmap_buffer(&self, _target: u32)2571     unsafe fn unmap_buffer(&self, _target: u32) {
2572         panic!("Unmap buffer is not supported");
2573     }
2574 
cull_face(&self, value: u32)2575     unsafe fn cull_face(&self, value: u32) {
2576         match self.raw {
2577             RawRenderingContext::WebGl1(ref gl) => gl.cull_face(value as u32),
2578             RawRenderingContext::WebGl2(ref gl) => gl.cull_face(value as u32),
2579         }
2580     }
2581 
color_mask(&self, red: bool, green: bool, blue: bool, alpha: bool)2582     unsafe fn color_mask(&self, red: bool, green: bool, blue: bool, alpha: bool) {
2583         match self.raw {
2584             RawRenderingContext::WebGl1(ref gl) => gl.color_mask(red, green, blue, alpha),
2585             RawRenderingContext::WebGl2(ref gl) => gl.color_mask(red, green, blue, alpha),
2586         }
2587     }
2588 
color_mask_draw_buffer( &self, _draw_buffer: u32, _red: bool, _green: bool, _blue: bool, _alpha: bool, )2589     unsafe fn color_mask_draw_buffer(
2590         &self,
2591         _draw_buffer: u32,
2592         _red: bool,
2593         _green: bool,
2594         _blue: bool,
2595         _alpha: bool,
2596     ) {
2597         panic!("Draw buffer color masks are not supported");
2598     }
2599 
depth_mask(&self, value: bool)2600     unsafe fn depth_mask(&self, value: bool) {
2601         match self.raw {
2602             RawRenderingContext::WebGl1(ref gl) => gl.depth_mask(value),
2603             RawRenderingContext::WebGl2(ref gl) => gl.depth_mask(value),
2604         }
2605     }
2606 
blend_color(&self, red: f32, green: f32, blue: f32, alpha: f32)2607     unsafe fn blend_color(&self, red: f32, green: f32, blue: f32, alpha: f32) {
2608         match self.raw {
2609             RawRenderingContext::WebGl1(ref gl) => gl.blend_color(red, green, blue, alpha),
2610             RawRenderingContext::WebGl2(ref gl) => gl.blend_color(red, green, blue, alpha),
2611         }
2612     }
2613 
line_width(&self, width: f32)2614     unsafe fn line_width(&self, width: f32) {
2615         match self.raw {
2616             RawRenderingContext::WebGl1(ref gl) => gl.line_width(width),
2617             RawRenderingContext::WebGl2(ref gl) => gl.line_width(width),
2618         }
2619     }
2620 
map_buffer_range( &self, _target: u32, _offset: i32, _length: i32, _access: u32, ) -> *mut u82621     unsafe fn map_buffer_range(
2622         &self,
2623         _target: u32,
2624         _offset: i32,
2625         _length: i32,
2626         _access: u32,
2627     ) -> *mut u8 {
2628         panic!("Map buffer range is not supported")
2629     }
2630 
flush_mapped_buffer_range(&self, _target: u32, _offset: i32, _length: i32)2631     unsafe fn flush_mapped_buffer_range(&self, _target: u32, _offset: i32, _length: i32) {
2632         panic!("Flush mapped buffer range is not supported")
2633     }
2634 
invalidate_buffer_sub_data(&self, _target: u32, _offset: i32, _length: i32)2635     unsafe fn invalidate_buffer_sub_data(&self, _target: u32, _offset: i32, _length: i32) {
2636         panic!("Invalidate buffer sub data is not supported")
2637     }
2638 
invalidate_framebuffer(&self, target: u32, attachments: &[u32])2639     unsafe fn invalidate_framebuffer(&self, target: u32, attachments: &[u32]) {
2640         match self.raw {
2641             RawRenderingContext::WebGl1(ref _gl) => {
2642                 panic!("Invalidate framebuffer is not supported");
2643             }
2644             RawRenderingContext::WebGl2(ref gl) => {
2645                 let js_attachments = Array::new();
2646                 for &a in attachments {
2647                     js_attachments.push(&a.into());
2648                 }
2649                 gl.invalidate_framebuffer(target, &js_attachments).unwrap();
2650             }
2651         }
2652     }
2653 
polygon_offset(&self, factor: f32, units: f32)2654     unsafe fn polygon_offset(&self, factor: f32, units: f32) {
2655         match self.raw {
2656             RawRenderingContext::WebGl1(ref gl) => gl.polygon_offset(factor, units),
2657             RawRenderingContext::WebGl2(ref gl) => gl.polygon_offset(factor, units),
2658         }
2659     }
2660 
polygon_mode(&self, _face: u32, mode: u32)2661     unsafe fn polygon_mode(&self, _face: u32, mode: u32) {
2662         if mode != FILL {
2663             panic!("Polygon mode other than FILL is not supported");
2664         }
2665     }
2666 
finish(&self)2667     unsafe fn finish(&self) {
2668         match self.raw {
2669             RawRenderingContext::WebGl1(ref gl) => gl.finish(),
2670             RawRenderingContext::WebGl2(ref gl) => gl.finish(),
2671         }
2672     }
2673 
bind_texture(&self, target: u32, texture: Option<Self::Texture>)2674     unsafe fn bind_texture(&self, target: u32, texture: Option<Self::Texture>) {
2675         let textures = self.textures.borrow();
2676         let raw_texture = texture.map(|t| textures.get_unchecked(t));
2677         match self.raw {
2678             RawRenderingContext::WebGl1(ref gl) => gl.bind_texture(target, raw_texture),
2679             RawRenderingContext::WebGl2(ref gl) => gl.bind_texture(target, raw_texture),
2680         }
2681     }
2682 
bind_sampler(&self, unit: u32, sampler: Option<Self::Sampler>)2683     unsafe fn bind_sampler(&self, unit: u32, sampler: Option<Self::Sampler>) {
2684         let samplers = self.samplers.borrow();
2685         let raw_sampler = sampler.map(|s| samplers.get_unchecked(s));
2686         match self.raw {
2687             RawRenderingContext::WebGl1(ref _gl) => panic!("Bind sampler is not supported"),
2688             RawRenderingContext::WebGl2(ref gl) => gl.bind_sampler(unit, raw_sampler),
2689         }
2690     }
2691 
active_texture(&self, unit: u32)2692     unsafe fn active_texture(&self, unit: u32) {
2693         match self.raw {
2694             RawRenderingContext::WebGl1(ref gl) => gl.active_texture(unit),
2695             RawRenderingContext::WebGl2(ref gl) => gl.active_texture(unit),
2696         }
2697     }
2698 
fence_sync(&self, condition: u32, flags: u32) -> Result<Self::Fence, String>2699     unsafe fn fence_sync(&self, condition: u32, flags: u32) -> Result<Self::Fence, String> {
2700         let raw_fence = match self.raw {
2701             RawRenderingContext::WebGl1(ref _gl) => panic!("Fences are not supported"),
2702             RawRenderingContext::WebGl2(ref gl) => gl.fence_sync(condition as u32, flags),
2703         };
2704         match raw_fence {
2705             Some(f) => {
2706                 let key = self.fences.borrow_mut().insert(f);
2707                 Ok(key)
2708             }
2709             None => Err(String::from("Unable to create fence object")),
2710         }
2711     }
2712 
tex_parameter_f32(&self, target: u32, parameter: u32, value: f32)2713     unsafe fn tex_parameter_f32(&self, target: u32, parameter: u32, value: f32) {
2714         match self.raw {
2715             RawRenderingContext::WebGl1(ref gl) => gl.tex_parameterf(target, parameter, value),
2716             RawRenderingContext::WebGl2(ref gl) => gl.tex_parameterf(target, parameter, value),
2717         }
2718     }
2719 
tex_parameter_i32(&self, target: u32, parameter: u32, value: i32)2720     unsafe fn tex_parameter_i32(&self, target: u32, parameter: u32, value: i32) {
2721         match self.raw {
2722             RawRenderingContext::WebGl1(ref gl) => gl.tex_parameteri(target, parameter, value),
2723             RawRenderingContext::WebGl2(ref gl) => gl.tex_parameteri(target, parameter, value),
2724         }
2725     }
2726 
tex_parameter_f32_slice(&self, _target: u32, _parameter: u32, _values: &[f32])2727     unsafe fn tex_parameter_f32_slice(&self, _target: u32, _parameter: u32, _values: &[f32]) {
2728         // Blocked by https://github.com/rustwasm/wasm-bindgen/issues/1038
2729         panic!("Texture parameters for `&[f32]` are not supported yet");
2730     }
2731 
tex_parameter_i32_slice(&self, _target: u32, _parameter: u32, _values: &[i32])2732     unsafe fn tex_parameter_i32_slice(&self, _target: u32, _parameter: u32, _values: &[i32]) {
2733         panic!("Texture parameters for `&[i32]` are not supported yet");
2734     }
2735 
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, )2736     unsafe fn tex_sub_image_2d(
2737         &self,
2738         target: u32,
2739         level: i32,
2740         x_offset: i32,
2741         y_offset: i32,
2742         width: i32,
2743         height: i32,
2744         format: u32,
2745         ty: u32,
2746         pixels: PixelUnpackData,
2747     ) {
2748         match self.raw {
2749             RawRenderingContext::WebGl1(ref gl) => {
2750                 match pixels {
2751                     PixelUnpackData::BufferOffset(_) => {
2752                         panic!("Sub image 2D pixel buffer offset is not supported");
2753                     }
2754                     PixelUnpackData::Slice(data) => {
2755                         let data = texture_data_view(ty, data);
2756                         gl.tex_sub_image_2d_with_i32_and_i32_and_u32_and_type_and_opt_array_buffer_view(
2757                             target, level, x_offset, y_offset, width, height, format, ty, Some(&data),
2758                         )
2759                     }
2760                 }
2761                 .unwrap(); // TODO: Handle return value?
2762             }
2763             RawRenderingContext::WebGl2(ref gl) => {
2764                 match pixels {
2765                     PixelUnpackData::BufferOffset(offset) => gl
2766                         .tex_sub_image_2d_with_i32_and_i32_and_u32_and_type_and_i32(
2767                             target,
2768                             level,
2769                             x_offset,
2770                             y_offset,
2771                             width,
2772                             height,
2773                             format,
2774                             ty,
2775                             offset as i32,
2776                         ),
2777                     PixelUnpackData::Slice(data) => {
2778                         let data = texture_data_view(ty, data);
2779                         gl.tex_sub_image_2d_with_i32_and_i32_and_u32_and_type_and_opt_array_buffer_view(
2780                             target, level, x_offset, y_offset, width, height, format, ty, Some(&data),
2781                         )
2782                     }
2783                 }
2784                 .unwrap(); // TODO: Handle return value?
2785             }
2786         }
2787     }
2788 
compressed_tex_sub_image_2d( &self, target: u32, level: i32, x_offset: i32, y_offset: i32, width: i32, height: i32, format: u32, pixels: CompressedPixelUnpackData, )2789     unsafe fn compressed_tex_sub_image_2d(
2790         &self,
2791         target: u32,
2792         level: i32,
2793         x_offset: i32,
2794         y_offset: i32,
2795         width: i32,
2796         height: i32,
2797         format: u32,
2798         pixels: CompressedPixelUnpackData,
2799     ) {
2800         match self.raw {
2801             RawRenderingContext::WebGl1(ref gl) => match pixels {
2802                 CompressedPixelUnpackData::BufferRange(_) => {
2803                     panic!("Compressed sub image 2D pixel buffer range is not supported");
2804                 }
2805                 CompressedPixelUnpackData::Slice(data) => {
2806                     let data = texture_data_view(BYTE, data);
2807                     gl.compressed_tex_sub_image_2d_with_array_buffer_view(
2808                         target, level, x_offset, y_offset, width, height, format, &data,
2809                     )
2810                 }
2811             },
2812             RawRenderingContext::WebGl2(ref gl) => match pixels {
2813                 CompressedPixelUnpackData::BufferRange(range) => gl
2814                     .compressed_tex_sub_image_2d_with_i32_and_i32(
2815                         target,
2816                         level,
2817                         x_offset,
2818                         y_offset,
2819                         width,
2820                         height,
2821                         format,
2822                         (range.end - range.start) as i32,
2823                         range.start as i32,
2824                     ),
2825                 CompressedPixelUnpackData::Slice(data) => {
2826                     let data = texture_data_view(BYTE, data);
2827                     gl.compressed_tex_sub_image_2d_with_array_buffer_view(
2828                         target, level, x_offset, y_offset, width, height, format, &data,
2829                     )
2830                 }
2831             },
2832         }
2833     }
2834 
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, )2835     unsafe fn tex_sub_image_3d(
2836         &self,
2837         target: u32,
2838         level: i32,
2839         x_offset: i32,
2840         y_offset: i32,
2841         z_offset: i32,
2842         width: i32,
2843         height: i32,
2844         depth: i32,
2845         format: u32,
2846         ty: u32,
2847         pixels: PixelUnpackData,
2848     ) {
2849         match self.raw {
2850             RawRenderingContext::WebGl1(ref _gl) => {
2851                 panic!("Sub image 3D is not supported");
2852             }
2853             RawRenderingContext::WebGl2(ref gl) => {
2854                 match pixels {
2855                     PixelUnpackData::BufferOffset(offset) => gl.tex_sub_image_3d_with_i32(
2856                         target,
2857                         level,
2858                         x_offset,
2859                         y_offset,
2860                         z_offset,
2861                         width,
2862                         height,
2863                         depth,
2864                         format,
2865                         ty,
2866                         offset as i32,
2867                     ),
2868                     PixelUnpackData::Slice(slice) => {
2869                         let slice = texture_data_view(ty, slice);
2870                         gl.tex_sub_image_3d_with_opt_array_buffer_view(
2871                             target,
2872                             level,
2873                             x_offset,
2874                             y_offset,
2875                             z_offset,
2876                             width,
2877                             height,
2878                             depth,
2879                             format,
2880                             ty,
2881                             Some(&slice),
2882                         )
2883                     }
2884                 }
2885                 .unwrap(); // TODO: Handle return value?
2886             }
2887         }
2888     }
2889 
compressed_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, pixels: CompressedPixelUnpackData, )2890     unsafe fn compressed_tex_sub_image_3d(
2891         &self,
2892         target: u32,
2893         level: i32,
2894         x_offset: i32,
2895         y_offset: i32,
2896         z_offset: i32,
2897         width: i32,
2898         height: i32,
2899         depth: i32,
2900         format: u32,
2901         pixels: CompressedPixelUnpackData,
2902     ) {
2903         match self.raw {
2904             RawRenderingContext::WebGl1(ref _gl) => {
2905                 panic!("Compressed sub image 3D is not supported");
2906             }
2907             RawRenderingContext::WebGl2(ref gl) => match pixels {
2908                 CompressedPixelUnpackData::BufferRange(range) => gl
2909                     .compressed_tex_sub_image_3d_with_i32_and_i32(
2910                         target,
2911                         level,
2912                         x_offset,
2913                         y_offset,
2914                         z_offset,
2915                         width,
2916                         height,
2917                         depth,
2918                         format,
2919                         (range.end - range.start) as i32,
2920                         range.start as i32,
2921                     ),
2922                 CompressedPixelUnpackData::Slice(data) => {
2923                     let data = texture_data_view(BYTE, data);
2924                     gl.compressed_tex_sub_image_3d_with_array_buffer_view(
2925                         target, level, x_offset, y_offset, z_offset, width, height, depth, format,
2926                         &data,
2927                     )
2928                 }
2929             },
2930         }
2931     }
2932 
depth_func(&self, func: u32)2933     unsafe fn depth_func(&self, func: u32) {
2934         match self.raw {
2935             RawRenderingContext::WebGl1(ref gl) => gl.depth_func(func as u32),
2936             RawRenderingContext::WebGl2(ref gl) => gl.depth_func(func as u32),
2937         }
2938     }
2939 
depth_range_f32(&self, near: f32, far: f32)2940     unsafe fn depth_range_f32(&self, near: f32, far: f32) {
2941         match self.raw {
2942             RawRenderingContext::WebGl1(ref gl) => gl.depth_range(near, far),
2943             RawRenderingContext::WebGl2(ref gl) => gl.depth_range(near, far),
2944         }
2945     }
2946 
depth_range_f64(&self, _near: f64, _far: f64)2947     unsafe fn depth_range_f64(&self, _near: f64, _far: f64) {
2948         panic!("Depth range with 64-bit float values is not supported");
2949     }
2950 
depth_range_f64_slice(&self, _first: u32, _count: i32, _values: &[[f64; 2]])2951     unsafe fn depth_range_f64_slice(&self, _first: u32, _count: i32, _values: &[[f64; 2]]) {
2952         panic!("Depth range with 64-bit float slices is not supported");
2953     }
2954 
scissor(&self, x: i32, y: i32, width: i32, height: i32)2955     unsafe fn scissor(&self, x: i32, y: i32, width: i32, height: i32) {
2956         match self.raw {
2957             RawRenderingContext::WebGl1(ref gl) => gl.scissor(x, y, width, height),
2958             RawRenderingContext::WebGl2(ref gl) => gl.scissor(x, y, width, height),
2959         }
2960     }
2961 
scissor_slice(&self, _first: u32, _count: i32, _scissors: &[[i32; 4]])2962     unsafe fn scissor_slice(&self, _first: u32, _count: i32, _scissors: &[[i32; 4]]) {
2963         panic!("Scissor slice is not supported");
2964     }
2965 
vertex_attrib_divisor(&self, index: u32, divisor: u32)2966     unsafe fn vertex_attrib_divisor(&self, index: u32, divisor: u32) {
2967         match self.raw {
2968             RawRenderingContext::WebGl1(ref _gl) => match &self.extensions.angle_instanced_arrays {
2969                 None => panic!("Vertex attrib divisor is not supported"),
2970                 Some(extension) => extension.vertex_attrib_divisor_angle(index, divisor),
2971             },
2972             RawRenderingContext::WebGl2(ref gl) => gl.vertex_attrib_divisor(index, divisor),
2973         }
2974     }
2975 
vertex_attrib_pointer_f32( &self, index: u32, size: i32, data_type: u32, normalized: bool, stride: i32, offset: i32, )2976     unsafe fn vertex_attrib_pointer_f32(
2977         &self,
2978         index: u32,
2979         size: i32,
2980         data_type: u32,
2981         normalized: bool,
2982         stride: i32,
2983         offset: i32,
2984     ) {
2985         match self.raw {
2986             RawRenderingContext::WebGl1(ref gl) => gl
2987                 .vertex_attrib_pointer_with_i32(index, size, data_type, normalized, stride, offset),
2988             RawRenderingContext::WebGl2(ref gl) => gl
2989                 .vertex_attrib_pointer_with_i32(index, size, data_type, normalized, stride, offset),
2990         }
2991     }
2992 
vertex_attrib_pointer_i32( &self, index: u32, size: i32, data_type: u32, stride: i32, offset: i32, )2993     unsafe fn vertex_attrib_pointer_i32(
2994         &self,
2995         index: u32,
2996         size: i32,
2997         data_type: u32,
2998         stride: i32,
2999         offset: i32,
3000     ) {
3001         match self.raw {
3002             RawRenderingContext::WebGl1(ref _gl) => {
3003                 panic!("Integer vertex attrib pointer is not supported")
3004             }
3005             RawRenderingContext::WebGl2(ref gl) => {
3006                 gl.vertex_attrib_i_pointer_with_i32(index, size, data_type, stride, offset)
3007             }
3008         }
3009     }
3010 
vertex_attrib_pointer_f64( &self, _index: u32, _size: i32, _data_type: u32, _stride: i32, _offset: i32, )3011     unsafe fn vertex_attrib_pointer_f64(
3012         &self,
3013         _index: u32,
3014         _size: i32,
3015         _data_type: u32,
3016         _stride: i32,
3017         _offset: i32,
3018     ) {
3019         panic!("64-bit float precision is not supported in WebGL");
3020     }
3021 
vertex_attrib_format_f32( &self, _index: u32, _size: i32, _data_type: u32, _normalized: bool, _relative_offset: u32, )3022     unsafe fn vertex_attrib_format_f32(
3023         &self,
3024         _index: u32,
3025         _size: i32,
3026         _data_type: u32,
3027         _normalized: bool,
3028         _relative_offset: u32,
3029     ) {
3030         panic!("Vertex attrib format is not supported in WebGL");
3031     }
3032 
vertex_attrib_format_i32( &self, _index: u32, _size: i32, _data_type: u32, _relative_offset: u32, )3033     unsafe fn vertex_attrib_format_i32(
3034         &self,
3035         _index: u32,
3036         _size: i32,
3037         _data_type: u32,
3038         _relative_offset: u32,
3039     ) {
3040         panic!("Vertex attrib format is not supported in WebGL");
3041     }
3042 
vertex_attrib_1_f32(&self, index: u32, x: f32)3043     unsafe fn vertex_attrib_1_f32(&self, index: u32, x: f32) {
3044         match self.raw {
3045             RawRenderingContext::WebGl1(ref gl) => gl.vertex_attrib1f(index, x),
3046             RawRenderingContext::WebGl2(ref gl) => gl.vertex_attrib1f(index, x),
3047         }
3048     }
3049 
vertex_attrib_2_f32(&self, index: u32, x: f32, y: f32)3050     unsafe fn vertex_attrib_2_f32(&self, index: u32, x: f32, y: f32) {
3051         match self.raw {
3052             RawRenderingContext::WebGl1(ref gl) => gl.vertex_attrib2f(index, x, y),
3053             RawRenderingContext::WebGl2(ref gl) => gl.vertex_attrib2f(index, x, y),
3054         }
3055     }
3056 
vertex_attrib_3_f32(&self, index: u32, x: f32, y: f32, z: f32)3057     unsafe fn vertex_attrib_3_f32(&self, index: u32, x: f32, y: f32, z: f32) {
3058         match self.raw {
3059             RawRenderingContext::WebGl1(ref gl) => gl.vertex_attrib3f(index, x, y, z),
3060             RawRenderingContext::WebGl2(ref gl) => gl.vertex_attrib3f(index, x, y, z),
3061         }
3062     }
3063 
vertex_attrib_4_f32(&self, index: u32, x: f32, y: f32, z: f32, w: f32)3064     unsafe fn vertex_attrib_4_f32(&self, index: u32, x: f32, y: f32, z: f32, w: f32) {
3065         match self.raw {
3066             RawRenderingContext::WebGl1(ref gl) => gl.vertex_attrib4f(index, x, y, z, w),
3067             RawRenderingContext::WebGl2(ref gl) => gl.vertex_attrib4f(index, x, y, z, w),
3068         }
3069     }
3070 
vertex_attrib_1_f32_slice(&self, index: u32, v: &[f32])3071     unsafe fn vertex_attrib_1_f32_slice(&self, index: u32, v: &[f32]) {
3072         match self.raw {
3073             RawRenderingContext::WebGl1(ref gl) => gl.vertex_attrib1fv_with_f32_array(index, v),
3074             RawRenderingContext::WebGl2(ref gl) => gl.vertex_attrib1fv_with_f32_array(index, v),
3075         }
3076     }
3077 
vertex_attrib_2_f32_slice(&self, index: u32, v: &[f32])3078     unsafe fn vertex_attrib_2_f32_slice(&self, index: u32, v: &[f32]) {
3079         match self.raw {
3080             RawRenderingContext::WebGl1(ref gl) => gl.vertex_attrib2fv_with_f32_array(index, v),
3081             RawRenderingContext::WebGl2(ref gl) => gl.vertex_attrib2fv_with_f32_array(index, v),
3082         }
3083     }
3084 
vertex_attrib_3_f32_slice(&self, index: u32, v: &[f32])3085     unsafe fn vertex_attrib_3_f32_slice(&self, index: u32, v: &[f32]) {
3086         match self.raw {
3087             RawRenderingContext::WebGl1(ref gl) => gl.vertex_attrib3fv_with_f32_array(index, v),
3088             RawRenderingContext::WebGl2(ref gl) => gl.vertex_attrib3fv_with_f32_array(index, v),
3089         }
3090     }
3091 
vertex_attrib_4_f32_slice(&self, index: u32, v: &[f32])3092     unsafe fn vertex_attrib_4_f32_slice(&self, index: u32, v: &[f32]) {
3093         match self.raw {
3094             RawRenderingContext::WebGl1(ref gl) => gl.vertex_attrib4fv_with_f32_array(index, v),
3095             RawRenderingContext::WebGl2(ref gl) => gl.vertex_attrib4fv_with_f32_array(index, v),
3096         }
3097     }
3098 
vertex_attrib_binding(&self, _attrib_index: u32, _binding_index: u32)3099     unsafe fn vertex_attrib_binding(&self, _attrib_index: u32, _binding_index: u32) {
3100         panic!("Vertex attrib binding is not supported");
3101     }
3102 
vertex_binding_divisor(&self, _binding_index: u32, _divisor: u32)3103     unsafe fn vertex_binding_divisor(&self, _binding_index: u32, _divisor: u32) {
3104         panic!("Vertex binding divisor is not supported");
3105     }
3106 
viewport(&self, x: i32, y: i32, width: i32, height: i32)3107     unsafe fn viewport(&self, x: i32, y: i32, width: i32, height: i32) {
3108         match self.raw {
3109             RawRenderingContext::WebGl1(ref gl) => gl.viewport(x, y, width, height),
3110             RawRenderingContext::WebGl2(ref gl) => gl.viewport(x, y, width, height),
3111         }
3112     }
3113 
viewport_f32_slice(&self, _first: u32, _count: i32, _values: &[[f32; 4]])3114     unsafe fn viewport_f32_slice(&self, _first: u32, _count: i32, _values: &[[f32; 4]]) {
3115         panic!("Viewport `f32` slice is not supported");
3116     }
3117 
blend_func(&self, src: u32, dst: u32)3118     unsafe fn blend_func(&self, src: u32, dst: u32) {
3119         match self.raw {
3120             RawRenderingContext::WebGl1(ref gl) => gl.blend_func(src as u32, dst as u32),
3121             RawRenderingContext::WebGl2(ref gl) => gl.blend_func(src as u32, dst as u32),
3122         }
3123     }
3124 
blend_func_draw_buffer(&self, _draw_buffer: u32, _src: u32, _dst: u32)3125     unsafe fn blend_func_draw_buffer(&self, _draw_buffer: u32, _src: u32, _dst: u32) {
3126         panic!("Draw buffer blend func is not supported");
3127     }
3128 
blend_func_separate( &self, src_rgb: u32, dst_rgb: u32, src_alpha: u32, dst_alpha: u32, )3129     unsafe fn blend_func_separate(
3130         &self,
3131         src_rgb: u32,
3132         dst_rgb: u32,
3133         src_alpha: u32,
3134         dst_alpha: u32,
3135     ) {
3136         match self.raw {
3137             RawRenderingContext::WebGl1(ref gl) => gl.blend_func_separate(
3138                 src_rgb as u32,
3139                 dst_rgb as u32,
3140                 src_alpha as u32,
3141                 dst_alpha as u32,
3142             ),
3143             RawRenderingContext::WebGl2(ref gl) => gl.blend_func_separate(
3144                 src_rgb as u32,
3145                 dst_rgb as u32,
3146                 src_alpha as u32,
3147                 dst_alpha as u32,
3148             ),
3149         }
3150     }
3151 
blend_func_separate_draw_buffer( &self, _draw_buffer: u32, _src_rgb: u32, _dst_rgb: u32, _src_alpha: u32, _dst_alpha: u32, )3152     unsafe fn blend_func_separate_draw_buffer(
3153         &self,
3154         _draw_buffer: u32,
3155         _src_rgb: u32,
3156         _dst_rgb: u32,
3157         _src_alpha: u32,
3158         _dst_alpha: u32,
3159     ) {
3160         panic!("Draw buffer blend func separate is not supported");
3161     }
3162 
blend_equation(&self, mode: u32)3163     unsafe fn blend_equation(&self, mode: u32) {
3164         match self.raw {
3165             RawRenderingContext::WebGl1(ref gl) => gl.blend_equation(mode as u32),
3166             RawRenderingContext::WebGl2(ref gl) => gl.blend_equation(mode as u32),
3167         }
3168     }
3169 
blend_equation_draw_buffer(&self, _draw_buffer: u32, _mode: u32)3170     unsafe fn blend_equation_draw_buffer(&self, _draw_buffer: u32, _mode: u32) {
3171         panic!("Draw buffer blend equation is not supported");
3172     }
3173 
blend_equation_separate(&self, mode_rgb: u32, mode_alpha: u32)3174     unsafe fn blend_equation_separate(&self, mode_rgb: u32, mode_alpha: u32) {
3175         match self.raw {
3176             RawRenderingContext::WebGl1(ref gl) => {
3177                 gl.blend_equation_separate(mode_rgb as u32, mode_alpha as u32)
3178             }
3179             RawRenderingContext::WebGl2(ref gl) => {
3180                 gl.blend_equation_separate(mode_rgb as u32, mode_alpha as u32)
3181             }
3182         }
3183     }
3184 
blend_equation_separate_draw_buffer( &self, _draw_buffer: u32, _mode_rgb: u32, _mode_alpha: u32, )3185     unsafe fn blend_equation_separate_draw_buffer(
3186         &self,
3187         _draw_buffer: u32,
3188         _mode_rgb: u32,
3189         _mode_alpha: u32,
3190     ) {
3191         panic!("Draw buffer blend equation separate is not supported");
3192     }
3193 
stencil_func(&self, func: u32, reference: i32, mask: u32)3194     unsafe fn stencil_func(&self, func: u32, reference: i32, mask: u32) {
3195         match self.raw {
3196             RawRenderingContext::WebGl1(ref gl) => gl.stencil_func(func as u32, reference, mask),
3197             RawRenderingContext::WebGl2(ref gl) => gl.stencil_func(func as u32, reference, mask),
3198         }
3199     }
3200 
stencil_func_separate(&self, face: u32, func: u32, reference: i32, mask: u32)3201     unsafe fn stencil_func_separate(&self, face: u32, func: u32, reference: i32, mask: u32) {
3202         match self.raw {
3203             RawRenderingContext::WebGl1(ref gl) => {
3204                 gl.stencil_func_separate(face as u32, func as u32, reference, mask)
3205             }
3206             RawRenderingContext::WebGl2(ref gl) => {
3207                 gl.stencil_func_separate(face as u32, func as u32, reference, mask)
3208             }
3209         }
3210     }
3211 
stencil_mask(&self, mask: u32)3212     unsafe fn stencil_mask(&self, mask: u32) {
3213         match self.raw {
3214             RawRenderingContext::WebGl1(ref gl) => gl.stencil_mask(mask),
3215             RawRenderingContext::WebGl2(ref gl) => gl.stencil_mask(mask),
3216         }
3217     }
3218 
stencil_mask_separate(&self, face: u32, mask: u32)3219     unsafe fn stencil_mask_separate(&self, face: u32, mask: u32) {
3220         match self.raw {
3221             RawRenderingContext::WebGl1(ref gl) => gl.stencil_mask_separate(face as u32, mask),
3222             RawRenderingContext::WebGl2(ref gl) => gl.stencil_mask_separate(face as u32, mask),
3223         }
3224     }
3225 
stencil_op(&self, stencil_fail: u32, depth_fail: u32, pass: u32)3226     unsafe fn stencil_op(&self, stencil_fail: u32, depth_fail: u32, pass: u32) {
3227         match self.raw {
3228             RawRenderingContext::WebGl1(ref gl) => {
3229                 gl.stencil_op(stencil_fail as u32, depth_fail as u32, pass as u32)
3230             }
3231             RawRenderingContext::WebGl2(ref gl) => {
3232                 gl.stencil_op(stencil_fail as u32, depth_fail as u32, pass as u32)
3233             }
3234         }
3235     }
3236 
stencil_op_separate(&self, face: u32, stencil_fail: u32, depth_fail: u32, pass: u32)3237     unsafe fn stencil_op_separate(&self, face: u32, stencil_fail: u32, depth_fail: u32, pass: u32) {
3238         match self.raw {
3239             RawRenderingContext::WebGl1(ref gl) => gl.stencil_op_separate(
3240                 face as u32,
3241                 stencil_fail as u32,
3242                 depth_fail as u32,
3243                 pass as u32,
3244             ),
3245             RawRenderingContext::WebGl2(ref gl) => gl.stencil_op_separate(
3246                 face as u32,
3247                 stencil_fail as u32,
3248                 depth_fail as u32,
3249                 pass as u32,
3250             ),
3251         }
3252     }
3253 
debug_message_control( &self, _source: u32, _msg_type: u32, _severity: u32, _ids: &[u32], _enabled: bool, )3254     unsafe fn debug_message_control(
3255         &self,
3256         _source: u32,
3257         _msg_type: u32,
3258         _severity: u32,
3259         _ids: &[u32],
3260         _enabled: bool,
3261     ) {
3262         panic!("WebGL does not support the KHR_debug extension.")
3263     }
3264 
debug_message_insert<S>( &self, _source: u32, _msg_type: u32, _id: u32, _severity: u32, _msg: S, ) where S: AsRef<str>,3265     unsafe fn debug_message_insert<S>(
3266         &self,
3267         _source: u32,
3268         _msg_type: u32,
3269         _id: u32,
3270         _severity: u32,
3271         _msg: S,
3272     ) where
3273         S: AsRef<str>,
3274     {
3275         panic!("WebGL does not support the KHR_debug extension.")
3276     }
3277 
debug_message_callback<F>(&self, _callback: F) where F: FnMut(u32, u32, u32, u32, &str),3278     unsafe fn debug_message_callback<F>(&self, _callback: F)
3279     where
3280         F: FnMut(u32, u32, u32, u32, &str),
3281     {
3282         panic!("WebGL does not support the KHR_debug extension.")
3283     }
3284 
get_debug_message_log(&self, _count: u32) -> Vec<DebugMessageLogEntry>3285     unsafe fn get_debug_message_log(&self, _count: u32) -> Vec<DebugMessageLogEntry> {
3286         panic!("WebGL does not support the KHR_debug extension.")
3287     }
3288 
push_debug_group<S>(&self, _source: u32, _id: u32, _message: S) where S: AsRef<str>,3289     unsafe fn push_debug_group<S>(&self, _source: u32, _id: u32, _message: S)
3290     where
3291         S: AsRef<str>,
3292     {
3293         panic!("WebGL does not support the KHR_debug extension.")
3294     }
3295 
pop_debug_group(&self)3296     unsafe fn pop_debug_group(&self) {
3297         panic!("WebGL does not support the KHR_debug extension.")
3298     }
3299 
object_label<S>(&self, _identifier: u32, _name: u32, _label: Option<S>) where S: AsRef<str>,3300     unsafe fn object_label<S>(&self, _identifier: u32, _name: u32, _label: Option<S>)
3301     where
3302         S: AsRef<str>,
3303     {
3304         panic!("WebGL does not support the KHR_debug extension.")
3305     }
3306 
get_object_label(&self, _identifier: u32, _name: u32) -> String3307     unsafe fn get_object_label(&self, _identifier: u32, _name: u32) -> String {
3308         panic!("WebGL does not support the KHR_debug extension.")
3309     }
3310 
object_ptr_label<S>(&self, _sync: Self::Fence, _label: Option<S>) where S: AsRef<str>,3311     unsafe fn object_ptr_label<S>(&self, _sync: Self::Fence, _label: Option<S>)
3312     where
3313         S: AsRef<str>,
3314     {
3315         panic!("WebGL does not support the KHR_debug extension.")
3316     }
3317 
get_object_ptr_label(&self, _sync: Self::Fence) -> String3318     unsafe fn get_object_ptr_label(&self, _sync: Self::Fence) -> String {
3319         panic!("WebGL does not support the KHR_debug extension.")
3320     }
3321 
get_uniform_block_index(&self, program: Self::Program, name: &str) -> Option<u32>3322     unsafe fn get_uniform_block_index(&self, program: Self::Program, name: &str) -> Option<u32> {
3323         let programs = self.programs.borrow();
3324         let raw_program = programs.get_unchecked(program);
3325         let index = match self.raw {
3326             RawRenderingContext::WebGl1(ref _gl) => panic!("Uniform blocks are not supported"),
3327             RawRenderingContext::WebGl2(ref gl) => gl.get_uniform_block_index(raw_program, name),
3328         };
3329         if index == INVALID_INDEX {
3330             None
3331         } else {
3332             Some(index)
3333         }
3334     }
3335 
uniform_block_binding(&self, program: Self::Program, index: u32, binding: u32)3336     unsafe fn uniform_block_binding(&self, program: Self::Program, index: u32, binding: u32) {
3337         match self.raw {
3338             RawRenderingContext::WebGl1(ref _gl) => {
3339                 panic!("Uniform buffer bindings are not supported")
3340             }
3341             RawRenderingContext::WebGl2(ref gl) => {
3342                 let programs = self.programs.borrow();
3343                 let raw_program = programs.get_unchecked(program);
3344                 gl.uniform_block_binding(raw_program, index, binding);
3345             }
3346         }
3347     }
3348 
get_shader_storage_block_index( &self, _program: Self::Program, _name: &str, ) -> Option<u32>3349     unsafe fn get_shader_storage_block_index(
3350         &self,
3351         _program: Self::Program,
3352         _name: &str,
3353     ) -> Option<u32> {
3354         panic!("Shader Storage Buffers are not supported by webgl")
3355     }
3356 
shader_storage_block_binding( &self, _program: Self::Program, _index: u32, _binding: u32, )3357     unsafe fn shader_storage_block_binding(
3358         &self,
3359         _program: Self::Program,
3360         _index: u32,
3361         _binding: u32,
3362     ) {
3363         panic!("Shader Storage Buffers are not supported by webgl")
3364     }
3365 
read_buffer(&self, src: u32)3366     unsafe fn read_buffer(&self, src: u32) {
3367         match self.raw {
3368             RawRenderingContext::WebGl1(..) => panic!("read_buffer is not supported by WebGL1"),
3369             RawRenderingContext::WebGl2(ref gl) => gl.read_buffer(src),
3370         }
3371     }
3372 
read_pixels( &self, x: i32, y: i32, width: i32, height: i32, format: u32, gltype: u32, pixels: PixelPackData, )3373     unsafe fn read_pixels(
3374         &self,
3375         x: i32,
3376         y: i32,
3377         width: i32,
3378         height: i32,
3379         format: u32,
3380         gltype: u32,
3381         pixels: PixelPackData,
3382     ) {
3383         match pixels {
3384             PixelPackData::BufferOffset(offset) => match self.raw {
3385                 RawRenderingContext::WebGl1(ref gl) => {
3386                     panic!("Read pixels into buffer offset is not supported")
3387                 }
3388                 RawRenderingContext::WebGl2(ref gl) => gl
3389                     .read_pixels_with_i32(x, y, width, height, format, gltype, offset as i32)
3390                     .unwrap(),
3391             },
3392             PixelPackData::Slice(bytes) => {
3393                 let data = texture_data_view(gltype, bytes);
3394                 match self.raw {
3395                     RawRenderingContext::WebGl1(ref gl) => gl
3396                         .read_pixels_with_opt_array_buffer_view(
3397                             x,
3398                             y,
3399                             width,
3400                             height,
3401                             format,
3402                             gltype,
3403                             Some(&data),
3404                         )
3405                         .unwrap(),
3406                     RawRenderingContext::WebGl2(ref gl) => gl
3407                         .read_pixels_with_opt_array_buffer_view(
3408                             x,
3409                             y,
3410                             width,
3411                             height,
3412                             format,
3413                             gltype,
3414                             Some(&data),
3415                         )
3416                         .unwrap(),
3417                 }
3418             }
3419         }
3420     }
3421 
get_uniform_i32( &self, program: Self::Program, location: &Self::UniformLocation, v: &mut [i32], )3422     unsafe fn get_uniform_i32(
3423         &self,
3424         program: Self::Program,
3425         location: &Self::UniformLocation,
3426         v: &mut [i32],
3427     ) {
3428         let programs = self.programs.borrow();
3429         let raw_program = programs.get_unchecked(program);
3430         let value = match self.raw {
3431             RawRenderingContext::WebGl1(ref gl) => gl.get_uniform(&raw_program, location),
3432             RawRenderingContext::WebGl2(ref gl) => gl.get_uniform(&raw_program, location),
3433         };
3434         use wasm_bindgen::JsCast;
3435         if let Some(value) = value.as_f64() {
3436             v[0] = value as i32;
3437         } else if let Some(values) = value.dyn_ref::<js_sys::Int32Array>() {
3438             values.copy_to(v)
3439         }
3440     }
3441 
get_uniform_f32( &self, program: Self::Program, location: &Self::UniformLocation, v: &mut [f32], )3442     unsafe fn get_uniform_f32(
3443         &self,
3444         program: Self::Program,
3445         location: &Self::UniformLocation,
3446         v: &mut [f32],
3447     ) {
3448         let programs = self.programs.borrow();
3449         let raw_program = programs.get_unchecked(program);
3450         let value = match self.raw {
3451             RawRenderingContext::WebGl1(ref gl) => gl.get_uniform(&raw_program, location),
3452             RawRenderingContext::WebGl2(ref gl) => gl.get_uniform(&raw_program, location),
3453         };
3454         use wasm_bindgen::JsCast;
3455         if let Some(value) = value.as_f64() {
3456             v[0] = value as f32;
3457         } else if let Some(values) = value.dyn_ref::<js_sys::Float32Array>() {
3458             values.copy_to(v)
3459         }
3460     }
3461 
begin_query(&self, target: u32, query: Self::Query)3462     unsafe fn begin_query(&self, target: u32, query: Self::Query) {
3463         let queries = self.queries.borrow();
3464         let raw_query = queries.get_unchecked(query);
3465         match self.raw {
3466             RawRenderingContext::WebGl1(ref _gl) => panic!("Query objects are not supported"),
3467             RawRenderingContext::WebGl2(ref gl) => gl.begin_query(target, raw_query),
3468         }
3469     }
3470 
end_query(&self, target: u32)3471     unsafe fn end_query(&self, target: u32) {
3472         match self.raw {
3473             RawRenderingContext::WebGl1(ref _gl) => panic!("Query objects are not supported"),
3474             RawRenderingContext::WebGl2(ref gl) => gl.end_query(target),
3475         }
3476     }
3477 
get_query_parameter_u32(&self, query: Self::Query, parameter: u32) -> u323478     unsafe fn get_query_parameter_u32(&self, query: Self::Query, parameter: u32) -> u32 {
3479         let queries = self.queries.borrow();
3480         let raw_query = queries.get_unchecked(query);
3481         match self.raw {
3482             RawRenderingContext::WebGl1(ref _gl) => panic!("Query objects are not supported"),
3483             RawRenderingContext::WebGl2(ref gl) => gl
3484                 .get_query_parameter(raw_query, parameter)
3485                 .as_f64()
3486                 .map(|v| v as u32)
3487                 .unwrap_or(0),
3488         }
3489     }
3490 
create_transform_feedback(&self) -> Result<Self::TransformFeedback, String>3491     unsafe fn create_transform_feedback(&self) -> Result<Self::TransformFeedback, String> {
3492         let raw_transform_feedback = match self.raw {
3493             RawRenderingContext::WebGl1(ref _gl) => {
3494                 panic!("TransformFeedback objects are not supported")
3495             }
3496             RawRenderingContext::WebGl2(ref gl) => gl.create_transform_feedback(),
3497         };
3498 
3499         match raw_transform_feedback {
3500             Some(t) => {
3501                 let key = self.transform_feedbacks.borrow_mut().insert(t);
3502                 Ok(key)
3503             }
3504             None => Err(String::from("Unable to create TransformFeedback object")),
3505         }
3506     }
3507 
delete_transform_feedback(&self, transform_feedback: Self::TransformFeedback)3508     unsafe fn delete_transform_feedback(&self, transform_feedback: Self::TransformFeedback) {
3509         let mut transform_feedbacks = self.transform_feedbacks.borrow_mut();
3510         if let Some(ref t) = transform_feedbacks.remove(transform_feedback) {
3511             match self.raw {
3512                 RawRenderingContext::WebGl1(ref _gl) => {
3513                     panic!("TransformFeedback objects are not supported")
3514                 }
3515                 RawRenderingContext::WebGl2(ref gl) => gl.delete_transform_feedback(Some(t)),
3516             }
3517         }
3518     }
3519 
bind_transform_feedback( &self, target: u32, transform_feedback: Option<Self::TransformFeedback>, )3520     unsafe fn bind_transform_feedback(
3521         &self,
3522         target: u32,
3523         transform_feedback: Option<Self::TransformFeedback>,
3524     ) {
3525         let transform_feedbacks = self.transform_feedbacks.borrow();
3526         let raw_transform_feedback =
3527             transform_feedback.map(|tf| transform_feedbacks.get_unchecked(tf));
3528         match self.raw {
3529             RawRenderingContext::WebGl1(ref _gl) => {
3530                 panic!("TransformFeedback objects are not supported")
3531             }
3532             RawRenderingContext::WebGl2(ref gl) => {
3533                 gl.bind_transform_feedback(target, raw_transform_feedback)
3534             }
3535         }
3536     }
3537 
begin_transform_feedback(&self, primitive_mode: u32)3538     unsafe fn begin_transform_feedback(&self, primitive_mode: u32) {
3539         match self.raw {
3540             RawRenderingContext::WebGl1(ref _gl) => {
3541                 panic!("TransformFeedback objects are not supported")
3542             }
3543             RawRenderingContext::WebGl2(ref gl) => gl.begin_transform_feedback(primitive_mode),
3544         }
3545     }
3546 
end_transform_feedback(&self)3547     unsafe fn end_transform_feedback(&self) {
3548         match self.raw {
3549             RawRenderingContext::WebGl1(ref _gl) => {
3550                 panic!("TransformFeedback objects are not supported")
3551             }
3552             RawRenderingContext::WebGl2(ref gl) => gl.end_transform_feedback(),
3553         }
3554     }
3555 
pause_transform_feedback(&self)3556     unsafe fn pause_transform_feedback(&self) {
3557         match self.raw {
3558             RawRenderingContext::WebGl1(ref _gl) => {
3559                 panic!("TransformFeedback objects are not supported")
3560             }
3561             RawRenderingContext::WebGl2(ref gl) => gl.pause_transform_feedback(),
3562         }
3563     }
3564 
resume_transform_feedback(&self)3565     unsafe fn resume_transform_feedback(&self) {
3566         match self.raw {
3567             RawRenderingContext::WebGl1(ref _gl) => {
3568                 panic!("TransformFeedback objects are not supported")
3569             }
3570             RawRenderingContext::WebGl2(ref gl) => gl.resume_transform_feedback(),
3571         }
3572     }
3573 
transform_feedback_varyings( &self, program: Self::Program, varyings: &[&str], buffer_mode: u32, )3574     unsafe fn transform_feedback_varyings(
3575         &self,
3576         program: Self::Program,
3577         varyings: &[&str],
3578         buffer_mode: u32,
3579     ) {
3580         let programs = self.programs.borrow();
3581         let raw_program = programs.get_unchecked(program);
3582         match self.raw {
3583             RawRenderingContext::WebGl1(ref _gl) => {
3584                 panic!("TransformFeedback objects are not supported")
3585             }
3586             RawRenderingContext::WebGl2(ref gl) => {
3587                 let js_varyings = Array::new();
3588                 for &v in varyings {
3589                     js_varyings.push(&v.into());
3590                 }
3591                 gl.transform_feedback_varyings(raw_program, &js_varyings, buffer_mode);
3592             }
3593         }
3594     }
3595 
get_transform_feedback_varying( &self, program: Self::Program, index: u32, ) -> Option<ActiveTransformFeedback>3596     unsafe fn get_transform_feedback_varying(
3597         &self,
3598         program: Self::Program,
3599         index: u32,
3600     ) -> Option<ActiveTransformFeedback> {
3601         let programs = self.programs.borrow();
3602         let raw_program = programs.get_unchecked(program);
3603         match self.raw {
3604             RawRenderingContext::WebGl1(ref _gl) => {
3605                 panic!("TransformFeedback objects are not supported")
3606             }
3607             RawRenderingContext::WebGl2(ref gl) => gl
3608                 .get_transform_feedback_varying(raw_program, index)
3609                 .map(|info| ActiveTransformFeedback {
3610                     size: info.size(),
3611                     tftype: info.type_(),
3612                     name: info.name(),
3613                 }),
3614         }
3615     }
3616 
memory_barrier(&self, _barriers: u32)3617     unsafe fn memory_barrier(&self, _barriers: u32) {
3618         panic!("Memory barriers are not supported")
3619     }
3620 
memory_barrier_by_region(&self, _barriers: u32)3621     unsafe fn memory_barrier_by_region(&self, _barriers: u32) {
3622         panic!("Memory barriers are not supported")
3623     }
3624 
bind_image_texture( &self, _unit: u32, _texture: Self::Texture, _level: i32, _layered: bool, _layer: i32, _access: u32, _format: u32, )3625     unsafe fn bind_image_texture(
3626         &self,
3627         _unit: u32,
3628         _texture: Self::Texture,
3629         _level: i32,
3630         _layered: bool,
3631         _layer: i32,
3632         _access: u32,
3633         _format: u32,
3634     ) {
3635         panic!("Image load/store is not supported")
3636     }
3637 
get_active_uniform_block_parameter_i32( &self, program: Self::Program, uniform_block_index: u32, parameter: u32, ) -> i323638     unsafe fn get_active_uniform_block_parameter_i32(
3639         &self,
3640         program: Self::Program,
3641         uniform_block_index: u32,
3642         parameter: u32,
3643     ) -> i32 {
3644         let programs = self.programs.borrow();
3645         let raw_program = programs.get_unchecked(program);
3646 
3647         match self.raw {
3648             RawRenderingContext::WebGl1(ref _gl) => panic!("Uniform blocks are not supported"),
3649             RawRenderingContext::WebGl2(ref gl) => gl
3650                 .get_active_uniform_block_parameter(raw_program, uniform_block_index, parameter)
3651                 .unwrap()
3652                 .as_f64()
3653                 .map(|v| v as i32)
3654                 // Errors will be caught by the browser or through `get_error`
3655                 // so return a default instead
3656                 .unwrap_or(0),
3657         }
3658     }
3659 
get_active_uniform_block_parameter_i32_slice( &self, program: Self::Program, uniform_block_index: u32, parameter: u32, out: &mut [i32], )3660     unsafe fn get_active_uniform_block_parameter_i32_slice(
3661         &self,
3662         program: Self::Program,
3663         uniform_block_index: u32,
3664         parameter: u32,
3665         out: &mut [i32],
3666     ) {
3667         let programs = self.programs.borrow();
3668         let raw_program = programs.get_unchecked(program);
3669 
3670         match self.raw {
3671             RawRenderingContext::WebGl1(ref _gl) => panic!("Uniform blocks are not supported"),
3672             RawRenderingContext::WebGl2(ref gl) => {
3673                 let value = gl
3674                     .get_active_uniform_block_parameter(raw_program, uniform_block_index, parameter)
3675                     .unwrap();
3676 
3677                 use wasm_bindgen::JsCast;
3678                 if let Some(value) = value.as_f64() {
3679                     out[0] = value as i32;
3680                 } else if let Some(values) = value.dyn_ref::<js_sys::Uint32Array>() {
3681                     // To maintain compatibility with the pointers returned by
3682                     // desktop GL, which are signed, an extra copy is needed
3683                     // here.
3684                     values
3685                         .to_vec()
3686                         .into_iter()
3687                         .zip(out.iter_mut())
3688                         .for_each(|(val, target)| *target = val as i32)
3689                 }
3690             }
3691         }
3692     }
get_active_uniform_block_name( &self, program: Self::Program, uniform_block_index: u32, ) -> String3693     unsafe fn get_active_uniform_block_name(
3694         &self,
3695         program: Self::Program,
3696         uniform_block_index: u32,
3697     ) -> String {
3698         let programs = self.programs.borrow();
3699         let raw_program = programs.get_unchecked(program);
3700 
3701         match self.raw {
3702             RawRenderingContext::WebGl1(ref _gl) => panic!("Uniform blocks are not supported"),
3703             RawRenderingContext::WebGl2(ref gl) => gl
3704                 .get_active_uniform_block_name(raw_program, uniform_block_index)
3705                 .unwrap(),
3706         }
3707     }
3708 }
3709 
3710 /// Sending texture data requires different data views for different data types.
3711 /// This function reinterprets the byte data into the correct type for the texture.
3712 /// The lookup is generated from this table: https://www.khronos.org/registry/webgl/specs/latest/2.0/#TEXTURE_PIXELS_TYPE_TABLE
texture_data_view(ty: u32, bytes: &[u8]) -> js_sys::Object3713 unsafe fn texture_data_view(ty: u32, bytes: &[u8]) -> js_sys::Object {
3714     use std::mem::size_of;
3715     use std::slice::from_raw_parts;
3716 
3717     match ty {
3718         BYTE => {
3719             let data = from_raw_parts(bytes.as_ptr() as *const i8, bytes.len() / size_of::<i8>());
3720             js_sys::Int8Array::view(data).into()
3721         }
3722 
3723         SHORT => {
3724             #[allow(clippy::cast_ptr_alignment)]
3725             let data = from_raw_parts(bytes.as_ptr() as *const i16, bytes.len() / size_of::<i16>());
3726             js_sys::Int16Array::view(data).into()
3727         }
3728 
3729         UNSIGNED_SHORT
3730         | UNSIGNED_SHORT_5_6_5
3731         | UNSIGNED_SHORT_5_5_5_1
3732         | UNSIGNED_SHORT_4_4_4_4
3733         | HALF_FLOAT => {
3734             #[allow(clippy::cast_ptr_alignment)]
3735             let data = from_raw_parts(bytes.as_ptr() as *const u16, bytes.len() / size_of::<u16>());
3736             js_sys::Uint16Array::view(data).into()
3737         }
3738 
3739         INT => {
3740             #[allow(clippy::cast_ptr_alignment)]
3741             let data = from_raw_parts(bytes.as_ptr() as *const i32, bytes.len() / size_of::<i32>());
3742             js_sys::Int32Array::view(data).into()
3743         }
3744 
3745         UNSIGNED_INT
3746         | UNSIGNED_INT_5_9_9_9_REV
3747         | UNSIGNED_INT_2_10_10_10_REV
3748         | UNSIGNED_INT_10F_11F_11F_REV
3749         | UNSIGNED_INT_24_8 => {
3750             #[allow(clippy::cast_ptr_alignment)]
3751             let data = from_raw_parts(bytes.as_ptr() as *const u32, bytes.len() / size_of::<u32>());
3752             js_sys::Uint32Array::view(data).into()
3753         }
3754 
3755         FLOAT => {
3756             #[allow(clippy::cast_ptr_alignment)]
3757             let data = from_raw_parts(bytes.as_ptr() as *const f32, bytes.len() / size_of::<f32>());
3758             js_sys::Float32Array::view(data).into()
3759         }
3760 
3761         UNSIGNED_BYTE | _ => js_sys::Uint8Array::view(bytes).into(),
3762     }
3763 }
3764