From 89910b8e7500ef16cef8fb138317589561b2d9cb Mon Sep 17 00:00:00 2001 From: Ian Douglas Scott Date: Thu, 25 Jan 2024 15:58:34 -0800 Subject: [PATCH] Use double-buffering for screencopy Currently this is unnecesssary, but it's needed if we use subsurfaces (or import) instead of immedaitely converting to an image. --- src/wayland/capture.rs | 5 +---- src/wayland/screencopy.rs | 40 ++++++++++++++++++++++----------------- 2 files changed, 24 insertions(+), 21 deletions(-) diff --git a/src/wayland/capture.rs b/src/wayland/capture.rs index a475caa..5a45b64 100644 --- a/src/wayland/capture.rs +++ b/src/wayland/capture.rs @@ -8,10 +8,7 @@ use cctk::{ }; use cosmic::cctk; -use std::sync::{ - atomic::{AtomicBool, Ordering}, - Arc, Mutex, -}; +use std::sync::{Arc, Mutex}; use super::{AppData, ScreencopySession, SessionData}; diff --git a/src/wayland/screencopy.rs b/src/wayland/screencopy.rs index 2614af9..c326711 100644 --- a/src/wayland/screencopy.rs +++ b/src/wayland/screencopy.rs @@ -9,12 +9,15 @@ use cosmic::cctk::{ }, wayland_client::{Connection, QueueHandle, WEnum}, }; -use std::sync::{Arc, Weak}; +use std::{ + mem, + sync::{Arc, Weak}, +}; use super::{AppData, Buffer, Capture, CaptureImage, CaptureSource, Event}; pub struct ScreencopySession { - buffer: Option, + buffers: Option<(Buffer, Buffer)>, session: zcosmic_screencopy_session_v1::ZcosmicScreencopySessionV1, first_frame: bool, } @@ -47,22 +50,20 @@ impl ScreencopySession { }; Self { - buffer: None, + buffers: None, session, first_frame: true, } } fn attach_buffer_and_commit(&mut self, capture: &Capture, conn: &Connection) { - let Some(buffer) = self.buffer.as_ref() else { + let Some((front, back)) = self.buffers.as_mut() else { return; }; - let node = buffer - .node() - .and_then(|x| x.to_str().map(|x| x.to_string())); + let node = front.node().and_then(|x| x.to_str().map(|x| x.to_string())); - self.session.attach_buffer(&buffer.buffer, node, 0); // XXX age? + self.session.attach_buffer(&back.buffer, node, 0); // XXX age? if self.first_frame { self.session .commit(zcosmic_screencopy_session_v1::Options::empty()); @@ -115,12 +116,13 @@ impl ScreencopyHandler for AppData { }; // Create new buffer if none, or different format - if !session - .buffer - .as_ref() - .map_or(false, |x| buffer_infos.contains(&x.buffer_info)) - { - session.buffer = Some(self.create_buffer(buffer_infos)); + if !session.buffers.as_ref().map_or(false, |(front, _)| { + buffer_infos.contains(&front.buffer_info) + }) { + session.buffers = Some(( + self.create_buffer(buffer_infos), + self.create_buffer(buffer_infos), + )); } session.attach_buffer_and_commit(&capture, conn); @@ -140,11 +142,15 @@ impl ScreencopyHandler for AppData { return; }; - if session.buffer.is_none() { - eprintln!("Error: No capture buffer?"); + if session.buffers.is_none() { + eprintln!("Error: No capture buffers?"); return; } - let img = unsafe { session.buffer.as_mut().unwrap().to_image() }; + + let (front, back) = session.buffers.as_mut().unwrap(); + mem::swap(front, back); + + let img = unsafe { front.to_image() }; let image = CaptureImage { img }; match &capture.source { CaptureSource::Toplevel(toplevel) => {