mirror of
https://github.com/italicsjenga/winit-sonoma-fix.git
synced 2024-12-24 22:31:30 +11:00
Convert GLX to the new design
This commit is contained in:
parent
8f3ec7998d
commit
b5d0a3eb67
|
@ -1,13 +1,14 @@
|
||||||
#![cfg(all(any(target_os = "linux", target_os = "dragonfly", target_os = "freebsd"), feature = "window"))]
|
#![cfg(all(any(target_os = "linux", target_os = "dragonfly", target_os = "freebsd"), feature = "window"))]
|
||||||
|
|
||||||
use BuilderAttribs;
|
|
||||||
use ContextError;
|
use ContextError;
|
||||||
use CreationError;
|
use CreationError;
|
||||||
|
use GlAttributes;
|
||||||
use GlContext;
|
use GlContext;
|
||||||
use GlProfile;
|
use GlProfile;
|
||||||
use GlRequest;
|
use GlRequest;
|
||||||
use Api;
|
use Api;
|
||||||
use PixelFormat;
|
use PixelFormat;
|
||||||
|
use PixelFormatRequirements;
|
||||||
use Robustness;
|
use Robustness;
|
||||||
|
|
||||||
use libc;
|
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 {
|
impl Context {
|
||||||
pub fn new<'a>(glx: ffi::glx::Glx, xlib: &ffi::Xlib, builder: &'a BuilderAttribs<'a>,
|
pub fn new<'a>(glx: ffi::glx::Glx, xlib: &ffi::Xlib, pf_reqs: &PixelFormatRequirements,
|
||||||
display: *mut ffi::Display)
|
opengl: &'a GlAttributes<&'a Context>, display: *mut ffi::Display)
|
||||||
-> Result<ContextPrototype<'a>, CreationError>
|
-> Result<ContextPrototype<'a>, CreationError>
|
||||||
{
|
{
|
||||||
// finding the pixel format we want
|
// finding the pixel format we want
|
||||||
let (fb_config, pixel_format) = {
|
let (fb_config, pixel_format) = {
|
||||||
let configs = unsafe { try!(enumerate_configs(&glx, xlib, display)) };
|
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
|
// getting the visual infos
|
||||||
|
@ -57,7 +58,7 @@ impl Context {
|
||||||
|
|
||||||
Ok(ContextPrototype {
|
Ok(ContextPrototype {
|
||||||
glx: glx,
|
glx: glx,
|
||||||
builder: builder,
|
opengl: opengl,
|
||||||
display: display,
|
display: display,
|
||||||
fb_config: fb_config,
|
fb_config: fb_config,
|
||||||
visual_infos: unsafe { mem::transmute(visual_infos) },
|
visual_infos: unsafe { mem::transmute(visual_infos) },
|
||||||
|
@ -120,7 +121,7 @@ impl Drop for Context {
|
||||||
|
|
||||||
pub struct ContextPrototype<'a> {
|
pub struct ContextPrototype<'a> {
|
||||||
glx: ffi::glx::Glx,
|
glx: ffi::glx::Glx,
|
||||||
builder: &'a BuilderAttribs<'a>,
|
opengl: &'a GlAttributes<&'a Context>,
|
||||||
display: *mut ffi::Display,
|
display: *mut ffi::Display,
|
||||||
fb_config: ffi::glx::types::GLXFBConfig,
|
fb_config: ffi::glx::types::GLXFBConfig,
|
||||||
visual_infos: ffi::XVisualInfo,
|
visual_infos: ffi::XVisualInfo,
|
||||||
|
@ -133,16 +134,9 @@ impl<'a> ContextPrototype<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn finish(self, window: ffi::Window) -> Result<Context, CreationError> {
|
pub fn finish(self, window: ffi::Window) -> Result<Context, CreationError> {
|
||||||
let share = if let Some(win) = self.builder.opengl.sharing {
|
let share = match self.opengl.sharing {
|
||||||
match win {
|
Some(ctxt) => ctxt.context,
|
||||||
&PlatformWindow::X(ref win) => match win.x.context {
|
None => ptr::null()
|
||||||
::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()
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// loading the list of extensions
|
// loading the list of extensions
|
||||||
|
@ -160,46 +154,46 @@ impl<'a> ContextPrototype<'a> {
|
||||||
});
|
});
|
||||||
|
|
||||||
// creating GL context
|
// creating GL context
|
||||||
let context = match self.builder.opengl.version {
|
let context = match self.opengl.version {
|
||||||
GlRequest::Latest => {
|
GlRequest::Latest => {
|
||||||
if let Ok(ctxt) = create_context(&self.glx, &extra_functions, &extensions, (3, 2),
|
if let Ok(ctxt) = create_context(&self.glx, &extra_functions, &extensions, (3, 2),
|
||||||
self.builder.opengl.profile, self.builder.opengl.debug,
|
self.opengl.profile, self.opengl.debug,
|
||||||
self.builder.opengl.robustness, share,
|
self.opengl.robustness, share,
|
||||||
self.display, self.fb_config, &self.visual_infos)
|
self.display, self.fb_config, &self.visual_infos)
|
||||||
{
|
{
|
||||||
ctxt
|
ctxt
|
||||||
} else if let Ok(ctxt) = create_context(&self.glx, &extra_functions, &extensions,
|
} else if let Ok(ctxt) = create_context(&self.glx, &extra_functions, &extensions,
|
||||||
(3, 1), self.builder.opengl.profile,
|
(3, 1), self.opengl.profile,
|
||||||
self.builder.opengl.debug,
|
self.opengl.debug,
|
||||||
self.builder.opengl.robustness, share, self.display,
|
self.opengl.robustness, share, self.display,
|
||||||
self.fb_config, &self.visual_infos)
|
self.fb_config, &self.visual_infos)
|
||||||
{
|
{
|
||||||
ctxt
|
ctxt
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
try!(create_context(&self.glx, &extra_functions, &extensions, (1, 0),
|
try!(create_context(&self.glx, &extra_functions, &extensions, (1, 0),
|
||||||
self.builder.opengl.profile, self.builder.opengl.debug,
|
self.opengl.profile, self.opengl.debug,
|
||||||
self.builder.opengl.robustness,
|
self.opengl.robustness,
|
||||||
share, self.display, self.fb_config, &self.visual_infos))
|
share, self.display, self.fb_config, &self.visual_infos))
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
GlRequest::Specific(Api::OpenGl, (major, minor)) => {
|
GlRequest::Specific(Api::OpenGl, (major, minor)) => {
|
||||||
try!(create_context(&self.glx, &extra_functions, &extensions, (major, minor),
|
try!(create_context(&self.glx, &extra_functions, &extensions, (major, minor),
|
||||||
self.builder.opengl.profile, self.builder.opengl.debug,
|
self.opengl.profile, self.opengl.debug,
|
||||||
self.builder.opengl.robustness, share, self.display, self.fb_config,
|
self.opengl.robustness, share, self.display, self.fb_config,
|
||||||
&self.visual_infos))
|
&self.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(&self.glx, &extra_functions, &extensions, (major, minor),
|
try!(create_context(&self.glx, &extra_functions, &extensions, (major, minor),
|
||||||
self.builder.opengl.profile, self.builder.opengl.debug,
|
self.opengl.profile, self.opengl.debug,
|
||||||
self.builder.opengl.robustness, share, self.display, self.fb_config,
|
self.opengl.robustness, share, self.display, self.fb_config,
|
||||||
&self.visual_infos))
|
&self.visual_infos))
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
// vsync
|
// vsync
|
||||||
if self.builder.opengl.vsync {
|
if self.opengl.vsync {
|
||||||
unsafe { self.glx.MakeCurrent(self.display as *mut _, window, context) };
|
unsafe { self.glx.MakeCurrent(self.display as *mut _, window, context) };
|
||||||
|
|
||||||
if extra_functions.SwapIntervalEXT.is_loaded() {
|
if extra_functions.SwapIntervalEXT.is_loaded() {
|
||||||
|
@ -209,7 +203,8 @@ impl<'a> ContextPrototype<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
// checking that it worked
|
// checking that it worked
|
||||||
if self.builder.strict {
|
// TODO: handle this
|
||||||
|
/*if self.builder.strict {
|
||||||
let mut swap = unsafe { mem::uninitialized() };
|
let mut swap = unsafe { mem::uninitialized() };
|
||||||
unsafe {
|
unsafe {
|
||||||
self.glx.QueryDrawable(self.display as *mut _, window,
|
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 \
|
return Err(CreationError::OsError(format!("Couldn't setup vsync: expected \
|
||||||
interval `1` but got `{}`", swap)));
|
interval `1` but got `{}`", swap)));
|
||||||
}
|
}
|
||||||
}
|
}*/
|
||||||
|
|
||||||
// GLX_MESA_swap_control is not official
|
// GLX_MESA_swap_control is not official
|
||||||
/*} else if extra_functions.SwapIntervalMESA.is_loaded() {
|
/*} else if extra_functions.SwapIntervalMESA.is_loaded() {
|
||||||
|
@ -234,9 +229,10 @@ impl<'a> ContextPrototype<'a> {
|
||||||
extra_functions.SwapIntervalSGI(1);
|
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")));
|
return Err(CreationError::OsError(format!("Couldn't find any available vsync extension")));
|
||||||
}
|
}*/
|
||||||
|
|
||||||
unsafe { self.glx.MakeCurrent(self.display as *mut _, 0, ptr::null()) };
|
unsafe { self.glx.MakeCurrent(self.display as *mut _, 0, ptr::null()) };
|
||||||
}
|
}
|
||||||
|
|
|
@ -349,22 +349,23 @@ impl Window {
|
||||||
Egl(::api::egl::ContextPrototype<'a>),
|
Egl(::api::egl::ContextPrototype<'a>),
|
||||||
}
|
}
|
||||||
let builder_clone = builder.clone();
|
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 {
|
let context = match builder.opengl.version {
|
||||||
GlRequest::Latest | GlRequest::Specific(Api::OpenGl, _) | GlRequest::GlThenGles { .. } => {
|
GlRequest::Latest | GlRequest::Specific(Api::OpenGl, _) | GlRequest::GlThenGles { .. } => {
|
||||||
// GLX should be preferred over EGL, otherwise crashes may occur
|
// GLX should be preferred over EGL, otherwise crashes may occur
|
||||||
// on X11 – issue #314
|
// on X11 – issue #314
|
||||||
if let Some(ref glx) = display.glx {
|
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 {
|
} 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 {
|
} else {
|
||||||
return Err(CreationError::NotSupported);
|
return Err(CreationError::NotSupported);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
GlRequest::Specific(Api::OpenGlEs, _) => {
|
GlRequest::Specific(Api::OpenGlEs, _) => {
|
||||||
if let Some(ref egl) = display.egl {
|
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 {
|
} else {
|
||||||
return Err(CreationError::NotSupported);
|
return Err(CreationError::NotSupported);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue