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