1
0
Fork 0
forked from wry/wry

drm: add unique identifiers to dmabufs

This commit is contained in:
Julian Orth 2024-02-18 15:28:07 +01:00
parent 3635ae0104
commit fed2ceb8b5
17 changed files with 72 additions and 25 deletions

View file

@ -1692,9 +1692,14 @@ impl MetalBackend {
if cursor { if cursor {
usage |= GBM_BO_USE_LINEAR; usage |= GBM_BO_USE_LINEAR;
}; };
let dev_bo = dev let dev_bo = dev.gbm.create_bo(
.gbm &self.state.dma_buf_ids,
.create_bo(width, height, format, &possible_modifiers, usage); width,
height,
format,
&possible_modifiers,
usage,
);
let dev_bo = match dev_bo { let dev_bo = match dev_bo {
Ok(b) => b, Ok(b) => b,
Err(e) => return Err(MetalError::ScanoutBuffer(e)), Err(e) => return Err(MetalError::ScanoutBuffer(e)),
@ -1740,11 +1745,14 @@ impl MetalBackend {
return Err(MetalError::MissingRenderModifier(format.name)); return Err(MetalError::MissingRenderModifier(format.name));
} }
usage = GBM_BO_USE_RENDERING | GBM_BO_USE_LINEAR; usage = GBM_BO_USE_RENDERING | GBM_BO_USE_LINEAR;
let render_bo = let render_bo = render_ctx.gfx.gbm().create_bo(
render_ctx &self.state.dma_buf_ids,
.gfx width,
.gbm() height,
.create_bo(width, height, format, &possible_modifiers, usage); format,
&possible_modifiers,
usage,
);
let render_bo = match render_bo { let render_bo = match render_bo {
Ok(b) => b, Ok(b) => b,
Err(e) => return Err(MetalError::ScanoutBuffer(e)), Err(e) => return Err(MetalError::ScanoutBuffer(e)),

View file

@ -393,9 +393,14 @@ impl XBackend {
panic!("Neither linear nor invalid modifier is supported"); panic!("Neither linear nor invalid modifier is supported");
}; };
for image in &mut images { for image in &mut images {
let bo = self let bo = self.gbm.create_bo(
.gbm &self.state.dma_buf_ids,
.create_bo(width, height, XRGB8888, modifier, usage)?; width,
height,
XRGB8888,
modifier,
usage,
)?;
let dma = bo.dmabuf(); let dma = bo.dmabuf();
assert!(dma.planes.len() == 1); assert!(dma.planes.len() == 1);
let plane = dma.planes.first().unwrap(); let plane = dma.planes.first().unwrap();

View file

@ -5,7 +5,7 @@ use {
tools::tool_client::{with_tool_client, Handle, ToolClient}, tools::tool_client::{with_tool_client, Handle, ToolClient},
utils::{errorfmt::ErrorFmt, queue::AsyncQueue}, utils::{errorfmt::ErrorFmt, queue::AsyncQueue},
video::{ video::{
dmabuf::{DmaBuf, DmaBufPlane, PlaneVec}, dmabuf::{DmaBuf, DmaBufIds, DmaBufPlane, PlaneVec},
drm::Drm, drm::Drm,
gbm::{GbmDevice, GBM_BO_USE_LINEAR, GBM_BO_USE_RENDERING}, gbm::{GbmDevice, GBM_BO_USE_LINEAR, GBM_BO_USE_RENDERING},
}, },
@ -55,7 +55,7 @@ async fn run(screenshot: Rc<Screenshot>) {
fatal!("Could not take a screenshot: {}", e); fatal!("Could not take a screenshot: {}", e);
} }
}; };
let data = buf_to_qoi(&buf); let data = buf_to_qoi(&DmaBufIds::default(), &buf);
let filename = screenshot let filename = screenshot
.args .args
.filename .filename
@ -67,7 +67,7 @@ async fn run(screenshot: Rc<Screenshot>) {
} }
} }
pub fn buf_to_qoi(buf: &Dmabuf) -> Vec<u8> { pub fn buf_to_qoi(dma_buf_ids: &DmaBufIds, buf: &Dmabuf) -> Vec<u8> {
let drm = match Drm::reopen(buf.drm_dev.raw(), false) { let drm = match Drm::reopen(buf.drm_dev.raw(), false) {
Ok(drm) => drm, Ok(drm) => drm,
Err(e) => { Err(e) => {
@ -87,6 +87,7 @@ pub fn buf_to_qoi(buf: &Dmabuf) -> Vec<u8> {
fd: buf.fd.clone(), fd: buf.fd.clone(),
}); });
let dmabuf = DmaBuf { let dmabuf = DmaBuf {
id: dma_buf_ids.next(),
width: buf.width as _, width: buf.width as _,
height: buf.height as _, height: buf.height as _,
format: XRGB8888, format: XRGB8888,

View file

@ -201,6 +201,7 @@ fn start_compositor2(
default_gfx_api: Cell::new(GfxApi::OpenGl), default_gfx_api: Cell::new(GfxApi::OpenGl),
activation_tokens: Default::default(), activation_tokens: Default::default(),
toplevel_lists: Default::default(), toplevel_lists: Default::default(),
dma_buf_ids: Default::default(),
}); });
state.tracker.register(ClientId::from_raw(0)); state.tracker.register(ClientId::from_raw(0));
create_dummy_output(&state); create_dummy_output(&state);

View file

@ -236,9 +236,14 @@ impl JayScreencast {
} }
false => &format.write_modifiers, false => &format.write_modifiers,
}; };
let buffer = let buffer = ctx.gbm().create_bo(
ctx.gbm() &self.client.state.dma_buf_ids,
.create_bo(mode.width, mode.height, XRGB8888, modifiers, usage)?; mode.width,
mode.height,
XRGB8888,
modifiers,
usage,
)?;
let fb = ctx.clone().dmabuf_img(buffer.dmabuf())?.to_framebuffer()?; let fb = ctx.clone().dmabuf_img(buffer.dmabuf())?.to_framebuffer()?;
buffers.push(ScreencastBuffer { buffers.push(ScreencastBuffer {
dmabuf: buffer.dmabuf().clone(), dmabuf: buffer.dmabuf().clone(),

View file

@ -119,6 +119,7 @@ impl WlDrm {
None => return Err(WlDrmError::InvalidFormat(req.format)), None => return Err(WlDrmError::InvalidFormat(req.format)),
}; };
let mut dmabuf = DmaBuf { let mut dmabuf = DmaBuf {
id: self.client.state.dma_buf_ids.next(),
width: req.width, width: req.width,
height: req.height, height: req.height,
format, format,

View file

@ -114,6 +114,7 @@ impl ZwpLinuxBufferParamsV1 {
return Err(ZwpLinuxBufferParamsV1Error::InvalidModifier(modifier)); return Err(ZwpLinuxBufferParamsV1Error::InvalidModifier(modifier));
} }
let mut dmabuf = DmaBuf { let mut dmabuf = DmaBuf {
id: self.parent.client.state.dma_buf_ids.next(),
width, width,
height, height,
format: format.format, format: format.format,

View file

@ -85,7 +85,7 @@ impl TestClient {
pub async fn take_screenshot(&self) -> Result<Vec<u8>, TestError> { pub async fn take_screenshot(&self) -> Result<Vec<u8>, TestError> {
let dmabuf = self.jc.take_screenshot().await?; 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) Ok(qoi)
} }

View file

@ -23,6 +23,7 @@ use {
copyhashmap::CopyHashMap, errorfmt::ErrorFmt, numcell::NumCell, copyhashmap::CopyHashMap, errorfmt::ErrorFmt, numcell::NumCell,
run_toplevel::RunToplevel, xrd::xrd, run_toplevel::RunToplevel, xrd::xrd,
}, },
video::dmabuf::DmaBufIds,
wheel::Wheel, wheel::Wheel,
wire_dbus::org, wire_dbus::org,
}, },
@ -84,6 +85,7 @@ async fn run_async(eng: Rc<AsyncEngine>, ring: Rc<IoUring>) {
screencasts: Default::default(), screencasts: Default::default(),
next_id: NumCell::new(1), next_id: NumCell::new(1),
render_ctxs: Default::default(), render_ctxs: Default::default(),
dma_buf_ids: Default::default(),
}); });
let _root = { let _root = {
let obj = state let obj = state
@ -143,6 +145,7 @@ struct PortalState {
screencasts: CopyHashMap<String, Rc<ScreencastSession>>, screencasts: CopyHashMap<String, Rc<ScreencastSession>>,
next_id: NumCell<u32>, next_id: NumCell<u32>,
render_ctxs: CopyHashMap<c::dev_t, Weak<PortalRenderCtx>>, render_ctxs: CopyHashMap<c::dev_t, Weak<PortalRenderCtx>>,
dma_buf_ids: Rc<DmaBufIds>,
} }
impl PortalState { impl PortalState {

View file

@ -247,7 +247,16 @@ async fn maybe_add_display(state: &Rc<PortalState>, name: &str) {
_ => return, _ => return,
}; };
let path = format!("{}/{}", state.xrd, name); 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, Ok(c) => c,
Err(e) => { Err(e) => {
log::error!( log::error!(

View file

@ -710,6 +710,7 @@ impl WindowData {
} }
for _ in 0..NUM_BUFFERS { for _ in 0..NUM_BUFFERS {
let bo = match ctx.ctx.gbm().create_bo( let bo = match ctx.ctx.gbm().create_bo(
&self.dpy.state.dma_buf_ids,
width, width,
height, height,
ARGB8888, ARGB8888,

View file

@ -60,6 +60,7 @@ pub fn take_screenshot(state: &State) -> Result<Screenshot, ScreenshooterError>
}; };
let gbm = ctx.gbm(); let gbm = ctx.gbm();
let bo = gbm.create_bo( let bo = gbm.create_bo(
&state.dma_buf_ids,
extents.width(), extents.width(),
extents.height(), extents.height(),
XRGB8888, XRGB8888,

View file

@ -50,7 +50,7 @@ use {
linkedlist::LinkedList, numcell::NumCell, queue::AsyncQueue, refcounted::RefCounted, linkedlist::LinkedList, numcell::NumCell, queue::AsyncQueue, refcounted::RefCounted,
run_toplevel::RunToplevel, run_toplevel::RunToplevel,
}, },
video::drm::Drm, video::{dmabuf::DmaBufIds, drm::Drm},
wheel::Wheel, wheel::Wheel,
wire::{ wire::{
ExtForeignToplevelListV1Id, JayRenderCtxId, JaySeatEventsId, JayWorkspaceWatcherId, ExtForeignToplevelListV1Id, JayRenderCtxId, JaySeatEventsId, JayWorkspaceWatcherId,
@ -142,6 +142,7 @@ pub struct State {
pub activation_tokens: CopyHashMap<ActivationToken, ()>, pub activation_tokens: CopyHashMap<ActivationToken, ()>,
pub toplevel_lists: pub toplevel_lists:
CopyHashMap<(ClientId, ExtForeignToplevelListV1Id), Rc<ExtForeignToplevelListV1>>, CopyHashMap<(ClientId, ExtForeignToplevelListV1Id), Rc<ExtForeignToplevelListV1>>,
pub dma_buf_ids: DmaBufIds,
} }
// impl Drop for State { // impl Drop for State {

View file

@ -5,15 +5,18 @@ use {
uapi::{c::ioctl, OwnedFd, _IOW, _IOWR}, uapi::{c::ioctl, OwnedFd, _IOW, _IOWR},
}; };
#[derive(Clone)] #[derive(Clone, Debug)]
pub struct DmaBufPlane { pub struct DmaBufPlane {
pub offset: u32, pub offset: u32,
pub stride: u32, pub stride: u32,
pub fd: Rc<OwnedFd>, pub fd: Rc<OwnedFd>,
} }
#[derive(Clone)] linear_ids!(DmaBufIds, DmaBufId);
#[derive(Debug, Clone)]
pub struct DmaBuf { pub struct DmaBuf {
pub id: DmaBufId,
pub width: i32, pub width: i32,
pub height: i32, pub height: i32,
pub format: &'static Format, pub format: &'static Format,

View file

@ -5,7 +5,7 @@ use {
format::{formats, Format}, format::{formats, Format},
utils::oserror::OsError, utils::oserror::OsError,
video::{ video::{
dmabuf::{DmaBuf, DmaBufPlane, PlaneVec}, dmabuf::{DmaBuf, DmaBufIds, DmaBufPlane, PlaneVec},
drm::{Drm, DrmError}, drm::{Drm, DrmError},
Modifier, INVALID_MODIFIER, Modifier, INVALID_MODIFIER,
}, },
@ -150,8 +150,9 @@ impl GbmBoMap {
} }
} }
unsafe fn export_bo(bo: *mut Bo) -> Result<DmaBuf, GbmError> { unsafe fn export_bo(dmabuf_ids: &DmaBufIds, bo: *mut Bo) -> Result<DmaBuf, GbmError> {
Ok(DmaBuf { Ok(DmaBuf {
id: dmabuf_ids.next(),
width: gbm_bo_get_width(bo) as _, width: gbm_bo_get_width(bo) as _,
height: gbm_bo_get_height(bo) as _, height: gbm_bo_get_height(bo) as _,
modifier: gbm_bo_get_modifier(bo), modifier: gbm_bo_get_modifier(bo),
@ -199,6 +200,7 @@ impl GbmDevice {
pub fn create_bo<'a>( pub fn create_bo<'a>(
&self, &self,
dma_buf_ids: &DmaBufIds,
width: i32, width: i32,
height: i32, height: i32,
format: &Format, format: &Format,
@ -229,7 +231,7 @@ impl GbmDevice {
return Err(GbmError::CreateBo(OsError::default())); return Err(GbmError::CreateBo(OsError::default()));
} }
let bo = BoHolder { bo }; let bo = BoHolder { bo };
let dma = export_bo(bo.bo)?; let dma = export_bo(dma_buf_ids, bo.bo)?;
Ok(GbmBo { bo, dmabuf: dma }) Ok(GbmBo { bo, dmabuf: dma })
} }
} }

View file

@ -20,6 +20,7 @@ use {
oserror::OsError, oserror::OsError,
vec_ext::VecExt, vec_ext::VecExt,
}, },
video::dmabuf::DmaBufIds,
wheel::Wheel, wheel::Wheel,
wire::wl_display, wire::wl_display,
wl_usr::{ wl_usr::{
@ -77,6 +78,7 @@ pub struct UsrCon {
outgoing: Cell<Option<SpawnedFuture<()>>>, outgoing: Cell<Option<SpawnedFuture<()>>>,
pub owner: CloneCell<Option<Rc<dyn UsrConOwner>>>, pub owner: CloneCell<Option<Rc<dyn UsrConOwner>>>,
dead: Cell<bool>, dead: Cell<bool>,
dma_buf_ids: Rc<DmaBufIds>,
} }
pub trait UsrConOwner { pub trait UsrConOwner {
@ -88,6 +90,7 @@ impl UsrCon {
ring: &Rc<IoUring>, ring: &Rc<IoUring>,
wheel: &Rc<Wheel>, wheel: &Rc<Wheel>,
eng: &Rc<AsyncEngine>, eng: &Rc<AsyncEngine>,
dma_buf_ids: &Rc<DmaBufIds>,
path: &str, path: &str,
server_id: u32, server_id: u32,
) -> Result<Rc<Self>, UsrConError> { ) -> Result<Rc<Self>, UsrConError> {
@ -122,6 +125,7 @@ impl UsrCon {
outgoing: Default::default(), outgoing: Default::default(),
owner: Default::default(), owner: Default::default(),
dead: Cell::new(false), dead: Cell::new(false),
dma_buf_ids: dma_buf_ids.clone(),
}); });
slf.objects.set( slf.objects.set(
WL_DISPLAY_ID.into(), WL_DISPLAY_ID.into(),

View file

@ -123,6 +123,7 @@ impl UsrJayScreencast {
_ => return Err(UsrJayScreencastError::UnknownFormat(ev.format)), _ => return Err(UsrJayScreencastError::UnknownFormat(ev.format)),
}; };
self.pending_buffers.borrow_mut().push(DmaBuf { self.pending_buffers.borrow_mut().push(DmaBuf {
id: self.con.dma_buf_ids.next(),
width: ev.width, width: ev.width,
height: ev.height, height: ev.height,
format, format,