mirror of
https://github.com/italicsjenga/winit-sonoma-fix.git
synced 2024-12-24 22:31:30 +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::ContextWrapper;
|
||||
use super::WindowWrapper;
|
||||
use super::make_current_guard::CurrentContextGuard;
|
||||
|
||||
use Api;
|
||||
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));
|
||||
|
||||
// making context current
|
||||
gl::wgl::MakeCurrent(dummy_window.1 as *const libc::c_void,
|
||||
dummy_context.0 as *const libc::c_void);
|
||||
let current_context = try!(CurrentContextGuard::make_current(&dummy_window,
|
||||
&dummy_context));
|
||||
|
||||
// loading the extra WGL functions
|
||||
let extra_functions = gl::wgl_extra::Wgl::load_with(|addr| {
|
||||
gl::wgl_extra::Wgl::load_with(|addr| {
|
||||
use libc;
|
||||
|
||||
let addr = CString::new(addr.as_bytes()).unwrap();
|
||||
let addr = addr.as_ptr();
|
||||
|
||||
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
|
||||
|
@ -237,15 +232,11 @@ unsafe fn init(title: Vec<u16>, builder: BuilderAttribs<'static>,
|
|||
// handling vsync
|
||||
if builder.vsync {
|
||||
if extra_functions.SwapIntervalEXT.is_loaded() {
|
||||
gl::wgl::MakeCurrent(real_window.1 as *const libc::c_void,
|
||||
context.0 as *const libc::c_void);
|
||||
let guard = try!(CurrentContextGuard::make_current(&real_window, &context));
|
||||
|
||||
if extra_functions.SwapIntervalEXT(1) == 0 {
|
||||
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 headless;
|
||||
mod init;
|
||||
mod make_current_guard;
|
||||
mod monitor;
|
||||
|
||||
/// The Win32 implementation of the main `Window` object.
|
||||
|
|
Loading…
Reference in a new issue