From 9d3ae5110ee710bab443e14a8737ddfb09d8d66f Mon Sep 17 00:00:00 2001 From: Robbert van der Helm Date: Fri, 11 Mar 2022 20:50:57 +0100 Subject: [PATCH] Allow taking ownership of the OpenGL context This is needed for certain GUI integrations that require moving the context into something that's `Send + Sync + 'static`. --- src/macos/window.rs | 4 ++-- src/win/window.rs | 26 +++++++++++++++----------- src/window.rs | 7 ++++--- src/x11/window.rs | 4 ++-- 4 files changed, 23 insertions(+), 18 deletions(-) diff --git a/src/macos/window.rs b/src/macos/window.rs index 08753774..12d958b1 100644 --- a/src/macos/window.rs +++ b/src/macos/window.rs @@ -303,8 +303,8 @@ impl Window { } #[cfg(feature = "opengl")] - pub fn gl_context(&self) -> Option<&GlContext> { - self.gl_context.as_ref() + pub fn gl_context(&mut self) -> Option { + self.gl_context.take() } #[cfg(feature = "opengl")] diff --git a/src/win/window.rs b/src/win/window.rs index 2f4f056e..163f3d7a 100644 --- a/src/win/window.rs +++ b/src/win/window.rs @@ -35,7 +35,10 @@ use crate::{ use super::keyboard::KeyboardState; #[cfg(feature = "opengl")] -use crate::{gl::GlContext, window::RawWindowHandleWrapper}; +use { + crate::{gl::GlContext, window::RawWindowHandleWrapper}, + std::sync::Mutex, +}; unsafe fn generate_guid() -> String { let mut guid: GUID = std::mem::zeroed(); @@ -373,7 +376,7 @@ struct WindowState { dw_style: u32, #[cfg(feature = "opengl")] - gl_context: Arc>, + gl_context: Arc>>, } impl WindowState { @@ -392,7 +395,7 @@ pub struct Window { hwnd: HWND, #[cfg(feature = "opengl")] - gl_context: Arc>, + gl_context: Arc>>, } impl Window { @@ -511,13 +514,14 @@ impl Window { // todo: manage error ^ #[cfg(feature = "opengl")] - let gl_context: Arc> = Arc::new(options.gl_config.map(|gl_config| { - let mut handle = Win32Handle::empty(); - handle.hwnd = hwnd as *mut c_void; - let handle = RawWindowHandleWrapper { handle: RawWindowHandle::Win32(handle) }; + let gl_context: Arc>> = + Arc::new(Mutex::new(options.gl_config.map(|gl_config| { + let mut handle = Win32Handle::empty(); + handle.hwnd = hwnd as *mut c_void; + let handle = RawWindowHandleWrapper { handle: RawWindowHandle::Win32(handle) }; - GlContext::create(&handle, gl_config).expect("Could not create OpenGL context") - })); + GlContext::create(&handle, gl_config).expect("Could not create OpenGL context") + }))); #[cfg(not(feature = "opengl"))] let handler = Box::new(build(&mut crate::Window::new(&mut Window { hwnd }))); @@ -608,8 +612,8 @@ impl Window { } #[cfg(feature = "opengl")] - pub fn gl_context(&self) -> Option<&GlContext> { - self.gl_context.as_ref().as_ref() + pub fn gl_context(&self) -> Option { + self.gl_context.lock().unwrap().take() } } diff --git a/src/window.rs b/src/window.rs index a0d91f64..6221392d 100644 --- a/src/window.rs +++ b/src/window.rs @@ -98,10 +98,11 @@ impl<'a> Window<'a> { self.window.close(); } - /// If provided, then an OpenGL context will be created for this window. You'll be able to - /// access this context through [crate::Window::gl_context]. + /// If the window has been created with [`WindowOpenOptions::gl_config`] set, then this will + /// contain the OpenGL context. Calling this function will take ownership of that OpenGL + /// context, so you can do this once after which you will need to store the context yourself. #[cfg(feature = "opengl")] - pub fn gl_context(&self) -> Option<&crate::gl::GlContext> { + pub fn gl_context(&mut self) -> Option { self.window.gl_context() } } diff --git a/src/x11/window.rs b/src/x11/window.rs index bfe9567d..62fb9eec 100644 --- a/src/x11/window.rs +++ b/src/x11/window.rs @@ -390,8 +390,8 @@ impl Window { } #[cfg(feature = "opengl")] - pub fn gl_context(&self) -> Option<&crate::gl::GlContext> { - self.gl_context.as_ref() + pub fn gl_context(&mut self) -> Option { + self.gl_context.take() } fn find_visual_for_depth(screen: &StructPtr, depth: u8) -> Option {