mirror of
https://github.com/italicsjenga/winit-sonoma-fix.git
synced 2024-12-25 06:41:31 +11:00
Merge pull request #497 from tomaka/robustness
Add with_robustness and handle robustness on all implementations
This commit is contained in:
commit
40b84577c3
8
build.rs
8
build.rs
|
@ -25,6 +25,7 @@ fn main() {
|
||||||
vec![
|
vec![
|
||||||
"WGL_ARB_create_context".to_string(),
|
"WGL_ARB_create_context".to_string(),
|
||||||
"WGL_ARB_create_context_profile".to_string(),
|
"WGL_ARB_create_context_profile".to_string(),
|
||||||
|
"WGL_ARB_create_context_robustness".to_string(),
|
||||||
"WGL_ARB_extensions_string".to_string(),
|
"WGL_ARB_extensions_string".to_string(),
|
||||||
"WGL_ARB_framebuffer_sRGB".to_string(),
|
"WGL_ARB_framebuffer_sRGB".to_string(),
|
||||||
"WGL_ARB_multisample".to_string(),
|
"WGL_ARB_multisample".to_string(),
|
||||||
|
@ -42,7 +43,8 @@ fn main() {
|
||||||
gl_generator::Fallbacks::All,
|
gl_generator::Fallbacks::All,
|
||||||
khronos_api::EGL_XML,
|
khronos_api::EGL_XML,
|
||||||
vec![
|
vec![
|
||||||
"EGL_KHR_create_context".to_string()
|
"EGL_KHR_create_context".to_string(),
|
||||||
|
"EGL_EXT_create_context_robustness".to_string(),
|
||||||
],
|
],
|
||||||
"1.5", "core", &mut file).unwrap();
|
"1.5", "core", &mut file).unwrap();
|
||||||
}
|
}
|
||||||
|
@ -63,6 +65,7 @@ fn main() {
|
||||||
vec![
|
vec![
|
||||||
"GLX_ARB_create_context".to_string(),
|
"GLX_ARB_create_context".to_string(),
|
||||||
"GLX_ARB_create_context_profile".to_string(),
|
"GLX_ARB_create_context_profile".to_string(),
|
||||||
|
"GLX_ARB_create_context_robustness".to_string(),
|
||||||
"GLX_ARB_framebuffer_sRGB".to_string(),
|
"GLX_ARB_framebuffer_sRGB".to_string(),
|
||||||
"GLX_EXT_framebuffer_sRGB".to_string(),
|
"GLX_EXT_framebuffer_sRGB".to_string(),
|
||||||
"GLX_EXT_swap_control".to_string(),
|
"GLX_EXT_swap_control".to_string(),
|
||||||
|
@ -76,7 +79,8 @@ fn main() {
|
||||||
gl_generator::Fallbacks::All,
|
gl_generator::Fallbacks::All,
|
||||||
khronos_api::EGL_XML,
|
khronos_api::EGL_XML,
|
||||||
vec![
|
vec![
|
||||||
"EGL_KHR_create_context".to_string()
|
"EGL_KHR_create_context".to_string(),
|
||||||
|
"EGL_EXT_create_context_robustness".to_string(),
|
||||||
],
|
],
|
||||||
"1.5", "core", &mut file).unwrap();
|
"1.5", "core", &mut file).unwrap();
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,6 +13,7 @@ use GlContext;
|
||||||
use GlProfile;
|
use GlProfile;
|
||||||
use GlRequest;
|
use GlRequest;
|
||||||
use PixelFormat;
|
use PixelFormat;
|
||||||
|
use Robustness;
|
||||||
use native_monitor::NativeMonitorId;
|
use native_monitor::NativeMonitorId;
|
||||||
|
|
||||||
use objc::runtime::{Class, Object, Sel, BOOL, YES, NO};
|
use objc::runtime::{Class, Object, Sel, BOOL, YES, NO};
|
||||||
|
@ -332,6 +333,13 @@ impl Window {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
match builder.gl_robustness {
|
||||||
|
Robustness::RobustNoResetNotification | Robustness::RobustLoseContextOnReset => {
|
||||||
|
return Err(CreationError::NotSupported);
|
||||||
|
},
|
||||||
|
_ => ()
|
||||||
|
}
|
||||||
|
|
||||||
let app = match Window::create_app() {
|
let app = match Window::create_app() {
|
||||||
Some(app) => app,
|
Some(app) => app,
|
||||||
None => { return Err(OsError(format!("Couldn't create NSApplication"))); },
|
None => { return Err(OsError(format!("Couldn't create NSApplication"))); },
|
||||||
|
|
|
@ -7,6 +7,7 @@ use CreationError;
|
||||||
use GlContext;
|
use GlContext;
|
||||||
use GlRequest;
|
use GlRequest;
|
||||||
use PixelFormat;
|
use PixelFormat;
|
||||||
|
use Robustness;
|
||||||
use Api;
|
use Api;
|
||||||
|
|
||||||
use libc;
|
use libc;
|
||||||
|
@ -116,15 +117,16 @@ impl Context {
|
||||||
let context = unsafe {
|
let context = unsafe {
|
||||||
if let Some(version) = version {
|
if let Some(version) = version {
|
||||||
try!(create_context(&egl, display, &egl_version, api, version, config_id,
|
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 {
|
} else if api == Api::OpenGlEs {
|
||||||
if let Ok(ctxt) = create_context(&egl, display, &egl_version, api, (2, 0),
|
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
|
ctxt
|
||||||
} else if let Ok(ctxt) = create_context(&egl, display, &egl_version, api, (1, 0),
|
} 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
|
ctxt
|
||||||
} else {
|
} else {
|
||||||
|
@ -133,15 +135,17 @@ impl Context {
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
if let Ok(ctxt) = create_context(&egl, display, &egl_version, api, (3, 2),
|
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
|
ctxt
|
||||||
} else if let Ok(ctxt) = create_context(&egl, display, &egl_version, api, (3, 1),
|
} 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
|
ctxt
|
||||||
} else if let Ok(ctxt) = create_context(&egl, display, &egl_version, api, (1, 0),
|
} 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
|
ctxt
|
||||||
} else {
|
} 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,
|
unsafe fn create_context(egl: &ffi::egl::Egl, display: ffi::egl::types::EGLDisplay,
|
||||||
egl_version: &(ffi::egl::types::EGLint, ffi::egl::types::EGLint),
|
egl_version: &(ffi::egl::types::EGLint, ffi::egl::types::EGLint),
|
||||||
api: Api, version: (u8, u8), config_id: ffi::egl::types::EGLConfig,
|
api: Api, version: (u8, u8), config_id: ffi::egl::types::EGLConfig,
|
||||||
gl_debug: bool)
|
gl_debug: bool, gl_robustness: Robustness)
|
||||||
-> Result<ffi::egl::types::EGLContext, ()>
|
-> Result<ffi::egl::types::EGLContext, CreationError>
|
||||||
{
|
{
|
||||||
let extensions = if egl_version >= &(1, 2) {
|
let extensions = if egl_version >= &(1, 2) {
|
||||||
let p = CStr::from_ptr(egl.QueryString(display, ffi::egl::EXTENSIONS as i32));
|
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 context_attributes = vec![];
|
||||||
|
let mut flags = 0;
|
||||||
|
|
||||||
if egl_version >= &(1, 5) ||
|
if egl_version >= &(1, 5) ||
|
||||||
extensions.contains("EGL_KHR_create_context ") ||
|
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(ffi::egl::CONTEXT_MINOR_VERSION as i32);
|
||||||
context_attributes.push(version.1 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 gl_debug {
|
||||||
if egl_version >= &(1, 5) {
|
if egl_version >= &(1, 5) {
|
||||||
context_attributes.push(ffi::egl::CONTEXT_OPENGL_DEBUG as i32);
|
context_attributes.push(ffi::egl::CONTEXT_OPENGL_DEBUG as i32);
|
||||||
context_attributes.push(ffi::egl::TRUE as i32);
|
context_attributes.push(ffi::egl::TRUE as i32);
|
||||||
} else {
|
} else {
|
||||||
context_attributes.push(ffi::egl::CONTEXT_FLAGS_KHR as i32);
|
flags = flags | ffi::egl::CONTEXT_OPENGL_DEBUG_BIT_KHR as i32;
|
||||||
context_attributes.push(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 {
|
} 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(ffi::egl::CONTEXT_CLIENT_VERSION as i32);
|
||||||
context_attributes.push(version.0 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());
|
context_attributes.as_ptr());
|
||||||
|
|
||||||
if context.is_null() {
|
if context.is_null() {
|
||||||
return Err(());
|
return Err(CreationError::NotSupported);
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(context)
|
Ok(context)
|
||||||
|
|
|
@ -8,9 +8,10 @@ use GlProfile;
|
||||||
use GlRequest;
|
use GlRequest;
|
||||||
use Api;
|
use Api;
|
||||||
use PixelFormat;
|
use PixelFormat;
|
||||||
|
use Robustness;
|
||||||
|
|
||||||
use libc;
|
use libc;
|
||||||
use std::ffi::CString;
|
use std::ffi::{CStr, CString};
|
||||||
use std::{mem, ptr};
|
use std::{mem, ptr};
|
||||||
|
|
||||||
use api::x11::ffi;
|
use api::x11::ffi;
|
||||||
|
@ -48,6 +49,13 @@ impl Context {
|
||||||
ptr::null()
|
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
|
// loading the extra GLX functions
|
||||||
let extra_functions = ffi::glx_extra::Glx::load_with(|addr| {
|
let extra_functions = ffi::glx_extra::Glx::load_with(|addr| {
|
||||||
with_c_str(addr, |s| {
|
with_c_str(addr, |s| {
|
||||||
|
@ -58,32 +66,35 @@ impl Context {
|
||||||
// creating GL context
|
// creating GL context
|
||||||
let context = match builder.gl_version {
|
let context = match builder.gl_version {
|
||||||
GlRequest::Latest => {
|
GlRequest::Latest => {
|
||||||
if let Ok(ctxt) = create_context(&glx, &extra_functions, (3, 2),
|
if let Ok(ctxt) = create_context(&glx, &extra_functions, &extensions, (3, 2),
|
||||||
builder.gl_profile, builder.gl_debug, share,
|
builder.gl_profile, builder.gl_debug,
|
||||||
|
builder.gl_robustness, share,
|
||||||
display, fb_config, &mut visual_infos)
|
display, fb_config, &mut visual_infos)
|
||||||
{
|
{
|
||||||
ctxt
|
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,
|
builder.gl_profile, builder.gl_debug,
|
||||||
share, display, fb_config,
|
builder.gl_robustness, share, display,
|
||||||
&mut visual_infos)
|
fb_config, &mut visual_infos)
|
||||||
{
|
{
|
||||||
ctxt
|
ctxt
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
try!(create_context(&glx, &extra_functions, (1, 0), builder.gl_profile,
|
try!(create_context(&glx, &extra_functions, &extensions, (1, 0),
|
||||||
builder.gl_debug, share, display, fb_config,
|
builder.gl_profile, builder.gl_debug, builder.gl_robustness,
|
||||||
&mut visual_infos))
|
share, display, fb_config, &mut visual_infos))
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
GlRequest::Specific(Api::OpenGl, (major, minor)) => {
|
GlRequest::Specific(Api::OpenGl, (major, minor)) => {
|
||||||
try!(create_context(&glx, &extra_functions, (major, minor), builder.gl_profile,
|
try!(create_context(&glx, &extra_functions, &extensions, (major, minor),
|
||||||
builder.gl_debug, share, display, fb_config, &mut visual_infos))
|
builder.gl_profile, builder.gl_debug, builder.gl_robustness,
|
||||||
|
share, display, fb_config, &mut visual_infos))
|
||||||
},
|
},
|
||||||
GlRequest::Specific(_, _) => panic!("Only OpenGL is supported"),
|
GlRequest::Specific(_, _) => panic!("Only OpenGL is supported"),
|
||||||
GlRequest::GlThenGles { opengl_version: (major, minor), .. } => {
|
GlRequest::GlThenGles { opengl_version: (major, minor), .. } => {
|
||||||
try!(create_context(&glx, &extra_functions, (major, minor), builder.gl_profile,
|
try!(create_context(&glx, &extra_functions, &extensions, (major, minor),
|
||||||
builder.gl_debug, share, display, fb_config, &mut visual_infos))
|
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,
|
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,
|
fb_config: ffi::glx::types::GLXFBConfig,
|
||||||
visual_infos: &mut ffi::glx::types::XVisualInfo)
|
visual_infos: &mut ffi::glx::types::XVisualInfo)
|
||||||
-> Result<ffi::GLXContext, CreationError>
|
-> 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);
|
attributes.push(flag as libc::c_int);
|
||||||
}
|
}
|
||||||
|
|
||||||
if debug {
|
let flags = {
|
||||||
attributes.push(ffi::glx_extra::CONTEXT_FLAGS_ARB as libc::c_int);
|
let mut flags = 0;
|
||||||
attributes.push(ffi::glx_extra::CONTEXT_DEBUG_BIT_ARB as libc::c_int);
|
|
||||||
}
|
// 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);
|
attributes.push(0);
|
||||||
|
|
||||||
|
|
|
@ -8,6 +8,7 @@ use ContextError;
|
||||||
use CreationError;
|
use CreationError;
|
||||||
use GlContext;
|
use GlContext;
|
||||||
use PixelFormat;
|
use PixelFormat;
|
||||||
|
use Robustness;
|
||||||
use libc;
|
use libc;
|
||||||
use std::{mem, ptr};
|
use std::{mem, ptr};
|
||||||
use std::ffi::CString;
|
use std::ffi::CString;
|
||||||
|
@ -38,6 +39,13 @@ impl OsMesaContext {
|
||||||
|
|
||||||
let dimensions = builder.dimensions.unwrap();
|
let dimensions = builder.dimensions.unwrap();
|
||||||
|
|
||||||
|
match builder.gl_robustness {
|
||||||
|
Robustness::RobustNoResetNotification | Robustness::RobustLoseContextOnReset => {
|
||||||
|
return Err(CreationError::NotSupported.into());
|
||||||
|
},
|
||||||
|
_ => ()
|
||||||
|
}
|
||||||
|
|
||||||
Ok(OsMesaContext {
|
Ok(OsMesaContext {
|
||||||
width: dimensions.0,
|
width: dimensions.0,
|
||||||
height: dimensions.1,
|
height: dimensions.1,
|
||||||
|
|
|
@ -7,6 +7,7 @@ use GlContext;
|
||||||
use GlRequest;
|
use GlRequest;
|
||||||
use GlProfile;
|
use GlProfile;
|
||||||
use PixelFormat;
|
use PixelFormat;
|
||||||
|
use Robustness;
|
||||||
use Api;
|
use Api;
|
||||||
|
|
||||||
use self::make_current_guard::CurrentContextGuard;
|
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 {
|
let flags = {
|
||||||
attributes.push(gl::wgl_extra::CONTEXT_FLAGS_ARB as libc::c_int);
|
let mut flags = 0;
|
||||||
attributes.push(gl::wgl_extra::CONTEXT_DEBUG_BIT_ARB as libc::c_int);
|
|
||||||
}
|
// 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);
|
attributes.push(0);
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,7 @@ use CreationError;
|
||||||
use GlRequest;
|
use GlRequest;
|
||||||
use GlContext;
|
use GlContext;
|
||||||
use PixelFormat;
|
use PixelFormat;
|
||||||
|
use Robustness;
|
||||||
|
|
||||||
use gl_common;
|
use gl_common;
|
||||||
use libc;
|
use libc;
|
||||||
|
@ -43,6 +44,12 @@ impl HeadlessRendererBuilder {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Sets the robustness of the OpenGL context. See the docs of `Robustness`.
|
||||||
|
pub fn with_gl_robustness(mut self, robustness: Robustness) -> HeadlessRendererBuilder {
|
||||||
|
self.attribs.gl_robustness = robustness;
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
/// Builds the headless context.
|
/// Builds the headless context.
|
||||||
///
|
///
|
||||||
/// Error should be very rare and only occur in case of permission denied, incompatible system,
|
/// Error should be very rare and only occur in case of permission denied, incompatible system,
|
||||||
|
|
30
src/lib.rs
30
src/lib.rs
|
@ -197,6 +197,33 @@ impl GlRequest {
|
||||||
/// the compatibility profile features.
|
/// the compatibility profile features.
|
||||||
pub static GL_CORE: GlRequest = GlRequest::Specific(Api::OpenGl, (3, 2));
|
pub static GL_CORE: GlRequest = GlRequest::Specific(Api::OpenGl, (3, 2));
|
||||||
|
|
||||||
|
/// Specifies the tolerance of the OpenGL context to faults. If you accept raw OpenGL commands
|
||||||
|
/// and/or raw shader code from an untrusted source, you should definitely care about this.
|
||||||
|
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
|
||||||
|
pub enum Robustness {
|
||||||
|
/// Not everything is checked. Your application can crash if you do something wrong with your
|
||||||
|
/// shaders.
|
||||||
|
NotRobust,
|
||||||
|
|
||||||
|
/// Everything is checked to avoid any crash. The driver will attempt to avoid any problem,
|
||||||
|
/// but if a problem occurs the behavior is implementation-defined. You are just guaranteed not
|
||||||
|
/// to get a crash.
|
||||||
|
RobustNoResetNotification,
|
||||||
|
|
||||||
|
/// Same as `RobustNoResetNotification` but the context creation doesn't fail if it's not
|
||||||
|
/// supported.
|
||||||
|
TryRobustNoResetNotification,
|
||||||
|
|
||||||
|
/// Everything is checked to avoid any crash. If a problem occurs, the context will enter a
|
||||||
|
/// "context lost" state. It must then be recreated. For the moment, glutin doesn't provide a
|
||||||
|
/// way to recreate a context with the same window :-/
|
||||||
|
RobustLoseContextOnReset,
|
||||||
|
|
||||||
|
/// Same as `RobustLoseContextOnReset` but the context creation doesn't fail if it's not
|
||||||
|
/// supported.
|
||||||
|
TryRobustLoseContextOnReset,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Copy, Clone)]
|
#[derive(Debug, Copy, Clone)]
|
||||||
pub enum MouseCursor {
|
pub enum MouseCursor {
|
||||||
/// The platform-dependent default cursor.
|
/// The platform-dependent default cursor.
|
||||||
|
@ -299,6 +326,7 @@ pub struct BuilderAttribs<'a> {
|
||||||
gl_version: GlRequest,
|
gl_version: GlRequest,
|
||||||
gl_profile: Option<GlProfile>,
|
gl_profile: Option<GlProfile>,
|
||||||
gl_debug: bool,
|
gl_debug: bool,
|
||||||
|
gl_robustness: Robustness,
|
||||||
vsync: bool,
|
vsync: bool,
|
||||||
visible: bool,
|
visible: bool,
|
||||||
multisampling: Option<u16>,
|
multisampling: Option<u16>,
|
||||||
|
@ -324,6 +352,7 @@ impl BuilderAttribs<'static> {
|
||||||
gl_version: GlRequest::Latest,
|
gl_version: GlRequest::Latest,
|
||||||
gl_profile: None,
|
gl_profile: None,
|
||||||
gl_debug: cfg!(debug_assertions),
|
gl_debug: cfg!(debug_assertions),
|
||||||
|
gl_robustness: Robustness::NotRobust,
|
||||||
vsync: false,
|
vsync: false,
|
||||||
visible: true,
|
visible: true,
|
||||||
multisampling: None,
|
multisampling: None,
|
||||||
|
@ -354,6 +383,7 @@ impl<'a> BuilderAttribs<'a> {
|
||||||
gl_version: self.gl_version,
|
gl_version: self.gl_version,
|
||||||
gl_profile: self.gl_profile,
|
gl_profile: self.gl_profile,
|
||||||
gl_debug: self.gl_debug,
|
gl_debug: self.gl_debug,
|
||||||
|
gl_robustness: self.gl_robustness,
|
||||||
vsync: self.vsync,
|
vsync: self.vsync,
|
||||||
visible: self.visible,
|
visible: self.visible,
|
||||||
multisampling: self.multisampling,
|
multisampling: self.multisampling,
|
||||||
|
|
|
@ -12,6 +12,7 @@ use GlProfile;
|
||||||
use GlRequest;
|
use GlRequest;
|
||||||
use MouseCursor;
|
use MouseCursor;
|
||||||
use PixelFormat;
|
use PixelFormat;
|
||||||
|
use Robustness;
|
||||||
use native_monitor::NativeMonitorId;
|
use native_monitor::NativeMonitorId;
|
||||||
|
|
||||||
use gl_common;
|
use gl_common;
|
||||||
|
@ -84,6 +85,12 @@ impl<'a> WindowBuilder<'a> {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Sets the robustness of the OpenGL context. See the docs of `Robustness`.
|
||||||
|
pub fn with_gl_robustness(mut self, robustness: Robustness) -> WindowBuilder<'a> {
|
||||||
|
self.attribs.gl_robustness = robustness;
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
/// Requests that the window has vsync enabled.
|
/// Requests that the window has vsync enabled.
|
||||||
pub fn with_vsync(mut self) -> WindowBuilder<'a> {
|
pub fn with_vsync(mut self) -> WindowBuilder<'a> {
|
||||||
self.attribs.vsync = true;
|
self.attribs.vsync = true;
|
||||||
|
|
Loading…
Reference in a new issue