video: add udmabuf allocator
This commit is contained in:
parent
2579834a60
commit
62cd29056a
33 changed files with 883 additions and 256 deletions
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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")]
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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(())
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue