image-copy: Use "buffer age" of 1 for capture

The logic `age_for_buffer` used seems to be a misinterpretation of the
protocol.

The wording is a little unclear, but it seems tracking buffer age is the
responsibility of the client, and the client is required to accumulate
damage and pass it in `damage_buffer`.

Our clients initially weren't doing that correctly. I updated
xdg-desktop-portal-cosmic to use `damage_buffer` after testing on
wlroots, and cosmic-workspaces was recently updated as well.
This commit is contained in:
Ian Douglas Scott 2025-09-17 11:40:51 -07:00 committed by Victoria Brekenfeld
parent 9bc1b6e1ee
commit e1342fb2e3
3 changed files with 6 additions and 46 deletions

View file

@ -1353,13 +1353,6 @@ impl SurfaceThreadState {
(&session, frame, res),
now.into(),
) {
session
.user_data()
.get::<SessionData>()
.unwrap()
.lock()
.unwrap()
.reset();
tracing::warn!(?err, "Failed to screencopy");
}
}
@ -1388,14 +1381,7 @@ impl SurfaceThreadState {
}
}
Err(err) => {
for (session, frame, _) in frames {
session
.user_data()
.get::<SessionData>()
.unwrap()
.lock()
.unwrap()
.reset();
for (_session, frame, _) in frames {
frame.fail(CaptureFailureReason::Unknown);
}
return Err(err).with_context(|| "Failed to submit result for display");
@ -1628,7 +1614,7 @@ fn take_screencopy_frames(
// TODO re-use offscreen buffer to damage track screencopy to shm
0
} else {
damage_tracking.age_for_buffer(&buffer)
1
};
if !additional_damage.is_empty() {

View file

@ -225,7 +225,7 @@ where
// TODO re-use offscreen buffer to damage track screencopy to shm
0
} else {
session_damage_tracking.age_for_buffer(&buffer)
1
};
let mut fb = offscreen
.as_mut()

View file

@ -1,11 +1,10 @@
// SPDX-License-Identifier: GPL-3.0-only
use std::{cell::RefCell, collections::HashMap, sync::Mutex};
use std::{cell::RefCell, sync::Mutex};
use smithay::{
backend::renderer::{damage::OutputDamageTracker, utils::CommitCounter},
backend::renderer::damage::OutputDamageTracker,
output::Output,
reexports::wayland_server::{Resource, Weak, protocol::wl_buffer::WlBuffer},
wayland::image_copy_capture::{
CursorSession, CursorSessionRef, Frame, FrameRef, Session, SessionRef,
},
@ -20,36 +19,11 @@ pub type SessionData = Mutex<SessionUserData>;
pub struct SessionUserData {
pub dt: OutputDamageTracker,
commit_counter: CommitCounter,
buffer_age: HashMap<Weak<WlBuffer>, CommitCounter>,
}
impl SessionUserData {
pub fn new(tracker: OutputDamageTracker) -> SessionUserData {
SessionUserData {
dt: tracker,
commit_counter: CommitCounter::default(),
buffer_age: HashMap::new(),
}
}
pub fn age_for_buffer(&mut self, buffer: &WlBuffer) -> usize {
self.buffer_age.retain(|k, _| k.upgrade().is_ok());
let weak = buffer.downgrade();
let age = self
.commit_counter
.distance(self.buffer_age.get(&weak).copied())
.unwrap_or(0);
self.buffer_age.insert(weak, self.commit_counter);
self.commit_counter.increment();
age
}
pub fn reset(&mut self) {
self.commit_counter = CommitCounter::default();
self.buffer_age.clear();
SessionUserData { dt: tracker }
}
}