WayVR: Use eglGetPlatformDisplayEXT if available, cargo clippy warning fixes (#205)

This commit is contained in:
Aleksander
2025-05-01 20:08:07 +02:00
committed by GitHub
parent fbb16eccf6
commit 7a68c3eec0
6 changed files with 125 additions and 84 deletions

View File

@@ -49,8 +49,8 @@ impl dbus::message::SignalArgs for OrgFreedesktopDBusPropertiesPropertiesChanged
const INTERFACE: &'static str = "org.freedesktop.DBus.Properties"; const INTERFACE: &'static str = "org.freedesktop.DBus.Properties";
} }
impl<'a, T: blocking::BlockingSender, C: ::std::ops::Deref<Target = T>> OrgFreedesktopDBusProperties impl<T: blocking::BlockingSender, C: ::std::ops::Deref<Target = T>> OrgFreedesktopDBusProperties
for blocking::Proxy<'a, C> for blocking::Proxy<'_, C>
{ {
fn get<R0: for<'b> arg::Get<'b> + 'static>( fn get<R0: for<'b> arg::Get<'b> + 'static>(
&self, &self,
@@ -92,8 +92,8 @@ pub trait OrgFreedesktopDBusIntrospectable {
fn introspect(&self) -> Result<String, dbus::Error>; fn introspect(&self) -> Result<String, dbus::Error>;
} }
impl<'a, T: blocking::BlockingSender, C: ::std::ops::Deref<Target = T>> impl<T: blocking::BlockingSender, C: ::std::ops::Deref<Target = T>> OrgFreedesktopDBusIntrospectable
OrgFreedesktopDBusIntrospectable for blocking::Proxy<'a, C> for blocking::Proxy<'_, C>
{ {
fn introspect(&self) -> Result<String, dbus::Error> { fn introspect(&self) -> Result<String, dbus::Error> {
self.method_call("org.freedesktop.DBus.Introspectable", "Introspect", ()) self.method_call("org.freedesktop.DBus.Introspectable", "Introspect", ())
@@ -106,8 +106,8 @@ pub trait OrgFreedesktopDBusPeer {
fn get_machine_id(&self) -> Result<String, dbus::Error>; fn get_machine_id(&self) -> Result<String, dbus::Error>;
} }
impl<'a, T: blocking::BlockingSender, C: ::std::ops::Deref<Target = T>> OrgFreedesktopDBusPeer impl<T: blocking::BlockingSender, C: ::std::ops::Deref<Target = T>> OrgFreedesktopDBusPeer
for blocking::Proxy<'a, C> for blocking::Proxy<'_, C>
{ {
fn ping(&self) -> Result<(), dbus::Error> { fn ping(&self) -> Result<(), dbus::Error> {
self.method_call("org.freedesktop.DBus.Peer", "Ping", ()) 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"; const INTERFACE: &'static str = "org.freedesktop.Notifications";
} }
impl<'a, T: blocking::BlockingSender, C: ::std::ops::Deref<Target = T>> OrgFreedesktopNotifications impl<T: blocking::BlockingSender, C: ::std::ops::Deref<Target = T>> OrgFreedesktopNotifications
for blocking::Proxy<'a, C> for blocking::Proxy<'_, C>
{ {
fn set_noti_window_visibility(&self, value: bool) -> Result<(), dbus::Error> { fn set_noti_window_visibility(&self, value: bool) -> Result<(), dbus::Error> {
self.method_call( self.method_call(

View File

@@ -1,5 +1,10 @@
use std::sync::Arc; use std::sync::Arc;
use crate::backend::wayvr::egl_ex::{
PFNEGLGETPLATFORMDISPLAYEXTPROC, PFNEGLQUERYDMABUFFORMATSEXTPROC,
PFNEGLQUERYDMABUFMODIFIERSEXTPROC,
};
use super::egl_ex; use super::egl_ex;
use anyhow::anyhow; use anyhow::anyhow;
@@ -45,84 +50,105 @@ pub enum RenderData {
Software(Option<RenderSoftwarePixelsData>), // will be set if the next image data is available Software(Option<RenderSoftwarePixelsData>), // will be set if the next image data is available
} }
impl EGLData { fn load_egl_func(
pub fn load_func(&self, func_name: &str) -> anyhow::Result<extern "system" fn()> { egl: &khronos_egl::Instance<khronos_egl::Static>,
let raw_fn = self func_name: &str,
.egl ) -> anyhow::Result<extern "system" fn()> {
.get_proc_address(func_name) let raw_fn = egl
.ok_or_else(|| anyhow::anyhow!("Required EGL function {} not found", func_name))?; .get_proc_address(func_name)
Ok(raw_fn) .ok_or_else(|| anyhow::anyhow!("Required EGL function {} not found", func_name))?;
} Ok(raw_fn)
}
pub fn new() -> anyhow::Result<Self> { fn get_disp(
unsafe { egl: &khronos_egl::Instance<khronos_egl::Static>,
let egl = khronos_egl::Instance::new(khronos_egl::Static); ) -> anyhow::Result<khronos_egl::Display> {
unsafe {
if let Ok(func) = load_egl_func(egl, "eglGetPlatformDisplayEXT") {
let egl_get_platform_display_ext =
bind_egl_function!(PFNEGLGETPLATFORMDISPLAYEXTPROC, &func);
let display = egl let display_ext = egl_get_platform_display_ext(
.get_display(khronos_egl::DEFAULT_DISPLAY) egl_ex::EGL_PLATFORM_WAYLAND_EXT, // platform
.ok_or_else(|| anyhow!( std::ptr::null_mut(), // void *native_display
"eglGetDisplay failed. This shouldn't happen unless you don't have any display manager running. Cannot continue, check your EGL installation." std::ptr::null_mut(), // EGLint *attrib_list
))?; );
let (major, minor) = egl.initialize(display)?; if display_ext.is_null() {
log::debug!("EGL version: {major}.{minor}"); log::warn!("eglGetPlatformDisplayEXT failed, using eglGetDisplay instead");
} else {
let attrib_list = [ return Ok(khronos_egl::Display::from_ptr(display_ext));
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,
})
} }
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<Self> {
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<DMAbufModifierInfo> { fn query_dmabuf_mod_info(&self) -> anyhow::Result<DMAbufModifierInfo> {
let target_fourcc = 0x3432_4258; //XB24 let target_fourcc = 0x3432_4258; //XB24
unsafe { unsafe {
use egl_ex::PFNEGLQUERYDMABUFFORMATSEXTPROC;
use egl_ex::PFNEGLQUERYDMABUFMODIFIERSEXTPROC;
let egl_query_dmabuf_formats_ext = bind_egl_function!( let egl_query_dmabuf_formats_ext = bind_egl_function!(
PFNEGLQUERYDMABUFFORMATSEXTPROC, PFNEGLQUERYDMABUFFORMATSEXTPROC,
&self.load_func("eglQueryDmaBufFormatsEXT")? &load_egl_func(&self.egl, "eglQueryDmaBufFormatsEXT")?
); );
// Query format count // Query format count
@@ -158,7 +184,7 @@ impl EGLData {
let egl_query_dmabuf_modifiers_ext = bind_egl_function!( let egl_query_dmabuf_modifiers_ext = bind_egl_function!(
PFNEGLQUERYDMABUFMODIFIERSEXTPROC, PFNEGLQUERYDMABUFMODIFIERSEXTPROC,
&self.load_func("eglQueryDmaBufModifiersEXT")? &load_egl_func(&self.egl, "eglQueryDmaBufModifiersEXT")?
); );
let mut num_mods: khronos_egl::Int = 0; let mut num_mods: khronos_egl::Int = 0;
@@ -229,7 +255,7 @@ impl EGLData {
use egl_ex::PFNEGLEXPORTDMABUFIMAGEMESAPROC as FUNC; use egl_ex::PFNEGLEXPORTDMABUFIMAGEMESAPROC as FUNC;
unsafe { unsafe {
let egl_export_dmabuf_image_mesa = 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 fds: [i32; 3] = [0; 3];
let mut strides: [i32; 3] = [0; 3]; let mut strides: [i32; 3] = [0; 3];

View File

@@ -1,6 +1,19 @@
#![allow(clippy::all)] #![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< pub type PFNEGLEXPORTDMABUFIMAGEMESAPROC = Option<
unsafe extern "C" fn( unsafe extern "C" fn(
dpy: khronos_egl::EGLDisplay, dpy: khronos_egl::EGLDisplay,
@@ -11,7 +24,8 @@ pub type PFNEGLEXPORTDMABUFIMAGEMESAPROC = Option<
) -> khronos_egl::Boolean, ) -> khronos_egl::Boolean,
>; >;
//eglQueryDmaBufModifiersEXT // eglQueryDmaBufModifiersEXT
// https://registry.khronos.org/EGL/extensions/EXT/EGL_EXT_image_dma_buf_import_modifiers.txt
pub type PFNEGLQUERYDMABUFMODIFIERSEXTPROC = Option< pub type PFNEGLQUERYDMABUFMODIFIERSEXTPROC = Option<
unsafe extern "C" fn( unsafe extern "C" fn(
dpy: khronos_egl::EGLDisplay, dpy: khronos_egl::EGLDisplay,
@@ -23,7 +37,8 @@ pub type PFNEGLQUERYDMABUFMODIFIERSEXTPROC = Option<
) -> khronos_egl::Boolean, ) -> khronos_egl::Boolean,
>; >;
//eglQueryDmaBufFormatsEXT // eglQueryDmaBufFormatsEXT
// https://registry.khronos.org/EGL/extensions/EXT/EGL_EXT_image_dma_buf_import_modifiers.txt
pub type PFNEGLQUERYDMABUFFORMATSEXTPROC = Option< pub type PFNEGLQUERYDMABUFFORMATSEXTPROC = Option<
unsafe extern "C" fn( unsafe extern "C" fn(
dpy: khronos_egl::EGLDisplay, dpy: khronos_egl::EGLDisplay,

View File

@@ -10,7 +10,7 @@ pub fn get_egl_context(
display: &smithay_egl::EGLDisplay, display: &smithay_egl::EGLDisplay,
) -> anyhow::Result<smithay_egl::EGLContext> { ) -> anyhow::Result<smithay_egl::EGLContext> {
let display_ptr = display.get_display_handle().handle; 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 config_ptr = data.config.as_ptr();
let context_ptr = data.context.as_ptr(); let context_ptr = data.context.as_ptr();
Ok(unsafe { smithay_egl::EGLContext::from_raw(display_ptr, config_ptr, context_ptr)? }) Ok(unsafe { smithay_egl::EGLContext::from_raw(display_ptr, config_ptr, context_ptr)? })

View File

@@ -236,10 +236,10 @@ impl WayVRConfig {
pub fn load_wayvr() -> WayVRConfig { pub fn load_wayvr() -> WayVRConfig {
let config_root_path = config_io::ConfigRoot::WayVR.ensure_dir(); 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!( log::info!(
"WayVR conf.d path: {:?}", "WayVR conf.d path: {}",
config_io::ConfigRoot::WayVR.get_conf_d_path() config_io::ConfigRoot::WayVR.get_conf_d_path().display()
); );
load_config_with_conf_d::<WayVRConfig>("wayvr.yaml", config_io::ConfigRoot::WayVR) load_config_with_conf_d::<WayVRConfig>("wayvr.yaml", config_io::ConfigRoot::WayVR)

View File

@@ -195,7 +195,7 @@ pub struct AppSession {
impl AppSession { impl AppSession {
pub fn load() -> Self { pub fn load() -> Self {
let config_root_path = config_io::ConfigRoot::Generic.ensure_dir(); 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 config = GeneralConfig::load_from_disk();
let mut toast_topics = IdMap::new(); let mut toast_topics = IdMap::new();