aboutsummaryrefslogtreecommitdiffstats
path: root/src/api/glx/mod.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/api/glx/mod.rs')
-rw-r--r--src/api/glx/mod.rs81
1 files changed, 62 insertions, 19 deletions
diff --git a/src/api/glx/mod.rs b/src/api/glx/mod.rs
index 455f6a5..2c15e18 100644
--- a/src/api/glx/mod.rs
+++ b/src/api/glx/mod.rs
@@ -8,9 +8,10 @@ use GlProfile;
use GlRequest;
use Api;
use PixelFormat;
+use Robustness;
use libc;
-use std::ffi::CString;
+use std::ffi::{CStr, CString};
use std::{mem, ptr};
use api::x11::ffi;
@@ -48,6 +49,13 @@ impl Context {
ptr::null()
};
+ // loading the list of extensions
+ let extensions = unsafe {
+ let extensions = glx.QueryExtensionsString(display as *mut _, 0); // FIXME: screen number
+ let extensions = CStr::from_ptr(extensions).to_bytes().to_vec();
+ String::from_utf8(extensions).unwrap()
+ };
+
// loading the extra GLX functions
let extra_functions = ffi::glx_extra::Glx::load_with(|addr| {
with_c_str(addr, |s| {
@@ -58,32 +66,35 @@ impl Context {
// creating GL context
let context = match builder.gl_version {
GlRequest::Latest => {
- if let Ok(ctxt) = create_context(&glx, &extra_functions, (3, 2),
- builder.gl_profile, builder.gl_debug, share,
+ if let Ok(ctxt) = create_context(&glx, &extra_functions, &extensions, (3, 2),
+ builder.gl_profile, builder.gl_debug,
+ builder.gl_robustness, share,
display, fb_config, &mut visual_infos)
{
ctxt
- } else if let Ok(ctxt) = create_context(&glx, &extra_functions, (3, 1),
+ } else if let Ok(ctxt) = create_context(&glx, &extra_functions, &extensions, (3, 1),
builder.gl_profile, builder.gl_debug,
- share, display, fb_config,
- &mut visual_infos)
+ builder.gl_robustness, share, display,
+ fb_config, &mut visual_infos)
{
ctxt
} else {
- try!(create_context(&glx, &extra_functions, (1, 0), builder.gl_profile,
- builder.gl_debug, share, display, fb_config,
- &mut visual_infos))
+ try!(create_context(&glx, &extra_functions, &extensions, (1, 0),
+ builder.gl_profile, builder.gl_debug, builder.gl_robustness,
+ share, display, fb_config, &mut visual_infos))
}
},
GlRequest::Specific(Api::OpenGl, (major, minor)) => {
- try!(create_context(&glx, &extra_functions, (major, minor), builder.gl_profile,
- builder.gl_debug, share, display, fb_config, &mut visual_infos))
+ try!(create_context(&glx, &extra_functions, &extensions, (major, minor),
+ builder.gl_profile, builder.gl_debug, builder.gl_robustness,
+ share, display, fb_config, &mut visual_infos))
},
GlRequest::Specific(_, _) => panic!("Only OpenGL is supported"),
GlRequest::GlThenGles { opengl_version: (major, minor), .. } => {
- try!(create_context(&glx, &extra_functions, (major, minor), builder.gl_profile,
- builder.gl_debug, share, display, fb_config, &mut visual_infos))
+ try!(create_context(&glx, &extra_functions, &extensions, (major, minor),
+ builder.gl_profile, builder.gl_debug, builder.gl_robustness,
+ share, display, fb_config, &mut visual_infos))
},
};
@@ -191,9 +202,9 @@ impl Drop for Context {
}
}
-fn create_context(glx: &ffi::glx::Glx, extra_functions: &ffi::glx_extra::Glx,
+fn create_context(glx: &ffi::glx::Glx, extra_functions: &ffi::glx_extra::Glx, extensions: &str,
version: (u8, u8), profile: Option<GlProfile>, debug: bool,
- share: ffi::GLXContext, display: *mut ffi::Display,
+ robustness: Robustness, share: ffi::GLXContext, display: *mut ffi::Display,
fb_config: ffi::glx::types::GLXFBConfig,
visual_infos: &mut ffi::glx::types::XVisualInfo)
-> Result<ffi::GLXContext, CreationError>
@@ -219,10 +230,42 @@ fn create_context(glx: &ffi::glx::Glx, extra_functions: &ffi::glx_extra::Glx,
attributes.push(flag as libc::c_int);
}
- if debug {
- attributes.push(ffi::glx_extra::CONTEXT_FLAGS_ARB as libc::c_int);
- attributes.push(ffi::glx_extra::CONTEXT_DEBUG_BIT_ARB as libc::c_int);
- }
+ let flags = {
+ let mut flags = 0;
+
+ // robustness
+ if extensions.split(' ').find(|&i| i == "GLX_ARB_create_context_robustness").is_some() {
+ match robustness {
+ Robustness::RobustNoResetNotification | Robustness::TryRobustNoResetNotification => {
+ attributes.push(ffi::glx_extra::CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB as libc::c_int);
+ attributes.push(ffi::glx_extra::NO_RESET_NOTIFICATION_ARB as libc::c_int);
+ flags = flags | ffi::glx_extra::CONTEXT_ROBUST_ACCESS_BIT_ARB as libc::c_int;
+ },
+ Robustness::RobustLoseContextOnReset | Robustness::TryRobustLoseContextOnReset => {
+ attributes.push(ffi::glx_extra::CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB as libc::c_int);
+ attributes.push(ffi::glx_extra::LOSE_CONTEXT_ON_RESET_ARB as libc::c_int);
+ flags = flags | ffi::glx_extra::CONTEXT_ROBUST_ACCESS_BIT_ARB as libc::c_int;
+ },
+ Robustness::NotRobust => ()
+ }
+ } else {
+ match robustness {
+ Robustness::RobustNoResetNotification | Robustness::RobustLoseContextOnReset => {
+ return Err(CreationError::NotSupported);
+ },
+ _ => ()
+ }
+ }
+
+ if debug {
+ flags = flags | ffi::glx_extra::CONTEXT_DEBUG_BIT_ARB as libc::c_int;
+ }
+
+ flags
+ };
+
+ attributes.push(ffi::glx_extra::CONTEXT_FLAGS_ARB as libc::c_int);
+ attributes.push(flags);
attributes.push(0);