From 9c8b8bd92f2e3679ec8f96b0cd0464c2deebc99a Mon Sep 17 00:00:00 2001 From: Simon Hausmann Date: Thu, 29 Jun 2023 19:32:48 +0200 Subject: [PATCH] egl: support ANGLE on Windows 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 | 2 ++ glutin/src/api/egl/display.rs | 18 +++++++++++++++++- glutin/src/display.rs | 5 +++++ glutin_egl_sys/src/lib.rs | 10 ++++++++++ 4 files changed, 34 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0eda9533f1..f99bdb925e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,7 @@ # Unreleased +- Added support for EGL on Windows using Angle. This assumes libEGL.dll/libGLESv2.dll present. + # Version 0.30.9 - Fixed lock on SwapBuffers with some GLX drivers. 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 a6eaee58fa..492e1e0223 100644 --- a/glutin/src/display.rs +++ b/glutin/src/display.rs @@ -417,6 +417,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};