feat: basic smithay setup

This commit is contained in:
Nova
2022-08-22 03:59:28 -04:00
parent fb14d1c0e6
commit bf4d5ba015
3 changed files with 146 additions and 1 deletions

View File

@@ -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"

View File

@@ -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
View 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,
})
}
}