Skip to content

Commit

Permalink
api/context: unify surfaceless APIs
Browse files Browse the repository at this point in the history
The API was implemented by all backend, this patch simply promotes it
to the top-level trait.

Co-authored-by: Marijn Suijten <[email protected]>
  • Loading branch information
kchibisov and MarijnS95 authored Nov 13, 2024
1 parent e8962ee commit d9a59b0
Show file tree
Hide file tree
Showing 6 changed files with 84 additions and 93 deletions.
11 changes: 1 addition & 10 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,17 +1,8 @@
# Unreleased

- Added `PossiblyCurrentContext::make_not_current_in_place(&self)` for when `Send` capability of `NotCurrentContext` is not required.
- Added `NotCurrentContext::make_current_surfaceless(self)` and
`PossiblyCurrentContext::make_current_surfaceless(&self)` in the `Cgl`
implementation to allow the use of surfaceless contexts on MacOS.
- Added `NotCurrentContext::make_current_surfaceless(self)` and
`PossiblyCurrentContext::make_current_surfaceless(&self)` in the `Glx`
implementation to allow the use of surfaceless contexts with GLX.
- Added `NotCurrentContext::make_current_surfaceless(self)` and
`PossiblyCurrentContext::make_current_surfaceless(&self)` in the `Wgl`
implementation to allow the use of surfaceless contexts with WGL.
- Added workaround for EGL drivers reporting `EGL_KHR_platform_gbm` without EGL 1.5 client.

- **Breaking:** Added `make_current_surfaceless(self)` for `{Possibly,Not}CurrentGlContext`.

# Version 0.32.1

Expand Down
23 changes: 9 additions & 14 deletions glutin/src/api/cgl/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,13 +74,6 @@ pub struct NotCurrentContext {
}

impl NotCurrentContext {
/// Make a [`Self::PossiblyCurrentContext`] indicating that the context
/// could be current on the thread.
pub fn make_current_surfaceless(self) -> Result<PossiblyCurrentContext> {
self.inner.make_current_surfaceless()?;
Ok(PossiblyCurrentContext { inner: self.inner, _nosendsync: PhantomData })
}

fn new(inner: ContextInner) -> Self {
Self { inner, _nosync: PhantomData }
}
Expand Down Expand Up @@ -109,6 +102,11 @@ impl NotCurrentGlContext for NotCurrentContext {
) -> Result<Self::PossiblyCurrentContext> {
Err(self.inner.make_current_draw_read(surface_draw, surface_read).into())
}

fn make_current_surfaceless(self) -> Result<PossiblyCurrentContext> {
self.inner.make_current_surfaceless()?;
Ok(PossiblyCurrentContext { inner: self.inner, _nosendsync: PhantomData })
}
}

impl GlContext for NotCurrentContext {
Expand Down Expand Up @@ -150,13 +148,6 @@ pub struct PossiblyCurrentContext {
_nosendsync: PhantomData<*mut ()>,
}

impl PossiblyCurrentContext {
/// Make this context current on the calling thread.
pub fn make_current_surfaceless(&self) -> Result<()> {
self.inner.make_current_surfaceless()
}
}

impl PossiblyCurrentGlContext for PossiblyCurrentContext {
type NotCurrentContext = NotCurrentContext;
type Surface<T: SurfaceTypeTrait> = Surface<T>;
Expand Down Expand Up @@ -189,6 +180,10 @@ impl PossiblyCurrentGlContext for PossiblyCurrentContext {
) -> Result<()> {
Err(self.inner.make_current_draw_read(surface_draw, surface_read).into())
}

fn make_current_surfaceless(&self) -> Result<()> {
self.inner.make_current_surfaceless()
}
}

impl GlContext for PossiblyCurrentContext {
Expand Down
23 changes: 9 additions & 14 deletions glutin/src/api/egl/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -172,13 +172,6 @@ pub struct NotCurrentContext {
}

impl NotCurrentContext {
/// Make a [`Self::PossiblyCurrentContext`] indicating that the context
/// could be current on the thread.
pub fn make_current_surfaceless(self) -> Result<PossiblyCurrentContext> {
self.inner.make_current_surfaceless()?;
Ok(PossiblyCurrentContext { inner: self.inner, _nosendsync: PhantomData })
}

fn new(inner: ContextInner) -> Self {
Self { inner }
}
Expand Down Expand Up @@ -208,6 +201,11 @@ impl NotCurrentGlContext for NotCurrentContext {
self.inner.make_current_draw_read(surface_draw, surface_read)?;
Ok(PossiblyCurrentContext { inner: self.inner, _nosendsync: PhantomData })
}

fn make_current_surfaceless(self) -> Result<PossiblyCurrentContext> {
self.inner.make_current_surfaceless()?;
Ok(PossiblyCurrentContext { inner: self.inner, _nosendsync: PhantomData })
}
}

impl GlContext for NotCurrentContext {
Expand Down Expand Up @@ -247,13 +245,6 @@ pub struct PossiblyCurrentContext {
_nosendsync: PhantomData<EGLContext>,
}

impl PossiblyCurrentContext {
/// Make this context current on the calling thread.
pub fn make_current_surfaceless(&self) -> Result<()> {
self.inner.make_current_surfaceless()
}
}

impl PossiblyCurrentGlContext for PossiblyCurrentContext {
type NotCurrentContext = NotCurrentContext;
type Surface<T: SurfaceTypeTrait> = Surface<T>;
Expand Down Expand Up @@ -285,6 +276,10 @@ impl PossiblyCurrentGlContext for PossiblyCurrentContext {
) -> Result<()> {
self.inner.make_current_draw_read(surface_draw, surface_read)
}

fn make_current_surfaceless(&self) -> Result<()> {
self.inner.make_current_surfaceless()
}
}

impl GlContext for PossiblyCurrentContext {
Expand Down
27 changes: 9 additions & 18 deletions glutin/src/api/glx/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -241,15 +241,6 @@ pub struct NotCurrentContext {
}

impl NotCurrentContext {
/// Make a [`Self::PossiblyCurrentContext`] indicating that the context
/// could be current on the thread.
///
/// Requires the GLX_ARB_create_context extension and OpenGL 3.0 or greater.
pub fn make_current_surfaceless(self) -> Result<PossiblyCurrentContext> {
self.inner.make_current_surfaceless()?;
Ok(PossiblyCurrentContext { inner: self.inner, _nosendsync: PhantomData })
}

fn new(inner: ContextInner) -> Self {
Self { inner }
}
Expand Down Expand Up @@ -279,6 +270,11 @@ impl NotCurrentGlContext for NotCurrentContext {
self.inner.make_current_draw_read(surface_draw, surface_read)?;
Ok(PossiblyCurrentContext { inner: self.inner, _nosendsync: PhantomData })
}

fn make_current_surfaceless(self) -> Result<PossiblyCurrentContext> {
self.inner.make_current_surfaceless()?;
Ok(PossiblyCurrentContext { inner: self.inner, _nosendsync: PhantomData })
}
}

impl GlContext for NotCurrentContext {
Expand Down Expand Up @@ -319,15 +315,6 @@ pub struct PossiblyCurrentContext {
_nosendsync: PhantomData<GLXContext>,
}

impl PossiblyCurrentContext {
/// Make this context current on the calling thread.
///
/// Requires the GLX_ARB_create_context extension and OpenGL 3.0 or greater.
pub fn make_current_surfaceless(&self) -> Result<()> {
self.inner.make_current_surfaceless()
}
}

impl PossiblyCurrentGlContext for PossiblyCurrentContext {
type NotCurrentContext = NotCurrentContext;
type Surface<T: SurfaceTypeTrait> = Surface<T>;
Expand Down Expand Up @@ -356,6 +343,10 @@ impl PossiblyCurrentGlContext for PossiblyCurrentContext {
) -> Result<()> {
self.inner.make_current_draw_read(surface_draw, surface_read)
}

fn make_current_surfaceless(&self) -> Result<()> {
self.inner.make_current_surfaceless()
}
}

impl GlContext for PossiblyCurrentContext {
Expand Down
27 changes: 9 additions & 18 deletions glutin/src/api/wgl/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -232,15 +232,6 @@ impl NotCurrentContext {
fn new(inner: ContextInner) -> Self {
Self { inner }
}

/// Make a [`Self::PossiblyCurrentContext`] indicating that the context
/// could be current on the thread.
///
/// Requires the WGL_ARB_create_context extension and OpenGL 3.0 or greater.
pub fn make_current_surfaceless(self) -> Result<PossiblyCurrentContext> {
self.inner.make_current_surfaceless()?;
Ok(PossiblyCurrentContext { inner: self.inner, _nosendsync: PhantomData })
}
}

impl NotCurrentGlContext for NotCurrentContext {
Expand All @@ -266,6 +257,11 @@ impl NotCurrentGlContext for NotCurrentContext {
) -> Result<Self::PossiblyCurrentContext> {
Err(self.inner.make_current_draw_read(surface_draw, surface_read).into())
}

fn make_current_surfaceless(self) -> Result<PossiblyCurrentContext> {
self.inner.make_current_surfaceless()?;
Ok(PossiblyCurrentContext { inner: self.inner, _nosendsync: PhantomData })
}
}

impl GlContext for NotCurrentContext {
Expand Down Expand Up @@ -304,15 +300,6 @@ pub struct PossiblyCurrentContext {
_nosendsync: PhantomData<HGLRC>,
}

impl PossiblyCurrentContext {
/// Make this context current on the calling thread.
///
/// Requires the WGL_ARB_create_context extension and OpenGL 3.0 or greater.
pub fn make_current_surfaceless(&self) -> Result<()> {
self.inner.make_current_surfaceless()
}
}

impl PossiblyCurrentGlContext for PossiblyCurrentContext {
type NotCurrentContext = NotCurrentContext;
type Surface<T: SurfaceTypeTrait> = Surface<T>;
Expand Down Expand Up @@ -349,6 +336,10 @@ impl PossiblyCurrentGlContext for PossiblyCurrentContext {
) -> Result<()> {
Err(self.inner.make_current_draw_read(surface_draw, surface_read).into())
}

fn make_current_surfaceless(&self) -> Result<()> {
self.inner.make_current_surfaceless()
}
}

impl Sealed for PossiblyCurrentContext {}
Expand Down
66 changes: 47 additions & 19 deletions glutin/src/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,9 +49,9 @@ pub trait NotCurrentGlContext: Sealed {
/// guaranteed to be current.
fn treat_as_possibly_current(self) -> Self::PossiblyCurrentContext;

/// Make [`Self::Surface`] on the calling thread producing the
/// [`Self::PossiblyCurrentContext`] indicating that the context could
/// be current on the thread.
/// Make context current on the calling thread and change its type to
/// [`Self::PossiblyCurrentContext`]. The `surface` is used as a target for
/// the default framebuffer.
///
/// # Platform specific
///
Expand All @@ -64,17 +64,26 @@ pub trait NotCurrentGlContext: Sealed {
surface: &Self::Surface<T>,
) -> Result<Self::PossiblyCurrentContext>;

/// The same as [`Self::make_current`], but provides a way to set read and
/// draw surfaces.
/// The same as [`Self::make_current`], but provides a way to set draw and
/// read surfaces.
///
/// # Api-specific:
/// # Api specific
///
/// - **WGL/CGL:** not supported.
fn make_current_draw_read<T: SurfaceTypeTrait>(
self,
surface_draw: &Self::Surface<T>,
surface_read: &Self::Surface<T>,
) -> Result<Self::PossiblyCurrentContext>;

/// Make context current on the calling thread without a default
/// framebuffer and change its type to [`Self::PossiblyCurrentContext`].
///
/// # Api specific
///
/// - **WGL/GLX:** requires OpenGL 3.0 or greater context and
/// `ARB_create_context` extensions.
fn make_current_surfaceless(self) -> Result<Self::PossiblyCurrentContext>;
}

/// A trait to group common context operations.
Expand All @@ -88,38 +97,47 @@ pub trait PossiblyCurrentGlContext: Sealed {
/// Returns `true` if this context is the current one in this thread.
fn is_current(&self) -> bool;

/// Make the context not current to the current thread and returns a
/// [`Self::NotCurrentContext`] to indicate that the context is a not
/// current to allow sending it to the different thread.
/// Make the context not current on the calling thread and change its type
/// to [`Self::NotCurrentContext`].
///
/// # Platform specific
///
/// - **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
/// Make the context not current on the calling 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.
/// Make context current on the calling thread. The `surface` is used as a
/// target for the default framebuffer.
///
/// # Platform specific
///
/// - **macOS: this will block if your main thread is blocked.**
fn make_current<T: SurfaceTypeTrait>(&self, surface: &Self::Surface<T>) -> Result<()>;

/// The same as [`Self::make_current`] but provides a way to set read and
/// draw surfaces explicitly.
/// The same as [`Self::make_current`], but provides a way to set draw and
/// read surfaces explicitly.
///
/// # Api-specific:
/// # Api specific
///
/// - **CGL/WGL:** not supported.
fn make_current_draw_read<T: SurfaceTypeTrait>(
&self,
surface_draw: &Self::Surface<T>,
surface_read: &Self::Surface<T>,
) -> Result<()>;

/// Make context current on the calling thread without a default
/// framebuffer.
///
/// # Api specific
///
/// - **WGL/GLX:** requires OpenGL 3.0 or greater context and
/// `ARB_create_context` extensions.
fn make_current_surfaceless(&self) -> Result<()>;
}

/// A trait that provides raw context.
Expand Down Expand Up @@ -156,7 +174,7 @@ impl ContextAttributesBuilder {
/// To get sharing working it's recommended to use the same [`Config`] when
/// creating contexts that are going to be shared.
///
/// # Platform-specific
/// # Platform specific
///
/// - **Wayland:** both contexts must use the same Wayland connection.
///
Expand Down Expand Up @@ -190,7 +208,7 @@ impl ContextAttributesBuilder {
///
/// By default the profile is unspecified.
///
/// # Api-specific
/// # Api specific
///
/// - **macOS:** not supported, the latest is picked automatically.
pub fn with_profile(mut self, profile: GlProfile) -> Self {
Expand All @@ -210,7 +228,7 @@ impl ContextAttributesBuilder {
///
/// The `raw_window_handle` isn't required and here for WGL compatibility.
///
/// # Api-specific
/// # Api specific
///
/// - **WGL:** you **must** pass a `raw_window_handle` if you plan to use
/// this context with that window.
Expand Down Expand Up @@ -338,7 +356,7 @@ pub enum ReleaseBehavior {
/// Doesn't do anything. Most notably doesn't flush. Not supported by all
/// drivers.
///
/// # Api-specific
/// # Api specific
///
/// - **macOS:** not supported, [`Self::Flush`] is always used.
None,
Expand Down Expand Up @@ -391,6 +409,12 @@ impl NotCurrentGlContext for NotCurrentContext {
gl_api_dispatch!(self; Self(context) => context.treat_as_possibly_current(); as PossiblyCurrentContext)
}

fn make_current_surfaceless(self) -> Result<PossiblyCurrentContext> {
Ok(
gl_api_dispatch!(self; Self(context) => context.make_current_surfaceless()?; as PossiblyCurrentContext),
)
}

fn make_current<T: SurfaceTypeTrait>(
self,
surface: &Self::Surface<T>,
Expand Down Expand Up @@ -522,8 +546,12 @@ impl PossiblyCurrentGlContext for PossiblyCurrentContext {
)
}

fn make_current_surfaceless(&self) -> Result<()> {
gl_api_dispatch!(self; Self(context) => context.make_current_surfaceless())
}

fn make_not_current_in_place(&self) -> Result<()> {
Ok(gl_api_dispatch!(self; Self(context) => context.make_not_current_in_place()?))
gl_api_dispatch!(self; Self(context) => context.make_not_current_in_place())
}

fn make_current<T: SurfaceTypeTrait>(&self, surface: &Self::Surface<T>) -> Result<()> {
Expand Down

0 comments on commit d9a59b0

Please sign in to comment.