Skip to content

Commit

Permalink
api/context: add make_not_current_as_possibly_current
Browse files Browse the repository at this point in the history
Allow making the context not current by reference.
  • Loading branch information
mickvangelderen authored Oct 2, 2024
1 parent 23e4ca1 commit 5a7783c
Show file tree
Hide file tree
Showing 7 changed files with 38 additions and 29 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -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.
Expand Down
6 changes: 5 additions & 1 deletion glutin/src/api/cgl/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -148,10 +148,14 @@ impl PossiblyCurrentGlContext for PossiblyCurrentContext {
type Surface<T: SurfaceTypeTrait> = Surface<T>;

fn make_not_current(self) -> Result<Self::NotCurrentContext> {
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
Expand Down
6 changes: 5 additions & 1 deletion glutin/src/api/egl/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -259,10 +259,14 @@ impl PossiblyCurrentGlContext for PossiblyCurrentContext {
type Surface<T: SurfaceTypeTrait> = Surface<T>;

fn make_not_current(self) -> Result<Self::NotCurrentContext> {
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();
Expand Down
6 changes: 5 additions & 1 deletion glutin/src/api/glx/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -302,10 +302,14 @@ impl PossiblyCurrentGlContext for PossiblyCurrentContext {
type Surface<T: SurfaceTypeTrait> = Surface<T>;

fn make_not_current(self) -> Result<Self::NotCurrentContext> {
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 }
}
Expand Down
8 changes: 6 additions & 2 deletions glutin/src/api/wgl/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -288,16 +288,20 @@ impl PossiblyCurrentGlContext for PossiblyCurrentContext {
type Surface<T: SurfaceTypeTrait> = Surface<T>;

fn make_not_current(self) -> Result<Self::NotCurrentContext> {
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();
if wgl::MakeCurrent(hdc, std::ptr::null()) == 0 {
return Err(IoError::last_os_error().into());
}
}

Ok(NotCurrentContext::new(self.inner))
}
Ok(())
}

fn is_current(&self) -> bool {
Expand Down
9 changes: 9 additions & 0 deletions glutin/src/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,11 @@ pub trait PossiblyCurrentGlContext: Sealed {
/// - **macOS: this will block if your main thread is blocked.**
fn make_not_current(self) -> Result<Self::NotCurrentContext>;

/// 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
Expand Down Expand Up @@ -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<T: SurfaceTypeTrait>(&self, surface: &Self::Surface<T>) -> Result<()> {
match (self, surface) {
#[cfg(egl_backend)]
Expand Down
30 changes: 6 additions & 24 deletions glutin_examples/examples/switch_render_thread.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -148,7 +147,7 @@ impl AppState {

/// A rendering context that can be shared between tasks.
struct RenderContext {
context: Option<PossiblyCurrentContext>,
context: PossiblyCurrentContext,
surface: Surface<WindowSurface>,
renderer: Renderer,
}
Expand All @@ -161,44 +160,27 @@ impl RenderContext {
surface: Surface<WindowSurface>,
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) {
self.renderer.draw_with_clear_color(red, green, blue, alpha)
}

fn resize(&mut self, size: PhysicalSize<NonZeroU32>) {
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);
}
}
Expand Down

0 comments on commit 5a7783c

Please sign in to comment.