From dcc2cd0575f1c0ce4f4d870e71061d8ec9a50043 Mon Sep 17 00:00:00 2001 From: galister <22305755+galister@users.noreply.github.com> Date: Mon, 29 Jul 2024 22:14:25 +0900 Subject: [PATCH] openxr: configurable screen downscale --- src/backend/openvr/lines.rs | 3 +++ src/backend/openxr/overlay.rs | 3 ++- src/backend/overlay.rs | 17 ++++++++++++++++ src/config.rs | 7 +++++++ src/gui/canvas/mod.rs | 4 ++++ src/overlays/mirror.rs | 4 ++++ src/overlays/screen.rs | 37 ++++++++++++++++++++--------------- 7 files changed, 58 insertions(+), 17 deletions(-) diff --git a/src/backend/openvr/lines.rs b/src/backend/openvr/lines.rs index cc5ad0b..ca1b950 100644 --- a/src/backend/openvr/lines.rs +++ b/src/backend/openvr/lines.rs @@ -189,4 +189,7 @@ impl OverlayRenderer for StaticRenderer { fn view(&mut self) -> Option> { Some(self.view.clone()) } + fn extent(&mut self) -> Option<[u32; 3]> { + Some(self.view.image().extent()) + } } diff --git a/src/backend/openxr/overlay.rs b/src/backend/openxr/overlay.rs index 095432a..8b3d772 100644 --- a/src/backend/openxr/overlay.rs +++ b/src/backend/openxr/overlay.rs @@ -38,7 +38,8 @@ impl OverlayData { log::warn!("{}: Will not show - image not ready", self.state.name); return Ok(CompositionLayer::None); }; - let extent = my_view.image().extent(); + + let extent = self.extent().unwrap(); // want panic let data = match self.data.swapchain { Some(ref mut data) => data, diff --git a/src/backend/overlay.rs b/src/backend/overlay.rs index 4244aa9..50a2a31 100644 --- a/src/backend/overlay.rs +++ b/src/backend/overlay.rs @@ -224,6 +224,9 @@ where pub fn view(&mut self) -> Option> { self.backend.view() } + pub fn extent(&mut self) -> Option<[u32; 3]> { + self.backend.extent() + } pub fn set_visible(&mut self, app: &mut AppState, visible: bool) -> anyhow::Result<()> { let old_visible = self.state.want_visible; self.state.want_visible = visible; @@ -239,11 +242,19 @@ where } pub trait OverlayRenderer { + /// Called once, before the first frame is rendered fn init(&mut self, app: &mut AppState) -> anyhow::Result<()>; fn pause(&mut self, app: &mut AppState) -> anyhow::Result<()>; fn resume(&mut self, app: &mut AppState) -> anyhow::Result<()>; + /// Called when the presentation layer is ready to present a new frame fn render(&mut self, app: &mut AppState) -> anyhow::Result<()>; + /// Called to retrieve the current image to be displayed fn view(&mut self) -> Option>; + /// Called to retrieve the effective extent of the image + /// Used for creating swapchains. + /// + /// Muse not be None if view() is also not None + fn extent(&mut self) -> Option<[u32; 3]>; } pub struct FallbackRenderer; @@ -264,6 +275,9 @@ impl OverlayRenderer for FallbackRenderer { fn view(&mut self) -> Option> { None } + fn extent(&mut self) -> Option<[u32; 3]> { + None + } } // Boilerplate and dummies @@ -318,6 +332,9 @@ impl OverlayRenderer for SplitOverlayBackend { fn view(&mut self) -> Option> { self.renderer.view() } + fn extent(&mut self) -> Option<[u32; 3]> { + self.renderer.extent() + } } impl InteractionHandler for SplitOverlayBackend { fn on_left(&mut self, app: &mut AppState, pointer: usize) { diff --git a/src/config.rs b/src/config.rs index c219b58..f4c783d 100644 --- a/src/config.rs +++ b/src/config.rs @@ -153,6 +153,10 @@ fn def_font() -> Arc { "LiberationSans:style=Bold".into() } +fn def_max_height() -> u16 { + 1440 +} + #[derive(Deserialize, Serialize)] pub struct GeneralConfig { #[serde(default = "def_watch_pos")] @@ -253,6 +257,9 @@ pub struct GeneralConfig { #[serde(default = "def_true")] pub use_skybox: bool, + + #[serde(default = "def_max_height")] + pub screen_max_height: u16, } impl GeneralConfig { diff --git a/src/gui/canvas/mod.rs b/src/gui/canvas/mod.rs index 00107fa..459917a 100644 --- a/src/gui/canvas/mod.rs +++ b/src/gui/canvas/mod.rs @@ -370,6 +370,10 @@ impl OverlayRenderer for Canvas { fn view(&mut self) -> Option> { Some(self.view_final.clone()) } + + fn extent(&mut self) -> Option<[u32; 3]> { + Some(self.view_final.image().extent()) + } } impl OverlayBackend for Canvas { diff --git a/src/overlays/mirror.rs b/src/overlays/mirror.rs index c227b46..d6801f8 100644 --- a/src/overlays/mirror.rs +++ b/src/overlays/mirror.rs @@ -121,6 +121,10 @@ impl OverlayRenderer for MirrorRenderer { fn view(&mut self) -> Option> { self.renderer.as_mut().and_then(|r| r.view()) } + + fn extent(&mut self) -> Option<[u32; 3]> { + Some(self.last_extent) + } } pub fn new_mirror( diff --git a/src/overlays/screen.rs b/src/overlays/screen.rs index d980576..7b7e50d 100644 --- a/src/overlays/screen.rs +++ b/src/overlays/screen.rs @@ -49,7 +49,7 @@ use crate::{ input::{Haptics, InteractionHandler, PointerHit, PointerMode}, overlay::{OverlayRenderer, OverlayState, SplitOverlayBackend}, }, - config::{def_pw_tokens, PwTokenMap}, + config::{def_pw_tokens, GeneralConfig, PwTokenMap}, graphics::{ fourcc_to_vk, WlxCommandBuffer, WlxPipeline, WlxPipelineLegacy, DRM_FORMAT_MOD_INVALID, }, @@ -296,7 +296,7 @@ impl ScreenRenderer { } #[cfg(feature = "wayland")] - pub fn new_wlr_dmabuf(output: &WlxOutput) -> Option { + pub fn new_wlr_dmabuf(output: &WlxOutput, config: &GeneralConfig) -> Option { let client = WlxClient::new()?; let capture = WlrDmabufCapture::new(client, output.id); @@ -305,12 +305,15 @@ impl ScreenRenderer { capture: Box::new(capture), pipeline: None, last_view: None, - extent: extent_from_res(output.size), + extent: extent_from_res(output.size, config), }) } #[cfg(feature = "wayland")] - pub fn new_wlr_screencopy(output: &WlxOutput) -> Option { + pub fn new_wlr_screencopy( + output: &WlxOutput, + config: &GeneralConfig, + ) -> Option { let client = WlxClient::new()?; let capture = WlrScreencopyCapture::new(client, output.id); @@ -319,7 +322,7 @@ impl ScreenRenderer { capture: Box::new(capture), pipeline: None, last_view: None, - extent: extent_from_res(output.size), + extent: extent_from_res(output.size, config), }) } @@ -360,14 +363,14 @@ impl ScreenRenderer { capture: Box::new(capture), pipeline: None, last_view: None, - extent: extent_from_res(output.size), + extent: extent_from_res(output.size, &session.config), }, select_screen_result.restore_token, )) } #[cfg(feature = "x11")] - pub fn new_xshm(screen: Arc) -> ScreenRenderer { + pub fn new_xshm(screen: Arc, config: &GeneralConfig) -> ScreenRenderer { let capture = XshmCapture::new(screen.clone()); ScreenRenderer { @@ -375,7 +378,7 @@ impl ScreenRenderer { capture: Box::new(capture), pipeline: None, last_view: None, - extent: extent_from_res((screen.monitor.width(), screen.monitor.height())), + extent: extent_from_res((screen.monitor.width(), screen.monitor.height()), config), } } } @@ -573,6 +576,9 @@ impl OverlayRenderer for ScreenRenderer { fn view(&mut self) -> Option> { self.last_view.clone() } + fn extent(&mut self) -> Option<[u32; 3]> { + Some(self.extent) + } } #[cfg(feature = "wayland")] @@ -588,12 +594,12 @@ pub fn create_screen_renderer_wl( && has_wlr_dmabuf { log::info!("{}: Using Wlr DMA-Buf", &output.name); - capture = ScreenRenderer::new_wlr_dmabuf(output); + capture = ScreenRenderer::new_wlr_dmabuf(output, &session.config); } if &*session.config.capture_method == "screencopy" && has_wlr_screencopy { log::info!("{}: Using Wlr Screencopy Wl-SHM", &output.name); - capture = ScreenRenderer::new_wlr_screencopy(output); + capture = ScreenRenderer::new_wlr_screencopy(output, &session.config); } if capture.is_none() { @@ -893,7 +899,7 @@ pub fn create_screens_x11pw(app: &mut AppState) -> anyhow::Result anyhow::Result for Transform { } } -fn extent_from_res(res: (i32, i32)) -> [u32; 3] { +fn extent_from_res(res: (i32, i32), config: &GeneralConfig) -> [u32; 3] { // screens above a certain resolution will have severe aliasing - // TODO make dynamic. maybe don't go above HMD resolution? - let w = res.0.min(2560) as u32; - let h = (res.1 as f32 / res.0 as f32 * w as f32) as u32; + let h = res.1.min(config.screen_max_height as i32) as u32; + let w = (res.0 as f32 / res.1 as f32 * h as f32) as u32; [w, h, 1] }