gleam/
gl.rs

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
10use ffi;
11use std::ffi::{CStr, CString};
12use std::mem;
13use std::mem::size_of;
14use std::os::raw::{c_char, c_int, c_void};
15use std::ptr;
16use std::rc::Rc;
17use std::str;
18use std::time::{Duration, Instant};
19
20pub use ffi::types::*;
21pub use ffi::*;
22
23pub use ffi_gl::Gl as GlFfi;
24pub use ffi_gles::Gles2 as GlesFfi;
25
26#[derive(Copy, Clone, Debug, Eq, PartialEq)]
27pub enum GlType {
28    Gl,
29    Gles,
30}
31
32impl Default for GlType {
33    #[cfg(any(target_os = "android", target_os = "ios"))]
34    fn default() -> GlType {
35        GlType::Gles
36    }
37    #[cfg(not(any(target_os = "android", target_os = "ios")))]
38    fn default() -> GlType {
39        GlType::Gl
40    }
41}
42
43fn bpp(format: GLenum, pixel_type: GLenum) -> GLsizei {
44    let colors = match format {
45        ffi::RED => 1,
46        ffi::RGB => 3,
47        ffi::BGR => 3,
48
49        ffi::RGBA => 4,
50        ffi::BGRA => 4,
51
52        ffi::ALPHA => 1,
53        ffi::R16 => 1,
54        ffi::LUMINANCE => 1,
55        ffi::DEPTH_COMPONENT => 1,
56        _ => panic!("unsupported format for read_pixels: {:?}", format),
57    };
58    let depth = match pixel_type {
59        ffi::UNSIGNED_BYTE => 1,
60        ffi::UNSIGNED_SHORT => 2,
61        ffi::SHORT => 2,
62        ffi::FLOAT => 4,
63        ffi::UNSIGNED_INT_8_8_8_8_REV => return 4,
64        _ => panic!("unsupported pixel_type for read_pixels: {:?}", pixel_type),
65    };
66    colors * depth
67}
68
69fn calculate_length(width: GLsizei, height: GLsizei, format: GLenum, pixel_type: GLenum) -> usize {
70    (width * height * bpp(format, pixel_type)) as usize
71}
72
73pub struct DebugMessage {
74    pub message: String,
75    pub source: GLenum,
76    pub ty: GLenum,
77    pub id: GLenum,
78    pub severity: GLenum,
79}
80
81macro_rules! declare_gl_apis {
82    // garbo is a hack to handle unsafe methods.
83    ($($(unsafe $([$garbo:expr])*)* fn $name:ident(&self $(, $arg:ident: $t:ty)* $(,)*) $(-> $retty:ty)* ;)+) => {
84        pub trait Gl {
85            $($(unsafe $($garbo)*)* fn $name(&self $(, $arg:$t)*) $(-> $retty)* ;)+
86        }
87
88        impl Gl for ErrorCheckingGl {
89            $($(unsafe $($garbo)*)* fn $name(&self $(, $arg:$t)*) $(-> $retty)* {
90                let rv = self.gl.$name($($arg,)*);
91                assert_eq!(self.gl.get_error(), 0);
92                rv
93            })+
94        }
95
96        impl<F: Fn(&dyn Gl, &str, GLenum)> Gl for ErrorReactingGl<F> {
97            $($(unsafe $($garbo)*)* fn $name(&self $(, $arg:$t)*) $(-> $retty)* {
98                let rv = self.gl.$name($($arg,)*);
99                let error = self.gl.get_error();
100                if error != 0 {
101                    (self.callback)(&*self.gl, stringify!($name), error);
102                }
103                rv
104            })+
105        }
106
107        impl<F: Fn(&str, Duration)> Gl for ProfilingGl<F> {
108            $($(unsafe $($garbo)*)* fn $name(&self $(, $arg:$t)*) $(-> $retty)* {
109                let start = Instant::now();
110                let rv = self.gl.$name($($arg,)*);
111                let duration = Instant::now() - start;
112                if duration > self.threshold {
113                    (self.callback)(stringify!($name), duration);
114                }
115                rv
116            })+
117        }
118    }
119}
120
121declare_gl_apis! {
122    fn get_type(&self) -> GlType;
123    fn buffer_data_untyped(
124        &self,
125        target: GLenum,
126        size: GLsizeiptr,
127        data: *const GLvoid,
128        usage: GLenum,
129    );
130    fn buffer_sub_data_untyped(
131        &self,
132        target: GLenum,
133        offset: isize,
134        size: GLsizeiptr,
135        data: *const GLvoid,
136    );
137    fn map_buffer(&self, target: GLenum, access: GLbitfield) -> *mut c_void;
138    fn map_buffer_range(
139        &self,
140        target: GLenum,
141        offset: GLintptr,
142        length: GLsizeiptr,
143        access: GLbitfield,
144    ) -> *mut c_void;
145    fn unmap_buffer(&self, target: GLenum) -> GLboolean;
146    fn tex_buffer(&self, target: GLenum, internal_format: GLenum, buffer: GLuint);
147    fn shader_source(&self, shader: GLuint, strings: &[&[u8]]);
148    fn read_buffer(&self, mode: GLenum);
149    fn read_pixels_into_buffer(
150        &self,
151        x: GLint,
152        y: GLint,
153        width: GLsizei,
154        height: GLsizei,
155        format: GLenum,
156        pixel_type: GLenum,
157        dst_buffer: &mut [u8],
158    );
159    fn read_pixels(
160        &self,
161        x: GLint,
162        y: GLint,
163        width: GLsizei,
164        height: GLsizei,
165        format: GLenum,
166        pixel_type: GLenum,
167    ) -> Vec<u8>;
168    unsafe fn read_pixels_into_pbo(
169        &self,
170        x: GLint,
171        y: GLint,
172        width: GLsizei,
173        height: GLsizei,
174        format: GLenum,
175        pixel_type: GLenum,
176    );
177    fn sample_coverage(&self, value: GLclampf, invert: bool);
178    fn polygon_offset(&self, factor: GLfloat, units: GLfloat);
179    fn pixel_store_i(&self, name: GLenum, param: GLint);
180    fn gen_buffers(&self, n: GLsizei) -> Vec<GLuint>;
181    fn gen_renderbuffers(&self, n: GLsizei) -> Vec<GLuint>;
182    fn gen_framebuffers(&self, n: GLsizei) -> Vec<GLuint>;
183    fn gen_textures(&self, n: GLsizei) -> Vec<GLuint>;
184    fn gen_vertex_arrays(&self, n: GLsizei) -> Vec<GLuint>;
185    fn gen_vertex_arrays_apple(&self, n: GLsizei) -> Vec<GLuint>;
186    fn gen_queries(&self, n: GLsizei) -> Vec<GLuint>;
187    fn begin_query(&self, target: GLenum, id: GLuint);
188    fn end_query(&self, target: GLenum);
189    fn query_counter(&self, id: GLuint, target: GLenum);
190    fn get_query_object_iv(&self, id: GLuint, pname: GLenum) -> i32;
191    fn get_query_object_uiv(&self, id: GLuint, pname: GLenum) -> u32;
192    fn get_query_object_i64v(&self, id: GLuint, pname: GLenum) -> i64;
193    fn get_query_object_ui64v(&self, id: GLuint, pname: GLenum) -> u64;
194    fn delete_queries(&self, queries: &[GLuint]);
195    fn delete_vertex_arrays(&self, vertex_arrays: &[GLuint]);
196    fn delete_vertex_arrays_apple(&self, vertex_arrays: &[GLuint]);
197    fn delete_buffers(&self, buffers: &[GLuint]);
198    fn delete_renderbuffers(&self, renderbuffers: &[GLuint]);
199    fn delete_framebuffers(&self, framebuffers: &[GLuint]);
200    fn delete_textures(&self, textures: &[GLuint]);
201    fn framebuffer_renderbuffer(
202        &self,
203        target: GLenum,
204        attachment: GLenum,
205        renderbuffertarget: GLenum,
206        renderbuffer: GLuint,
207    );
208    fn renderbuffer_storage(
209        &self,
210        target: GLenum,
211        internalformat: GLenum,
212        width: GLsizei,
213        height: GLsizei,
214    );
215    fn depth_func(&self, func: GLenum);
216    fn active_texture(&self, texture: GLenum);
217    fn attach_shader(&self, program: GLuint, shader: GLuint);
218    fn bind_attrib_location(&self, program: GLuint, index: GLuint, name: &str);
219    unsafe fn get_uniform_iv(&self, program: GLuint, location: GLint, result: &mut [GLint]);
220    unsafe fn get_uniform_fv(&self, program: GLuint, location: GLint, result: &mut [GLfloat]);
221    fn get_uniform_block_index(&self, program: GLuint, name: &str) -> GLuint;
222    fn get_uniform_indices(&self, program: GLuint, names: &[&str]) -> Vec<GLuint>;
223    fn bind_buffer_base(&self, target: GLenum, index: GLuint, buffer: GLuint);
224    fn bind_buffer_range(
225        &self,
226        target: GLenum,
227        index: GLuint,
228        buffer: GLuint,
229        offset: GLintptr,
230        size: GLsizeiptr,
231    );
232    fn uniform_block_binding(
233        &self,
234        program: GLuint,
235        uniform_block_index: GLuint,
236        uniform_block_binding: GLuint,
237    );
238    fn bind_buffer(&self, target: GLenum, buffer: GLuint);
239    fn bind_vertex_array(&self, vao: GLuint);
240    fn bind_vertex_array_apple(&self, vao: GLuint);
241    fn bind_renderbuffer(&self, target: GLenum, renderbuffer: GLuint);
242    fn bind_framebuffer(&self, target: GLenum, framebuffer: GLuint);
243    fn bind_texture(&self, target: GLenum, texture: GLuint);
244    fn bind_vertex_buffer(&self, binding_index: GLuint, buffer: GLuint, offset: GLintptr, stride: GLint);
245    fn draw_buffers(&self, bufs: &[GLenum]);
246    fn tex_image_2d(
247        &self,
248        target: GLenum,
249        level: GLint,
250        internal_format: GLint,
251        width: GLsizei,
252        height: GLsizei,
253        border: GLint,
254        format: GLenum,
255        ty: GLenum,
256        opt_data: Option<&[u8]>,
257    );
258    fn compressed_tex_image_2d(
259        &self,
260        target: GLenum,
261        level: GLint,
262        internal_format: GLenum,
263        width: GLsizei,
264        height: GLsizei,
265        border: GLint,
266        data: &[u8],
267    );
268    fn compressed_tex_sub_image_2d(
269        &self,
270        target: GLenum,
271        level: GLint,
272        xoffset: GLint,
273        yoffset: GLint,
274        width: GLsizei,
275        height: GLsizei,
276        format: GLenum,
277        data: &[u8],
278    );
279    fn tex_image_3d(
280        &self,
281        target: GLenum,
282        level: GLint,
283        internal_format: GLint,
284        width: GLsizei,
285        height: GLsizei,
286        depth: GLsizei,
287        border: GLint,
288        format: GLenum,
289        ty: GLenum,
290        opt_data: Option<&[u8]>,
291    );
292    fn copy_tex_image_2d(
293        &self,
294        target: GLenum,
295        level: GLint,
296        internal_format: GLenum,
297        x: GLint,
298        y: GLint,
299        width: GLsizei,
300        height: GLsizei,
301        border: GLint,
302    );
303    fn copy_tex_sub_image_2d(
304        &self,
305        target: GLenum,
306        level: GLint,
307        xoffset: GLint,
308        yoffset: GLint,
309        x: GLint,
310        y: GLint,
311        width: GLsizei,
312        height: GLsizei,
313    );
314    fn copy_tex_sub_image_3d(
315        &self,
316        target: GLenum,
317        level: GLint,
318        xoffset: GLint,
319        yoffset: GLint,
320        zoffset: GLint,
321        x: GLint,
322        y: GLint,
323        width: GLsizei,
324        height: GLsizei,
325    );
326    fn tex_sub_image_2d(
327        &self,
328        target: GLenum,
329        level: GLint,
330        xoffset: GLint,
331        yoffset: GLint,
332        width: GLsizei,
333        height: GLsizei,
334        format: GLenum,
335        ty: GLenum,
336        data: &[u8],
337    );
338    fn tex_sub_image_2d_pbo(
339        &self,
340        target: GLenum,
341        level: GLint,
342        xoffset: GLint,
343        yoffset: GLint,
344        width: GLsizei,
345        height: GLsizei,
346        format: GLenum,
347        ty: GLenum,
348        offset: usize,
349    );
350    fn tex_sub_image_3d(
351        &self,
352        target: GLenum,
353        level: GLint,
354        xoffset: GLint,
355        yoffset: GLint,
356        zoffset: GLint,
357        width: GLsizei,
358        height: GLsizei,
359        depth: GLsizei,
360        format: GLenum,
361        ty: GLenum,
362        data: &[u8],
363    );
364    fn tex_sub_image_3d_pbo(
365        &self,
366        target: GLenum,
367        level: GLint,
368        xoffset: GLint,
369        yoffset: GLint,
370        zoffset: GLint,
371        width: GLsizei,
372        height: GLsizei,
373        depth: GLsizei,
374        format: GLenum,
375        ty: GLenum,
376        offset: usize,
377    );
378    fn tex_storage_2d(
379        &self,
380        target: GLenum,
381        levels: GLint,
382        internal_format: GLenum,
383        width: GLsizei,
384        height: GLsizei,
385    );
386    fn tex_storage_3d(
387        &self,
388        target: GLenum,
389        levels: GLint,
390        internal_format: GLenum,
391        width: GLsizei,
392        height: GLsizei,
393        depth: GLsizei,
394    );
395    fn get_tex_image_into_buffer(
396        &self,
397        target: GLenum,
398        level: GLint,
399        format: GLenum,
400        ty: GLenum,
401        output: &mut [u8],
402    );
403    unsafe fn copy_image_sub_data(
404        &self,
405        src_name: GLuint,
406        src_target: GLenum,
407        src_level: GLint,
408        src_x: GLint,
409        src_y: GLint,
410        src_z: GLint,
411        dst_name: GLuint,
412        dst_target: GLenum,
413        dst_level: GLint,
414        dst_x: GLint,
415        dst_y: GLint,
416        dst_z: GLint,
417        src_width: GLsizei,
418        src_height: GLsizei,
419        src_depth: GLsizei,
420    );
421
422    fn invalidate_framebuffer(&self, target: GLenum, attachments: &[GLenum]);
423    fn invalidate_sub_framebuffer(
424        &self,
425        target: GLenum,
426        attachments: &[GLenum],
427        xoffset: GLint,
428        yoffset: GLint,
429        width: GLsizei,
430        height: GLsizei,
431    );
432
433    unsafe fn get_integer_v(&self, name: GLenum, result: &mut [GLint]);
434    unsafe fn get_integer_64v(&self, name: GLenum, result: &mut [GLint64]);
435    unsafe fn get_integer_iv(&self, name: GLenum, index: GLuint, result: &mut [GLint]);
436    unsafe fn get_integer_64iv(&self, name: GLenum, index: GLuint, result: &mut [GLint64]);
437    unsafe fn get_boolean_v(&self, name: GLenum, result: &mut [GLboolean]);
438    unsafe fn get_float_v(&self, name: GLenum, result: &mut [GLfloat]);
439
440    fn get_framebuffer_attachment_parameter_iv(
441        &self,
442        target: GLenum,
443        attachment: GLenum,
444        pname: GLenum,
445    ) -> GLint;
446    fn get_renderbuffer_parameter_iv(&self, target: GLenum, pname: GLenum) -> GLint;
447    fn get_tex_parameter_iv(&self, target: GLenum, name: GLenum) -> GLint;
448    fn get_tex_parameter_fv(&self, target: GLenum, name: GLenum) -> GLfloat;
449    fn tex_parameter_i(&self, target: GLenum, pname: GLenum, param: GLint);
450    fn tex_parameter_f(&self, target: GLenum, pname: GLenum, param: GLfloat);
451    fn framebuffer_texture_2d(
452        &self,
453        target: GLenum,
454        attachment: GLenum,
455        textarget: GLenum,
456        texture: GLuint,
457        level: GLint,
458    );
459    fn framebuffer_texture_layer(
460        &self,
461        target: GLenum,
462        attachment: GLenum,
463        texture: GLuint,
464        level: GLint,
465        layer: GLint,
466    );
467    fn blit_framebuffer(
468        &self,
469        src_x0: GLint,
470        src_y0: GLint,
471        src_x1: GLint,
472        src_y1: GLint,
473        dst_x0: GLint,
474        dst_y0: GLint,
475        dst_x1: GLint,
476        dst_y1: GLint,
477        mask: GLbitfield,
478        filter: GLenum,
479    );
480    fn vertex_attrib_4f(&self, index: GLuint, x: GLfloat, y: GLfloat, z: GLfloat, w: GLfloat);
481    fn vertex_attrib_binding(&self, attrib_index: GLuint, binding_index: GLuint);
482    fn vertex_attrib_pointer_f32(
483        &self,
484        index: GLuint,
485        size: GLint,
486        normalized: bool,
487        stride: GLsizei,
488        offset: GLuint,
489    );
490    fn vertex_attrib_pointer(
491        &self,
492        index: GLuint,
493        size: GLint,
494        type_: GLenum,
495        normalized: bool,
496        stride: GLsizei,
497        offset: GLuint,
498    );
499    fn vertex_attrib_i_pointer(
500        &self,
501        index: GLuint,
502        size: GLint,
503        type_: GLenum,
504        stride: GLsizei,
505        offset: GLuint,
506    );
507    fn vertex_attrib_divisor(&self, index: GLuint, divisor: GLuint);
508    fn vertex_attrib_format(&self, attrib_index: GLuint, size: GLint, type_: GLenum, normalized: bool, relative_offset: GLuint);
509    fn vertex_attrib_i_format(&self, attrib_index: GLuint, size: GLint, type_: GLenum, relative_offset: GLuint);
510    fn vertex_binding_divisor(&self, binding_index: GLuint, divisor: GLuint);
511    fn viewport(&self, x: GLint, y: GLint, width: GLsizei, height: GLsizei);
512    fn scissor(&self, x: GLint, y: GLint, width: GLsizei, height: GLsizei);
513    fn line_width(&self, width: GLfloat);
514    fn use_program(&self, program: GLuint);
515    fn validate_program(&self, program: GLuint);
516    fn draw_arrays(&self, mode: GLenum, first: GLint, count: GLsizei);
517    fn draw_arrays_instanced(&self, mode: GLenum, first: GLint, count: GLsizei, primcount: GLsizei);
518    fn draw_elements(
519        &self,
520        mode: GLenum,
521        count: GLsizei,
522        element_type: GLenum,
523        indices_offset: GLuint,
524    );
525    fn draw_elements_instanced(
526        &self,
527        mode: GLenum,
528        count: GLsizei,
529        element_type: GLenum,
530        indices_offset: GLuint,
531        primcount: GLsizei,
532    );
533    fn blend_color(&self, r: f32, g: f32, b: f32, a: f32);
534    fn blend_func(&self, sfactor: GLenum, dfactor: GLenum);
535    fn blend_func_separate(
536        &self,
537        src_rgb: GLenum,
538        dest_rgb: GLenum,
539        src_alpha: GLenum,
540        dest_alpha: GLenum,
541    );
542    fn blend_equation(&self, mode: GLenum);
543    fn blend_equation_separate(&self, mode_rgb: GLenum, mode_alpha: GLenum);
544    fn color_mask(&self, r: bool, g: bool, b: bool, a: bool);
545    fn cull_face(&self, mode: GLenum);
546    fn front_face(&self, mode: GLenum);
547    fn enable(&self, cap: GLenum);
548    fn disable(&self, cap: GLenum);
549    fn hint(&self, param_name: GLenum, param_val: GLenum);
550    fn is_enabled(&self, cap: GLenum) -> GLboolean;
551    fn is_shader(&self, shader: GLuint) -> GLboolean;
552    fn is_texture(&self, texture: GLenum) -> GLboolean;
553    fn is_framebuffer(&self, framebuffer: GLenum) -> GLboolean;
554    fn is_renderbuffer(&self, renderbuffer: GLenum) -> GLboolean;
555    fn check_frame_buffer_status(&self, target: GLenum) -> GLenum;
556    fn enable_vertex_attrib_array(&self, index: GLuint);
557    fn disable_vertex_attrib_array(&self, index: GLuint);
558    fn uniform_1f(&self, location: GLint, v0: GLfloat);
559    fn uniform_1fv(&self, location: GLint, values: &[f32]);
560    fn uniform_1i(&self, location: GLint, v0: GLint);
561    fn uniform_1iv(&self, location: GLint, values: &[i32]);
562    fn uniform_1ui(&self, location: GLint, v0: GLuint);
563    fn uniform_2f(&self, location: GLint, v0: GLfloat, v1: GLfloat);
564    fn uniform_2fv(&self, location: GLint, values: &[f32]);
565    fn uniform_2i(&self, location: GLint, v0: GLint, v1: GLint);
566    fn uniform_2iv(&self, location: GLint, values: &[i32]);
567    fn uniform_2ui(&self, location: GLint, v0: GLuint, v1: GLuint);
568    fn uniform_3f(&self, location: GLint, v0: GLfloat, v1: GLfloat, v2: GLfloat);
569    fn uniform_3fv(&self, location: GLint, values: &[f32]);
570    fn uniform_3i(&self, location: GLint, v0: GLint, v1: GLint, v2: GLint);
571    fn uniform_3iv(&self, location: GLint, values: &[i32]);
572    fn uniform_3ui(&self, location: GLint, v0: GLuint, v1: GLuint, v2: GLuint);
573    fn uniform_4f(&self, location: GLint, x: GLfloat, y: GLfloat, z: GLfloat, w: GLfloat);
574    fn uniform_4i(&self, location: GLint, x: GLint, y: GLint, z: GLint, w: GLint);
575    fn uniform_4iv(&self, location: GLint, values: &[i32]);
576    fn uniform_4ui(&self, location: GLint, x: GLuint, y: GLuint, z: GLuint, w: GLuint);
577    fn uniform_4fv(&self, location: GLint, values: &[f32]);
578    fn uniform_matrix_2fv(&self, location: GLint, transpose: bool, value: &[f32]);
579    fn uniform_matrix_3fv(&self, location: GLint, transpose: bool, value: &[f32]);
580    fn uniform_matrix_4fv(&self, location: GLint, transpose: bool, value: &[f32]);
581    fn depth_mask(&self, flag: bool);
582    fn depth_range(&self, near: f64, far: f64);
583    fn get_active_attrib(&self, program: GLuint, index: GLuint) -> (i32, u32, String);
584    fn get_active_uniform(&self, program: GLuint, index: GLuint) -> (i32, u32, String);
585    fn get_active_uniforms_iv(
586        &self,
587        program: GLuint,
588        indices: Vec<GLuint>,
589        pname: GLenum,
590    ) -> Vec<GLint>;
591    fn get_active_uniform_block_i(&self, program: GLuint, index: GLuint, pname: GLenum) -> GLint;
592    fn get_active_uniform_block_iv(
593        &self,
594        program: GLuint,
595        index: GLuint,
596        pname: GLenum,
597    ) -> Vec<GLint>;
598    fn get_active_uniform_block_name(&self, program: GLuint, index: GLuint) -> String;
599    fn get_attrib_location(&self, program: GLuint, name: &str) -> c_int;
600    fn get_frag_data_location(&self, program: GLuint, name: &str) -> c_int;
601    fn get_uniform_location(&self, program: GLuint, name: &str) -> c_int;
602    fn get_program_info_log(&self, program: GLuint) -> String;
603    unsafe fn get_program_iv(&self, program: GLuint, pname: GLenum, result: &mut [GLint]);
604    fn get_program_binary(&self, program: GLuint) -> (Vec<u8>, GLenum);
605    fn program_binary(&self, program: GLuint, format: GLenum, binary: &[u8]);
606    fn program_parameter_i(&self, program: GLuint, pname: GLenum, value: GLint);
607    unsafe fn get_vertex_attrib_iv(&self, index: GLuint, pname: GLenum, result: &mut [GLint]);
608    unsafe fn get_vertex_attrib_fv(&self, index: GLuint, pname: GLenum, result: &mut [GLfloat]);
609    fn get_vertex_attrib_pointer_v(&self, index: GLuint, pname: GLenum) -> GLsizeiptr;
610    fn get_buffer_parameter_iv(&self, target: GLuint, pname: GLenum) -> GLint;
611    fn get_shader_info_log(&self, shader: GLuint) -> String;
612    fn get_string(&self, which: GLenum) -> String;
613    fn get_string_i(&self, which: GLenum, index: GLuint) -> String;
614    unsafe fn get_shader_iv(&self, shader: GLuint, pname: GLenum, result: &mut [GLint]);
615    fn get_shader_precision_format(
616        &self,
617        shader_type: GLuint,
618        precision_type: GLuint,
619    ) -> (GLint, GLint, GLint);
620    fn compile_shader(&self, shader: GLuint);
621    fn create_program(&self) -> GLuint;
622    fn delete_program(&self, program: GLuint);
623    fn create_shader(&self, shader_type: GLenum) -> GLuint;
624    fn delete_shader(&self, shader: GLuint);
625    fn detach_shader(&self, program: GLuint, shader: GLuint);
626    fn link_program(&self, program: GLuint);
627    fn clear_color(&self, r: f32, g: f32, b: f32, a: f32);
628    fn clear(&self, buffer_mask: GLbitfield);
629    fn clear_depth(&self, depth: f64);
630    fn clear_stencil(&self, s: GLint);
631    fn flush(&self);
632    fn finish(&self);
633    fn get_error(&self) -> GLenum;
634    fn stencil_mask(&self, mask: GLuint);
635    fn stencil_mask_separate(&self, face: GLenum, mask: GLuint);
636    fn stencil_func(&self, func: GLenum, ref_: GLint, mask: GLuint);
637    fn stencil_func_separate(&self, face: GLenum, func: GLenum, ref_: GLint, mask: GLuint);
638    fn stencil_op(&self, sfail: GLenum, dpfail: GLenum, dppass: GLenum);
639    fn stencil_op_separate(&self, face: GLenum, sfail: GLenum, dpfail: GLenum, dppass: GLenum);
640    fn egl_image_target_texture2d_oes(&self, target: GLenum, image: GLeglImageOES);
641    fn egl_image_target_renderbuffer_storage_oes(&self, target: GLenum, image: GLeglImageOES);
642    fn generate_mipmap(&self, target: GLenum);
643    fn insert_event_marker_ext(&self, message: &str);
644    fn push_group_marker_ext(&self, message: &str);
645    fn pop_group_marker_ext(&self);
646    fn debug_message_insert_khr(
647        &self,
648        source: GLenum,
649        type_: GLenum,
650        id: GLuint,
651        severity: GLenum,
652        message: &str,
653    );
654    fn push_debug_group_khr(&self, source: GLenum, id: GLuint, message: &str);
655    fn pop_debug_group_khr(&self);
656    fn fence_sync(&self, condition: GLenum, flags: GLbitfield) -> GLsync;
657    fn client_wait_sync(&self, sync: GLsync, flags: GLbitfield, timeout: GLuint64) -> GLenum;
658    fn wait_sync(&self, sync: GLsync, flags: GLbitfield, timeout: GLuint64);
659    fn delete_sync(&self, sync: GLsync);
660    fn texture_range_apple(&self, target: GLenum, data: &[u8]);
661    fn gen_fences_apple(&self, n: GLsizei) -> Vec<GLuint>;
662    fn delete_fences_apple(&self, fences: &[GLuint]);
663    fn set_fence_apple(&self, fence: GLuint);
664    fn finish_fence_apple(&self, fence: GLuint);
665    fn test_fence_apple(&self, fence: GLuint);
666    fn test_object_apple(&self, object: GLenum, name: GLuint) -> GLboolean;
667    fn finish_object_apple(&self, object: GLenum, name: GLuint);
668    // GL_KHR_blend_equation_advanced
669    fn blend_barrier_khr(&self);
670
671    // GL_ARB_blend_func_extended
672    fn bind_frag_data_location_indexed(
673        &self,
674        program: GLuint,
675        color_number: GLuint,
676        index: GLuint,
677        name: &str,
678    );
679    fn get_frag_data_index(&self, program: GLuint, name: &str) -> GLint;
680
681    // GL_KHR_debug
682    fn get_debug_messages(&self) -> Vec<DebugMessage>;
683
684    // GL_ANGLE_provoking_vertex
685    fn provoking_vertex_angle(&self, mode: GLenum);
686
687    // GL_CHROMIUM_copy_texture
688    fn copy_texture_chromium(
689        &self,
690        source_id: GLuint,
691        source_level: GLint,
692        dest_target: GLenum,
693        dest_id: GLuint,
694        dest_level: GLint,
695        internal_format: GLint,
696        dest_type: GLenum,
697        unpack_flip_y: GLboolean,
698        unpack_premultiply_alpha: GLboolean,
699        unpack_unmultiply_alpha: GLboolean,
700    );
701    fn copy_sub_texture_chromium(
702        &self,
703        source_id: GLuint,
704        source_level: GLint,
705        dest_target: GLenum,
706        dest_id: GLuint,
707        dest_level: GLint,
708        x_offset: GLint,
709        y_offset: GLint,
710        x: GLint,
711        y: GLint,
712        width: GLsizei,
713        height: GLsizei,
714        unpack_flip_y: GLboolean,
715        unpack_premultiply_alpha: GLboolean,
716        unpack_unmultiply_alpha: GLboolean,
717    );
718
719    // GL_ANGLE_copy_texture_3d
720    fn copy_texture_3d_angle(
721        &self,
722        source_id: GLuint,
723        source_level: GLint,
724        dest_target: GLenum,
725        dest_id: GLuint,
726        dest_level: GLint,
727        internal_format: GLint,
728        dest_type: GLenum,
729        unpack_flip_y: GLboolean,
730        unpack_premultiply_alpha: GLboolean,
731        unpack_unmultiply_alpha: GLboolean,
732    );
733
734    fn copy_sub_texture_3d_angle(
735        &self,
736        source_id: GLuint,
737        source_level: GLint,
738        dest_target: GLenum,
739        dest_id: GLuint,
740        dest_level: GLint,
741        x_offset: GLint,
742        y_offset: GLint,
743        z_offset: GLint,
744        x: GLint,
745        y: GLint,
746        z: GLint,
747        width: GLsizei,
748        height: GLsizei,
749        depth: GLsizei,
750        unpack_flip_y: GLboolean,
751        unpack_premultiply_alpha: GLboolean,
752        unpack_unmultiply_alpha: GLboolean,
753    );
754
755    fn buffer_storage(
756        &self,
757        target: GLenum,
758        size: GLsizeiptr,
759        data: *const GLvoid,
760        flags: GLbitfield,
761    );
762
763    fn flush_mapped_buffer_range(&self, target: GLenum, offset: GLintptr, length: GLsizeiptr);
764
765    fn start_tiling_qcom(&self, x: GLuint, y: GLuint, width: GLuint, height: GLuint, preserve_mask: GLbitfield);
766    fn end_tiling_qcom(&self, preserve_mask: GLbitfield);
767}
768
769//#[deprecated(since = "0.6.11", note = "use ErrorReactingGl instead")]
770pub struct ErrorCheckingGl {
771    gl: Rc<dyn Gl>,
772}
773
774impl ErrorCheckingGl {
775    pub fn wrap(fns: Rc<dyn Gl>) -> Rc<dyn Gl> {
776        Rc::new(ErrorCheckingGl { gl: fns }) as Rc<dyn Gl>
777    }
778}
779
780/// A wrapper around GL context that calls a specified callback on each GL error.
781pub struct ErrorReactingGl<F> {
782    gl: Rc<dyn Gl>,
783    callback: F,
784}
785
786impl<F: 'static + Fn(&dyn Gl, &str, GLenum)> ErrorReactingGl<F> {
787    pub fn wrap(fns: Rc<dyn Gl>, callback: F) -> Rc<dyn Gl> {
788        Rc::new(ErrorReactingGl { gl: fns, callback }) as Rc<dyn Gl>
789    }
790}
791
792/// A wrapper around GL context that times each call and invokes the callback
793/// if the call takes longer than the threshold.
794pub struct ProfilingGl<F> {
795    gl: Rc<dyn Gl>,
796    threshold: Duration,
797    callback: F,
798}
799
800impl<F: 'static + Fn(&str, Duration)> ProfilingGl<F> {
801    pub fn wrap(fns: Rc<dyn Gl>, threshold: Duration, callback: F) -> Rc<dyn Gl> {
802        Rc::new(ProfilingGl {
803            gl: fns,
804            threshold,
805            callback,
806        }) as Rc<dyn Gl>
807    }
808}
809
810#[inline]
811pub fn buffer_data<T>(gl_: &dyn Gl, target: GLenum, data: &[T], usage: GLenum) {
812    gl_.buffer_data_untyped(
813        target,
814        (data.len() * size_of::<T>()) as GLsizeiptr,
815        data.as_ptr() as *const GLvoid,
816        usage,
817    )
818}
819
820#[inline]
821pub fn buffer_data_raw<T>(gl_: &dyn Gl, target: GLenum, data: &T, usage: GLenum) {
822    gl_.buffer_data_untyped(
823        target,
824        size_of::<T>() as GLsizeiptr,
825        data as *const T as *const GLvoid,
826        usage,
827    )
828}
829
830#[inline]
831pub fn buffer_sub_data<T>(gl_: &dyn Gl, target: GLenum, offset: isize, data: &[T]) {
832    gl_.buffer_sub_data_untyped(
833        target,
834        offset,
835        (data.len() * size_of::<T>()) as GLsizeiptr,
836        data.as_ptr() as *const GLvoid,
837    );
838}
839
840include!("gl_fns.rs");
841include!("gles_fns.rs");