screencopy: Accumulate buffer damage

This commit is contained in:
Ian Douglas Scott 2025-09-16 13:51:53 -07:00 committed by Ian Douglas Scott
parent 7670bfb9ff
commit 85436fa9d6
2 changed files with 26 additions and 12 deletions

View file

@ -1,5 +1,5 @@
use cctk::{ use cctk::{
screencopy::Formats, screencopy::{Formats, Rect},
wayland_client::{ wayland_client::{
Connection, Dispatch, QueueHandle, Connection, Dispatch, QueueHandle,
protocol::{wl_buffer, wl_shm, wl_shm_pool}, protocol::{wl_buffer, wl_shm, wl_shm_pool},
@ -20,6 +20,7 @@ use crate::utils;
pub struct Buffer { pub struct Buffer {
pub backing: Arc<BufferSource>, pub backing: Arc<BufferSource>,
pub buffer: wl_buffer::WlBuffer, pub buffer: wl_buffer::WlBuffer,
pub buffer_damage: Vec<Rect>,
pub size: (u32, u32), pub size: (u32, u32),
#[cfg(feature = "no-subsurfaces")] #[cfg(feature = "no-subsurfaces")]
pub mmap: memmap2::Mmap, pub mmap: memmap2::Mmap,
@ -52,6 +53,13 @@ impl AppData {
#[cfg(feature = "no-subsurfaces")] #[cfg(feature = "no-subsurfaces")]
let mmap = unsafe { memmap2::Mmap::map(&fd).unwrap() }; 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 { Buffer {
backing: Arc::new( backing: Arc::new(
Shmbuf { Shmbuf {
@ -65,6 +73,7 @@ impl AppData {
.into(), .into(),
), ),
buffer, buffer,
buffer_damage: full_damage,
#[cfg(feature = "no-subsurfaces")] #[cfg(feature = "no-subsurfaces")]
mmap, mmap,
size: (width, height), size: (width, height),
@ -148,6 +157,13 @@ impl AppData {
) )
.0; .0;
let full_damage = vec![Rect {
x: 0,
y: 0,
width: width as i32,
height: height as i32,
}];
Ok(Some(Buffer { Ok(Some(Buffer {
backing: Arc::new( backing: Arc::new(
Dmabuf { Dmabuf {
@ -160,6 +176,7 @@ impl AppData {
.into(), .into(),
), ),
buffer, buffer,
buffer_damage: full_damage,
size: (width, height), size: (width, height),
})) }))
} }

View file

@ -69,18 +69,9 @@ impl ScreencopySession {
// TODO // TODO
// let node = back.node().and_then(|x| x.to_str().map(|x| x.to_string())); // 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( self.session.capture(
&back.buffer, &back.buffer,
full_damage, &back.buffer_damage,
qh, qh,
FrameData { FrameData {
frame_data: Default::default(), frame_data: Default::default(),
@ -185,7 +176,13 @@ impl ScreencopyHandler for AppData {
session.attach_buffer_and_commit(&capture_clone, &conn, &qh); 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()); let (buffer, release) = SubsurfaceBuffer::new(front.backing.clone());
session.release = Some(release); session.release = Some(release);
let image = CaptureImage { let image = CaptureImage {