1
0
Fork 0
forked from wry/wry

video: add udmabuf allocator

This commit is contained in:
Julian Orth 2024-09-01 20:23:04 +02:00
parent 2579834a60
commit 62cd29056a
33 changed files with 883 additions and 256 deletions

View file

@ -32,6 +32,7 @@ use {
};
pub const CREATE_EI_SESSION_SINCE: Version = Version(5);
pub const SCREENSHOT_SPLITUP_SINCE: Version = Version(6);
pub struct JayCompositorGlobal {
name: GlobalName,
@ -69,7 +70,7 @@ impl Global for JayCompositorGlobal {
}
fn version(&self) -> u32 {
5
6
}
fn required_caps(&self) -> ClientCaps {
@ -117,16 +118,30 @@ impl JayCompositor {
match take_screenshot(&self.client.state, include_cursor) {
Ok(s) => {
let dmabuf = s.bo.dmabuf();
let plane = &dmabuf.planes[0];
ss.send_dmabuf(
&s.drm,
&plane.fd,
dmabuf.width,
dmabuf.height,
plane.offset,
plane.stride,
dmabuf.modifier,
);
if self.version < SCREENSHOT_SPLITUP_SINCE {
if let Some(drm) = &s.drm {
let plane = &dmabuf.planes[0];
ss.send_dmabuf(
drm,
&plane.fd,
dmabuf.width,
dmabuf.height,
plane.offset,
plane.stride,
dmabuf.modifier,
);
} else {
ss.send_error("Buffer has no associated DRM device");
}
} else {
if let Some(drm) = &s.drm {
ss.send_drm_dev(drm);
}
for plane in &dmabuf.planes {
ss.send_plane(plane);
}
ss.send_dmabuf2(dmabuf);
}
}
Err(e) => {
let msg = ErrorFmt(e).to_string();

View file

@ -21,10 +21,16 @@ impl JayRenderCtx {
pub fn send_render_ctx(&self, ctx: Option<Rc<dyn GfxContext>>) {
let mut fd = None;
if let Some(ctx) = ctx {
match ctx.gbm().drm.dup_render() {
Ok(d) => fd = Some(d.fd().clone()),
Err(e) => {
log::error!("Could not dup drm fd: {}", ErrorFmt(e));
let allocator = ctx.allocator();
match allocator.drm() {
Some(drm) => match drm.dup_render() {
Ok(d) => fd = Some(d.fd().clone()),
Err(e) => {
log::error!("Could not dup drm fd: {}", ErrorFmt(e));
}
},
None => {
log::error!("Allocator does not have a DRM device");
}
}
} else {

View file

@ -1,5 +1,6 @@
use {
crate::{
allocator::{AllocatorError, BufferObject, BO_USE_LINEAR, BO_USE_RENDERING},
client::{Client, ClientError},
format::XRGB8888,
gfx_api::{GfxContext, GfxError, GfxFramebuffer, GfxTexture},
@ -16,17 +17,11 @@ use {
numcell::NumCell,
option_ext::OptionExt,
},
video::{
dmabuf::DmaBuf,
gbm::{GbmBo, GbmError, GBM_BO_USE_LINEAR, GBM_BO_USE_RENDERING},
Modifier, INVALID_MODIFIER, LINEAR_MODIFIER,
},
video::{dmabuf::DmaBuf, INVALID_MODIFIER, LINEAR_MODIFIER},
wire::{jay_screencast::*, JayScreencastId},
},
ahash::AHashSet,
indexmap::{indexset, IndexSet},
jay_config::video::Transform,
once_cell::sync::Lazy,
std::{
cell::{Cell, RefCell},
ops::DerefMut,
@ -108,7 +103,7 @@ struct Pending {
}
struct ScreencastBuffer {
_bo: GbmBo,
_bo: Rc<dyn BufferObject>,
dmabuf: DmaBuf,
fb: Rc<dyn GfxFramebuffer>,
free: bool,
@ -381,31 +376,27 @@ impl JayScreencast {
if width == 0 || height == 0 {
continue;
}
let mut usage = GBM_BO_USE_RENDERING;
let mut usage = BO_USE_RENDERING;
let modifiers = match self.linear.get() {
true if format.write_modifiers.contains(&LINEAR_MODIFIER) => {
static MODS: Lazy<IndexSet<Modifier>> =
Lazy::new(|| indexset![LINEAR_MODIFIER]);
&MODS
vec![LINEAR_MODIFIER]
}
true if format.write_modifiers.contains(&INVALID_MODIFIER) => {
usage |= GBM_BO_USE_LINEAR;
static MODS: Lazy<IndexSet<Modifier>> =
Lazy::new(|| indexset![INVALID_MODIFIER]);
&MODS
usage |= BO_USE_LINEAR;
vec![INVALID_MODIFIER]
}
true => return Err(JayScreencastError::Modifier),
false if format.write_modifiers.is_empty() => {
return Err(JayScreencastError::XRGB8888Writing)
}
false => &format.write_modifiers,
false => format.write_modifiers.iter().copied().collect(),
};
let buffer = ctx.gbm().create_bo(
let buffer = ctx.allocator().create_bo(
&self.client.state.dma_buf_ids,
width,
height,
XRGB8888,
modifiers,
&modifiers,
usage,
)?;
let fb = ctx.clone().dmabuf_img(buffer.dmabuf())?.to_framebuffer()?;
@ -681,7 +672,7 @@ pub enum JayScreencastError {
#[error("Buffer index {0} is out-of-bounds")]
OutOfBounds(u32),
#[error(transparent)]
GbmError(#[from] GbmError),
AllocatorError(#[from] AllocatorError),
#[error(transparent)]
GfxError(#[from] GfxError),
#[error("Render context does not support XRGB8888 format")]

View file

@ -3,6 +3,7 @@ use {
client::Client,
leaks::Tracker,
object::{Object, Version},
video::dmabuf::{DmaBuf, DmaBufPlane},
wire::{jay_screenshot::*, JayScreenshotId},
},
std::{convert::Infallible, rc::Rc},
@ -45,6 +46,31 @@ impl JayScreenshot {
msg,
});
}
pub fn send_drm_dev(&self, drm: &Rc<OwnedFd>) {
self.client.event(DrmDev {
self_id: self.id,
drm_dev: drm.clone(),
})
}
pub fn send_plane(&self, plane: &DmaBufPlane) {
self.client.event(Plane {
self_id: self.id,
fd: plane.fd.clone(),
offset: plane.offset,
stride: plane.stride,
})
}
pub fn send_dmabuf2(&self, buf: &DmaBuf) {
self.client.event(Dmabuf2 {
self_id: self.id,
width: buf.width,
height: buf.height,
modifier: buf.modifier,
})
}
}
impl JayScreenshotRequestHandler for JayScreenshot {

View file

@ -43,7 +43,9 @@ impl WlDrmGlobal {
track!(client, obj);
client.add_client_obj(&obj)?;
if let Some(rc) = client.state.render_ctx.get() {
obj.send_device(&rc.render_node());
if let Some(rn) = rc.render_node() {
obj.send_device(&rn);
}
obj.send_capabilities(PRIME);
}
Ok(())

View file

@ -202,7 +202,10 @@ impl Drop for SurfaceBuffer {
log::error!("Cannot signal release point because there is no render context");
return;
};
let ctx = ctx.sync_obj_ctx();
let Some(ctx) = ctx.sync_obj_ctx() else {
log::error!("Cannot signal release point because there is no syncobj context");
return;
};
if sync_files.is_not_empty() {
let res = ctx.import_sync_files(
&release.sync_obj,