From 8c690e9648b66fab27190eb7b5c0846300d2dce0 Mon Sep 17 00:00:00 2001 From: Ian Douglas Scott Date: Thu, 9 Feb 2023 14:10:31 -0800 Subject: [PATCH] Split wayland buffer code into a file --- src/wayland/buffer.rs | 58 ++++++++++++++++++++++++++++++ src/{wayland.rs => wayland/mod.rs} | 54 +++------------------------- 2 files changed, 63 insertions(+), 49 deletions(-) create mode 100644 src/wayland/buffer.rs rename src/{wayland.rs => wayland/mod.rs} (92%) diff --git a/src/wayland/buffer.rs b/src/wayland/buffer.rs new file mode 100644 index 0000000..df566e4 --- /dev/null +++ b/src/wayland/buffer.rs @@ -0,0 +1,58 @@ +use cctk::{ + screencopy::BufferInfo, + sctk::{globals::ProvidesBoundGlobal, shm::raw::RawPool}, + wayland_client::{ + protocol::{wl_buffer, wl_shm}, + QueueHandle, + }, +}; +use cosmic::iced::widget::image; + +pub struct Buffer { + pub pool: RawPool, + pub buffer: wl_buffer::WlBuffer, + pub buffer_info: BufferInfo, +} + +impl Buffer { + pub fn new( + buffer_info: BufferInfo, + shm: &impl ProvidesBoundGlobal, + qh: &QueueHandle, + ) -> Self { + // Assume format is already known to be valid + let mut pool = + RawPool::new((buffer_info.stride * buffer_info.height) as usize, shm).unwrap(); + let format = wl_shm::Format::try_from(buffer_info.format).unwrap(); + let buffer = pool.create_buffer( + 0, + buffer_info.width as i32, + buffer_info.height as i32, + buffer_info.stride as i32, + format, + (), + qh, + ); + Self { + pool, + buffer, + buffer_info, + } + } + + // Buffer must be released by server for safety + pub unsafe fn to_image(&mut self) -> image::Handle { + // XXX is this at all a performance issue? + image::Handle::from_pixels( + self.buffer_info.width, + self.buffer_info.height, + self.pool.mmap().to_vec(), + ) + } +} + +impl Drop for Buffer { + fn drop(&mut self) { + self.buffer.destroy(); + } +} diff --git a/src/wayland.rs b/src/wayland/mod.rs similarity index 92% rename from src/wayland.rs rename to src/wayland/mod.rs index 79e712b..6c19cf6 100644 --- a/src/wayland.rs +++ b/src/wayland/mod.rs @@ -20,11 +20,10 @@ use cctk::{ sctk::{ self, event_loop::WaylandSource, - globals::ProvidesBoundGlobal, output::{OutputHandler, OutputState}, registry::{ProvidesRegistryState, RegistryState}, seat::{SeatHandler, SeatState}, - shm::{raw::RawPool, ShmHandler, ShmState}, + shm::{ShmHandler, ShmState}, }, toplevel_info::{ToplevelInfo, ToplevelInfoHandler, ToplevelInfoState}, toplevel_management::{ToplevelManagerHandler, ToplevelManagerState}, @@ -52,6 +51,9 @@ use std::{ thread, }; +mod buffer; +use buffer::Buffer; + // TODO define subscription for a particular output/workspace/toplevel (but we want to rate limit?) #[derive(Clone, Debug)] @@ -115,45 +117,6 @@ pub enum Cmd { CaptureFilter(CaptureFilter), } -struct Buffer { - pool: RawPool, - buffer: wl_buffer::WlBuffer, - buffer_info: BufferInfo, -} - -impl Buffer { - fn new( - buffer_info: BufferInfo, - shm: &impl ProvidesBoundGlobal, - qh: &QueueHandle, - ) -> Self { - // Assume format is already known to be valid - let mut pool = - RawPool::new((buffer_info.stride * buffer_info.height) as usize, shm).unwrap(); - let format = wl_shm::Format::try_from(buffer_info.format).unwrap(); - let buffer = pool.create_buffer( - 0, - buffer_info.width as i32, - buffer_info.height as i32, - buffer_info.stride as i32, - format, - (), - qh, - ); - Self { - pool, - buffer, - buffer_info, - } - } -} - -impl Drop for Buffer { - fn drop(&mut self) { - self.buffer.destroy(); - } -} - struct Capture { buffer: Mutex>, source: CaptureSource, @@ -432,7 +395,6 @@ impl ScreencopyHandler for AppData { && x.format == wl_shm::Format::Abgr8888.into() }) .unwrap(); - let buf_len = buffer_info.stride * buffer_info.height; // XXX fix in compositor if buffer_info.width == 0 || buffer_info.height == 0 || buffer_info.stride == 0 { @@ -472,13 +434,7 @@ impl ScreencopyHandler for AppData { } let mut buffer = capture.buffer.lock().unwrap(); - let mut buffer = buffer.as_mut().unwrap(); - // XXX is this at all a performance issue? - let image = image::Handle::from_pixels( - buffer.buffer_info.width, - buffer.buffer_info.height, - buffer.pool.mmap().to_vec(), - ); + let image = unsafe { buffer.as_mut().unwrap().to_image() }; let event = match &capture.source { CaptureSource::Toplevel(toplevel) => Event::ToplevelCapture(toplevel.clone(), image), CaptureSource::Workspace(workspace, _) => {