From 656ab7fd8e83c52137fe2a8ae7f6793e6d93b802 Mon Sep 17 00:00:00 2001 From: valaphee <32491319+valaphee@users.noreply.github.com> Date: Sun, 15 Sep 2024 12:43:27 +0200 Subject: [PATCH] Implement priority hints for EGL --- glutin/src/api/egl/context.rs | 21 ++++++++++++++++++++- glutin/src/context.rs | 31 +++++++++++++++++++++++++++++++ glutin_egl_sys/build.rs | 2 ++ 3 files changed, 53 insertions(+), 1 deletion(-) diff --git a/glutin/src/api/egl/context.rs b/glutin/src/api/egl/context.rs index 7647e43347..0a48d8a815 100644 --- a/glutin/src/api/egl/context.rs +++ b/glutin/src/api/egl/context.rs @@ -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}; @@ -54,6 +55,24 @@ impl Display { }, }; + if context_attributes.priority != Priority::Medium + && self.inner.display_extensions.contains("EGL_IMG_context_priority") + { + attrs.push(egl::CONTEXT_PRIORITY_LEVEL_IMG as EGLint); + attrs.push(match context_attributes.priority { + Priority::Low => egl::CONTEXT_PRIORITY_LOW_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 + } + }, + _ => unreachable!(), + } as EGLint); + } + let is_one_five = self.inner.version >= Version::new(1, 5); if is_one_five || self.inner.display_extensions.contains("EGL_KHR_create_context") { let mut flags = 0; diff --git a/glutin/src/context.rs b/glutin/src/context.rs index 7d14582fef..1179c897b7 100644 --- a/glutin/src/context.rs +++ b/glutin/src/context.rs @@ -201,6 +201,19 @@ impl ContextAttributesBuilder { self } + /// Sets 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 + /// + /// # Api-specific + /// + /// - Only EGL at the moment implements context priorities. + pub fn with_priority(mut self, priority: Priority) -> Self { + self.attributes.priority = priority; + self + } + /// Build the context attributes. /// /// The `raw_window_handle` isn't required and here for WGL compatibility. @@ -228,6 +241,8 @@ pub struct ContextAttributes { pub(crate) api: Option, + pub(crate) priority: Priority, + pub(crate) shared_context: Option, pub(crate) raw_window_handle: Option, @@ -608,6 +623,22 @@ 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. But will fallback to high if not supported. + Realtime, +} + /// Pick `GlProfile` and `Version` based on the provided params. #[cfg(any(egl_backend, glx_backend, wgl_backend))] pub(crate) fn pick_profile( diff --git a/glutin_egl_sys/build.rs b/glutin_egl_sys/build.rs index c8dbedf87a..3915585143 100644 --- a/glutin_egl_sys/build.rs +++ b/glutin_egl_sys/build.rs @@ -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", @@ -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") {