Skip to content

Commit

Permalink
Merge pull request #207 from cmr/unsafe
Browse files Browse the repository at this point in the history
Make all GL functions unsafe
  • Loading branch information
emberian committed Nov 5, 2014
2 parents c713e4d + 7da8928 commit 678346e
Show file tree
Hide file tree
Showing 9 changed files with 74 additions and 98 deletions.
6 changes: 4 additions & 2 deletions examples/static_basic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,10 @@ fn main() {
glfw.poll_events();

// Clear the screen to black
gl::ClearColor(0.3, 0.3, 0.3, 1.0);
gl::Clear(gl::COLOR_BUFFER_BIT);
unsafe {
gl::ClearColor(0.3, 0.3, 0.3, 1.0);
gl::Clear(gl::COLOR_BUFFER_BIT);
}

// Swap buffers
window.swap_buffers();
Expand Down
51 changes: 26 additions & 25 deletions examples/static_triangle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,9 @@ fn start(argc: int, argv: *const *const u8) -> int {
}

fn compile_shader(src: &str, ty: GLenum) -> GLuint {
let shader = gl::CreateShader(ty);
let shader;
unsafe {
shader = gl::CreateShader(ty);
// Attempt to compile the shader
src.with_c_str(|ptr| gl::ShaderSource(shader, 1, &ptr, ptr::null()));
gl::CompileShader(shader);
Expand All @@ -75,27 +76,25 @@ fn compile_shader(src: &str, ty: GLenum) -> GLuint {
shader
}

fn link_program(vs: GLuint, fs: GLuint) -> GLuint {
fn link_program(vs: GLuint, fs: GLuint) -> GLuint { unsafe {
let program = gl::CreateProgram();
gl::AttachShader(program, vs);
gl::AttachShader(program, fs);
gl::LinkProgram(program);
unsafe {
// Get the link status
let mut status = gl::FALSE as GLint;
gl::GetProgramiv(program, gl::LINK_STATUS, &mut status);

// Fail on error
if status != (gl::TRUE as GLint) {
let mut len: GLint = 0;
gl::GetProgramiv(program, gl::INFO_LOG_LENGTH, &mut len);
let mut buf = Vec::from_elem(len as uint - 1, 0u8); // subtract 1 to skip the trailing null character
gl::GetProgramInfoLog(program, len, ptr::null_mut(), buf.as_mut_ptr() as *mut GLchar);
panic!("{}", str::from_utf8(buf.as_slice()).expect("ProgramInfoLog not valid utf8"));
}
// Get the link status
let mut status = gl::FALSE as GLint;
gl::GetProgramiv(program, gl::LINK_STATUS, &mut status);

// Fail on error
if status != (gl::TRUE as GLint) {
let mut len: GLint = 0;
gl::GetProgramiv(program, gl::INFO_LOG_LENGTH, &mut len);
let mut buf = Vec::from_elem(len as uint - 1, 0u8); // subtract 1 to skip the trailing null character
gl::GetProgramInfoLog(program, len, ptr::null_mut(), buf.as_mut_ptr() as *mut GLchar);
panic!("{}", str::from_utf8(buf.as_slice()).expect("ProgramInfoLog not valid utf8"));
}
program
}
} }

fn main() {
let glfw = glfw::init(glfw::FAIL_ON_ERRORS).unwrap();
Expand Down Expand Up @@ -150,22 +149,24 @@ fn main() {
// Poll events
glfw.poll_events();

// Clear the screen to black
gl::ClearColor(0.3, 0.3, 0.3, 1.0);
gl::Clear(gl::COLOR_BUFFER_BIT);
unsafe {
// Clear the screen to black
gl::ClearColor(0.3, 0.3, 0.3, 1.0);
gl::Clear(gl::COLOR_BUFFER_BIT);

// Draw a triangle from the 3 vertices
gl::DrawArrays(gl::TRIANGLES, 0, 3);
// Draw a triangle from the 3 vertices
gl::DrawArrays(gl::TRIANGLES, 0, 3);
}

// Swap buffers
window.swap_buffers();
}

// Cleanup
gl::DeleteProgram(program);
gl::DeleteShader(fs);
gl::DeleteShader(vs);
unsafe {
// Cleanup
gl::DeleteProgram(program);
gl::DeleteShader(fs);
gl::DeleteShader(vs);
gl::DeleteBuffers(1, &vbo);
gl::DeleteVertexArrays(1, &vao);
}
Expand Down
27 changes: 15 additions & 12 deletions examples/struct_triangle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,8 +70,9 @@ fn start(argc: int, argv: *const *const u8) -> int {
}

fn compile_shader(gl: &Gl, src: &str, ty: GLenum) -> GLuint {
let shader = gl.CreateShader(ty);
let shader;
unsafe {
shader = gl.CreateShader(ty);
// Attempt to compile the shader
src.with_c_str(|ptr| gl.ShaderSource(shader, 1, &ptr, ptr::null()));
gl.CompileShader(shader);
Expand All @@ -92,7 +93,7 @@ fn compile_shader(gl: &Gl, src: &str, ty: GLenum) -> GLuint {
shader
}

fn link_program(gl: &Gl, vs: GLuint, fs: GLuint) -> GLuint {
fn link_program(gl: &Gl, vs: GLuint, fs: GLuint) -> GLuint { unsafe {
let program = gl.CreateProgram();
gl.AttachShader(program, vs);
gl.AttachShader(program, fs);
Expand All @@ -112,7 +113,7 @@ fn link_program(gl: &Gl, vs: GLuint, fs: GLuint) -> GLuint {
}
}
program
}
}}

fn main() {
let glfw = glfw::init(glfw::FAIL_ON_ERRORS).unwrap();
Expand Down Expand Up @@ -167,22 +168,24 @@ fn main() {
// Poll events
glfw.poll_events();

// Clear the screen to black
gl.ClearColor(0.3, 0.3, 0.3, 1.0);
gl.Clear(gl::COLOR_BUFFER_BIT);
unsafe {
// Clear the screen to black
gl.ClearColor(0.3, 0.3, 0.3, 1.0);
gl.Clear(gl::COLOR_BUFFER_BIT);

// Draw a triangle from the 3 vertices
gl.DrawArrays(gl::TRIANGLES, 0, 3);
// Draw a triangle from the 3 vertices
gl.DrawArrays(gl::TRIANGLES, 0, 3);
}

// Swap buffers
window.swap_buffers();
}

// Cleanup
gl.DeleteProgram(program);
gl.DeleteShader(fs);
gl.DeleteShader(vs);
unsafe {
// Cleanup
gl.DeleteProgram(program);
gl.DeleteShader(fs);
gl.DeleteShader(vs);
gl.DeleteBuffers(1, &vbo);
gl.DeleteVertexArrays(1, &vao);
}
Expand Down
2 changes: 1 addition & 1 deletion src/gl/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@
//! gl::TEXTURE_2D;
//!
//! // calling a function
//! gl::DrawArrays(gl::TRIANGLES, 0, 3);
//! unsafe { gl::DrawArrays(gl::TRIANGLES, 0, 3) };
//!
//! // functions that take pointers are unsafe
//! # let shader = 0;
Expand Down
20 changes: 2 additions & 18 deletions src/gl_generator/generators/global_gen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -108,23 +108,7 @@ fn write_fns(ecx: &ExtCtxt, registry: &Registry) -> Vec<P<ast::Item>> {
None => "".to_string()
};

ecx.parse_item(if c.is_safe {
format!(
"#[allow(non_snake_case)] #[allow(unused_variables)] #[allow(dead_code)]
#[inline] #[unstable] {doc} pub fn {name}({params}) -> {return_suffix} {{ \
unsafe {{ \
__gl_imports::mem::transmute::<_, extern \"system\" fn({types}) -> {return_suffix}>\
(storage::{name}.f)({idents}) \
}} \
}}",
name = c.proto.ident,
doc = doc,
params = super::gen_parameters(ecx, c).into_iter().map(|p| p.to_source()).collect::<Vec<String>>().connect(", "),
types = super::gen_parameters(ecx, c).into_iter().map(|p| p.ty.to_source()).collect::<Vec<String>>().connect(", "),
return_suffix = super::gen_return_type(ecx, c).to_source(),
idents = super::gen_parameters(ecx, c).into_iter().map(|p| p.pat.to_source()).collect::<Vec<String>>().connect(", "),
)
} else {
ecx.parse_item(
format!(
"#[allow(non_snake_case)] #[allow(unused_variables)] #[allow(dead_code)]
#[inline] #[unstable] {doc} pub unsafe fn {name}({typed_params}) -> {return_suffix} {{ \
Expand All @@ -137,7 +121,7 @@ fn write_fns(ecx: &ExtCtxt, registry: &Registry) -> Vec<P<ast::Item>> {
return_suffix = super::gen_return_type(ecx, c).to_source(),
idents = super::gen_parameters(ecx, c).into_iter().map(|p| p.pat.to_source()).collect::<Vec<String>>().connect(", "),
)
})
)
}).collect()
}

Expand Down
39 changes: 11 additions & 28 deletions src/gl_generator/generators/struct_gen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -233,34 +233,17 @@ fn write_impl(ecx: &ExtCtxt, registry: &Registry, ns: &Ns) -> P<ast::Item> {
modules = registry.cmd_iter().map(|c| {
use syntax::ext::quote::rt::ToSource;

if c.is_safe {
format!(
"#[allow(non_snake_case)] #[allow(unused_variables)] #[allow(dead_code)]
#[inline] #[unstable] pub fn {name}(&self, {params}) -> {return_suffix} {{ \
unsafe {{ \
__gl_imports::mem::transmute::<_, extern \"system\" fn({types}) -> {return_suffix}>\
(self.{name}.f)({idents}) \
}} \
}}",
name = c.proto.ident,
params = super::gen_parameters(ecx, c).into_iter().map(|p| p.to_source()).collect::<Vec<String>>().connect(", "),
types = super::gen_parameters(ecx, c).into_iter().map(|p| p.ty.to_source()).collect::<Vec<String>>().connect(", "),
return_suffix = super::gen_return_type(ecx, c).to_source(),
idents = super::gen_parameters(ecx, c).into_iter().map(|p| p.pat.to_source()).collect::<Vec<String>>().connect(", "),
)
} else {
format!(
"#[allow(non_snake_case)] #[allow(unused_variables)] #[allow(dead_code)]
#[inline] #[unstable] pub unsafe fn {name}(&self, {typed_params}) -> {return_suffix} {{ \
__gl_imports::mem::transmute::<_, extern \"system\" fn({typed_params}) -> {return_suffix}>\
(self.{name}.f)({idents}) \
}}",
name = c.proto.ident,
typed_params = super::gen_parameters(ecx, c).into_iter().map(|p| p.to_source()).collect::<Vec<String>>().connect(", "),
return_suffix = super::gen_return_type(ecx, c).to_source(),
idents = super::gen_parameters(ecx, c).into_iter().map(|p| p.pat.to_source()).collect::<Vec<String>>().connect(", "),
)
}
format!(
"#[allow(non_snake_case)] #[allow(unused_variables)] #[allow(dead_code)]
#[inline] #[unstable] pub unsafe fn {name}(&self, {typed_params}) -> {return_suffix} {{ \
__gl_imports::mem::transmute::<_, extern \"system\" fn({typed_params}) -> {return_suffix}>\
(self.{name}.f)({idents}) \
}}",
name = c.proto.ident,
typed_params = super::gen_parameters(ecx, c).into_iter().map(|p| p.to_source()).collect::<Vec<String>>().connect(", "),
return_suffix = super::gen_return_type(ecx, c).to_source(),
idents = super::gen_parameters(ecx, c).into_iter().map(|p| p.pat.to_source()).collect::<Vec<String>>().connect(", "),
)
}).collect::<Vec<String>>().connect("\n")
))
}
3 changes: 3 additions & 0 deletions src/gl_generator/registry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,9 @@ pub struct Binding {
pub struct Cmd {
pub proto: Binding,
pub params: Vec<Binding>,
/// True if this command doesn't take any pointers.
///
/// Unused by the built-in generators.
pub is_safe: bool,
pub alias: Option<String>,
pub vecequiv: Option<String>,
Expand Down
20 changes: 10 additions & 10 deletions tests/generators_symbols.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ mod egl {

#[test]
#[ignore]
fn test_gl() {
fn test_gl() { unsafe {
gl::Clear(gl::COLOR_BUFFER_BIT);
let _: libc::c_uint = gl::CreateProgram();
gl::CompileShader(5);
Expand All @@ -76,32 +76,32 @@ fn test_gl() {
gl::GetActiveUniformBlockiv(0, 0, gl::UNIFORM_BLOCK_REFERENCED_BY_GEOMETRY_SHADER,
std::ptr::null_mut());
}
}
}}

#[test]
#[ignore]
fn test_gles() {
fn test_gles() { unsafe {
gles::Clear(gles::COLOR_BUFFER_BIT);
let _: libc::c_uint = gles::CreateProgram();
gles::CompileShader(5);
}
}}

#[test]
#[ignore]
fn test_glx() {
fn test_glx() { unsafe {
let _ = unsafe { glx::GetProcAddress(std::mem::uninitialized()) };
unsafe { glx::SwapBuffers(std::mem::uninitialized(), std::mem::uninitialized()) };
}
}}

#[test]
#[ignore]
fn test_wgl() {
fn test_wgl() { unsafe {
let _: wgl::types::HGLRC = unsafe { wgl::CreateContext(std::mem::uninitialized()) };
}
}}

#[test]
#[ignore]
fn test_egl() {
fn test_egl() { unsafe {
let _ = [
egl::SURFACE_TYPE, egl::WINDOW_BIT,
egl::BLUE_SIZE, 8,
Expand All @@ -112,4 +112,4 @@ fn test_egl() {

let _ = egl::GetDisplay(egl::DEFAULT_DISPLAY);
egl::Terminate(unsafe { std::mem::uninitialized() });
}
}}
4 changes: 2 additions & 2 deletions tests/gl_symbols.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ extern crate libc;

#[test]
#[ignore]
fn symbols_exist() {
fn symbols_exist() { unsafe {
gl::Clear(gl::COLOR_BUFFER_BIT);
let _: libc::c_uint = gl::CreateProgram();
gl::CompileShader(5);
Expand All @@ -14,7 +14,7 @@ fn symbols_exist() {
gl::GetActiveUniformBlockiv(0, 0, gl::UNIFORM_BLOCK_REFERENCED_BY_GEOMETRY_SHADER,
std::ptr::null_mut());
}
}
} }

#[test]
fn fallback_works() {
Expand Down

0 comments on commit 678346e

Please sign in to comment.