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 ffi;
11 use std::ffi::{CStr, CString};
12 use std::mem;
13 use std::mem::size_of;
14 use std::os::raw::{c_char, c_int, c_void};
15 use std::ptr;
16 use std::rc::Rc;
17 use std::str;
18 use std::time::{Duration, Instant};
19
20 pub use ffi::types::*;
21 pub use ffi::*;
22
23 pub use ffi_gl::Gl as GlFfi;
24 pub use ffi_gles::Gles2 as GlesFfi;
25
26 #[derive(Copy, Clone, Debug, Eq, PartialEq)]
27 pub enum GlType {
28 Gl,
29 Gles,
30 }
31
32 impl Default for GlType {
33 #[cfg(any(target_os = "android", target_os = "ios"))]
default() -> GlType34 fn default() -> GlType {
35 GlType::Gles
36 }
37 #[cfg(not(any(target_os = "android", target_os = "ios")))]
default() -> GlType38 fn default() -> GlType {
39 GlType::Gl
40 }
41 }
42
bpp(format: GLenum, pixel_type: GLenum) -> GLsizei43 fn 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
calculate_length(width: GLsizei, height: GLsizei, format: GLenum, pixel_type: GLenum) -> usize69 fn calculate_length(width: GLsizei, height: GLsizei, format: GLenum, pixel_type: GLenum) -> usize {
70 (width * height * bpp(format, pixel_type)) as usize
71 }
72
73 pub struct DebugMessage {
74 pub message: String,
75 pub source: GLenum,
76 pub ty: GLenum,
77 pub id: GLenum,
78 pub severity: GLenum,
79 }
80
81 macro_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
121 declare_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 draw_buffers(&self, bufs: &[GLenum]);
245 fn tex_image_2d(
246 &self,
247 target: GLenum,
248 level: GLint,
249 internal_format: GLint,
250 width: GLsizei,
251 height: GLsizei,
252 border: GLint,
253 format: GLenum,
254 ty: GLenum,
255 opt_data: Option<&[u8]>,
256 );
257 fn compressed_tex_image_2d(
258 &self,
259 target: GLenum,
260 level: GLint,
261 internal_format: GLenum,
262 width: GLsizei,
263 height: GLsizei,
264 border: GLint,
265 data: &[u8],
266 );
267 fn compressed_tex_sub_image_2d(
268 &self,
269 target: GLenum,
270 level: GLint,
271 xoffset: GLint,
272 yoffset: GLint,
273 width: GLsizei,
274 height: GLsizei,
275 format: GLenum,
276 data: &[u8],
277 );
278 fn tex_image_3d(
279 &self,
280 target: GLenum,
281 level: GLint,
282 internal_format: GLint,
283 width: GLsizei,
284 height: GLsizei,
285 depth: GLsizei,
286 border: GLint,
287 format: GLenum,
288 ty: GLenum,
289 opt_data: Option<&[u8]>,
290 );
291 fn copy_tex_image_2d(
292 &self,
293 target: GLenum,
294 level: GLint,
295 internal_format: GLenum,
296 x: GLint,
297 y: GLint,
298 width: GLsizei,
299 height: GLsizei,
300 border: GLint,
301 );
302 fn copy_tex_sub_image_2d(
303 &self,
304 target: GLenum,
305 level: GLint,
306 xoffset: GLint,
307 yoffset: GLint,
308 x: GLint,
309 y: GLint,
310 width: GLsizei,
311 height: GLsizei,
312 );
313 fn copy_tex_sub_image_3d(
314 &self,
315 target: GLenum,
316 level: GLint,
317 xoffset: GLint,
318 yoffset: GLint,
319 zoffset: GLint,
320 x: GLint,
321 y: GLint,
322 width: GLsizei,
323 height: GLsizei,
324 );
325 fn tex_sub_image_2d(
326 &self,
327 target: GLenum,
328 level: GLint,
329 xoffset: GLint,
330 yoffset: GLint,
331 width: GLsizei,
332 height: GLsizei,
333 format: GLenum,
334 ty: GLenum,
335 data: &[u8],
336 );
337 fn tex_sub_image_2d_pbo(
338 &self,
339 target: GLenum,
340 level: GLint,
341 xoffset: GLint,
342 yoffset: GLint,
343 width: GLsizei,
344 height: GLsizei,
345 format: GLenum,
346 ty: GLenum,
347 offset: usize,
348 );
349 fn tex_sub_image_3d(
350 &self,
351 target: GLenum,
352 level: GLint,
353 xoffset: GLint,
354 yoffset: GLint,
355 zoffset: GLint,
356 width: GLsizei,
357 height: GLsizei,
358 depth: GLsizei,
359 format: GLenum,
360 ty: GLenum,
361 data: &[u8],
362 );
363 fn tex_sub_image_3d_pbo(
364 &self,
365 target: GLenum,
366 level: GLint,
367 xoffset: GLint,
368 yoffset: GLint,
369 zoffset: GLint,
370 width: GLsizei,
371 height: GLsizei,
372 depth: GLsizei,
373 format: GLenum,
374 ty: GLenum,
375 offset: usize,
376 );
377 fn tex_storage_2d(
378 &self,
379 target: GLenum,
380 levels: GLint,
381 internal_format: GLenum,
382 width: GLsizei,
383 height: GLsizei,
384 );
385 fn tex_storage_3d(
386 &self,
387 target: GLenum,
388 levels: GLint,
389 internal_format: GLenum,
390 width: GLsizei,
391 height: GLsizei,
392 depth: GLsizei,
393 );
394 fn get_tex_image_into_buffer(
395 &self,
396 target: GLenum,
397 level: GLint,
398 format: GLenum,
399 ty: GLenum,
400 output: &mut [u8],
401 );
402 unsafe fn copy_image_sub_data(
403 &self,
404 src_name: GLuint,
405 src_target: GLenum,
406 src_level: GLint,
407 src_x: GLint,
408 src_y: GLint,
409 src_z: GLint,
410 dst_name: GLuint,
411 dst_target: GLenum,
412 dst_level: GLint,
413 dst_x: GLint,
414 dst_y: GLint,
415 dst_z: GLint,
416 src_width: GLsizei,
417 src_height: GLsizei,
418 src_depth: GLsizei,
419 );
420
421 fn invalidate_framebuffer(&self, target: GLenum, attachments: &[GLenum]);
422 fn invalidate_sub_framebuffer(
423 &self,
424 target: GLenum,
425 attachments: &[GLenum],
426 xoffset: GLint,
427 yoffset: GLint,
428 width: GLsizei,
429 height: GLsizei,
430 );
431
432 unsafe fn get_integer_v(&self, name: GLenum, result: &mut [GLint]);
433 unsafe fn get_integer_64v(&self, name: GLenum, result: &mut [GLint64]);
434 unsafe fn get_integer_iv(&self, name: GLenum, index: GLuint, result: &mut [GLint]);
435 unsafe fn get_integer_64iv(&self, name: GLenum, index: GLuint, result: &mut [GLint64]);
436 unsafe fn get_boolean_v(&self, name: GLenum, result: &mut [GLboolean]);
437 unsafe fn get_float_v(&self, name: GLenum, result: &mut [GLfloat]);
438
439 fn get_framebuffer_attachment_parameter_iv(
440 &self,
441 target: GLenum,
442 attachment: GLenum,
443 pname: GLenum,
444 ) -> GLint;
445 fn get_renderbuffer_parameter_iv(&self, target: GLenum, pname: GLenum) -> GLint;
446 fn get_tex_parameter_iv(&self, target: GLenum, name: GLenum) -> GLint;
447 fn get_tex_parameter_fv(&self, target: GLenum, name: GLenum) -> GLfloat;
448 fn tex_parameter_i(&self, target: GLenum, pname: GLenum, param: GLint);
449 fn tex_parameter_f(&self, target: GLenum, pname: GLenum, param: GLfloat);
450 fn framebuffer_texture_2d(
451 &self,
452 target: GLenum,
453 attachment: GLenum,
454 textarget: GLenum,
455 texture: GLuint,
456 level: GLint,
457 );
458 fn framebuffer_texture_layer(
459 &self,
460 target: GLenum,
461 attachment: GLenum,
462 texture: GLuint,
463 level: GLint,
464 layer: GLint,
465 );
466 fn blit_framebuffer(
467 &self,
468 src_x0: GLint,
469 src_y0: GLint,
470 src_x1: GLint,
471 src_y1: GLint,
472 dst_x0: GLint,
473 dst_y0: GLint,
474 dst_x1: GLint,
475 dst_y1: GLint,
476 mask: GLbitfield,
477 filter: GLenum,
478 );
479 fn vertex_attrib_4f(&self, index: GLuint, x: GLfloat, y: GLfloat, z: GLfloat, w: GLfloat);
480 fn vertex_attrib_pointer_f32(
481 &self,
482 index: GLuint,
483 size: GLint,
484 normalized: bool,
485 stride: GLsizei,
486 offset: GLuint,
487 );
488 fn vertex_attrib_pointer(
489 &self,
490 index: GLuint,
491 size: GLint,
492 type_: GLenum,
493 normalized: bool,
494 stride: GLsizei,
495 offset: GLuint,
496 );
497 fn vertex_attrib_i_pointer(
498 &self,
499 index: GLuint,
500 size: GLint,
501 type_: GLenum,
502 stride: GLsizei,
503 offset: GLuint,
504 );
505 fn vertex_attrib_divisor(&self, index: GLuint, divisor: GLuint);
506 fn viewport(&self, x: GLint, y: GLint, width: GLsizei, height: GLsizei);
507 fn scissor(&self, x: GLint, y: GLint, width: GLsizei, height: GLsizei);
508 fn line_width(&self, width: GLfloat);
509 fn use_program(&self, program: GLuint);
510 fn validate_program(&self, program: GLuint);
511 fn draw_arrays(&self, mode: GLenum, first: GLint, count: GLsizei);
512 fn draw_arrays_instanced(&self, mode: GLenum, first: GLint, count: GLsizei, primcount: GLsizei);
513 fn draw_elements(
514 &self,
515 mode: GLenum,
516 count: GLsizei,
517 element_type: GLenum,
518 indices_offset: GLuint,
519 );
520 fn draw_elements_instanced(
521 &self,
522 mode: GLenum,
523 count: GLsizei,
524 element_type: GLenum,
525 indices_offset: GLuint,
526 primcount: GLsizei,
527 );
528 fn blend_color(&self, r: f32, g: f32, b: f32, a: f32);
529 fn blend_func(&self, sfactor: GLenum, dfactor: GLenum);
530 fn blend_func_separate(
531 &self,
532 src_rgb: GLenum,
533 dest_rgb: GLenum,
534 src_alpha: GLenum,
535 dest_alpha: GLenum,
536 );
537 fn blend_equation(&self, mode: GLenum);
538 fn blend_equation_separate(&self, mode_rgb: GLenum, mode_alpha: GLenum);
539 fn color_mask(&self, r: bool, g: bool, b: bool, a: bool);
540 fn cull_face(&self, mode: GLenum);
541 fn front_face(&self, mode: GLenum);
542 fn enable(&self, cap: GLenum);
543 fn disable(&self, cap: GLenum);
544 fn hint(&self, param_name: GLenum, param_val: GLenum);
545 fn is_enabled(&self, cap: GLenum) -> GLboolean;
546 fn is_shader(&self, shader: GLuint) -> GLboolean;
547 fn is_texture(&self, texture: GLenum) -> GLboolean;
548 fn is_framebuffer(&self, framebuffer: GLenum) -> GLboolean;
549 fn is_renderbuffer(&self, renderbuffer: GLenum) -> GLboolean;
550 fn check_frame_buffer_status(&self, target: GLenum) -> GLenum;
551 fn enable_vertex_attrib_array(&self, index: GLuint);
552 fn disable_vertex_attrib_array(&self, index: GLuint);
553 fn uniform_1f(&self, location: GLint, v0: GLfloat);
554 fn uniform_1fv(&self, location: GLint, values: &[f32]);
555 fn uniform_1i(&self, location: GLint, v0: GLint);
556 fn uniform_1iv(&self, location: GLint, values: &[i32]);
557 fn uniform_1ui(&self, location: GLint, v0: GLuint);
558 fn uniform_2f(&self, location: GLint, v0: GLfloat, v1: GLfloat);
559 fn uniform_2fv(&self, location: GLint, values: &[f32]);
560 fn uniform_2i(&self, location: GLint, v0: GLint, v1: GLint);
561 fn uniform_2iv(&self, location: GLint, values: &[i32]);
562 fn uniform_2ui(&self, location: GLint, v0: GLuint, v1: GLuint);
563 fn uniform_3f(&self, location: GLint, v0: GLfloat, v1: GLfloat, v2: GLfloat);
564 fn uniform_3fv(&self, location: GLint, values: &[f32]);
565 fn uniform_3i(&self, location: GLint, v0: GLint, v1: GLint, v2: GLint);
566 fn uniform_3iv(&self, location: GLint, values: &[i32]);
567 fn uniform_3ui(&self, location: GLint, v0: GLuint, v1: GLuint, v2: GLuint);
568 fn uniform_4f(&self, location: GLint, x: GLfloat, y: GLfloat, z: GLfloat, w: GLfloat);
569 fn uniform_4i(&self, location: GLint, x: GLint, y: GLint, z: GLint, w: GLint);
570 fn uniform_4iv(&self, location: GLint, values: &[i32]);
571 fn uniform_4ui(&self, location: GLint, x: GLuint, y: GLuint, z: GLuint, w: GLuint);
572 fn uniform_4fv(&self, location: GLint, values: &[f32]);
573 fn uniform_matrix_2fv(&self, location: GLint, transpose: bool, value: &[f32]);
574 fn uniform_matrix_3fv(&self, location: GLint, transpose: bool, value: &[f32]);
575 fn uniform_matrix_4fv(&self, location: GLint, transpose: bool, value: &[f32]);
576 fn depth_mask(&self, flag: bool);
577 fn depth_range(&self, near: f64, far: f64);
578 fn get_active_attrib(&self, program: GLuint, index: GLuint) -> (i32, u32, String);
579 fn get_active_uniform(&self, program: GLuint, index: GLuint) -> (i32, u32, String);
580 fn get_active_uniforms_iv(
581 &self,
582 program: GLuint,
583 indices: Vec<GLuint>,
584 pname: GLenum,
585 ) -> Vec<GLint>;
586 fn get_active_uniform_block_i(&self, program: GLuint, index: GLuint, pname: GLenum) -> GLint;
587 fn get_active_uniform_block_iv(
588 &self,
589 program: GLuint,
590 index: GLuint,
591 pname: GLenum,
592 ) -> Vec<GLint>;
593 fn get_active_uniform_block_name(&self, program: GLuint, index: GLuint) -> String;
594 fn get_attrib_location(&self, program: GLuint, name: &str) -> c_int;
595 fn get_frag_data_location(&self, program: GLuint, name: &str) -> c_int;
596 fn get_uniform_location(&self, program: GLuint, name: &str) -> c_int;
597 fn get_program_info_log(&self, program: GLuint) -> String;
598 unsafe fn get_program_iv(&self, program: GLuint, pname: GLenum, result: &mut [GLint]);
599 fn get_program_binary(&self, program: GLuint) -> (Vec<u8>, GLenum);
600 fn program_binary(&self, program: GLuint, format: GLenum, binary: &[u8]);
601 fn program_parameter_i(&self, program: GLuint, pname: GLenum, value: GLint);
602 unsafe fn get_vertex_attrib_iv(&self, index: GLuint, pname: GLenum, result: &mut [GLint]);
603 unsafe fn get_vertex_attrib_fv(&self, index: GLuint, pname: GLenum, result: &mut [GLfloat]);
604 fn get_vertex_attrib_pointer_v(&self, index: GLuint, pname: GLenum) -> GLsizeiptr;
605 fn get_buffer_parameter_iv(&self, target: GLuint, pname: GLenum) -> GLint;
606 fn get_shader_info_log(&self, shader: GLuint) -> String;
607 fn get_string(&self, which: GLenum) -> String;
608 fn get_string_i(&self, which: GLenum, index: GLuint) -> String;
609 unsafe fn get_shader_iv(&self, shader: GLuint, pname: GLenum, result: &mut [GLint]);
610 fn get_shader_precision_format(
611 &self,
612 shader_type: GLuint,
613 precision_type: GLuint,
614 ) -> (GLint, GLint, GLint);
615 fn compile_shader(&self, shader: GLuint);
616 fn create_program(&self) -> GLuint;
617 fn delete_program(&self, program: GLuint);
618 fn create_shader(&self, shader_type: GLenum) -> GLuint;
619 fn delete_shader(&self, shader: GLuint);
620 fn detach_shader(&self, program: GLuint, shader: GLuint);
621 fn link_program(&self, program: GLuint);
622 fn clear_color(&self, r: f32, g: f32, b: f32, a: f32);
623 fn clear(&self, buffer_mask: GLbitfield);
624 fn clear_depth(&self, depth: f64);
625 fn clear_stencil(&self, s: GLint);
626 fn flush(&self);
627 fn finish(&self);
628 fn get_error(&self) -> GLenum;
629 fn stencil_mask(&self, mask: GLuint);
630 fn stencil_mask_separate(&self, face: GLenum, mask: GLuint);
631 fn stencil_func(&self, func: GLenum, ref_: GLint, mask: GLuint);
632 fn stencil_func_separate(&self, face: GLenum, func: GLenum, ref_: GLint, mask: GLuint);
633 fn stencil_op(&self, sfail: GLenum, dpfail: GLenum, dppass: GLenum);
634 fn stencil_op_separate(&self, face: GLenum, sfail: GLenum, dpfail: GLenum, dppass: GLenum);
635 fn egl_image_target_texture2d_oes(&self, target: GLenum, image: GLeglImageOES);
636 fn egl_image_target_renderbuffer_storage_oes(&self, target: GLenum, image: GLeglImageOES);
637 fn generate_mipmap(&self, target: GLenum);
638 fn insert_event_marker_ext(&self, message: &str);
639 fn push_group_marker_ext(&self, message: &str);
640 fn pop_group_marker_ext(&self);
641 fn debug_message_insert_khr(
642 &self,
643 source: GLenum,
644 type_: GLenum,
645 id: GLuint,
646 severity: GLenum,
647 message: &str,
648 );
649 fn push_debug_group_khr(&self, source: GLenum, id: GLuint, message: &str);
650 fn pop_debug_group_khr(&self);
651 fn fence_sync(&self, condition: GLenum, flags: GLbitfield) -> GLsync;
652 fn client_wait_sync(&self, sync: GLsync, flags: GLbitfield, timeout: GLuint64) -> GLenum;
653 fn wait_sync(&self, sync: GLsync, flags: GLbitfield, timeout: GLuint64);
654 fn delete_sync(&self, sync: GLsync);
655 fn texture_range_apple(&self, target: GLenum, data: &[u8]);
656 fn gen_fences_apple(&self, n: GLsizei) -> Vec<GLuint>;
657 fn delete_fences_apple(&self, fences: &[GLuint]);
658 fn set_fence_apple(&self, fence: GLuint);
659 fn finish_fence_apple(&self, fence: GLuint);
660 fn test_fence_apple(&self, fence: GLuint);
661 fn test_object_apple(&self, object: GLenum, name: GLuint) -> GLboolean;
662 fn finish_object_apple(&self, object: GLenum, name: GLuint);
663 // GL_KHR_blend_equation_advanced
664 fn blend_barrier_khr(&self);
665
666 // GL_ARB_blend_func_extended
667 fn bind_frag_data_location_indexed(
668 &self,
669 program: GLuint,
670 color_number: GLuint,
671 index: GLuint,
672 name: &str,
673 );
674 fn get_frag_data_index(&self, program: GLuint, name: &str) -> GLint;
675
676 // GL_KHR_debug
677 fn get_debug_messages(&self) -> Vec<DebugMessage>;
678
679 // GL_ANGLE_provoking_vertex
680 fn provoking_vertex_angle(&self, mode: GLenum);
681
682 // GL_CHROMIUM_copy_texture
683 fn copy_texture_chromium(
684 &self,
685 source_id: GLuint,
686 source_level: GLint,
687 dest_target: GLenum,
688 dest_id: GLuint,
689 dest_level: GLint,
690 internal_format: GLint,
691 dest_type: GLenum,
692 unpack_flip_y: GLboolean,
693 unpack_premultiply_alpha: GLboolean,
694 unpack_unmultiply_alpha: GLboolean,
695 );
696 fn copy_sub_texture_chromium(
697 &self,
698 source_id: GLuint,
699 source_level: GLint,
700 dest_target: GLenum,
701 dest_id: GLuint,
702 dest_level: GLint,
703 x_offset: GLint,
704 y_offset: GLint,
705 x: GLint,
706 y: GLint,
707 width: GLsizei,
708 height: GLsizei,
709 unpack_flip_y: GLboolean,
710 unpack_premultiply_alpha: GLboolean,
711 unpack_unmultiply_alpha: GLboolean,
712 );
713
714 // GL_ANGLE_copy_texture_3d
715 fn copy_texture_3d_angle(
716 &self,
717 source_id: GLuint,
718 source_level: GLint,
719 dest_target: GLenum,
720 dest_id: GLuint,
721 dest_level: GLint,
722 internal_format: GLint,
723 dest_type: GLenum,
724 unpack_flip_y: GLboolean,
725 unpack_premultiply_alpha: GLboolean,
726 unpack_unmultiply_alpha: GLboolean,
727 );
728
729 fn copy_sub_texture_3d_angle(
730 &self,
731 source_id: GLuint,
732 source_level: GLint,
733 dest_target: GLenum,
734 dest_id: GLuint,
735 dest_level: GLint,
736 x_offset: GLint,
737 y_offset: GLint,
738 z_offset: GLint,
739 x: GLint,
740 y: GLint,
741 z: GLint,
742 width: GLsizei,
743 height: GLsizei,
744 depth: GLsizei,
745 unpack_flip_y: GLboolean,
746 unpack_premultiply_alpha: GLboolean,
747 unpack_unmultiply_alpha: GLboolean,
748 );
749
750 fn buffer_storage(
751 &self,
752 target: GLenum,
753 size: GLsizeiptr,
754 data: *const GLvoid,
755 flags: GLbitfield,
756 );
757
758 fn flush_mapped_buffer_range(&self, target: GLenum, offset: GLintptr, length: GLsizeiptr);
759 }
760
761 //#[deprecated(since = "0.6.11", note = "use ErrorReactingGl instead")]
762 pub struct ErrorCheckingGl {
763 gl: Rc<dyn Gl>,
764 }
765
766 impl ErrorCheckingGl {
wrap(fns: Rc<dyn Gl>) -> Rc<dyn Gl>767 pub fn wrap(fns: Rc<dyn Gl>) -> Rc<dyn Gl> {
768 Rc::new(ErrorCheckingGl { gl: fns }) as Rc<dyn Gl>
769 }
770 }
771
772 /// A wrapper around GL context that calls a specified callback on each GL error.
773 pub struct ErrorReactingGl<F> {
774 gl: Rc<dyn Gl>,
775 callback: F,
776 }
777
778 impl<F: 'static + Fn(&dyn Gl, &str, GLenum)> ErrorReactingGl<F> {
wrap(fns: Rc<dyn Gl>, callback: F) -> Rc<dyn Gl>779 pub fn wrap(fns: Rc<dyn Gl>, callback: F) -> Rc<dyn Gl> {
780 Rc::new(ErrorReactingGl { gl: fns, callback }) as Rc<dyn Gl>
781 }
782 }
783
784 /// A wrapper around GL context that times each call and invokes the callback
785 /// if the call takes longer than the threshold.
786 pub struct ProfilingGl<F> {
787 gl: Rc<dyn Gl>,
788 threshold: Duration,
789 callback: F,
790 }
791
792 impl<F: 'static + Fn(&str, Duration)> ProfilingGl<F> {
wrap(fns: Rc<dyn Gl>, threshold: Duration, callback: F) -> Rc<dyn Gl>793 pub fn wrap(fns: Rc<dyn Gl>, threshold: Duration, callback: F) -> Rc<dyn Gl> {
794 Rc::new(ProfilingGl {
795 gl: fns,
796 threshold,
797 callback,
798 }) as Rc<dyn Gl>
799 }
800 }
801
802 #[inline]
buffer_data<T>(gl_: &dyn Gl, target: GLenum, data: &[T], usage: GLenum)803 pub fn buffer_data<T>(gl_: &dyn Gl, target: GLenum, data: &[T], usage: GLenum) {
804 gl_.buffer_data_untyped(
805 target,
806 (data.len() * size_of::<T>()) as GLsizeiptr,
807 data.as_ptr() as *const GLvoid,
808 usage,
809 )
810 }
811
812 #[inline]
buffer_data_raw<T>(gl_: &dyn Gl, target: GLenum, data: &T, usage: GLenum)813 pub fn buffer_data_raw<T>(gl_: &dyn Gl, target: GLenum, data: &T, usage: GLenum) {
814 gl_.buffer_data_untyped(
815 target,
816 size_of::<T>() as GLsizeiptr,
817 data as *const T as *const GLvoid,
818 usage,
819 )
820 }
821
822 #[inline]
buffer_sub_data<T>(gl_: &dyn Gl, target: GLenum, offset: isize, data: &[T])823 pub fn buffer_sub_data<T>(gl_: &dyn Gl, target: GLenum, offset: isize, data: &[T]) {
824 gl_.buffer_sub_data_untyped(
825 target,
826 offset,
827 (data.len() * size_of::<T>()) as GLsizeiptr,
828 data.as_ptr() as *const GLvoid,
829 );
830 }
831
832 include!("gl_fns.rs");
833 include!("gles_fns.rs");
834