Skip to content

Commit

Permalink
api/context: add ways to get/set context priority
Browse files Browse the repository at this point in the history
Add `GlContext::priority` and `ContextAttributesBuilder::with_priority`
to get and set context priority respectively.

Fixes rust-windowing#1694.
Fixes rust-windowing#1645.
  • Loading branch information
valaphee authored and kchibisov committed Nov 12, 2024
1 parent d5edc13 commit 7e95d85
Show file tree
Hide file tree
Showing 7 changed files with 125 additions and 9 deletions.
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
- 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 `GlContext::priority`/`ContextAttributesBuilder::with_priority` to get/set context priority.

# Version 0.32.1

Expand Down
8 changes: 8 additions & 0 deletions glutin/src/api/cgl/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,10 @@ impl GlContext for NotCurrentContext {
fn context_api(&self) -> ContextApi {
self.inner.context_api()
}

fn priority(&self) -> Priority {
Priority::Medium
}
}

impl GetGlConfig for NotCurrentContext {
Expand Down Expand Up @@ -195,6 +199,10 @@ impl GlContext for PossiblyCurrentContext {
fn context_api(&self) -> ContextApi {
self.inner.context_api()
}

fn priority(&self) -> Priority {
Priority::Medium
}
}

impl GetGlConfig for PossiblyCurrentContext {
Expand Down
42 changes: 41 additions & 1 deletion glutin/src/api/egl/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ use glutin_egl_sys::{egl, EGLContext};

use crate::config::{Api, GetGlConfig};
use crate::context::{
self, AsRawContext, ContextApi, ContextAttributes, GlProfile, RawContext, Robustness, Version,
self, AsRawContext, ContextApi, ContextAttributes, GlProfile, Priority, RawContext, Robustness,
Version,
};
use crate::display::{DisplayFeatures, GetGlDisplay};
use crate::error::{ErrorKind, Result};
Expand Down Expand Up @@ -126,6 +127,27 @@ impl Display {
}
}

if let Some(priority) = context_attributes
.priority
.filter(|_| self.inner.display_extensions.contains("EGL_IMG_context_priority"))
{
let priority = match priority {
Priority::Low => egl::CONTEXT_PRIORITY_LOW_IMG,
Priority::Medium => egl::CONTEXT_PRIORITY_MEDIUM_IMG,
Priority::High => egl::CONTEXT_PRIORITY_HIGH_IMG,
Priority::Realtime => {
if self.inner.display_extensions.contains("EGL_NV_context_priority_realtime") {
egl::CONTEXT_PRIORITY_REALTIME_NV
} else {
egl::CONTEXT_PRIORITY_HIGH_IMG
}
},
};

attrs.push(egl::CONTEXT_PRIORITY_LEVEL_IMG as EGLint);
attrs.push(priority as EGLint);
}

attrs.push(egl::NONE as EGLint);

let shared_context = if let Some(shared_context) =
Expand Down Expand Up @@ -214,6 +236,10 @@ impl GlContext for NotCurrentContext {
fn context_api(&self) -> ContextApi {
self.inner.context_api()
}

fn priority(&self) -> Priority {
self.inner.priority()
}
}

impl GetGlConfig for NotCurrentContext {
Expand Down Expand Up @@ -291,6 +317,10 @@ impl GlContext for PossiblyCurrentContext {
fn context_api(&self) -> ContextApi {
self.inner.context_api()
}

fn priority(&self) -> Priority {
self.inner.priority()
}
}

impl GetGlConfig for PossiblyCurrentContext {
Expand Down Expand Up @@ -385,6 +415,16 @@ impl ContextInner {
}
}

fn priority(&self) -> Priority {
match self.query_attribute(egl::CONTEXT_PRIORITY_LEVEL_IMG as EGLint).map(|a| a as EGLenum)
{
Some(egl::CONTEXT_PRIORITY_LOW_IMG) => Priority::Low,
Some(egl::CONTEXT_PRIORITY_HIGH_IMG) => Priority::High,
Some(egl::CONTEXT_PRIORITY_REALTIME_NV) => Priority::Realtime,
_ => Priority::Medium,
}
}

/// Query the context attribute.
fn query_attribute(&self, attribute: EGLint) -> Option<EGLint> {
unsafe {
Expand Down
12 changes: 10 additions & 2 deletions glutin/src/api/glx/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ use glutin_glx_sys::{glx, glx_extra};

use crate::config::GetGlConfig;
use crate::context::{
self, AsRawContext, ContextApi, ContextAttributes, GlProfile, RawContext, ReleaseBehavior,
Robustness, Version,
self, AsRawContext, ContextApi, ContextAttributes, GlProfile, Priority, RawContext,
ReleaseBehavior, Robustness, Version,
};
use crate::display::{DisplayFeatures, GetGlDisplay};
use crate::error::{ErrorKind, Result};
Expand Down Expand Up @@ -285,6 +285,10 @@ impl GlContext for NotCurrentContext {
fn context_api(&self) -> ContextApi {
self.inner.context_api()
}

fn priority(&self) -> Priority {
Priority::Medium
}
}

impl GetGlConfig for NotCurrentContext {
Expand Down Expand Up @@ -362,6 +366,10 @@ impl GlContext for PossiblyCurrentContext {
fn context_api(&self) -> ContextApi {
self.inner.context_api()
}

fn priority(&self) -> Priority {
Priority::Medium
}
}

impl GetGlConfig for PossiblyCurrentContext {
Expand Down
8 changes: 8 additions & 0 deletions glutin/src/api/wgl/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -272,6 +272,10 @@ impl GlContext for NotCurrentContext {
fn context_api(&self) -> ContextApi {
self.inner.context_api()
}

fn priority(&self) -> Priority {
Priority::Medium
}
}

impl GetGlDisplay for NotCurrentContext {
Expand Down Expand Up @@ -373,6 +377,10 @@ impl GlContext for PossiblyCurrentContext {
fn context_api(&self) -> ContextApi {
self.inner.context_api()
}

fn priority(&self) -> Priority {
Priority::Medium
}
}

impl AsRawContext for PossiblyCurrentContext {
Expand Down
60 changes: 55 additions & 5 deletions glutin/src/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,9 @@ pub trait GlContext: Sealed {
///
/// The returned value's [`Version`] will always be `None`.
fn context_api(&self) -> ContextApi;

/// Get the [`Priority`] used by the context.
fn priority(&self) -> Priority;
}

/// A trait to group common not current operations.
Expand Down Expand Up @@ -67,7 +70,7 @@ pub trait NotCurrentGlContext: Sealed {
/// The same as [`Self::make_current`], but provides a way to set read and
/// draw surfaces.
///
/// # Api-specific:
/// # Api specific
///
/// - **WGL/CGL:** not supported.
fn make_current_draw_read<T: SurfaceTypeTrait>(
Expand Down Expand Up @@ -112,7 +115,7 @@ pub trait PossiblyCurrentGlContext: Sealed {
/// The same as [`Self::make_current`] but provides a way to set read and
/// draw surfaces explicitly.
///
/// # Api-specific:
/// # Api specific
///
/// - **CGL/WGL:** not supported.
fn make_current_draw_read<T: SurfaceTypeTrait>(
Expand Down Expand Up @@ -190,7 +193,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 @@ -206,11 +209,29 @@ impl ContextAttributesBuilder {
self
}

/// Set the priority hint, which might not be honored if the API does not
/// support it, if there are constraints on the number of high priority
/// contexts available in the system, or system policy limits access to
/// high priority contexts to appropriate system privilege level the
/// context creation may fail.
///
/// By default no priority is specified, which corresponds to
/// [`Priority::Medium`].
///
/// # Api specific
///
/// - **WGL/GLX:** not implemented.
/// - **CGL:** not supported.
pub fn with_priority(mut self, priority: Priority) -> Self {
self.attributes.priority = Some(priority);
self
}

/// Build the context attributes.
///
/// 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 All @@ -233,6 +254,8 @@ pub struct ContextAttributes {

pub(crate) api: Option<ContextApi>,

pub(crate) priority: Option<Priority>,

pub(crate) shared_context: Option<RawContext>,

pub(crate) raw_window_handle: Option<RawWindowHandle>,
Expand Down Expand Up @@ -338,7 +361,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 @@ -447,6 +470,10 @@ impl GlContext for NotCurrentContext {
fn context_api(&self) -> ContextApi {
gl_api_dispatch!(self; Self(context) => context.context_api())
}

fn priority(&self) -> Priority {
gl_api_dispatch!(self; Self(context) => context.priority())
}
}

impl GetGlConfig for NotCurrentContext {
Expand Down Expand Up @@ -571,6 +598,10 @@ impl GlContext for PossiblyCurrentContext {
fn context_api(&self) -> ContextApi {
gl_api_dispatch!(self; Self(context) => context.context_api())
}

fn priority(&self) -> Priority {
gl_api_dispatch!(self; Self(context) => context.priority())
}
}

impl GetGlConfig for PossiblyCurrentContext {
Expand Down Expand Up @@ -617,6 +648,25 @@ pub enum RawContext {
Cgl(*const ffi::c_void),
}

/// Priority hint
#[derive(Debug, Copy, Clone, PartialEq, Eq, Default)]
pub enum Priority {
/// Lowest priority, contexts using this priority give way for most other
/// contexts.
Low,
/// Default priority.
#[default]
Medium,
/// High priority is usually required for VR applications.
High,
/// Realtime priority contexts are executed immediately and preempt any
/// current context running.
///
/// When such context is not supported, [`Priority::High`] will be requested
/// instead.
Realtime,
}

/// Pick `GlProfile` and `Version` based on the provided params.
#[cfg(any(egl_backend, glx_backend, wgl_backend))]
pub(crate) fn pick_profile(
Expand Down
2 changes: 2 additions & 0 deletions glutin_egl_sys/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ fn main() {
"EGL_EXT_platform_wayland",
"EGL_EXT_platform_x11",
"EGL_EXT_swap_buffers_with_damage",
"EGL_IMG_context_priority",
"EGL_KHR_create_context",
"EGL_KHR_create_context_no_error",
"EGL_KHR_display_reference",
Expand All @@ -47,6 +48,7 @@ fn main() {
"EGL_KHR_swap_buffers_with_damage",
"EGL_KHR_wait_sync",
"EGL_MESA_platform_gbm",
"EGL_NV_context_priority_realtime",
]);

if target.contains("ios") {
Expand Down

0 comments on commit 7e95d85

Please sign in to comment.