diff options
| author | Pierre Krieger <pierre.krieger1708@gmail.com> | 2015-07-18 18:32:02 +0200 | 
|---|---|---|
| committer | Pierre Krieger <pierre.krieger1708@gmail.com> | 2015-07-18 18:43:23 +0200 | 
| commit | 4eacfce59e99e4d841255a053ce6acdc77b0c91c (patch) | |
| tree | 67774d64b1e3ab7e5350f6e1123f33d959cdb7c6 /src/api | |
| parent | c1ebb8cf310947d7771c51c4949acedb19c41ee0 (diff) | |
| download | glutin-4eacfce59e99e4d841255a053ce6acdc77b0c91c.tar.gz glutin-4eacfce59e99e4d841255a053ce6acdc77b0c91c.zip | |
Split creating an EGL context in two parts
Diffstat (limited to 'src/api')
| -rw-r--r-- | src/api/android/mod.rs | 4 | ||||
| -rw-r--r-- | src/api/egl/mod.rs | 157 | ||||
| -rw-r--r-- | src/api/wayland/mod.rs | 6 | ||||
| -rw-r--r-- | src/api/win32/init.rs | 4 | ||||
| -rw-r--r-- | src/api/x11/window.rs | 4 | 
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 15e27ce..04ad2ab 100644 --- a/src/api/x11/window.rs +++ b/src/api/x11/window.rs @@ -572,14 +572,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);                  } | 
