1 // Copyright 2014 The Servo Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution.
3 //
4 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
5 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
6 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
7 // option. This file may not be copied, modified, or distributed
8 // except according to those terms.
9 
10 pub struct GlesFns {
11     ffi_gl_: GlesFfi,
12 }
13 
14 impl GlesFns {
load_with<'a, F>(loadfn: F) -> Rc<Gl> where F: FnMut(&str) -> *const c_void,15     pub unsafe fn load_with<'a, F>(loadfn: F) -> Rc<Gl>
16     where
17         F: FnMut(&str) -> *const c_void,
18     {
19         let ffi_gl_ = GlesFfi::load_with(loadfn);
20         Rc::new(GlesFns { ffi_gl_: ffi_gl_ }) as Rc<Gl>
21     }
22 }
23 
24 impl Gl for GlesFns {
get_type(&self) -> GlType25     fn get_type(&self) -> GlType {
26         GlType::Gles
27     }
28 
buffer_data_untyped( &self, target: GLenum, size: GLsizeiptr, data: *const GLvoid, usage: GLenum, )29     fn buffer_data_untyped(
30         &self,
31         target: GLenum,
32         size: GLsizeiptr,
33         data: *const GLvoid,
34         usage: GLenum,
35     ) {
36         unsafe {
37             self.ffi_gl_.BufferData(target, size, data, usage);
38         }
39     }
40 
tex_buffer(&self, _target: GLenum, _internal_format: GLenum, _buffer: GLuint)41     fn tex_buffer(&self, _target: GLenum, _internal_format: GLenum, _buffer: GLuint) {
42         panic!("not supported")
43     }
44 
buffer_sub_data_untyped( &self, target: GLenum, offset: isize, size: GLsizeiptr, data: *const GLvoid, )45     fn buffer_sub_data_untyped(
46         &self,
47         target: GLenum,
48         offset: isize,
49         size: GLsizeiptr,
50         data: *const GLvoid,
51     ) {
52         unsafe {
53             self.ffi_gl_.BufferSubData(target, offset, size, data);
54         }
55     }
56 
map_buffer(&self, _target: GLenum, _access: GLbitfield) -> *mut c_void57     fn map_buffer(&self,
58                   _target: GLenum,
59                   _access: GLbitfield) -> *mut c_void {
60         panic!("not supported")
61     }
62 
map_buffer_range(&self, target: GLenum, offset: GLintptr, length: GLsizeiptr, access: GLbitfield) -> *mut c_void63     fn map_buffer_range(&self,
64                         target: GLenum,
65                         offset: GLintptr,
66                         length: GLsizeiptr,
67                         access: GLbitfield) -> *mut c_void {
68         unsafe {
69             return self.ffi_gl_.MapBufferRange(target, offset, length, access);
70         }
71     }
72 
unmap_buffer(&self, target: GLenum) -> GLboolean73     fn unmap_buffer(&self, target: GLenum) -> GLboolean {
74         unsafe {
75             return self.ffi_gl_.UnmapBuffer(target);
76         }
77     }
78 
shader_source(&self, shader: GLuint, strings: &[&[u8]])79     fn shader_source(&self, shader: GLuint, strings: &[&[u8]]) {
80         let pointers: Vec<*const u8> = strings.iter().map(|string| (*string).as_ptr()).collect();
81         let lengths: Vec<GLint> = strings.iter().map(|string| string.len() as GLint).collect();
82         unsafe {
83             self.ffi_gl_.ShaderSource(
84                 shader,
85                 pointers.len() as GLsizei,
86                 pointers.as_ptr() as *const *const GLchar,
87                 lengths.as_ptr(),
88             );
89         }
90         drop(lengths);
91         drop(pointers);
92     }
93 
94     #[allow(unused_variables)]
read_buffer(&self, mode: GLenum)95     fn read_buffer(&self, mode: GLenum) {
96         panic!("not supported")
97     }
98 
read_pixels_into_buffer( &self, x: GLint, y: GLint, width: GLsizei, height: GLsizei, format: GLenum, pixel_type: GLenum, dst_buffer: &mut [u8], )99     fn read_pixels_into_buffer(
100         &self,
101         x: GLint,
102         y: GLint,
103         width: GLsizei,
104         height: GLsizei,
105         format: GLenum,
106         pixel_type: GLenum,
107         dst_buffer: &mut [u8],
108     ) {
109         // Assumes that the user properly allocated the size for dst_buffer.
110         assert!(calculate_length(width, height, format, pixel_type) == dst_buffer.len());
111 
112         unsafe {
113             // We don't want any alignment padding on pixel rows.
114             self.ffi_gl_.PixelStorei(ffi::PACK_ALIGNMENT, 1);
115             self.ffi_gl_.ReadPixels(
116                 x,
117                 y,
118                 width,
119                 height,
120                 format,
121                 pixel_type,
122                 dst_buffer.as_mut_ptr() as *mut c_void,
123             );
124         }
125     }
126 
read_pixels( &self, x: GLint, y: GLint, width: GLsizei, height: GLsizei, format: GLenum, pixel_type: GLenum, ) -> Vec<u8>127     fn read_pixels(
128         &self,
129         x: GLint,
130         y: GLint,
131         width: GLsizei,
132         height: GLsizei,
133         format: GLenum,
134         pixel_type: GLenum,
135     ) -> Vec<u8> {
136         let len = calculate_length(width, height, format, pixel_type);
137         let mut pixels: Vec<u8> = Vec::new();
138         pixels.reserve(len);
139         unsafe {
140             pixels.set_len(len);
141         }
142 
143         self.read_pixels_into_buffer(
144             x,
145             y,
146             width,
147             height,
148             format,
149             pixel_type,
150             pixels.as_mut_slice(),
151         );
152 
153         pixels
154     }
155 
read_pixels_into_pbo(&self, x: GLint, y: GLint, width: GLsizei, height: GLsizei, format: GLenum, pixel_type: GLenum)156     unsafe fn read_pixels_into_pbo(&self,
157                                    x: GLint,
158                                    y: GLint,
159                                    width: GLsizei,
160                                    height: GLsizei,
161                                    format: GLenum,
162                                    pixel_type: GLenum) {
163         self.ffi_gl_.ReadPixels(x, y, width, height, format, pixel_type, ptr::null_mut());
164     }
165 
sample_coverage(&self, value: GLclampf, invert: bool)166     fn sample_coverage(&self, value: GLclampf, invert: bool) {
167         unsafe {
168             self.ffi_gl_.SampleCoverage(value, invert as GLboolean);
169         }
170     }
171 
polygon_offset(&self, factor: GLfloat, units: GLfloat)172     fn polygon_offset(&self, factor: GLfloat, units: GLfloat) {
173         unsafe {
174             self.ffi_gl_.PolygonOffset(factor, units);
175         }
176     }
177 
pixel_store_i(&self, name: GLenum, param: GLint)178     fn pixel_store_i(&self, name: GLenum, param: GLint) {
179         unsafe {
180             self.ffi_gl_.PixelStorei(name, param);
181         }
182     }
183 
gen_buffers(&self, n: GLsizei) -> Vec<GLuint>184     fn gen_buffers(&self, n: GLsizei) -> Vec<GLuint> {
185         let mut result = vec![0 as GLuint; n as usize];
186         unsafe {
187             self.ffi_gl_.GenBuffers(n, result.as_mut_ptr());
188         }
189         result
190     }
191 
gen_renderbuffers(&self, n: GLsizei) -> Vec<GLuint>192     fn gen_renderbuffers(&self, n: GLsizei) -> Vec<GLuint> {
193         let mut result = vec![0 as GLuint; n as usize];
194         unsafe {
195             self.ffi_gl_.GenRenderbuffers(n, result.as_mut_ptr());
196         }
197         result
198     }
199 
gen_framebuffers(&self, n: GLsizei) -> Vec<GLuint>200     fn gen_framebuffers(&self, n: GLsizei) -> Vec<GLuint> {
201         let mut result = vec![0 as GLuint; n as usize];
202         unsafe {
203             self.ffi_gl_.GenFramebuffers(n, result.as_mut_ptr());
204         }
205         result
206     }
207 
gen_textures(&self, n: GLsizei) -> Vec<GLuint>208     fn gen_textures(&self, n: GLsizei) -> Vec<GLuint> {
209         let mut result = vec![0 as GLuint; n as usize];
210         unsafe {
211             self.ffi_gl_.GenTextures(n, result.as_mut_ptr());
212         }
213         result
214     }
215 
gen_vertex_arrays(&self, n: GLsizei) -> Vec<GLuint>216     fn gen_vertex_arrays(&self, n: GLsizei) -> Vec<GLuint> {
217         let mut result = vec![0 as GLuint; n as usize];
218         unsafe {
219             self.ffi_gl_.GenVertexArrays(n, result.as_mut_ptr());
220         }
221         result
222     }
223 
gen_queries(&self, n: GLsizei) -> Vec<GLuint>224     fn gen_queries(&self, n: GLsizei) -> Vec<GLuint> {
225         if !self.ffi_gl_.GenQueriesEXT.is_loaded() {
226             return Vec::new();
227         }
228         let mut result = vec![0 as GLuint; n as usize];
229         unsafe {
230             self.ffi_gl_.GenQueriesEXT(n, result.as_mut_ptr());
231         }
232         result
233     }
234 
begin_query(&self, target: GLenum, id: GLuint)235     fn begin_query(&self, target: GLenum, id: GLuint) {
236         if !self.ffi_gl_.BeginQueryEXT.is_loaded() {
237             return;
238         }
239         unsafe {
240             self.ffi_gl_.BeginQueryEXT(target, id);
241         }
242     }
243 
end_query(&self, target: GLenum)244     fn end_query(&self, target: GLenum) {
245         if !self.ffi_gl_.EndQueryEXT.is_loaded() {
246             return;
247         }
248         unsafe {
249             self.ffi_gl_.EndQueryEXT(target);
250         }
251     }
252 
query_counter(&self, id: GLuint, target: GLenum)253     fn query_counter(&self, id: GLuint, target: GLenum) {
254         if !self.ffi_gl_.QueryCounterEXT.is_loaded() {
255             return;
256         }
257         unsafe {
258             self.ffi_gl_.QueryCounterEXT(id, target);
259         }
260     }
261 
get_query_object_iv(&self, id: GLuint, pname: GLenum) -> i32262     fn get_query_object_iv(&self, id: GLuint, pname: GLenum) -> i32 {
263         if !self.ffi_gl_.GetQueryObjectivEXT.is_loaded() {
264             return 0;
265         }
266         let mut result = 0;
267         unsafe {
268             self.ffi_gl_.GetQueryObjectivEXT(id, pname, &mut result);
269         }
270         result
271     }
272 
get_query_object_uiv(&self, id: GLuint, pname: GLenum) -> u32273     fn get_query_object_uiv(&self, id: GLuint, pname: GLenum) -> u32 {
274         if !self.ffi_gl_.GetQueryObjectuivEXT.is_loaded() {
275             return 0;
276         }
277         let mut result = 0;
278         unsafe {
279             self.ffi_gl_.GetQueryObjectuivEXT(id, pname, &mut result);
280         }
281         result
282     }
283 
get_query_object_i64v(&self, id: GLuint, pname: GLenum) -> i64284     fn get_query_object_i64v(&self, id: GLuint, pname: GLenum) -> i64 {
285         if !self.ffi_gl_.GetQueryObjecti64vEXT.is_loaded() {
286             return 0;
287         }
288         let mut result = 0;
289         unsafe {
290             self.ffi_gl_.GetQueryObjecti64vEXT(id, pname, &mut result);
291         }
292         result
293     }
294 
get_query_object_ui64v(&self, id: GLuint, pname: GLenum) -> u64295     fn get_query_object_ui64v(&self, id: GLuint, pname: GLenum) -> u64 {
296         if !self.ffi_gl_.GetQueryObjectui64vEXT.is_loaded() {
297             return 0;
298         }
299         let mut result = 0;
300         unsafe {
301             self.ffi_gl_.GetQueryObjectui64vEXT(id, pname, &mut result);
302         }
303         result
304     }
305 
delete_queries(&self, queries: &[GLuint])306     fn delete_queries(&self, queries: &[GLuint]) {
307         if !self.ffi_gl_.DeleteQueriesEXT.is_loaded() {
308             return;
309         }
310         unsafe {
311             self.ffi_gl_
312                 .DeleteQueriesEXT(queries.len() as GLsizei, queries.as_ptr());
313         }
314     }
315 
delete_vertex_arrays(&self, vertex_arrays: &[GLuint])316     fn delete_vertex_arrays(&self, vertex_arrays: &[GLuint]) {
317         unsafe {
318             self.ffi_gl_
319                 .DeleteVertexArrays(vertex_arrays.len() as GLsizei, vertex_arrays.as_ptr());
320         }
321     }
322 
delete_buffers(&self, buffers: &[GLuint])323     fn delete_buffers(&self, buffers: &[GLuint]) {
324         unsafe {
325             self.ffi_gl_
326                 .DeleteBuffers(buffers.len() as GLsizei, buffers.as_ptr());
327         }
328     }
329 
delete_renderbuffers(&self, renderbuffers: &[GLuint])330     fn delete_renderbuffers(&self, renderbuffers: &[GLuint]) {
331         unsafe {
332             self.ffi_gl_
333                 .DeleteRenderbuffers(renderbuffers.len() as GLsizei, renderbuffers.as_ptr());
334         }
335     }
336 
delete_framebuffers(&self, framebuffers: &[GLuint])337     fn delete_framebuffers(&self, framebuffers: &[GLuint]) {
338         unsafe {
339             self.ffi_gl_
340                 .DeleteFramebuffers(framebuffers.len() as GLsizei, framebuffers.as_ptr());
341         }
342     }
343 
delete_textures(&self, textures: &[GLuint])344     fn delete_textures(&self, textures: &[GLuint]) {
345         unsafe {
346             self.ffi_gl_
347                 .DeleteTextures(textures.len() as GLsizei, textures.as_ptr());
348         }
349     }
350 
framebuffer_renderbuffer( &self, target: GLenum, attachment: GLenum, renderbuffertarget: GLenum, renderbuffer: GLuint, )351     fn framebuffer_renderbuffer(
352         &self,
353         target: GLenum,
354         attachment: GLenum,
355         renderbuffertarget: GLenum,
356         renderbuffer: GLuint,
357     ) {
358         unsafe {
359             self.ffi_gl_.FramebufferRenderbuffer(
360                 target,
361                 attachment,
362                 renderbuffertarget,
363                 renderbuffer,
364             );
365         }
366     }
367 
renderbuffer_storage( &self, target: GLenum, internalformat: GLenum, width: GLsizei, height: GLsizei, )368     fn renderbuffer_storage(
369         &self,
370         target: GLenum,
371         internalformat: GLenum,
372         width: GLsizei,
373         height: GLsizei,
374     ) {
375         unsafe {
376             self.ffi_gl_
377                 .RenderbufferStorage(target, internalformat, width, height);
378         }
379     }
380 
depth_func(&self, func: GLenum)381     fn depth_func(&self, func: GLenum) {
382         unsafe {
383             self.ffi_gl_.DepthFunc(func);
384         }
385     }
386 
active_texture(&self, texture: GLenum)387     fn active_texture(&self, texture: GLenum) {
388         unsafe {
389             self.ffi_gl_.ActiveTexture(texture);
390         }
391     }
392 
attach_shader(&self, program: GLuint, shader: GLuint)393     fn attach_shader(&self, program: GLuint, shader: GLuint) {
394         unsafe {
395             self.ffi_gl_.AttachShader(program, shader);
396         }
397     }
398 
bind_attrib_location(&self, program: GLuint, index: GLuint, name: &str)399     fn bind_attrib_location(&self, program: GLuint, index: GLuint, name: &str) {
400         let c_string = CString::new(name).unwrap();
401         unsafe {
402             self.ffi_gl_
403                 .BindAttribLocation(program, index, c_string.as_ptr())
404         }
405     }
406 
407     // https://www.khronos.org/registry/OpenGL-Refpages/es2.0/xhtml/glGetUniform.xml
get_uniform_iv(&self, program: GLuint, location: GLint, result: &mut [GLint])408     unsafe fn get_uniform_iv(&self, program: GLuint, location: GLint, result: &mut [GLint]) {
409         assert!(!result.is_empty());
410         self.ffi_gl_
411             .GetUniformiv(program, location, result.as_mut_ptr());
412     }
413 
414     // https://www.khronos.org/registry/OpenGL-Refpages/es2.0/xhtml/glGetUniform.xml
get_uniform_fv(&self, program: GLuint, location: GLint, result: &mut [GLfloat])415     unsafe fn get_uniform_fv(&self, program: GLuint, location: GLint, result: &mut [GLfloat]) {
416         assert!(!result.is_empty());
417         self.ffi_gl_
418             .GetUniformfv(program, location, result.as_mut_ptr());
419     }
420 
get_uniform_block_index(&self, program: GLuint, name: &str) -> GLuint421     fn get_uniform_block_index(&self, program: GLuint, name: &str) -> GLuint {
422         let c_string = CString::new(name).unwrap();
423         unsafe {
424             self.ffi_gl_
425                 .GetUniformBlockIndex(program, c_string.as_ptr())
426         }
427     }
428 
get_uniform_indices(&self, program: GLuint, names: &[&str]) -> Vec<GLuint>429     fn get_uniform_indices(&self, program: GLuint, names: &[&str]) -> Vec<GLuint> {
430         let c_strings: Vec<CString> = names.iter().map(|n| CString::new(*n).unwrap()).collect();
431         let pointers: Vec<*const GLchar> = c_strings.iter().map(|string| string.as_ptr()).collect();
432         let mut result = Vec::with_capacity(c_strings.len());
433         unsafe {
434             result.set_len(c_strings.len());
435             self.ffi_gl_.GetUniformIndices(
436                 program,
437                 pointers.len() as GLsizei,
438                 pointers.as_ptr(),
439                 result.as_mut_ptr(),
440             );
441         }
442         result
443     }
444 
bind_buffer_base(&self, target: GLenum, index: GLuint, buffer: GLuint)445     fn bind_buffer_base(&self, target: GLenum, index: GLuint, buffer: GLuint) {
446         unsafe {
447             self.ffi_gl_.BindBufferBase(target, index, buffer);
448         }
449     }
450 
bind_buffer_range( &self, target: GLenum, index: GLuint, buffer: GLuint, offset: GLintptr, size: GLsizeiptr, )451     fn bind_buffer_range(
452         &self,
453         target: GLenum,
454         index: GLuint,
455         buffer: GLuint,
456         offset: GLintptr,
457         size: GLsizeiptr,
458     ) {
459         unsafe {
460             self.ffi_gl_
461                 .BindBufferRange(target, index, buffer, offset, size);
462         }
463     }
464 
uniform_block_binding( &self, program: GLuint, uniform_block_index: GLuint, uniform_block_binding: GLuint, )465     fn uniform_block_binding(
466         &self,
467         program: GLuint,
468         uniform_block_index: GLuint,
469         uniform_block_binding: GLuint,
470     ) {
471         unsafe {
472             self.ffi_gl_
473                 .UniformBlockBinding(program, uniform_block_index, uniform_block_binding);
474         }
475     }
476 
bind_buffer(&self, target: GLenum, buffer: GLuint)477     fn bind_buffer(&self, target: GLenum, buffer: GLuint) {
478         unsafe {
479             self.ffi_gl_.BindBuffer(target, buffer);
480         }
481     }
482 
bind_vertex_array(&self, vao: GLuint)483     fn bind_vertex_array(&self, vao: GLuint) {
484         unsafe {
485             self.ffi_gl_.BindVertexArray(vao);
486         }
487     }
488 
bind_renderbuffer(&self, target: GLenum, renderbuffer: GLuint)489     fn bind_renderbuffer(&self, target: GLenum, renderbuffer: GLuint) {
490         unsafe {
491             self.ffi_gl_.BindRenderbuffer(target, renderbuffer);
492         }
493     }
494 
bind_framebuffer(&self, target: GLenum, framebuffer: GLuint)495     fn bind_framebuffer(&self, target: GLenum, framebuffer: GLuint) {
496         unsafe {
497             self.ffi_gl_.BindFramebuffer(target, framebuffer);
498         }
499     }
500 
bind_texture(&self, target: GLenum, texture: GLuint)501     fn bind_texture(&self, target: GLenum, texture: GLuint) {
502         unsafe {
503             self.ffi_gl_.BindTexture(target, texture);
504         }
505     }
506 
draw_buffers(&self, bufs: &[GLenum])507     fn draw_buffers(&self, bufs: &[GLenum]) {
508         unsafe {
509             self.ffi_gl_
510                 .DrawBuffers(bufs.len() as GLsizei, bufs.as_ptr());
511         }
512     }
513 
514     // FIXME: Does not verify buffer size -- unsafe!
tex_image_2d( &self, target: GLenum, level: GLint, internal_format: GLint, width: GLsizei, height: GLsizei, border: GLint, format: GLenum, ty: GLenum, opt_data: Option<&[u8]>, )515     fn tex_image_2d(
516         &self,
517         target: GLenum,
518         level: GLint,
519         internal_format: GLint,
520         width: GLsizei,
521         height: GLsizei,
522         border: GLint,
523         format: GLenum,
524         ty: GLenum,
525         opt_data: Option<&[u8]>,
526     ) {
527         match opt_data {
528             Some(data) => unsafe {
529                 self.ffi_gl_.TexImage2D(
530                     target,
531                     level,
532                     internal_format,
533                     width,
534                     height,
535                     border,
536                     format,
537                     ty,
538                     data.as_ptr() as *const GLvoid,
539                 );
540             },
541             None => unsafe {
542                 self.ffi_gl_.TexImage2D(
543                     target,
544                     level,
545                     internal_format,
546                     width,
547                     height,
548                     border,
549                     format,
550                     ty,
551                     ptr::null(),
552                 );
553             },
554         }
555     }
556 
compressed_tex_image_2d( &self, target: GLenum, level: GLint, internal_format: GLenum, width: GLsizei, height: GLsizei, border: GLint, data: &[u8], )557     fn compressed_tex_image_2d(
558         &self,
559         target: GLenum,
560         level: GLint,
561         internal_format: GLenum,
562         width: GLsizei,
563         height: GLsizei,
564         border: GLint,
565         data: &[u8],
566     ) {
567         unsafe {
568             self.ffi_gl_.CompressedTexImage2D(
569                 target,
570                 level,
571                 internal_format,
572                 width,
573                 height,
574                 border,
575                 data.len() as GLsizei,
576                 data.as_ptr() as *const GLvoid,
577             );
578         }
579     }
580 
compressed_tex_sub_image_2d( &self, target: GLenum, level: GLint, xoffset: GLint, yoffset: GLint, width: GLsizei, height: GLsizei, format: GLenum, data: &[u8], )581     fn compressed_tex_sub_image_2d(
582         &self,
583         target: GLenum,
584         level: GLint,
585         xoffset: GLint,
586         yoffset: GLint,
587         width: GLsizei,
588         height: GLsizei,
589         format: GLenum,
590         data: &[u8],
591     ) {
592         unsafe {
593             self.ffi_gl_.CompressedTexSubImage2D(
594                 target,
595                 level,
596                 xoffset,
597                 yoffset,
598                 width,
599                 height,
600                 format,
601                 data.len() as GLsizei,
602                 data.as_ptr() as *const GLvoid,
603             );
604         }
605     }
606 
607     // FIXME: Does not verify buffer size -- unsafe!
tex_image_3d( &self, target: GLenum, level: GLint, internal_format: GLint, width: GLsizei, height: GLsizei, depth: GLsizei, border: GLint, format: GLenum, ty: GLenum, opt_data: Option<&[u8]>, )608     fn tex_image_3d(
609         &self,
610         target: GLenum,
611         level: GLint,
612         internal_format: GLint,
613         width: GLsizei,
614         height: GLsizei,
615         depth: GLsizei,
616         border: GLint,
617         format: GLenum,
618         ty: GLenum,
619         opt_data: Option<&[u8]>,
620     ) {
621         unsafe {
622             let pdata = match opt_data {
623                 Some(data) => mem::transmute(data.as_ptr()),
624                 None => ptr::null(),
625             };
626             self.ffi_gl_.TexImage3D(
627                 target,
628                 level,
629                 internal_format,
630                 width,
631                 height,
632                 depth,
633                 border,
634                 format,
635                 ty,
636                 pdata,
637             );
638         }
639     }
640 
copy_tex_image_2d( &self, target: GLenum, level: GLint, internal_format: GLenum, x: GLint, y: GLint, width: GLsizei, height: GLsizei, border: GLint, )641     fn copy_tex_image_2d(
642         &self,
643         target: GLenum,
644         level: GLint,
645         internal_format: GLenum,
646         x: GLint,
647         y: GLint,
648         width: GLsizei,
649         height: GLsizei,
650         border: GLint,
651     ) {
652         unsafe {
653             self.ffi_gl_.CopyTexImage2D(
654                 target,
655                 level,
656                 internal_format,
657                 x,
658                 y,
659                 width,
660                 height,
661                 border,
662             );
663         }
664     }
665 
copy_tex_sub_image_2d( &self, target: GLenum, level: GLint, xoffset: GLint, yoffset: GLint, x: GLint, y: GLint, width: GLsizei, height: GLsizei, )666     fn copy_tex_sub_image_2d(
667         &self,
668         target: GLenum,
669         level: GLint,
670         xoffset: GLint,
671         yoffset: GLint,
672         x: GLint,
673         y: GLint,
674         width: GLsizei,
675         height: GLsizei,
676     ) {
677         unsafe {
678             self.ffi_gl_
679                 .CopyTexSubImage2D(target, level, xoffset, yoffset, x, y, width, height);
680         }
681     }
682 
copy_tex_sub_image_3d( &self, target: GLenum, level: GLint, xoffset: GLint, yoffset: GLint, zoffset: GLint, x: GLint, y: GLint, width: GLsizei, height: GLsizei, )683     fn copy_tex_sub_image_3d(
684         &self,
685         target: GLenum,
686         level: GLint,
687         xoffset: GLint,
688         yoffset: GLint,
689         zoffset: GLint,
690         x: GLint,
691         y: GLint,
692         width: GLsizei,
693         height: GLsizei,
694     ) {
695         unsafe {
696             self.ffi_gl_.CopyTexSubImage3D(
697                 target, level, xoffset, yoffset, zoffset, x, y, width, height,
698             );
699         }
700     }
701 
tex_sub_image_2d( &self, target: GLenum, level: GLint, xoffset: GLint, yoffset: GLint, width: GLsizei, height: GLsizei, format: GLenum, ty: GLenum, data: &[u8], )702     fn tex_sub_image_2d(
703         &self,
704         target: GLenum,
705         level: GLint,
706         xoffset: GLint,
707         yoffset: GLint,
708         width: GLsizei,
709         height: GLsizei,
710         format: GLenum,
711         ty: GLenum,
712         data: &[u8],
713     ) {
714         unsafe {
715             self.ffi_gl_.TexSubImage2D(
716                 target,
717                 level,
718                 xoffset,
719                 yoffset,
720                 width,
721                 height,
722                 format,
723                 ty,
724                 data.as_ptr() as *const c_void,
725             );
726         }
727     }
728 
tex_sub_image_2d_pbo( &self, target: GLenum, level: GLint, xoffset: GLint, yoffset: GLint, width: GLsizei, height: GLsizei, format: GLenum, ty: GLenum, offset: usize, )729     fn tex_sub_image_2d_pbo(
730         &self,
731         target: GLenum,
732         level: GLint,
733         xoffset: GLint,
734         yoffset: GLint,
735         width: GLsizei,
736         height: GLsizei,
737         format: GLenum,
738         ty: GLenum,
739         offset: usize,
740     ) {
741         unsafe {
742             self.ffi_gl_.TexSubImage2D(
743                 target,
744                 level,
745                 xoffset,
746                 yoffset,
747                 width,
748                 height,
749                 format,
750                 ty,
751                 offset as *const c_void,
752             );
753         }
754     }
755 
tex_sub_image_3d( &self, target: GLenum, level: GLint, xoffset: GLint, yoffset: GLint, zoffset: GLint, width: GLsizei, height: GLsizei, depth: GLsizei, format: GLenum, ty: GLenum, data: &[u8], )756     fn tex_sub_image_3d(
757         &self,
758         target: GLenum,
759         level: GLint,
760         xoffset: GLint,
761         yoffset: GLint,
762         zoffset: GLint,
763         width: GLsizei,
764         height: GLsizei,
765         depth: GLsizei,
766         format: GLenum,
767         ty: GLenum,
768         data: &[u8],
769     ) {
770         unsafe {
771             self.ffi_gl_.TexSubImage3D(
772                 target,
773                 level,
774                 xoffset,
775                 yoffset,
776                 zoffset,
777                 width,
778                 height,
779                 depth,
780                 format,
781                 ty,
782                 data.as_ptr() as *const c_void,
783             );
784         }
785     }
786 
tex_sub_image_3d_pbo( &self, target: GLenum, level: GLint, xoffset: GLint, yoffset: GLint, zoffset: GLint, width: GLsizei, height: GLsizei, depth: GLsizei, format: GLenum, ty: GLenum, offset: usize, )787     fn tex_sub_image_3d_pbo(
788         &self,
789         target: GLenum,
790         level: GLint,
791         xoffset: GLint,
792         yoffset: GLint,
793         zoffset: GLint,
794         width: GLsizei,
795         height: GLsizei,
796         depth: GLsizei,
797         format: GLenum,
798         ty: GLenum,
799         offset: usize,
800     ) {
801         unsafe {
802             self.ffi_gl_.TexSubImage3D(
803                 target,
804                 level,
805                 xoffset,
806                 yoffset,
807                 zoffset,
808                 width,
809                 height,
810                 depth,
811                 format,
812                 ty,
813                 offset as *const c_void,
814             );
815         }
816     }
817 
tex_storage_2d( &self, target: GLenum, levels: GLint, internal_format: GLenum, width: GLsizei, height: GLsizei, )818     fn tex_storage_2d(
819         &self,
820         target: GLenum,
821         levels: GLint,
822         internal_format: GLenum,
823         width: GLsizei,
824         height: GLsizei,
825     ) {
826         unsafe {
827             self.ffi_gl_
828                 .TexStorage2D(target, levels, internal_format, width, height);
829         }
830     }
831 
tex_storage_3d( &self, target: GLenum, levels: GLint, internal_format: GLenum, width: GLsizei, height: GLsizei, depth: GLsizei, )832     fn tex_storage_3d(
833         &self,
834         target: GLenum,
835         levels: GLint,
836         internal_format: GLenum,
837         width: GLsizei,
838         height: GLsizei,
839         depth: GLsizei,
840     ) {
841         unsafe {
842             self.ffi_gl_
843                 .TexStorage3D(target, levels, internal_format, width, height, depth);
844         }
845     }
846 
847     #[allow(unused_variables)]
get_tex_image_into_buffer( &self, target: GLenum, level: GLint, format: GLenum, ty: GLenum, output: &mut [u8], )848     fn get_tex_image_into_buffer(
849         &self,
850         target: GLenum,
851         level: GLint,
852         format: GLenum,
853         ty: GLenum,
854         output: &mut [u8],
855     ) {
856         panic!("not supported");
857     }
858 
copy_image_sub_data( &self, src_name: GLuint, src_target: GLenum, src_level: GLint, src_x: GLint, src_y: GLint, src_z: GLint, dst_name: GLuint, dst_target: GLenum, dst_level: GLint, dst_x: GLint, dst_y: GLint, dst_z: GLint, src_width: GLsizei, src_height: GLsizei, src_depth: GLsizei, )859     unsafe fn copy_image_sub_data(
860         &self,
861         src_name: GLuint,
862         src_target: GLenum,
863         src_level: GLint,
864         src_x: GLint,
865         src_y: GLint,
866         src_z: GLint,
867         dst_name: GLuint,
868         dst_target: GLenum,
869         dst_level: GLint,
870         dst_x: GLint,
871         dst_y: GLint,
872         dst_z: GLint,
873         src_width: GLsizei,
874         src_height: GLsizei,
875         src_depth: GLsizei,
876     ) {
877         self.ffi_gl_.CopyImageSubDataEXT(
878             src_name, src_target, src_level, src_x, src_y, src_z, dst_name, dst_target, dst_level,
879             dst_x, dst_y, dst_z, src_width, src_height, src_depth,
880         );
881     }
882 
invalidate_framebuffer(&self, target: GLenum, attachments: &[GLenum])883     fn invalidate_framebuffer(&self, target: GLenum, attachments: &[GLenum]) {
884         unsafe {
885             self.ffi_gl_.InvalidateFramebuffer(
886                 target,
887                 attachments.len() as GLsizei,
888                 attachments.as_ptr(),
889             );
890         }
891     }
892 
invalidate_sub_framebuffer( &self, target: GLenum, attachments: &[GLenum], xoffset: GLint, yoffset: GLint, width: GLsizei, height: GLsizei, )893     fn invalidate_sub_framebuffer(
894         &self,
895         target: GLenum,
896         attachments: &[GLenum],
897         xoffset: GLint,
898         yoffset: GLint,
899         width: GLsizei,
900         height: GLsizei,
901     ) {
902         unsafe {
903             self.ffi_gl_.InvalidateSubFramebuffer(
904                 target,
905                 attachments.len() as GLsizei,
906                 attachments.as_ptr(),
907                 xoffset,
908                 yoffset,
909                 width,
910                 height,
911             );
912         }
913     }
914 
915     #[inline]
get_integer_v(&self, name: GLenum, result: &mut [GLint])916     unsafe fn get_integer_v(&self, name: GLenum, result: &mut [GLint]) {
917         assert!(!result.is_empty());
918         self.ffi_gl_.GetIntegerv(name, result.as_mut_ptr());
919     }
920 
921     #[inline]
get_integer_64v(&self, name: GLenum, result: &mut [GLint64])922     unsafe fn get_integer_64v(&self, name: GLenum, result: &mut [GLint64]) {
923         assert!(!result.is_empty());
924         self.ffi_gl_.GetInteger64v(name, result.as_mut_ptr());
925     }
926 
927     #[inline]
get_integer_iv(&self, name: GLenum, index: GLuint, result: &mut [GLint])928     unsafe fn get_integer_iv(&self, name: GLenum, index: GLuint, result: &mut [GLint]) {
929         assert!(!result.is_empty());
930         self.ffi_gl_.GetIntegeri_v(name, index, result.as_mut_ptr());
931     }
932 
933     #[inline]
get_integer_64iv(&self, name: GLenum, index: GLuint, result: &mut [GLint64])934     unsafe fn get_integer_64iv(&self, name: GLenum, index: GLuint, result: &mut [GLint64]) {
935         assert!(!result.is_empty());
936         self.ffi_gl_
937             .GetInteger64i_v(name, index, result.as_mut_ptr());
938     }
939 
940     #[inline]
get_boolean_v(&self, name: GLenum, result: &mut [GLboolean])941     unsafe fn get_boolean_v(&self, name: GLenum, result: &mut [GLboolean]) {
942         assert!(!result.is_empty());
943         self.ffi_gl_.GetBooleanv(name, result.as_mut_ptr());
944     }
945 
946     #[inline]
get_float_v(&self, name: GLenum, result: &mut [GLfloat])947     unsafe fn get_float_v(&self, name: GLenum, result: &mut [GLfloat]) {
948         assert!(!result.is_empty());
949         self.ffi_gl_.GetFloatv(name, result.as_mut_ptr());
950     }
951 
get_renderbuffer_parameter_iv(&self, target: GLenum, pname: GLenum) -> GLint952     fn get_renderbuffer_parameter_iv(&self, target: GLenum, pname: GLenum) -> GLint {
953         let mut result: GLint = 0;
954         unsafe {
955             self.ffi_gl_
956                 .GetRenderbufferParameteriv(target, pname, &mut result);
957         }
958         result
959     }
960 
get_framebuffer_attachment_parameter_iv( &self, target: GLenum, attachment: GLenum, pname: GLenum, ) -> GLint961     fn get_framebuffer_attachment_parameter_iv(
962         &self,
963         target: GLenum,
964         attachment: GLenum,
965         pname: GLenum,
966     ) -> GLint {
967         let mut result: GLint = 0;
968         unsafe {
969             self.ffi_gl_.GetFramebufferAttachmentParameteriv(
970                 target,
971                 attachment,
972                 pname,
973                 &mut result,
974             );
975         }
976         result
977     }
978 
get_tex_parameter_iv(&self, target: GLenum, pname: GLenum) -> GLint979     fn get_tex_parameter_iv(&self, target: GLenum, pname: GLenum) -> GLint {
980         let mut result: GLint = 0;
981         unsafe {
982             self.ffi_gl_.GetTexParameteriv(target, pname, &mut result);
983         }
984         result
985     }
986 
get_tex_parameter_fv(&self, target: GLenum, pname: GLenum) -> GLfloat987     fn get_tex_parameter_fv(&self, target: GLenum, pname: GLenum) -> GLfloat {
988         let mut result: GLfloat = 0.0;
989         unsafe {
990             self.ffi_gl_.GetTexParameterfv(target, pname, &mut result);
991         }
992         result
993     }
994 
tex_parameter_i(&self, target: GLenum, pname: GLenum, param: GLint)995     fn tex_parameter_i(&self, target: GLenum, pname: GLenum, param: GLint) {
996         unsafe {
997             self.ffi_gl_.TexParameteri(target, pname, param);
998         }
999     }
1000 
tex_parameter_f(&self, target: GLenum, pname: GLenum, param: GLfloat)1001     fn tex_parameter_f(&self, target: GLenum, pname: GLenum, param: GLfloat) {
1002         unsafe {
1003             self.ffi_gl_.TexParameterf(target, pname, param);
1004         }
1005     }
1006 
framebuffer_texture_2d( &self, target: GLenum, attachment: GLenum, textarget: GLenum, texture: GLuint, level: GLint, )1007     fn framebuffer_texture_2d(
1008         &self,
1009         target: GLenum,
1010         attachment: GLenum,
1011         textarget: GLenum,
1012         texture: GLuint,
1013         level: GLint,
1014     ) {
1015         unsafe {
1016             self.ffi_gl_
1017                 .FramebufferTexture2D(target, attachment, textarget, texture, level);
1018         }
1019     }
1020 
framebuffer_texture_layer( &self, target: GLenum, attachment: GLenum, texture: GLuint, level: GLint, layer: GLint, )1021     fn framebuffer_texture_layer(
1022         &self,
1023         target: GLenum,
1024         attachment: GLenum,
1025         texture: GLuint,
1026         level: GLint,
1027         layer: GLint,
1028     ) {
1029         unsafe {
1030             self.ffi_gl_
1031                 .FramebufferTextureLayer(target, attachment, texture, level, layer);
1032         }
1033     }
1034 
blit_framebuffer( &self, src_x0: GLint, src_y0: GLint, src_x1: GLint, src_y1: GLint, dst_x0: GLint, dst_y0: GLint, dst_x1: GLint, dst_y1: GLint, mask: GLbitfield, filter: GLenum, )1035     fn blit_framebuffer(
1036         &self,
1037         src_x0: GLint,
1038         src_y0: GLint,
1039         src_x1: GLint,
1040         src_y1: GLint,
1041         dst_x0: GLint,
1042         dst_y0: GLint,
1043         dst_x1: GLint,
1044         dst_y1: GLint,
1045         mask: GLbitfield,
1046         filter: GLenum,
1047     ) {
1048         unsafe {
1049             self.ffi_gl_.BlitFramebuffer(
1050                 src_x0, src_y0, src_x1, src_y1, dst_x0, dst_y0, dst_x1, dst_y1, mask, filter,
1051             );
1052         }
1053     }
1054 
vertex_attrib_4f(&self, index: GLuint, x: GLfloat, y: GLfloat, z: GLfloat, w: GLfloat)1055     fn vertex_attrib_4f(&self, index: GLuint, x: GLfloat, y: GLfloat, z: GLfloat, w: GLfloat) {
1056         unsafe { self.ffi_gl_.VertexAttrib4f(index, x, y, z, w) }
1057     }
1058 
vertex_attrib_pointer_f32( &self, index: GLuint, size: GLint, normalized: bool, stride: GLsizei, offset: GLuint, )1059     fn vertex_attrib_pointer_f32(
1060         &self,
1061         index: GLuint,
1062         size: GLint,
1063         normalized: bool,
1064         stride: GLsizei,
1065         offset: GLuint,
1066     ) {
1067         unsafe {
1068             self.ffi_gl_.VertexAttribPointer(
1069                 index,
1070                 size,
1071                 ffi::FLOAT,
1072                 normalized as GLboolean,
1073                 stride,
1074                 offset as *const GLvoid,
1075             )
1076         }
1077     }
1078 
vertex_attrib_pointer( &self, index: GLuint, size: GLint, type_: GLenum, normalized: bool, stride: GLsizei, offset: GLuint, )1079     fn vertex_attrib_pointer(
1080         &self,
1081         index: GLuint,
1082         size: GLint,
1083         type_: GLenum,
1084         normalized: bool,
1085         stride: GLsizei,
1086         offset: GLuint,
1087     ) {
1088         unsafe {
1089             self.ffi_gl_.VertexAttribPointer(
1090                 index,
1091                 size,
1092                 type_,
1093                 normalized as GLboolean,
1094                 stride,
1095                 offset as *const GLvoid,
1096             )
1097         }
1098     }
1099 
vertex_attrib_i_pointer( &self, index: GLuint, size: GLint, type_: GLenum, stride: GLsizei, offset: GLuint, )1100     fn vertex_attrib_i_pointer(
1101         &self,
1102         index: GLuint,
1103         size: GLint,
1104         type_: GLenum,
1105         stride: GLsizei,
1106         offset: GLuint,
1107     ) {
1108         unsafe {
1109             self.ffi_gl_
1110                 .VertexAttribIPointer(index, size, type_, stride, offset as *const GLvoid)
1111         }
1112     }
1113 
vertex_attrib_divisor(&self, index: GLuint, divisor: GLuint)1114     fn vertex_attrib_divisor(&self, index: GLuint, divisor: GLuint) {
1115         unsafe { self.ffi_gl_.VertexAttribDivisor(index, divisor) }
1116     }
1117 
viewport(&self, x: GLint, y: GLint, width: GLsizei, height: GLsizei)1118     fn viewport(&self, x: GLint, y: GLint, width: GLsizei, height: GLsizei) {
1119         unsafe {
1120             self.ffi_gl_.Viewport(x, y, width, height);
1121         }
1122     }
1123 
scissor(&self, x: GLint, y: GLint, width: GLsizei, height: GLsizei)1124     fn scissor(&self, x: GLint, y: GLint, width: GLsizei, height: GLsizei) {
1125         unsafe {
1126             self.ffi_gl_.Scissor(x, y, width, height);
1127         }
1128     }
1129 
line_width(&self, width: GLfloat)1130     fn line_width(&self, width: GLfloat) {
1131         unsafe {
1132             self.ffi_gl_.LineWidth(width);
1133         }
1134     }
1135 
use_program(&self, program: GLuint)1136     fn use_program(&self, program: GLuint) {
1137         unsafe {
1138             self.ffi_gl_.UseProgram(program);
1139         }
1140     }
1141 
validate_program(&self, program: GLuint)1142     fn validate_program(&self, program: GLuint) {
1143         unsafe {
1144             self.ffi_gl_.ValidateProgram(program);
1145         }
1146     }
1147 
draw_arrays(&self, mode: GLenum, first: GLint, count: GLsizei)1148     fn draw_arrays(&self, mode: GLenum, first: GLint, count: GLsizei) {
1149         unsafe {
1150             return self.ffi_gl_.DrawArrays(mode, first, count);
1151         }
1152     }
1153 
draw_arrays_instanced( &self, mode: GLenum, first: GLint, count: GLsizei, primcount: GLsizei, )1154     fn draw_arrays_instanced(
1155         &self,
1156         mode: GLenum,
1157         first: GLint,
1158         count: GLsizei,
1159         primcount: GLsizei,
1160     ) {
1161         unsafe {
1162             return self
1163                 .ffi_gl_
1164                 .DrawArraysInstanced(mode, first, count, primcount);
1165         }
1166     }
1167 
draw_elements( &self, mode: GLenum, count: GLsizei, element_type: GLenum, indices_offset: GLuint, )1168     fn draw_elements(
1169         &self,
1170         mode: GLenum,
1171         count: GLsizei,
1172         element_type: GLenum,
1173         indices_offset: GLuint,
1174     ) {
1175         unsafe {
1176             return self.ffi_gl_.DrawElements(
1177                 mode,
1178                 count,
1179                 element_type,
1180                 indices_offset as *const c_void,
1181             );
1182         }
1183     }
1184 
draw_elements_instanced( &self, mode: GLenum, count: GLsizei, element_type: GLenum, indices_offset: GLuint, primcount: GLsizei, )1185     fn draw_elements_instanced(
1186         &self,
1187         mode: GLenum,
1188         count: GLsizei,
1189         element_type: GLenum,
1190         indices_offset: GLuint,
1191         primcount: GLsizei,
1192     ) {
1193         unsafe {
1194             return self.ffi_gl_.DrawElementsInstanced(
1195                 mode,
1196                 count,
1197                 element_type,
1198                 indices_offset as *const c_void,
1199                 primcount,
1200             );
1201         }
1202     }
1203 
blend_color(&self, r: f32, g: f32, b: f32, a: f32)1204     fn blend_color(&self, r: f32, g: f32, b: f32, a: f32) {
1205         unsafe {
1206             self.ffi_gl_.BlendColor(r, g, b, a);
1207         }
1208     }
1209 
blend_func(&self, sfactor: GLenum, dfactor: GLenum)1210     fn blend_func(&self, sfactor: GLenum, dfactor: GLenum) {
1211         unsafe {
1212             self.ffi_gl_.BlendFunc(sfactor, dfactor);
1213         }
1214     }
1215 
blend_func_separate( &self, src_rgb: GLenum, dest_rgb: GLenum, src_alpha: GLenum, dest_alpha: GLenum, )1216     fn blend_func_separate(
1217         &self,
1218         src_rgb: GLenum,
1219         dest_rgb: GLenum,
1220         src_alpha: GLenum,
1221         dest_alpha: GLenum,
1222     ) {
1223         unsafe {
1224             self.ffi_gl_
1225                 .BlendFuncSeparate(src_rgb, dest_rgb, src_alpha, dest_alpha);
1226         }
1227     }
1228 
blend_equation(&self, mode: GLenum)1229     fn blend_equation(&self, mode: GLenum) {
1230         unsafe {
1231             self.ffi_gl_.BlendEquation(mode);
1232         }
1233     }
1234 
blend_equation_separate(&self, mode_rgb: GLenum, mode_alpha: GLenum)1235     fn blend_equation_separate(&self, mode_rgb: GLenum, mode_alpha: GLenum) {
1236         unsafe {
1237             self.ffi_gl_.BlendEquationSeparate(mode_rgb, mode_alpha);
1238         }
1239     }
1240 
color_mask(&self, r: bool, g: bool, b: bool, a: bool)1241     fn color_mask(&self, r: bool, g: bool, b: bool, a: bool) {
1242         unsafe {
1243             self.ffi_gl_.ColorMask(
1244                 r as GLboolean,
1245                 g as GLboolean,
1246                 b as GLboolean,
1247                 a as GLboolean,
1248             );
1249         }
1250     }
1251 
cull_face(&self, mode: GLenum)1252     fn cull_face(&self, mode: GLenum) {
1253         unsafe {
1254             self.ffi_gl_.CullFace(mode);
1255         }
1256     }
1257 
front_face(&self, mode: GLenum)1258     fn front_face(&self, mode: GLenum) {
1259         unsafe {
1260             self.ffi_gl_.FrontFace(mode);
1261         }
1262     }
1263 
enable(&self, cap: GLenum)1264     fn enable(&self, cap: GLenum) {
1265         unsafe {
1266             self.ffi_gl_.Enable(cap);
1267         }
1268     }
1269 
disable(&self, cap: GLenum)1270     fn disable(&self, cap: GLenum) {
1271         unsafe {
1272             self.ffi_gl_.Disable(cap);
1273         }
1274     }
1275 
hint(&self, param_name: GLenum, param_val: GLenum)1276     fn hint(&self, param_name: GLenum, param_val: GLenum) {
1277         unsafe {
1278             self.ffi_gl_.Hint(param_name, param_val);
1279         }
1280     }
1281 
is_enabled(&self, cap: GLenum) -> GLboolean1282     fn is_enabled(&self, cap: GLenum) -> GLboolean {
1283         unsafe { self.ffi_gl_.IsEnabled(cap) }
1284     }
1285 
is_shader(&self, shader: GLuint) -> GLboolean1286     fn is_shader(&self, shader: GLuint) -> GLboolean {
1287         unsafe { self.ffi_gl_.IsShader(shader) }
1288     }
1289 
is_texture(&self, texture: GLenum) -> GLboolean1290     fn is_texture(&self, texture: GLenum) -> GLboolean {
1291         unsafe { self.ffi_gl_.IsTexture(texture) }
1292     }
1293 
is_framebuffer(&self, framebuffer: GLenum) -> GLboolean1294     fn is_framebuffer(&self, framebuffer: GLenum) -> GLboolean {
1295         unsafe { self.ffi_gl_.IsFramebuffer(framebuffer) }
1296     }
1297 
is_renderbuffer(&self, renderbuffer: GLenum) -> GLboolean1298     fn is_renderbuffer(&self, renderbuffer: GLenum) -> GLboolean {
1299         unsafe { self.ffi_gl_.IsRenderbuffer(renderbuffer) }
1300     }
1301 
check_frame_buffer_status(&self, target: GLenum) -> GLenum1302     fn check_frame_buffer_status(&self, target: GLenum) -> GLenum {
1303         unsafe { self.ffi_gl_.CheckFramebufferStatus(target) }
1304     }
1305 
enable_vertex_attrib_array(&self, index: GLuint)1306     fn enable_vertex_attrib_array(&self, index: GLuint) {
1307         unsafe {
1308             self.ffi_gl_.EnableVertexAttribArray(index);
1309         }
1310     }
1311 
disable_vertex_attrib_array(&self, index: GLuint)1312     fn disable_vertex_attrib_array(&self, index: GLuint) {
1313         unsafe {
1314             self.ffi_gl_.DisableVertexAttribArray(index);
1315         }
1316     }
1317 
uniform_1f(&self, location: GLint, v0: GLfloat)1318     fn uniform_1f(&self, location: GLint, v0: GLfloat) {
1319         unsafe {
1320             self.ffi_gl_.Uniform1f(location, v0);
1321         }
1322     }
1323 
uniform_1fv(&self, location: GLint, values: &[f32])1324     fn uniform_1fv(&self, location: GLint, values: &[f32]) {
1325         unsafe {
1326             self.ffi_gl_
1327                 .Uniform1fv(location, values.len() as GLsizei, values.as_ptr());
1328         }
1329     }
1330 
uniform_1i(&self, location: GLint, v0: GLint)1331     fn uniform_1i(&self, location: GLint, v0: GLint) {
1332         unsafe {
1333             self.ffi_gl_.Uniform1i(location, v0);
1334         }
1335     }
1336 
uniform_1iv(&self, location: GLint, values: &[i32])1337     fn uniform_1iv(&self, location: GLint, values: &[i32]) {
1338         unsafe {
1339             self.ffi_gl_
1340                 .Uniform1iv(location, values.len() as GLsizei, values.as_ptr());
1341         }
1342     }
1343 
1344     #[allow(unused_variables)]
uniform_1ui(&self, location: GLint, v0: GLuint)1345     fn uniform_1ui(&self, location: GLint, v0: GLuint) {
1346         panic!("not supported")
1347     }
1348 
uniform_2f(&self, location: GLint, v0: GLfloat, v1: GLfloat)1349     fn uniform_2f(&self, location: GLint, v0: GLfloat, v1: GLfloat) {
1350         unsafe {
1351             self.ffi_gl_.Uniform2f(location, v0, v1);
1352         }
1353     }
1354 
uniform_2fv(&self, location: GLint, values: &[f32])1355     fn uniform_2fv(&self, location: GLint, values: &[f32]) {
1356         unsafe {
1357             self.ffi_gl_
1358                 .Uniform2fv(location, (values.len() / 2) as GLsizei, values.as_ptr());
1359         }
1360     }
1361 
uniform_2i(&self, location: GLint, v0: GLint, v1: GLint)1362     fn uniform_2i(&self, location: GLint, v0: GLint, v1: GLint) {
1363         unsafe {
1364             self.ffi_gl_.Uniform2i(location, v0, v1);
1365         }
1366     }
1367 
uniform_2iv(&self, location: GLint, values: &[i32])1368     fn uniform_2iv(&self, location: GLint, values: &[i32]) {
1369         unsafe {
1370             self.ffi_gl_
1371                 .Uniform2iv(location, (values.len() / 2) as GLsizei, values.as_ptr());
1372         }
1373     }
1374 
1375     #[allow(unused_variables)]
uniform_2ui(&self, location: GLint, v0: GLuint, v1: GLuint)1376     fn uniform_2ui(&self, location: GLint, v0: GLuint, v1: GLuint) {
1377         panic!("not supported")
1378     }
1379 
uniform_3f(&self, location: GLint, v0: GLfloat, v1: GLfloat, v2: GLfloat)1380     fn uniform_3f(&self, location: GLint, v0: GLfloat, v1: GLfloat, v2: GLfloat) {
1381         unsafe {
1382             self.ffi_gl_.Uniform3f(location, v0, v1, v2);
1383         }
1384     }
1385 
uniform_3fv(&self, location: GLint, values: &[f32])1386     fn uniform_3fv(&self, location: GLint, values: &[f32]) {
1387         unsafe {
1388             self.ffi_gl_
1389                 .Uniform3fv(location, (values.len() / 3) as GLsizei, values.as_ptr());
1390         }
1391     }
1392 
uniform_3i(&self, location: GLint, v0: GLint, v1: GLint, v2: GLint)1393     fn uniform_3i(&self, location: GLint, v0: GLint, v1: GLint, v2: GLint) {
1394         unsafe {
1395             self.ffi_gl_.Uniform3i(location, v0, v1, v2);
1396         }
1397     }
1398 
uniform_3iv(&self, location: GLint, values: &[i32])1399     fn uniform_3iv(&self, location: GLint, values: &[i32]) {
1400         unsafe {
1401             self.ffi_gl_
1402                 .Uniform3iv(location, (values.len() / 3) as GLsizei, values.as_ptr());
1403         }
1404     }
1405 
1406     #[allow(unused_variables)]
uniform_3ui(&self, location: GLint, v0: GLuint, v1: GLuint, v2: GLuint)1407     fn uniform_3ui(&self, location: GLint, v0: GLuint, v1: GLuint, v2: GLuint) {
1408         panic!("not supported")
1409     }
1410 
uniform_4f(&self, location: GLint, x: GLfloat, y: GLfloat, z: GLfloat, w: GLfloat)1411     fn uniform_4f(&self, location: GLint, x: GLfloat, y: GLfloat, z: GLfloat, w: GLfloat) {
1412         unsafe {
1413             self.ffi_gl_.Uniform4f(location, x, y, z, w);
1414         }
1415     }
1416 
uniform_4i(&self, location: GLint, x: GLint, y: GLint, z: GLint, w: GLint)1417     fn uniform_4i(&self, location: GLint, x: GLint, y: GLint, z: GLint, w: GLint) {
1418         unsafe {
1419             self.ffi_gl_.Uniform4i(location, x, y, z, w);
1420         }
1421     }
1422 
uniform_4iv(&self, location: GLint, values: &[i32])1423     fn uniform_4iv(&self, location: GLint, values: &[i32]) {
1424         unsafe {
1425             self.ffi_gl_
1426                 .Uniform4iv(location, (values.len() / 4) as GLsizei, values.as_ptr());
1427         }
1428     }
1429 
1430     #[allow(unused_variables)]
uniform_4ui(&self, location: GLint, x: GLuint, y: GLuint, z: GLuint, w: GLuint)1431     fn uniform_4ui(&self, location: GLint, x: GLuint, y: GLuint, z: GLuint, w: GLuint) {
1432         panic!("not supported")
1433     }
1434 
uniform_4fv(&self, location: GLint, values: &[f32])1435     fn uniform_4fv(&self, location: GLint, values: &[f32]) {
1436         unsafe {
1437             self.ffi_gl_
1438                 .Uniform4fv(location, (values.len() / 4) as GLsizei, values.as_ptr());
1439         }
1440     }
1441 
uniform_matrix_2fv(&self, location: GLint, transpose: bool, value: &[f32])1442     fn uniform_matrix_2fv(&self, location: GLint, transpose: bool, value: &[f32]) {
1443         unsafe {
1444             self.ffi_gl_.UniformMatrix2fv(
1445                 location,
1446                 (value.len() / 4) as GLsizei,
1447                 transpose as GLboolean,
1448                 value.as_ptr(),
1449             );
1450         }
1451     }
1452 
uniform_matrix_3fv(&self, location: GLint, transpose: bool, value: &[f32])1453     fn uniform_matrix_3fv(&self, location: GLint, transpose: bool, value: &[f32]) {
1454         unsafe {
1455             self.ffi_gl_.UniformMatrix3fv(
1456                 location,
1457                 (value.len() / 9) as GLsizei,
1458                 transpose as GLboolean,
1459                 value.as_ptr(),
1460             );
1461         }
1462     }
1463 
uniform_matrix_4fv(&self, location: GLint, transpose: bool, value: &[f32])1464     fn uniform_matrix_4fv(&self, location: GLint, transpose: bool, value: &[f32]) {
1465         unsafe {
1466             self.ffi_gl_.UniformMatrix4fv(
1467                 location,
1468                 (value.len() / 16) as GLsizei,
1469                 transpose as GLboolean,
1470                 value.as_ptr(),
1471             );
1472         }
1473     }
1474 
depth_mask(&self, flag: bool)1475     fn depth_mask(&self, flag: bool) {
1476         unsafe {
1477             self.ffi_gl_.DepthMask(flag as GLboolean);
1478         }
1479     }
1480 
depth_range(&self, near: f64, far: f64)1481     fn depth_range(&self, near: f64, far: f64) {
1482         unsafe {
1483             self.ffi_gl_.DepthRangef(near as GLclampf, far as GLclampf);
1484         }
1485     }
1486 
get_active_attrib(&self, program: GLuint, index: GLuint) -> (i32, u32, String)1487     fn get_active_attrib(&self, program: GLuint, index: GLuint) -> (i32, u32, String) {
1488         let mut buf_size = [0];
1489         unsafe {
1490             self.get_program_iv(program, ffi::ACTIVE_ATTRIBUTE_MAX_LENGTH, &mut buf_size);
1491         }
1492         let mut name = vec![0u8; buf_size[0] as usize];
1493         let mut length = 0 as GLsizei;
1494         let mut size = 0 as i32;
1495         let mut type_ = 0 as u32;
1496         unsafe {
1497             self.ffi_gl_.GetActiveAttrib(
1498                 program,
1499                 index,
1500                 buf_size[0],
1501                 &mut length,
1502                 &mut size,
1503                 &mut type_,
1504                 name.as_mut_ptr() as *mut GLchar,
1505             );
1506         }
1507         name.truncate(if length > 0 { length as usize } else { 0 });
1508         (size, type_, String::from_utf8(name).unwrap())
1509     }
1510 
get_active_uniform(&self, program: GLuint, index: GLuint) -> (i32, u32, String)1511     fn get_active_uniform(&self, program: GLuint, index: GLuint) -> (i32, u32, String) {
1512         let mut buf_size = [0];
1513         unsafe {
1514             self.get_program_iv(program, ffi::ACTIVE_UNIFORM_MAX_LENGTH, &mut buf_size);
1515         }
1516         let mut name = vec![0 as u8; buf_size[0] as usize];
1517         let mut length: GLsizei = 0;
1518         let mut size: i32 = 0;
1519         let mut type_: u32 = 0;
1520 
1521         unsafe {
1522             self.ffi_gl_.GetActiveUniform(
1523                 program,
1524                 index,
1525                 buf_size[0],
1526                 &mut length,
1527                 &mut size,
1528                 &mut type_,
1529                 name.as_mut_ptr() as *mut GLchar,
1530             );
1531         }
1532 
1533         name.truncate(if length > 0 { length as usize } else { 0 });
1534 
1535         (size, type_, String::from_utf8(name).unwrap())
1536     }
1537 
get_active_uniforms_iv( &self, program: GLuint, indices: Vec<GLuint>, pname: GLenum, ) -> Vec<GLint>1538     fn get_active_uniforms_iv(
1539         &self,
1540         program: GLuint,
1541         indices: Vec<GLuint>,
1542         pname: GLenum,
1543     ) -> Vec<GLint> {
1544         let mut result = Vec::with_capacity(indices.len());
1545         unsafe {
1546             result.set_len(indices.len());
1547             self.ffi_gl_.GetActiveUniformsiv(
1548                 program,
1549                 indices.len() as GLsizei,
1550                 indices.as_ptr(),
1551                 pname,
1552                 result.as_mut_ptr(),
1553             );
1554         }
1555         result
1556     }
1557 
get_active_uniform_block_i(&self, program: GLuint, index: GLuint, pname: GLenum) -> GLint1558     fn get_active_uniform_block_i(&self, program: GLuint, index: GLuint, pname: GLenum) -> GLint {
1559         let mut result = 0 as GLint;
1560         unsafe {
1561             self.ffi_gl_
1562                 .GetActiveUniformBlockiv(program, index, pname, &mut result);
1563         }
1564         result
1565     }
1566 
get_active_uniform_block_iv( &self, program: GLuint, index: GLuint, pname: GLenum, ) -> Vec<GLint>1567     fn get_active_uniform_block_iv(
1568         &self,
1569         program: GLuint,
1570         index: GLuint,
1571         pname: GLenum,
1572     ) -> Vec<GLint> {
1573         let count =
1574             self.get_active_uniform_block_i(program, index, ffi::UNIFORM_BLOCK_ACTIVE_UNIFORMS);
1575         let mut result = Vec::with_capacity(count as usize);
1576         unsafe {
1577             result.set_len(count as usize);
1578             self.ffi_gl_
1579                 .GetActiveUniformBlockiv(program, index, pname, result.as_mut_ptr());
1580         }
1581         result
1582     }
1583 
get_active_uniform_block_name(&self, program: GLuint, index: GLuint) -> String1584     fn get_active_uniform_block_name(&self, program: GLuint, index: GLuint) -> String {
1585         let buf_size =
1586             self.get_active_uniform_block_i(program, index, ffi::UNIFORM_BLOCK_NAME_LENGTH);
1587         let mut name = vec![0 as u8; buf_size as usize];
1588         let mut length: GLsizei = 0;
1589         unsafe {
1590             self.ffi_gl_.GetActiveUniformBlockName(
1591                 program,
1592                 index,
1593                 buf_size,
1594                 &mut length,
1595                 name.as_mut_ptr() as *mut GLchar,
1596             );
1597         }
1598         name.truncate(if length > 0 { length as usize } else { 0 });
1599 
1600         String::from_utf8(name).unwrap()
1601     }
1602 
get_attrib_location(&self, program: GLuint, name: &str) -> c_int1603     fn get_attrib_location(&self, program: GLuint, name: &str) -> c_int {
1604         let name = CString::new(name).unwrap();
1605         unsafe { self.ffi_gl_.GetAttribLocation(program, name.as_ptr()) }
1606     }
1607 
1608     #[allow(unused_variables)]
get_frag_data_location(&self, program: GLuint, name: &str) -> c_int1609     fn get_frag_data_location(&self, program: GLuint, name: &str) -> c_int {
1610         panic!("not supported")
1611     }
1612 
get_uniform_location(&self, program: GLuint, name: &str) -> c_int1613     fn get_uniform_location(&self, program: GLuint, name: &str) -> c_int {
1614         let name = CString::new(name).unwrap();
1615         unsafe { self.ffi_gl_.GetUniformLocation(program, name.as_ptr()) }
1616     }
1617 
get_program_info_log(&self, program: GLuint) -> String1618     fn get_program_info_log(&self, program: GLuint) -> String {
1619         let mut max_len = [0];
1620         unsafe {
1621             self.get_program_iv(program, ffi::INFO_LOG_LENGTH, &mut max_len);
1622         }
1623         if max_len[0] == 0 {
1624             return String::new();
1625         }
1626         let mut result = vec![0u8; max_len[0] as usize];
1627         let mut result_len = 0 as GLsizei;
1628         unsafe {
1629             self.ffi_gl_.GetProgramInfoLog(
1630                 program,
1631                 max_len[0] as GLsizei,
1632                 &mut result_len,
1633                 result.as_mut_ptr() as *mut GLchar,
1634             );
1635         }
1636         result.truncate(if result_len > 0 {
1637             result_len as usize
1638         } else {
1639             0
1640         });
1641         String::from_utf8(result).unwrap()
1642     }
1643 
1644     #[inline]
get_program_iv(&self, program: GLuint, pname: GLenum, result: &mut [GLint])1645     unsafe fn get_program_iv(&self, program: GLuint, pname: GLenum, result: &mut [GLint]) {
1646         assert!(!result.is_empty());
1647         self.ffi_gl_
1648             .GetProgramiv(program, pname, result.as_mut_ptr());
1649     }
1650 
get_program_binary(&self, program: GLuint) -> (Vec<u8>, GLenum)1651     fn get_program_binary(&self, program: GLuint) -> (Vec<u8>, GLenum) {
1652         let mut len = [0];
1653         unsafe {
1654             self.get_program_iv(program, ffi::PROGRAM_BINARY_LENGTH, &mut len);
1655         }
1656         if len[0] <= 0 {
1657             return (Vec::new(), NONE);
1658         }
1659         let mut binary: Vec<u8> = Vec::with_capacity(len[0] as usize);
1660         let mut format = NONE;
1661         let mut out_len = 0;
1662         unsafe {
1663             binary.set_len(len[0] as usize);
1664             self.ffi_gl_.GetProgramBinary(
1665                 program,
1666                 len[0],
1667                 &mut out_len as *mut GLsizei,
1668                 &mut format,
1669                 binary.as_mut_ptr() as *mut c_void,
1670             );
1671         }
1672         if len[0] != out_len {
1673             return (Vec::new(), NONE);
1674         }
1675 
1676         (binary, format)
1677     }
1678 
program_binary(&self, program: GLuint, format: GLenum, binary: &[u8])1679     fn program_binary(&self, program: GLuint, format: GLenum, binary: &[u8]) {
1680         unsafe {
1681             self.ffi_gl_.ProgramBinary(
1682                 program,
1683                 format,
1684                 binary.as_ptr() as *const c_void,
1685                 binary.len() as GLsizei,
1686             );
1687         }
1688     }
1689 
program_parameter_i(&self, program: GLuint, pname: GLenum, value: GLint)1690     fn program_parameter_i(&self, program: GLuint, pname: GLenum, value: GLint) {
1691         unsafe {
1692             self.ffi_gl_.ProgramParameteri(program, pname, value);
1693         }
1694     }
1695 
1696     #[inline]
get_vertex_attrib_iv(&self, index: GLuint, pname: GLenum, result: &mut [GLint])1697     unsafe fn get_vertex_attrib_iv(&self, index: GLuint, pname: GLenum, result: &mut [GLint]) {
1698         assert!(!result.is_empty());
1699         self.ffi_gl_
1700             .GetVertexAttribiv(index, pname, result.as_mut_ptr());
1701     }
1702 
1703     #[inline]
get_vertex_attrib_fv(&self, index: GLuint, pname: GLenum, result: &mut [GLfloat])1704     unsafe fn get_vertex_attrib_fv(&self, index: GLuint, pname: GLenum, result: &mut [GLfloat]) {
1705         assert!(!result.is_empty());
1706         self.ffi_gl_
1707             .GetVertexAttribfv(index, pname, result.as_mut_ptr());
1708     }
1709 
get_vertex_attrib_pointer_v(&self, index: GLuint, pname: GLenum) -> GLsizeiptr1710     fn get_vertex_attrib_pointer_v(&self, index: GLuint, pname: GLenum) -> GLsizeiptr {
1711         let mut result = 0 as *mut GLvoid;
1712         unsafe {
1713             self.ffi_gl_
1714                 .GetVertexAttribPointerv(index, pname, &mut result)
1715         }
1716         result as GLsizeiptr
1717     }
1718 
get_buffer_parameter_iv(&self, target: GLuint, pname: GLenum) -> GLint1719     fn get_buffer_parameter_iv(&self, target: GLuint, pname: GLenum) -> GLint {
1720         let mut result = 0 as GLint;
1721         unsafe {
1722             self.ffi_gl_
1723                 .GetBufferParameteriv(target, pname, &mut result);
1724         }
1725         result
1726     }
1727 
get_shader_info_log(&self, shader: GLuint) -> String1728     fn get_shader_info_log(&self, shader: GLuint) -> String {
1729         let mut max_len = [0];
1730         unsafe {
1731             self.get_shader_iv(shader, ffi::INFO_LOG_LENGTH, &mut max_len);
1732         }
1733         if max_len[0] == 0 {
1734             return String::new();
1735         }
1736         let mut result = vec![0u8; max_len[0] as usize];
1737         let mut result_len = 0 as GLsizei;
1738         unsafe {
1739             self.ffi_gl_.GetShaderInfoLog(
1740                 shader,
1741                 max_len[0] as GLsizei,
1742                 &mut result_len,
1743                 result.as_mut_ptr() as *mut GLchar,
1744             );
1745         }
1746         result.truncate(if result_len > 0 {
1747             result_len as usize
1748         } else {
1749             0
1750         });
1751         String::from_utf8(result).unwrap()
1752     }
1753 
get_string(&self, which: GLenum) -> String1754     fn get_string(&self, which: GLenum) -> String {
1755         unsafe {
1756             let llstr = self.ffi_gl_.GetString(which);
1757             if !llstr.is_null() {
1758                 return str::from_utf8_unchecked(CStr::from_ptr(llstr as *const c_char).to_bytes())
1759                     .to_string();
1760             } else {
1761                 return "".to_string();
1762             }
1763         }
1764     }
1765 
get_string_i(&self, which: GLenum, index: GLuint) -> String1766     fn get_string_i(&self, which: GLenum, index: GLuint) -> String {
1767         unsafe {
1768             let llstr = self.ffi_gl_.GetStringi(which, index);
1769             if !llstr.is_null() {
1770                 str::from_utf8_unchecked(CStr::from_ptr(llstr as *const c_char).to_bytes())
1771                     .to_string()
1772             } else {
1773                 "".to_string()
1774             }
1775         }
1776     }
1777 
get_shader_iv(&self, shader: GLuint, pname: GLenum, result: &mut [GLint])1778     unsafe fn get_shader_iv(&self, shader: GLuint, pname: GLenum, result: &mut [GLint]) {
1779         assert!(!result.is_empty());
1780         self.ffi_gl_.GetShaderiv(shader, pname, result.as_mut_ptr());
1781     }
1782 
get_shader_precision_format( &self, shader_type: GLuint, precision_type: GLuint, ) -> (GLint, GLint, GLint)1783     fn get_shader_precision_format(
1784         &self,
1785         shader_type: GLuint,
1786         precision_type: GLuint,
1787     ) -> (GLint, GLint, GLint) {
1788         let (mut range, mut precision) = match precision_type {
1789             // These values are for a 32-bit twos-complement integer format.
1790             ffi::LOW_INT | ffi::MEDIUM_INT | ffi::HIGH_INT => ([31, 30], 0),
1791 
1792             // These values are for an IEEE single-precision floating-point format.
1793             ffi::LOW_FLOAT | ffi::MEDIUM_FLOAT | ffi::HIGH_FLOAT => ([127, 127], 23),
1794 
1795             _ => unreachable!("invalid precision"),
1796         };
1797         // This function is sometimes defined even though it's really just
1798         // a stub, so we need to set range and precision as if it weren't
1799         // defined before calling it. Suppress any error that might occur.
1800         unsafe {
1801             self.ffi_gl_.GetShaderPrecisionFormat(
1802                 shader_type,
1803                 precision_type,
1804                 range.as_mut_ptr(),
1805                 &mut precision,
1806             );
1807             let _ = self.ffi_gl_.GetError();
1808         }
1809 
1810         (range[0], range[1], precision)
1811     }
1812 
compile_shader(&self, shader: GLuint)1813     fn compile_shader(&self, shader: GLuint) {
1814         unsafe {
1815             self.ffi_gl_.CompileShader(shader);
1816         }
1817     }
1818 
create_program(&self) -> GLuint1819     fn create_program(&self) -> GLuint {
1820         unsafe {
1821             return self.ffi_gl_.CreateProgram();
1822         }
1823     }
1824 
delete_program(&self, program: GLuint)1825     fn delete_program(&self, program: GLuint) {
1826         unsafe {
1827             self.ffi_gl_.DeleteProgram(program);
1828         }
1829     }
1830 
create_shader(&self, shader_type: GLenum) -> GLuint1831     fn create_shader(&self, shader_type: GLenum) -> GLuint {
1832         unsafe {
1833             return self.ffi_gl_.CreateShader(shader_type);
1834         }
1835     }
1836 
delete_shader(&self, shader: GLuint)1837     fn delete_shader(&self, shader: GLuint) {
1838         unsafe {
1839             self.ffi_gl_.DeleteShader(shader);
1840         }
1841     }
1842 
detach_shader(&self, program: GLuint, shader: GLuint)1843     fn detach_shader(&self, program: GLuint, shader: GLuint) {
1844         unsafe {
1845             self.ffi_gl_.DetachShader(program, shader);
1846         }
1847     }
1848 
link_program(&self, program: GLuint)1849     fn link_program(&self, program: GLuint) {
1850         unsafe {
1851             return self.ffi_gl_.LinkProgram(program);
1852         }
1853     }
1854 
clear_color(&self, r: f32, g: f32, b: f32, a: f32)1855     fn clear_color(&self, r: f32, g: f32, b: f32, a: f32) {
1856         unsafe {
1857             self.ffi_gl_.ClearColor(r, g, b, a);
1858         }
1859     }
1860 
clear(&self, buffer_mask: GLbitfield)1861     fn clear(&self, buffer_mask: GLbitfield) {
1862         unsafe {
1863             self.ffi_gl_.Clear(buffer_mask);
1864         }
1865     }
1866 
clear_depth(&self, depth: f64)1867     fn clear_depth(&self, depth: f64) {
1868         unsafe {
1869             self.ffi_gl_.ClearDepthf(depth as GLclampf);
1870         }
1871     }
1872 
clear_stencil(&self, s: GLint)1873     fn clear_stencil(&self, s: GLint) {
1874         unsafe {
1875             self.ffi_gl_.ClearStencil(s);
1876         }
1877     }
1878 
flush(&self)1879     fn flush(&self) {
1880         unsafe {
1881             self.ffi_gl_.Flush();
1882         }
1883     }
1884 
finish(&self)1885     fn finish(&self) {
1886         unsafe {
1887             self.ffi_gl_.Finish();
1888         }
1889     }
1890 
get_error(&self) -> GLenum1891     fn get_error(&self) -> GLenum {
1892         unsafe { self.ffi_gl_.GetError() }
1893     }
1894 
stencil_mask(&self, mask: GLuint)1895     fn stencil_mask(&self, mask: GLuint) {
1896         unsafe { self.ffi_gl_.StencilMask(mask) }
1897     }
1898 
stencil_mask_separate(&self, face: GLenum, mask: GLuint)1899     fn stencil_mask_separate(&self, face: GLenum, mask: GLuint) {
1900         unsafe { self.ffi_gl_.StencilMaskSeparate(face, mask) }
1901     }
1902 
stencil_func(&self, func: GLenum, ref_: GLint, mask: GLuint)1903     fn stencil_func(&self, func: GLenum, ref_: GLint, mask: GLuint) {
1904         unsafe { self.ffi_gl_.StencilFunc(func, ref_, mask) }
1905     }
1906 
stencil_func_separate(&self, face: GLenum, func: GLenum, ref_: GLint, mask: GLuint)1907     fn stencil_func_separate(&self, face: GLenum, func: GLenum, ref_: GLint, mask: GLuint) {
1908         unsafe { self.ffi_gl_.StencilFuncSeparate(face, func, ref_, mask) }
1909     }
1910 
stencil_op(&self, sfail: GLenum, dpfail: GLenum, dppass: GLenum)1911     fn stencil_op(&self, sfail: GLenum, dpfail: GLenum, dppass: GLenum) {
1912         unsafe { self.ffi_gl_.StencilOp(sfail, dpfail, dppass) }
1913     }
1914 
stencil_op_separate(&self, face: GLenum, sfail: GLenum, dpfail: GLenum, dppass: GLenum)1915     fn stencil_op_separate(&self, face: GLenum, sfail: GLenum, dpfail: GLenum, dppass: GLenum) {
1916         unsafe { self.ffi_gl_.StencilOpSeparate(face, sfail, dpfail, dppass) }
1917     }
1918 
egl_image_target_texture2d_oes(&self, target: GLenum, image: GLeglImageOES)1919     fn egl_image_target_texture2d_oes(&self, target: GLenum, image: GLeglImageOES) {
1920         unsafe {
1921             self.ffi_gl_.EGLImageTargetTexture2DOES(target, image);
1922         }
1923     }
1924 
generate_mipmap(&self, target: GLenum)1925     fn generate_mipmap(&self, target: GLenum) {
1926         unsafe { self.ffi_gl_.GenerateMipmap(target) }
1927     }
1928 
insert_event_marker_ext(&self, message: &str)1929     fn insert_event_marker_ext(&self, message: &str) {
1930         if self.ffi_gl_.InsertEventMarkerEXT.is_loaded() {
1931             unsafe {
1932                 self.ffi_gl_
1933                     .InsertEventMarkerEXT(message.len() as GLsizei, message.as_ptr() as *const _);
1934             }
1935         }
1936     }
1937 
push_group_marker_ext(&self, message: &str)1938     fn push_group_marker_ext(&self, message: &str) {
1939         if self.ffi_gl_.PushGroupMarkerEXT.is_loaded() {
1940             unsafe {
1941                 self.ffi_gl_
1942                     .PushGroupMarkerEXT(message.len() as GLsizei, message.as_ptr() as *const _);
1943             }
1944         }
1945     }
1946 
pop_group_marker_ext(&self)1947     fn pop_group_marker_ext(&self) {
1948         if self.ffi_gl_.PopGroupMarkerEXT.is_loaded() {
1949             unsafe {
1950                 self.ffi_gl_.PopGroupMarkerEXT();
1951             }
1952         }
1953     }
1954 
debug_message_insert_khr(&self, source: GLenum, type_: GLenum, id: GLuint, severity: GLenum, message: &str)1955     fn debug_message_insert_khr(&self, source: GLenum, type_: GLenum, id: GLuint, severity: GLenum, message: &str) {
1956         if self.ffi_gl_.DebugMessageInsertKHR.is_loaded() {
1957             unsafe {
1958                 self.ffi_gl_
1959                     .DebugMessageInsertKHR(source, type_, id, severity, message.len() as GLsizei, message.as_ptr() as *const _);
1960             }
1961         }
1962     }
1963 
push_debug_group_khr(&self, source: GLenum, id: GLuint, message: &str)1964     fn push_debug_group_khr(&self, source: GLenum, id: GLuint, message: &str) {
1965         if self.ffi_gl_.PushDebugGroupKHR.is_loaded() {
1966             unsafe {
1967                 self.ffi_gl_
1968                     .PushDebugGroupKHR(source, id, message.len() as GLsizei, message.as_ptr() as *const _);
1969             }
1970         }
1971     }
1972 
pop_debug_group_khr(&self)1973     fn pop_debug_group_khr(&self) {
1974         if self.ffi_gl_.PopDebugGroupKHR.is_loaded() {
1975             unsafe {
1976                 self.ffi_gl_.PopDebugGroupKHR();
1977             }
1978         }
1979     }
1980 
fence_sync(&self, condition: GLenum, flags: GLbitfield) -> GLsync1981     fn fence_sync(&self, condition: GLenum, flags: GLbitfield) -> GLsync {
1982         unsafe { self.ffi_gl_.FenceSync(condition, flags) as *const _ }
1983     }
1984 
client_wait_sync(&self, sync: GLsync, flags: GLbitfield, timeout: GLuint64)1985     fn client_wait_sync(&self, sync: GLsync, flags: GLbitfield, timeout: GLuint64) {
1986         unsafe {
1987             self.ffi_gl_
1988                 .ClientWaitSync(sync as *const _, flags, timeout);
1989         }
1990     }
1991 
wait_sync(&self, sync: GLsync, flags: GLbitfield, timeout: GLuint64)1992     fn wait_sync(&self, sync: GLsync, flags: GLbitfield, timeout: GLuint64) {
1993         unsafe {
1994             self.ffi_gl_.WaitSync(sync as *const _, flags, timeout);
1995         }
1996     }
1997 
delete_sync(&self, sync: GLsync)1998     fn delete_sync(&self, sync: GLsync) {
1999         unsafe {
2000             self.ffi_gl_.DeleteSync(sync as *const _);
2001         }
2002     }
2003 
texture_range_apple(&self, _target: GLenum, _data: &[u8])2004     fn texture_range_apple(&self, _target: GLenum, _data: &[u8]) {
2005         panic!("not supported")
2006     }
2007 
gen_fences_apple(&self, _n: GLsizei) -> Vec<GLuint>2008     fn gen_fences_apple(&self, _n: GLsizei) -> Vec<GLuint> {
2009         panic!("not supported")
2010     }
2011 
delete_fences_apple(&self, _fences: &[GLuint])2012     fn delete_fences_apple(&self, _fences: &[GLuint]) {
2013         panic!("not supported")
2014     }
2015 
set_fence_apple(&self, _fence: GLuint)2016     fn set_fence_apple(&self, _fence: GLuint) {
2017         panic!("not supported")
2018     }
2019 
finish_fence_apple(&self, _fence: GLuint)2020     fn finish_fence_apple(&self, _fence: GLuint) {
2021         panic!("not supported")
2022     }
2023 
test_fence_apple(&self, _fence: GLuint)2024     fn test_fence_apple(&self, _fence: GLuint) {
2025         panic!("not supported")
2026     }
2027 
test_object_apple(&self, _object: GLenum, _name: GLuint) -> GLboolean2028     fn test_object_apple(&self, _object: GLenum, _name: GLuint) -> GLboolean {
2029         panic!("not supported")
2030     }
2031 
finish_object_apple(&self, _object: GLenum, _name: GLuint)2032     fn finish_object_apple(&self, _object: GLenum, _name: GLuint) {
2033         panic!("not supported")
2034     }
2035 
2036 
2037 
2038     // GL_ARB_blend_func_extended
bind_frag_data_location_indexed( &self, _program: GLuint, _color_number: GLuint, _index: GLuint, _name: &str, )2039     fn bind_frag_data_location_indexed(
2040         &self,
2041         _program: GLuint,
2042         _color_number: GLuint,
2043         _index: GLuint,
2044         _name: &str,
2045     ) {
2046         panic!("not supported");
2047     }
2048 
get_frag_data_index(&self, _program: GLuint, _name: &str) -> GLint2049     fn get_frag_data_index(&self, _program: GLuint, _name: &str) -> GLint {
2050         panic!("not supported");
2051     }
2052 
2053     // GL_KHR_debug
get_debug_messages(&self) -> Vec<DebugMessage>2054     fn get_debug_messages(&self) -> Vec<DebugMessage> {
2055         if !self.ffi_gl_.GetDebugMessageLog.is_loaded() {
2056             return Vec::new();
2057         }
2058 
2059         let mut max_message_len = 0;
2060         unsafe {
2061             self.ffi_gl_
2062                 .GetIntegerv(ffi::MAX_DEBUG_MESSAGE_LENGTH, &mut max_message_len)
2063         }
2064 
2065         let mut output = Vec::new();
2066         const CAPACITY: usize = 4;
2067 
2068         let mut msg_data = vec![0u8; CAPACITY * max_message_len as usize];
2069         let mut sources = [0 as GLenum; CAPACITY];
2070         let mut types = [0 as GLenum; CAPACITY];
2071         let mut severities = [0 as GLenum; CAPACITY];
2072         let mut ids = [0 as GLuint; CAPACITY];
2073         let mut lengths = [0 as GLsizei; CAPACITY];
2074 
2075         loop {
2076             let count = unsafe {
2077                 self.ffi_gl_.GetDebugMessageLog(
2078                     CAPACITY as _,
2079                     msg_data.len() as _,
2080                     sources.as_mut_ptr(),
2081                     types.as_mut_ptr(),
2082                     ids.as_mut_ptr(),
2083                     severities.as_mut_ptr(),
2084                     lengths.as_mut_ptr(),
2085                     msg_data.as_mut_ptr() as *mut _,
2086                 )
2087             };
2088 
2089             let mut offset = 0;
2090             output.extend((0..count as usize).map(|i| {
2091                 let len = lengths[i] as usize;
2092                 let slice = &msg_data[offset..offset + len];
2093                 offset += len;
2094                 DebugMessage {
2095                     message: String::from_utf8_lossy(slice).to_string(),
2096                     source: sources[i],
2097                     ty: types[i],
2098                     id: ids[i],
2099                     severity: severities[i],
2100                 }
2101             }));
2102 
2103             if (count as usize) < CAPACITY {
2104                 return output;
2105             }
2106         }
2107     }
2108 
provoking_vertex_angle(&self, mode: GLenum)2109     fn provoking_vertex_angle(&self, mode: GLenum) {
2110         unsafe {
2111             self.ffi_gl_.ProvokingVertexANGLE(mode);
2112         }
2113     }
2114 
2115     // GL_KHR_blend_equation_advanced
blend_barrier_khr(&self)2116     fn blend_barrier_khr(&self) {
2117         if self.ffi_gl_.BlendBarrierKHR.is_loaded() {
2118             unsafe {
2119                 self.ffi_gl_.BlendBarrierKHR();
2120             }
2121         }
2122     }
2123 }
2124