tree: split output captures
This commit is contained in:
parent
fa1ad20864
commit
4074cee365
2 changed files with 169 additions and 160 deletions
|
|
@ -1,3 +1,4 @@
|
||||||
|
mod captures;
|
||||||
mod policy;
|
mod policy;
|
||||||
mod render_data;
|
mod render_data;
|
||||||
mod workspaces;
|
mod workspaces;
|
||||||
|
|
@ -18,14 +19,11 @@ use {
|
||||||
HardwareCursor, Mode, transaction::BackendConnectorTransactionError,
|
HardwareCursor, Mode, transaction::BackendConnectorTransactionError,
|
||||||
},
|
},
|
||||||
client::ClientId,
|
client::ClientId,
|
||||||
cmm::cmm_description::ColorDescription,
|
|
||||||
cursor::KnownCursor,
|
cursor::KnownCursor,
|
||||||
fixed::Fixed,
|
fixed::Fixed,
|
||||||
gfx_api::{AcquireSync, BufferResv, GfxTexture, ReleaseSync},
|
|
||||||
ifs::{
|
ifs::{
|
||||||
ext_image_copy::ext_image_copy_capture_session_v1::ExtImageCopyCaptureSessionV1,
|
ext_image_copy::ext_image_copy_capture_session_v1::ExtImageCopyCaptureSessionV1,
|
||||||
jay_output::JayOutput,
|
jay_output::JayOutput,
|
||||||
wl_buffer::WlBufferStorage,
|
|
||||||
wl_output::{BlendSpace, WlOutputGlobal},
|
wl_output::{BlendSpace, WlOutputGlobal},
|
||||||
wl_seat::{
|
wl_seat::{
|
||||||
BTN_LEFT, NodeSeatState, SeatId, WlSeatGlobal,
|
BTN_LEFT, NodeSeatState, SeatId, WlSeatGlobal,
|
||||||
|
|
@ -69,7 +67,6 @@ use {
|
||||||
copyhashmap::CopyHashMap,
|
copyhashmap::CopyHashMap,
|
||||||
errorfmt::ErrorFmt,
|
errorfmt::ErrorFmt,
|
||||||
event_listener::{EventSource, LazyEventSource},
|
event_listener::{EventSource, LazyEventSource},
|
||||||
hash_map_ext::HashMapExt,
|
|
||||||
linkedlist::LinkedList,
|
linkedlist::LinkedList,
|
||||||
on_drop_event::OnDropEvent,
|
on_drop_event::OnDropEvent,
|
||||||
scroller::Scroller,
|
scroller::Scroller,
|
||||||
|
|
@ -279,162 +276,6 @@ impl OutputNode {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn captures_changed(&self) {
|
|
||||||
for ws in self.workspaces.iter() {
|
|
||||||
ws.update_has_captures();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn perform_screencopies(
|
|
||||||
&self,
|
|
||||||
tex: &Rc<dyn GfxTexture>,
|
|
||||||
cd: &Rc<ColorDescription>,
|
|
||||||
resv: Option<&Rc<dyn BufferResv>>,
|
|
||||||
acquire_sync: &AcquireSync,
|
|
||||||
release_sync: ReleaseSync,
|
|
||||||
render_hardware_cursor: bool,
|
|
||||||
x_off: i32,
|
|
||||||
y_off: i32,
|
|
||||||
size: Option<(i32, i32)>,
|
|
||||||
) {
|
|
||||||
if let Some(workspace) = self.workspace.get() {
|
|
||||||
if !workspace.may_capture.get() {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
self.perform_wlr_screencopies(
|
|
||||||
tex,
|
|
||||||
cd,
|
|
||||||
resv,
|
|
||||||
acquire_sync,
|
|
||||||
release_sync,
|
|
||||||
render_hardware_cursor,
|
|
||||||
x_off,
|
|
||||||
y_off,
|
|
||||||
size,
|
|
||||||
);
|
|
||||||
for sc in self.ext_copy_sessions.lock().values() {
|
|
||||||
sc.copy_texture(
|
|
||||||
self,
|
|
||||||
tex,
|
|
||||||
cd,
|
|
||||||
resv,
|
|
||||||
acquire_sync,
|
|
||||||
release_sync,
|
|
||||||
render_hardware_cursor,
|
|
||||||
x_off,
|
|
||||||
y_off,
|
|
||||||
size,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn perform_wlr_screencopies(
|
|
||||||
&self,
|
|
||||||
tex: &Rc<dyn GfxTexture>,
|
|
||||||
cd: &Rc<ColorDescription>,
|
|
||||||
resv: Option<&Rc<dyn BufferResv>>,
|
|
||||||
acquire_sync: &AcquireSync,
|
|
||||||
release_sync: ReleaseSync,
|
|
||||||
render_hardware_cursors: bool,
|
|
||||||
x_off: i32,
|
|
||||||
y_off: i32,
|
|
||||||
size: Option<(i32, i32)>,
|
|
||||||
) {
|
|
||||||
if self.screencopies.is_empty() {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
let now = self.state.now();
|
|
||||||
for capture in self.screencopies.lock().drain_values() {
|
|
||||||
let wl_buffer = match capture.buffer.take() {
|
|
||||||
Some(b) => b,
|
|
||||||
_ => {
|
|
||||||
log::warn!("Capture frame is pending but has no buffer attached");
|
|
||||||
capture.send_failed();
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
if wl_buffer.destroyed() {
|
|
||||||
capture.send_failed();
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
let mut ready = true;
|
|
||||||
if let Some(storage) = wl_buffer.storage.borrow_mut().deref() {
|
|
||||||
match storage {
|
|
||||||
WlBufferStorage::Shm { mem, stride, .. } => {
|
|
||||||
let res = self.state.perform_shm_screencopy(
|
|
||||||
tex,
|
|
||||||
cd,
|
|
||||||
acquire_sync,
|
|
||||||
self.global.pos.get(),
|
|
||||||
x_off,
|
|
||||||
y_off,
|
|
||||||
size,
|
|
||||||
&capture,
|
|
||||||
mem,
|
|
||||||
*stride,
|
|
||||||
wl_buffer.format,
|
|
||||||
self.global.persistent.transform.get(),
|
|
||||||
self.global.persistent.scale.get(),
|
|
||||||
);
|
|
||||||
match res {
|
|
||||||
Ok(p) => {
|
|
||||||
ready = p.is_none();
|
|
||||||
capture.pending.set(p);
|
|
||||||
}
|
|
||||||
Err(e) => {
|
|
||||||
log::warn!("Could not perform shm screencopy: {}", ErrorFmt(e));
|
|
||||||
capture.send_failed();
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
WlBufferStorage::Dmabuf { fb, .. } => {
|
|
||||||
let fb = match fb {
|
|
||||||
Some(fb) => fb,
|
|
||||||
_ => {
|
|
||||||
log::warn!("Capture buffer has no framebuffer");
|
|
||||||
capture.send_failed();
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
let res = self.state.perform_screencopy(
|
|
||||||
tex,
|
|
||||||
resv,
|
|
||||||
acquire_sync,
|
|
||||||
release_sync,
|
|
||||||
cd,
|
|
||||||
&fb,
|
|
||||||
AcquireSync::Implicit,
|
|
||||||
ReleaseSync::Implicit,
|
|
||||||
self.global.persistent.transform.get(),
|
|
||||||
self.state.color_manager.srgb_gamma22(),
|
|
||||||
self.global.pos.get(),
|
|
||||||
render_hardware_cursors,
|
|
||||||
x_off - capture.rect.x1(),
|
|
||||||
y_off - capture.rect.y1(),
|
|
||||||
size,
|
|
||||||
self.global.persistent.transform.get(),
|
|
||||||
self.global.persistent.scale.get(),
|
|
||||||
);
|
|
||||||
if let Err(e) = res {
|
|
||||||
log::warn!("Could not perform screencopy: {}", ErrorFmt(e));
|
|
||||||
capture.send_failed();
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if capture.with_damage.get() {
|
|
||||||
capture.send_damage();
|
|
||||||
}
|
|
||||||
if ready {
|
|
||||||
capture.send_ready(now.0.tv_sec as _, now.0.tv_nsec as _);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
self.captures_changed();
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn clear(&self) {
|
pub fn clear(&self) {
|
||||||
self.global.clear();
|
self.global.clear();
|
||||||
self.workspace.set(None);
|
self.workspace.set(None);
|
||||||
|
|
|
||||||
168
src/tree/output/captures.rs
Normal file
168
src/tree/output/captures.rs
Normal file
|
|
@ -0,0 +1,168 @@
|
||||||
|
use {
|
||||||
|
super::OutputNode,
|
||||||
|
crate::{
|
||||||
|
cmm::cmm_description::ColorDescription,
|
||||||
|
gfx_api::{AcquireSync, BufferResv, GfxTexture, ReleaseSync},
|
||||||
|
ifs::wl_buffer::WlBufferStorage,
|
||||||
|
utils::{errorfmt::ErrorFmt, hash_map_ext::HashMapExt},
|
||||||
|
},
|
||||||
|
std::{ops::Deref, rc::Rc},
|
||||||
|
};
|
||||||
|
|
||||||
|
impl OutputNode {
|
||||||
|
pub fn captures_changed(&self) {
|
||||||
|
for ws in self.workspaces.iter() {
|
||||||
|
ws.update_has_captures();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn perform_screencopies(
|
||||||
|
&self,
|
||||||
|
tex: &Rc<dyn GfxTexture>,
|
||||||
|
cd: &Rc<ColorDescription>,
|
||||||
|
resv: Option<&Rc<dyn BufferResv>>,
|
||||||
|
acquire_sync: &AcquireSync,
|
||||||
|
release_sync: ReleaseSync,
|
||||||
|
render_hardware_cursor: bool,
|
||||||
|
x_off: i32,
|
||||||
|
y_off: i32,
|
||||||
|
size: Option<(i32, i32)>,
|
||||||
|
) {
|
||||||
|
if let Some(workspace) = self.workspace.get() {
|
||||||
|
if !workspace.may_capture.get() {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
self.perform_wlr_screencopies(
|
||||||
|
tex,
|
||||||
|
cd,
|
||||||
|
resv,
|
||||||
|
acquire_sync,
|
||||||
|
release_sync,
|
||||||
|
render_hardware_cursor,
|
||||||
|
x_off,
|
||||||
|
y_off,
|
||||||
|
size,
|
||||||
|
);
|
||||||
|
for sc in self.ext_copy_sessions.lock().values() {
|
||||||
|
sc.copy_texture(
|
||||||
|
self,
|
||||||
|
tex,
|
||||||
|
cd,
|
||||||
|
resv,
|
||||||
|
acquire_sync,
|
||||||
|
release_sync,
|
||||||
|
render_hardware_cursor,
|
||||||
|
x_off,
|
||||||
|
y_off,
|
||||||
|
size,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn perform_wlr_screencopies(
|
||||||
|
&self,
|
||||||
|
tex: &Rc<dyn GfxTexture>,
|
||||||
|
cd: &Rc<ColorDescription>,
|
||||||
|
resv: Option<&Rc<dyn BufferResv>>,
|
||||||
|
acquire_sync: &AcquireSync,
|
||||||
|
release_sync: ReleaseSync,
|
||||||
|
render_hardware_cursors: bool,
|
||||||
|
x_off: i32,
|
||||||
|
y_off: i32,
|
||||||
|
size: Option<(i32, i32)>,
|
||||||
|
) {
|
||||||
|
if self.screencopies.is_empty() {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let now = self.state.now();
|
||||||
|
for capture in self.screencopies.lock().drain_values() {
|
||||||
|
let wl_buffer = match capture.buffer.take() {
|
||||||
|
Some(b) => b,
|
||||||
|
_ => {
|
||||||
|
log::warn!("Capture frame is pending but has no buffer attached");
|
||||||
|
capture.send_failed();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
if wl_buffer.destroyed() {
|
||||||
|
capture.send_failed();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
let mut ready = true;
|
||||||
|
if let Some(storage) = wl_buffer.storage.borrow_mut().deref() {
|
||||||
|
match storage {
|
||||||
|
WlBufferStorage::Shm { mem, stride, .. } => {
|
||||||
|
let res = self.state.perform_shm_screencopy(
|
||||||
|
tex,
|
||||||
|
cd,
|
||||||
|
acquire_sync,
|
||||||
|
self.global.pos.get(),
|
||||||
|
x_off,
|
||||||
|
y_off,
|
||||||
|
size,
|
||||||
|
&capture,
|
||||||
|
mem,
|
||||||
|
*stride,
|
||||||
|
wl_buffer.format,
|
||||||
|
self.global.persistent.transform.get(),
|
||||||
|
self.global.persistent.scale.get(),
|
||||||
|
);
|
||||||
|
match res {
|
||||||
|
Ok(p) => {
|
||||||
|
ready = p.is_none();
|
||||||
|
capture.pending.set(p);
|
||||||
|
}
|
||||||
|
Err(e) => {
|
||||||
|
log::warn!("Could not perform shm screencopy: {}", ErrorFmt(e));
|
||||||
|
capture.send_failed();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
WlBufferStorage::Dmabuf { fb, .. } => {
|
||||||
|
let fb = match fb {
|
||||||
|
Some(fb) => fb,
|
||||||
|
_ => {
|
||||||
|
log::warn!("Capture buffer has no framebuffer");
|
||||||
|
capture.send_failed();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
let res = self.state.perform_screencopy(
|
||||||
|
tex,
|
||||||
|
resv,
|
||||||
|
acquire_sync,
|
||||||
|
release_sync,
|
||||||
|
cd,
|
||||||
|
&fb,
|
||||||
|
AcquireSync::Implicit,
|
||||||
|
ReleaseSync::Implicit,
|
||||||
|
self.global.persistent.transform.get(),
|
||||||
|
self.state.color_manager.srgb_gamma22(),
|
||||||
|
self.global.pos.get(),
|
||||||
|
render_hardware_cursors,
|
||||||
|
x_off - capture.rect.x1(),
|
||||||
|
y_off - capture.rect.y1(),
|
||||||
|
size,
|
||||||
|
self.global.persistent.transform.get(),
|
||||||
|
self.global.persistent.scale.get(),
|
||||||
|
);
|
||||||
|
if let Err(e) = res {
|
||||||
|
log::warn!("Could not perform screencopy: {}", ErrorFmt(e));
|
||||||
|
capture.send_failed();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if capture.with_damage.get() {
|
||||||
|
capture.send_damage();
|
||||||
|
}
|
||||||
|
if ready {
|
||||||
|
capture.send_ready(now.0.tv_sec as _, now.0.tv_nsec as _);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
self.captures_changed();
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue