pipewire: dmabuf capture !!!

This commit is contained in:
galister
2024-02-17 12:32:23 +01:00
parent d42c0ef670
commit 5bbaf59790
5 changed files with 51 additions and 21 deletions

2
Cargo.lock generated
View File

@@ -4280,7 +4280,7 @@ dependencies = [
[[package]] [[package]]
name = "wlx-capture" name = "wlx-capture"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/galister/wlx-capture#c91b249d29319f4c5882abee5e911d84943aa6da" source = "git+https://github.com/galister/wlx-capture#332dd363357a845e4107aaada9a67899e7398839"
dependencies = [ dependencies = [
"ashpd", "ashpd",
"drm-fourcc", "drm-fourcc",

View File

@@ -55,12 +55,18 @@ where
keyboard.state.want_visible = false; keyboard.state.want_visible = false;
overlays.insert(keyboard.state.id, keyboard); 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 { for mut screen in screens {
if first { if show_screens.contains(&screen.state.name) {
screen.state.show_hide = true; screen.state.show_hide = true;
screen.state.want_visible = false; screen.state.want_visible = false;
first = false;
} }
overlays.insert(screen.state.id, screen); overlays.insert(screen.state.id, screen);
} }

View File

@@ -1,3 +1,5 @@
use std::sync::Arc;
use crate::config_io; use crate::config_io;
use crate::config_io::get_conf_d_path; use crate::config_io::get_conf_d_path;
use crate::load_with_fallback; use crate::load_with_fallback;
@@ -39,6 +41,14 @@ fn def_osc_port() -> u16 {
9000 9000
} }
fn def_screens() -> Vec<Arc<str>> {
vec![]
}
fn def_auto() -> Arc<str> {
"auto".into()
}
#[derive(Deserialize, Serialize)] #[derive(Deserialize, Serialize)]
pub struct GeneralConfig { pub struct GeneralConfig {
#[serde(default = "def_click_freeze_time_ms")] #[serde(default = "def_click_freeze_time_ms")]
@@ -70,6 +80,12 @@ pub struct GeneralConfig {
#[serde(default = "def_false")] #[serde(default = "def_false")]
pub upright_screen_fix: bool, pub upright_screen_fix: bool,
#[serde(default = "def_screens")]
pub show_screens: Vec<Arc<str>>,
#[serde(default = "def_auto")]
pub capture_method: Arc<str>,
} }
impl GeneralConfig { impl GeneralConfig {

View File

@@ -246,7 +246,6 @@ impl ScreenRenderer {
pub fn new_pw( pub fn new_pw(
output: &WlxOutput, output: &WlxOutput,
token: Option<&str>, token: Option<&str>,
_fallback: bool,
) -> Option<( ) -> Option<(
ScreenRenderer, ScreenRenderer,
Option<String>, /* pipewire restore token */ Option<String>, /* pipewire restore token */
@@ -288,9 +287,18 @@ impl OverlayRenderer for ScreenRenderer {
fn init(&mut self, _app: &mut AppState) {} fn init(&mut self, _app: &mut AppState) {}
fn render(&mut self, app: &mut AppState) { fn render(&mut self, app: &mut AppState) {
let receiver = self.receiver.get_or_insert_with(|| { 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(); let graphics = app.graphics.clone();
move || { 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 = [ let possible_formats = [
DRM_FORMAT_ABGR8888.into(), DRM_FORMAT_ABGR8888.into(),
DRM_FORMAT_XBGR8888.into(), DRM_FORMAT_XBGR8888.into(),
@@ -310,6 +318,8 @@ impl OverlayRenderer for ScreenRenderer {
modifiers: props modifiers: props
.drm_format_modifier_properties .drm_format_modifier_properties
.iter() .iter()
// important bit: only allow single-plane
.filter(|m| m.drm_format_modifier_plane_count == 1)
.map(|m| m.drm_format_modifier) .map(|m| m.drm_format_modifier)
.collect(), .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(); self.capture.request_new_frame();
rx rx
}); });
@@ -333,8 +343,6 @@ impl OverlayRenderer for ScreenRenderer {
continue; continue;
} }
if let Some(new) = app.graphics.dmabuf_texture(frame) { 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(); let view = ImageView::new_default(new.clone()).unwrap();
self.last_view = Some(view); self.last_view = Some(view);
@@ -455,7 +463,7 @@ where
let size = (output.size.0, output.size.1); let size = (output.size.0, output.size.1);
let mut capture: Option<ScreenRenderer> = None; let mut capture: Option<ScreenRenderer> = 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); log::info!("{}: Using Wlr DMA-Buf", &output.name);
capture = ScreenRenderer::new_wlr(output); capture = ScreenRenderer::new_wlr(output);
} }
@@ -475,9 +483,7 @@ where
); );
} }
if let Some((renderer, restore_token)) = if let Some((renderer, restore_token)) = ScreenRenderer::new_pw(output, token) {
ScreenRenderer::new_pw(output, token, session.capture_method == "pw_fallback")
{
capture = Some(renderer); capture = Some(renderer);
if let Some(token) = restore_token { if let Some(token) = restore_token {
@@ -541,7 +547,11 @@ where
state: OverlayState { state: OverlayState {
name: output.name.clone(), name: output.name.clone(),
size, 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, grabbable: true,
recenter: true, recenter: true,
interactable: true, interactable: true,
@@ -672,7 +682,11 @@ where
state: OverlayState { state: OverlayState {
name: s.name.clone(), name: s.name.clone(),
size, 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, grabbable: true,
recenter: true, recenter: true,
interactable: true, interactable: true,

View File

@@ -66,16 +66,12 @@ pub struct AppSession {
pub config_root_path: PathBuf, pub config_root_path: PathBuf,
pub config: GeneralConfig, pub config: GeneralConfig,
pub show_screens: Vec<String>,
pub watch_hand: usize, pub watch_hand: usize,
pub watch_pos: Vec3, pub watch_pos: Vec3,
pub watch_rot: Quat, pub watch_rot: Quat,
pub primary_hand: usize, pub primary_hand: usize,
pub capture_method: String,
pub color_norm: Vec3, pub color_norm: Vec3,
pub color_shift: Vec3, pub color_shift: Vec3,
pub color_alt: Vec3, pub color_alt: Vec3,
@@ -91,8 +87,6 @@ impl AppSession {
AppSession { AppSession {
config_root_path, config_root_path,
config, config,
show_screens: vec!["DP-3".to_string()],
capture_method: "auto".to_string(),
primary_hand: 1, primary_hand: 1,
watch_hand: 0, watch_hand: 0,
watch_pos: WATCH_DEFAULT_POS, watch_pos: WATCH_DEFAULT_POS,