Convert GLX to the new design

This commit is contained in:
Pierre Krieger 2015-09-21 11:39:34 +02:00
parent 8f3ec7998d
commit b5d0a3eb67
2 changed files with 34 additions and 37 deletions

View file

@ -1,13 +1,14 @@
#![cfg(all(any(target_os = "linux", target_os = "dragonfly", target_os = "freebsd"), feature = "window"))]
use BuilderAttribs;
use ContextError;
use CreationError;
use GlAttributes;
use GlContext;
use GlProfile;
use GlRequest;
use Api;
use PixelFormat;
use PixelFormatRequirements;
use Robustness;
use libc;
@ -34,14 +35,14 @@ fn with_c_str<F, T>(s: &str, f: F) -> T where F: FnOnce(*const libc::c_char) ->
}
impl Context {
pub fn new<'a>(glx: ffi::glx::Glx, xlib: &ffi::Xlib, builder: &'a BuilderAttribs<'a>,
display: *mut ffi::Display)
pub fn new<'a>(glx: ffi::glx::Glx, xlib: &ffi::Xlib, pf_reqs: &PixelFormatRequirements,
opengl: &'a GlAttributes<&'a Context>, display: *mut ffi::Display)
-> Result<ContextPrototype<'a>, CreationError>
{
// finding the pixel format we want
let (fb_config, pixel_format) = {
let configs = unsafe { try!(enumerate_configs(&glx, xlib, display)) };
try!(builder.choose_pixel_format(configs.into_iter()))
try!(pf_reqs.choose_pixel_format(configs.into_iter()))
};
// getting the visual infos
@ -57,7 +58,7 @@ impl Context {
Ok(ContextPrototype {
glx: glx,
builder: builder,
opengl: opengl,
display: display,
fb_config: fb_config,
visual_infos: unsafe { mem::transmute(visual_infos) },
@ -120,7 +121,7 @@ impl Drop for Context {
pub struct ContextPrototype<'a> {
glx: ffi::glx::Glx,
builder: &'a BuilderAttribs<'a>,
opengl: &'a GlAttributes<&'a Context>,
display: *mut ffi::Display,
fb_config: ffi::glx::types::GLXFBConfig,
visual_infos: ffi::XVisualInfo,
@ -133,16 +134,9 @@ impl<'a> ContextPrototype<'a> {
}
pub fn finish(self, window: ffi::Window) -> Result<Context, CreationError> {
let share = if let Some(win) = self.builder.opengl.sharing {
match win {
&PlatformWindow::X(ref win) => match win.x.context {
::api::x11::Context::Glx(ref c) => c.context,
_ => panic!("Cannot share contexts between different APIs")
},
_ => panic!("Cannot use glx on a non-X11 window.")
}
} else {
ptr::null()
let share = match self.opengl.sharing {
Some(ctxt) => ctxt.context,
None => ptr::null()
};
// loading the list of extensions
@ -160,46 +154,46 @@ impl<'a> ContextPrototype<'a> {
});
// creating GL context
let context = match self.builder.opengl.version {
let context = match self.opengl.version {
GlRequest::Latest => {
if let Ok(ctxt) = create_context(&self.glx, &extra_functions, &extensions, (3, 2),
self.builder.opengl.profile, self.builder.opengl.debug,
self.builder.opengl.robustness, share,
self.opengl.profile, self.opengl.debug,
self.opengl.robustness, share,
self.display, self.fb_config, &self.visual_infos)
{
ctxt
} else if let Ok(ctxt) = create_context(&self.glx, &extra_functions, &extensions,
(3, 1), self.builder.opengl.profile,
self.builder.opengl.debug,
self.builder.opengl.robustness, share, self.display,
(3, 1), self.opengl.profile,
self.opengl.debug,
self.opengl.robustness, share, self.display,
self.fb_config, &self.visual_infos)
{
ctxt
} else {
try!(create_context(&self.glx, &extra_functions, &extensions, (1, 0),
self.builder.opengl.profile, self.builder.opengl.debug,
self.builder.opengl.robustness,
self.opengl.profile, self.opengl.debug,
self.opengl.robustness,
share, self.display, self.fb_config, &self.visual_infos))
}
},
GlRequest::Specific(Api::OpenGl, (major, minor)) => {
try!(create_context(&self.glx, &extra_functions, &extensions, (major, minor),
self.builder.opengl.profile, self.builder.opengl.debug,
self.builder.opengl.robustness, share, self.display, self.fb_config,
self.opengl.profile, self.opengl.debug,
self.opengl.robustness, share, self.display, self.fb_config,
&self.visual_infos))
},
GlRequest::Specific(_, _) => panic!("Only OpenGL is supported"),
GlRequest::GlThenGles { opengl_version: (major, minor), .. } => {
try!(create_context(&self.glx, &extra_functions, &extensions, (major, minor),
self.builder.opengl.profile, self.builder.opengl.debug,
self.builder.opengl.robustness, share, self.display, self.fb_config,
self.opengl.profile, self.opengl.debug,
self.opengl.robustness, share, self.display, self.fb_config,
&self.visual_infos))
},
};
// vsync
if self.builder.opengl.vsync {
if self.opengl.vsync {
unsafe { self.glx.MakeCurrent(self.display as *mut _, window, context) };
if extra_functions.SwapIntervalEXT.is_loaded() {
@ -209,7 +203,8 @@ impl<'a> ContextPrototype<'a> {
}
// checking that it worked
if self.builder.strict {
// TODO: handle this
/*if self.builder.strict {
let mut swap = unsafe { mem::uninitialized() };
unsafe {
self.glx.QueryDrawable(self.display as *mut _, window,
@ -221,7 +216,7 @@ impl<'a> ContextPrototype<'a> {
return Err(CreationError::OsError(format!("Couldn't setup vsync: expected \
interval `1` but got `{}`", swap)));
}
}
}*/
// GLX_MESA_swap_control is not official
/*} else if extra_functions.SwapIntervalMESA.is_loaded() {
@ -234,9 +229,10 @@ impl<'a> ContextPrototype<'a> {
extra_functions.SwapIntervalSGI(1);
}
} else if self.builder.strict {
}/* else if self.builder.strict {
// TODO: handle this
return Err(CreationError::OsError(format!("Couldn't find any available vsync extension")));
}
}*/
unsafe { self.glx.MakeCurrent(self.display as *mut _, 0, ptr::null()) };
}

View file

@ -349,22 +349,23 @@ impl Window {
Egl(::api::egl::ContextPrototype<'a>),
}
let builder_clone = builder.clone();
let builder_clone_opengl = builder_clone.opengl.clone().map_sharing(|_| unimplemented!());
let builder_clone_opengl_glx = builder_clone.opengl.clone().map_sharing(|_| unimplemented!()); // FIXME:
let builder_clone_opengl_egl = builder_clone.opengl.clone().map_sharing(|_| unimplemented!()); // FIXME:
let context = match builder.opengl.version {
GlRequest::Latest | GlRequest::Specific(Api::OpenGl, _) | GlRequest::GlThenGles { .. } => {
// GLX should be preferred over EGL, otherwise crashes may occur
// on X11 issue #314
if let Some(ref glx) = display.glx {
Prototype::Glx(try!(GlxContext::new(glx.clone(), &display.xlib, &builder_clone, display.display)))
Prototype::Glx(try!(GlxContext::new(glx.clone(), &display.xlib, &builder_clone.pf_reqs, &builder_clone_opengl_glx, display.display)))
} else if let Some(ref egl) = display.egl {
Prototype::Egl(try!(EglContext::new(egl.clone(), &builder_clone.pf_reqs, &builder_clone_opengl, egl::NativeDisplay::X11(Some(display.display as *const _)))))
Prototype::Egl(try!(EglContext::new(egl.clone(), &builder_clone.pf_reqs, &builder_clone_opengl_egl, egl::NativeDisplay::X11(Some(display.display as *const _)))))
} else {
return Err(CreationError::NotSupported);
}
},
GlRequest::Specific(Api::OpenGlEs, _) => {
if let Some(ref egl) = display.egl {
Prototype::Egl(try!(EglContext::new(egl.clone(), &builder_clone.pf_reqs, &builder_clone_opengl, egl::NativeDisplay::X11(Some(display.display as *const _)))))
Prototype::Egl(try!(EglContext::new(egl.clone(), &builder_clone.pf_reqs, &builder_clone_opengl_egl, egl::NativeDisplay::X11(Some(display.display as *const _)))))
} else {
return Err(CreationError::NotSupported);
}