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 use std::mem;
11 use std::mem::size_of;
12 use std::os::raw::{c_char, c_int, c_void};
13 use std::ptr;
14 use std::rc::Rc;
15 use std::str;
16 use std::ffi::{CString, CStr};
17 use ffi;
18 
19 pub use ffi::types::*;
20 pub use ffi::*;
21 
22 pub use ffi_gl::Gl as GlFfi;
23 pub use ffi_gles::Gles2 as GlesFfi;
24 
25 #[derive(Debug, Eq, PartialEq)]
26 pub enum GlType {
27     Gl,
28     Gles,
29 }
30 
31 impl Default for GlType {
32     #[cfg(any(target_os="android", target_os="ios"))]
default() -> GlType33     fn default() -> GlType {
34         GlType::Gles
35     }
36     #[cfg(not(any(target_os="android", target_os="ios")))]
default() -> GlType37     fn default() -> GlType {
38         GlType::Gl
39     }
40 }
41 
calculate_length(width: GLsizei, height: GLsizei, format: GLenum, pixel_type: GLenum) -> usize42 fn calculate_length(width: GLsizei, height: GLsizei, format: GLenum, pixel_type: GLenum) -> usize {
43     let colors = match format {
44         ffi::RED => 1,
45         ffi::RGB => 3,
46         ffi::BGR => 3,
47 
48         ffi::RGBA => 4,
49         ffi::BGRA => 4,
50 
51         ffi::ALPHA => 1,
52         ffi::R16 => 1,
53         ffi::LUMINANCE => 1,
54         ffi::DEPTH_COMPONENT => 1,
55         _ => panic!("unsupported format for read_pixels: {:?}", format),
56     };
57     let depth = match pixel_type {
58         ffi::UNSIGNED_BYTE => 1,
59         ffi::UNSIGNED_SHORT => 2,
60         ffi::SHORT => 2,
61         ffi::FLOAT => 4,
62         _ => panic!("unsupported pixel_type for read_pixels: {:?}", pixel_type),
63     };
64 
65     return (width * height * colors * depth) as usize;
66 }
67 
68 pub struct DebugMessage {
69     pub message: String,
70     pub source: GLenum,
71     pub ty: GLenum,
72     pub id: GLenum,
73     pub severity: GLenum,
74 }
75 
76 macro_rules! declare_gl_apis {
77     // garbo is a hack to handle unsafe methods.
78     ($($(unsafe $([$garbo:expr])*)* fn $name:ident(&self $(, $arg:ident: $t:ty)* $(,)*) $(-> $retty:ty)* ;)+) => {
79         pub trait Gl {
80             $($(unsafe $($garbo)*)* fn $name(&self $(, $arg:$t)*) $(-> $retty)* ;)+
81         }
82 
83         impl Gl for ErrorCheckingGl {
84             $($(unsafe $($garbo)*)* fn $name(&self $(, $arg:$t)*) $(-> $retty)* {
85                 let rv = self.gl.$name($($arg,)*);
86                 assert_eq!(self.gl.get_error(), 0);
87                 rv
88             })+
89         }
90     }
91 }
92 
93 declare_gl_apis! {
94     fn get_type(&self) -> GlType;
95     fn buffer_data_untyped(&self,
96                             target: GLenum,
97                             size: GLsizeiptr,
98                             data: *const GLvoid,
99                             usage: GLenum);
100     fn buffer_sub_data_untyped(&self,
101                                 target: GLenum,
102                                 offset: isize,
103                                 size: GLsizeiptr,
104                                 data: *const GLvoid);
105     fn tex_buffer(&self, target: GLenum, internal_format: GLenum, buffer: GLuint);
106     fn shader_source(&self, shader: GLuint, strings: &[&[u8]]);
107     fn read_buffer(&self, mode: GLenum);
108     fn read_pixels_into_buffer(&self,
109                                 x: GLint,
110                                 y: GLint,
111                                 width: GLsizei,
112                                 height: GLsizei,
113                                 format: GLenum,
114                                 pixel_type: GLenum,
115                                 dst_buffer: &mut [u8]);
116     fn read_pixels(&self,
117                     x: GLint,
118                     y: GLint,
119                     width: GLsizei,
120                     height: GLsizei,
121                     format: GLenum,
122                     pixel_type: GLenum)
123                     -> Vec<u8>;
124     fn sample_coverage(&self, value: GLclampf, invert: bool);
125     fn polygon_offset(&self, factor: GLfloat, units: GLfloat);
126     fn pixel_store_i(&self, name: GLenum, param: GLint);
127     fn gen_buffers(&self, n: GLsizei) -> Vec<GLuint>;
128     fn gen_renderbuffers(&self, n: GLsizei) -> Vec<GLuint>;
129     fn gen_framebuffers(&self, n: GLsizei) -> Vec<GLuint>;
130     fn gen_textures(&self, n: GLsizei) -> Vec<GLuint>;
131     fn gen_vertex_arrays(&self, n: GLsizei) -> Vec<GLuint>;
132     fn gen_queries(&self, n: GLsizei) -> Vec<GLuint>;
133     fn begin_query(&self, target: GLenum, id: GLuint);
134     fn end_query(&self, target: GLenum);
135     fn query_counter(&self, id: GLuint, target: GLenum);
136     fn get_query_object_iv(&self, id: GLuint, pname: GLenum) -> i32;
137     fn get_query_object_uiv(&self, id: GLuint, pname: GLenum) -> u32;
138     fn get_query_object_i64v(&self, id: GLuint, pname: GLenum) -> i64;
139     fn get_query_object_ui64v(&self, id: GLuint, pname: GLenum) -> u64;
140     fn delete_queries(&self, queries: &[GLuint]);
141     fn delete_vertex_arrays(&self, vertex_arrays: &[GLuint]);
142     fn delete_buffers(&self, buffers: &[GLuint]);
143     fn delete_renderbuffers(&self, renderbuffers: &[GLuint]);
144     fn delete_framebuffers(&self, framebuffers: &[GLuint]);
145     fn delete_textures(&self, textures: &[GLuint]);
146     fn framebuffer_renderbuffer(&self,
147                                 target: GLenum,
148                                 attachment: GLenum,
149                                 renderbuffertarget: GLenum,
150                                 renderbuffer: GLuint);
151     fn renderbuffer_storage(&self,
152                             target: GLenum,
153                             internalformat: GLenum,
154                             width: GLsizei,
155                             height: GLsizei);
156     fn depth_func(&self, func: GLenum);
157     fn active_texture(&self, texture: GLenum);
158     fn attach_shader(&self, program: GLuint, shader: GLuint);
159     fn bind_attrib_location(&self, program: GLuint, index: GLuint, name: &str);
160     unsafe fn get_uniform_iv(&self, program: GLuint, location: GLint, result: &mut [GLint]);
161     unsafe fn get_uniform_fv(&self, program: GLuint, location: GLint, result: &mut [GLfloat]);
162     fn get_uniform_block_index(&self, program: GLuint, name: &str) -> GLuint;
163     fn get_uniform_indices(&self,  program: GLuint, names: &[&str]) -> Vec<GLuint>;
164     fn bind_buffer_base(&self, target: GLenum, index: GLuint, buffer: GLuint);
165     fn bind_buffer_range(&self, target: GLenum, index: GLuint, buffer: GLuint, offset: GLintptr, size: GLsizeiptr);
166     fn uniform_block_binding(&self,
167                                 program: GLuint,
168                                 uniform_block_index: GLuint,
169                                 uniform_block_binding: GLuint);
170     fn bind_buffer(&self, target: GLenum, buffer: GLuint);
171     fn bind_vertex_array(&self, vao: GLuint);
172     fn bind_renderbuffer(&self, target: GLenum, renderbuffer: GLuint);
173     fn bind_framebuffer(&self, target: GLenum, framebuffer: GLuint);
174     fn bind_texture(&self, target: GLenum, texture: GLuint);
175     fn draw_buffers(&self, bufs: &[GLenum]);
176     fn tex_image_2d(&self,
177                     target: GLenum,
178                     level: GLint,
179                     internal_format: GLint,
180                     width: GLsizei,
181                     height: GLsizei,
182                     border: GLint,
183                     format: GLenum,
184                     ty: GLenum,
185                     opt_data: Option<&[u8]>);
186     fn compressed_tex_image_2d(&self,
187                                 target: GLenum,
188                                 level: GLint,
189                                 internal_format: GLenum,
190                                 width: GLsizei,
191                                 height: GLsizei,
192                                 border: GLint,
193                                 data: &[u8]);
194     fn compressed_tex_sub_image_2d(&self,
195                                     target: GLenum,
196                                     level: GLint,
197                                     xoffset: GLint,
198                                     yoffset: GLint,
199                                     width: GLsizei,
200                                     height: GLsizei,
201                                     format: GLenum,
202                                     data: &[u8]);
203     fn tex_image_3d(&self,
204                     target: GLenum,
205                     level: GLint,
206                     internal_format: GLint,
207                     width: GLsizei,
208                     height: GLsizei,
209                     depth: GLsizei,
210                     border: GLint,
211                     format: GLenum,
212                     ty: GLenum,
213                     opt_data: Option<&[u8]>);
214     fn copy_tex_image_2d(&self,
215                             target: GLenum,
216                             level: GLint,
217                             internal_format: GLenum,
218                             x: GLint,
219                             y: GLint,
220                             width: GLsizei,
221                             height: GLsizei,
222                             border: GLint);
223     fn copy_tex_sub_image_2d(&self,
224                                 target: GLenum,
225                                 level: GLint,
226                                 xoffset: GLint,
227                                 yoffset: GLint,
228                                 x: GLint,
229                                 y: GLint,
230                                 width: GLsizei,
231                                 height: GLsizei);
232     fn copy_tex_sub_image_3d(&self,
233                                 target: GLenum,
234                                 level: GLint,
235                                 xoffset: GLint,
236                                 yoffset: GLint,
237                                 zoffset: GLint,
238                                 x: GLint,
239                                 y: GLint,
240                                 width: GLsizei,
241                                 height: GLsizei);
242     fn tex_sub_image_2d(&self,
243                         target: GLenum,
244                         level: GLint,
245                         xoffset: GLint,
246                         yoffset: GLint,
247                         width: GLsizei,
248                         height: GLsizei,
249                         format: GLenum,
250                         ty: GLenum,
251                         data: &[u8]);
252     fn tex_sub_image_2d_pbo(&self,
253                             target: GLenum,
254                             level: GLint,
255                             xoffset: GLint,
256                             yoffset: GLint,
257                             width: GLsizei,
258                             height: GLsizei,
259                             format: GLenum,
260                             ty: GLenum,
261                             offset: usize);
262     fn tex_sub_image_3d(&self,
263                         target: GLenum,
264                         level: GLint,
265                         xoffset: GLint,
266                         yoffset: GLint,
267                         zoffset: GLint,
268                         width: GLsizei,
269                         height: GLsizei,
270                         depth: GLsizei,
271                         format: GLenum,
272                         ty: GLenum,
273                         data: &[u8]);
274     fn tex_sub_image_3d_pbo(&self,
275                             target: GLenum,
276                             level: GLint,
277                             xoffset: GLint,
278                             yoffset: GLint,
279                             zoffset: GLint,
280                             width: GLsizei,
281                             height: GLsizei,
282                             depth: GLsizei,
283                             format: GLenum,
284                             ty: GLenum,
285                             offset: usize);
286     fn tex_storage_2d(&self,
287                       target: GLenum,
288                       levels: GLint,
289                       internal_format: GLenum,
290                       width: GLsizei,
291                       height: GLsizei);
292     fn tex_storage_3d(&self,
293                       target: GLenum,
294                       levels: GLint,
295                       internal_format: GLenum,
296                       width: GLsizei,
297                       height: GLsizei,
298                       depth: GLsizei);
299     fn get_tex_image_into_buffer(&self,
300                                 target: GLenum,
301                                 level: GLint,
302                                 format: GLenum,
303                                 ty: GLenum,
304                                 output: &mut [u8]);
305 
306     fn invalidate_framebuffer(&self,
307                               target: GLenum,
308                               attachments: &[GLenum]);
309     fn invalidate_sub_framebuffer(&self,
310                                   target: GLenum,
311                                   attachments: &[GLenum],
312                                   xoffset: GLint,
313                                   yoffset: GLint,
314                                   width: GLsizei,
315                                   height: GLsizei);
316 
317     unsafe fn get_integer_v(&self, name: GLenum, result: &mut [GLint]);
318     unsafe fn get_integer_64v(&self, name: GLenum, result: &mut [GLint64]);
319     unsafe fn get_integer_iv(&self, name: GLenum, index: GLuint, result: &mut [GLint]);
320     unsafe fn get_integer_64iv(&self, name: GLenum, index: GLuint, result: &mut [GLint64]);
321     unsafe fn get_boolean_v(&self, name: GLenum, result: &mut [GLboolean]);
322     unsafe fn get_float_v(&self, name: GLenum, result: &mut [GLfloat]);
323 
324     fn get_framebuffer_attachment_parameter_iv(&self,
325                                             target: GLenum,
326                                             attachment: GLenum,
327                                             pname: GLenum) -> GLint;
328     fn get_renderbuffer_parameter_iv(&self,
329                                      target: GLenum,
330                                      pname: GLenum) -> GLint;
331     fn get_tex_parameter_iv(&self, target: GLenum, name: GLenum) -> GLint;
332     fn get_tex_parameter_fv(&self, target: GLenum, name: GLenum) -> GLfloat;
333     fn tex_parameter_i(&self, target: GLenum, pname: GLenum, param: GLint);
334     fn tex_parameter_f(&self, target: GLenum, pname: GLenum, param: GLfloat);
335     fn framebuffer_texture_2d(&self,
336                                 target: GLenum,
337                                 attachment: GLenum,
338                                 textarget: GLenum,
339                                 texture: GLuint,
340                                 level: GLint);
341     fn framebuffer_texture_layer(&self,
342                                     target: GLenum,
343                                     attachment: GLenum,
344                                     texture: GLuint,
345                                     level: GLint,
346                                     layer: GLint);
347     fn blit_framebuffer(&self,
348                         src_x0: GLint,
349                         src_y0: GLint,
350                         src_x1: GLint,
351                         src_y1: GLint,
352                         dst_x0: GLint,
353                         dst_y0: GLint,
354                         dst_x1: GLint,
355                         dst_y1: GLint,
356                         mask: GLbitfield,
357                         filter: GLenum);
358     fn vertex_attrib_4f(&self, index: GLuint, x: GLfloat, y: GLfloat, z: GLfloat, w: GLfloat);
359     fn vertex_attrib_pointer_f32(&self,
360                                     index: GLuint,
361                                     size: GLint,
362                                     normalized: bool,
363                                     stride: GLsizei,
364                                     offset: GLuint);
365     fn vertex_attrib_pointer(&self,
366                             index: GLuint,
367                             size: GLint,
368                             type_: GLenum,
369                             normalized: bool,
370                             stride: GLsizei,
371                             offset: GLuint);
372     fn vertex_attrib_i_pointer(&self,
373                             index: GLuint,
374                             size: GLint,
375                             type_: GLenum,
376                             stride: GLsizei,
377                             offset: GLuint);
378     fn vertex_attrib_divisor(&self, index: GLuint, divisor: GLuint);
379     fn viewport(&self, x: GLint, y: GLint, width: GLsizei, height: GLsizei);
380     fn scissor(&self, x: GLint, y: GLint, width: GLsizei, height: GLsizei);
381     fn line_width(&self, width: GLfloat);
382     fn use_program(&self, program: GLuint);
383     fn validate_program(&self, program: GLuint);
384     fn draw_arrays(&self, mode: GLenum, first: GLint, count: GLsizei);
385     fn draw_arrays_instanced(&self,
386                             mode: GLenum,
387                             first: GLint,
388                             count: GLsizei,
389                             primcount: GLsizei);
390     fn draw_elements(&self,
391                     mode: GLenum,
392                     count: GLsizei,
393                     element_type: GLenum,
394                     indices_offset: GLuint);
395     fn draw_elements_instanced(&self,
396                             mode: GLenum,
397                             count: GLsizei,
398                             element_type: GLenum,
399                             indices_offset: GLuint,
400                             primcount: GLsizei);
401     fn blend_color(&self, r: f32, g: f32, b: f32, a: f32);
402     fn blend_func(&self, sfactor: GLenum, dfactor: GLenum);
403     fn blend_func_separate(&self,
404                         src_rgb: GLenum,
405                         dest_rgb: GLenum,
406                         src_alpha: GLenum,
407                         dest_alpha: GLenum);
408     fn blend_equation(&self, mode: GLenum);
409     fn blend_equation_separate(&self, mode_rgb: GLenum, mode_alpha: GLenum);
410     fn color_mask(&self, r: bool, g: bool, b: bool, a: bool);
411     fn cull_face(&self, mode: GLenum);
412     fn front_face(&self, mode: GLenum);
413     fn enable(&self, cap: GLenum);
414     fn disable(&self, cap: GLenum);
415     fn hint(&self, param_name: GLenum, param_val: GLenum);
416     fn is_enabled(&self, cap: GLenum) -> GLboolean;
417     fn is_shader(&self, shader: GLuint) -> GLboolean;
418     fn is_texture(&self, texture: GLenum) -> GLboolean;
419     fn is_framebuffer(&self, framebuffer: GLenum) -> GLboolean;
420     fn is_renderbuffer(&self, renderbuffer: GLenum) -> GLboolean;
421     fn check_frame_buffer_status(&self, target: GLenum) -> GLenum;
422     fn enable_vertex_attrib_array(&self, index: GLuint);
423     fn disable_vertex_attrib_array(&self, index: GLuint);
424     fn uniform_1f(&self, location: GLint, v0: GLfloat);
425     fn uniform_1fv(&self, location: GLint, values: &[f32]);
426     fn uniform_1i(&self, location: GLint, v0: GLint);
427     fn uniform_1iv(&self, location: GLint, values: &[i32]);
428     fn uniform_1ui(&self, location: GLint, v0: GLuint);
429     fn uniform_2f(&self, location: GLint, v0: GLfloat, v1: GLfloat);
430     fn uniform_2fv(&self, location: GLint, values: &[f32]);
431     fn uniform_2i(&self, location: GLint, v0: GLint, v1: GLint);
432     fn uniform_2iv(&self, location: GLint, values: &[i32]);
433     fn uniform_2ui(&self, location: GLint, v0: GLuint, v1: GLuint);
434     fn uniform_3f(&self, location: GLint, v0: GLfloat, v1: GLfloat, v2: GLfloat);
435     fn uniform_3fv(&self, location: GLint, values: &[f32]);
436     fn uniform_3i(&self, location: GLint, v0: GLint, v1: GLint, v2: GLint);
437     fn uniform_3iv(&self, location: GLint, values: &[i32]);
438     fn uniform_3ui(&self, location: GLint, v0: GLuint, v1: GLuint, v2: GLuint);
439     fn uniform_4f(&self, location: GLint, x: GLfloat, y: GLfloat, z: GLfloat, w: GLfloat);
440     fn uniform_4i(&self, location: GLint, x: GLint, y: GLint, z: GLint, w: GLint);
441     fn uniform_4iv(&self, location: GLint, values: &[i32]);
442     fn uniform_4ui(&self, location: GLint, x: GLuint, y: GLuint, z: GLuint, w: GLuint);
443     fn uniform_4fv(&self, location: GLint, values: &[f32]);
444     fn uniform_matrix_2fv(&self, location: GLint, transpose: bool, value: &[f32]);
445     fn uniform_matrix_3fv(&self, location: GLint, transpose: bool, value: &[f32]);
446     fn uniform_matrix_4fv(&self, location: GLint, transpose: bool, value: &[f32]);
447     fn depth_mask(&self, flag: bool);
448     fn depth_range(&self, near: f64, far: f64);
449     fn get_active_attrib(&self, program: GLuint, index: GLuint) -> (i32, u32, String);
450     fn get_active_uniform(&self, program: GLuint, index: GLuint) -> (i32, u32, String);
451     fn get_active_uniforms_iv(&self, program: GLuint, indices: Vec<GLuint>, pname: GLenum) -> Vec<GLint>;
452     fn get_active_uniform_block_i(&self, program: GLuint, index: GLuint, pname: GLenum) -> GLint;
453     fn get_active_uniform_block_iv(&self, program: GLuint, index: GLuint, pname: GLenum) -> Vec<GLint>;
454     fn get_active_uniform_block_name(&self, program: GLuint, index: GLuint) -> String;
455     fn get_attrib_location(&self, program: GLuint, name: &str) -> c_int;
456     fn get_frag_data_location(&self, program: GLuint, name: &str) -> c_int;
457     fn get_uniform_location(&self, program: GLuint, name: &str) -> c_int;
458     fn get_program_info_log(&self, program: GLuint) -> String;
459     unsafe fn get_program_iv(&self, program: GLuint, pname: GLenum, result: &mut [GLint]);
460     fn get_program_binary(&self, program: GLuint) -> (Vec<u8>, GLenum);
461     fn program_binary(&self, program: GLuint, format: GLenum, binary: &[u8]);
462     fn program_parameter_i(&self, program: GLuint, pname: GLenum, value: GLint);
463     unsafe fn get_vertex_attrib_iv(&self, index: GLuint, pname: GLenum, result: &mut [GLint]);
464     unsafe fn get_vertex_attrib_fv(&self, index: GLuint, pname: GLenum, result: &mut [GLfloat]);
465     fn get_vertex_attrib_pointer_v(&self, index: GLuint, pname: GLenum) -> GLsizeiptr;
466     fn get_buffer_parameter_iv(&self, target: GLuint, pname: GLenum) -> GLint;
467     fn get_shader_info_log(&self, shader: GLuint) -> String;
468     fn get_string(&self, which: GLenum) -> String;
469     fn get_string_i(&self, which: GLenum, index: GLuint) -> String;
470     unsafe fn get_shader_iv(&self, shader: GLuint, pname: GLenum, result: &mut [GLint]);
471     fn get_shader_precision_format(&self,
472                                 shader_type: GLuint,
473                                 precision_type: GLuint)
474                                 -> (GLint, GLint, GLint);
475     fn compile_shader(&self, shader: GLuint);
476     fn create_program(&self) -> GLuint;
477     fn delete_program(&self, program: GLuint);
478     fn create_shader(&self, shader_type: GLenum) -> GLuint;
479     fn delete_shader(&self, shader: GLuint);
480     fn detach_shader(&self, program: GLuint, shader: GLuint);
481     fn link_program(&self, program: GLuint);
482     fn clear_color(&self, r: f32, g: f32, b: f32, a: f32);
483     fn clear(&self, buffer_mask: GLbitfield);
484     fn clear_depth(&self, depth: f64);
485     fn clear_stencil(&self, s: GLint);
486     fn flush(&self);
487     fn finish(&self);
488     fn get_error(&self) -> GLenum;
489     fn stencil_mask(&self, mask: GLuint);
490     fn stencil_mask_separate(&self, face: GLenum, mask: GLuint);
491     fn stencil_func(&self, func: GLenum, ref_: GLint, mask: GLuint);
492     fn stencil_func_separate(&self, face: GLenum, func: GLenum, ref_: GLint, mask: GLuint);
493     fn stencil_op(&self, sfail: GLenum, dpfail: GLenum, dppass: GLenum);
494     fn stencil_op_separate(&self, face: GLenum, sfail: GLenum, dpfail: GLenum, dppass: GLenum);
495     fn egl_image_target_texture2d_oes(&self, target: GLenum, image: GLeglImageOES);
496     fn generate_mipmap(&self, target: GLenum);
497     fn insert_event_marker_ext(&self, message: &str);
498     fn push_group_marker_ext(&self, message: &str);
499     fn pop_group_marker_ext(&self);
500     fn fence_sync(&self, condition: GLenum, flags: GLbitfield) -> GLsync;
501     fn client_wait_sync(&self, sync: GLsync, flags: GLbitfield, timeout: GLuint64);
502     fn wait_sync(&self, sync: GLsync, flags: GLbitfield, timeout: GLuint64);
503     fn delete_sync(&self, sync: GLsync);
504     fn texture_range_apple(&self, target: GLenum, data: &[u8]);
505     fn gen_fences_apple(&self, n: GLsizei) -> Vec<GLuint>;
506     fn delete_fences_apple(&self, fences: &[GLuint]);
507     fn set_fence_apple(&self, fence: GLuint);
508     fn finish_fence_apple(&self, fence: GLuint);
509     fn test_fence_apple(&self, fence: GLuint);
510 
511     // GL_ARB_blend_func_extended
512     fn bind_frag_data_location_indexed(
513         &self,
514         program: GLuint,
515         color_number: GLuint,
516         index: GLuint,
517         name: &str,
518     );
519     fn get_frag_data_index(
520         &self,
521         program: GLuint,
522         name: &str,
523     ) -> GLint;
524 
525     // GL_KHR_debug
526     fn get_debug_messages(&self) -> Vec<DebugMessage>;
527 }
528 
529 pub struct ErrorCheckingGl {
530     gl: Rc<Gl>,
531 }
532 
533 impl ErrorCheckingGl {
wrap(fns: Rc<Gl>) -> Rc<Gl>534     pub fn wrap(fns: Rc<Gl>) -> Rc<Gl> {
535         Rc::new(ErrorCheckingGl { gl: fns }) as Rc<Gl>
536     }
537 }
538 
539 #[inline]
buffer_data<T>(gl_: &Gl, target: GLenum, data: &[T], usage: GLenum)540 pub fn buffer_data<T>(gl_: &Gl, target: GLenum, data: &[T], usage: GLenum) {
541     gl_.buffer_data_untyped(target,
542                             (data.len() * size_of::<T>()) as GLsizeiptr,
543                             data.as_ptr() as *const GLvoid,
544                             usage)
545 }
546 
547 #[inline]
buffer_data_raw<T>(gl_: &Gl, target: GLenum, data: &T, usage: GLenum)548 pub fn buffer_data_raw<T>(gl_: &Gl, target: GLenum, data: &T, usage: GLenum) {
549     gl_.buffer_data_untyped(target,
550                             size_of::<T>() as GLsizeiptr,
551                             data as *const T as *const GLvoid,
552                             usage)
553 }
554 
555 #[inline]
buffer_sub_data<T>(gl_: &Gl, target: GLenum, offset: isize, data: &[T])556 pub fn buffer_sub_data<T>(gl_: &Gl, target: GLenum, offset: isize, data: &[T]) {
557     gl_.buffer_sub_data_untyped(target,
558                                 offset,
559                                 (data.len() * size_of::<T>()) as GLsizeiptr,
560                                 data.as_ptr() as *const GLvoid);
561 }
562 
563 include!("gl_fns.rs");
564 include!("gles_fns.rs");
565