From 5bbaf5979013c18bf78d0a265348bf95daed7789 Mon Sep 17 00:00:00 2001 From: galister <22305755+galister@users.noreply.github.com> Date: Sat, 17 Feb 2024 12:32:23 +0100 Subject: [PATCH] pipewire: dmabuf capture !!! --- Cargo.lock | 2 +- src/backend/common.rs | 12 +++++++++--- src/config.rs | 16 ++++++++++++++++ src/overlays/screen.rs | 36 +++++++++++++++++++++++++----------- src/state.rs | 6 ------ 5 files changed, 51 insertions(+), 21 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 5c3f44e..84205b6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4280,7 +4280,7 @@ dependencies = [ [[package]] name = "wlx-capture" version = "0.1.0" -source = "git+https://github.com/galister/wlx-capture#c91b249d29319f4c5882abee5e911d84943aa6da" +source = "git+https://github.com/galister/wlx-capture#332dd363357a845e4107aaada9a67899e7398839" dependencies = [ "ashpd", "drm-fourcc", diff --git a/src/backend/common.rs b/src/backend/common.rs index 947af58..f693c21 100644 --- a/src/backend/common.rs +++ b/src/backend/common.rs @@ -55,12 +55,18 @@ where keyboard.state.want_visible = false; overlays.insert(keyboard.state.id, keyboard); - let mut first = true; + let mut show_screens = app.session.config.show_screens.clone(); + if show_screens.is_empty() { + screens.first().and_then(|s| { + show_screens.push(s.state.name.clone()); + Some(()) + }); + } + for mut screen in screens { - if first { + if show_screens.contains(&screen.state.name) { screen.state.show_hide = true; screen.state.want_visible = false; - first = false; } overlays.insert(screen.state.id, screen); } diff --git a/src/config.rs b/src/config.rs index ad5dbdc..7375a3b 100644 --- a/src/config.rs +++ b/src/config.rs @@ -1,3 +1,5 @@ +use std::sync::Arc; + use crate::config_io; use crate::config_io::get_conf_d_path; use crate::load_with_fallback; @@ -39,6 +41,14 @@ fn def_osc_port() -> u16 { 9000 } +fn def_screens() -> Vec> { + vec![] +} + +fn def_auto() -> Arc { + "auto".into() +} + #[derive(Deserialize, Serialize)] pub struct GeneralConfig { #[serde(default = "def_click_freeze_time_ms")] @@ -70,6 +80,12 @@ pub struct GeneralConfig { #[serde(default = "def_false")] pub upright_screen_fix: bool, + + #[serde(default = "def_screens")] + pub show_screens: Vec>, + + #[serde(default = "def_auto")] + pub capture_method: Arc, } impl GeneralConfig { diff --git a/src/overlays/screen.rs b/src/overlays/screen.rs index 652beaf..f007b37 100644 --- a/src/overlays/screen.rs +++ b/src/overlays/screen.rs @@ -246,7 +246,6 @@ impl ScreenRenderer { pub fn new_pw( output: &WlxOutput, token: Option<&str>, - _fallback: bool, ) -> Option<( ScreenRenderer, Option, /* pipewire restore token */ @@ -288,9 +287,18 @@ impl OverlayRenderer for ScreenRenderer { fn init(&mut self, _app: &mut AppState) {} fn render(&mut self, app: &mut AppState) { let receiver = self.receiver.get_or_insert_with(|| { - let _drm_formats = DRM_FORMATS.get_or_init({ + let allow_dmabuf = &*app.session.config.capture_method != "pw_fallback"; + + let drm_formats = DRM_FORMATS.get_or_init({ let graphics = app.graphics.clone(); move || { + if !allow_dmabuf { + log::info!("Using MemFd capture due to pw_fallback"); + return vec![]; + } + log::warn!("Using DMA-buf capture. If screens are blank for you, switch to SHM using:"); + log::warn!("echo 'capture_method: pw_fallback' > ~/.config/wlxoverlay/conf.d/pw_fallback.yaml"); + let possible_formats = [ DRM_FORMAT_ABGR8888.into(), DRM_FORMAT_XBGR8888.into(), @@ -310,6 +318,8 @@ impl OverlayRenderer for ScreenRenderer { modifiers: props .drm_format_modifier_properties .iter() + // important bit: only allow single-plane + .filter(|m| m.drm_format_modifier_plane_count == 1) .map(|m| m.drm_format_modifier) .collect(), }) @@ -318,7 +328,7 @@ impl OverlayRenderer for ScreenRenderer { } }); - let rx = self.capture.init(&[]); // TODO: use drm_formats + let rx = self.capture.init(&drm_formats); self.capture.request_new_frame(); rx }); @@ -333,8 +343,6 @@ impl OverlayRenderer for ScreenRenderer { continue; } if let Some(new) = app.graphics.dmabuf_texture(frame) { - log::info!("{}: New DMA-buf frame", self.name); - let view = ImageView::new_default(new.clone()).unwrap(); self.last_view = Some(view); @@ -455,7 +463,7 @@ where let size = (output.size.0, output.size.1); let mut capture: Option = None; - if session.capture_method == "auto" && wl.maybe_wlr_dmabuf_mgr.is_some() { + if &*session.config.capture_method == "auto" && wl.maybe_wlr_dmabuf_mgr.is_some() { log::info!("{}: Using Wlr DMA-Buf", &output.name); capture = ScreenRenderer::new_wlr(output); } @@ -475,9 +483,7 @@ where ); } - if let Some((renderer, restore_token)) = - ScreenRenderer::new_pw(output, token, session.capture_method == "pw_fallback") - { + if let Some((renderer, restore_token)) = ScreenRenderer::new_pw(output, token) { capture = Some(renderer); if let Some(token) = restore_token { @@ -541,7 +547,11 @@ where state: OverlayState { name: output.name.clone(), size, - want_visible: session.show_screens.iter().any(|s| s == &*output.name), + show_hide: session + .config + .show_screens + .iter() + .any(|s| s.as_ref() == output.name.as_ref()), grabbable: true, recenter: true, interactable: true, @@ -672,7 +682,11 @@ where state: OverlayState { name: s.name.clone(), size, - want_visible: session.show_screens.iter().any(|x| x == &*s.name), + show_hide: session + .config + .show_screens + .iter() + .any(|x| x.as_ref() == s.name.as_ref()), grabbable: true, recenter: true, interactable: true, diff --git a/src/state.rs b/src/state.rs index f82c503..1557c9e 100644 --- a/src/state.rs +++ b/src/state.rs @@ -66,16 +66,12 @@ pub struct AppSession { pub config_root_path: PathBuf, pub config: GeneralConfig, - pub show_screens: Vec, - pub watch_hand: usize, pub watch_pos: Vec3, pub watch_rot: Quat, pub primary_hand: usize, - pub capture_method: String, - pub color_norm: Vec3, pub color_shift: Vec3, pub color_alt: Vec3, @@ -91,8 +87,6 @@ impl AppSession { AppSession { config_root_path, config, - show_screens: vec!["DP-3".to_string()], - capture_method: "auto".to_string(), primary_hand: 1, watch_hand: 0, watch_pos: WATCH_DEFAULT_POS,