diff --git a/src/backend/wayland/buffer.rs b/src/backend/wayland/buffer.rs index 7973790..ce91d51 100644 --- a/src/backend/wayland/buffer.rs +++ b/src/backend/wayland/buffer.rs @@ -1,5 +1,5 @@ use cctk::{ - screencopy::Formats, + screencopy::{Formats, Rect}, wayland_client::{ Connection, Dispatch, QueueHandle, protocol::{wl_buffer, wl_shm, wl_shm_pool}, @@ -20,6 +20,7 @@ use crate::utils; pub struct Buffer { pub backing: Arc, pub buffer: wl_buffer::WlBuffer, + pub buffer_damage: Vec, pub size: (u32, u32), #[cfg(feature = "no-subsurfaces")] pub mmap: memmap2::Mmap, @@ -52,6 +53,13 @@ impl AppData { #[cfg(feature = "no-subsurfaces")] let mmap = unsafe { memmap2::Mmap::map(&fd).unwrap() }; + let full_damage = vec![Rect { + x: 0, + y: 0, + width: width as i32, + height: height as i32, + }]; + Buffer { backing: Arc::new( Shmbuf { @@ -65,6 +73,7 @@ impl AppData { .into(), ), buffer, + buffer_damage: full_damage, #[cfg(feature = "no-subsurfaces")] mmap, size: (width, height), @@ -148,6 +157,13 @@ impl AppData { ) .0; + let full_damage = vec![Rect { + x: 0, + y: 0, + width: width as i32, + height: height as i32, + }]; + Ok(Some(Buffer { backing: Arc::new( Dmabuf { @@ -160,6 +176,7 @@ impl AppData { .into(), ), buffer, + buffer_damage: full_damage, size: (width, height), })) } diff --git a/src/backend/wayland/screencopy.rs b/src/backend/wayland/screencopy.rs index 1594720..adf1c3f 100644 --- a/src/backend/wayland/screencopy.rs +++ b/src/backend/wayland/screencopy.rs @@ -19,10 +19,13 @@ use std::{ use super::{AppData, Buffer, Capture, CaptureImage, Event}; +// Number of buffers to swap between +const BUFFER_COUNT: usize = 2; + pub struct ScreencopySession { formats: Option, // swapchain buffers - buffers: Option<[Buffer; 2]>, + buffers: Option<[Buffer; BUFFER_COUNT]>, session: CaptureSession, // Future signaled when buffer is signaled. // if triple buffer is used, will need more than one. @@ -66,18 +69,9 @@ impl ScreencopySession { // TODO // let node = back.node().and_then(|x| x.to_str().map(|x| x.to_string())); - // TODO: accumulate damage - let (width, height) = back.size; - let full_damage = &[Rect { - x: 0, - y: 0, - width: width as i32, - height: height as i32, - }]; - self.session.capture( &back.buffer, - full_damage, + &back.buffer_damage, qh, FrameData { frame_data: Default::default(), @@ -182,7 +176,13 @@ impl ScreencopyHandler for AppData { session.attach_buffer_and_commit(&capture_clone, &conn, &qh); }); - let front = session.buffers.as_mut().unwrap().first_mut().unwrap(); + // Clear `buffer_damage` for front buffer; accumulate for other buffers. + session.buffers.as_mut().unwrap()[0].buffer_damage.clear(); + for buffer in &mut session.buffers.as_mut().unwrap()[1..] { + buffer.buffer_damage.extend_from_slice(&frame.damage); + } + + let front = &session.buffers.as_ref().unwrap()[0]; let (buffer, release) = SubsurfaceBuffer::new(front.backing.clone()); session.release = Some(release); let image = CaptureImage {