Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

api: unify surfaceless APIs on context #1715

Merged
merged 4 commits into from
Nov 13, 2024
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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())
kchibisov marked this conversation as resolved.
Show resolved Hide resolved
}

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 to the current thread and change its type
kchibisov marked this conversation as resolved.
Show resolved Hide resolved
/// 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
Loading