Merge pull request #220 from tomaka/x11-vsync

Implement vsync for x11 and add vsync example
This commit is contained in:
tomaka 2015-01-25 12:56:15 +01:00
commit f8c66ff2a9
4 changed files with 96 additions and 2 deletions

View file

@ -23,6 +23,9 @@ gl_common = "*"
gl_generator = "*" gl_generator = "*"
khronos_api = "*" khronos_api = "*"
[dev-dependencies]
clock_ticks = "*"
[target.arm-linux-androideabi.dependencies.android_glue] [target.arm-linux-androideabi.dependencies.android_glue]
git = "https://github.com/tomaka/android-rs-glue" git = "https://github.com/tomaka/android-rs-glue"

View file

@ -40,6 +40,8 @@ fn main() {
khronos_api::GLX_XML, khronos_api::GLX_XML,
vec![ vec![
"GLX_ARB_create_context".to_string(), "GLX_ARB_create_context".to_string(),
"GLX_EXT_swap_control".to_string(),
"GLX_SGI_swap_control".to_string()
], ],
"1.4", "core", &mut file).unwrap(); "1.4", "core", &mut file).unwrap();
} }

46
examples/vsync.rs Normal file
View file

@ -0,0 +1,46 @@
#[cfg(target_os = "android")]
#[macro_use]
extern crate android_glue;
extern crate clock_ticks;
extern crate glutin;
mod support;
#[cfg(target_os = "android")]
android_start!(main);
#[cfg(not(feature = "window"))]
fn main() { println!("This example requires glutin to be compiled with the `window` feature"); }
#[cfg(feature = "window")]
fn resize_callback(width: u32, height: u32) {
println!("Window resized to {}x{}", width, height);
}
#[cfg(feature = "window")]
fn main() {
println!("Vsync example. This example may panic if your driver or your system forces \
you out of vsync. This is intended when `build_strict` is used.");
let mut window = glutin::WindowBuilder::new().with_vsync().build_strict().unwrap();
window.set_window_resize_callback(Some(resize_callback as fn(u32, u32)));
unsafe { window.make_current() };
let context = support::load(&window);
while !window.is_closed() {
let before = clock_ticks::precise_time_ns();
context.draw_frame((0.0, 1.0, 0.0, 1.0));
window.swap_buffers();
for ev in window.poll_events() {
println!("{:?}", ev);
}
let after = clock_ticks::precise_time_ns();
println!("Vsync example - Time of previous frame: {}ms",
(after - before) as f32 / 1000000.0);
}
}

View file

@ -303,7 +303,7 @@ impl Window {
// creating GL context // creating GL context
let context = unsafe { let (context, extra_functions) = unsafe {
let mut attributes = Vec::new(); let mut attributes = Vec::new();
if builder.gl_version.is_some() { if builder.gl_version.is_some() {
@ -350,9 +350,52 @@ impl Window {
return Err(OsError(format!("GL context creation failed"))); return Err(OsError(format!("GL context creation failed")));
} }
context (context, extra_functions)
}; };
// vsync
if builder.vsync {
unsafe { ffi::glx::MakeCurrent(display, window, context) };
if extra_functions.SwapIntervalEXT.is_loaded() {
// this should be the most common extension
unsafe {
extra_functions.SwapIntervalEXT(display as *mut _, window, 1);
}
// checking that it worked
if builder.strict {
let mut swap = unsafe { mem::uninitialized() };
unsafe {
ffi::glx::QueryDrawable(display, window,
ffi::glx_extra::SWAP_INTERVAL_EXT as i32,
&mut swap);
}
if swap != 1 {
return Err(OsError(format!("Couldn't setup vsync: expected \
interval `1` but got `{}`", swap)));
}
}
// GLX_MESA_swap_control is not official
/*} else if extra_functions.SwapIntervalMESA.is_loaded() {
unsafe {
extra_functions.SwapIntervalMESA(1);
}*/
} else if extra_functions.SwapIntervalSGI.is_loaded() {
unsafe {
extra_functions.SwapIntervalSGI(1);
}
} else if builder.strict {
return Err(OsError(format!("Couldn't find any available vsync extension")));
}
unsafe { ffi::glx::MakeCurrent(display, 0, ptr::null()) };
}
// creating the window object // creating the window object
let window = Window { let window = Window {
x: Arc::new(XWindow { x: Arc::new(XWindow {