aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authortomaka <pierre.krieger1708@gmail.com>2015-07-19 09:42:56 +0200
committertomaka <pierre.krieger1708@gmail.com>2015-07-19 09:42:56 +0200
commit896640f2e0fd659e952e492c1b74841624db8d08 (patch)
treeadccd7de2cc8374f432b84e921fb986988ad0679
parent7d1d035d9ad5d262a67c6857596caefe957dcfda (diff)
parent4eacfce59e99e4d841255a053ce6acdc77b0c91c (diff)
downloadglutin-896640f2e0fd659e952e492c1b74841624db8d08.tar.gz
glutin-896640f2e0fd659e952e492c1b74841624db8d08.zip
Merge pull request #523 from tomaka/egl-split
Split creating an EGL context in two parts
-rw-r--r--src/api/android/mod.rs4
-rw-r--r--src/api/egl/mod.rs157
-rw-r--r--src/api/wayland/mod.rs6
-rw-r--r--src/api/win32/init.rs4
-rw-r--r--src/api/x11/window.rs4
5 files changed, 112 insertions, 63 deletions
diff --git a/src/api/android/mod.rs b/src/api/android/mod.rs
index 1649772..b5fac08 100644
--- a/src/api/android/mod.rs
+++ b/src/api/android/mod.rs
@@ -111,8 +111,8 @@ impl Window {
return Err(OsError(format!("Android's native window is null")));
}
- let context = try!(EglContext::new(egl::ffi::egl::Egl, &builder, None,
- native_window as *const _));
+ let context = try!(EglContext::new(egl::ffi::egl::Egl, &builder, None)
+ .and_then(|p| p.finish(native_window as *const _)));
let (tx, rx) = channel();
android_glue::add_sender(tx);
diff --git a/src/api/egl/mod.rs b/src/api/egl/mod.rs
index 1a6cc06..0cb6dbd 100644
--- a/src/api/egl/mod.rs
+++ b/src/api/egl/mod.rs
@@ -26,9 +26,14 @@ pub struct Context {
}
impl Context {
- pub fn new(egl: ffi::egl::Egl, builder: &BuilderAttribs,
- native_display: Option<ffi::EGLNativeDisplayType>,
- native_window: ffi::EGLNativeWindowType) -> Result<Context, CreationError>
+ /// Start building an EGL context.
+ ///
+ /// This function initializes some things and chooses the pixel format.
+ ///
+ /// To finish the process, you must call `.finish(window)` on the `ContextPrototype`.
+ pub fn new<'a>(egl: ffi::egl::Egl, builder: &'a BuilderAttribs<'a>,
+ native_display: Option<ffi::EGLNativeDisplayType>)
+ -> Result<ContextPrototype<'a>, CreationError>
{
if builder.sharing.is_some() {
unimplemented!()
@@ -106,60 +111,14 @@ impl Context {
let configs = unsafe { try!(enumerate_configs(&egl, display, &egl_version, api, version)) };
let (config_id, pixel_format) = try!(builder.choose_pixel_format(configs.into_iter()));
- let surface = unsafe {
- let surface = egl.CreateWindowSurface(display, config_id, native_window, ptr::null());
- if surface.is_null() {
- return Err(CreationError::OsError(format!("eglCreateWindowSurface failed")))
- }
- surface
- };
-
- let context = unsafe {
- if let Some(version) = version {
- try!(create_context(&egl, display, &egl_version, api, version, config_id,
- 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, builder.gl_robustness)
- {
- ctxt
- } else if let Ok(ctxt) = create_context(&egl, display, &egl_version, api, (1, 0),
- config_id, builder.gl_debug,
- builder.gl_robustness)
- {
- ctxt
- } else {
- return Err(CreationError::NotSupported);
- }
-
- } else {
- if let Ok(ctxt) = create_context(&egl, display, &egl_version, api, (3, 2),
- 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,
- builder.gl_robustness)
- {
- ctxt
- } else if let Ok(ctxt) = create_context(&egl, display, &egl_version, api, (1, 0),
- config_id, builder.gl_debug,
- builder.gl_robustness)
- {
- ctxt
- } else {
- return Err(CreationError::NotSupported);
- }
- }
- };
-
- Ok(Context {
+ Ok(ContextPrototype {
+ builder: builder,
egl: egl,
display: display,
- context: context,
- surface: surface,
+ egl_version: egl_version,
api: api,
+ version: version,
+ config_id: config_id,
pixel_format: pixel_format,
})
}
@@ -234,6 +193,96 @@ impl Drop for Context {
}
}
+pub struct ContextPrototype<'a> {
+ builder: &'a BuilderAttribs<'a>,
+ egl: ffi::egl::Egl,
+ display: ffi::egl::types::EGLDisplay,
+ egl_version: (ffi::egl::types::EGLint, ffi::egl::types::EGLint),
+ api: Api,
+ version: Option<(u8, u8)>,
+ config_id: ffi::egl::types::EGLConfig,
+ pixel_format: PixelFormat,
+}
+
+impl<'a> ContextPrototype<'a> {
+ pub fn get_native_visual_id(&self) -> ffi::egl::types::EGLint {
+ let mut value = unsafe { mem::uninitialized() };
+ let ret = unsafe { self.egl.GetConfigAttrib(self.display, self.config_id,
+ ffi::egl::NATIVE_VISUAL_ID
+ as ffi::egl::types::EGLint, &mut value) };
+ if ret == 0 { panic!("eglGetConfigAttrib failed") };
+ value
+ }
+
+ pub fn finish(self, native_window: ffi::EGLNativeWindowType)
+ -> Result<Context, CreationError>
+ {
+ let surface = unsafe {
+ let surface = self.egl.CreateWindowSurface(self.display, self.config_id, native_window,
+ ptr::null());
+ if surface.is_null() {
+ return Err(CreationError::OsError(format!("eglCreateWindowSurface failed")))
+ }
+ surface
+ };
+
+ let context = unsafe {
+ if let Some(version) = self.version {
+ try!(create_context(&self.egl, self.display, &self.egl_version, self.api,
+ version, self.config_id, self.builder.gl_debug,
+ self.builder.gl_robustness))
+
+ } else if self.api == Api::OpenGlEs {
+ if let Ok(ctxt) = create_context(&self.egl, self.display, &self.egl_version,
+ self.api, (2, 0), self.config_id,
+ self.builder.gl_debug, self.builder.gl_robustness)
+ {
+ ctxt
+ } else if let Ok(ctxt) = create_context(&self.egl, self.display, &self.egl_version,
+ self.api, (1, 0), self.config_id,
+ self.builder.gl_debug,
+ self.builder.gl_robustness)
+ {
+ ctxt
+ } else {
+ return Err(CreationError::NotSupported);
+ }
+
+ } else {
+ if let Ok(ctxt) = create_context(&self.egl, self.display, &self.egl_version,
+ self.api, (3, 2), self.config_id,
+ self.builder.gl_debug, self.builder.gl_robustness)
+ {
+ ctxt
+ } else if let Ok(ctxt) = create_context(&self.egl, self.display, &self.egl_version,
+ self.api, (3, 1), self.config_id,
+ self.builder.gl_debug,
+ self.builder.gl_robustness)
+ {
+ ctxt
+ } else if let Ok(ctxt) = create_context(&self.egl, self.display, &self.egl_version,
+ self.api, (1, 0), self.config_id,
+ self.builder.gl_debug,
+ self.builder.gl_robustness)
+ {
+ ctxt
+ } else {
+ return Err(CreationError::NotSupported);
+ }
+ }
+ };
+
+ Ok(Context {
+ egl: self.egl,
+ display: self.display,
+ context: context,
+ surface: surface,
+ api: self.api,
+ pixel_format: self.pixel_format,
+ })
+ }
+}
+
unsafe fn enumerate_configs(egl: &ffi::egl::Egl, display: ffi::egl::types::EGLDisplay,
egl_version: &(ffi::egl::types::EGLint, ffi::egl::types::EGLint),
api: Api, version: Option<(u8, u8)>)
diff --git a/src/api/wayland/mod.rs b/src/api/wayland/mod.rs
index 0af5496..826826e 100644
--- a/src/api/wayland/mod.rs
+++ b/src/api/wayland/mod.rs
@@ -169,9 +169,9 @@ impl Window {
try!(EglContext::new(
egl,
&builder,
- Some(wayland_context.display.ptr() as *const _),
- (*shell_surface).ptr() as *const _
- ))
+ Some(wayland_context.display.ptr() as *const _))
+ .and_then(|p| p.finish((*shell_surface).ptr() as *const _))
+ )
};
let events = Arc::new(Mutex::new(VecDeque::new()));
diff --git a/src/api/win32/init.rs b/src/api/win32/init.rs
index cc6d2d2..fdb88c9 100644
--- a/src/api/win32/init.rs
+++ b/src/api/win32/init.rs
@@ -177,8 +177,8 @@ unsafe fn init(title: Vec<u16>, builder: BuilderAttribs<'static>,
unsafe { kernel32::GetProcAddress(dll, name.as_ptr()) as *const libc::c_void }
});
- if let Ok(c) = EglContext::new(egl, &builder, Some(ptr::null()),
- real_window.0)
+ if let Ok(c) = EglContext::new(egl, &builder, Some(ptr::null()))
+ .and_then(|p| p.finish(real_window.0))
{
Context::Egl(c)
diff --git a/src/api/x11/window.rs b/src/api/x11/window.rs
index b13a94a..79118ff 100644
--- a/src/api/x11/window.rs
+++ b/src/api/x11/window.rs
@@ -552,14 +552,14 @@ impl Window {
Context::Glx(try!(GlxContext::new(glx.clone(), builder, display.display, window,
fb_config, visual_infos)))
} else if let Some(ref egl) = display.egl {
- Context::Egl(try!(EglContext::new(egl.clone(), &builder, Some(display.display as *const _), window as *const _)))
+ Context::Egl(try!(EglContext::new(egl.clone(), &builder, Some(display.display as *const _)).and_then(|p| p.finish(window as *const _))))
} else {
return Err(CreationError::NotSupported);
}
},
GlRequest::Specific(Api::OpenGlEs, _) => {
if let Some(ref egl) = display.egl {
- Context::Egl(try!(EglContext::new(egl.clone(), &builder, Some(display.display as *const _), window as *const _)))
+ Context::Egl(try!(EglContext::new(egl.clone(), &builder, Some(display.display as *const _)).and_then(|p| p.finish(window as *const _))))
} else {
return Err(CreationError::NotSupported);
}