Add with_robustness and handle robustness on all implementations

This commit is contained in:
Pierre Krieger 2015-06-22 17:58:32 +02:00
parent 1aedc828c5
commit dbaca24cde
9 changed files with 216 additions and 36 deletions

View file

@ -13,6 +13,7 @@ use GlContext;
use GlProfile;
use GlRequest;
use PixelFormat;
use Robustness;
use native_monitor::NativeMonitorId;
use objc::runtime::{Class, Object, Sel, BOOL, YES, NO};
@ -332,6 +333,13 @@ impl Window {
unimplemented!()
}
match builder.gl_robustness {
Robustness::RobustNoResetNotification | Robustness::RobustLoseContextOnReset => {
return Err(CreationError::NotSupported);
},
_ => ()
}
let app = match Window::create_app() {
Some(app) => app,
None => { return Err(OsError(format!("Couldn't create NSApplication"))); },

View file

@ -7,6 +7,7 @@ use CreationError;
use GlContext;
use GlRequest;
use PixelFormat;
use Robustness;
use Api;
use libc;
@ -116,15 +117,16 @@ impl Context {
let context = unsafe {
if let Some(version) = version {
try!(create_context(&egl, display, &egl_version, api, version, config_id,
builder.gl_debug).map_err(|_| CreationError::NotSupported))
builder.gl_debug, builder.gl_robustness))
} else if api == Api::OpenGlEs {
if let Ok(ctxt) = create_context(&egl, display, &egl_version, api, (2, 0),
config_id, builder.gl_debug)
config_id, builder.gl_debug, builder.gl_robustness)
{
ctxt
} else if let Ok(ctxt) = create_context(&egl, display, &egl_version, api, (1, 0),
config_id, builder.gl_debug)
config_id, builder.gl_debug,
builder.gl_robustness)
{
ctxt
} else {
@ -133,15 +135,17 @@ impl Context {
} else {
if let Ok(ctxt) = create_context(&egl, display, &egl_version, api, (3, 2),
config_id, builder.gl_debug)
config_id, builder.gl_debug, builder.gl_robustness)
{
ctxt
} else if let Ok(ctxt) = create_context(&egl, display, &egl_version, api, (3, 1),
config_id, builder.gl_debug)
config_id, builder.gl_debug,
builder.gl_robustness)
{
ctxt
} else if let Ok(ctxt) = create_context(&egl, display, &egl_version, api, (1, 0),
config_id, builder.gl_debug)
config_id, builder.gl_debug,
builder.gl_robustness)
{
ctxt
} else {
@ -335,8 +339,8 @@ unsafe fn enumerate_configs(egl: &ffi::egl::Egl, display: ffi::egl::types::EGLDi
unsafe fn create_context(egl: &ffi::egl::Egl, display: ffi::egl::types::EGLDisplay,
egl_version: &(ffi::egl::types::EGLint, ffi::egl::types::EGLint),
api: Api, version: (u8, u8), config_id: ffi::egl::types::EGLConfig,
gl_debug: bool)
-> Result<ffi::egl::types::EGLContext, ()>
gl_debug: bool, gl_robustness: Robustness)
-> Result<ffi::egl::types::EGLContext, CreationError>
{
let extensions = if egl_version >= &(1, 2) {
let p = CStr::from_ptr(egl.QueryString(display, ffi::egl::EXTENSIONS as i32));
@ -346,6 +350,7 @@ unsafe fn create_context(egl: &ffi::egl::Egl, display: ffi::egl::types::EGLDispl
};
let mut context_attributes = vec![];
let mut flags = 0;
if egl_version >= &(1, 5) ||
extensions.contains("EGL_KHR_create_context ") ||
@ -356,17 +361,52 @@ unsafe fn create_context(egl: &ffi::egl::Egl, display: ffi::egl::types::EGLDispl
context_attributes.push(ffi::egl::CONTEXT_MINOR_VERSION as i32);
context_attributes.push(version.1 as i32);
if egl_version >= &(1, 5) ||
extensions.contains("EGL_EXT_create_context_robustness ") ||
extensions.ends_with("EGL_EXT_create_context_robustness")
{
match gl_robustness {
Robustness::RobustNoResetNotification | Robustness::TryRobustNoResetNotification => {
context_attributes.push(ffi::egl::CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY as libc::c_int);
context_attributes.push(ffi::egl::NO_RESET_NOTIFICATION as libc::c_int);
flags = flags | ffi::egl::CONTEXT_OPENGL_ROBUST_ACCESS as libc::c_int;
},
Robustness::RobustLoseContextOnReset | Robustness::TryRobustLoseContextOnReset => {
context_attributes.push(ffi::egl::CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY as libc::c_int);
context_attributes.push(ffi::egl::LOSE_CONTEXT_ON_RESET as libc::c_int);
flags = flags | ffi::egl::CONTEXT_OPENGL_ROBUST_ACCESS as libc::c_int;
},
Robustness::NotRobust => ()
}
} else {
match gl_robustness {
Robustness::RobustNoResetNotification | Robustness::RobustLoseContextOnReset => {
return Err(CreationError::NotSupported);
},
_ => ()
}
}
if gl_debug {
if egl_version >= &(1, 5) {
context_attributes.push(ffi::egl::CONTEXT_OPENGL_DEBUG as i32);
context_attributes.push(ffi::egl::TRUE as i32);
} else {
context_attributes.push(ffi::egl::CONTEXT_FLAGS_KHR as i32);
context_attributes.push(ffi::egl::CONTEXT_OPENGL_DEBUG_BIT_KHR as i32);
flags = flags | ffi::egl::CONTEXT_OPENGL_DEBUG_BIT_KHR as i32;
}
}
context_attributes.push(ffi::egl::CONTEXT_FLAGS_KHR as i32);
context_attributes.push(flags);
} else if egl_version >= &(1, 3) && api == Api::OpenGlEs {
match gl_robustness {
Robustness::RobustNoResetNotification | Robustness::RobustLoseContextOnReset => {
return Err(CreationError::NotSupported);
},
_ => ()
}
context_attributes.push(ffi::egl::CONTEXT_CLIENT_VERSION as i32);
context_attributes.push(version.0 as i32);
}
@ -377,7 +417,7 @@ unsafe fn create_context(egl: &ffi::egl::Egl, display: ffi::egl::types::EGLDispl
context_attributes.as_ptr());
if context.is_null() {
return Err(());
return Err(CreationError::NotSupported);
}
Ok(context)

View file

@ -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);

View file

@ -8,6 +8,7 @@ use ContextError;
use CreationError;
use GlContext;
use PixelFormat;
use Robustness;
use libc;
use std::{mem, ptr};
use std::ffi::CString;
@ -38,6 +39,13 @@ impl OsMesaContext {
let dimensions = builder.dimensions.unwrap();
match builder.gl_robustness {
Robustness::RobustNoResetNotification | Robustness::RobustLoseContextOnReset => {
return Err(CreationError::NotSupported.into());
},
_ => ()
}
Ok(OsMesaContext {
width: dimensions.0,
height: dimensions.1,

View file

@ -7,6 +7,7 @@ use GlContext;
use GlRequest;
use GlProfile;
use PixelFormat;
use Robustness;
use Api;
use self::make_current_guard::CurrentContextGuard;
@ -266,10 +267,42 @@ unsafe fn create_context(extra: Option<(&gl::wgl_extra::Wgl, &BuilderAttribs<'st
}
}
if builder.gl_debug {
attributes.push(gl::wgl_extra::CONTEXT_FLAGS_ARB as libc::c_int);
attributes.push(gl::wgl_extra::CONTEXT_DEBUG_BIT_ARB as libc::c_int);
}
let flags = {
let mut flags = 0;
// robustness
if extensions.split(' ').find(|&i| i == "WGL_ARB_create_context_robustness").is_some() {
match builder.gl_robustness {
Robustness::RobustNoResetNotification | Robustness::TryRobustNoResetNotification => {
attributes.push(gl::wgl_extra::CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB as libc::c_int);
attributes.push(gl::wgl_extra::NO_RESET_NOTIFICATION_ARB as libc::c_int);
flags = flags | gl::wgl_extra::CONTEXT_ROBUST_ACCESS_BIT_ARB as libc::c_int;
},
Robustness::RobustLoseContextOnReset | Robustness::TryRobustLoseContextOnReset => {
attributes.push(gl::wgl_extra::CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB as libc::c_int);
attributes.push(gl::wgl_extra::LOSE_CONTEXT_ON_RESET_ARB as libc::c_int);
flags = flags | gl::wgl_extra::CONTEXT_ROBUST_ACCESS_BIT_ARB as libc::c_int;
},
Robustness::NotRobust => ()
}
} else {
match builder.gl_robustness {
Robustness::RobustNoResetNotification | Robustness::RobustLoseContextOnReset => {
return Err(CreationError::NotSupported);
},
_ => ()
}
}
if builder.gl_debug {
flags = flags | gl::wgl_extra::CONTEXT_DEBUG_BIT_ARB as libc::c_int;
}
flags
};
attributes.push(gl::wgl_extra::CONTEXT_FLAGS_ARB as libc::c_int);
attributes.push(flags);
attributes.push(0);