mirror of
https://github.com/italicsjenga/winit-sonoma-fix.git
synced 2024-12-25 06:41:31 +11:00
Add a guard for the calls to MakeCurrent during initialization
This commit is contained in:
parent
cca23f8544
commit
4f98ea3128
|
@ -9,6 +9,7 @@ use super::Window;
|
||||||
use super::MonitorID;
|
use super::MonitorID;
|
||||||
use super::ContextWrapper;
|
use super::ContextWrapper;
|
||||||
use super::WindowWrapper;
|
use super::WindowWrapper;
|
||||||
|
use super::make_current_guard::CurrentContextGuard;
|
||||||
|
|
||||||
use Api;
|
use Api;
|
||||||
use BuilderAttribs;
|
use BuilderAttribs;
|
||||||
|
@ -143,24 +144,18 @@ unsafe fn init(title: Vec<u16>, builder: BuilderAttribs<'static>,
|
||||||
let dummy_context = try!(create_context(None, &dummy_window, None));
|
let dummy_context = try!(create_context(None, &dummy_window, None));
|
||||||
|
|
||||||
// making context current
|
// making context current
|
||||||
gl::wgl::MakeCurrent(dummy_window.1 as *const libc::c_void,
|
let current_context = try!(CurrentContextGuard::make_current(&dummy_window,
|
||||||
dummy_context.0 as *const libc::c_void);
|
&dummy_context));
|
||||||
|
|
||||||
// loading the extra WGL functions
|
// loading the extra WGL functions
|
||||||
let extra_functions = gl::wgl_extra::Wgl::load_with(|addr| {
|
gl::wgl_extra::Wgl::load_with(|addr| {
|
||||||
use libc;
|
use libc;
|
||||||
|
|
||||||
let addr = CString::new(addr.as_bytes()).unwrap();
|
let addr = CString::new(addr.as_bytes()).unwrap();
|
||||||
let addr = addr.as_ptr();
|
let addr = addr.as_ptr();
|
||||||
|
|
||||||
gl::wgl::GetProcAddress(addr) as *const libc::c_void
|
gl::wgl::GetProcAddress(addr) as *const libc::c_void
|
||||||
});
|
})
|
||||||
|
|
||||||
// removing current context
|
|
||||||
gl::wgl::MakeCurrent(ptr::null(), ptr::null());
|
|
||||||
|
|
||||||
// returning the address
|
|
||||||
extra_functions
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// creating the real window this time
|
// creating the real window this time
|
||||||
|
@ -237,15 +232,11 @@ unsafe fn init(title: Vec<u16>, builder: BuilderAttribs<'static>,
|
||||||
// handling vsync
|
// handling vsync
|
||||||
if builder.vsync {
|
if builder.vsync {
|
||||||
if extra_functions.SwapIntervalEXT.is_loaded() {
|
if extra_functions.SwapIntervalEXT.is_loaded() {
|
||||||
gl::wgl::MakeCurrent(real_window.1 as *const libc::c_void,
|
let guard = try!(CurrentContextGuard::make_current(&real_window, &context));
|
||||||
context.0 as *const libc::c_void);
|
|
||||||
if extra_functions.SwapIntervalEXT(1) == 0 {
|
if extra_functions.SwapIntervalEXT(1) == 0 {
|
||||||
return Err(OsError(format!("wglSwapIntervalEXT failed")));
|
return Err(OsError(format!("wglSwapIntervalEXT failed")));
|
||||||
}
|
}
|
||||||
|
|
||||||
// it is important to remove the current context, otherwise you get very weird
|
|
||||||
// errors
|
|
||||||
gl::wgl::MakeCurrent(ptr::null(), ptr::null());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
53
src/win32/make_current_guard.rs
Normal file
53
src/win32/make_current_guard.rs
Normal file
|
@ -0,0 +1,53 @@
|
||||||
|
use std::marker::PhantomData;
|
||||||
|
use std::os;
|
||||||
|
|
||||||
|
use libc;
|
||||||
|
use winapi;
|
||||||
|
use CreationError;
|
||||||
|
|
||||||
|
use super::gl;
|
||||||
|
use super::ContextWrapper;
|
||||||
|
use super::WindowWrapper;
|
||||||
|
|
||||||
|
/// A guard for when you want to make the context current. Destroying the guard restores the
|
||||||
|
/// previously-current context.
|
||||||
|
pub struct CurrentContextGuard<'a, 'b> {
|
||||||
|
previous_hdc: winapi::HDC,
|
||||||
|
previous_hglrc: winapi::HGLRC,
|
||||||
|
marker1: PhantomData<&'a ()>,
|
||||||
|
marker2: PhantomData<&'b ()>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a, 'b> CurrentContextGuard<'a, 'b> {
|
||||||
|
pub unsafe fn make_current(window: &'a WindowWrapper, context: &'b ContextWrapper)
|
||||||
|
-> Result<CurrentContextGuard<'a, 'b>, CreationError>
|
||||||
|
{
|
||||||
|
let previous_hdc = gl::wgl::GetCurrentDC() as winapi::HDC;
|
||||||
|
let previous_hglrc = gl::wgl::GetCurrentContext() as winapi::HGLRC;
|
||||||
|
|
||||||
|
let result = gl::wgl::MakeCurrent(window.1 as *const libc::c_void,
|
||||||
|
context.0 as *const libc::c_void);
|
||||||
|
|
||||||
|
if result == 0 {
|
||||||
|
return Err(CreationError::OsError(format!("wglMakeCurrent function failed: {}",
|
||||||
|
os::error_string(os::errno()))));
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(CurrentContextGuard {
|
||||||
|
previous_hdc: previous_hdc,
|
||||||
|
previous_hglrc: previous_hglrc,
|
||||||
|
marker1: PhantomData,
|
||||||
|
marker2: PhantomData,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[unsafe_destructor]
|
||||||
|
impl<'a, 'b> Drop for CurrentContextGuard<'a, 'b> {
|
||||||
|
fn drop(&mut self) {
|
||||||
|
unsafe {
|
||||||
|
gl::wgl::MakeCurrent(self.previous_hdc as *const libc::c_void,
|
||||||
|
self.previous_hglrc as *const libc::c_void);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -21,6 +21,7 @@ mod event;
|
||||||
mod gl;
|
mod gl;
|
||||||
mod headless;
|
mod headless;
|
||||||
mod init;
|
mod init;
|
||||||
|
mod make_current_guard;
|
||||||
mod monitor;
|
mod monitor;
|
||||||
|
|
||||||
/// The Win32 implementation of the main `Window` object.
|
/// The Win32 implementation of the main `Window` object.
|
||||||
|
|
Loading…
Reference in a new issue