refactor: split cargo workspace
This commit is contained in:
parent
5db14936e7
commit
1c21bd1259
695 changed files with 32023 additions and 44964 deletions
201
crates/video-types/src/dmabuf.rs
Normal file
201
crates/video-types/src/dmabuf.rs
Normal file
|
|
@ -0,0 +1,201 @@
|
|||
use {
|
||||
crate::{LINEAR_MODIFIER, Modifier},
|
||||
arrayvec::ArrayVec,
|
||||
jay_formats::Format,
|
||||
jay_utils::{compat::IoctlNumber, numcell::NumCell, oserror::OsError},
|
||||
std::{cell::OnceCell, rc::Rc, sync::OnceLock},
|
||||
uapi::{
|
||||
_IOW, _IOWR, OwnedFd,
|
||||
c::{self, dev_t, ioctl},
|
||||
format_ustr,
|
||||
},
|
||||
};
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct DmaBufPlane {
|
||||
pub offset: u32,
|
||||
pub stride: u32,
|
||||
pub fd: Rc<OwnedFd>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct DmaBufIds {
|
||||
next: NumCell<u32>,
|
||||
}
|
||||
|
||||
impl Default for DmaBufIds {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
next: NumCell::new(1),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl DmaBufIds {
|
||||
pub fn next(&self) -> DmaBufId {
|
||||
DmaBufId(self.next.fetch_add(1))
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash, Ord, PartialOrd)]
|
||||
pub struct DmaBufId(u32);
|
||||
|
||||
impl DmaBufId {
|
||||
#[allow(dead_code)]
|
||||
pub fn raw(&self) -> u32 {
|
||||
self.0
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub fn from_raw(id: u32) -> Self {
|
||||
Self(id)
|
||||
}
|
||||
}
|
||||
|
||||
impl std::fmt::Display for DmaBufId {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
std::fmt::Display::fmt(&self.0, f)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct DmaBuf {
|
||||
pub id: DmaBufId,
|
||||
pub width: i32,
|
||||
pub height: i32,
|
||||
pub format: &'static Format,
|
||||
pub modifier: Modifier,
|
||||
pub planes: PlaneVec<DmaBufPlane>,
|
||||
pub is_disjoint: OnceCell<bool>,
|
||||
}
|
||||
|
||||
pub const MAX_PLANES: usize = 4;
|
||||
|
||||
pub type PlaneVec<T> = ArrayVec<T, MAX_PLANES>;
|
||||
|
||||
impl DmaBuf {
|
||||
pub fn is_disjoint(&self) -> bool {
|
||||
*self.is_disjoint.get_or_init(|| {
|
||||
if self.planes.len() <= 1 {
|
||||
return false;
|
||||
}
|
||||
let stat = match uapi::fstat(self.planes[0].fd.raw()) {
|
||||
Ok(s) => s,
|
||||
_ => return true,
|
||||
};
|
||||
for plane in &self.planes[1..] {
|
||||
let stat2 = match uapi::fstat(plane.fd.raw()) {
|
||||
Ok(s) => s,
|
||||
_ => return true,
|
||||
};
|
||||
if stat2.st_ino != stat.st_ino {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
false
|
||||
})
|
||||
}
|
||||
|
||||
pub fn is_one_file(&self) -> bool {
|
||||
!self.is_disjoint()
|
||||
}
|
||||
|
||||
pub fn udmabuf_size(&self) -> Option<usize> {
|
||||
if self.planes.len() != 1 {
|
||||
return None;
|
||||
}
|
||||
if self.modifier != LINEAR_MODIFIER {
|
||||
return None;
|
||||
}
|
||||
let stat = match uapi::fstat(self.planes[0].fd.raw()) {
|
||||
Ok(s) => s,
|
||||
_ => return None,
|
||||
};
|
||||
static DMABUF_DEV: OnceLock<dev_t> = OnceLock::new();
|
||||
match DMABUF_DEV.get() {
|
||||
Some(d) => {
|
||||
if stat.st_dev != *d {
|
||||
return None;
|
||||
}
|
||||
}
|
||||
None => {
|
||||
if dma_buf_export_sync_file(&self.planes[0].fd, DMA_BUF_SYNC_READ).is_err() {
|
||||
return None;
|
||||
}
|
||||
let _ = DMABUF_DEV.set(stat.st_dev);
|
||||
}
|
||||
}
|
||||
let path = format_ustr!("/sys/kernel/dmabuf/buffers/{}/exporter_name", stat.st_ino);
|
||||
let Ok(file) = uapi::open(path, c::O_RDONLY, 0) else {
|
||||
return None;
|
||||
};
|
||||
const MARKER: &[u8] = b"udmabuf\n";
|
||||
let mut buf = [0u8; MARKER.len()];
|
||||
if uapi::read(file.raw(), &mut buf).is_err() {
|
||||
return None;
|
||||
}
|
||||
if buf != MARKER {
|
||||
return None;
|
||||
}
|
||||
Some(stat.st_size as usize)
|
||||
}
|
||||
|
||||
pub fn import_sync_file(&self, flags: u32, sync_file: &OwnedFd) -> Result<(), OsError> {
|
||||
for plane in &self.planes {
|
||||
dma_buf_import_sync_file(&plane.fd, flags, sync_file)?;
|
||||
if self.is_one_file() {
|
||||
break;
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
const DMA_BUF_BASE: u64 = b'b' as _;
|
||||
|
||||
#[repr(C)]
|
||||
struct dma_buf_export_sync_file {
|
||||
flags: u32,
|
||||
fd: i32,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
struct dma_buf_import_sync_file {
|
||||
flags: u32,
|
||||
fd: i32,
|
||||
}
|
||||
|
||||
pub const DMA_BUF_SYNC_READ: u32 = 1 << 0;
|
||||
pub const DMA_BUF_SYNC_WRITE: u32 = 1 << 1;
|
||||
|
||||
const DMA_BUF_IOCTL_EXPORT_SYNC_FILE: IoctlNumber =
|
||||
_IOWR::<dma_buf_export_sync_file>(DMA_BUF_BASE, 2) as IoctlNumber;
|
||||
const DMA_BUF_IOCTL_IMPORT_SYNC_FILE: IoctlNumber =
|
||||
_IOW::<dma_buf_import_sync_file>(DMA_BUF_BASE, 3) as IoctlNumber;
|
||||
|
||||
pub fn dma_buf_export_sync_file(dmabuf: &OwnedFd, flags: u32) -> Result<OwnedFd, OsError> {
|
||||
let mut data = dma_buf_export_sync_file { flags, fd: -1 };
|
||||
let res = unsafe { ioctl(dmabuf.raw(), DMA_BUF_IOCTL_EXPORT_SYNC_FILE, &mut data) };
|
||||
if res != 0 {
|
||||
Err(OsError::default())
|
||||
} else {
|
||||
Ok(OwnedFd::new(data.fd))
|
||||
}
|
||||
}
|
||||
|
||||
pub fn dma_buf_import_sync_file(
|
||||
dmabuf: &OwnedFd,
|
||||
flags: u32,
|
||||
sync_file: &OwnedFd,
|
||||
) -> Result<(), OsError> {
|
||||
let mut data = dma_buf_import_sync_file {
|
||||
flags,
|
||||
fd: sync_file.raw(),
|
||||
};
|
||||
let res = unsafe { ioctl(dmabuf.raw(), DMA_BUF_IOCTL_IMPORT_SYNC_FILE, &mut data) };
|
||||
if res != 0 {
|
||||
Err(OsError::default())
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
48
crates/video-types/src/drm.rs
Normal file
48
crates/video-types/src/drm.rs
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
pub const DRM_MODE_OBJECT_CRTC: u32 = 0xcccccccc;
|
||||
pub const DRM_MODE_OBJECT_CONNECTOR: u32 = 0xc0c0c0c0;
|
||||
pub const DRM_MODE_OBJECT_ENCODER: u32 = 0xe0e0e0e0;
|
||||
pub const DRM_MODE_OBJECT_PROPERTY: u32 = 0xb0b0b0b0;
|
||||
pub const DRM_MODE_OBJECT_FB: u32 = 0xfbfbfbfb;
|
||||
pub const DRM_MODE_OBJECT_BLOB: u32 = 0xbbbbbbbb;
|
||||
pub const DRM_MODE_OBJECT_PLANE: u32 = 0xeeeeeeee;
|
||||
|
||||
pub trait DrmObject {
|
||||
const TYPE: u32;
|
||||
const NONE: Self;
|
||||
fn id(&self) -> u32;
|
||||
fn is_some(&self) -> bool;
|
||||
fn is_none(&self) -> bool;
|
||||
}
|
||||
|
||||
macro_rules! drm_obj {
|
||||
($name:ident, $ty:expr) => {
|
||||
#[repr(transparent)]
|
||||
#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash, Default, Ord, PartialOrd)]
|
||||
pub struct $name(pub u32);
|
||||
|
||||
impl DrmObject for $name {
|
||||
const TYPE: u32 = $ty;
|
||||
const NONE: Self = Self(0);
|
||||
|
||||
fn id(&self) -> u32 {
|
||||
self.0
|
||||
}
|
||||
|
||||
fn is_some(&self) -> bool {
|
||||
self.0 != 0
|
||||
}
|
||||
|
||||
fn is_none(&self) -> bool {
|
||||
self.0 == 0
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
drm_obj!(DrmCrtc, DRM_MODE_OBJECT_CRTC);
|
||||
drm_obj!(DrmConnector, DRM_MODE_OBJECT_CONNECTOR);
|
||||
drm_obj!(DrmEncoder, DRM_MODE_OBJECT_ENCODER);
|
||||
drm_obj!(DrmProperty, DRM_MODE_OBJECT_PROPERTY);
|
||||
drm_obj!(DrmFb, DRM_MODE_OBJECT_FB);
|
||||
drm_obj!(DrmBlob, DRM_MODE_OBJECT_BLOB);
|
||||
drm_obj!(DrmPlane, DRM_MODE_OBJECT_PLANE);
|
||||
10
crates/video-types/src/lib.rs
Normal file
10
crates/video-types/src/lib.rs
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
pub mod drm;
|
||||
pub mod dmabuf;
|
||||
|
||||
pub type Modifier = u64;
|
||||
|
||||
pub const INVALID_MODIFIER: Modifier = 0x00ff_ffff_ffff_ffff;
|
||||
pub const LINEAR_MODIFIER: Modifier = 0;
|
||||
|
||||
// This is required by AMD and therefore everyone else uses this too.
|
||||
pub const LINEAR_STRIDE_ALIGN: u64 = 256;
|
||||
Loading…
Add table
Add a link
Reference in a new issue