From 4074cee36504231cacd59a27979dfc201a85efc8 Mon Sep 17 00:00:00 2001 From: kossLAN Date: Fri, 29 May 2026 21:48:05 -0400 Subject: [PATCH] tree: split output captures --- src/tree/output.rs | 161 +--------------------------------- src/tree/output/captures.rs | 168 ++++++++++++++++++++++++++++++++++++ 2 files changed, 169 insertions(+), 160 deletions(-) create mode 100644 src/tree/output/captures.rs diff --git a/src/tree/output.rs b/src/tree/output.rs index b3b2f8d4..bf12bc48 100644 --- a/src/tree/output.rs +++ b/src/tree/output.rs @@ -1,3 +1,4 @@ +mod captures; mod policy; mod render_data; mod workspaces; @@ -18,14 +19,11 @@ use { HardwareCursor, Mode, transaction::BackendConnectorTransactionError, }, client::ClientId, - cmm::cmm_description::ColorDescription, cursor::KnownCursor, fixed::Fixed, - gfx_api::{AcquireSync, BufferResv, GfxTexture, ReleaseSync}, ifs::{ ext_image_copy::ext_image_copy_capture_session_v1::ExtImageCopyCaptureSessionV1, jay_output::JayOutput, - wl_buffer::WlBufferStorage, wl_output::{BlendSpace, WlOutputGlobal}, wl_seat::{ BTN_LEFT, NodeSeatState, SeatId, WlSeatGlobal, @@ -69,7 +67,6 @@ use { copyhashmap::CopyHashMap, errorfmt::ErrorFmt, event_listener::{EventSource, LazyEventSource}, - hash_map_ext::HashMapExt, linkedlist::LinkedList, on_drop_event::OnDropEvent, scroller::Scroller, @@ -279,162 +276,6 @@ impl OutputNode { } } - pub fn captures_changed(&self) { - for ws in self.workspaces.iter() { - ws.update_has_captures(); - } - } - - pub fn perform_screencopies( - &self, - tex: &Rc, - cd: &Rc, - resv: Option<&Rc>, - acquire_sync: &AcquireSync, - release_sync: ReleaseSync, - render_hardware_cursor: bool, - x_off: i32, - y_off: i32, - size: Option<(i32, i32)>, - ) { - if let Some(workspace) = self.workspace.get() { - if !workspace.may_capture.get() { - return; - } - } - self.perform_wlr_screencopies( - tex, - cd, - resv, - acquire_sync, - release_sync, - render_hardware_cursor, - x_off, - y_off, - size, - ); - for sc in self.ext_copy_sessions.lock().values() { - sc.copy_texture( - self, - tex, - cd, - resv, - acquire_sync, - release_sync, - render_hardware_cursor, - x_off, - y_off, - size, - ); - } - } - - pub fn perform_wlr_screencopies( - &self, - tex: &Rc, - cd: &Rc, - resv: Option<&Rc>, - acquire_sync: &AcquireSync, - release_sync: ReleaseSync, - render_hardware_cursors: bool, - x_off: i32, - y_off: i32, - size: Option<(i32, i32)>, - ) { - if self.screencopies.is_empty() { - return; - } - let now = self.state.now(); - for capture in self.screencopies.lock().drain_values() { - let wl_buffer = match capture.buffer.take() { - Some(b) => b, - _ => { - log::warn!("Capture frame is pending but has no buffer attached"); - capture.send_failed(); - continue; - } - }; - if wl_buffer.destroyed() { - capture.send_failed(); - continue; - } - let mut ready = true; - if let Some(storage) = wl_buffer.storage.borrow_mut().deref() { - match storage { - WlBufferStorage::Shm { mem, stride, .. } => { - let res = self.state.perform_shm_screencopy( - tex, - cd, - acquire_sync, - self.global.pos.get(), - x_off, - y_off, - size, - &capture, - mem, - *stride, - wl_buffer.format, - self.global.persistent.transform.get(), - self.global.persistent.scale.get(), - ); - match res { - Ok(p) => { - ready = p.is_none(); - capture.pending.set(p); - } - Err(e) => { - log::warn!("Could not perform shm screencopy: {}", ErrorFmt(e)); - capture.send_failed(); - continue; - } - } - } - WlBufferStorage::Dmabuf { fb, .. } => { - let fb = match fb { - Some(fb) => fb, - _ => { - log::warn!("Capture buffer has no framebuffer"); - capture.send_failed(); - continue; - } - }; - let res = self.state.perform_screencopy( - tex, - resv, - acquire_sync, - release_sync, - cd, - &fb, - AcquireSync::Implicit, - ReleaseSync::Implicit, - self.global.persistent.transform.get(), - self.state.color_manager.srgb_gamma22(), - self.global.pos.get(), - render_hardware_cursors, - x_off - capture.rect.x1(), - y_off - capture.rect.y1(), - size, - self.global.persistent.transform.get(), - self.global.persistent.scale.get(), - ); - if let Err(e) = res { - log::warn!("Could not perform screencopy: {}", ErrorFmt(e)); - capture.send_failed(); - continue; - } - } - } - } - if capture.with_damage.get() { - capture.send_damage(); - } - if ready { - capture.send_ready(now.0.tv_sec as _, now.0.tv_nsec as _); - } - } - self.captures_changed(); - } - pub fn clear(&self) { self.global.clear(); self.workspace.set(None); diff --git a/src/tree/output/captures.rs b/src/tree/output/captures.rs new file mode 100644 index 00000000..2fa93119 --- /dev/null +++ b/src/tree/output/captures.rs @@ -0,0 +1,168 @@ +use { + super::OutputNode, + crate::{ + cmm::cmm_description::ColorDescription, + gfx_api::{AcquireSync, BufferResv, GfxTexture, ReleaseSync}, + ifs::wl_buffer::WlBufferStorage, + utils::{errorfmt::ErrorFmt, hash_map_ext::HashMapExt}, + }, + std::{ops::Deref, rc::Rc}, +}; + +impl OutputNode { + pub fn captures_changed(&self) { + for ws in self.workspaces.iter() { + ws.update_has_captures(); + } + } + + pub fn perform_screencopies( + &self, + tex: &Rc, + cd: &Rc, + resv: Option<&Rc>, + acquire_sync: &AcquireSync, + release_sync: ReleaseSync, + render_hardware_cursor: bool, + x_off: i32, + y_off: i32, + size: Option<(i32, i32)>, + ) { + if let Some(workspace) = self.workspace.get() { + if !workspace.may_capture.get() { + return; + } + } + self.perform_wlr_screencopies( + tex, + cd, + resv, + acquire_sync, + release_sync, + render_hardware_cursor, + x_off, + y_off, + size, + ); + for sc in self.ext_copy_sessions.lock().values() { + sc.copy_texture( + self, + tex, + cd, + resv, + acquire_sync, + release_sync, + render_hardware_cursor, + x_off, + y_off, + size, + ); + } + } + + pub fn perform_wlr_screencopies( + &self, + tex: &Rc, + cd: &Rc, + resv: Option<&Rc>, + acquire_sync: &AcquireSync, + release_sync: ReleaseSync, + render_hardware_cursors: bool, + x_off: i32, + y_off: i32, + size: Option<(i32, i32)>, + ) { + if self.screencopies.is_empty() { + return; + } + let now = self.state.now(); + for capture in self.screencopies.lock().drain_values() { + let wl_buffer = match capture.buffer.take() { + Some(b) => b, + _ => { + log::warn!("Capture frame is pending but has no buffer attached"); + capture.send_failed(); + continue; + } + }; + if wl_buffer.destroyed() { + capture.send_failed(); + continue; + } + let mut ready = true; + if let Some(storage) = wl_buffer.storage.borrow_mut().deref() { + match storage { + WlBufferStorage::Shm { mem, stride, .. } => { + let res = self.state.perform_shm_screencopy( + tex, + cd, + acquire_sync, + self.global.pos.get(), + x_off, + y_off, + size, + &capture, + mem, + *stride, + wl_buffer.format, + self.global.persistent.transform.get(), + self.global.persistent.scale.get(), + ); + match res { + Ok(p) => { + ready = p.is_none(); + capture.pending.set(p); + } + Err(e) => { + log::warn!("Could not perform shm screencopy: {}", ErrorFmt(e)); + capture.send_failed(); + continue; + } + } + } + WlBufferStorage::Dmabuf { fb, .. } => { + let fb = match fb { + Some(fb) => fb, + _ => { + log::warn!("Capture buffer has no framebuffer"); + capture.send_failed(); + continue; + } + }; + let res = self.state.perform_screencopy( + tex, + resv, + acquire_sync, + release_sync, + cd, + &fb, + AcquireSync::Implicit, + ReleaseSync::Implicit, + self.global.persistent.transform.get(), + self.state.color_manager.srgb_gamma22(), + self.global.pos.get(), + render_hardware_cursors, + x_off - capture.rect.x1(), + y_off - capture.rect.y1(), + size, + self.global.persistent.transform.get(), + self.global.persistent.scale.get(), + ); + if let Err(e) = res { + log::warn!("Could not perform screencopy: {}", ErrorFmt(e)); + capture.send_failed(); + continue; + } + } + } + } + if capture.with_damage.get() { + capture.send_damage(); + } + if ready { + capture.send_ready(now.0.tv_sec as _, now.0.tv_nsec as _); + } + } + self.captures_changed(); + } +}