zwlr_screencopy v3 support
This commit is contained in:
@@ -178,7 +178,7 @@ impl WvrServerState {
|
||||
// this will throw a compile-time error if smithay's drm-fourcc is out of sync with wlx-capture's
|
||||
let mut formats: Vec<smithay::backend::allocator::Format> = vec![];
|
||||
|
||||
for f in &gfx_extras.drm_formats {
|
||||
for f in &*gfx_extras.drm_formats {
|
||||
formats.push(*f);
|
||||
}
|
||||
|
||||
|
||||
@@ -10,11 +10,14 @@ use vulkano::{
|
||||
VulkanError, VulkanObject,
|
||||
device::Device,
|
||||
format::Format,
|
||||
image::{Image, ImageCreateInfo, ImageTiling, ImageUsage, SubresourceLayout, sys::RawImage},
|
||||
image::{
|
||||
Image, ImageCreateInfo, ImageMemory, ImageTiling, ImageType, ImageUsage, SubresourceLayout,
|
||||
sys::RawImage, view::ImageView,
|
||||
},
|
||||
memory::{
|
||||
DedicatedAllocation, DeviceMemory, ExternalMemoryHandleType, ExternalMemoryHandleTypes,
|
||||
MemoryAllocateInfo, MemoryImportInfo, MemoryPropertyFlags, ResourceMemory,
|
||||
allocator::{MemoryAllocator, MemoryTypeFilter},
|
||||
allocator::{AllocationCreateInfo, MemoryAllocator, MemoryTypeFilter},
|
||||
},
|
||||
sync::Sharing,
|
||||
};
|
||||
@@ -299,6 +302,70 @@ pub(super) unsafe fn create_dmabuf_image(
|
||||
}
|
||||
}
|
||||
|
||||
pub struct ExportedDmabufImage {
|
||||
pub view: Arc<ImageView>,
|
||||
pub fd: std::fs::File,
|
||||
pub offset: u32,
|
||||
pub stride: i32,
|
||||
pub modifier: DrmModifier,
|
||||
}
|
||||
|
||||
pub fn export_dmabuf_image(
|
||||
allocator: Arc<dyn MemoryAllocator>,
|
||||
extent: [u32; 3],
|
||||
format: Format,
|
||||
modifier: DrmModifier,
|
||||
) -> anyhow::Result<ExportedDmabufImage> {
|
||||
let layout = SubresourceLayout {
|
||||
offset: 0,
|
||||
size: 0,
|
||||
row_pitch: align_to(format.block_size() * (extent[0] as u64), 64),
|
||||
array_pitch: None,
|
||||
depth_pitch: None,
|
||||
};
|
||||
|
||||
let image = Image::new(
|
||||
allocator.clone(),
|
||||
ImageCreateInfo {
|
||||
image_type: ImageType::Dim2d,
|
||||
format,
|
||||
extent,
|
||||
usage: ImageUsage::TRANSFER_DST | ImageUsage::TRANSFER_SRC | ImageUsage::SAMPLED,
|
||||
tiling: ImageTiling::DrmFormatModifier,
|
||||
drm_format_modifiers: vec![modifier.into()],
|
||||
drm_format_modifier_plane_layouts: vec![layout],
|
||||
external_memory_handle_types: ExternalMemoryHandleTypes::DMA_BUF,
|
||||
..Default::default()
|
||||
},
|
||||
AllocationCreateInfo {
|
||||
..Default::default()
|
||||
},
|
||||
)
|
||||
.context("Could not create image to export")?;
|
||||
|
||||
let fd = match image.memory() {
|
||||
ImageMemory::Normal(planes) if planes.len() == 1 => {
|
||||
let plane = planes.first().unwrap();
|
||||
plane
|
||||
.device_memory()
|
||||
.export_fd(ExternalMemoryHandleType::DmaBuf)?
|
||||
}
|
||||
_ => anyhow::bail!("Could not export DMA-buf: invalid ImageMemory"),
|
||||
};
|
||||
|
||||
Ok(ExportedDmabufImage {
|
||||
view: ImageView::new_default(image)?,
|
||||
fd,
|
||||
modifier: DrmModifier::from(modifier),
|
||||
offset: layout.offset as _,
|
||||
stride: layout.row_pitch as _,
|
||||
})
|
||||
}
|
||||
|
||||
fn align_to(value: u64, alignment: u64) -> u64 {
|
||||
((value + alignment - 1) / alignment) * alignment
|
||||
}
|
||||
|
||||
pub(super) fn get_drm_formats(device: Arc<Device>) -> Vec<DrmFormat> {
|
||||
let possible_formats = [
|
||||
DrmFourcc::Abgr8888,
|
||||
|
||||
@@ -69,7 +69,7 @@ pub const BLEND_ALPHA: AttachmentBlend = AttachmentBlend {
|
||||
|
||||
pub struct WGfxExtras {
|
||||
pub shaders: HashMap<&'static str, Arc<ShaderModule>>,
|
||||
pub drm_formats: Vec<DrmFormat>,
|
||||
pub drm_formats: Arc<[DrmFormat]>,
|
||||
pub queue_capture: Option<Arc<Queue>>,
|
||||
pub quad_verts: Vert2Buf,
|
||||
pub fallback_image: Arc<ImageView>,
|
||||
@@ -95,7 +95,7 @@ impl WGfxExtras {
|
||||
let shader = frag_screen::load(gfx.device.clone())?;
|
||||
shaders.insert("frag_screen", shader);
|
||||
|
||||
let drm_formats = get_drm_formats(gfx.device.clone());
|
||||
let drm_formats = get_drm_formats(gfx.device.clone()).into();
|
||||
|
||||
let vertices = [
|
||||
Vert2Uv {
|
||||
|
||||
@@ -12,6 +12,7 @@ use crate::{
|
||||
input::{HoverResult, PointerHit, PointerMode},
|
||||
},
|
||||
graphics::ExtentExt,
|
||||
overlays::screen::capture::MyFirstDmaExporter,
|
||||
state::AppState,
|
||||
subsystem::hid::{MOUSE_LEFT, MOUSE_MIDDLE, MOUSE_RIGHT, WheelDelta},
|
||||
windowing::backend::{
|
||||
@@ -41,8 +42,15 @@ fn set_next_move(millis_from_now: u64) {
|
||||
);
|
||||
}
|
||||
|
||||
pub(super) enum CaptureType {
|
||||
PipeWire,
|
||||
ScreenCopy,
|
||||
Xshm,
|
||||
}
|
||||
|
||||
pub struct ScreenBackend {
|
||||
name: Arc<str>,
|
||||
capture_type: CaptureType,
|
||||
capture: Box<dyn WlxCapture<WlxCaptureIn, WlxCaptureOut>>,
|
||||
pipeline: Option<ScreenPipeline>,
|
||||
cur_frame: Option<WlxCaptureOut>,
|
||||
@@ -61,10 +69,12 @@ impl ScreenBackend {
|
||||
pub(super) fn new_raw(
|
||||
name: Arc<str>,
|
||||
xr_backend: XrBackend,
|
||||
capture_type: CaptureType,
|
||||
capture: Box<dyn WlxCapture<WlxCaptureIn, WlxCaptureOut>>,
|
||||
) -> Self {
|
||||
Self {
|
||||
name,
|
||||
capture_type,
|
||||
capture,
|
||||
pipeline: None,
|
||||
cur_frame: None,
|
||||
@@ -151,17 +161,17 @@ impl OverlayBackend for ScreenBackend {
|
||||
|
||||
let allow_dmabuf = !matches!(
|
||||
capture_method,
|
||||
CaptureMethod::PwFallback | CaptureMethod::ScreenCopy
|
||||
CaptureMethod::PipeWireCpu | CaptureMethod::ScreenCopyCpu
|
||||
);
|
||||
|
||||
let dmabuf_formats = if !supports_dmabuf {
|
||||
let (dmabuf_formats, dma_exporter) = if !supports_dmabuf {
|
||||
log::info!("Capture method does not support DMA-buf");
|
||||
if app.gfx_extras.queue_capture.is_none() {
|
||||
log::warn!(
|
||||
"Current GPU does not support multiple queues. Software capture will take place on the main thread. Expect degraded performance."
|
||||
);
|
||||
}
|
||||
&Vec::new()
|
||||
([].as_slice(), None)
|
||||
} else if !allow_dmabuf {
|
||||
log::info!(
|
||||
"Not using DMA-buf capture due to {}",
|
||||
@@ -172,16 +182,25 @@ impl OverlayBackend for ScreenBackend {
|
||||
"Current GPU does not support multiple queues. Software capture will take place on the main thread. Expect degraded performance."
|
||||
);
|
||||
}
|
||||
&Vec::new()
|
||||
([].as_slice(), None)
|
||||
} else {
|
||||
log::warn!(
|
||||
"Using GPU capture. If you're having issues with screens, go to the Dashboard's Settings tab and switch 'Wayland capture method' to a CPU option!"
|
||||
);
|
||||
|
||||
&app.gfx_extras.drm_formats
|
||||
let dma_exporter = if matches!(self.capture_type, CaptureType::ScreenCopy) {
|
||||
Some(MyFirstDmaExporter::new(
|
||||
app.gfx.clone(),
|
||||
app.gfx_extras.drm_formats.clone(),
|
||||
))
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
(&*app.gfx_extras.drm_formats, dma_exporter)
|
||||
};
|
||||
|
||||
let user_data = WlxCaptureIn::new(self.name.clone(), app);
|
||||
let user_data = WlxCaptureIn::new(self.name.clone(), app, dma_exporter);
|
||||
self.capture
|
||||
.init(dmabuf_formats, user_data, receive_callback);
|
||||
self.capture.request_new_frame();
|
||||
|
||||
@@ -1,4 +1,8 @@
|
||||
use std::{f32::consts::PI, sync::Arc};
|
||||
use std::{
|
||||
f32::consts::PI,
|
||||
os::fd::AsRawFd,
|
||||
sync::{Arc, OnceLock},
|
||||
};
|
||||
|
||||
use glam::{Affine3A, Vec3};
|
||||
use smallvec::{SmallVec, smallvec};
|
||||
@@ -8,24 +12,30 @@ use vulkano::{
|
||||
device::Queue,
|
||||
format::Format,
|
||||
image::{Image, sampler::Filter, view::ImageView},
|
||||
memory::{ExternalMemoryHandleTypes, allocator::MemoryAllocator},
|
||||
pipeline::graphics::color_blend::AttachmentBlend,
|
||||
};
|
||||
use wgui::gfx::{
|
||||
WGfx,
|
||||
cmd::WGfxClearMode,
|
||||
pass::WGfxPass,
|
||||
pipeline::{WGfxPipeline, WPipelineCreateInfo},
|
||||
use wgui::{
|
||||
gfx::{
|
||||
WGfx,
|
||||
cmd::WGfxClearMode,
|
||||
memory_allocator,
|
||||
pass::WGfxPass,
|
||||
pipeline::{WGfxPipeline, WPipelineCreateInfo},
|
||||
},
|
||||
log::LogErr,
|
||||
};
|
||||
use wlx_capture::{
|
||||
DrmFormat, WlxCapture,
|
||||
DrmFormat, DrmFourcc, DrmModifier, WlxCapture,
|
||||
frame::{self as wlx_frame, FrameFormat, MouseMeta, WlxFrame},
|
||||
wlr_screencopy::DmaExporter,
|
||||
};
|
||||
use wlx_common::{config::GeneralConfig, overlays::StereoMode};
|
||||
|
||||
use crate::{
|
||||
graphics::{
|
||||
Vert2Uv,
|
||||
dmabuf::{WGfxDmabuf, fourcc_to_vk},
|
||||
ExtentExt, Vert2Uv,
|
||||
dmabuf::{ExportedDmabufImage, WGfxDmabuf, export_dmabuf_image, fourcc_to_vk},
|
||||
upload_quad_vertices,
|
||||
},
|
||||
state::AppState,
|
||||
@@ -343,15 +353,120 @@ fn stereo_mode_to_verts(stereo: StereoMode, array_index: usize) -> [Vert2Uv; 4]
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
static DMA_ALLOCATOR: OnceLock<Arc<dyn MemoryAllocator>> = OnceLock::new();
|
||||
|
||||
pub(super) struct MyFirstDmaExporter {
|
||||
gfx: Arc<WGfx>,
|
||||
drm_formats: Arc<[DrmFormat]>,
|
||||
images: SmallVec<[ExportedDmabufImage; 2]>,
|
||||
fourcc: DrmFourcc,
|
||||
current: usize,
|
||||
}
|
||||
|
||||
impl MyFirstDmaExporter {
|
||||
pub(super) fn new(gfx: Arc<WGfx>, drm_formats: Arc<[DrmFormat]>) -> Self {
|
||||
Self {
|
||||
gfx,
|
||||
drm_formats,
|
||||
images: smallvec![],
|
||||
fourcc: DrmFourcc::Argb8888,
|
||||
current: 0,
|
||||
}
|
||||
}
|
||||
|
||||
fn get_current(&self) -> Option<(Arc<ImageView>, FrameFormat)> {
|
||||
let image = self.images.get(self.current)?;
|
||||
let extent = image.view.extent_u32arr();
|
||||
Some((
|
||||
image.view.clone(),
|
||||
FrameFormat {
|
||||
width: extent[0],
|
||||
height: extent[1],
|
||||
drm_format: DrmFormat {
|
||||
code: self.fourcc,
|
||||
modifier: image.modifier,
|
||||
},
|
||||
transform: wlx_frame::Transform::Undefined,
|
||||
},
|
||||
))
|
||||
}
|
||||
|
||||
fn set_format(
|
||||
&mut self,
|
||||
width: u32,
|
||||
height: u32,
|
||||
fourcc: wlx_capture::DrmFourcc,
|
||||
) -> Option<()> {
|
||||
if let Some(image) = self.images.first() {
|
||||
let extent = image.view.image().extent();
|
||||
if self.fourcc == fourcc && extent[0] == width && extent[1] == height {
|
||||
return Some(());
|
||||
}
|
||||
}
|
||||
self.images.clear();
|
||||
|
||||
let Some(modifier) = self
|
||||
.drm_formats
|
||||
.iter()
|
||||
.filter(|f| f.code == fourcc)
|
||||
.map(|f| f.modifier)
|
||||
.next()
|
||||
else {
|
||||
log::error!("Unsupported format requested: {fourcc}");
|
||||
return None;
|
||||
};
|
||||
|
||||
let format = fourcc_to_vk(fourcc)
|
||||
.log_err("Could not export new dmabuf due to invalid format")
|
||||
.ok()?;
|
||||
|
||||
let allocator = DMA_ALLOCATOR.get_or_init(|| {
|
||||
memory_allocator(
|
||||
self.gfx.device.clone(),
|
||||
Some(ExternalMemoryHandleTypes::DMA_BUF),
|
||||
)
|
||||
});
|
||||
|
||||
for _ in 0..2 {
|
||||
let image =
|
||||
export_dmabuf_image(allocator.clone(), [width, height, 1], format, modifier)
|
||||
.log_err("Could not export DMA-buf image")
|
||||
.ok()?;
|
||||
|
||||
self.images.push(image);
|
||||
}
|
||||
|
||||
Some(())
|
||||
}
|
||||
|
||||
fn next_frame(&mut self) -> Option<(wlx_frame::FramePlane, DrmModifier)> {
|
||||
self.current = 1 - self.current;
|
||||
let image = self.images.get(self.current)?;
|
||||
|
||||
Some((
|
||||
wlx_frame::FramePlane {
|
||||
fd: Some(image.fd.as_raw_fd()),
|
||||
offset: image.offset,
|
||||
stride: image.stride,
|
||||
},
|
||||
image.modifier,
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
pub struct WlxCaptureIn {
|
||||
name: Arc<str>,
|
||||
gfx: Arc<WGfx>,
|
||||
queue: Arc<Queue>,
|
||||
dma_exporter: Option<MyFirstDmaExporter>,
|
||||
}
|
||||
|
||||
impl WlxCaptureIn {
|
||||
pub(super) fn new(name: Arc<str>, app: &AppState) -> Self {
|
||||
pub(super) fn new(
|
||||
name: Arc<str>,
|
||||
app: &AppState,
|
||||
dma_exporter: Option<MyFirstDmaExporter>,
|
||||
) -> Self {
|
||||
Self {
|
||||
name,
|
||||
gfx: app.gfx.clone(),
|
||||
@@ -361,10 +476,24 @@ impl WlxCaptureIn {
|
||||
.as_ref()
|
||||
.unwrap_or_else(|| &app.gfx.queue_xfer)
|
||||
.clone(),
|
||||
dma_exporter,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl DmaExporter for WlxCaptureIn {
|
||||
fn next_frame(
|
||||
&mut self,
|
||||
width: u32,
|
||||
height: u32,
|
||||
fourcc: DrmFourcc,
|
||||
) -> Option<(wlx_frame::FramePlane, DrmModifier)> {
|
||||
let dma_exporter = self.dma_exporter.as_mut()?;
|
||||
dma_exporter.set_format(width, height, fourcc)?;
|
||||
dma_exporter.next_frame()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub(super) struct WlxCaptureOut {
|
||||
pub(super) image: Arc<ImageView>,
|
||||
@@ -501,6 +630,33 @@ pub(super) fn receive_callback(me: &WlxCaptureIn, frame: WlxFrame) -> Option<Wlx
|
||||
mouse: frame.mouse,
|
||||
})
|
||||
}
|
||||
WlxFrame::Implicit => {
|
||||
log::trace!("{}: New Implicit frame", me.name);
|
||||
|
||||
let Some((image, format)) = me.dma_exporter.as_ref().unwrap().get_current() else {
|
||||
log::error!("{}: Implicit frame is missing!", me.name);
|
||||
return None;
|
||||
};
|
||||
|
||||
Some(WlxCaptureOut {
|
||||
image,
|
||||
format,
|
||||
mouse: None,
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// DmaExporter is not used for SHM capture
|
||||
pub(super) struct DummyDrmExporter;
|
||||
impl DmaExporter for DummyDrmExporter {
|
||||
fn next_frame(
|
||||
&mut self,
|
||||
_: u32,
|
||||
_: u32,
|
||||
_: DrmFourcc,
|
||||
) -> Option<(wlx_frame::FramePlane, DrmModifier)> {
|
||||
unreachable!()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -508,7 +664,7 @@ pub(super) fn receive_callback(me: &WlxCaptureIn, frame: WlxFrame) -> Option<Wlx
|
||||
// In this case, receive_callback needs to run on the main thread
|
||||
pub(super) struct MainThreadWlxCapture<T>
|
||||
where
|
||||
T: WlxCapture<(), WlxFrame>,
|
||||
T: WlxCapture<DummyDrmExporter, WlxFrame>,
|
||||
{
|
||||
inner: T,
|
||||
data: Option<WlxCaptureIn>,
|
||||
@@ -516,7 +672,7 @@ where
|
||||
|
||||
impl<T> MainThreadWlxCapture<T>
|
||||
where
|
||||
T: WlxCapture<(), WlxFrame>,
|
||||
T: WlxCapture<DummyDrmExporter, WlxFrame>,
|
||||
{
|
||||
pub const fn new(inner: T) -> Self {
|
||||
Self { inner, data: None }
|
||||
@@ -525,7 +681,7 @@ where
|
||||
|
||||
impl<T> WlxCapture<WlxCaptureIn, WlxCaptureOut> for MainThreadWlxCapture<T>
|
||||
where
|
||||
T: WlxCapture<(), WlxFrame>,
|
||||
T: WlxCapture<DummyDrmExporter, WlxFrame>,
|
||||
{
|
||||
fn init(
|
||||
&mut self,
|
||||
@@ -534,7 +690,8 @@ where
|
||||
_: fn(&WlxCaptureIn, WlxFrame) -> Option<WlxCaptureOut>,
|
||||
) {
|
||||
self.data = Some(user_data);
|
||||
self.inner.init(dmabuf_formats, (), receive_callback_dummy);
|
||||
self.inner
|
||||
.init(dmabuf_formats, DummyDrmExporter, receive_callback_dummy);
|
||||
}
|
||||
fn is_ready(&self) -> bool {
|
||||
self.inner.is_ready()
|
||||
@@ -559,7 +716,7 @@ where
|
||||
}
|
||||
|
||||
#[allow(clippy::trivially_copy_pass_by_ref, clippy::unnecessary_wraps)]
|
||||
const fn receive_callback_dummy(_: &(), frame: WlxFrame) -> Option<WlxFrame> {
|
||||
const fn receive_callback_dummy(_: &DummyDrmExporter, frame: WlxFrame) -> Option<WlxFrame> {
|
||||
Some(frame)
|
||||
}
|
||||
|
||||
|
||||
@@ -22,7 +22,10 @@ use crate::{
|
||||
input::{HoverResult, PointerHit},
|
||||
task::{OverlayTask, TaskType, ToggleMode},
|
||||
},
|
||||
overlays::screen::capture::{MainThreadWlxCapture, new_wlx_capture},
|
||||
overlays::screen::{
|
||||
backend::CaptureType,
|
||||
capture::{MainThreadWlxCapture, new_wlx_capture},
|
||||
},
|
||||
state::{AppSession, AppState},
|
||||
subsystem::hid::WheelDelta,
|
||||
windowing::{
|
||||
@@ -94,6 +97,7 @@ impl OverlayBackend for MirrorBackend {
|
||||
self.renderer = Some(ScreenBackend::new_raw(
|
||||
self.name.clone(),
|
||||
app.xr_backend,
|
||||
CaptureType::PipeWire,
|
||||
capture,
|
||||
));
|
||||
app.tasks
|
||||
|
||||
@@ -25,6 +25,8 @@ impl ScreenBackend {
|
||||
token: Option<&str>,
|
||||
app: &mut AppState,
|
||||
) -> anyhow::Result<(Self, Option<String> /* pipewire restore token */)> {
|
||||
use crate::overlays::screen::backend::CaptureType;
|
||||
|
||||
let name = output.name.clone();
|
||||
let embed_mouse = !app.session.config.double_cursor_fix;
|
||||
|
||||
@@ -57,7 +59,12 @@ impl ScreenBackend {
|
||||
PipewireCapture::new(name, node_id)
|
||||
);
|
||||
Ok((
|
||||
Self::new_raw(output.name.clone(), app.xr_backend, capture),
|
||||
Self::new_raw(
|
||||
output.name.clone(),
|
||||
app.xr_backend,
|
||||
CaptureType::PipeWire,
|
||||
capture,
|
||||
),
|
||||
select_screen_result.restore_token,
|
||||
))
|
||||
}
|
||||
|
||||
@@ -3,7 +3,6 @@ use wlx_capture::{
|
||||
WlxCapture,
|
||||
frame::Transform,
|
||||
wayland::{WlxClient, WlxOutput},
|
||||
wlr_dmabuf::WlrDmabufCapture,
|
||||
wlr_screencopy::WlrScreencopyCapture,
|
||||
};
|
||||
use wlx_common::{
|
||||
@@ -12,7 +11,7 @@ use wlx_common::{
|
||||
};
|
||||
|
||||
use crate::{
|
||||
overlays::screen::create_screen_from_backend,
|
||||
overlays::screen::{backend::CaptureType, create_screen_from_backend},
|
||||
state::{AppState, ScreenMeta},
|
||||
};
|
||||
|
||||
@@ -24,22 +23,18 @@ use super::{
|
||||
};
|
||||
|
||||
impl ScreenBackend {
|
||||
pub fn new_wlr_dmabuf(output: &WlxOutput, app: &AppState) -> Option<Self> {
|
||||
let client = WlxClient::new()?;
|
||||
let capture = new_wlx_capture!(
|
||||
app.gfx_extras.queue_capture,
|
||||
WlrDmabufCapture::new(client, output.id)
|
||||
);
|
||||
Some(Self::new_raw(output.name.clone(), app.xr_backend, capture))
|
||||
}
|
||||
|
||||
pub fn new_wlr_screencopy(output: &WlxOutput, app: &AppState) -> Option<Self> {
|
||||
let client = WlxClient::new()?;
|
||||
let capture = new_wlx_capture!(
|
||||
app.gfx_extras.queue_capture,
|
||||
WlrScreencopyCapture::new(client, output.id)
|
||||
);
|
||||
Some(Self::new_raw(output.name.clone(), app.xr_backend, capture))
|
||||
Some(Self::new_raw(
|
||||
output.name.clone(),
|
||||
app.xr_backend,
|
||||
CaptureType::ScreenCopy,
|
||||
capture,
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -52,9 +47,12 @@ pub fn create_screen_renderer_wl(
|
||||
) -> Option<ScreenBackend> {
|
||||
let mut capture: Option<ScreenBackend> = None;
|
||||
|
||||
if matches!(app.session.config.capture_method, CaptureMethod::ScreenCopy) && has_wlr_screencopy
|
||||
if matches!(
|
||||
app.session.config.capture_method,
|
||||
CaptureMethod::ScreenCopyCpu | CaptureMethod::ScreenCopyGpu | CaptureMethod::Auto
|
||||
) && has_wlr_screencopy
|
||||
{
|
||||
log::info!("{}: Using Wlr Screencopy Wl-SHM", &output.name);
|
||||
log::info!("{}: Using ScreenCopy capture", &output.name);
|
||||
capture = ScreenBackend::new_wlr_screencopy(output, app);
|
||||
}
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ use wlx_capture::{
|
||||
};
|
||||
|
||||
use crate::{
|
||||
overlays::screen::create_screen_from_backend,
|
||||
overlays::screen::{backend::CaptureType, create_screen_from_backend},
|
||||
state::{AppState, ScreenMeta},
|
||||
};
|
||||
|
||||
@@ -27,7 +27,12 @@ impl ScreenBackend {
|
||||
app.gfx_extras.queue_capture,
|
||||
XshmCapture::new(screen.clone())
|
||||
);
|
||||
Self::new_raw(screen.name.clone(), app.xr_backend, capture)
|
||||
Self::new_raw(
|
||||
screen.name.clone(),
|
||||
app.xr_backend,
|
||||
CaptureType::Xshm,
|
||||
capture,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -97,6 +102,7 @@ pub fn create_screens_x11pw(app: &mut AppState) -> anyhow::Result<ScreenCreateDa
|
||||
let mut backend = ScreenBackend::new_raw(
|
||||
m.name.clone(),
|
||||
app.xr_backend,
|
||||
CaptureType::PipeWire,
|
||||
new_wlx_capture!(
|
||||
app.gfx_extras.queue_capture,
|
||||
PipewireCapture::new(m.name.clone(), s.node_id)
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
use chrono_tz::PST8PDT;
|
||||
use glam::{Affine2, Affine3A, Quat, Vec2, Vec3, vec2, vec3};
|
||||
use smithay::{
|
||||
desktop::PopupManager,
|
||||
|
||||
Reference in New Issue
Block a user