pipewire: dmabuf capture !!!
This commit is contained in:
2
Cargo.lock
generated
2
Cargo.lock
generated
@@ -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",
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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 {
|
||||||
|
|||||||
@@ -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,
|
||||||
|
|||||||
@@ -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,
|
||||||
|
|||||||
Reference in New Issue
Block a user