aboutsummaryrefslogtreecommitdiff
path: root/src/protocols
diff options
context:
space:
mode:
authorIvan Molodetskikh <yalterz@gmail.com>2024-08-08 12:52:24 +0300
committerIvan Molodetskikh <yalterz@gmail.com>2024-08-08 13:32:37 +0300
commit47680e43c5b7d71b06c0721803b3788a4b2aa44d (patch)
tree16a7aae06d3691187d7777b1ec537ae66aa5483c /src/protocols
parent0f1e44aac66d53a085919b5dcd28e85348ad2b94 (diff)
downloadniri-47680e43c5b7d71b06c0721803b3788a4b2aa44d.tar.gz
niri-47680e43c5b7d71b06c0721803b3788a4b2aa44d.tar.bz2
niri-47680e43c5b7d71b06c0721803b3788a4b2aa44d.zip
screencopy: Wait for SyncPoint before submitting
Diffstat (limited to 'src/protocols')
-rw-r--r--src/protocols/screencopy.rs35
1 files changed, 30 insertions, 5 deletions
diff --git a/src/protocols/screencopy.rs b/src/protocols/screencopy.rs
index d7e3d08f..d8b7944e 100644
--- a/src/protocols/screencopy.rs
+++ b/src/protocols/screencopy.rs
@@ -1,10 +1,14 @@
use std::collections::HashMap;
use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::Arc;
+use std::time::Duration;
+use calloop::generic::Generic;
+use calloop::{Interest, LoopHandle, Mode, PostAction};
use smithay::backend::allocator::dmabuf::Dmabuf;
use smithay::backend::allocator::{Buffer, Fourcc};
use smithay::backend::renderer::damage::OutputDamageTracker;
+use smithay::backend::renderer::sync::SyncPoint;
use smithay::output::Output;
use smithay::reexports::wayland_protocols_wlr::screencopy::v1::server::zwlr_screencopy_frame_v1::{
Flags, ZwlrScreencopyFrameV1,
@@ -464,7 +468,7 @@ impl Screencopy {
}
/// Submit the copied content.
- pub fn submit(mut self, y_invert: bool) {
+ fn submit(mut self, y_invert: bool, timestamp: Duration) {
// Notify client that buffer is ordinary.
self.frame.flags(if y_invert {
Flags::YInvert
@@ -473,13 +477,34 @@ impl Screencopy {
});
// Notify client about successful copy.
- let time = get_monotonic_time();
- let tv_sec_hi = (time.as_secs() >> 32) as u32;
- let tv_sec_lo = (time.as_secs() & 0xFFFFFFFF) as u32;
- let tv_nsec = time.subsec_nanos();
+ let tv_sec_hi = (timestamp.as_secs() >> 32) as u32;
+ let tv_sec_lo = (timestamp.as_secs() & 0xFFFFFFFF) as u32;
+ let tv_nsec = timestamp.subsec_nanos();
self.frame.ready(tv_sec_hi, tv_sec_lo, tv_nsec);
// Mark frame as submitted to ensure destructor isn't run.
self.submitted = true;
}
+
+ pub fn submit_after_sync<T>(
+ self,
+ y_invert: bool,
+ sync_point: Option<SyncPoint>,
+ event_loop: &LoopHandle<'_, T>,
+ ) {
+ let timestamp = get_monotonic_time();
+ match sync_point.and_then(|s| s.export()) {
+ None => self.submit(y_invert, timestamp),
+ Some(sync_fd) => {
+ let source = Generic::new(sync_fd, Interest::READ, Mode::OneShot);
+ let mut screencopy = Some(self);
+ event_loop
+ .insert_source(source, move |_, _, _| {
+ screencopy.take().unwrap().submit(y_invert, timestamp);
+ Ok(PostAction::Remove)
+ })
+ .unwrap();
+ }
+ }
+ }
}