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.
This commit is contained in:
parent
6262329635
commit
89910b8e75
2 changed files with 24 additions and 21 deletions
|
|
@ -8,10 +8,7 @@ use cctk::{
|
||||||
};
|
};
|
||||||
use cosmic::cctk;
|
use cosmic::cctk;
|
||||||
|
|
||||||
use std::sync::{
|
use std::sync::{Arc, Mutex};
|
||||||
atomic::{AtomicBool, Ordering},
|
|
||||||
Arc, Mutex,
|
|
||||||
};
|
|
||||||
|
|
||||||
use super::{AppData, ScreencopySession, SessionData};
|
use super::{AppData, ScreencopySession, SessionData};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -9,12 +9,15 @@ use cosmic::cctk::{
|
||||||
},
|
},
|
||||||
wayland_client::{Connection, QueueHandle, WEnum},
|
wayland_client::{Connection, QueueHandle, WEnum},
|
||||||
};
|
};
|
||||||
use std::sync::{Arc, Weak};
|
use std::{
|
||||||
|
mem,
|
||||||
|
sync::{Arc, Weak},
|
||||||
|
};
|
||||||
|
|
||||||
use super::{AppData, Buffer, Capture, CaptureImage, CaptureSource, Event};
|
use super::{AppData, Buffer, Capture, CaptureImage, CaptureSource, Event};
|
||||||
|
|
||||||
pub struct ScreencopySession {
|
pub struct ScreencopySession {
|
||||||
buffer: Option<Buffer>,
|
buffers: Option<(Buffer, Buffer)>,
|
||||||
session: zcosmic_screencopy_session_v1::ZcosmicScreencopySessionV1,
|
session: zcosmic_screencopy_session_v1::ZcosmicScreencopySessionV1,
|
||||||
first_frame: bool,
|
first_frame: bool,
|
||||||
}
|
}
|
||||||
|
|
@ -47,22 +50,20 @@ impl ScreencopySession {
|
||||||
};
|
};
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
buffer: None,
|
buffers: None,
|
||||||
session,
|
session,
|
||||||
first_frame: true,
|
first_frame: true,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn attach_buffer_and_commit(&mut self, capture: &Capture, conn: &Connection) {
|
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;
|
return;
|
||||||
};
|
};
|
||||||
|
|
||||||
let node = buffer
|
let node = front.node().and_then(|x| x.to_str().map(|x| x.to_string()));
|
||||||
.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 {
|
if self.first_frame {
|
||||||
self.session
|
self.session
|
||||||
.commit(zcosmic_screencopy_session_v1::Options::empty());
|
.commit(zcosmic_screencopy_session_v1::Options::empty());
|
||||||
|
|
@ -115,12 +116,13 @@ impl ScreencopyHandler for AppData {
|
||||||
};
|
};
|
||||||
|
|
||||||
// Create new buffer if none, or different format
|
// Create new buffer if none, or different format
|
||||||
if !session
|
if !session.buffers.as_ref().map_or(false, |(front, _)| {
|
||||||
.buffer
|
buffer_infos.contains(&front.buffer_info)
|
||||||
.as_ref()
|
}) {
|
||||||
.map_or(false, |x| buffer_infos.contains(&x.buffer_info))
|
session.buffers = Some((
|
||||||
{
|
self.create_buffer(buffer_infos),
|
||||||
session.buffer = Some(self.create_buffer(buffer_infos));
|
self.create_buffer(buffer_infos),
|
||||||
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
session.attach_buffer_and_commit(&capture, conn);
|
session.attach_buffer_and_commit(&capture, conn);
|
||||||
|
|
@ -140,11 +142,15 @@ impl ScreencopyHandler for AppData {
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
||||||
if session.buffer.is_none() {
|
if session.buffers.is_none() {
|
||||||
eprintln!("Error: No capture buffer?");
|
eprintln!("Error: No capture buffers?");
|
||||||
return;
|
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 };
|
let image = CaptureImage { img };
|
||||||
match &capture.source {
|
match &capture.source {
|
||||||
CaptureSource::Toplevel(toplevel) => {
|
CaptureSource::Toplevel(toplevel) => {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue