diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 19:33:14 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 19:33:14 +0000 |
commit | 36d22d82aa202bb199967e9512281e9a53db42c9 (patch) | |
tree | 105e8c98ddea1c1e4784a60a5a6410fa416be2de /gfx/wr/swgl/src/swgl_fns.rs | |
parent | Initial commit. (diff) | |
download | firefox-esr-36d22d82aa202bb199967e9512281e9a53db42c9.tar.xz firefox-esr-36d22d82aa202bb199967e9512281e9a53db42c9.zip |
Adding upstream version 115.7.0esr.upstream/115.7.0esr
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'gfx/wr/swgl/src/swgl_fns.rs')
-rw-r--r-- | gfx/wr/swgl/src/swgl_fns.rs | 2489 |
1 files changed, 2489 insertions, 0 deletions
diff --git a/gfx/wr/swgl/src/swgl_fns.rs b/gfx/wr/swgl/src/swgl_fns.rs new file mode 100644 index 0000000000..79669bd205 --- /dev/null +++ b/gfx/wr/swgl/src/swgl_fns.rs @@ -0,0 +1,2489 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +#![allow(unused_variables)] + +use gleam::gl::*; +use std::ffi::{CStr, CString}; +use std::os::raw::{c_char, c_int, c_void}; +use std::ptr; +use std::str; + +#[allow(unused)] +macro_rules! debug { + ($($x:tt)*) => {}; +} + +#[repr(C)] +struct LockedTexture { + _private: [u8; 0], +} + +#[allow(dead_code)] +extern "C" { + fn ActiveTexture(texture: GLenum); + fn BindTexture(target: GLenum, texture: GLuint); + fn BindBuffer(target: GLenum, buffer: GLuint); + fn BindVertexArray(vao: GLuint); + fn BindFramebuffer(target: GLenum, fb: GLuint); + fn BindRenderbuffer(target: GLenum, rb: GLuint); + fn BlendFunc(srgb: GLenum, drgb: GLenum, sa: GLenum, da: GLenum); + fn BlendColor(r: GLfloat, g: GLfloat, b: GLfloat, a: GLfloat); + fn BlendEquation(mode: GLenum); + fn Enable(cap: GLenum); + fn Disable(cap: GLenum); + fn GenQueries(n: GLsizei, result: *mut GLuint); + fn BeginQuery(target: GLenum, id: GLuint); + fn EndQuery(target: GLenum); + fn GetQueryObjectui64v(id: GLuint, pname: GLenum, params: *mut GLuint64); + fn GenBuffers(n: i32, result: *mut GLuint); + fn GenTextures(n: i32, result: *mut GLuint); + fn GenFramebuffers(n: i32, result: *mut GLuint); + fn GenRenderbuffers(n: i32, result: *mut GLuint); + fn BufferData(target: GLenum, size: GLsizeiptr, data: *const GLvoid, usage: GLenum); + fn BufferSubData(target: GLenum, offset: GLintptr, size: GLsizeiptr, data: *const GLvoid); + fn MapBuffer(target: GLenum, access: GLbitfield) -> *mut c_void; + fn MapBufferRange( + target: GLenum, + offset: GLintptr, + length: GLsizeiptr, + access: GLbitfield, + ) -> *mut c_void; + fn UnmapBuffer(target: GLenum) -> GLboolean; + fn TexStorage2D( + target: GLenum, + levels: GLint, + internal_format: GLenum, + width: GLsizei, + height: GLsizei, + ); + fn FramebufferTexture2D( + target: GLenum, + attachment: GLenum, + textarget: GLenum, + texture: GLuint, + level: GLint, + ); + fn CheckFramebufferStatus(target: GLenum) -> GLenum; + fn InvalidateFramebuffer(target: GLenum, num_attachments: GLsizei, attachments: *const GLenum); + fn TexImage2D( + target: GLenum, + level: GLint, + internal_format: GLint, + width: GLsizei, + height: GLsizei, + border: GLint, + format: GLenum, + ty: GLenum, + data: *const c_void, + ); + fn TexSubImage2D( + target: GLenum, + level: GLint, + xoffset: GLint, + yoffset: GLint, + width: GLsizei, + height: GLsizei, + format: GLenum, + ty: GLenum, + data: *const c_void, + ); + fn GenerateMipmap(target: GLenum); + fn GetUniformLocation(program: GLuint, name: *const GLchar) -> GLint; + fn BindAttribLocation(program: GLuint, index: GLuint, name: *const GLchar); + fn GetAttribLocation(program: GLuint, name: *const GLchar) -> GLint; + fn GenVertexArrays(n: i32, result: *mut GLuint); + fn VertexAttribPointer( + index: GLuint, + size: GLint, + type_: GLenum, + normalized: GLboolean, + stride: GLsizei, + offset: *const GLvoid, + ); + fn VertexAttribIPointer( + index: GLuint, + size: GLint, + type_: GLenum, + stride: GLsizei, + offset: *const GLvoid, + ); + fn CreateShader(shader_type: GLenum) -> GLuint; + fn AttachShader(program: GLuint, shader: GLuint); + fn CreateProgram() -> GLuint; + fn Uniform1i(location: GLint, v0: GLint); + fn Uniform4fv(location: GLint, count: GLsizei, value: *const GLfloat); + fn UniformMatrix4fv( + location: GLint, + count: GLsizei, + transpose: GLboolean, + value: *const GLfloat, + ); + fn DrawElementsInstanced( + mode: GLenum, + count: GLsizei, + type_: GLenum, + indices: GLintptr, + instancecount: GLsizei, + ); + fn EnableVertexAttribArray(index: GLuint); + fn VertexAttribDivisor(index: GLuint, divisor: GLuint); + fn LinkProgram(program: GLuint); + fn GetLinkStatus(program: GLuint) -> GLint; + fn UseProgram(program: GLuint); + fn SetViewport(x: GLint, y: GLint, width: GLsizei, height: GLsizei); + fn FramebufferRenderbuffer( + target: GLenum, + attachment: GLenum, + renderbuffertarget: GLenum, + renderbuffer: GLuint, + ); + fn RenderbufferStorage(target: GLenum, internalformat: GLenum, width: GLsizei, height: GLsizei); + fn DepthMask(flag: GLboolean); + fn DepthFunc(func: GLenum); + fn SetScissor(x: GLint, y: GLint, width: GLsizei, height: GLsizei); + fn ClearColor(r: GLfloat, g: GLfloat, b: GLfloat, a: GLfloat); + fn ClearDepth(depth: GLdouble); + fn Clear(mask: GLbitfield); + fn ClearTexSubImage( + target: GLenum, + level: GLint, + xoffset: GLint, + yoffset: GLint, + zoffset: GLint, + width: GLsizei, + height: GLsizei, + depth: GLsizei, + format: GLenum, + ty: GLenum, + data: *const c_void, + ); + fn ClearTexImage(target: GLenum, level: GLint, format: GLenum, ty: GLenum, data: *const c_void); + fn ClearColorRect( + fbo: GLuint, + xoffset: GLint, + yoffset: GLint, + width: GLsizei, + height: GLsizei, + r: GLfloat, + g: GLfloat, + b: GLfloat, + a: GLfloat, + ); + fn PixelStorei(name: GLenum, param: GLint); + fn ReadPixels( + x: GLint, + y: GLint, + width: GLsizei, + height: GLsizei, + format: GLenum, + ty: GLenum, + data: *mut c_void, + ); + fn Finish(); + fn ShaderSourceByName(shader: GLuint, name: *const GLchar); + fn TexParameteri(target: GLenum, pname: GLenum, param: GLint); + fn CopyImageSubData( + src_name: GLuint, + src_target: GLenum, + src_level: GLint, + src_x: GLint, + src_y: GLint, + src_z: GLint, + dst_name: GLuint, + dst_target: GLenum, + dst_level: GLint, + dst_x: GLint, + dst_y: GLint, + dst_z: GLint, + src_width: GLsizei, + src_height: GLsizei, + src_depth: GLsizei, + ); + fn CopyTexSubImage2D( + target: GLenum, + level: GLint, + xoffset: GLint, + yoffset: GLint, + x: GLint, + y: GLint, + width: GLsizei, + height: GLsizei, + ); + fn BlitFramebuffer( + 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, + ); + fn GetIntegerv(pname: GLenum, params: *mut GLint); + fn GetBooleanv(pname: GLenum, params: *mut GLboolean); + fn GetString(name: GLenum) -> *const c_char; + fn GetStringi(name: GLenum, index: GLuint) -> *const c_char; + fn GetError() -> GLenum; + fn InitDefaultFramebuffer( + x: i32, + y: i32, + width: i32, + height: i32, + stride: i32, + buf: *mut c_void, + ); + fn GetColorBuffer( + fbo: GLuint, + flush: GLboolean, + width: *mut i32, + height: *mut i32, + stride: *mut i32, + ) -> *mut c_void; + fn ResolveFramebuffer(fbo: GLuint); + fn SetTextureBuffer( + tex: GLuint, + internal_format: GLenum, + width: GLsizei, + height: GLsizei, + stride: GLsizei, + buf: *mut c_void, + min_width: GLsizei, + min_height: GLsizei, + ); + fn SetTextureParameter(tex: GLuint, pname: GLenum, param: GLint); + fn DeleteTexture(n: GLuint); + fn DeleteRenderbuffer(n: GLuint); + fn DeleteFramebuffer(n: GLuint); + fn DeleteBuffer(n: GLuint); + fn DeleteVertexArray(n: GLuint); + fn DeleteQuery(n: GLuint); + fn DeleteShader(shader: GLuint); + fn DeleteProgram(program: GLuint); + fn LockFramebuffer(fbo: GLuint) -> *mut LockedTexture; + fn LockTexture(tex: GLuint) -> *mut LockedTexture; + fn LockResource(resource: *mut LockedTexture); + fn UnlockResource(resource: *mut LockedTexture); + fn GetResourceBuffer( + resource: *mut LockedTexture, + width: *mut i32, + height: *mut i32, + stride: *mut i32, + ) -> *mut c_void; + fn Composite( + locked_dst: *mut LockedTexture, + locked_src: *mut LockedTexture, + src_x: GLint, + src_y: GLint, + src_width: GLsizei, + src_height: GLsizei, + dst_x: GLint, + dst_y: GLint, + dst_width: GLsizei, + dst_height: GLsizei, + opaque: GLboolean, + flip_x: GLboolean, + flip_y: GLboolean, + filter: GLenum, + clip_x: GLint, + clip_y: GLint, + clip_width: GLsizei, + clip_height: GLsizei, + ); + fn CompositeYUV( + locked_dst: *mut LockedTexture, + locked_y: *mut LockedTexture, + locked_u: *mut LockedTexture, + locked_v: *mut LockedTexture, + color_space: YuvRangedColorSpace, + color_depth: GLuint, + src_x: GLint, + src_y: GLint, + src_width: GLsizei, + src_height: GLsizei, + dst_x: GLint, + dst_y: GLint, + dst_width: GLsizei, + dst_height: GLsizei, + flip_x: GLboolean, + flip_y: GLboolean, + clip_x: GLint, + clip_y: GLint, + clip_width: GLsizei, + clip_height: GLsizei, + ); + fn CreateContext() -> *mut c_void; + fn ReferenceContext(ctx: *mut c_void); + fn DestroyContext(ctx: *mut c_void); + fn MakeCurrent(ctx: *mut c_void); + fn ReportMemory(ctx: *mut c_void, size_of_op: unsafe extern "C" fn(ptr: *const c_void) -> usize) -> usize; +} + +#[derive(Clone, Copy)] +pub struct Context(*mut c_void); + +impl Context { + pub fn create() -> Self { + Context(unsafe { CreateContext() }) + } + + pub fn reference(&self) { + unsafe { + ReferenceContext(self.0); + } + } + + pub fn destroy(&self) { + unsafe { + DestroyContext(self.0); + } + } + + pub fn make_current(&self) { + unsafe { + MakeCurrent(self.0); + } + } + + pub fn init_default_framebuffer( + &self, + x: i32, + y: i32, + width: i32, + height: i32, + stride: i32, + buf: *mut c_void, + ) { + unsafe { + InitDefaultFramebuffer(x, y, width, height, stride, buf); + } + } + + pub fn get_color_buffer(&self, fbo: GLuint, flush: bool) -> (*mut c_void, i32, i32, i32) { + unsafe { + let mut width: i32 = 0; + let mut height: i32 = 0; + let mut stride: i32 = 0; + let data_ptr = GetColorBuffer( + fbo, + flush as GLboolean, + &mut width, + &mut height, + &mut stride, + ); + (data_ptr, width, height, stride) + } + } + + pub fn resolve_framebuffer(&self, fbo: GLuint) { + unsafe { + ResolveFramebuffer(fbo); + } + } + + pub fn clear_color_rect( + &self, + fbo: GLuint, + xoffset: GLint, + yoffset: GLint, + width: GLsizei, + height: GLsizei, + r: f32, + g: f32, + b: f32, + a: f32, + ) { + unsafe { + ClearColorRect(fbo, xoffset, yoffset, width, height, r, g, b, a); + } + } + + pub fn set_texture_buffer( + &self, + tex: GLuint, + internal_format: GLenum, + width: GLsizei, + height: GLsizei, + stride: GLsizei, + buf: *mut c_void, + min_width: GLsizei, + min_height: GLsizei, + ) { + unsafe { + SetTextureBuffer( + tex, + internal_format, + width, + height, + stride, + buf, + min_width, + min_height, + ); + } + } + + pub fn set_texture_parameter(&self, tex: GLuint, pname: GLenum, param: GLint) { + unsafe { + SetTextureParameter(tex, pname, param); + } + } + + pub fn lock_framebuffer(&self, fbo: GLuint) -> Option<LockedResource> { + unsafe { + let resource = LockFramebuffer(fbo); + if resource != ptr::null_mut() { + Some(LockedResource(resource)) + } else { + None + } + } + } + + pub fn lock_texture(&self, tex: GLuint) -> Option<LockedResource> { + unsafe { + let resource = LockTexture(tex); + if resource != ptr::null_mut() { + Some(LockedResource(resource)) + } else { + None + } + } + } + + pub fn report_memory(&self, size_of_op: unsafe extern "C" fn(ptr: *const c_void) -> usize) -> usize { + unsafe { ReportMemory(self.0, size_of_op) } + } +} + +impl From<*mut c_void> for Context { + fn from(ptr: *mut c_void) -> Self { + Context(ptr) + } +} + +impl From<Context> for *mut c_void { + fn from(ctx: Context) -> Self { + ctx.0 + } +} + +fn calculate_length(width: GLsizei, height: GLsizei, format: GLenum, pixel_type: GLenum) -> usize { + let colors = match format { + RED => 1, + RGB => 3, + BGR => 3, + + RGBA => 4, + BGRA => 4, + + ALPHA => 1, + R16 => 1, + LUMINANCE => 1, + DEPTH_COMPONENT => 1, + _ => panic!("unsupported format for read_pixels: {:?}", format), + }; + let depth = match pixel_type { + UNSIGNED_BYTE => 1, + UNSIGNED_SHORT => 2, + SHORT => 2, + FLOAT => 4, + UNSIGNED_INT_8_8_8_8_REV => 1, + _ => panic!("unsupported pixel_type for read_pixels: {:?}", pixel_type), + }; + + return (width * height * colors * depth) as usize; +} + +impl Gl for Context { + fn get_type(&self) -> GlType { + GlType::Gl + } + + fn buffer_data_untyped( + &self, + target: GLenum, + size: GLsizeiptr, + data: *const GLvoid, + usage: GLenum, + ) { + debug!( + "buffer_data_untyped {} {} {:?} {}", + target, size, data, usage + ); + //panic!(); + unsafe { + BufferData(target, size, data, usage); + } + } + + fn buffer_sub_data_untyped( + &self, + target: GLenum, + offset: isize, + size: GLsizeiptr, + data: *const GLvoid, + ) { + debug!( + "buffer_sub_data_untyped {} {} {} {:?}", + target, offset, size, data + ); + //panic!(); + unsafe { + BufferSubData(target, offset, size, data); + } + } + + fn map_buffer(&self, target: GLenum, access: GLbitfield) -> *mut c_void { + unsafe { MapBuffer(target, access) } + } + + fn map_buffer_range( + &self, + target: GLenum, + offset: GLintptr, + length: GLsizeiptr, + access: GLbitfield, + ) -> *mut c_void { + unsafe { MapBufferRange(target, offset, length, access) } + } + + fn unmap_buffer(&self, target: GLenum) -> GLboolean { + unsafe { UnmapBuffer(target) } + } + + fn shader_source(&self, shader: GLuint, strings: &[&[u8]]) { + //panic!(); + debug!("shader_source {}", shader); + //for s in strings { + // debug!("{}", str::from_utf8(s).unwrap()); + //} + //panic!(); + for s in strings { + let u = str::from_utf8(s).unwrap(); + const PREFIX: &'static str = "// shader: "; + if let Some(start) = u.find(PREFIX) { + if let Some(end) = u[start..].find('\n') { + let name = u[start + PREFIX.len()..start + end].trim(); + debug!("shader name: {}", name); + unsafe { + let c_string = CString::new(name).unwrap(); + ShaderSourceByName(shader, c_string.as_ptr()); + return; + } + } + } + } + panic!("unknown shader"); + } + + fn tex_buffer(&self, target: GLenum, internal_format: GLenum, buffer: GLuint) { + panic!(); + } + + fn read_buffer(&self, mode: GLenum) { + panic!(); + } + + fn read_pixels_into_buffer( + &self, + x: GLint, + y: GLint, + width: GLsizei, + height: GLsizei, + format: GLenum, + pixel_type: GLenum, + dst_buffer: &mut [u8], + ) { + // Assumes that the user properly allocated the size for dst_buffer. + assert!(calculate_length(width, height, format, pixel_type) == dst_buffer.len()); + + unsafe { + ReadPixels( + x, + y, + width, + height, + format, + pixel_type, + dst_buffer.as_mut_ptr() as *mut c_void, + ); + } + } + + fn read_pixels( + &self, + x: GLint, + y: GLint, + width: GLsizei, + height: GLsizei, + format: GLenum, + pixel_type: GLenum, + ) -> Vec<u8> { + let len = calculate_length(width, height, format, pixel_type); + let mut pixels: Vec<u8> = Vec::new(); + pixels.reserve(len); + unsafe { + pixels.set_len(len); + } + + self.read_pixels_into_buffer( + x, + y, + width, + height, + format, + pixel_type, + pixels.as_mut_slice(), + ); + + pixels + } + + unsafe fn read_pixels_into_pbo( + &self, + x: GLint, + y: GLint, + width: GLsizei, + height: GLsizei, + format: GLenum, + pixel_type: GLenum, + ) { + ReadPixels(x, y, width, height, format, pixel_type, ptr::null_mut()); + } + + fn sample_coverage(&self, value: GLclampf, invert: bool) { + panic!(); + } + + fn polygon_offset(&self, factor: GLfloat, units: GLfloat) { + panic!(); + } + + fn pixel_store_i(&self, name: GLenum, param: GLint) { + //panic!(); + debug!("pixel_store_i {:x} {}", name, param); + unsafe { + PixelStorei(name, param); + } + } + + fn gen_buffers(&self, n: GLsizei) -> Vec<GLuint> { + //panic!(); + let mut result = vec![0 as GLuint; n as usize]; + unsafe { + GenBuffers(n, result.as_mut_ptr()); + } + result + } + + fn gen_renderbuffers(&self, n: GLsizei) -> Vec<GLuint> { + debug!("gen_renderbuffers {}", n); + //panic!(); + let mut result = vec![0 as GLuint; n as usize]; + unsafe { + GenRenderbuffers(n, result.as_mut_ptr()); + } + result + } + + fn gen_framebuffers(&self, n: GLsizei) -> Vec<GLuint> { + //panic!(); + debug!("gen_framebuffers {}", n); + let mut result = vec![0 as GLuint; n as usize]; + unsafe { + GenFramebuffers(n, result.as_mut_ptr()); + } + result + } + + fn gen_textures(&self, n: GLsizei) -> Vec<GLuint> { + //panic!(); + let mut result = vec![0 as GLuint; n as usize]; + unsafe { + GenTextures(n, result.as_mut_ptr()); + } + result + } + + fn gen_vertex_arrays(&self, n: GLsizei) -> Vec<GLuint> { + //panic!(); + let mut result = vec![0 as GLuint; n as usize]; + unsafe { + GenVertexArrays(n, result.as_mut_ptr()); + } + result + } + + fn gen_vertex_arrays_apple(&self, n: GLsizei) -> Vec<GLuint> { + self.gen_vertex_arrays(n) + } + + fn gen_queries(&self, n: GLsizei) -> Vec<GLuint> { + let mut result = vec![0 as GLuint; n as usize]; + unsafe { + GenQueries(n, result.as_mut_ptr()); + } + result + } + + fn begin_query(&self, target: GLenum, id: GLuint) { + unsafe { + BeginQuery(target, id); + } + } + + fn end_query(&self, target: GLenum) { + unsafe { + EndQuery(target); + } + } + + fn query_counter(&self, id: GLuint, target: GLenum) { + panic!(); + } + + fn get_query_object_iv(&self, id: GLuint, pname: GLenum) -> i32 { + panic!(); + //0 + } + + fn get_query_object_uiv(&self, id: GLuint, pname: GLenum) -> u32 { + panic!(); + //0 + } + + fn get_query_object_i64v(&self, id: GLuint, pname: GLenum) -> i64 { + panic!(); + //0 + } + + fn get_query_object_ui64v(&self, id: GLuint, pname: GLenum) -> u64 { + let mut result = 0; + unsafe { + GetQueryObjectui64v(id, pname, &mut result); + } + result + } + + fn delete_queries(&self, queries: &[GLuint]) { + unsafe { + for q in queries { + DeleteQuery(*q); + } + } + } + + fn delete_vertex_arrays(&self, vertex_arrays: &[GLuint]) { + unsafe { + for v in vertex_arrays { + DeleteVertexArray(*v); + } + } + } + + fn delete_vertex_arrays_apple(&self, vertex_arrays: &[GLuint]) { + self.delete_vertex_arrays(vertex_arrays) + } + + fn delete_buffers(&self, buffers: &[GLuint]) { + unsafe { + for b in buffers { + DeleteBuffer(*b); + } + } + } + + fn delete_renderbuffers(&self, renderbuffers: &[GLuint]) { + unsafe { + for r in renderbuffers { + DeleteRenderbuffer(*r); + } + } + } + + fn delete_framebuffers(&self, framebuffers: &[GLuint]) { + unsafe { + for f in framebuffers { + DeleteFramebuffer(*f); + } + } + } + + fn delete_textures(&self, textures: &[GLuint]) { + unsafe { + for t in textures { + DeleteTexture(*t); + } + } + } + + fn framebuffer_renderbuffer( + &self, + target: GLenum, + attachment: GLenum, + renderbuffertarget: GLenum, + renderbuffer: GLuint, + ) { + debug!( + "framebufer_renderbuffer {} {} {} {}", + target, attachment, renderbuffertarget, renderbuffer + ); + //panic!(); + unsafe { + FramebufferRenderbuffer(target, attachment, renderbuffertarget, renderbuffer); + } + } + + fn renderbuffer_storage( + &self, + target: GLenum, + internalformat: GLenum, + width: GLsizei, + height: GLsizei, + ) { + debug!( + "renderbuffer_storage {} {} {} {}", + target, internalformat, width, height + ); + //panic!(); + unsafe { + RenderbufferStorage(target, internalformat, width, height); + } + } + + fn depth_func(&self, func: GLenum) { + debug!("depth_func {}", func); + //panic!(); + unsafe { + DepthFunc(func); + } + } + + fn active_texture(&self, texture: GLenum) { + //panic!(); + unsafe { + ActiveTexture(texture); + } + } + + fn attach_shader(&self, program: GLuint, shader: GLuint) { + debug!("attach shader {} {}", program, shader); + //panic!(); + unsafe { + AttachShader(program, shader); + } + } + + fn bind_attrib_location(&self, program: GLuint, index: GLuint, name: &str) { + debug!("bind_attrib_location {} {} {}", program, index, name); + //panic!(); + let c_string = CString::new(name).unwrap(); + unsafe { BindAttribLocation(program, index, c_string.as_ptr()) } + } + + // https://www.khronos.org/registry/OpenGL-Refpages/es2.0/xhtml/glGetUniform.xml + unsafe fn get_uniform_iv(&self, program: GLuint, location: GLint, result: &mut [GLint]) { + panic!(); + //assert!(!result.is_empty()); + } + + // https://www.khronos.org/registry/OpenGL-Refpages/es2.0/xhtml/glGetUniform.xml + unsafe fn get_uniform_fv(&self, program: GLuint, location: GLint, result: &mut [GLfloat]) { + panic!(); + //assert!(!result.is_empty()); + } + + fn get_uniform_block_index(&self, program: GLuint, name: &str) -> GLuint { + panic!(); + //0 + } + + fn get_uniform_indices(&self, program: GLuint, names: &[&str]) -> Vec<GLuint> { + panic!(); + //Vec::new() + } + + fn bind_buffer_base(&self, target: GLenum, index: GLuint, buffer: GLuint) { + panic!(); + } + + fn bind_buffer_range( + &self, + target: GLenum, + index: GLuint, + buffer: GLuint, + offset: GLintptr, + size: GLsizeiptr, + ) { + panic!(); + } + + fn uniform_block_binding( + &self, + program: GLuint, + uniform_block_index: GLuint, + uniform_block_binding: GLuint, + ) { + panic!(); + } + + fn bind_buffer(&self, target: GLenum, buffer: GLuint) { + //panic!(); + unsafe { + BindBuffer(target, buffer); + } + } + + fn bind_vertex_array(&self, vao: GLuint) { + //panic!(); + unsafe { + BindVertexArray(vao); + } + } + + fn bind_vertex_array_apple(&self, vao: GLuint) { + self.bind_vertex_array(vao) + } + + fn bind_renderbuffer(&self, target: GLenum, renderbuffer: GLuint) { + debug!("bind_renderbuffer {} {}", target, renderbuffer); + //panic!(); + unsafe { + BindRenderbuffer(target, renderbuffer); + } + } + + fn bind_framebuffer(&self, target: GLenum, framebuffer: GLuint) { + debug!("bind_framebuffer {} {}", target, framebuffer); + //panic!(); + unsafe { + BindFramebuffer(target, framebuffer); + } + } + + fn bind_vertex_buffer( + &self, + binding_index: GLuint, + buffer: GLuint, + offset: GLintptr, + stride: GLint, + ) { + unimplemented!("Not supported by SWGL"); + } + + fn bind_texture(&self, target: GLenum, texture: GLuint) { + //panic!(); + unsafe { + BindTexture(target, texture); + } + } + + fn draw_buffers(&self, bufs: &[GLenum]) { + panic!(); + //unsafe {} + } + + // FIXME: Does not verify buffer size -- unsafe! + fn 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]>, + ) { + unsafe { + let pdata = match opt_data { + Some(data) => data.as_ptr() as *const GLvoid, + None => ptr::null(), + }; + TexImage2D( + target, + level, + internal_format, + width, + height, + border, + format, + ty, + pdata, + ); + } + } + + fn compressed_tex_image_2d( + &self, + target: GLenum, + level: GLint, + internal_format: GLenum, + width: GLsizei, + height: GLsizei, + border: GLint, + data: &[u8], + ) { + panic!(); + } + + fn compressed_tex_sub_image_2d( + &self, + target: GLenum, + level: GLint, + xoffset: GLint, + yoffset: GLint, + width: GLsizei, + height: GLsizei, + format: GLenum, + data: &[u8], + ) { + panic!(); + } + + fn 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]>, + ) { + panic!(); + } + + fn copy_tex_image_2d( + &self, + target: GLenum, + level: GLint, + internal_format: GLenum, + x: GLint, + y: GLint, + width: GLsizei, + height: GLsizei, + border: GLint, + ) { + panic!(); + } + + fn copy_tex_sub_image_2d( + &self, + target: GLenum, + level: GLint, + xoffset: GLint, + yoffset: GLint, + x: GLint, + y: GLint, + width: GLsizei, + height: GLsizei, + ) { + unsafe { + CopyTexSubImage2D(target, level, xoffset, yoffset, x, y, width, height); + } + } + + fn copy_tex_sub_image_3d( + &self, + target: GLenum, + level: GLint, + xoffset: GLint, + yoffset: GLint, + zoffset: GLint, + x: GLint, + y: GLint, + width: GLsizei, + height: GLsizei, + ) { + panic!(); + } + + fn tex_sub_image_2d( + &self, + target: GLenum, + level: GLint, + xoffset: GLint, + yoffset: GLint, + width: GLsizei, + height: GLsizei, + format: GLenum, + ty: GLenum, + data: &[u8], + ) { + debug!( + "tex_sub_image_2d {} {} {} {} {} {} {} {}", + target, level, xoffset, yoffset, width, height, format, ty + ); + //panic!(); + unsafe { + TexSubImage2D( + target, + level, + xoffset, + yoffset, + width, + height, + format, + ty, + data.as_ptr() as *const c_void, + ); + } + } + + fn tex_sub_image_2d_pbo( + &self, + target: GLenum, + level: GLint, + xoffset: GLint, + yoffset: GLint, + width: GLsizei, + height: GLsizei, + format: GLenum, + ty: GLenum, + offset: usize, + ) { + debug!( + "tex_sub_image_2d_pbo {} {} {} {} {} {} {} {} {}", + target, level, xoffset, yoffset, width, height, format, ty, offset + ); + //panic!(); + unsafe { + TexSubImage2D( + target, + level, + xoffset, + yoffset, + width, + height, + format, + ty, + offset as *const c_void, + ); + } + } + + fn 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], + ) { + debug!("tex_sub_image_3d"); + panic!(); + } + + fn 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, + ) { + panic!(); + } + + fn tex_storage_2d( + &self, + target: GLenum, + levels: GLint, + internal_format: GLenum, + width: GLsizei, + height: GLsizei, + ) { + //panic!(); + unsafe { + TexStorage2D(target, levels, internal_format, width, height); + } + } + + fn tex_storage_3d( + &self, + target: GLenum, + levels: GLint, + internal_format: GLenum, + width: GLsizei, + height: GLsizei, + depth: GLsizei, + ) { + panic!(); + } + + fn get_tex_image_into_buffer( + &self, + target: GLenum, + level: GLint, + format: GLenum, + ty: GLenum, + output: &mut [u8], + ) { + panic!(); + } + + unsafe fn copy_image_sub_data( + &self, + src_name: GLuint, + src_target: GLenum, + src_level: GLint, + src_x: GLint, + src_y: GLint, + src_z: GLint, + dst_name: GLuint, + dst_target: GLenum, + dst_level: GLint, + dst_x: GLint, + dst_y: GLint, + dst_z: GLint, + src_width: GLsizei, + src_height: GLsizei, + src_depth: GLsizei, + ) { + CopyImageSubData( + src_name, src_target, src_level, src_x, src_y, src_z, dst_name, dst_target, dst_level, + dst_x, dst_y, dst_z, src_width, src_height, src_depth, + ); + } + + fn invalidate_framebuffer(&self, target: GLenum, attachments: &[GLenum]) { + unsafe { + InvalidateFramebuffer(target, attachments.len() as GLsizei, attachments.as_ptr()); + } + } + + fn invalidate_sub_framebuffer( + &self, + target: GLenum, + attachments: &[GLenum], + xoffset: GLint, + yoffset: GLint, + width: GLsizei, + height: GLsizei, + ) { + } + + #[inline] + unsafe fn get_integer_v(&self, name: GLenum, result: &mut [GLint]) { + //panic!(); + assert!(!result.is_empty()); + GetIntegerv(name, result.as_mut_ptr()); + } + + #[inline] + unsafe fn get_integer_64v(&self, name: GLenum, result: &mut [GLint64]) { + panic!(); + //assert!(!result.is_empty()); + } + + #[inline] + unsafe fn get_integer_iv(&self, name: GLenum, index: GLuint, result: &mut [GLint]) { + panic!(); + //assert!(!result.is_empty()); + } + + #[inline] + unsafe fn get_integer_64iv(&self, name: GLenum, index: GLuint, result: &mut [GLint64]) { + panic!(); + //assert!(!result.is_empty()); + } + + #[inline] + unsafe fn get_boolean_v(&self, name: GLenum, result: &mut [GLboolean]) { + debug!("get_boolean_v {}", name); + //panic!(); + assert!(!result.is_empty()); + GetBooleanv(name, result.as_mut_ptr()); + } + + #[inline] + unsafe fn get_float_v(&self, name: GLenum, result: &mut [GLfloat]) { + panic!(); + //assert!(!result.is_empty()); + } + + fn get_framebuffer_attachment_parameter_iv( + &self, + target: GLenum, + attachment: GLenum, + pname: GLenum, + ) -> GLint { + panic!(); + //0 + } + + fn get_renderbuffer_parameter_iv(&self, target: GLenum, pname: GLenum) -> GLint { + panic!(); + //0 + } + + fn get_tex_parameter_iv(&self, target: GLenum, pname: GLenum) -> GLint { + panic!(); + //0 + } + + fn get_tex_parameter_fv(&self, target: GLenum, pname: GLenum) -> GLfloat { + panic!(); + //0.0 + } + + fn tex_parameter_i(&self, target: GLenum, pname: GLenum, param: GLint) { + //panic!(); + unsafe { + TexParameteri(target, pname, param); + } + } + + fn tex_parameter_f(&self, target: GLenum, pname: GLenum, param: GLfloat) { + panic!(); + } + + fn framebuffer_texture_2d( + &self, + target: GLenum, + attachment: GLenum, + textarget: GLenum, + texture: GLuint, + level: GLint, + ) { + debug!( + "framebuffer_texture_2d {} {} {} {} {}", + target, attachment, textarget, texture, level + ); + //panic!(); + unsafe { + FramebufferTexture2D(target, attachment, textarget, texture, level); + } + } + + fn framebuffer_texture_layer( + &self, + target: GLenum, + attachment: GLenum, + texture: GLuint, + level: GLint, + layer: GLint, + ) { + debug!( + "framebuffer_texture_layer {} {} {} {} {}", + target, attachment, texture, level, layer + ); + panic!(); + } + + fn 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, + ) { + unsafe { + BlitFramebuffer( + src_x0, src_y0, src_x1, src_y1, dst_x0, dst_y0, dst_x1, dst_y1, mask, filter, + ); + } + } + + fn vertex_attrib_4f(&self, index: GLuint, x: GLfloat, y: GLfloat, z: GLfloat, w: GLfloat) { + panic!(); + } + + fn vertex_attrib_binding(&self, attrib_index: GLuint, binding_index: GLuint) { + unimplemented!("Not supported by SWGL"); + } + + fn vertex_attrib_pointer_f32( + &self, + index: GLuint, + size: GLint, + normalized: bool, + stride: GLsizei, + offset: GLuint, + ) { + panic!(); + } + + fn vertex_attrib_pointer( + &self, + index: GLuint, + size: GLint, + type_: GLenum, + normalized: bool, + stride: GLsizei, + offset: GLuint, + ) { + debug!( + "vertex_attrib_pointer {} {} {} {} {} {}", + index, size, type_, normalized, stride, offset + ); + //panic!(); + unsafe { + VertexAttribPointer( + index, + size, + type_, + normalized as GLboolean, + stride, + offset as *const GLvoid, + ); + } + } + + fn vertex_attrib_i_pointer( + &self, + index: GLuint, + size: GLint, + type_: GLenum, + stride: GLsizei, + offset: GLuint, + ) { + debug!( + "vertex_attrib_i_pointer {} {} {} {} {}", + index, size, type_, stride, offset + ); + //panic!(); + unsafe { + VertexAttribIPointer(index, size, type_, stride, offset as *const GLvoid); + } + } + + fn vertex_attrib_divisor(&self, index: GLuint, divisor: GLuint) { + debug!("vertex_attrib_divisor {} {}", index, divisor); + //assert!(index == 0 && divisor == 0); + //panic!(); + unsafe { + VertexAttribDivisor(index, divisor); + } + } + + fn vertex_attrib_format( + &self, + attrib_index: GLuint, + size: GLint, + type_: GLenum, + normalized: bool, + relative_offset: GLuint, + ) { + unimplemented!("Not supported by SWGL"); + } + + fn vertex_attrib_i_format( + &self, + attrib_index: GLuint, + size: GLint, + type_: GLenum, + relative_offset: GLuint, + ) { + unimplemented!("Not supported by SWGL"); + } + + fn vertex_binding_divisor(&self, binding_index: GLuint, divisor: GLuint) { + unimplemented!("Not supported by SWGL"); + } + + fn viewport(&self, x: GLint, y: GLint, width: GLsizei, height: GLsizei) { + debug!("viewport {} {} {} {}", x, y, width, height); + //panic!(); + unsafe { + SetViewport(x, y, width, height); + } + } + + fn scissor(&self, x: GLint, y: GLint, width: GLsizei, height: GLsizei) { + //panic!(); + unsafe { + SetScissor(x, y, width, height); + } + } + + fn line_width(&self, width: GLfloat) { + panic!(); + } + + fn use_program(&self, program: GLuint) { + //panic!(); + unsafe { + UseProgram(program); + } + } + + fn validate_program(&self, program: GLuint) { + panic!(); + } + + fn draw_arrays(&self, mode: GLenum, first: GLint, count: GLsizei) { + unsafe { + DrawElementsInstanced(mode, count, NONE, first as GLintptr, 1); + } + } + + fn draw_arrays_instanced( + &self, + mode: GLenum, + first: GLint, + count: GLsizei, + primcount: GLsizei, + ) { + unsafe { + DrawElementsInstanced(mode, count, NONE, first as GLintptr, primcount); + } + } + + fn draw_elements( + &self, + mode: GLenum, + count: GLsizei, + element_type: GLenum, + indices_offset: GLuint, + ) { + debug!( + "draw_elements {} {} {} {} {}", + mode, count, element_type, indices_offset + ); + //panic!(); + unsafe { + DrawElementsInstanced(mode, count, element_type, indices_offset as GLintptr, 1); + } + } + + fn draw_elements_instanced( + &self, + mode: GLenum, + count: GLsizei, + element_type: GLenum, + indices_offset: GLuint, + primcount: GLsizei, + ) { + debug!( + "draw_elements_instanced {} {} {} {} {}", + mode, count, element_type, indices_offset, primcount + ); + //panic!(); + unsafe { + DrawElementsInstanced( + mode, + count, + element_type, + indices_offset as GLintptr, + primcount, + ); + } + } + + fn blend_color(&self, r: f32, g: f32, b: f32, a: f32) { + unsafe { + BlendColor(r, g, b, a); + } + } + + fn blend_func(&self, sfactor: GLenum, dfactor: GLenum) { + unsafe { + BlendFunc(sfactor, dfactor, sfactor, dfactor); + } + } + + fn blend_func_separate( + &self, + src_rgb: GLenum, + dest_rgb: GLenum, + src_alpha: GLenum, + dest_alpha: GLenum, + ) { + unsafe { + BlendFunc(src_rgb, dest_rgb, src_alpha, dest_alpha); + } + } + + fn blend_equation(&self, mode: GLenum) { + unsafe { + BlendEquation(mode); + } + } + + fn blend_equation_separate(&self, mode_rgb: GLenum, mode_alpha: GLenum) { + panic!(); + } + + fn color_mask(&self, r: bool, g: bool, b: bool, a: bool) { + panic!(); + } + + fn cull_face(&self, mode: GLenum) { + panic!(); + } + + fn front_face(&self, mode: GLenum) { + panic!(); + } + + fn enable(&self, cap: GLenum) { + debug!("enable {}", cap); + //panic!(); + unsafe { + Enable(cap); + } + } + + fn disable(&self, cap: GLenum) { + debug!("disable {}", cap); + //panic!(); + unsafe { + Disable(cap); + } + } + + fn hint(&self, param_name: GLenum, param_val: GLenum) { + panic!(); + } + + fn is_enabled(&self, cap: GLenum) -> GLboolean { + panic!(); + //0 + } + + fn is_shader(&self, shader: GLuint) -> GLboolean { + panic!(); + //0 + } + + fn is_texture(&self, texture: GLenum) -> GLboolean { + panic!(); + //0 + } + + fn is_framebuffer(&self, framebuffer: GLenum) -> GLboolean { + panic!(); + //0 + } + + fn is_renderbuffer(&self, renderbuffer: GLenum) -> GLboolean { + panic!(); + //0 + } + + fn check_frame_buffer_status(&self, target: GLenum) -> GLenum { + debug!("check_frame_buffer_status {}", target); + //panic!(); + unsafe { CheckFramebufferStatus(target) } + } + + fn enable_vertex_attrib_array(&self, index: GLuint) { + //panic!(); + debug!("enable_vertex_attrib_array {}", index); + unsafe { + EnableVertexAttribArray(index); + //assert_eq!(index, 0); + } + } + + fn disable_vertex_attrib_array(&self, index: GLuint) { + panic!(); + } + + fn uniform_1f(&self, location: GLint, v0: GLfloat) { + panic!(); + } + + fn uniform_1fv(&self, location: GLint, values: &[f32]) { + panic!(); + } + + fn uniform_1i(&self, location: GLint, v0: GLint) { + debug!("uniform_1i {} {}", location, v0); + //panic!(); + unsafe { + Uniform1i(location, v0); + } + } + + fn uniform_1iv(&self, location: GLint, values: &[i32]) { + panic!(); + } + + fn uniform_1ui(&self, location: GLint, v0: GLuint) { + panic!(); + } + + fn uniform_2f(&self, location: GLint, v0: GLfloat, v1: GLfloat) { + panic!(); + } + + fn uniform_2fv(&self, location: GLint, values: &[f32]) { + panic!(); + } + + fn uniform_2i(&self, location: GLint, v0: GLint, v1: GLint) { + panic!(); + } + + fn uniform_2iv(&self, location: GLint, values: &[i32]) { + panic!(); + } + + fn uniform_2ui(&self, location: GLint, v0: GLuint, v1: GLuint) { + panic!(); + } + + fn uniform_3f(&self, location: GLint, v0: GLfloat, v1: GLfloat, v2: GLfloat) { + panic!(); + } + + fn uniform_3fv(&self, location: GLint, values: &[f32]) { + panic!(); + } + + fn uniform_3i(&self, location: GLint, v0: GLint, v1: GLint, v2: GLint) { + panic!(); + } + + fn uniform_3iv(&self, location: GLint, values: &[i32]) { + panic!(); + } + + fn uniform_3ui(&self, location: GLint, v0: GLuint, v1: GLuint, v2: GLuint) { + panic!(); + } + + fn uniform_4f(&self, location: GLint, x: GLfloat, y: GLfloat, z: GLfloat, w: GLfloat) { + panic!(); + } + + fn uniform_4i(&self, location: GLint, x: GLint, y: GLint, z: GLint, w: GLint) { + panic!(); + } + + fn uniform_4iv(&self, location: GLint, values: &[i32]) { + panic!(); + } + + fn uniform_4ui(&self, location: GLint, x: GLuint, y: GLuint, z: GLuint, w: GLuint) { + panic!(); + } + + fn uniform_4fv(&self, location: GLint, values: &[f32]) { + unsafe { + Uniform4fv(location, (values.len() / 4) as GLsizei, values.as_ptr()); + } + } + + fn uniform_matrix_2fv(&self, location: GLint, transpose: bool, value: &[f32]) { + panic!(); + } + + fn uniform_matrix_3fv(&self, location: GLint, transpose: bool, value: &[f32]) { + panic!(); + } + + fn uniform_matrix_4fv(&self, location: GLint, transpose: bool, value: &[f32]) { + debug!("uniform_matrix_4fv {} {} {:?}", location, transpose, value); + //panic!(); + unsafe { + UniformMatrix4fv( + location, + (value.len() / 16) as GLsizei, + transpose as GLboolean, + value.as_ptr(), + ); + } + } + + fn depth_mask(&self, flag: bool) { + debug!("depth_mask {}", flag); + //panic!(); + unsafe { + DepthMask(flag as GLboolean); + } + } + + fn depth_range(&self, near: f64, far: f64) { + panic!(); + } + + fn get_active_attrib(&self, program: GLuint, index: GLuint) -> (i32, u32, String) { + panic!(); + //(0, 0, String::new()) + } + + fn get_active_uniform(&self, program: GLuint, index: GLuint) -> (i32, u32, String) { + panic!(); + //(0, 0, String::new()) + } + + fn get_active_uniforms_iv( + &self, + program: GLuint, + indices: Vec<GLuint>, + pname: GLenum, + ) -> Vec<GLint> { + panic!(); + //Vec::new() + } + + fn get_active_uniform_block_i(&self, program: GLuint, index: GLuint, pname: GLenum) -> GLint { + panic!(); + //0 + } + + fn get_active_uniform_block_iv( + &self, + program: GLuint, + index: GLuint, + pname: GLenum, + ) -> Vec<GLint> { + panic!(); + //Vec::new() + } + + fn get_active_uniform_block_name(&self, program: GLuint, index: GLuint) -> String { + panic!(); + //String::new() + } + + fn get_attrib_location(&self, program: GLuint, name: &str) -> c_int { + let name = CString::new(name).unwrap(); + unsafe { GetAttribLocation(program, name.as_ptr()) } + } + + fn get_frag_data_location(&self, program: GLuint, name: &str) -> c_int { + panic!(); + //0 + } + + fn get_uniform_location(&self, program: GLuint, name: &str) -> c_int { + debug!("get_uniform_location {} {}", program, name); + //panic!(); + let name = CString::new(name).unwrap(); + unsafe { GetUniformLocation(program, name.as_ptr()) } + } + + fn get_program_info_log(&self, program: GLuint) -> String { + debug!("get_program_info_log {}", program); + String::new() + } + + #[inline] + unsafe fn get_program_iv(&self, program: GLuint, pname: GLenum, result: &mut [GLint]) { + debug!("get_program_iv {}", pname); + //panic!(); + assert!(!result.is_empty()); + //#define GL_LINK_STATUS 0x8B82 + if pname == 0x8b82 { + result[0] = GetLinkStatus(program); + } + } + + fn get_program_binary(&self, program: GLuint) -> (Vec<u8>, GLenum) { + panic!(); + //(Vec::new(), NONE) + } + + fn program_binary(&self, program: GLuint, format: GLenum, binary: &[u8]) { + panic!(); + } + + fn program_parameter_i(&self, program: GLuint, pname: GLenum, value: GLint) { + panic!(); + } + + #[inline] + unsafe fn get_vertex_attrib_iv(&self, index: GLuint, pname: GLenum, result: &mut [GLint]) { + panic!(); + //assert!(!result.is_empty()); + } + + #[inline] + unsafe fn get_vertex_attrib_fv(&self, index: GLuint, pname: GLenum, result: &mut [GLfloat]) { + panic!(); + //assert!(!result.is_empty()); + } + + fn get_vertex_attrib_pointer_v(&self, index: GLuint, pname: GLenum) -> GLsizeiptr { + panic!(); + //0 + } + + fn get_buffer_parameter_iv(&self, target: GLuint, pname: GLenum) -> GLint { + panic!(); + //0 + } + + fn get_shader_info_log(&self, shader: GLuint) -> String { + debug!("get_shader_info_log {}", shader); + //panic!(); + String::new() + } + + fn get_string(&self, which: GLenum) -> String { + // panic!(); + unsafe { + let llstr = GetString(which); + if !llstr.is_null() { + return str::from_utf8_unchecked(CStr::from_ptr(llstr).to_bytes()).to_string(); + } else { + return "".to_string(); + } + } + } + + fn get_string_i(&self, which: GLenum, index: GLuint) -> String { + //panic!(); + unsafe { + let llstr = GetStringi(which, index); + if !llstr.is_null() { + str::from_utf8_unchecked(CStr::from_ptr(llstr).to_bytes()).to_string() + } else { + "".to_string() + } + } + } + + unsafe fn get_shader_iv(&self, shader: GLuint, pname: GLenum, result: &mut [GLint]) { + debug!("get_shader_iv"); + //panic!(); + assert!(!result.is_empty()); + if pname == 0x8B81 + /*gl::COMPILE_STATUS*/ + { + result[0] = 1; + } + } + + fn get_shader_precision_format( + &self, + _shader_type: GLuint, + precision_type: GLuint, + ) -> (GLint, GLint, GLint) { + // gl.GetShaderPrecisionFormat is not available until OpenGL 4.1. + // Fallback to OpenGL standard precissions that most desktop hardware support. + match precision_type { + LOW_FLOAT | MEDIUM_FLOAT | HIGH_FLOAT => { + // Fallback to IEEE 754 single precision + // Range: from -2^127 to 2^127 + // Significand precision: 23 bits + (127, 127, 23) + } + LOW_INT | MEDIUM_INT | HIGH_INT => { + // Fallback to single precision integer + // Range: from -2^24 to 2^24 + // Precision: For integer formats this value is always 0 + (24, 24, 0) + } + _ => (0, 0, 0), + } + } + + fn compile_shader(&self, shader: GLuint) { + debug!("compile_shader {}", shader); + //panic!(); + } + + fn create_program(&self) -> GLuint { + debug!("create_program"); + //panic!(); + unsafe { CreateProgram() } + } + + fn delete_program(&self, program: GLuint) { + unsafe { + DeleteProgram(program); + } + } + + fn create_shader(&self, shader_type: GLenum) -> GLuint { + debug!("create_shader {}", shader_type); + //panic!(); + unsafe { CreateShader(shader_type) } + } + + fn delete_shader(&self, shader: GLuint) { + debug!("delete_shader {}", shader); + //panic!(); + unsafe { + DeleteShader(shader); + } + } + + fn detach_shader(&self, program: GLuint, shader: GLuint) { + debug!("detach_shader {} {}", program, shader); + //panic!(); + } + + fn link_program(&self, program: GLuint) { + debug!("link_program {}", program); + //panic!(); + unsafe { + LinkProgram(program); + } + } + + fn clear_color(&self, r: f32, g: f32, b: f32, a: f32) { + //panic!(); + unsafe { + ClearColor(r, g, b, a); + } + } + + fn clear(&self, buffer_mask: GLbitfield) { + debug!("clear {}", buffer_mask); + //panic!(); + unsafe { + Clear(buffer_mask); + } + } + + fn clear_depth(&self, depth: f64) { + debug!("clear_depth {}", depth); + //panic!(); + unsafe { + ClearDepth(depth as GLclampd); + } + } + + fn clear_stencil(&self, s: GLint) { + panic!(); + } + + fn flush(&self) {} + + fn finish(&self) { + unsafe { + Finish(); + } + } + + fn get_error(&self) -> GLenum { + //panic!(); + unsafe { GetError() } + } + + fn stencil_mask(&self, mask: GLuint) { + panic!(); + } + + fn stencil_mask_separate(&self, face: GLenum, mask: GLuint) { + panic!(); + } + + fn stencil_func(&self, func: GLenum, ref_: GLint, mask: GLuint) { + panic!(); + } + + fn stencil_func_separate(&self, face: GLenum, func: GLenum, ref_: GLint, mask: GLuint) { + panic!(); + } + + fn stencil_op(&self, sfail: GLenum, dpfail: GLenum, dppass: GLenum) { + panic!(); + } + + fn stencil_op_separate(&self, face: GLenum, sfail: GLenum, dpfail: GLenum, dppass: GLenum) { + panic!(); + } + + fn egl_image_target_texture2d_oes(&self, target: GLenum, image: GLeglImageOES) { + panic!("not supported") + } + + fn egl_image_target_renderbuffer_storage_oes(&self, target: GLenum, image: GLeglImageOES) { + panic!("not supported") + } + + fn generate_mipmap(&self, target: GLenum) { + unsafe { + GenerateMipmap(target); + } + } + + fn insert_event_marker_ext(&self, message: &str) { + panic!(); + } + + fn push_group_marker_ext(&self, message: &str) { + debug!("push group {}", message); + panic!(); + } + + fn pop_group_marker_ext(&self) { + debug!("pop group"); + panic!(); + } + + fn debug_message_insert_khr( + &self, + source: GLenum, + type_: GLenum, + id: GLuint, + severity: GLenum, + message: &str, + ) { + panic!(); + } + + fn push_debug_group_khr(&self, source: GLenum, id: GLuint, message: &str) { + panic!(); + } + + fn pop_debug_group_khr(&self) { + panic!(); + } + + fn fence_sync(&self, condition: GLenum, flags: GLbitfield) -> GLsync { + panic!(); + //ptr::null() + } + + fn client_wait_sync(&self, sync: GLsync, flags: GLbitfield, timeout: GLuint64) -> GLenum { + panic!(); + } + + fn wait_sync(&self, sync: GLsync, flags: GLbitfield, timeout: GLuint64) { + panic!(); + } + + fn texture_range_apple(&self, target: GLenum, data: &[u8]) { + panic!(); + } + + fn delete_sync(&self, sync: GLsync) { + panic!(); + } + + fn gen_fences_apple(&self, n: GLsizei) -> Vec<GLuint> { + panic!(); + //Vec::new() + } + + fn delete_fences_apple(&self, fences: &[GLuint]) { + panic!(); + } + + fn set_fence_apple(&self, fence: GLuint) { + panic!(); + } + + fn finish_fence_apple(&self, fence: GLuint) { + panic!(); + } + + fn test_fence_apple(&self, fence: GLuint) { + panic!(); + } + + fn test_object_apple(&self, object: GLenum, name: GLuint) -> GLboolean { + panic!(); + //0 + } + + fn finish_object_apple(&self, object: GLenum, name: GLuint) { + panic!(); + } + + // GL_ARB_blend_func_extended + fn bind_frag_data_location_indexed( + &self, + program: GLuint, + color_number: GLuint, + index: GLuint, + name: &str, + ) { + panic!(); + } + + fn get_frag_data_index(&self, program: GLuint, name: &str) -> GLint { + panic!(); + //-1 + } + + // GL_KHR_debug + fn get_debug_messages(&self) -> Vec<DebugMessage> { + Vec::new() + } + + fn provoking_vertex_angle(&self, _mode: GLenum) { + unimplemented!("This extension is GLES only"); + } + + // GL_KHR_blend_equation_advanced + fn blend_barrier_khr(&self) { + // No barrier required, so nothing to do + } + + // GL_CHROMIUM_copy_texture + fn copy_texture_chromium( + &self, + _source_id: GLuint, + _source_level: GLint, + _dest_target: GLenum, + _dest_id: GLuint, + _dest_level: GLint, + _internal_format: GLint, + _dest_type: GLenum, + _unpack_flip_y: GLboolean, + _unpack_premultiply_alpha: GLboolean, + _unpack_unmultiply_alpha: GLboolean, + ) { + unimplemented!("This extension is GLES only"); + } + fn copy_sub_texture_chromium( + &self, + _source_id: GLuint, + _source_level: GLint, + _dest_target: GLenum, + _dest_id: GLuint, + _dest_level: GLint, + _x_offset: GLint, + _y_offset: GLint, + _x: GLint, + _y: GLint, + _width: GLsizei, + _height: GLsizei, + _unpack_flip_y: GLboolean, + _unpack_premultiply_alpha: GLboolean, + _unpack_unmultiply_alpha: GLboolean, + ) { + unimplemented!("This extension is GLES only"); + } + + // GL_ANGLE_copy_texture_3d + fn copy_texture_3d_angle( + &self, + _source_id: GLuint, + _source_level: GLint, + _dest_target: GLenum, + _dest_id: GLuint, + _dest_level: GLint, + _internal_format: GLint, + _dest_type: GLenum, + _unpack_flip_y: GLboolean, + _unpack_premultiply_alpha: GLboolean, + _unpack_unmultiply_alpha: GLboolean, + ) { + unimplemented!("Not supported by SWGL"); + } + + fn copy_sub_texture_3d_angle( + &self, + _source_id: GLuint, + _source_level: GLint, + _dest_target: GLenum, + _dest_id: GLuint, + _dest_level: GLint, + _x_offset: GLint, + _y_offset: GLint, + _z_offset: GLint, + _x: GLint, + _y: GLint, + _z: GLint, + _width: GLsizei, + _height: GLsizei, + _depth: GLsizei, + _unpack_flip_y: GLboolean, + _unpack_premultiply_alpha: GLboolean, + _unpack_unmultiply_alpha: GLboolean, + ) { + unimplemented!("Not supported by SWGL"); + } + + fn buffer_storage( + &self, + target: GLenum, + size: GLsizeiptr, + data: *const GLvoid, + flags: GLbitfield, + ) { + unimplemented!("Not supported by SWGL"); + } + + fn flush_mapped_buffer_range(&self, target: GLenum, offset: GLintptr, length: GLsizeiptr) { + unimplemented!("Not supported by SWGL"); + } + + fn start_tiling_qcom( + &self, + x: GLuint, + y: GLuint, + width: GLuint, + height: GLuint, + preserve_mask: GLbitfield, + ) { + unimplemented!("Not supported by SWGL"); + } + + fn end_tiling_qcom(&self, preserve_mask: GLbitfield) { + unimplemented!("Not supported by SWGL"); + } +} + +/// A resource that is intended for sharing between threads. +/// Locked resources such as textures or framebuffers will +/// not allow any further modifications while it remains +/// locked. The resource will be unlocked when LockedResource +/// is dropped. +pub struct LockedResource(*mut LockedTexture); + +unsafe impl Send for LockedResource {} +unsafe impl Sync for LockedResource {} + +#[repr(u8)] +pub enum YuvRangedColorSpace { + Rec601Narrow = 0, + Rec601Full, + Rec709Narrow, + Rec709Full, + Rec2020Narrow, + Rec2020Full, + GbrIdentity, +} + +impl LockedResource { + /// Composites from a locked resource to another locked resource. The band + /// offset and height are relative to the destination rectangle and specify + /// how to clip the composition into appropriate range for this band. + pub fn composite( + &self, + locked_src: &LockedResource, + src_x: GLint, + src_y: GLint, + src_width: GLsizei, + src_height: GLsizei, + dst_x: GLint, + dst_y: GLint, + dst_width: GLsizei, + dst_height: GLsizei, + opaque: bool, + flip_x: bool, + flip_y: bool, + filter: GLenum, + clip_x: GLint, + clip_y: GLint, + clip_width: GLsizei, + clip_height: GLsizei, + ) { + unsafe { + Composite( + self.0, + locked_src.0, + src_x, + src_y, + src_width, + src_height, + dst_x, + dst_y, + dst_width, + dst_height, + opaque as GLboolean, + flip_x as GLboolean, + flip_y as GLboolean, + filter, + clip_x, + clip_y, + clip_width, + clip_height, + ); + } + } + + /// Composites from locked resources representing YUV planes + pub fn composite_yuv( + &self, + locked_y: &LockedResource, + locked_u: &LockedResource, + locked_v: &LockedResource, + color_space: YuvRangedColorSpace, + color_depth: GLuint, + src_x: GLint, + src_y: GLint, + src_width: GLsizei, + src_height: GLsizei, + dst_x: GLint, + dst_y: GLint, + dst_width: GLsizei, + dst_height: GLsizei, + flip_x: bool, + flip_y: bool, + clip_x: GLint, + clip_y: GLint, + clip_width: GLsizei, + clip_height: GLsizei, + ) { + unsafe { + CompositeYUV( + self.0, + locked_y.0, + locked_u.0, + locked_v.0, + color_space, + color_depth, + src_x, + src_y, + src_width, + src_height, + dst_x, + dst_y, + dst_width, + dst_height, + flip_x as GLboolean, + flip_y as GLboolean, + clip_x, + clip_y, + clip_width, + clip_height, + ); + } + } + + /// Get the underlying buffer for a locked resource + pub fn get_buffer(&self) -> (*mut c_void, i32, i32, i32) { + unsafe { + let mut width: i32 = 0; + let mut height: i32 = 0; + let mut stride: i32 = 0; + let data_ptr = GetResourceBuffer(self.0, &mut width, &mut height, &mut stride); + (data_ptr, width, height, stride) + } + } +} + +impl Clone for LockedResource { + fn clone(&self) -> Self { + unsafe { + LockResource(self.0); + } + LockedResource(self.0) + } +} + +impl Drop for LockedResource { + fn drop(&mut self) { + unsafe { + UnlockResource(self.0); + } + } +} |