From 7a68c3eec06fd0e71bd96cc7d55b137aa86077f8 Mon Sep 17 00:00:00 2001 From: Aleksander Date: Thu, 1 May 2025 20:08:07 +0200 Subject: [PATCH] WayVR: Use eglGetPlatformDisplayEXT if available, cargo clippy warning fixes (#205) --- src/backend/notifications_dbus.rs | 16 +-- src/backend/wayvr/egl_data.rs | 162 ++++++++++++++++----------- src/backend/wayvr/egl_ex.rs | 21 +++- src/backend/wayvr/smithay_wrapper.rs | 2 +- src/config_wayvr.rs | 6 +- src/state.rs | 2 +- 6 files changed, 125 insertions(+), 84 deletions(-) diff --git a/src/backend/notifications_dbus.rs b/src/backend/notifications_dbus.rs index acaabda..3d64285 100644 --- a/src/backend/notifications_dbus.rs +++ b/src/backend/notifications_dbus.rs @@ -49,8 +49,8 @@ impl dbus::message::SignalArgs for OrgFreedesktopDBusPropertiesPropertiesChanged const INTERFACE: &'static str = "org.freedesktop.DBus.Properties"; } -impl<'a, T: blocking::BlockingSender, C: ::std::ops::Deref> OrgFreedesktopDBusProperties - for blocking::Proxy<'a, C> +impl> OrgFreedesktopDBusProperties + for blocking::Proxy<'_, C> { fn get arg::Get<'b> + 'static>( &self, @@ -92,8 +92,8 @@ pub trait OrgFreedesktopDBusIntrospectable { fn introspect(&self) -> Result; } -impl<'a, T: blocking::BlockingSender, C: ::std::ops::Deref> - OrgFreedesktopDBusIntrospectable for blocking::Proxy<'a, C> +impl> OrgFreedesktopDBusIntrospectable + for blocking::Proxy<'_, C> { fn introspect(&self) -> Result { self.method_call("org.freedesktop.DBus.Introspectable", "Introspect", ()) @@ -106,8 +106,8 @@ pub trait OrgFreedesktopDBusPeer { fn get_machine_id(&self) -> Result; } -impl<'a, T: blocking::BlockingSender, C: ::std::ops::Deref> OrgFreedesktopDBusPeer - for blocking::Proxy<'a, C> +impl> OrgFreedesktopDBusPeer + for blocking::Proxy<'_, C> { fn ping(&self) -> Result<(), dbus::Error> { self.method_call("org.freedesktop.DBus.Peer", "Ping", ()) @@ -248,8 +248,8 @@ impl dbus::message::SignalArgs for OrgFreedesktopNotificationsNotificationReplie const INTERFACE: &'static str = "org.freedesktop.Notifications"; } -impl<'a, T: blocking::BlockingSender, C: ::std::ops::Deref> OrgFreedesktopNotifications - for blocking::Proxy<'a, C> +impl> OrgFreedesktopNotifications + for blocking::Proxy<'_, C> { fn set_noti_window_visibility(&self, value: bool) -> Result<(), dbus::Error> { self.method_call( diff --git a/src/backend/wayvr/egl_data.rs b/src/backend/wayvr/egl_data.rs index 771f16b..cf47514 100644 --- a/src/backend/wayvr/egl_data.rs +++ b/src/backend/wayvr/egl_data.rs @@ -1,5 +1,10 @@ use std::sync::Arc; +use crate::backend::wayvr::egl_ex::{ + PFNEGLGETPLATFORMDISPLAYEXTPROC, PFNEGLQUERYDMABUFFORMATSEXTPROC, + PFNEGLQUERYDMABUFMODIFIERSEXTPROC, +}; + use super::egl_ex; use anyhow::anyhow; @@ -45,84 +50,105 @@ pub enum RenderData { Software(Option), // will be set if the next image data is available } -impl EGLData { - pub fn load_func(&self, func_name: &str) -> anyhow::Result { - let raw_fn = self - .egl - .get_proc_address(func_name) - .ok_or_else(|| anyhow::anyhow!("Required EGL function {} not found", func_name))?; - Ok(raw_fn) - } +fn load_egl_func( + egl: &khronos_egl::Instance, + func_name: &str, +) -> anyhow::Result { + let raw_fn = egl + .get_proc_address(func_name) + .ok_or_else(|| anyhow::anyhow!("Required EGL function {} not found", func_name))?; + Ok(raw_fn) +} - pub fn new() -> anyhow::Result { - unsafe { - let egl = khronos_egl::Instance::new(khronos_egl::Static); +fn get_disp( + egl: &khronos_egl::Instance, +) -> anyhow::Result { + unsafe { + if let Ok(func) = load_egl_func(egl, "eglGetPlatformDisplayEXT") { + let egl_get_platform_display_ext = + bind_egl_function!(PFNEGLGETPLATFORMDISPLAYEXTPROC, &func); - let display = egl - .get_display(khronos_egl::DEFAULT_DISPLAY) - .ok_or_else(|| anyhow!( - "eglGetDisplay failed. This shouldn't happen unless you don't have any display manager running. Cannot continue, check your EGL installation." - ))?; + let display_ext = egl_get_platform_display_ext( + egl_ex::EGL_PLATFORM_WAYLAND_EXT, // platform + std::ptr::null_mut(), // void *native_display + std::ptr::null_mut(), // EGLint *attrib_list + ); - let (major, minor) = egl.initialize(display)?; - log::debug!("EGL version: {major}.{minor}"); - - let attrib_list = [ - khronos_egl::RED_SIZE, - 8, - khronos_egl::GREEN_SIZE, - 8, - khronos_egl::BLUE_SIZE, - 8, - khronos_egl::SURFACE_TYPE, - khronos_egl::WINDOW_BIT, - khronos_egl::RENDERABLE_TYPE, - khronos_egl::OPENGL_BIT, - khronos_egl::NONE, - ]; - - let config = egl - .choose_first_config(display, &attrib_list)? - .ok_or_else(|| anyhow!("Failed to get EGL config"))?; - - egl.bind_api(khronos_egl::OPENGL_ES_API)?; - - log::debug!("eglCreateContext"); - - // Require OpenGL ES 3.0 - let context_attrib_list = [ - khronos_egl::CONTEXT_MAJOR_VERSION, - 3, - khronos_egl::CONTEXT_MINOR_VERSION, - 0, - khronos_egl::NONE, - ]; - - let context = egl.create_context(display, config, None, &context_attrib_list)?; - - log::debug!("eglMakeCurrent"); - - egl.make_current(display, None, None, Some(context))?; - - Ok(Self { - egl, - display, - config, - context, - }) + if display_ext.is_null() { + log::warn!("eglGetPlatformDisplayEXT failed, using eglGetDisplay instead"); + } else { + return Ok(khronos_egl::Display::from_ptr(display_ext)); + } } + + egl + .get_display(khronos_egl::DEFAULT_DISPLAY) + .ok_or_else(|| anyhow!( + "Both eglGetPlatformDisplayEXT and eglGetDisplay failed. This shouldn't happen unless you don't have any display manager running. Cannot continue, check your EGL installation." + )) + } +} + +impl EGLData { + pub fn new() -> anyhow::Result { + let egl = khronos_egl::Instance::new(khronos_egl::Static); + let display = get_disp(&egl)?; + + let (major, minor) = egl.initialize(display)?; + log::debug!("EGL version: {major}.{minor}"); + + let attrib_list = [ + khronos_egl::RED_SIZE, + 8, + khronos_egl::GREEN_SIZE, + 8, + khronos_egl::BLUE_SIZE, + 8, + khronos_egl::SURFACE_TYPE, + khronos_egl::WINDOW_BIT, + khronos_egl::RENDERABLE_TYPE, + khronos_egl::OPENGL_BIT, + khronos_egl::NONE, + ]; + + let config = egl + .choose_first_config(display, &attrib_list)? + .ok_or_else(|| anyhow!("Failed to get EGL config"))?; + + egl.bind_api(khronos_egl::OPENGL_ES_API)?; + + log::debug!("eglCreateContext"); + + // Require OpenGL ES 3.0 + let context_attrib_list = [ + khronos_egl::CONTEXT_MAJOR_VERSION, + 3, + khronos_egl::CONTEXT_MINOR_VERSION, + 0, + khronos_egl::NONE, + ]; + + let context = egl.create_context(display, config, None, &context_attrib_list)?; + + log::debug!("eglMakeCurrent"); + + egl.make_current(display, None, None, Some(context))?; + + Ok(Self { + egl, + display, + config, + context, + }) } fn query_dmabuf_mod_info(&self) -> anyhow::Result { let target_fourcc = 0x3432_4258; //XB24 unsafe { - use egl_ex::PFNEGLQUERYDMABUFFORMATSEXTPROC; - use egl_ex::PFNEGLQUERYDMABUFMODIFIERSEXTPROC; - let egl_query_dmabuf_formats_ext = bind_egl_function!( PFNEGLQUERYDMABUFFORMATSEXTPROC, - &self.load_func("eglQueryDmaBufFormatsEXT")? + &load_egl_func(&self.egl, "eglQueryDmaBufFormatsEXT")? ); // Query format count @@ -158,7 +184,7 @@ impl EGLData { let egl_query_dmabuf_modifiers_ext = bind_egl_function!( PFNEGLQUERYDMABUFMODIFIERSEXTPROC, - &self.load_func("eglQueryDmaBufModifiersEXT")? + &load_egl_func(&self.egl, "eglQueryDmaBufModifiersEXT")? ); let mut num_mods: khronos_egl::Int = 0; @@ -229,7 +255,7 @@ impl EGLData { use egl_ex::PFNEGLEXPORTDMABUFIMAGEMESAPROC as FUNC; unsafe { let egl_export_dmabuf_image_mesa = - bind_egl_function!(FUNC, &self.load_func("eglExportDMABUFImageMESA")?); + bind_egl_function!(FUNC, &load_egl_func(&self.egl, "eglExportDMABUFImageMESA")?); let mut fds: [i32; 3] = [0; 3]; let mut strides: [i32; 3] = [0; 3]; diff --git a/src/backend/wayvr/egl_ex.rs b/src/backend/wayvr/egl_ex.rs index 032c8d2..bf26492 100644 --- a/src/backend/wayvr/egl_ex.rs +++ b/src/backend/wayvr/egl_ex.rs @@ -1,6 +1,19 @@ #![allow(clippy::all)] -//eglExportDMABUFImageMESA +pub const EGL_PLATFORM_WAYLAND_EXT: khronos_egl::Enum = 0x31D8; + +// eglGetPlatformDisplayEXT +// https://registry.khronos.org/EGL/extensions/EXT/EGL_EXT_platform_base.txt +pub type PFNEGLGETPLATFORMDISPLAYEXTPROC = Option< + unsafe extern "C" fn( + platform: khronos_egl::Enum, + native_display: *mut std::ffi::c_void, + attrib_list: *mut khronos_egl::Enum, + ) -> khronos_egl::EGLDisplay, +>; + +// eglExportDMABUFImageMESA +// https://registry.khronos.org/EGL/extensions/MESA/EGL_MESA_image_dma_buf_export.txt pub type PFNEGLEXPORTDMABUFIMAGEMESAPROC = Option< unsafe extern "C" fn( dpy: khronos_egl::EGLDisplay, @@ -11,7 +24,8 @@ pub type PFNEGLEXPORTDMABUFIMAGEMESAPROC = Option< ) -> khronos_egl::Boolean, >; -//eglQueryDmaBufModifiersEXT +// eglQueryDmaBufModifiersEXT +// https://registry.khronos.org/EGL/extensions/EXT/EGL_EXT_image_dma_buf_import_modifiers.txt pub type PFNEGLQUERYDMABUFMODIFIERSEXTPROC = Option< unsafe extern "C" fn( dpy: khronos_egl::EGLDisplay, @@ -23,7 +37,8 @@ pub type PFNEGLQUERYDMABUFMODIFIERSEXTPROC = Option< ) -> khronos_egl::Boolean, >; -//eglQueryDmaBufFormatsEXT +// eglQueryDmaBufFormatsEXT +// https://registry.khronos.org/EGL/extensions/EXT/EGL_EXT_image_dma_buf_import_modifiers.txt pub type PFNEGLQUERYDMABUFFORMATSEXTPROC = Option< unsafe extern "C" fn( dpy: khronos_egl::EGLDisplay, diff --git a/src/backend/wayvr/smithay_wrapper.rs b/src/backend/wayvr/smithay_wrapper.rs index e381976..2cafe8e 100644 --- a/src/backend/wayvr/smithay_wrapper.rs +++ b/src/backend/wayvr/smithay_wrapper.rs @@ -10,7 +10,7 @@ pub fn get_egl_context( display: &smithay_egl::EGLDisplay, ) -> anyhow::Result { let display_ptr = display.get_display_handle().handle; - debug_assert!(display_ptr == data.display.as_ptr()); + debug_assert!(std::ptr::eq(display_ptr, data.display.as_ptr())); let config_ptr = data.config.as_ptr(); let context_ptr = data.context.as_ptr(); Ok(unsafe { smithay_egl::EGLContext::from_raw(display_ptr, config_ptr, context_ptr)? }) diff --git a/src/config_wayvr.rs b/src/config_wayvr.rs index c1b1507..8af987d 100644 --- a/src/config_wayvr.rs +++ b/src/config_wayvr.rs @@ -236,10 +236,10 @@ impl WayVRConfig { pub fn load_wayvr() -> WayVRConfig { let config_root_path = config_io::ConfigRoot::WayVR.ensure_dir(); - log::info!("WayVR Config root path: {config_root_path:?}"); + log::info!("WayVR Config root path: {}", config_root_path.display()); log::info!( - "WayVR conf.d path: {:?}", - config_io::ConfigRoot::WayVR.get_conf_d_path() + "WayVR conf.d path: {}", + config_io::ConfigRoot::WayVR.get_conf_d_path().display() ); load_config_with_conf_d::("wayvr.yaml", config_io::ConfigRoot::WayVR) diff --git a/src/state.rs b/src/state.rs index 8a5f435..b593af2 100644 --- a/src/state.rs +++ b/src/state.rs @@ -195,7 +195,7 @@ pub struct AppSession { impl AppSession { pub fn load() -> Self { let config_root_path = config_io::ConfigRoot::Generic.ensure_dir(); - log::info!("Config root path: {config_root_path:?}"); + log::info!("Config root path: {}", config_root_path.display()); let config = GeneralConfig::load_from_disk(); let mut toast_topics = IdMap::new();