From bf4d5ba0155f906667c7c4a5138a95b504038fd5 Mon Sep 17 00:00:00 2001 From: Nova Date: Mon, 22 Aug 2022 03:59:28 -0400 Subject: [PATCH] feat: basic smithay setup --- Cargo.toml | 5 +++ src/main.rs | 63 +++++++++++++++++++++++++++++++++++- src/wayland/mod.rs | 79 ++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 146 insertions(+), 1 deletion(-) create mode 100644 src/wayland/mod.rs diff --git a/Cargo.toml b/Cargo.toml index 193b5fe..97226ca 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -24,6 +24,8 @@ tokio = { version = "1", features = ["full"] } thiserror = "1.0.31" send_wrapper = "0.6.0" prisma = "0.1.1" +slog = "2.7.0" +slog-stdlog = "4.1.1" [dependencies.libstardustxr] path = "../libstardustxr-rs" @@ -33,3 +35,6 @@ default-features = false path = "../stereokit-rs" default-features = false features = ["linux-egl"] + +[dependencies.smithay] +git = "https://github.com/Smithay/smithay.git" diff --git a/src/main.rs b/src/main.rs index 344c78b..9fdc1a1 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,14 +1,22 @@ mod core; mod nodes; +mod wayland; use crate::nodes::model::{MODELS_TO_DROP, MODEL_REGISTRY}; +use crate::wayland::{ClientState, WaylandState}; use self::core::eventloop::EventLoop; -use anyhow::Result; +use anyhow::{ensure, Result}; use clap::Parser; use once_cell::sync::Lazy; use parking_lot::Mutex; +use slog::Drain; +use smithay::backend::egl::EGLContext; +use smithay::backend::renderer::gles2::Gles2Renderer; +use smithay::reexports::wayland_server::{Display, ListeningSocket}; +use std::ffi::c_void; use std::sync::Arc; +use stereokit as sk; use stereokit::{lifecycle::DisplayMode, Settings}; use tokio::{runtime::Handle, sync::oneshot}; @@ -26,8 +34,31 @@ struct CliArgs { overlay: bool, } +struct EGLRawHandles { + display: *const c_void, + config: *const c_void, + context: *const c_void, +} +fn get_sk_egl() -> Result { + ensure!( + unsafe { sk::sys::backend_graphics_get() } + == sk::sys::backend_graphics__backend_graphics_opengles_egl, + "StereoKit is not running using EGL!" + ); + + Ok(unsafe { + EGLRawHandles { + display: sk::sys::backend_opengl_egl_get_display() as *const c_void, + config: sk::sys::backend_opengl_egl_get_config() as *const c_void, + context: sk::sys::backend_opengl_egl_get_context() as *const c_void, + } + }) +} + fn main() -> Result<()> { let cli_args = Arc::new(CliArgs::parse()); + let log = ::slog::Logger::root(::slog_stdlog::StdLog.fuse(), slog::o!()); + slog_stdlog::init()?; let stereokit = Settings::default() .app_name("Stardust XR") @@ -47,13 +78,43 @@ fn main() -> Result<()> { .name("event_loop".to_owned()) .spawn(move || event_loop(event_stop_rx))?; + let egl_raw_handles = get_sk_egl()?; + let renderer = unsafe { + Gles2Renderer::new( + EGLContext::from_raw( + egl_raw_handles.display, + egl_raw_handles.config, + egl_raw_handles.context, + log.clone(), + )?, + log.clone(), + )? + }; + + let mut display: Display = Display::new()?; + let socket = ListeningSocket::bind_auto("wayland", 0..33)?; + if let Some(socket_name) = socket.socket_name() { + println!("Wayland compositor {:?} active", socket_name); + } + let mut wayland_state = WaylandState::new(&display, renderer, log)?; + stereokit.run( |draw_ctx| { + if let Ok(Some(client)) = socket.accept() { + let _ = display + .handle() + .insert_client(client, Arc::new(ClientState)); + } + display.dispatch_clients(&mut wayland_state).unwrap(); + display.flush_clients().unwrap(); + nodes::root::Root::logic_step(stereokit.time_elapsed()); for model in MODEL_REGISTRY.get_valid_contents() { model.draw(&stereokit, draw_ctx); } MODELS_TO_DROP.lock().clear(); + + unsafe { wayland_state.renderer.egl_context().make_current().unwrap() }; }, || { println!("Cleanly shut down StereoKit"); diff --git a/src/wayland/mod.rs b/src/wayland/mod.rs new file mode 100644 index 0000000..b0df5d2 --- /dev/null +++ b/src/wayland/mod.rs @@ -0,0 +1,79 @@ +use anyhow::Result; +use slog::Logger; +use smithay::{ + backend::renderer::gles2::Gles2Renderer, + reexports::wayland_server::{ + backend::{ClientData, ClientId, DisconnectReason}, + Display, DisplayHandle, + }, +}; + +pub struct ClientState; +impl ClientData for ClientState { + fn initialized(&self, _client_id: ClientId) { + println!("initialized"); + } + + fn disconnected(&self, _client_id: ClientId, _reason: DisconnectReason) { + println!("disconnected"); + } +} + +pub struct WaylandState { + pub log: slog::Logger, + + pub display_handle: DisplayHandle, + pub renderer: Gles2Renderer, + // pub compositor_state: CompositorState, + // pub xdg_shell_state: XdgShellState, + // pub xdg_decoration_state: XdgDecorationState, + // pub shm_state: ShmState, + // pub output_manager_state: OutputManagerState, + // pub output: Output, + // pub seat_state: SeatState, + // pub data_device_state: DataDeviceState, +} + +impl WaylandState { + pub fn new( + display: &Display, + renderer: Gles2Renderer, + log: Logger, + ) -> Result { + let display_handle = display.handle(); + + // let compositor_state = CompositorState::new::(&display_handle, log.clone()); + // let xdg_shell_state = XdgShellState::new::(&display_handle, log.clone()); + // let xdg_decoration_state = XdgDecorationState::new::(&display_handle, log.clone()); + // let shm_state = ShmState::new::(&display_handle, vec![], log.clone()); + // let output_manager_state = OutputManagerState::new_with_xdg_output::(&display_handle); + // let output = Output::new( + // "1x".to_owned(), + // smithay::wayland::output::PhysicalProperties { + // size: Size::default(), + // subpixel: Subpixel::None, + // make: "Virtual XR Display".to_owned(), + // model: "Your Headset Name Here".to_owned(), + // }, + // log.clone(), + // ); + // let _global = output.create_global::(&display_handle); + // output.change_current_state(None, None, Some(Integer(2)), None); + // let seat_state = SeatState::new(); + // let data_device_state = DataDeviceState::new(&dh, log.clone()); + + Ok(WaylandState { + log, + display_handle, + renderer, + // compositor_state, + // xdg_shell_state, + // xdg_decoration_state, + // shm_state, + // output_manager_state, + // output, + // seat_state, + // data_device_state, + }) + } +}