Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
79 changes: 60 additions & 19 deletions drm-ffi/src/syncobj.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use drm_sys::*;

use std::{
io,
os::unix::io::{AsRawFd, BorrowedFd},
os::fd::{AsRawFd, BorrowedFd},
};

/// Creates a syncobj.
Expand Down Expand Up @@ -39,22 +39,40 @@ pub fn destroy(fd: BorrowedFd<'_>, handle: u32) -> io::Result<drm_syncobj_destro
Ok(args)
}

/// Exports a syncobj as an inter-process file descriptor or as a poll()-able sync file.
pub fn handle_to_fd(
/// Exports a syncobj as an inter-process file descriptor.
pub fn handle_to_fd(fd: BorrowedFd<'_>, handle: u32) -> io::Result<drm_syncobj_handle> {
let mut args = drm_syncobj_handle {
handle,
flags: 0,
fd: 0,
pad: 0,
point: 0,
};

unsafe {
ioctl::syncobj::handle_to_fd(fd, &mut args)?;
}

Ok(args)
}

/// Exports a syncobj as a poll-able `sync_file` optionally for a specified timeline point.
pub fn handle_to_sync_file(
fd: BorrowedFd<'_>,
handle: u32,
export_sync_file: bool,
timeline_point: Option<u64>,
) -> io::Result<drm_syncobj_handle> {
let mut args = drm_syncobj_handle {
handle,
flags: if export_sync_file {
DRM_SYNCOBJ_HANDLE_TO_FD_FLAGS_EXPORT_SYNC_FILE
} else {
0
},
flags: DRM_SYNCOBJ_HANDLE_TO_FD_FLAGS_EXPORT_SYNC_FILE
| if timeline_point.is_some() {
DRM_SYNCOBJ_HANDLE_TO_FD_FLAGS_TIMELINE
} else {
0
},
fd: 0,
pad: 0,
point: 0, // TODO: Add support for TIMELINE sync files
point: timeline_point.unwrap_or(0),
};

unsafe {
Expand All @@ -64,22 +82,45 @@ pub fn handle_to_fd(
Ok(args)
}

/// Imports a file descriptor exported by [`handle_to_fd`] back into a process-local handle.
/// Imports a file descriptor exported by [`handle_to_fd()`] back into a process-local handle.
pub fn fd_to_handle(
fd: BorrowedFd<'_>,
syncobj_fd: BorrowedFd<'_>,
import_sync_file: bool,
opaque_fd: BorrowedFd<'_>,
) -> io::Result<drm_syncobj_handle> {
let mut args = drm_syncobj_handle {
handle: 0,
flags: if import_sync_file {
DRM_SYNCOBJ_FD_TO_HANDLE_FLAGS_IMPORT_SYNC_FILE
} else {
0
},
flags: 0,
fd: opaque_fd.as_raw_fd(),
pad: 0,
point: 0,
};

unsafe {
ioctl::syncobj::fd_to_handle(fd, &mut args)?;
}

Ok(args)
}

/// Imports a `sync_file` exported by [`handle_to_sync_file()`] into an existing process-local handle,
/// optionally for a specified timeline point.
pub fn sync_file_into_handle(
fd: BorrowedFd<'_>,
syncobj_fd: BorrowedFd<'_>,
handle: u32,
timeline_point: Option<u64>,
) -> io::Result<drm_syncobj_handle> {
let mut args = drm_syncobj_handle {
handle,
flags: DRM_SYNCOBJ_FD_TO_HANDLE_FLAGS_IMPORT_SYNC_FILE
| if timeline_point.is_some() {
DRM_SYNCOBJ_FD_TO_HANDLE_FLAGS_TIMELINE
} else {
0
},
fd: syncobj_fd.as_raw_fd(),
pad: 0,
point: 0, // TODO: Add support for TIMELINE sync files
point: timeline_point.unwrap_or(0),
};

unsafe {
Expand Down
2 changes: 1 addition & 1 deletion examples/syncobj.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ impl Card {
self.syncobj_signal(&[syncobj])?;

// Export fence set by previous ioctl to file descriptor.
self.syncobj_to_fd(syncobj, true)
self.syncobj_to_sync_file(syncobj, None)
};

// The sync file descriptor constitutes ownership of the fence, so the syncobj can be
Expand Down
35 changes: 25 additions & 10 deletions src/control/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -838,24 +838,39 @@ pub trait Device: super::Device {
Ok(())
}

/// Exports a syncobj as an inter-process file descriptor or as a poll()-able sync file.
fn syncobj_to_fd(
/// Exports a syncobj as an inter-process file descriptor.
fn syncobj_to_fd(&self, handle: syncobj::Handle) -> io::Result<OwnedFd> {
let args = ffi::syncobj::handle_to_fd(self.as_fd(), handle.into())?;
Ok(unsafe { OwnedFd::from_raw_fd(args.fd) })
}

/// Exports a syncobj as a poll-able sync file optionally for a specified timeline point.
fn syncobj_to_sync_file(
&self,
handle: syncobj::Handle,
export_sync_file: bool,
timeline_point: Option<u64>,
) -> io::Result<OwnedFd> {
let info = ffi::syncobj::handle_to_fd(self.as_fd(), handle.into(), export_sync_file)?;
Ok(unsafe { OwnedFd::from_raw_fd(info.fd) })
let args = ffi::syncobj::handle_to_sync_file(self.as_fd(), handle.into(), timeline_point)?;
Ok(unsafe { OwnedFd::from_raw_fd(args.fd) })
}

/// Imports a file descriptor exported by [`Self::syncobj_to_fd`] back into a process-local handle.
fn fd_to_syncobj(
fn fd_to_syncobj(&self, fd: BorrowedFd<'_>) -> io::Result<syncobj::Handle> {
let args = ffi::syncobj::fd_to_handle(self.as_fd(), fd)?;
Ok(from_u32(args.handle).unwrap())
}

/// Imports a sync file exported by [`Self::syncobj_to_sync_file`] into an existing process-local handle
/// optionally for a specified timeline point.
fn sync_file_into_syncobj(
&self,
fd: BorrowedFd<'_>,
import_sync_file: bool,
) -> io::Result<syncobj::Handle> {
let info = ffi::syncobj::fd_to_handle(self.as_fd(), fd, import_sync_file)?;
Ok(from_u32(info.handle).unwrap())
handle: syncobj::Handle,
timeline_point: Option<u64>,
) -> io::Result<()> {
let _ =
ffi::syncobj::sync_file_into_handle(self.as_fd(), fd, handle.into(), timeline_point)?;
Ok(())
}

/// Waits for one or more syncobjs to become signalled.
Expand Down