openxr: configurable screen downscale
This commit is contained in:
@@ -189,4 +189,7 @@ impl OverlayRenderer for StaticRenderer {
|
|||||||
fn view(&mut self) -> Option<Arc<ImageView>> {
|
fn view(&mut self) -> Option<Arc<ImageView>> {
|
||||||
Some(self.view.clone())
|
Some(self.view.clone())
|
||||||
}
|
}
|
||||||
|
fn extent(&mut self) -> Option<[u32; 3]> {
|
||||||
|
Some(self.view.image().extent())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -38,7 +38,8 @@ impl OverlayData<OpenXrOverlayData> {
|
|||||||
log::warn!("{}: Will not show - image not ready", self.state.name);
|
log::warn!("{}: Will not show - image not ready", self.state.name);
|
||||||
return Ok(CompositionLayer::None);
|
return Ok(CompositionLayer::None);
|
||||||
};
|
};
|
||||||
let extent = my_view.image().extent();
|
|
||||||
|
let extent = self.extent().unwrap(); // want panic
|
||||||
|
|
||||||
let data = match self.data.swapchain {
|
let data = match self.data.swapchain {
|
||||||
Some(ref mut data) => data,
|
Some(ref mut data) => data,
|
||||||
|
|||||||
@@ -224,6 +224,9 @@ where
|
|||||||
pub fn view(&mut self) -> Option<Arc<ImageView>> {
|
pub fn view(&mut self) -> Option<Arc<ImageView>> {
|
||||||
self.backend.view()
|
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<()> {
|
pub fn set_visible(&mut self, app: &mut AppState, visible: bool) -> anyhow::Result<()> {
|
||||||
let old_visible = self.state.want_visible;
|
let old_visible = self.state.want_visible;
|
||||||
self.state.want_visible = visible;
|
self.state.want_visible = visible;
|
||||||
@@ -239,11 +242,19 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub trait OverlayRenderer {
|
pub trait OverlayRenderer {
|
||||||
|
/// Called once, before the first frame is rendered
|
||||||
fn init(&mut self, app: &mut AppState) -> anyhow::Result<()>;
|
fn init(&mut self, app: &mut AppState) -> anyhow::Result<()>;
|
||||||
fn pause(&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<()>;
|
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<()>;
|
fn render(&mut self, app: &mut AppState) -> anyhow::Result<()>;
|
||||||
|
/// Called to retrieve the current image to be displayed
|
||||||
fn view(&mut self) -> Option<Arc<ImageView>>;
|
fn view(&mut self) -> Option<Arc<ImageView>>;
|
||||||
|
/// 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;
|
pub struct FallbackRenderer;
|
||||||
@@ -264,6 +275,9 @@ impl OverlayRenderer for FallbackRenderer {
|
|||||||
fn view(&mut self) -> Option<Arc<ImageView>> {
|
fn view(&mut self) -> Option<Arc<ImageView>> {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
fn extent(&mut self) -> Option<[u32; 3]> {
|
||||||
|
None
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// Boilerplate and dummies
|
// Boilerplate and dummies
|
||||||
|
|
||||||
@@ -318,6 +332,9 @@ impl OverlayRenderer for SplitOverlayBackend {
|
|||||||
fn view(&mut self) -> Option<Arc<ImageView>> {
|
fn view(&mut self) -> Option<Arc<ImageView>> {
|
||||||
self.renderer.view()
|
self.renderer.view()
|
||||||
}
|
}
|
||||||
|
fn extent(&mut self) -> Option<[u32; 3]> {
|
||||||
|
self.renderer.extent()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
impl InteractionHandler for SplitOverlayBackend {
|
impl InteractionHandler for SplitOverlayBackend {
|
||||||
fn on_left(&mut self, app: &mut AppState, pointer: usize) {
|
fn on_left(&mut self, app: &mut AppState, pointer: usize) {
|
||||||
|
|||||||
@@ -153,6 +153,10 @@ fn def_font() -> Arc<str> {
|
|||||||
"LiberationSans:style=Bold".into()
|
"LiberationSans:style=Bold".into()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn def_max_height() -> u16 {
|
||||||
|
1440
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Deserialize, Serialize)]
|
#[derive(Deserialize, Serialize)]
|
||||||
pub struct GeneralConfig {
|
pub struct GeneralConfig {
|
||||||
#[serde(default = "def_watch_pos")]
|
#[serde(default = "def_watch_pos")]
|
||||||
@@ -253,6 +257,9 @@ pub struct GeneralConfig {
|
|||||||
|
|
||||||
#[serde(default = "def_true")]
|
#[serde(default = "def_true")]
|
||||||
pub use_skybox: bool,
|
pub use_skybox: bool,
|
||||||
|
|
||||||
|
#[serde(default = "def_max_height")]
|
||||||
|
pub screen_max_height: u16,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl GeneralConfig {
|
impl GeneralConfig {
|
||||||
|
|||||||
@@ -370,6 +370,10 @@ impl<D, S> OverlayRenderer for Canvas<D, S> {
|
|||||||
fn view(&mut self) -> Option<Arc<ImageView>> {
|
fn view(&mut self) -> Option<Arc<ImageView>> {
|
||||||
Some(self.view_final.clone())
|
Some(self.view_final.clone())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn extent(&mut self) -> Option<[u32; 3]> {
|
||||||
|
Some(self.view_final.image().extent())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<D, S> OverlayBackend for Canvas<D, S> {
|
impl<D, S> OverlayBackend for Canvas<D, S> {
|
||||||
|
|||||||
@@ -121,6 +121,10 @@ impl OverlayRenderer for MirrorRenderer {
|
|||||||
fn view(&mut self) -> Option<std::sync::Arc<vulkano::image::view::ImageView>> {
|
fn view(&mut self) -> Option<std::sync::Arc<vulkano::image::view::ImageView>> {
|
||||||
self.renderer.as_mut().and_then(|r| r.view())
|
self.renderer.as_mut().and_then(|r| r.view())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn extent(&mut self) -> Option<[u32; 3]> {
|
||||||
|
Some(self.last_extent)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new_mirror(
|
pub fn new_mirror(
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ use crate::{
|
|||||||
input::{Haptics, InteractionHandler, PointerHit, PointerMode},
|
input::{Haptics, InteractionHandler, PointerHit, PointerMode},
|
||||||
overlay::{OverlayRenderer, OverlayState, SplitOverlayBackend},
|
overlay::{OverlayRenderer, OverlayState, SplitOverlayBackend},
|
||||||
},
|
},
|
||||||
config::{def_pw_tokens, PwTokenMap},
|
config::{def_pw_tokens, GeneralConfig, PwTokenMap},
|
||||||
graphics::{
|
graphics::{
|
||||||
fourcc_to_vk, WlxCommandBuffer, WlxPipeline, WlxPipelineLegacy, DRM_FORMAT_MOD_INVALID,
|
fourcc_to_vk, WlxCommandBuffer, WlxPipeline, WlxPipelineLegacy, DRM_FORMAT_MOD_INVALID,
|
||||||
},
|
},
|
||||||
@@ -296,7 +296,7 @@ impl ScreenRenderer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "wayland")]
|
#[cfg(feature = "wayland")]
|
||||||
pub fn new_wlr_dmabuf(output: &WlxOutput) -> Option<ScreenRenderer> {
|
pub fn new_wlr_dmabuf(output: &WlxOutput, config: &GeneralConfig) -> Option<ScreenRenderer> {
|
||||||
let client = WlxClient::new()?;
|
let client = WlxClient::new()?;
|
||||||
let capture = WlrDmabufCapture::new(client, output.id);
|
let capture = WlrDmabufCapture::new(client, output.id);
|
||||||
|
|
||||||
@@ -305,12 +305,15 @@ impl ScreenRenderer {
|
|||||||
capture: Box::new(capture),
|
capture: Box::new(capture),
|
||||||
pipeline: None,
|
pipeline: None,
|
||||||
last_view: None,
|
last_view: None,
|
||||||
extent: extent_from_res(output.size),
|
extent: extent_from_res(output.size, config),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "wayland")]
|
#[cfg(feature = "wayland")]
|
||||||
pub fn new_wlr_screencopy(output: &WlxOutput) -> Option<ScreenRenderer> {
|
pub fn new_wlr_screencopy(
|
||||||
|
output: &WlxOutput,
|
||||||
|
config: &GeneralConfig,
|
||||||
|
) -> Option<ScreenRenderer> {
|
||||||
let client = WlxClient::new()?;
|
let client = WlxClient::new()?;
|
||||||
let capture = WlrScreencopyCapture::new(client, output.id);
|
let capture = WlrScreencopyCapture::new(client, output.id);
|
||||||
|
|
||||||
@@ -319,7 +322,7 @@ impl ScreenRenderer {
|
|||||||
capture: Box::new(capture),
|
capture: Box::new(capture),
|
||||||
pipeline: None,
|
pipeline: None,
|
||||||
last_view: 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),
|
capture: Box::new(capture),
|
||||||
pipeline: None,
|
pipeline: None,
|
||||||
last_view: None,
|
last_view: None,
|
||||||
extent: extent_from_res(output.size),
|
extent: extent_from_res(output.size, &session.config),
|
||||||
},
|
},
|
||||||
select_screen_result.restore_token,
|
select_screen_result.restore_token,
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "x11")]
|
#[cfg(feature = "x11")]
|
||||||
pub fn new_xshm(screen: Arc<XshmScreen>) -> ScreenRenderer {
|
pub fn new_xshm(screen: Arc<XshmScreen>, config: &GeneralConfig) -> ScreenRenderer {
|
||||||
let capture = XshmCapture::new(screen.clone());
|
let capture = XshmCapture::new(screen.clone());
|
||||||
|
|
||||||
ScreenRenderer {
|
ScreenRenderer {
|
||||||
@@ -375,7 +378,7 @@ impl ScreenRenderer {
|
|||||||
capture: Box::new(capture),
|
capture: Box::new(capture),
|
||||||
pipeline: None,
|
pipeline: None,
|
||||||
last_view: 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<Arc<ImageView>> {
|
fn view(&mut self) -> Option<Arc<ImageView>> {
|
||||||
self.last_view.clone()
|
self.last_view.clone()
|
||||||
}
|
}
|
||||||
|
fn extent(&mut self) -> Option<[u32; 3]> {
|
||||||
|
Some(self.extent)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "wayland")]
|
#[cfg(feature = "wayland")]
|
||||||
@@ -588,12 +594,12 @@ pub fn create_screen_renderer_wl(
|
|||||||
&& has_wlr_dmabuf
|
&& has_wlr_dmabuf
|
||||||
{
|
{
|
||||||
log::info!("{}: Using Wlr DMA-Buf", &output.name);
|
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 {
|
if &*session.config.capture_method == "screencopy" && has_wlr_screencopy {
|
||||||
log::info!("{}: Using Wlr Screencopy Wl-SHM", &output.name);
|
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() {
|
if capture.is_none() {
|
||||||
@@ -893,7 +899,7 @@ pub fn create_screens_x11pw(app: &mut AppState) -> anyhow::Result<ScreenCreateDa
|
|||||||
capture: Box::new(PipewireCapture::new(m.name.clone(), s.node_id)),
|
capture: Box::new(PipewireCapture::new(m.name.clone(), s.node_id)),
|
||||||
pipeline: None,
|
pipeline: None,
|
||||||
last_view: None,
|
last_view: None,
|
||||||
extent: extent_from_res(size),
|
extent: extent_from_res(size, &app.session.config),
|
||||||
};
|
};
|
||||||
|
|
||||||
let backend = Box::new(SplitOverlayBackend {
|
let backend = Box::new(SplitOverlayBackend {
|
||||||
@@ -931,7 +937,7 @@ pub fn create_screens_xshm(app: &mut AppState) -> anyhow::Result<ScreenCreateDat
|
|||||||
|
|
||||||
let size = (s.monitor.width(), s.monitor.height());
|
let size = (s.monitor.width(), s.monitor.height());
|
||||||
let pos = (s.monitor.x(), s.monitor.y());
|
let pos = (s.monitor.x(), s.monitor.y());
|
||||||
let renderer = ScreenRenderer::new_xshm(s.clone());
|
let renderer = ScreenRenderer::new_xshm(s.clone(), &app.session.config);
|
||||||
|
|
||||||
log::info!(
|
log::info!(
|
||||||
"{}: Init X11 screen of res {:?} at {:?}",
|
"{}: Init X11 screen of res {:?} at {:?}",
|
||||||
@@ -997,12 +1003,11 @@ impl From<wl_output::Transform> 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
|
// screens above a certain resolution will have severe aliasing
|
||||||
|
|
||||||
// TODO make dynamic. maybe don't go above HMD resolution?
|
let h = res.1.min(config.screen_max_height as i32) as u32;
|
||||||
let w = res.0.min(2560) as u32;
|
let w = (res.0 as f32 / res.1 as f32 * h as f32) as u32;
|
||||||
let h = (res.1 as f32 / res.0 as f32 * w as f32) as u32;
|
|
||||||
[w, h, 1]
|
[w, h, 1]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user