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 #1694.
Fixes #1645.

Co-authored-by: Kirill Chibisov <[email protected]>
  • Loading branch information
valaphee and kchibisov authored Nov 13, 2024
1 parent d9a59b0 commit 2c09d89
Show file tree
Hide file tree
Showing 7 changed files with 136 additions and 6 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
- Added `PossiblyCurrentContext::make_not_current_in_place(&self)` for when `Send` capability of `NotCurrentContext` is not required.
- 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`.
- Added `GlContext::priority`/`ContextAttributesBuilder::with_priority` to get/set context priority.

# Version 0.32.1

Expand Down
12 changes: 11 additions & 1 deletion glutin/src/api/cgl/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@ use objc2_app_kit::{NSOpenGLCPSwapInterval, NSView};
use objc2_foundation::{run_on_main, MainThreadBound};

use crate::config::GetGlConfig;
use crate::context::{AsRawContext, ContextApi, ContextAttributes, RawContext, Robustness};
use crate::context::{
AsRawContext, ContextApi, ContextAttributes, Priority, RawContext, Robustness,
};
use crate::display::GetGlDisplay;
use crate::error::{ErrorKind, Result};
use crate::prelude::*;
Expand Down Expand Up @@ -113,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 @@ -190,6 +196,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
53 changes: 52 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,38 @@ impl Display {
}
}

if let Some(priority) = context_attributes.priority.filter(|_| {
let extensions = &self.inner.display_extensions;

// Some android versions don't report support for this extension, even though
// it's supported.
//
// https://github.com/googlevr/gvr-android-sdk/issues/330
#[cfg(android_platform)]
let android = extensions.contains("EGL_ANDROID_front_buffer_auto_refresh")
&& extensions.contains("EGL_ANDROID_create_native_client_buffer");
#[cfg(not(android_platform))]
let android = false;

extensions.contains("EGL_IMG_context_priority") || android
}) {
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 @@ -212,6 +245,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 @@ -286,6 +323,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 @@ -380,6 +421,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 @@ -281,6 +281,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 @@ -353,6 +357,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
12 changes: 10 additions & 2 deletions glutin/src/api/wgl/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ use windows_sys::Win32::Graphics::Gdi::{self as gdi, HDC};

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 @@ -268,6 +268,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 @@ -364,6 +368,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
50 changes: 50 additions & 0 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 @@ -224,6 +227,24 @@ 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.
Expand Down Expand Up @@ -251,6 +272,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 @@ -471,6 +494,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 @@ -599,6 +626,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 @@ -645,6 +676,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 2c09d89

Please sign in to comment.