feat: basic smithay setup
This commit is contained in:
@@ -24,6 +24,8 @@ tokio = { version = "1", features = ["full"] }
|
|||||||
thiserror = "1.0.31"
|
thiserror = "1.0.31"
|
||||||
send_wrapper = "0.6.0"
|
send_wrapper = "0.6.0"
|
||||||
prisma = "0.1.1"
|
prisma = "0.1.1"
|
||||||
|
slog = "2.7.0"
|
||||||
|
slog-stdlog = "4.1.1"
|
||||||
|
|
||||||
[dependencies.libstardustxr]
|
[dependencies.libstardustxr]
|
||||||
path = "../libstardustxr-rs"
|
path = "../libstardustxr-rs"
|
||||||
@@ -33,3 +35,6 @@ default-features = false
|
|||||||
path = "../stereokit-rs"
|
path = "../stereokit-rs"
|
||||||
default-features = false
|
default-features = false
|
||||||
features = ["linux-egl"]
|
features = ["linux-egl"]
|
||||||
|
|
||||||
|
[dependencies.smithay]
|
||||||
|
git = "https://github.com/Smithay/smithay.git"
|
||||||
|
|||||||
63
src/main.rs
63
src/main.rs
@@ -1,14 +1,22 @@
|
|||||||
mod core;
|
mod core;
|
||||||
mod nodes;
|
mod nodes;
|
||||||
|
mod wayland;
|
||||||
|
|
||||||
use crate::nodes::model::{MODELS_TO_DROP, MODEL_REGISTRY};
|
use crate::nodes::model::{MODELS_TO_DROP, MODEL_REGISTRY};
|
||||||
|
use crate::wayland::{ClientState, WaylandState};
|
||||||
|
|
||||||
use self::core::eventloop::EventLoop;
|
use self::core::eventloop::EventLoop;
|
||||||
use anyhow::Result;
|
use anyhow::{ensure, Result};
|
||||||
use clap::Parser;
|
use clap::Parser;
|
||||||
use once_cell::sync::Lazy;
|
use once_cell::sync::Lazy;
|
||||||
use parking_lot::Mutex;
|
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 std::sync::Arc;
|
||||||
|
use stereokit as sk;
|
||||||
use stereokit::{lifecycle::DisplayMode, Settings};
|
use stereokit::{lifecycle::DisplayMode, Settings};
|
||||||
use tokio::{runtime::Handle, sync::oneshot};
|
use tokio::{runtime::Handle, sync::oneshot};
|
||||||
|
|
||||||
@@ -26,8 +34,31 @@ struct CliArgs {
|
|||||||
overlay: bool,
|
overlay: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct EGLRawHandles {
|
||||||
|
display: *const c_void,
|
||||||
|
config: *const c_void,
|
||||||
|
context: *const c_void,
|
||||||
|
}
|
||||||
|
fn get_sk_egl() -> Result<EGLRawHandles> {
|
||||||
|
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<()> {
|
fn main() -> Result<()> {
|
||||||
let cli_args = Arc::new(CliArgs::parse());
|
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()
|
let stereokit = Settings::default()
|
||||||
.app_name("Stardust XR")
|
.app_name("Stardust XR")
|
||||||
@@ -47,13 +78,43 @@ fn main() -> Result<()> {
|
|||||||
.name("event_loop".to_owned())
|
.name("event_loop".to_owned())
|
||||||
.spawn(move || event_loop(event_stop_rx))?;
|
.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<WaylandState> = 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(
|
stereokit.run(
|
||||||
|draw_ctx| {
|
|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());
|
nodes::root::Root::logic_step(stereokit.time_elapsed());
|
||||||
for model in MODEL_REGISTRY.get_valid_contents() {
|
for model in MODEL_REGISTRY.get_valid_contents() {
|
||||||
model.draw(&stereokit, draw_ctx);
|
model.draw(&stereokit, draw_ctx);
|
||||||
}
|
}
|
||||||
MODELS_TO_DROP.lock().clear();
|
MODELS_TO_DROP.lock().clear();
|
||||||
|
|
||||||
|
unsafe { wayland_state.renderer.egl_context().make_current().unwrap() };
|
||||||
},
|
},
|
||||||
|| {
|
|| {
|
||||||
println!("Cleanly shut down StereoKit");
|
println!("Cleanly shut down StereoKit");
|
||||||
|
|||||||
79
src/wayland/mod.rs
Normal file
79
src/wayland/mod.rs
Normal file
@@ -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<WaylandState>,
|
||||||
|
// pub data_device_state: DataDeviceState,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl WaylandState {
|
||||||
|
pub fn new(
|
||||||
|
display: &Display<WaylandState>,
|
||||||
|
renderer: Gles2Renderer,
|
||||||
|
log: Logger,
|
||||||
|
) -> Result<Self> {
|
||||||
|
let display_handle = display.handle();
|
||||||
|
|
||||||
|
// let compositor_state = CompositorState::new::<Self, _>(&display_handle, log.clone());
|
||||||
|
// let xdg_shell_state = XdgShellState::new::<Self, _>(&display_handle, log.clone());
|
||||||
|
// let xdg_decoration_state = XdgDecorationState::new::<Self, _>(&display_handle, log.clone());
|
||||||
|
// let shm_state = ShmState::new::<Self, _>(&display_handle, vec![], log.clone());
|
||||||
|
// let output_manager_state = OutputManagerState::new_with_xdg_output::<Self>(&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::<Self>(&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,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user