aboutsummaryrefslogtreecommitdiffstats
path: root/src/api/egl/mod.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/api/egl/mod.rs')
-rw-r--r--src/api/egl/mod.rs120
1 files changed, 104 insertions, 16 deletions
diff --git a/src/api/egl/mod.rs b/src/api/egl/mod.rs
index 3335de0..1a6cc06 100644
--- a/src/api/egl/mod.rs
+++ b/src/api/egl/mod.rs
@@ -2,10 +2,12 @@
#![allow(unused_variables)]
use BuilderAttribs;
+use ContextError;
use CreationError;
use GlContext;
use GlRequest;
use PixelFormat;
+use Robustness;
use Api;
use libc;
@@ -115,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 {
@@ -132,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 {
@@ -161,11 +166,18 @@ impl Context {
}
impl GlContext for Context {
- unsafe fn make_current(&self) {
+ unsafe fn make_current(&self) -> Result<(), ContextError> {
let ret = self.egl.MakeCurrent(self.display, self.surface, self.surface, self.context);
if ret == 0 {
- panic!("eglMakeCurrent failed");
+ if self.egl.GetError() as u32 == ffi::egl::CONTEXT_LOST {
+ return Err(ContextError::ContextLost);
+ } else {
+ panic!("eglMakeCurrent failed");
+ }
+
+ } else {
+ Ok(())
}
}
@@ -181,13 +193,20 @@ impl GlContext for Context {
}
}
- fn swap_buffers(&self) {
+ fn swap_buffers(&self) -> Result<(), ContextError> {
let ret = unsafe {
self.egl.SwapBuffers(self.display, self.surface)
};
if ret == 0 {
- panic!("eglSwapBuffers failed");
+ if unsafe { self.egl.GetError() } as u32 == ffi::egl::CONTEXT_LOST {
+ return Err(ContextError::ContextLost);
+ } else {
+ panic!("eglSwapBuffers failed");
+ }
+
+ } else {
+ Ok(())
}
}
@@ -320,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));
@@ -330,7 +349,8 @@ unsafe fn create_context(egl: &ffi::egl::Egl, display: ffi::egl::types::EGLDispl
format!("")
};
- let mut context_attributes = vec![];
+ let mut context_attributes = Vec::with_capacity(10);
+ let mut flags = 0;
if egl_version >= &(1, 5) ||
extensions.contains("EGL_KHR_create_context ") ||
@@ -341,17 +361,85 @@ 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);
+ // handling robustness
+ let supports_robustness = egl_version >= &(1, 5) ||
+ extensions.contains("EGL_EXT_create_context_robustness ") ||
+ extensions.ends_with("EGL_EXT_create_context_robustness");
+
+ match gl_robustness {
+ Robustness::NotRobust => (),
+
+ Robustness::NoError => {
+ if extensions.contains("EGL_KHR_create_context_no_error ") ||
+ extensions.ends_with("EGL_KHR_create_context_no_error")
+ {
+ context_attributes.push(ffi::egl::CONTEXT_OPENGL_NO_ERROR_KHR as libc::c_int);
+ context_attributes.push(1);
+ }
+ },
+
+ Robustness::RobustNoResetNotification => {
+ if supports_robustness {
+ 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;
+ } else {
+ return Err(CreationError::NotSupported);
+ }
+ },
+
+ Robustness::TryRobustNoResetNotification => {
+ if supports_robustness {
+ 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 => {
+ if supports_robustness {
+ 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;
+ } else {
+ return Err(CreationError::NotSupported);
+ }
+ },
+
+ Robustness::TryRobustLoseContextOnReset => {
+ if supports_robustness {
+ 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;
+ }
+ },
+ }
+
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 {
+ // robustness is not supported
+ 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);
}
@@ -362,7 +450,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)