apply pipewire transforms to screens

This commit is contained in:
galister
2024-11-19 15:38:28 +09:00
parent a3f9f7cc46
commit e23444aa89
12 changed files with 875 additions and 700 deletions

View File

@@ -7,7 +7,7 @@ use std::{
use crate::{
backend::{
input::{InteractionHandler, PointerMode},
overlay::{OverlayBackend, OverlayData, OverlayRenderer, OverlayState},
overlay::{FrameTransform, OverlayBackend, OverlayData, OverlayRenderer, OverlayState},
},
config::{self, ConfigType},
gui::{
@@ -533,8 +533,8 @@ impl OverlayRenderer for KeyboardBackend {
fn render(&mut self, app: &mut AppState) -> anyhow::Result<()> {
self.canvas.render(app)
}
fn extent(&mut self) -> Option<[u32; 3]> {
self.canvas.extent()
fn frame_transform(&mut self) -> Option<FrameTransform> {
self.canvas.frame_transform()
}
fn view(&mut self) -> Option<std::sync::Arc<vulkano::image::view::ImageView>> {
self.canvas.view()

View File

@@ -10,7 +10,8 @@ use crate::{
backend::{
common::OverlaySelector,
overlay::{
ui_transform, OverlayBackend, OverlayRenderer, OverlayState, SplitOverlayBackend,
ui_transform, FrameTransform, OverlayBackend, OverlayRenderer, OverlayState,
SplitOverlayBackend,
},
task::TaskType,
},
@@ -121,8 +122,11 @@ impl OverlayRenderer for MirrorRenderer {
self.renderer.as_mut().and_then(|r| r.view())
}
fn extent(&mut self) -> Option<[u32; 3]> {
Some(self.last_extent)
fn frame_transform(&mut self) -> Option<FrameTransform> {
Some(FrameTransform {
extent: self.last_extent,
..Default::default()
})
}
}

View File

@@ -13,6 +13,8 @@ use vulkano::{
image::{sampler::Filter, view::ImageView, Image},
pipeline::graphics::color_blend::AttachmentBlend,
};
use wlx_capture::frame as wlx_frame;
use wlx_capture::{
frame::{
DrmFormat, FrameFormat, MouseMeta, WlxFrame, DRM_FORMAT_ABGR2101010, DRM_FORMAT_ABGR8888,
@@ -46,12 +48,12 @@ use {
#[cfg(feature = "x11")]
use wlx_capture::xshm::{XshmCapture, XshmScreen};
use glam::{vec2, vec3a, Affine2, Quat, Vec2, Vec3};
use glam::{vec2, vec3a, Affine2, Affine3A, Quat, Vec2, Vec3};
use crate::{
backend::{
input::{Haptics, InteractionHandler, PointerHit, PointerMode},
overlay::{OverlayRenderer, OverlayState, SplitOverlayBackend},
overlay::{FrameTransform, OverlayRenderer, OverlayState, SplitOverlayBackend},
},
config::{def_pw_tokens, GeneralConfig, PwTokenMap},
graphics::{
@@ -284,6 +286,7 @@ pub struct ScreenRenderer {
capture: Box<dyn WlxCapture>,
pipeline: Option<ScreenPipeline>,
last_view: Option<Arc<ImageView>>,
transform: Affine3A,
extent: Option<[u32; 3]>,
}
@@ -295,6 +298,7 @@ impl ScreenRenderer {
capture,
pipeline: None,
last_view: None,
transform: Affine3A::IDENTITY,
extent: None,
}
}
@@ -309,6 +313,7 @@ impl ScreenRenderer {
capture: Box::new(capture),
pipeline: None,
last_view: None,
transform: Affine3A::IDENTITY,
extent: None,
})
}
@@ -323,6 +328,7 @@ impl ScreenRenderer {
capture: Box::new(capture),
pipeline: None,
last_view: None,
transform: Affine3A::IDENTITY,
extent: None,
})
}
@@ -365,6 +371,7 @@ impl ScreenRenderer {
capture: Box::new(capture),
pipeline: None,
last_view: None,
transform: Affine3A::IDENTITY,
extent: None,
},
select_screen_result.restore_token,
@@ -380,6 +387,7 @@ impl ScreenRenderer {
capture: Box::new(capture),
pipeline: None,
last_view: None,
transform: Affine3A::IDENTITY,
extent: None,
}
}
@@ -469,6 +477,7 @@ impl OverlayRenderer for ScreenRenderer {
continue;
}
self.extent.get_or_insert_with(|| {
self.transform = affine_from_format(&frame.format);
extent_from_format(frame.format, &app.session.config)
});
match app.graphics.dmabuf_texture(frame) {
@@ -511,6 +520,7 @@ impl OverlayRenderer for ScreenRenderer {
continue;
};
self.extent.get_or_insert_with(|| {
self.transform = affine_from_format(&frame.format);
extent_from_format(frame.format, &app.session.config)
});
log::debug!("{}: New MemFd frame", self.name);
@@ -601,8 +611,11 @@ impl OverlayRenderer for ScreenRenderer {
fn view(&mut self) -> Option<Arc<ImageView>> {
self.last_view.clone()
}
fn extent(&mut self) -> Option<[u32; 3]> {
self.extent
fn frame_transform(&mut self) -> Option<FrameTransform> {
self.extent.map(|extent| FrameTransform {
extent,
transform: self.transform,
})
}
}
@@ -771,16 +784,10 @@ pub fn create_screens_wayland(
wl: &mut WlxClientAlias,
app: &mut AppState,
) -> anyhow::Result<ScreenCreateData> {
use crate::config::AStrMap;
let mut screens = vec![];
// Load existing Pipewire tokens from file
let mut pw_tokens: PwTokenMap = if let Ok(conf) = load_pw_token_config() {
conf
} else {
AStrMap::new()
};
let mut pw_tokens: PwTokenMap = load_pw_token_config().unwrap_or_default();
let pw_tokens_copy = pw_tokens.clone();
let has_wlr_dmabuf = wl.maybe_wlr_dmabuf_mgr.is_some();
@@ -857,15 +864,10 @@ pub fn create_screens_x11pw(_app: &mut AppState) -> anyhow::Result<ScreenCreateD
#[cfg(all(feature = "x11", feature = "pipewire"))]
pub fn create_screens_x11pw(app: &mut AppState) -> anyhow::Result<ScreenCreateData> {
use crate::config::{AStrMap, AStrMapExt};
use anyhow::bail;
// Load existing Pipewire tokens from file
let mut pw_tokens: PwTokenMap = if let Ok(conf) = load_pw_token_config() {
conf
} else {
AStrMap::new()
};
let mut pw_tokens: PwTokenMap = load_pw_token_config().unwrap_or_default();
let pw_tokens_copy = pw_tokens.clone();
let token = pw_tokens.arc_get("x11").map(|s| s.as_str());
let embed_mouse = !app.session.config.double_cursor_fix;
@@ -931,6 +933,7 @@ pub fn create_screens_x11pw(app: &mut AppState) -> anyhow::Result<ScreenCreateDa
capture: Box::new(PipewireCapture::new(m.name.clone(), s.node_id)),
pipeline: None,
last_view: None,
transform: Affine3A::IDENTITY,
extent: Some(extent_from_res(
size.0 as _,
size.1 as _,
@@ -1050,6 +1053,31 @@ fn extent_from_res(width: u32, height: u32, config: &GeneralConfig) -> [u32; 3]
[w, h, 1]
}
fn affine_from_format(format: &FrameFormat) -> Affine3A {
const FLIP_X: Vec3 = Vec3 {
x: -1.0,
y: 1.0,
z: 1.0,
};
match format.transform {
wlx_frame::Transform::None => Affine3A::IDENTITY,
wlx_frame::Transform::Rotated90 => Affine3A::from_rotation_z(PI / 2.0),
wlx_frame::Transform::Rotated180 => Affine3A::from_rotation_z(PI),
wlx_frame::Transform::Rotated270 => Affine3A::from_rotation_z(-PI / 2.0),
wlx_frame::Transform::Flipped => Affine3A::from_scale(FLIP_X),
wlx_frame::Transform::Flipped90 => {
Affine3A::from_scale(FLIP_X) * Affine3A::from_rotation_z(PI / 2.0)
}
wlx_frame::Transform::Flipped180 => {
Affine3A::from_scale(FLIP_X) * Affine3A::from_rotation_z(PI)
}
wlx_frame::Transform::Flipped270 => {
Affine3A::from_scale(FLIP_X) * Affine3A::from_rotation_z(-PI / 2.0)
}
}
}
#[cfg(all(feature = "pipewire", feature = "x11"))]
fn best_match<'a>(
stream: &PipewireStream,

View File

@@ -9,7 +9,7 @@ use crate::{
common::{OverlayContainer, OverlaySelector},
input::{self, InteractionHandler},
overlay::{
ui_transform, OverlayData, OverlayID, OverlayRenderer, OverlayState,
ui_transform, FrameTransform, OverlayData, OverlayID, OverlayRenderer, OverlayState,
SplitOverlayBackend,
},
task::TaskType,
@@ -299,6 +299,7 @@ impl WayVRRenderer {
value: data.mod_info.fourcc,
},
modifier: data.mod_info.modifiers[0], /* possibly not proper? */
..Default::default()
},
num_planes: 1,
planes,
@@ -373,8 +374,11 @@ impl OverlayRenderer for WayVRRenderer {
self.view.clone()
}
fn extent(&mut self) -> Option<[u32; 3]> {
self.view.as_ref().map(|view| view.image().extent())
fn frame_transform(&mut self) -> Option<FrameTransform> {
self.view.as_ref().map(|view| FrameTransform {
extent: view.image().extent(),
..Default::default()
})
}
}