From 5a7783c3290a498a17a23030d0aa814bb9febd55 Mon Sep 17 00:00:00 2001 From: Mick van Gelderen Date: Wed, 2 Oct 2024 19:01:32 +0200 Subject: [PATCH] api/context: add `make_not_current_as_possibly_current` Allow making the context not current by reference. --- CHANGELOG.md | 2 ++ glutin/src/api/cgl/context.rs | 6 +++- glutin/src/api/egl/context.rs | 6 +++- glutin/src/api/glx/context.rs | 6 +++- glutin/src/api/wgl/context.rs | 8 +++-- glutin/src/context.rs | 9 ++++++ .../examples/switch_render_thread.rs | 30 ++++--------------- 7 files changed, 38 insertions(+), 29 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f613522474..cfc3032ce9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,7 @@ # Unreleased +- Add `PossiblyCurrentContext::make_not_current_in_place(&self)` for when `Send` capability of `NotCurrentContext` is not required. + # Version 0.32.1 - Fixed EGL's `Device::query_devices()` being too strict about required extensions. diff --git a/glutin/src/api/cgl/context.rs b/glutin/src/api/cgl/context.rs index d5b16a9e5d..2b5d04f791 100644 --- a/glutin/src/api/cgl/context.rs +++ b/glutin/src/api/cgl/context.rs @@ -148,10 +148,14 @@ impl PossiblyCurrentGlContext for PossiblyCurrentContext { type Surface = Surface; fn make_not_current(self) -> Result { - self.inner.make_not_current()?; + self.make_not_current_in_place()?; Ok(NotCurrentContext::new(self.inner)) } + fn make_not_current_in_place(&self) -> Result<()> { + self.inner.make_not_current() + } + fn is_current(&self) -> bool { if let Some(current) = NSOpenGLContext::currentContext() { current == self.inner.raw diff --git a/glutin/src/api/egl/context.rs b/glutin/src/api/egl/context.rs index 7647e43347..d8827d9329 100644 --- a/glutin/src/api/egl/context.rs +++ b/glutin/src/api/egl/context.rs @@ -259,10 +259,14 @@ impl PossiblyCurrentGlContext for PossiblyCurrentContext { type Surface = Surface; fn make_not_current(self) -> Result { - self.inner.make_not_current()?; + self.make_not_current_in_place()?; Ok(NotCurrentContext::new(self.inner)) } + fn make_not_current_in_place(&self) -> Result<()> { + self.inner.make_not_current() + } + fn is_current(&self) -> bool { unsafe { self.inner.bind_api(); diff --git a/glutin/src/api/glx/context.rs b/glutin/src/api/glx/context.rs index af77728a0a..2fd8124343 100644 --- a/glutin/src/api/glx/context.rs +++ b/glutin/src/api/glx/context.rs @@ -302,10 +302,14 @@ impl PossiblyCurrentGlContext for PossiblyCurrentContext { type Surface = Surface; fn make_not_current(self) -> Result { - self.inner.make_not_current()?; + self.make_not_current_in_place()?; Ok(NotCurrentContext::new(self.inner)) } + fn make_not_current_in_place(&self) -> Result<()> { + self.inner.make_not_current() + } + fn is_current(&self) -> bool { unsafe { self.inner.display.inner.glx.GetCurrentContext() == *self.inner.raw } } diff --git a/glutin/src/api/wgl/context.rs b/glutin/src/api/wgl/context.rs index 25e5de00ba..b443cab6da 100644 --- a/glutin/src/api/wgl/context.rs +++ b/glutin/src/api/wgl/context.rs @@ -288,6 +288,11 @@ impl PossiblyCurrentGlContext for PossiblyCurrentContext { type Surface = Surface; fn make_not_current(self) -> Result { + self.make_not_current_in_place()?; + Ok(NotCurrentContext::new(self.inner)) + } + + fn make_not_current_in_place(&self) -> Result<()> { unsafe { if self.is_current() { let hdc = wgl::GetCurrentDC(); @@ -295,9 +300,8 @@ impl PossiblyCurrentGlContext for PossiblyCurrentContext { return Err(IoError::last_os_error().into()); } } - - Ok(NotCurrentContext::new(self.inner)) } + Ok(()) } fn is_current(&self) -> bool { diff --git a/glutin/src/context.rs b/glutin/src/context.rs index 7d14582fef..1c1c22b04c 100644 --- a/glutin/src/context.rs +++ b/glutin/src/context.rs @@ -97,6 +97,11 @@ pub trait PossiblyCurrentGlContext: Sealed { /// - **macOS: this will block if your main thread is blocked.** fn make_not_current(self) -> Result; + /// Make the context not current to the current thread. If you need to + /// send the context to another thread, use [`Self::make_not_current`] + /// instead. + fn make_not_current_in_place(&self) -> Result<()>; + /// Make [`Self::Surface`] current on the calling thread. /// /// # Platform specific @@ -517,6 +522,10 @@ impl PossiblyCurrentGlContext for PossiblyCurrentContext { ) } + fn make_not_current_in_place(&self) -> Result<()> { + Ok(gl_api_dispatch!(self; Self(context) => context.make_not_current_in_place()?)) + } + fn make_current(&self, surface: &Self::Surface) -> Result<()> { match (self, surface) { #[cfg(egl_backend)] diff --git a/glutin_examples/examples/switch_render_thread.rs b/glutin_examples/examples/switch_render_thread.rs index 822c9ce382..51ee77cce5 100644 --- a/glutin_examples/examples/switch_render_thread.rs +++ b/glutin_examples/examples/switch_render_thread.rs @@ -7,7 +7,6 @@ use std::thread; use glutin::config::ConfigTemplateBuilder; use glutin::context::{ContextAttributesBuilder, PossiblyCurrentContext}; use glutin::display::GetGlDisplay; -use glutin::error::{Error as GlutinError, ErrorKind}; use glutin::prelude::*; use glutin::surface::{Surface, WindowSurface}; use glutin_examples::gl::types::GLfloat; @@ -148,7 +147,7 @@ impl AppState { /// A rendering context that can be shared between tasks. struct RenderContext { - context: Option, + context: PossiblyCurrentContext, surface: Surface, renderer: Renderer, } @@ -161,31 +160,19 @@ impl RenderContext { surface: Surface, renderer: Renderer, ) -> Self { - Self { context: Some(context), surface, renderer } + Self { context, surface, renderer } } fn make_current(&mut self) -> Result<(), impl Error> { - let ctx = - self.context.take().ok_or_else(|| GlutinError::from(ErrorKind::BadContextState))?; - let result = ctx.make_current(&self.surface); - self.context = Some(ctx); - result + self.context.make_current(&self.surface) } fn make_not_current(&mut self) -> Result<(), impl Error> { - let ctx = - self.context.take().ok_or_else(|| GlutinError::from(ErrorKind::BadContextState))?; - let not_current_ctx = ctx.make_not_current()?; - self.context = Some(not_current_ctx.treat_as_possibly_current()); - Ok::<(), GlutinError>(()) + self.context.make_not_current_in_place() } fn swap_buffers(&mut self) -> Result<(), impl Error> { - let ctx = - self.context.take().ok_or_else(|| GlutinError::from(ErrorKind::BadContextState))?; - let result = self.surface.swap_buffers(&ctx); - self.context = Some(ctx); - result + self.surface.swap_buffers(&self.context) } fn draw_with_clear_color(&self, red: GLfloat, green: GLfloat, blue: GLfloat, alpha: GLfloat) { @@ -193,12 +180,7 @@ impl RenderContext { } fn resize(&mut self, size: PhysicalSize) { - let Some(ctx) = self.context.take() else { - return; - }; - self.surface.resize(&ctx, size.width, size.height); - self.context = Some(ctx); - + self.surface.resize(&self.context, size.width, size.height); self.renderer.resize(size.width.get() as i32, size.height.get() as i32); } }