From 4ec2f4dd05e873aafbbc4b3e5a8496010ee50f57 Mon Sep 17 00:00:00 2001 From: Simon Hausmann Date: Thu, 29 Jun 2023 14:36:19 +0200 Subject: [PATCH] Add support for creating glutin EGL displays on Windows using Angle Angle provides libEGL.dll, which glutin loads. The only change necessary is to get the platform display via EGL_PLATFORM_ANGLE_ANGLE and treating it as a legacy display. Fixes #1508 --- CHANGELOG.md | 1 + glutin/src/api/egl/display.rs | 18 +++++++++++++++++- glutin/src/display.rs | 5 +++++ glutin_egl_sys/src/lib.rs | 10 ++++++++++ 4 files changed, 33 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 744db41aa0..7666fc6a1b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ - **Breaking:** `GlContext` trait is now a part of the `prelude`. - Fixed lock on SwapBuffers with some GLX drivers. - Fixed EGL's `Surface::is_single_buffered` being inversed. +- Added support for EGL on Windows using Angle. This assumes libEGL.dll/libGLESv2.dll present. # Version 0.30.8 diff --git a/glutin/src/api/egl/display.rs b/glutin/src/api/egl/display.rs index 376e51a1aa..518a34872c 100644 --- a/glutin/src/api/egl/display.rs +++ b/glutin/src/api/egl/display.rs @@ -241,6 +241,7 @@ impl Display { let extensions = NO_DISPLAY_EXTENSIONS.get().unwrap(); let mut attrs = Vec::::new(); + let mut legacy = false; let (platform, mut display) = match display { #[cfg(wayland_platform)] RawDisplayHandle::Wayland(handle) @@ -266,6 +267,11 @@ impl Display { RawDisplayHandle::Gbm(handle) if extensions.contains("EGL_MESA_platform_gbm") => { (egl::PLATFORM_GBM_MESA, handle.gbm_device) }, + RawDisplayHandle::Windows(..) if extensions.contains("EGL_ANGLE_platform_angle") => { + // Only CreateWindowSurface appears to work with Angle. + legacy = true; + (egl::PLATFORM_ANGLE_ANGLE, egl::DEFAULT_DISPLAY as *mut _) + }, _ => { return Err( ErrorKind::NotSupported("provided display handle is not supported").into() @@ -284,7 +290,17 @@ impl Display { let display = unsafe { egl.GetPlatformDisplayEXT(platform, display as *mut _, attrs.as_ptr()) }; - Self::check_display_error(display).map(EglDisplay::Ext) + Self::check_display_error(display).map(|display| { + if legacy { + // NOTE: For angle we use the Legacy code path, as that uses CreateWindowSurface + // instead of CreatePlatformWindowSurface*. The latter somehow + // doesn't work, only the former does. But Angle's own example also use the + // former: https://github.com/google/angle/blob/main/util/EGLWindow.cpp#L424 + EglDisplay::Legacy(display) + } else { + EglDisplay::Ext(display) + } + }) } fn get_display(egl: &Egl, display: RawDisplayHandle) -> Result { diff --git a/glutin/src/display.rs b/glutin/src/display.rs index c4a49bde93..25aa99888b 100644 --- a/glutin/src/display.rs +++ b/glutin/src/display.rs @@ -426,6 +426,11 @@ pub enum DisplayApiPreference { /// /// But despite this issues it should be preferred on at least Linux over /// GLX, given that GLX is phasing away. + /// + /// # Platform-specific + /// + /// **Windows:** ANGLE can be used if `libEGL.dll` and `libGLESv2.dll` are + /// in the library search path. #[cfg(egl_backend)] Egl, diff --git a/glutin_egl_sys/src/lib.rs b/glutin_egl_sys/src/lib.rs index f2c23d29e0..cb1dad8e9a 100644 --- a/glutin_egl_sys/src/lib.rs +++ b/glutin_egl_sys/src/lib.rs @@ -32,6 +32,16 @@ pub mod egl { pub const PLATFORM_XCB_SCREEN_EXT: super::EGLenum = 0x31DE; // EGL_EXT_device_query_name pub const RENDERER_EXT: super::EGLenum = 0x335F; + // EGL_ANGLE_platform_angle - https://chromium.googlesource.com/angle/angle/+/HEAD/extensions/EGL_ANGLE_platform_angle.txt + pub const PLATFORM_ANGLE_ANGLE: super::EGLenum = 0x3202; + pub const PLATFORM_ANGLE_TYPE_ANGLE: super::EGLenum = 0x3203; + pub const PLATFORM_ANGLE_MAX_VERSION_MAJOR_ANGLE: super::EGLenum = 0x3204; + pub const PLATFORM_ANGLE_MAX_VERSION_MINOR_ANGLE: super::EGLenum = 0x3205; + pub const PLATFORM_ANGLE_DEBUG_LAYERS_ENABLED: super::EGLenum = 0x3451; + pub const PLATFORM_ANGLE_NATIVE_PLATFORM_TYPE_ANGLE: super::EGLenum = 0x348F; + pub const PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE: super::EGLenum = 0x3206; + pub const PLATFORM_ANGLE_DEVICE_TYPE_HARDWARE_ANGLE: super::EGLenum = 0x320A; + pub const PLATFORM_ANGLE_DEVICE_TYPE_NULL_ANGLE: super::EGLenum = 0x345E; } pub use self::egl::types::{EGLContext, EGLDisplay};