diff --git a/Cargo.lock b/Cargo.lock index 83fc4995..ea44c1c1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1734,7 +1734,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" dependencies = [ "libc", - "windows-sys 0.61.2", + "windows-sys 0.52.0", ] [[package]] @@ -3148,7 +3148,7 @@ version = "0.50.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7957b9740744892f114936ab4a57b3f487491bbeafaf8083688b16841a4240e5" dependencies = [ - "windows-sys 0.61.2", + "windows-sys 0.59.0", ] [[package]] @@ -3650,7 +3650,7 @@ dependencies = [ [[package]] name = "ovr_overlay" version = "0.0.0" -source = "git+https://github.com/galister/ovr_overlay_oyasumi?rev=e477bd2a9e04293ea68c1e7529ef2cb131f32acc#e477bd2a9e04293ea68c1e7529ef2cb131f32acc" +source = "git+https://github.com/galister/ovr_overlay_oyasumi?rev=0ad843c793aec71f37e4efd43942607c94cff34c#0ad843c793aec71f37e4efd43942607c94cff34c" dependencies = [ "byteorder", "derive_more", @@ -3665,7 +3665,7 @@ dependencies = [ [[package]] name = "ovr_overlay_sys" version = "0.0.0" -source = "git+https://github.com/galister/ovr_overlay_oyasumi?rev=e477bd2a9e04293ea68c1e7529ef2cb131f32acc#e477bd2a9e04293ea68c1e7529ef2cb131f32acc" +source = "git+https://github.com/galister/ovr_overlay_oyasumi?rev=0ad843c793aec71f37e4efd43942607c94cff34c#0ad843c793aec71f37e4efd43942607c94cff34c" dependencies = [ "autocxx", "autocxx-build", @@ -4053,7 +4053,7 @@ version = "0.14.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "03da047801ff44bb6a4d407d4860c05fd70bb81714e6b2f3812603d5b145b042" dependencies = [ - "heck 0.5.0", + "heck 0.4.1", "itertools 0.14.0", "log", "multimap", @@ -4666,7 +4666,7 @@ dependencies = [ "errno", "libc", "linux-raw-sys 0.12.1", - "windows-sys 0.61.2", + "windows-sys 0.52.0", ] [[package]] @@ -5400,10 +5400,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32497e9a4c7b38532efcdebeef879707aa9f794296a4f0244f6f69e9bc8574bd" dependencies = [ "fastrand", - "getrandom 0.4.3", + "getrandom 0.3.4", "once_cell", "rustix 1.1.4", - "windows-sys 0.61.2", + "windows-sys 0.52.0", ] [[package]] @@ -6424,7 +6424,7 @@ version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22" dependencies = [ - "windows-sys 0.61.2", + "windows-sys 0.48.0", ] [[package]] diff --git a/wayvr/Cargo.toml b/wayvr/Cargo.toml index 8f608ce4..30d45b23 100644 --- a/wayvr/Cargo.toml +++ b/wayvr/Cargo.toml @@ -86,7 +86,7 @@ mint = "0.5.9" openxr = { version = "0.21.1", features = ["linked", "mint"], optional = true } ovr_overlay = { git = "https://github.com/galister/ovr_overlay_oyasumi", - rev = "e477bd2a9e04293ea68c1e7529ef2cb131f32acc", + rev = "0ad843c793aec71f37e4efd43942607c94cff34c", features = [ "ovr_input", "ovr_system", diff --git a/wayvr/src/assets/gui/edit.xml b/wayvr/src/assets/gui/edit.xml index 6efc8632..a77bcfed 100644 --- a/wayvr/src/assets/gui/edit.xml +++ b/wayvr/src/assets/gui/edit.xml @@ -79,8 +79,8 @@ - - + +
diff --git a/wayvr/src/backend/openvr/mod.rs b/wayvr/src/backend/openvr/mod.rs index add2c4dc..f2bbf4dc 100644 --- a/wayvr/src/backend/openvr/mod.rs +++ b/wayvr/src/backend/openvr/mod.rs @@ -331,6 +331,7 @@ pub fn openvr_run(args: &Args) -> Result<(), BackendError> { views: smallvec![o.ensure_staging_image(&mut app, meta.extent)?], }; let mut rdr = RenderResources::new(app.gfx.clone(), tgt, &meta)?; + o.set_stereo_mode(meta.stereo); o.render(&mut app, &mut rdr)?; o.data.image_dirty = true; futures.execute_results(rdr.end()?)?; diff --git a/wayvr/src/backend/openvr/overlay.rs b/wayvr/src/backend/openvr/overlay.rs index ba769f44..b368d973 100644 --- a/wayvr/src/backend/openvr/overlay.rs +++ b/wayvr/src/backend/openvr/overlay.rs @@ -5,13 +5,14 @@ use glam::Vec4; use ovr_overlay::{ overlay::{OverlayHandle, OverlayManager}, pose::Matrix3x4, - sys::{ETrackingUniverseOrigin, VRVulkanTextureData_t}, + sys::{ETrackingUniverseOrigin, VROverlayFlags, VRVulkanTextureData_t}, }; use vulkano::{ Handle, VulkanObject, image::{ImageUsage, view::ImageView}, }; use wgui::gfx::WGfx; +use wlx_common::overlays::StereoMode; use crate::{graphics::ExtentExt, state::AppState, windowing::window::OverlayWindowData}; @@ -26,6 +27,8 @@ pub(super) struct OpenVrOverlayData { pub(super) override_width: bool, pub(super) image_view: Option>, pub(super) image_dirty: bool, + pub(super) cur_stereo_mode: StereoMode, + pub(super) pending_stereo_mode: Option, } impl OverlayWindowData { @@ -56,6 +59,7 @@ impl OverlayWindowData { self.upload_width(overlay); self.upload_color(overlay); self.upload_alpha(overlay); + self.upload_flags(overlay); self.upload_curvature(overlay); self.upload_sort_order(overlay); @@ -122,12 +126,19 @@ impl OverlayWindowData { self.upload_transform(universe, overlay); self.upload_alpha(overlay); + self.upload_flags(overlay); self.config.dirty = false; } self.upload_texture(overlay, graphics); } } + pub(super) fn set_stereo_mode(&mut self, stereo_mode: StereoMode) { + if self.data.cur_stereo_mode != stereo_mode { + self.data.pending_stereo_mode = Some(stereo_mode); + } + } + fn show_internal( &mut self, overlay: &mut OverlayManager, @@ -161,6 +172,31 @@ impl OverlayWindowData { self.config.backend.pause(app) } + const fn stereo_mode_to_flag(stereo_mode: StereoMode) -> Option { + match stereo_mode { + StereoMode::LeftRight => Some(VROverlayFlags::VROverlayFlags_SideBySide_Parallel), + StereoMode::RightLeft => Some(VROverlayFlags::VROverlayFlags_SideBySide_Crossed), + _ => None, + } + } + + fn upload_flags(&mut self, overlay: &mut OverlayManager) { + let Some(handle) = self.data.handle else { + log::debug!("{}: No overlay handle", self.config.name); + return; + }; + + if let Some(pending) = self.data.pending_stereo_mode.take() { + if let Some(flag) = Self::stereo_mode_to_flag(self.data.cur_stereo_mode) { + let _ = overlay.set_overlay_flag(handle, flag, false); + } + if let Some(flag) = Self::stereo_mode_to_flag(pending) { + let _ = overlay.set_overlay_flag(handle, flag, true); + } + self.data.cur_stereo_mode = pending; + } + } + pub(super) fn upload_alpha(&self, overlay: &mut OverlayManager) { let Some(handle) = self.data.handle else { log::debug!("{}: No overlay handle", self.config.name); diff --git a/wayvr/src/overlays/edit/mod.rs b/wayvr/src/overlays/edit/mod.rs index 7600fc95..041c24d4 100644 --- a/wayvr/src/overlays/edit/mod.rs +++ b/wayvr/src/overlays/edit/mod.rs @@ -528,16 +528,22 @@ fn make_edit_panel(app: &mut AppState) -> anyhow::Result { } }); - let mut panel = GuiPanel::new_from_template( - app, - "gui/edit.xml", - state, - NewGuiPanelParams { - on_custom_attrib: Some(on_custom_attrib), - resize_to_parent: true, - ..Default::default() - }, - )?; + let mut params = NewGuiPanelParams { + on_custom_attrib: Some(on_custom_attrib), + resize_to_parent: true, + ..Default::default() + }; + params.extra_vars.insert( + "openvr".into(), + (if app.xr_backend.is_open_vr() { + "1" + } else { + "0" + }) + .into(), + ); + + let mut panel = GuiPanel::new_from_template(app, "gui/edit.xml", state, params)?; panel.state.pos = new_pos_tab_handler(&mut panel)?; panel.state.stereo = new_stereo_tab_handler(&mut panel)?; diff --git a/wayvr/src/overlays/screen/backend.rs b/wayvr/src/overlays/screen/backend.rs index 0485e593..497894ff 100644 --- a/wayvr/src/overlays/screen/backend.rs +++ b/wayvr/src/overlays/screen/backend.rs @@ -7,7 +7,6 @@ use glam::{Affine2, DVec2, Vec2, vec2}; use wlx_capture::{WlxCapture, frame::Transform}; use crate::{ - XrBackend, backend::input::{HoverResult, PointerHit, PointerMode}, overlays::screen::capture::MyFirstDmaExporter, state::AppState, @@ -55,7 +54,7 @@ pub struct ScreenBackend { meta: Option, mouse_transform: Affine2, interaction_transform: Option, - stereo: Option, + stereo: StereoMode, stereo_full_frame: bool, stereo_adjust_mouse: bool, pub(super) logical_pos: Vec2, @@ -67,7 +66,6 @@ pub struct ScreenBackend { impl ScreenBackend { pub(super) fn new_raw( name: Arc, - xr_backend: XrBackend, capture_type: CaptureType, capture: Box>, ) -> Self { @@ -80,7 +78,7 @@ impl ScreenBackend { meta: None, mouse_transform: Affine2::ZERO, interaction_transform: None, - stereo: xr_backend.is_open_xr().then_some(StereoMode::None), + stereo: StereoMode::None, stereo_full_frame: false, stereo_adjust_mouse: false, logical_pos: Vec2::ZERO, @@ -94,10 +92,8 @@ impl ScreenBackend { let mut size = self.logical_size; let pos = self.logical_pos; - if self.stereo_adjust_mouse - && let Some(stereo) = self.stereo.as_ref() - { - match stereo { + if self.stereo_adjust_mouse { + match self.stereo { StereoMode::LeftRight | StereoMode::RightLeft => size.x *= 0.5, StereoMode::TopBottom | StereoMode::BottomTop => size.y *= 0.5, _ => {} @@ -209,21 +205,18 @@ impl OverlayBackend for ScreenBackend { } if let Some(frame) = self.capture.receive() { - let stereo = self.stereo.unwrap_or(StereoMode::None); - let mut meta = frame.get_frame_meta(&app.session.config, stereo); + let mut meta = frame.get_frame_meta(&app.session.config, self.stereo); - if let Some(stereo) = self.stereo { - // Apply stereo full frame logic - if self.stereo_full_frame { - match stereo { - StereoMode::LeftRight | StereoMode::RightLeft => { - meta.extent[0] /= 2; - } - StereoMode::TopBottom | StereoMode::BottomTop => { - meta.extent[1] /= 2; - } - _ => {} + // Apply stereo full frame logic + if self.stereo_full_frame { + match self.stereo { + StereoMode::LeftRight | StereoMode::RightLeft => { + meta.extent[0] /= 2; } + StereoMode::TopBottom | StereoMode::BottomTop => { + meta.extent[1] /= 2; + } + _ => {} } } @@ -241,7 +234,7 @@ impl OverlayBackend for ScreenBackend { } } else { let pipeline = - ScreenPipeline::new(&meta, app, stereo, [0., 0.], frame.format.transform)?; + ScreenPipeline::new(&meta, app, self.stereo, [0., 0.], frame.format.transform)?; self.pipeline = Some(pipeline); self.interaction_transform = Some(ui_transform(meta.extent)); } @@ -360,7 +353,7 @@ impl OverlayBackend for ScreenBackend { } fn get_attrib(&self, attrib: BackendAttrib) -> Option { match attrib { - BackendAttrib::Stereo => self.stereo.map(BackendAttribValue::Stereo), + BackendAttrib::Stereo => Some(BackendAttribValue::Stereo(self.stereo)), BackendAttrib::MouseTransform => Some(BackendAttribValue::MouseTransform( self.mouse_transform_override, )), @@ -373,19 +366,15 @@ impl OverlayBackend for ScreenBackend { _ => None, } } - fn set_attrib(&mut self, _app: &mut AppState, value: BackendAttribValue) -> bool { + fn set_attrib(&mut self, app: &mut AppState, value: BackendAttribValue) -> bool { match value { BackendAttribValue::Stereo(new) => { - if let Some(stereo) = self.stereo.as_mut() { - log::debug!("{}: stereo: {stereo:?} → {new:?}", self.name); - *stereo = new; - if let Some(pipeline) = self.pipeline.as_mut() { - pipeline.ensure_stereo(new); - } - true - } else { - false + log::debug!("{}: stereo: {:?} → {new:?}", self.name, self.stereo); + self.stereo = new; + if let Some(pipeline) = self.pipeline.as_mut() { + pipeline.ensure_stereo(app.xr_backend, new); } + true } BackendAttribValue::MouseTransform(new) => { self.mouse_transform_override = new; diff --git a/wayvr/src/overlays/screen/capture.rs b/wayvr/src/overlays/screen/capture.rs index e670b32f..1489a497 100644 --- a/wayvr/src/overlays/screen/capture.rs +++ b/wayvr/src/overlays/screen/capture.rs @@ -28,7 +28,7 @@ use wlx_capture::{ DrmFormat, DrmFourcc, DrmModifier, WlxCapture, frame::{self as wlx_frame, DmaExporter, FrameFormat, MouseMeta, WlxFrame}, }; -use wlx_common::{config::GeneralConfig, overlays::StereoMode}; +use wlx_common::{XrBackend, config::GeneralConfig, overlays::StereoMode}; use crate::{ graphics::{ @@ -87,13 +87,17 @@ impl ScreenPipeline { stereo, stereo_adjust_mouse: false, }; - me.ensure_stereo(stereo); + me.ensure_stereo(app.xr_backend, stereo); Ok(me) } - pub fn ensure_stereo(&mut self, stereo: StereoMode) { + pub fn ensure_stereo(&mut self, xr_backend: XrBackend, stereo: StereoMode) { if self.stereo == stereo { return; + } else if xr_backend.is_open_vr() { + // OpenVR takes raw SBS texture + self.stereo = StereoMode::None; + return; } self.stereo = stereo; diff --git a/wayvr/src/overlays/screen/mirror.rs b/wayvr/src/overlays/screen/mirror.rs index 3e7801b1..fe6e5b88 100644 --- a/wayvr/src/overlays/screen/mirror.rs +++ b/wayvr/src/overlays/screen/mirror.rs @@ -83,10 +83,9 @@ pub fn new_mirror(name: Arc, app: &mut AppState) -> anyhow::Result>, - app: &mut AppState, + _app: &mut AppState, ) -> Box { - let renderer = - ScreenBackend::new_raw(name.clone(), app.xr_backend, CaptureType::PipeWire, capture); + let renderer = ScreenBackend::new_raw(name.clone(), CaptureType::PipeWire, capture); let backend = MirrorBackend(renderer); diff --git a/wayvr/src/overlays/screen/pw.rs b/wayvr/src/overlays/screen/pw.rs index 782953d8..e100def0 100644 --- a/wayvr/src/overlays/screen/pw.rs +++ b/wayvr/src/overlays/screen/pw.rs @@ -76,12 +76,11 @@ impl ScreenCastBackend { logical_pos: Vec2, logical_size: Vec2, capture: Box>, - app: &mut AppState, + _app: &mut AppState, ) -> Box { use wlx_capture::frame::Transform; - let mut backend = - ScreenBackend::new_raw(name, app.xr_backend, CaptureType::PipeWire, capture); + let mut backend = ScreenBackend::new_raw(name, CaptureType::PipeWire, capture); backend.logical_pos = logical_pos; backend.logical_size = logical_size; diff --git a/wayvr/src/overlays/screen/wl.rs b/wayvr/src/overlays/screen/wl.rs index ba1692a6..ea7624a8 100644 --- a/wayvr/src/overlays/screen/wl.rs +++ b/wayvr/src/overlays/screen/wl.rs @@ -29,7 +29,6 @@ impl ScreenBackend { ); Some(Self::new_raw( output.name.clone(), - app.xr_backend, CaptureType::ScreenCopy, capture, )) diff --git a/wayvr/src/overlays/screen/x11.rs b/wayvr/src/overlays/screen/x11.rs index 783f518e..e45c9672 100644 --- a/wayvr/src/overlays/screen/x11.rs +++ b/wayvr/src/overlays/screen/x11.rs @@ -31,12 +31,7 @@ impl ScreenBackend { app.gfx_extras.queue_capture, XshmCapture::new(screen.clone()) ); - Self::new_raw( - screen.name.clone(), - app.xr_backend, - CaptureType::Xshm, - capture, - ) + Self::new_raw(screen.name.clone(), CaptureType::Xshm, capture) } } @@ -103,7 +98,6 @@ pub fn create_screens_x11pw(app: &mut AppState) -> anyhow::Result, mouse: Option, - stereo: Option, + stereo: StereoMode, stereo_full_frame: bool, stereo_adjust_mouse: bool, cur_image: Option>, @@ -248,7 +248,7 @@ impl WvrWindowBackend { just_resumed: false, meta: None, mouse: None, - stereo: app.xr_backend.is_open_xr().then_some(StereoMode::None), + stereo: StereoMode::None, stereo_full_frame: false, stereo_adjust_mouse: false, cur_image: None, @@ -316,10 +316,8 @@ impl WvrWindowBackend { -((BORDER_SIZE + BAR_SIZE) as f32) / meta.extent[1] as f32, ); - if self.stereo_adjust_mouse - && let Some(stereo) = self.stereo - { - match stereo { + if self.stereo_adjust_mouse { + match self.stereo { StereoMode::LeftRight | StereoMode::RightLeft => { scale.x *= 0.5; translation.x *= 0.5; @@ -591,22 +589,20 @@ impl OverlayBackend for WvrWindowBackend { extent: surf.image.extent_u32arr(), format: surf.image.format(), clear: WGfxClearMode::Clear([0.0, 0.0, 0.0, 0.0]), - stereo: self.stereo.unwrap_or(StereoMode::None), + stereo: self.stereo, ..Default::default() }; - if let Some(stereo) = self.stereo { - // Apply stereo full frame logic - if self.stereo_full_frame { - match stereo { - StereoMode::LeftRight | StereoMode::RightLeft => { - meta.extent[0] /= 2; - } - StereoMode::TopBottom | StereoMode::BottomTop => { - meta.extent[1] /= 2; - } - _ => {} + // Apply stereo full frame logic + if self.stereo_full_frame { + match self.stereo { + StereoMode::LeftRight | StereoMode::RightLeft => { + meta.extent[0] /= 2; } + StereoMode::TopBottom | StereoMode::BottomTop => { + meta.extent[1] /= 2; + } + _ => {} } } @@ -641,7 +637,7 @@ impl OverlayBackend for WvrWindowBackend { let pipeline = ScreenPipeline::new( &meta, app, - self.stereo.unwrap_or(StereoMode::None), + self.stereo, [BORDER_SIZE as _, (BAR_SIZE + BORDER_SIZE) as _], Transform::Normal, )?; @@ -1025,7 +1021,7 @@ impl OverlayBackend for WvrWindowBackend { fn get_attrib(&self, attrib: BackendAttrib) -> Option { match attrib { - BackendAttrib::Stereo => self.stereo.map(BackendAttribValue::Stereo), + BackendAttrib::Stereo => Some(BackendAttribValue::Stereo(self.stereo)), BackendAttrib::Icon => Some(BackendAttribValue::Icon(self.icon.clone())), BackendAttrib::StereoFullFrame => { Some(BackendAttribValue::StereoFullFrame(self.stereo_full_frame)) @@ -1041,19 +1037,15 @@ impl OverlayBackend for WvrWindowBackend { fn set_attrib(&mut self, app: &mut AppState, value: BackendAttribValue) -> bool { match value { BackendAttribValue::Stereo(new) => { - if let Some(stereo) = self.stereo.as_mut() { - log::debug!("{}: stereo: {stereo:?} → {new:?}", self.name); - *stereo = new; - if let Some(meta) = self.meta.clone() { - let _ = self.apply_extent(app, &meta); - } - if let Some(pipeline) = self.pipeline.as_mut() { - pipeline.ensure_stereo(new); - } - true - } else { - false + log::debug!("{}: stereo: {:?} → {new:?}", self.name, self.stereo); + self.stereo = new; + if let Some(meta) = self.meta.clone() { + let _ = self.apply_extent(app, &meta); } + if let Some(pipeline) = self.pipeline.as_mut() { + pipeline.ensure_stereo(app.xr_backend, new); + } + true } BackendAttribValue::StereoFullFrame(new) => { self.stereo_full_frame = new;