diff --git a/src/backends/metal/video.rs b/src/backends/metal/video.rs index 03f15e06..5873eb7a 100644 --- a/src/backends/metal/video.rs +++ b/src/backends/metal/video.rs @@ -1692,9 +1692,14 @@ impl MetalBackend { if cursor { usage |= GBM_BO_USE_LINEAR; }; - let dev_bo = dev - .gbm - .create_bo(width, height, format, &possible_modifiers, usage); + let dev_bo = dev.gbm.create_bo( + &self.state.dma_buf_ids, + width, + height, + format, + &possible_modifiers, + usage, + ); let dev_bo = match dev_bo { Ok(b) => b, Err(e) => return Err(MetalError::ScanoutBuffer(e)), @@ -1740,11 +1745,14 @@ impl MetalBackend { return Err(MetalError::MissingRenderModifier(format.name)); } usage = GBM_BO_USE_RENDERING | GBM_BO_USE_LINEAR; - let render_bo = - render_ctx - .gfx - .gbm() - .create_bo(width, height, format, &possible_modifiers, usage); + let render_bo = render_ctx.gfx.gbm().create_bo( + &self.state.dma_buf_ids, + width, + height, + format, + &possible_modifiers, + usage, + ); let render_bo = match render_bo { Ok(b) => b, Err(e) => return Err(MetalError::ScanoutBuffer(e)), diff --git a/src/backends/x.rs b/src/backends/x.rs index ce3b46de..f6131a79 100644 --- a/src/backends/x.rs +++ b/src/backends/x.rs @@ -393,9 +393,14 @@ impl XBackend { panic!("Neither linear nor invalid modifier is supported"); }; for image in &mut images { - let bo = self - .gbm - .create_bo(width, height, XRGB8888, modifier, usage)?; + let bo = self.gbm.create_bo( + &self.state.dma_buf_ids, + width, + height, + XRGB8888, + modifier, + usage, + )?; let dma = bo.dmabuf(); assert!(dma.planes.len() == 1); let plane = dma.planes.first().unwrap(); diff --git a/src/cli/screenshot.rs b/src/cli/screenshot.rs index 91222eba..865d5646 100644 --- a/src/cli/screenshot.rs +++ b/src/cli/screenshot.rs @@ -5,7 +5,7 @@ use { tools::tool_client::{with_tool_client, Handle, ToolClient}, utils::{errorfmt::ErrorFmt, queue::AsyncQueue}, video::{ - dmabuf::{DmaBuf, DmaBufPlane, PlaneVec}, + dmabuf::{DmaBuf, DmaBufIds, DmaBufPlane, PlaneVec}, drm::Drm, gbm::{GbmDevice, GBM_BO_USE_LINEAR, GBM_BO_USE_RENDERING}, }, @@ -55,7 +55,7 @@ async fn run(screenshot: Rc) { fatal!("Could not take a screenshot: {}", e); } }; - let data = buf_to_qoi(&buf); + let data = buf_to_qoi(&DmaBufIds::default(), &buf); let filename = screenshot .args .filename @@ -67,7 +67,7 @@ async fn run(screenshot: Rc) { } } -pub fn buf_to_qoi(buf: &Dmabuf) -> Vec { +pub fn buf_to_qoi(dma_buf_ids: &DmaBufIds, buf: &Dmabuf) -> Vec { let drm = match Drm::reopen(buf.drm_dev.raw(), false) { Ok(drm) => drm, Err(e) => { @@ -87,6 +87,7 @@ pub fn buf_to_qoi(buf: &Dmabuf) -> Vec { fd: buf.fd.clone(), }); let dmabuf = DmaBuf { + id: dma_buf_ids.next(), width: buf.width as _, height: buf.height as _, format: XRGB8888, diff --git a/src/compositor.rs b/src/compositor.rs index 05ab43cf..37bacd32 100644 --- a/src/compositor.rs +++ b/src/compositor.rs @@ -201,6 +201,7 @@ fn start_compositor2( default_gfx_api: Cell::new(GfxApi::OpenGl), activation_tokens: Default::default(), toplevel_lists: Default::default(), + dma_buf_ids: Default::default(), }); state.tracker.register(ClientId::from_raw(0)); create_dummy_output(&state); diff --git a/src/ifs/jay_screencast.rs b/src/ifs/jay_screencast.rs index 112a8a99..eea05d0c 100644 --- a/src/ifs/jay_screencast.rs +++ b/src/ifs/jay_screencast.rs @@ -236,9 +236,14 @@ impl JayScreencast { } false => &format.write_modifiers, }; - let buffer = - ctx.gbm() - .create_bo(mode.width, mode.height, XRGB8888, modifiers, usage)?; + let buffer = ctx.gbm().create_bo( + &self.client.state.dma_buf_ids, + mode.width, + mode.height, + XRGB8888, + modifiers, + usage, + )?; let fb = ctx.clone().dmabuf_img(buffer.dmabuf())?.to_framebuffer()?; buffers.push(ScreencastBuffer { dmabuf: buffer.dmabuf().clone(), diff --git a/src/ifs/wl_drm.rs b/src/ifs/wl_drm.rs index 4bf5a01c..b7f22a7c 100644 --- a/src/ifs/wl_drm.rs +++ b/src/ifs/wl_drm.rs @@ -119,6 +119,7 @@ impl WlDrm { None => return Err(WlDrmError::InvalidFormat(req.format)), }; let mut dmabuf = DmaBuf { + id: self.client.state.dma_buf_ids.next(), width: req.width, height: req.height, format, diff --git a/src/ifs/zwp_linux_buffer_params_v1.rs b/src/ifs/zwp_linux_buffer_params_v1.rs index fbfb38e5..4dcebf55 100644 --- a/src/ifs/zwp_linux_buffer_params_v1.rs +++ b/src/ifs/zwp_linux_buffer_params_v1.rs @@ -114,6 +114,7 @@ impl ZwpLinuxBufferParamsV1 { return Err(ZwpLinuxBufferParamsV1Error::InvalidModifier(modifier)); } let mut dmabuf = DmaBuf { + id: self.parent.client.state.dma_buf_ids.next(), width, height, format: format.format, diff --git a/src/it/test_client.rs b/src/it/test_client.rs index c9e28d88..e6eb7ced 100644 --- a/src/it/test_client.rs +++ b/src/it/test_client.rs @@ -85,7 +85,7 @@ impl TestClient { pub async fn take_screenshot(&self) -> Result, TestError> { let dmabuf = self.jc.take_screenshot().await?; - let qoi = buf_to_qoi(&dmabuf); + let qoi = buf_to_qoi(&self.server.state.dma_buf_ids, &dmabuf); Ok(qoi) } diff --git a/src/portal.rs b/src/portal.rs index 6b9ffb3e..18a2b383 100644 --- a/src/portal.rs +++ b/src/portal.rs @@ -23,6 +23,7 @@ use { copyhashmap::CopyHashMap, errorfmt::ErrorFmt, numcell::NumCell, run_toplevel::RunToplevel, xrd::xrd, }, + video::dmabuf::DmaBufIds, wheel::Wheel, wire_dbus::org, }, @@ -84,6 +85,7 @@ async fn run_async(eng: Rc, ring: Rc) { screencasts: Default::default(), next_id: NumCell::new(1), render_ctxs: Default::default(), + dma_buf_ids: Default::default(), }); let _root = { let obj = state @@ -143,6 +145,7 @@ struct PortalState { screencasts: CopyHashMap>, next_id: NumCell, render_ctxs: CopyHashMap>, + dma_buf_ids: Rc, } impl PortalState { diff --git a/src/portal/ptl_display.rs b/src/portal/ptl_display.rs index 7c16b11d..c6fc7939 100644 --- a/src/portal/ptl_display.rs +++ b/src/portal/ptl_display.rs @@ -247,7 +247,16 @@ async fn maybe_add_display(state: &Rc, name: &str) { _ => return, }; let path = format!("{}/{}", state.xrd, name); - let con = match UsrCon::new(&state.ring, &state.wheel, &state.eng, &path, num).await { + let con = match UsrCon::new( + &state.ring, + &state.wheel, + &state.eng, + &state.dma_buf_ids, + &path, + num, + ) + .await + { Ok(c) => c, Err(e) => { log::error!( diff --git a/src/portal/ptr_gui.rs b/src/portal/ptr_gui.rs index 93276069..668675f6 100644 --- a/src/portal/ptr_gui.rs +++ b/src/portal/ptr_gui.rs @@ -710,6 +710,7 @@ impl WindowData { } for _ in 0..NUM_BUFFERS { let bo = match ctx.ctx.gbm().create_bo( + &self.dpy.state.dma_buf_ids, width, height, ARGB8888, diff --git a/src/screenshoter.rs b/src/screenshoter.rs index 4732abfe..89d46146 100644 --- a/src/screenshoter.rs +++ b/src/screenshoter.rs @@ -60,6 +60,7 @@ pub fn take_screenshot(state: &State) -> Result }; let gbm = ctx.gbm(); let bo = gbm.create_bo( + &state.dma_buf_ids, extents.width(), extents.height(), XRGB8888, diff --git a/src/state.rs b/src/state.rs index 7db7be9e..a4fa07c9 100644 --- a/src/state.rs +++ b/src/state.rs @@ -50,7 +50,7 @@ use { linkedlist::LinkedList, numcell::NumCell, queue::AsyncQueue, refcounted::RefCounted, run_toplevel::RunToplevel, }, - video::drm::Drm, + video::{dmabuf::DmaBufIds, drm::Drm}, wheel::Wheel, wire::{ ExtForeignToplevelListV1Id, JayRenderCtxId, JaySeatEventsId, JayWorkspaceWatcherId, @@ -142,6 +142,7 @@ pub struct State { pub activation_tokens: CopyHashMap, pub toplevel_lists: CopyHashMap<(ClientId, ExtForeignToplevelListV1Id), Rc>, + pub dma_buf_ids: DmaBufIds, } // impl Drop for State { diff --git a/src/video/dmabuf.rs b/src/video/dmabuf.rs index 1f8fe7ad..c217bfba 100644 --- a/src/video/dmabuf.rs +++ b/src/video/dmabuf.rs @@ -5,15 +5,18 @@ use { uapi::{c::ioctl, OwnedFd, _IOW, _IOWR}, }; -#[derive(Clone)] +#[derive(Clone, Debug)] pub struct DmaBufPlane { pub offset: u32, pub stride: u32, pub fd: Rc, } -#[derive(Clone)] +linear_ids!(DmaBufIds, DmaBufId); + +#[derive(Debug, Clone)] pub struct DmaBuf { + pub id: DmaBufId, pub width: i32, pub height: i32, pub format: &'static Format, diff --git a/src/video/gbm.rs b/src/video/gbm.rs index 904f9330..3338e2fb 100644 --- a/src/video/gbm.rs +++ b/src/video/gbm.rs @@ -5,7 +5,7 @@ use { format::{formats, Format}, utils::oserror::OsError, video::{ - dmabuf::{DmaBuf, DmaBufPlane, PlaneVec}, + dmabuf::{DmaBuf, DmaBufIds, DmaBufPlane, PlaneVec}, drm::{Drm, DrmError}, Modifier, INVALID_MODIFIER, }, @@ -150,8 +150,9 @@ impl GbmBoMap { } } -unsafe fn export_bo(bo: *mut Bo) -> Result { +unsafe fn export_bo(dmabuf_ids: &DmaBufIds, bo: *mut Bo) -> Result { Ok(DmaBuf { + id: dmabuf_ids.next(), width: gbm_bo_get_width(bo) as _, height: gbm_bo_get_height(bo) as _, modifier: gbm_bo_get_modifier(bo), @@ -199,6 +200,7 @@ impl GbmDevice { pub fn create_bo<'a>( &self, + dma_buf_ids: &DmaBufIds, width: i32, height: i32, format: &Format, @@ -229,7 +231,7 @@ impl GbmDevice { return Err(GbmError::CreateBo(OsError::default())); } let bo = BoHolder { bo }; - let dma = export_bo(bo.bo)?; + let dma = export_bo(dma_buf_ids, bo.bo)?; Ok(GbmBo { bo, dmabuf: dma }) } } diff --git a/src/wl_usr.rs b/src/wl_usr.rs index a8a6ca24..1b2fc47a 100644 --- a/src/wl_usr.rs +++ b/src/wl_usr.rs @@ -20,6 +20,7 @@ use { oserror::OsError, vec_ext::VecExt, }, + video::dmabuf::DmaBufIds, wheel::Wheel, wire::wl_display, wl_usr::{ @@ -77,6 +78,7 @@ pub struct UsrCon { outgoing: Cell>>, pub owner: CloneCell>>, dead: Cell, + dma_buf_ids: Rc, } pub trait UsrConOwner { @@ -88,6 +90,7 @@ impl UsrCon { ring: &Rc, wheel: &Rc, eng: &Rc, + dma_buf_ids: &Rc, path: &str, server_id: u32, ) -> Result, UsrConError> { @@ -122,6 +125,7 @@ impl UsrCon { outgoing: Default::default(), owner: Default::default(), dead: Cell::new(false), + dma_buf_ids: dma_buf_ids.clone(), }); slf.objects.set( WL_DISPLAY_ID.into(), diff --git a/src/wl_usr/usr_ifs/usr_jay_screencast.rs b/src/wl_usr/usr_ifs/usr_jay_screencast.rs index 87917e43..6630aaad 100644 --- a/src/wl_usr/usr_ifs/usr_jay_screencast.rs +++ b/src/wl_usr/usr_ifs/usr_jay_screencast.rs @@ -123,6 +123,7 @@ impl UsrJayScreencast { _ => return Err(UsrJayScreencastError::UnknownFormat(ev.format)), }; self.pending_buffers.borrow_mut().push(DmaBuf { + id: self.con.dma_buf_ids.next(), width: ev.width, height: ev.height, format,