kms/surface: Don't send screencopysuccess() until sync point is reached

This commit is contained in:
Ian Douglas Scott 2025-08-19 13:05:12 -07:00 committed by Victoria Brekenfeld
parent 28e9024681
commit 10c05bc1d4
2 changed files with 40 additions and 2 deletions

View file

@ -819,8 +819,12 @@ impl SurfaceThreadState {
self.timings.presented(clock);
while let Ok(PendingImageCopyData { frame, damage, .. }) = frames.recv() {
frame.success(self.output.current_transform(), damage, clock);
while let Ok(pending_image_copy_data) = frames.recv() {
pending_image_copy_data.send_success_when_ready(
self.output.current_transform(),
&self.loop_handle,
clock,
);
}
}
}

View file

@ -1,3 +1,4 @@
use calloop::LoopHandle;
use smithay::{
backend::{
allocator::{dmabuf::Dmabuf, format::get_transparent, Buffer, Fourcc},
@ -60,6 +61,39 @@ pub struct PendingImageCopyData {
pub sync: SyncPoint,
}
impl PendingImageCopyData {
/// Send `success` to image copy frame, once sync point is reached
pub fn send_success_when_ready<LoopData>(
self,
transform: Transform,
loop_handle: &LoopHandle<'static, LoopData>,
presented: impl Into<Duration>,
) {
let presented = presented.into();
if self.sync.is_reached() {
self.frame.success(transform, self.damage, presented);
} else if let Some(fence_fd) = self.sync.export() {
let source = calloop::generic::Generic::new(
fence_fd,
calloop::Interest::READ,
calloop::Mode::OneShot,
);
let mut data = Some(self);
loop_handle
.insert_source(source, move |_, _, _| {
let data = data.take().unwrap();
data.frame.success(transform, data.damage, presented);
Ok(calloop::PostAction::Remove)
})
.expect("Failed to wait on sync point");
} else {
// Should be able to export fence; but otherwise wait
let _ = self.sync.wait();
self.frame.success(transform, self.damage, presented);
}
}
}
pub fn submit_buffer<R>(
frame: Frame,
renderer: &mut R,