WayVR: Haptics support, fix warnings, EGL fix, display visibility IPC, bump dashboard resolution to 1080p
This commit is contained in:
2
Cargo.lock
generated
2
Cargo.lock
generated
@@ -4582,7 +4582,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "wayvr_ipc"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/olekolek1000/wayvr-ipc.git?rev=94ab6125ec07c091099bf71b028d701b58eccccf#94ab6125ec07c091099bf71b028d701b58eccccf"
|
||||
source = "git+https://github.com/olekolek1000/wayvr-ipc.git?rev=fe2e8be04c7b86adcf972be7ebe46961bd881f35#fe2e8be04c7b86adcf972be7ebe46961bd881f35"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"bytes",
|
||||
|
||||
@@ -86,7 +86,7 @@ wayland-client = { version = "0.31.6", optional = true }
|
||||
wayland-egl = { version = "0.32.4", optional = true }
|
||||
interprocess = { version = "2.2.2", optional = true }
|
||||
bytes = { version = "1.9.0", optional = true }
|
||||
wayvr_ipc = { git = "https://github.com/olekolek1000/wayvr-ipc.git", rev = "94ab6125ec07c091099bf71b028d701b58eccccf", default-features = false, optional = true }
|
||||
wayvr_ipc = { git = "https://github.com/olekolek1000/wayvr-ipc.git", rev = "fe2e8be04c7b86adcf972be7ebe46961bd881f35", default-features = false, optional = true }
|
||||
################################
|
||||
|
||||
[build-dependencies]
|
||||
|
||||
@@ -241,6 +241,7 @@ pub struct PointerHit {
|
||||
pub dist: f32,
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct Haptics {
|
||||
pub intensity: f32,
|
||||
pub duration: f32,
|
||||
|
||||
@@ -135,7 +135,7 @@ impl LinePool {
|
||||
&'a mut self,
|
||||
xr: &'a XrState,
|
||||
command_buffer: &mut WlxCommandBuffer,
|
||||
) -> anyhow::Result<Vec<CompositionLayer>> {
|
||||
) -> anyhow::Result<Vec<CompositionLayer<'a>>> {
|
||||
let mut quads = Vec::new();
|
||||
|
||||
for line in self.lines.values_mut() {
|
||||
|
||||
@@ -27,7 +27,7 @@ impl OverlayData<OpenXrOverlayData> {
|
||||
&'a mut self,
|
||||
xr: &'a XrState,
|
||||
command_buffer: &mut WlxCommandBuffer,
|
||||
) -> anyhow::Result<CompositionLayer> {
|
||||
) -> anyhow::Result<CompositionLayer<'a>> {
|
||||
if let Some(new_view) = self.view() {
|
||||
self.data.last_view = Some(new_view);
|
||||
}
|
||||
|
||||
@@ -74,7 +74,7 @@ impl Skybox {
|
||||
xr: &'a XrState,
|
||||
hmd: Affine3A,
|
||||
command_buffer: &mut WlxCommandBuffer,
|
||||
) -> anyhow::Result<Vec<CompositionLayer>> {
|
||||
) -> anyhow::Result<Vec<CompositionLayer<'a>>> {
|
||||
let (sky_image, grid_image) = if let Some((ref mut srd_sky, ref mut srd_grid)) = self.srd {
|
||||
(srd_sky.present_last()?, srd_grid.present_last()?)
|
||||
} else {
|
||||
|
||||
@@ -32,7 +32,8 @@ pub const Z_ORDER_TOAST: u32 = 70;
|
||||
pub const Z_ORDER_LINES: u32 = 69;
|
||||
pub const Z_ORDER_WATCH: u32 = 68;
|
||||
pub const Z_ORDER_ANCHOR: u32 = 67;
|
||||
pub const Z_ORDER_DASHBOARD: u32 = 66;
|
||||
pub const Z_ORDER_DEFAULT: u32 = 0;
|
||||
pub const Z_ORDER_DASHBOARD: u32 = Z_ORDER_DEFAULT;
|
||||
|
||||
pub struct OverlayState {
|
||||
pub id: OverlayID,
|
||||
@@ -73,7 +74,7 @@ impl Default for OverlayState {
|
||||
keyboard_focus: None,
|
||||
dirty: true,
|
||||
alpha: 1.0,
|
||||
z_order: 0,
|
||||
z_order: Z_ORDER_DEFAULT,
|
||||
relative_to: RelativeTo::None,
|
||||
curvature: None,
|
||||
spawn_scale: 1.0,
|
||||
|
||||
@@ -124,7 +124,7 @@ impl Display {
|
||||
)
|
||||
})?;
|
||||
|
||||
let egl_image = egl_data.create_egl_image(tex_id, width as u32, height as u32)?;
|
||||
let egl_image = egl_data.create_egl_image(tex_id)?;
|
||||
let dmabuf_data = egl_data.create_dmabuf_data(&egl_image)?;
|
||||
|
||||
let opaque = false;
|
||||
@@ -207,7 +207,8 @@ impl Display {
|
||||
} else if let Some(auto_hide_delay) = config.auto_hide_delay {
|
||||
if let Some(s) = self.no_windows_since {
|
||||
if s + (auto_hide_delay as u64) < get_millis() {
|
||||
signals.send(WayVRSignal::DisplayHideRequest(*handle));
|
||||
// Auto-hide after specific time
|
||||
signals.send(WayVRSignal::DisplayVisibility(*handle, false));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -45,7 +45,9 @@ impl EGLData {
|
||||
|
||||
let display = egl
|
||||
.get_display(khronos_egl::DEFAULT_DISPLAY)
|
||||
.ok_or(anyhow!("eglGetDisplay failed"))?;
|
||||
.ok_or(anyhow!(
|
||||
"eglGetDisplay failed. This shouldn't happen unless you don't have any display manager running. Cannot continue, check your EGL installation."
|
||||
))?;
|
||||
|
||||
let (major, minor) = egl.initialize(display)?;
|
||||
log::debug!("EGL version: {}.{}", major, minor);
|
||||
@@ -242,25 +244,14 @@ impl EGLData {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn create_egl_image(
|
||||
&self,
|
||||
gl_tex_id: u32,
|
||||
width: u32,
|
||||
height: u32,
|
||||
) -> anyhow::Result<khronos_egl::Image> {
|
||||
pub fn create_egl_image(&self, gl_tex_id: u32) -> anyhow::Result<khronos_egl::Image> {
|
||||
unsafe {
|
||||
Ok(self.egl.create_image(
|
||||
self.display,
|
||||
self.context,
|
||||
khronos_egl::GL_TEXTURE_2D as std::ffi::c_uint,
|
||||
khronos_egl::ClientBuffer::from_ptr(gl_tex_id as *mut std::ffi::c_void),
|
||||
&[
|
||||
khronos_egl::WIDTH as usize,
|
||||
width as usize,
|
||||
khronos_egl::HEIGHT as usize,
|
||||
height as usize,
|
||||
khronos_egl::ATTRIB_NONE,
|
||||
],
|
||||
&[khronos_egl::ATTRIB_NONE],
|
||||
)?)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -70,11 +70,12 @@ pub enum WayVRTask {
|
||||
NewExternalProcess(ExternalProcessRequest),
|
||||
DropOverlay(super::overlay::OverlayID),
|
||||
ProcessTerminationRequest(process::ProcessHandle),
|
||||
Haptics(super::input::Haptics),
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub enum WayVRSignal {
|
||||
DisplayHideRequest(display::DisplayHandle),
|
||||
DisplayVisibility(display::DisplayHandle, bool),
|
||||
}
|
||||
|
||||
pub struct Config {
|
||||
@@ -93,14 +94,15 @@ pub struct WayVRState {
|
||||
pub processes: process::ProcessVec,
|
||||
config: Config,
|
||||
dashboard_display: Option<display::DisplayHandle>,
|
||||
tasks: SyncEventQueue<WayVRTask>,
|
||||
pub tasks: SyncEventQueue<WayVRTask>,
|
||||
pub signals: SyncEventQueue<WayVRSignal>,
|
||||
ticks: u64,
|
||||
pub pending_haptic: Option<super::input::Haptics>,
|
||||
}
|
||||
|
||||
pub struct WayVR {
|
||||
pub state: WayVRState,
|
||||
ipc_server: WayVRServer,
|
||||
pub signals: SyncEventQueue<WayVRSignal>,
|
||||
}
|
||||
|
||||
pub enum MouseIndex {
|
||||
@@ -235,13 +237,11 @@ impl WayVR {
|
||||
dashboard_display: None,
|
||||
ticks: 0,
|
||||
tasks,
|
||||
pending_haptic: None,
|
||||
signals: SyncEventQueue::new(),
|
||||
};
|
||||
|
||||
Ok(Self {
|
||||
state,
|
||||
signals: SyncEventQueue::new(),
|
||||
ipc_server,
|
||||
})
|
||||
Ok(Self { state, ipc_server })
|
||||
}
|
||||
|
||||
pub fn tick_display(&mut self, display: display::DisplayHandle) -> anyhow::Result<()> {
|
||||
@@ -314,7 +314,7 @@ impl WayVR {
|
||||
}
|
||||
|
||||
self.state.displays.iter_mut(&mut |handle, display| {
|
||||
display.tick(&self.state.config, &handle, &mut self.signals);
|
||||
display.tick(&self.state.config, &handle, &mut self.state.signals);
|
||||
});
|
||||
|
||||
while let Some(task) = self.state.tasks.read() {
|
||||
@@ -358,6 +358,9 @@ impl WayVR {
|
||||
process.terminate();
|
||||
}
|
||||
}
|
||||
WayVRTask::Haptics(haptics) => {
|
||||
self.state.pending_haptic = Some(haptics);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
use super::{display, process, TickTask};
|
||||
use super::{display, process, TickTask, WayVRSignal};
|
||||
use bytes::BufMut;
|
||||
use interprocess::local_socket::{self, traits::Listener, ToNsName};
|
||||
use smallvec::SmallVec;
|
||||
@@ -223,6 +223,19 @@ impl Connection {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn handle_wvr_display_set_visible(
|
||||
&mut self,
|
||||
params: &mut TickParams,
|
||||
handle: packet_server::WvrDisplayHandle,
|
||||
visible: bool,
|
||||
) -> anyhow::Result<()> {
|
||||
params.state.signals.send(WayVRSignal::DisplayVisibility(
|
||||
display::DisplayHandle::from_packet(handle),
|
||||
visible,
|
||||
));
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn handle_wvr_process_launch(
|
||||
&mut self,
|
||||
params: &mut TickParams,
|
||||
@@ -319,6 +332,22 @@ impl Connection {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn handle_wlx_haptics(
|
||||
&mut self,
|
||||
params: &mut TickParams,
|
||||
haptics_params: packet_client::WlxHapticsParams,
|
||||
) -> anyhow::Result<()> {
|
||||
params
|
||||
.state
|
||||
.tasks
|
||||
.send(super::WayVRTask::Haptics(crate::backend::input::Haptics {
|
||||
duration: haptics_params.duration,
|
||||
frequency: haptics_params.frequency,
|
||||
intensity: haptics_params.intensity,
|
||||
}));
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn process_payload(&mut self, params: &mut TickParams, payload: Payload) -> anyhow::Result<()> {
|
||||
let packet: PacketClient = ipc::data_decode(&payload)?;
|
||||
|
||||
@@ -338,6 +367,9 @@ impl Connection {
|
||||
PacketClient::WvrDisplayRemove(serial, display_handle) => {
|
||||
self.handle_wvr_display_remove(params, serial, display_handle)?;
|
||||
}
|
||||
PacketClient::WvrDisplaySetVisible(display_handle, visible) => {
|
||||
self.handle_wvr_display_set_visible(params, display_handle, visible)?;
|
||||
}
|
||||
PacketClient::WvrProcessList(serial) => {
|
||||
self.handle_wvr_process_list(params, serial)?;
|
||||
}
|
||||
@@ -350,6 +382,9 @@ impl Connection {
|
||||
PacketClient::WvrProcessTerminate(process_handle) => {
|
||||
self.handle_wvr_process_terminate(params, process_handle)?;
|
||||
}
|
||||
PacketClient::WlxHaptics(haptics_params) => {
|
||||
self.handle_wlx_haptics(params, haptics_params)?;
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
|
||||
@@ -27,8 +27,8 @@ use crate::{
|
||||
use super::toast::error_toast;
|
||||
|
||||
// Hard-coded for now
|
||||
const DASHBOARD_WIDTH: u16 = 960;
|
||||
const DASHBOARD_HEIGHT: u16 = 540;
|
||||
const DASHBOARD_WIDTH: u16 = 1920;
|
||||
const DASHBOARD_HEIGHT: u16 = 1080;
|
||||
const DASHBOARD_DISPLAY_NAME: &str = "_DASHBOARD";
|
||||
|
||||
pub struct WayVRContext {
|
||||
@@ -125,7 +125,7 @@ impl InteractionHandler for WayVRInteractionHandler {
|
||||
wayvr.state.send_mouse_move(ctx.display, x as u32, y as u32);
|
||||
}
|
||||
|
||||
None
|
||||
wayvr.state.pending_haptic.take()
|
||||
}
|
||||
|
||||
fn on_left(&mut self, _app: &mut state::AppState, _pointer: usize) {
|
||||
@@ -280,7 +280,8 @@ where
|
||||
)?;
|
||||
|
||||
overlay.state.want_visible = true;
|
||||
overlay.state.spawn_scale = 1.25;
|
||||
overlay.state.spawn_scale = 2.0;
|
||||
overlay.state.spawn_point = vec3a(0.0, -0.35, -1.75);
|
||||
overlay.state.z_order = Z_ORDER_DASHBOARD;
|
||||
overlay.state.reset(app, true);
|
||||
|
||||
@@ -416,16 +417,19 @@ where
|
||||
|
||||
let mut wayvr = r_wayvr.borrow_mut();
|
||||
|
||||
while let Some(signal) = wayvr.data.signals.read() {
|
||||
while let Some(signal) = wayvr.data.state.signals.read() {
|
||||
match signal {
|
||||
wayvr::WayVRSignal::DisplayHideRequest(display_handle) => {
|
||||
wayvr::WayVRSignal::DisplayVisibility(display_handle, visible) => {
|
||||
if let Some(overlay_id) = wayvr.display_handle_map.get(&display_handle) {
|
||||
let overlay_id = *overlay_id;
|
||||
wayvr.data.state.set_display_visible(display_handle, false);
|
||||
wayvr
|
||||
.data
|
||||
.state
|
||||
.set_display_visible(display_handle, visible);
|
||||
app.tasks.enqueue(TaskType::Overlay(
|
||||
OverlaySelector::Id(overlay_id),
|
||||
Box::new(move |_app, o| {
|
||||
o.want_visible = false;
|
||||
o.want_visible = visible;
|
||||
}),
|
||||
));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user