feat: basic smithay setup
This commit is contained in:
@@ -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"
|
||||
|
||||
63
src/main.rs
63
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<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<()> {
|
||||
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<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(
|
||||
|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");
|
||||
|
||||
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