Merge pull request #768 from mahkoh/jorth/syncobj
all: syncobj is one word
This commit is contained in:
commit
19edb3ea95
20 changed files with 199 additions and 199 deletions
|
|
@ -2470,7 +2470,7 @@ impl MetalBackend {
|
||||||
}
|
}
|
||||||
let ctx = dev.ctx.get();
|
let ctx = dev.ctx.get();
|
||||||
if self.signaled_sync_file.is_none()
|
if self.signaled_sync_file.is_none()
|
||||||
&& let Some(sync) = ctx.gfx.sync_obj_ctx()
|
&& let Some(sync) = ctx.gfx.syncobj_ctx()
|
||||||
{
|
{
|
||||||
match sync.create_signaled_sync_file() {
|
match sync.create_signaled_sync_file() {
|
||||||
Ok(sf) => {
|
Ok(sf) => {
|
||||||
|
|
|
||||||
|
|
@ -185,7 +185,7 @@ impl Clients {
|
||||||
surfaces_by_xwayland_serial: Default::default(),
|
surfaces_by_xwayland_serial: Default::default(),
|
||||||
activation_tokens: Default::default(),
|
activation_tokens: Default::default(),
|
||||||
commit_timelines: Rc::new(CommitTimelines::new(
|
commit_timelines: Rc::new(CommitTimelines::new(
|
||||||
&global.wait_for_sync_obj,
|
&global.wait_for_syncobj,
|
||||||
&global.ring,
|
&global.ring,
|
||||||
&global.eng,
|
&global.eng,
|
||||||
slf,
|
slf,
|
||||||
|
|
|
||||||
|
|
@ -78,7 +78,7 @@ use {
|
||||||
tri::Try,
|
tri::Try,
|
||||||
},
|
},
|
||||||
version::VERSION,
|
version::VERSION,
|
||||||
video::drm::wait_for_sync_obj::WaitForSyncObj,
|
video::drm::wait_for_syncobj::WaitForSyncobj,
|
||||||
wheel::{Wheel, WheelError},
|
wheel::{Wheel, WheelError},
|
||||||
},
|
},
|
||||||
ahash::AHashSet,
|
ahash::AHashSet,
|
||||||
|
|
@ -318,7 +318,7 @@ fn start_compositor2(
|
||||||
double_click_distance: Cell::new(5),
|
double_click_distance: Cell::new(5),
|
||||||
create_default_seat: Cell::new(true),
|
create_default_seat: Cell::new(true),
|
||||||
subsurface_ids: Default::default(),
|
subsurface_ids: Default::default(),
|
||||||
wait_for_sync_obj: Rc::new(WaitForSyncObj::new(&ring, &engine)),
|
wait_for_syncobj: Rc::new(WaitForSyncobj::new(&ring, &engine)),
|
||||||
explicit_sync_enabled: Cell::new(true),
|
explicit_sync_enabled: Cell::new(true),
|
||||||
explicit_sync_supported: Default::default(),
|
explicit_sync_supported: Default::default(),
|
||||||
keyboard_state_ids: Default::default(),
|
keyboard_state_ids: Default::default(),
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,7 @@ use {
|
||||||
theme::Color,
|
theme::Color,
|
||||||
tree::{Node, OutputNode, Transform},
|
tree::{Node, OutputNode, Transform},
|
||||||
utils::clonecell::UnsafeCellCloneSafe,
|
utils::clonecell::UnsafeCellCloneSafe,
|
||||||
video::{Modifier, dmabuf::DmaBuf, drm::sync_obj::SyncObjCtx},
|
video::{Modifier, dmabuf::DmaBuf, drm::syncobj::SyncobjCtx},
|
||||||
},
|
},
|
||||||
ahash::AHashMap,
|
ahash::AHashMap,
|
||||||
indexmap::{IndexMap, IndexSet},
|
indexmap::{IndexMap, IndexSet},
|
||||||
|
|
@ -846,7 +846,7 @@ pub trait GfxContext: Debug {
|
||||||
format: &'static Format,
|
format: &'static Format,
|
||||||
) -> Result<Rc<dyn GfxInternalFramebuffer>, GfxError>;
|
) -> Result<Rc<dyn GfxInternalFramebuffer>, GfxError>;
|
||||||
|
|
||||||
fn sync_obj_ctx(&self) -> Option<&Rc<SyncObjCtx>>;
|
fn syncobj_ctx(&self) -> Option<&Rc<SyncobjCtx>>;
|
||||||
|
|
||||||
fn create_staging_buffer(
|
fn create_staging_buffer(
|
||||||
&self,
|
&self,
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,7 @@ use {
|
||||||
rect::Rect,
|
rect::Rect,
|
||||||
video::{
|
video::{
|
||||||
dmabuf::DmaBuf,
|
dmabuf::DmaBuf,
|
||||||
drm::{Drm, sync_obj::SyncObjCtx},
|
drm::{Drm, syncobj::SyncobjCtx},
|
||||||
gbm::GbmDevice,
|
gbm::GbmDevice,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
@ -75,7 +75,7 @@ pub(in crate::gfx_apis::gl) enum TexSourceType {
|
||||||
pub(in crate::gfx_apis::gl) struct GlRenderContext {
|
pub(in crate::gfx_apis::gl) struct GlRenderContext {
|
||||||
pub(crate) ctx: Rc<EglContext>,
|
pub(crate) ctx: Rc<EglContext>,
|
||||||
pub gbm: Rc<GbmDevice>,
|
pub gbm: Rc<GbmDevice>,
|
||||||
pub sync_ctx: Rc<SyncObjCtx>,
|
pub sync_ctx: Rc<SyncobjCtx>,
|
||||||
|
|
||||||
pub(crate) render_node: Rc<CString>,
|
pub(crate) render_node: Rc<CString>,
|
||||||
|
|
||||||
|
|
@ -166,7 +166,7 @@ impl GlRenderContext {
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
ctx: ctx.clone(),
|
ctx: ctx.clone(),
|
||||||
gbm: ctx.dpy.gbm.clone(),
|
gbm: ctx.dpy.gbm.clone(),
|
||||||
sync_ctx: Rc::new(SyncObjCtx::new(ctx.dpy.gbm.drm.fd())),
|
sync_ctx: Rc::new(SyncobjCtx::new(ctx.dpy.gbm.drm.fd())),
|
||||||
|
|
||||||
render_node: node.clone(),
|
render_node: node.clone(),
|
||||||
|
|
||||||
|
|
@ -343,7 +343,7 @@ impl GfxContext for GlRenderContext {
|
||||||
Ok(Rc::new(Framebuffer { ctx: self, gl: fb }))
|
Ok(Rc::new(Framebuffer { ctx: self, gl: fb }))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn sync_obj_ctx(&self) -> Option<&Rc<SyncObjCtx>> {
|
fn syncobj_ctx(&self) -> Option<&Rc<SyncobjCtx>> {
|
||||||
Some(&self.sync_ctx)
|
Some(&self.sync_ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -43,7 +43,7 @@ use {
|
||||||
utils::{errorfmt::ErrorFmt, oserror::OsError},
|
utils::{errorfmt::ErrorFmt, oserror::OsError},
|
||||||
video::{
|
video::{
|
||||||
dmabuf::DmaBuf,
|
dmabuf::DmaBuf,
|
||||||
drm::{Drm, DrmError, sync_obj::SyncObjCtx},
|
drm::{Drm, DrmError, syncobj::SyncobjCtx},
|
||||||
gbm::GbmError,
|
gbm::GbmError,
|
||||||
},
|
},
|
||||||
vulkan_core::VulkanCoreError,
|
vulkan_core::VulkanCoreError,
|
||||||
|
|
@ -358,7 +358,7 @@ impl GfxContext for Context {
|
||||||
Ok(fb)
|
Ok(fb)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn sync_obj_ctx(&self) -> Option<&Rc<SyncObjCtx>> {
|
fn syncobj_ctx(&self) -> Option<&Rc<SyncobjCtx>> {
|
||||||
Some(&self.0.device.sync_ctx)
|
Some(&self.0.device.sync_ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@ use {
|
||||||
utils::bitflags::BitflagsExt,
|
utils::bitflags::BitflagsExt,
|
||||||
video::{
|
video::{
|
||||||
dmabuf::DmaBufIds,
|
dmabuf::DmaBufIds,
|
||||||
drm::{Drm, sync_obj::SyncObjCtx},
|
drm::{Drm, syncobj::SyncobjCtx},
|
||||||
gbm::{GBM_BO_USE_RENDERING, GbmDevice},
|
gbm::{GBM_BO_USE_RENDERING, GbmDevice},
|
||||||
},
|
},
|
||||||
vulkan_core::{
|
vulkan_core::{
|
||||||
|
|
@ -60,7 +60,7 @@ pub struct VulkanDevice {
|
||||||
pub(super) physical_device: PhysicalDevice,
|
pub(super) physical_device: PhysicalDevice,
|
||||||
pub(super) render_node: Rc<CString>,
|
pub(super) render_node: Rc<CString>,
|
||||||
pub(super) gbm: Rc<GbmDevice>,
|
pub(super) gbm: Rc<GbmDevice>,
|
||||||
pub(super) sync_ctx: Rc<SyncObjCtx>,
|
pub(super) sync_ctx: Rc<SyncobjCtx>,
|
||||||
pub(super) instance: Rc<VulkanInstance>,
|
pub(super) instance: Rc<VulkanInstance>,
|
||||||
pub(super) device: Arc<Device>,
|
pub(super) device: Arc<Device>,
|
||||||
pub(super) external_memory_fd: external_memory_fd::Device,
|
pub(super) external_memory_fd: external_memory_fd::Device,
|
||||||
|
|
@ -553,7 +553,7 @@ impl VulkanInstance {
|
||||||
Ok(Rc::new(VulkanDevice {
|
Ok(Rc::new(VulkanDevice {
|
||||||
physical_device: phy_dev,
|
physical_device: phy_dev,
|
||||||
render_node,
|
render_node,
|
||||||
sync_ctx: Rc::new(SyncObjCtx::new(gbm.drm.fd())),
|
sync_ctx: Rc::new(SyncobjCtx::new(gbm.drm.fd())),
|
||||||
gbm: Rc::new(gbm),
|
gbm: Rc::new(gbm),
|
||||||
instance: self.clone(),
|
instance: self.clone(),
|
||||||
device: Arc::new(device),
|
device: Arc::new(device),
|
||||||
|
|
|
||||||
|
|
@ -90,7 +90,7 @@ use {
|
||||||
},
|
},
|
||||||
video::{
|
video::{
|
||||||
dmabuf::DMA_BUF_SYNC_READ,
|
dmabuf::DMA_BUF_SYNC_READ,
|
||||||
drm::sync_obj::{SyncObj, SyncObjPoint},
|
drm::syncobj::{Syncobj, SyncobjPoint},
|
||||||
},
|
},
|
||||||
wire::{
|
wire::{
|
||||||
WlOutputId, WlSurfaceId, WpColorManagementSurfaceFeedbackV1Id, ZwpIdleInhibitorV1Id,
|
WlOutputId, WlSurfaceId, WpColorManagementSurfaceFeedbackV1Id, ZwpIdleInhibitorV1Id,
|
||||||
|
|
@ -217,7 +217,7 @@ pub struct SurfaceBuffer {
|
||||||
pub buffer: AttachedBuffer,
|
pub buffer: AttachedBuffer,
|
||||||
sync_files: SmallMap<BufferResvUser, SyncFile, 1>,
|
sync_files: SmallMap<BufferResvUser, SyncFile, 1>,
|
||||||
pub release_sync: ReleaseSync,
|
pub release_sync: ReleaseSync,
|
||||||
release: Option<SyncObjRelease>,
|
release: Option<SyncobjRelease>,
|
||||||
_surface_release: SmallVec<[SurfaceRelease; 1]>,
|
_surface_release: SmallVec<[SurfaceRelease; 1]>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -303,7 +303,7 @@ pub struct WlSurface {
|
||||||
pub has_content_type_manager: Cell<bool>,
|
pub has_content_type_manager: Cell<bool>,
|
||||||
pub content_type: Cell<Option<ContentType>>,
|
pub content_type: Cell<Option<ContentType>>,
|
||||||
pub drm_feedback: CopyHashMap<ZwpLinuxDmabufFeedbackV1Id, Rc<ZwpLinuxDmabufFeedbackV1>>,
|
pub drm_feedback: CopyHashMap<ZwpLinuxDmabufFeedbackV1Id, Rc<ZwpLinuxDmabufFeedbackV1>>,
|
||||||
sync_obj_surface: CloneCell<Option<Rc<WpLinuxDrmSyncobjSurfaceV1>>>,
|
syncobj_surface: CloneCell<Option<Rc<WpLinuxDrmSyncobjSurfaceV1>>>,
|
||||||
destroyed: Cell<bool>,
|
destroyed: Cell<bool>,
|
||||||
commit_timeline: CommitTimeline,
|
commit_timeline: CommitTimeline,
|
||||||
alpha_modifier: CloneCell<Option<Rc<WpAlphaModifierSurfaceV1>>>,
|
alpha_modifier: CloneCell<Option<Rc<WpAlphaModifierSurfaceV1>>>,
|
||||||
|
|
@ -452,8 +452,8 @@ struct PendingState {
|
||||||
xdg_surface: Option<Box<PendingXdgSurfaceData>>,
|
xdg_surface: Option<Box<PendingXdgSurfaceData>>,
|
||||||
layer_surface: Option<Box<PendingLayerSurfaceData>>,
|
layer_surface: Option<Box<PendingLayerSurfaceData>>,
|
||||||
subsurfaces: AHashMap<SubsurfaceId, AttachedSubsurfaceState>,
|
subsurfaces: AHashMap<SubsurfaceId, AttachedSubsurfaceState>,
|
||||||
acquire_point: Option<(Rc<SyncObj>, SyncObjPoint)>,
|
acquire_point: Option<(Rc<Syncobj>, SyncobjPoint)>,
|
||||||
release_point: Option<SyncObjRelease>,
|
release_point: Option<SyncobjRelease>,
|
||||||
alpha_multiplier: Option<Option<f32>>,
|
alpha_multiplier: Option<Option<f32>>,
|
||||||
explicit_sync: bool,
|
explicit_sync: bool,
|
||||||
fifo_barrier_set: bool,
|
fifo_barrier_set: bool,
|
||||||
|
|
@ -652,7 +652,7 @@ impl WlSurface {
|
||||||
has_content_type_manager: Default::default(),
|
has_content_type_manager: Default::default(),
|
||||||
content_type: Default::default(),
|
content_type: Default::default(),
|
||||||
drm_feedback: Default::default(),
|
drm_feedback: Default::default(),
|
||||||
sync_obj_surface: Default::default(),
|
syncobj_surface: Default::default(),
|
||||||
destroyed: Cell::new(false),
|
destroyed: Cell::new(false),
|
||||||
commit_timeline: client.commit_timelines.create_timeline(),
|
commit_timeline: client.commit_timelines.create_timeline(),
|
||||||
alpha_modifier: Default::default(),
|
alpha_modifier: Default::default(),
|
||||||
|
|
@ -1541,7 +1541,7 @@ impl WlSurface {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn verify_explicit_sync(&self, pending: &mut PendingState) -> Result<(), WlSurfaceError> {
|
fn verify_explicit_sync(&self, pending: &mut PendingState) -> Result<(), WlSurfaceError> {
|
||||||
pending.explicit_sync = self.sync_obj_surface.is_some();
|
pending.explicit_sync = self.syncobj_surface.is_some();
|
||||||
if !pending.explicit_sync {
|
if !pending.explicit_sync {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
|
@ -2255,47 +2255,47 @@ impl Drop for FrameRequest {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct SyncObjRelease {
|
pub struct SyncobjRelease {
|
||||||
state: Rc<State>,
|
state: Rc<State>,
|
||||||
committed: bool,
|
committed: bool,
|
||||||
syncobj: Option<Rc<SyncObj>>,
|
syncobj: Option<Rc<Syncobj>>,
|
||||||
point: SyncObjPoint,
|
point: SyncobjPoint,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SyncObjRelease {
|
impl SyncobjRelease {
|
||||||
fn signal(&mut self, sync_files: Option<&SmallVec<[(BufferResvUser, SyncFile); 1]>>) {
|
fn signal(&mut self, sync_files: Option<&SmallVec<[(BufferResvUser, SyncFile); 1]>>) {
|
||||||
if !self.committed {
|
if !self.committed {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let Some(sync_obj) = self.syncobj.take() else {
|
let Some(syncobj) = self.syncobj.take() else {
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
let Some(ctx) = self.state.render_ctx.get() else {
|
let Some(ctx) = self.state.render_ctx.get() else {
|
||||||
log::error!("Cannot signal release point because there is no render context");
|
log::error!("Cannot signal release point because there is no render context");
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
let Some(ctx) = ctx.sync_obj_ctx() else {
|
let Some(ctx) = ctx.syncobj_ctx() else {
|
||||||
log::error!("Cannot signal release point because there is no syncobj context");
|
log::error!("Cannot signal release point because there is no syncobj context");
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
if let Some(sync_files) = sync_files
|
if let Some(sync_files) = sync_files
|
||||||
&& sync_files.is_not_empty()
|
&& sync_files.is_not_empty()
|
||||||
{
|
{
|
||||||
let res = ctx.import_sync_files(&sync_obj, self.point, sync_files.iter().map(|f| &f.1));
|
let res = ctx.import_sync_files(&syncobj, self.point, sync_files.iter().map(|f| &f.1));
|
||||||
match res {
|
match res {
|
||||||
Ok(_) => return,
|
Ok(_) => return,
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
log::error!("Could not import sync files into sync obj: {}", ErrorFmt(e));
|
log::error!("Could not import sync files into syncobj: {}", ErrorFmt(e));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if let Err(e) = ctx.signal(&sync_obj, self.point) {
|
if let Err(e) = ctx.signal(&syncobj, self.point) {
|
||||||
log::error!("Could not signal release point: {}", ErrorFmt(e));
|
log::error!("Could not signal release point: {}", ErrorFmt(e));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Drop for SyncObjRelease {
|
impl Drop for SyncobjRelease {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
self.signal(None);
|
self.signal(None);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -22,8 +22,8 @@ use {
|
||||||
},
|
},
|
||||||
video::drm::{
|
video::drm::{
|
||||||
DrmError,
|
DrmError,
|
||||||
sync_obj::{SyncObj, SyncObjPoint},
|
syncobj::{Syncobj, SyncobjPoint},
|
||||||
wait_for_sync_obj::{SyncObjWaiter, WaitForSyncObj, WaitForSyncObjHandle},
|
wait_for_syncobj::{SyncobjWaiter, WaitForSyncobj, WaitForSyncobjHandle},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
isnt::std_1::{primitive::IsntSliceExt, vec::IsntVecExt},
|
isnt::std_1::{primitive::IsntSliceExt, vec::IsntVecExt},
|
||||||
|
|
@ -45,7 +45,7 @@ linear_ids!(CommitTimelineIds, CommitTimelineId, u64);
|
||||||
|
|
||||||
pub struct CommitTimelines {
|
pub struct CommitTimelines {
|
||||||
next_id: CommitTimelineIds,
|
next_id: CommitTimelineIds,
|
||||||
wfs: Rc<WaitForSyncObj>,
|
wfs: Rc<WaitForSyncobj>,
|
||||||
ring: Rc<IoUring>,
|
ring: Rc<IoUring>,
|
||||||
depth: NumCell<usize>,
|
depth: NumCell<usize>,
|
||||||
gc: CopyHashMap<CommitTimelineId, LinkedList<Entry>>,
|
gc: CopyHashMap<CommitTimelineId, LinkedList<Entry>>,
|
||||||
|
|
@ -113,7 +113,7 @@ pub enum CommitTimelineError {
|
||||||
|
|
||||||
impl CommitTimelines {
|
impl CommitTimelines {
|
||||||
pub fn new(
|
pub fn new(
|
||||||
wfs: &Rc<WaitForSyncObj>,
|
wfs: &Rc<WaitForSyncobj>,
|
||||||
ring: &Rc<IoUring>,
|
ring: &Rc<IoUring>,
|
||||||
eng: &Rc<AsyncEngine>,
|
eng: &Rc<AsyncEngine>,
|
||||||
client: &Weak<Client>,
|
client: &Weak<Client>,
|
||||||
|
|
@ -238,7 +238,7 @@ impl CommitTimeline {
|
||||||
EntryKind::Commit(Commit {
|
EntryKind::Commit(Commit {
|
||||||
surface: surface.clone(),
|
surface: surface.clone(),
|
||||||
pending: RefCell::new(mem::take(pending)),
|
pending: RefCell::new(mem::take(pending)),
|
||||||
sync_obj: NumCell::new(points.len()),
|
syncobj: NumCell::new(points.len()),
|
||||||
wait_handles: Cell::new(Default::default()),
|
wait_handles: Cell::new(Default::default()),
|
||||||
pending_uploads: NumCell::new(pending_uploads),
|
pending_uploads: NumCell::new(pending_uploads),
|
||||||
shm_upload: RefCell::new(ShmUploadState::None),
|
shm_upload: RefCell::new(ShmUploadState::None),
|
||||||
|
|
@ -256,11 +256,11 @@ impl CommitTimeline {
|
||||||
};
|
};
|
||||||
if points.is_not_empty() {
|
if points.is_not_empty() {
|
||||||
let mut wait_handles = SmallVec::new();
|
let mut wait_handles = SmallVec::new();
|
||||||
for (sync_obj, point) in points {
|
for (syncobj, point) in points {
|
||||||
let handle = self
|
let handle = self
|
||||||
.shared
|
.shared
|
||||||
.wfs
|
.wfs
|
||||||
.wait(&sync_obj, point, true, noderef.clone())
|
.wait(&syncobj, point, true, noderef.clone())
|
||||||
.map_err(CommitTimelineError::RegisterWait)?;
|
.map_err(CommitTimelineError::RegisterWait)?;
|
||||||
wait_handles.push(handle);
|
wait_handles.push(handle);
|
||||||
}
|
}
|
||||||
|
|
@ -336,7 +336,7 @@ impl CommitTimeline {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SyncObjWaiter for NodeRef<Entry> {
|
impl SyncobjWaiter for NodeRef<Entry> {
|
||||||
fn done(self: Rc<Self>, result: Result<(), DrmError>) {
|
fn done(self: Rc<Self>, result: Result<(), DrmError>) {
|
||||||
let EntryKind::Commit(commit) = &self.kind else {
|
let EntryKind::Commit(commit) = &self.kind else {
|
||||||
unreachable!();
|
unreachable!();
|
||||||
|
|
@ -345,7 +345,7 @@ impl SyncObjWaiter for NodeRef<Entry> {
|
||||||
commit.surface.client.error(CommitTimelineError::Wait(e));
|
commit.surface.client.error(CommitTimelineError::Wait(e));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
commit.sync_obj.fetch_sub(1);
|
commit.syncobj.fetch_sub(1);
|
||||||
flush_commit(&self, commit);
|
flush_commit(&self, commit);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -440,8 +440,8 @@ enum CommitTimesState {
|
||||||
struct Commit {
|
struct Commit {
|
||||||
surface: Rc<WlSurface>,
|
surface: Rc<WlSurface>,
|
||||||
pending: RefCell<Box<PendingState>>,
|
pending: RefCell<Box<PendingState>>,
|
||||||
sync_obj: NumCell<usize>,
|
syncobj: NumCell<usize>,
|
||||||
wait_handles: Cell<SmallVec<[WaitForSyncObjHandle; 1]>>,
|
wait_handles: Cell<SmallVec<[WaitForSyncobjHandle; 1]>>,
|
||||||
pending_uploads: NumCell<usize>,
|
pending_uploads: NumCell<usize>,
|
||||||
shm_upload: RefCell<ShmUploadState>,
|
shm_upload: RefCell<ShmUploadState>,
|
||||||
num_pending_polls: NumCell<usize>,
|
num_pending_polls: NumCell<usize>,
|
||||||
|
|
@ -471,7 +471,7 @@ impl NodeRef<Entry> {
|
||||||
match &self.kind {
|
match &self.kind {
|
||||||
EntryKind::Commit(c) => {
|
EntryKind::Commit(c) => {
|
||||||
let mut has_unmet_dependencies = false;
|
let mut has_unmet_dependencies = false;
|
||||||
let may_access_buffer = c.sync_obj.get() == 0 && c.num_pending_polls.get() == 0;
|
let may_access_buffer = c.syncobj.get() == 0 && c.num_pending_polls.get() == 0;
|
||||||
if may_access_buffer {
|
if may_access_buffer {
|
||||||
if c.pending_uploads.get() > 0 {
|
if c.pending_uploads.get() > 0 {
|
||||||
check_shm_uploads(c)?;
|
check_shm_uploads(c)?;
|
||||||
|
|
@ -687,7 +687,7 @@ fn schedule_async_upload(
|
||||||
.map_err(WlSurfaceError::PrepareAsyncUpload)
|
.map_err(WlSurfaceError::PrepareAsyncUpload)
|
||||||
}
|
}
|
||||||
|
|
||||||
type Point = (Rc<SyncObj>, SyncObjPoint);
|
type Point = (Rc<Syncobj>, SyncobjPoint);
|
||||||
|
|
||||||
struct CommitDataCollector {
|
struct CommitDataCollector {
|
||||||
acquire_points: SmallVec<[Point; 1]>,
|
acquire_points: SmallVec<[Point; 1]>,
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,10 @@
|
||||||
use {
|
use {
|
||||||
crate::{
|
crate::{
|
||||||
client::{Client, ClientError},
|
client::{Client, ClientError},
|
||||||
ifs::wl_surface::{SyncObjRelease, WlSurface},
|
ifs::wl_surface::{SyncobjRelease, WlSurface},
|
||||||
leaks::Tracker,
|
leaks::Tracker,
|
||||||
object::{Object, Version},
|
object::{Object, Version},
|
||||||
video::drm::sync_obj::SyncObjPoint,
|
video::drm::syncobj::SyncobjPoint,
|
||||||
wire::{WpLinuxDrmSyncobjSurfaceV1Id, wp_linux_drm_syncobj_surface_v1::*},
|
wire::{WpLinuxDrmSyncobjSurfaceV1Id, wp_linux_drm_syncobj_surface_v1::*},
|
||||||
},
|
},
|
||||||
std::rc::Rc,
|
std::rc::Rc,
|
||||||
|
|
@ -36,10 +36,10 @@ impl WpLinuxDrmSyncobjSurfaceV1 {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn install(self: &Rc<Self>) -> Result<(), WpLinuxDrmSyncobjSurfaceV1Error> {
|
pub fn install(self: &Rc<Self>) -> Result<(), WpLinuxDrmSyncobjSurfaceV1Error> {
|
||||||
if self.surface.sync_obj_surface.is_some() {
|
if self.surface.syncobj_surface.is_some() {
|
||||||
return Err(WpLinuxDrmSyncobjSurfaceV1Error::Exists);
|
return Err(WpLinuxDrmSyncobjSurfaceV1Error::Exists);
|
||||||
}
|
}
|
||||||
self.surface.sync_obj_surface.set(Some(self.clone()));
|
self.surface.syncobj_surface.set(Some(self.clone()));
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -48,7 +48,7 @@ impl WpLinuxDrmSyncobjSurfaceV1RequestHandler for WpLinuxDrmSyncobjSurfaceV1 {
|
||||||
type Error = WpLinuxDrmSyncobjSurfaceV1Error;
|
type Error = WpLinuxDrmSyncobjSurfaceV1Error;
|
||||||
|
|
||||||
fn destroy(&self, _req: Destroy, _slf: &Rc<Self>) -> Result<(), Self::Error> {
|
fn destroy(&self, _req: Destroy, _slf: &Rc<Self>) -> Result<(), Self::Error> {
|
||||||
self.surface.sync_obj_surface.take();
|
self.surface.syncobj_surface.take();
|
||||||
let pending = &mut *self.surface.pending.borrow_mut();
|
let pending = &mut *self.surface.pending.borrow_mut();
|
||||||
pending.release_point.take();
|
pending.release_point.take();
|
||||||
pending.acquire_point.take();
|
pending.acquire_point.take();
|
||||||
|
|
@ -57,19 +57,19 @@ impl WpLinuxDrmSyncobjSurfaceV1RequestHandler for WpLinuxDrmSyncobjSurfaceV1 {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_acquire_point(&self, req: SetAcquirePoint, _slf: &Rc<Self>) -> Result<(), Self::Error> {
|
fn set_acquire_point(&self, req: SetAcquirePoint, _slf: &Rc<Self>) -> Result<(), Self::Error> {
|
||||||
let point = SyncObjPoint(req.point);
|
let point = SyncobjPoint(req.point);
|
||||||
let timeline = self.client.lookup(req.timeline)?;
|
let timeline = self.client.lookup(req.timeline)?;
|
||||||
self.surface.pending.borrow_mut().acquire_point = Some((timeline.sync_obj.clone(), point));
|
self.surface.pending.borrow_mut().acquire_point = Some((timeline.syncobj.clone(), point));
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_release_point(&self, req: SetReleasePoint, _slf: &Rc<Self>) -> Result<(), Self::Error> {
|
fn set_release_point(&self, req: SetReleasePoint, _slf: &Rc<Self>) -> Result<(), Self::Error> {
|
||||||
let point = SyncObjPoint(req.point);
|
let point = SyncobjPoint(req.point);
|
||||||
let timeline = self.client.lookup(req.timeline)?;
|
let timeline = self.client.lookup(req.timeline)?;
|
||||||
self.surface.pending.borrow_mut().release_point = Some(SyncObjRelease {
|
self.surface.pending.borrow_mut().release_point = Some(SyncobjRelease {
|
||||||
state: self.client.state.clone(),
|
state: self.client.state.clone(),
|
||||||
committed: false,
|
committed: false,
|
||||||
syncobj: Some(timeline.sync_obj.clone()),
|
syncobj: Some(timeline.syncobj.clone()),
|
||||||
point,
|
point,
|
||||||
});
|
});
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ use {
|
||||||
leaks::Tracker,
|
leaks::Tracker,
|
||||||
object::{Object, Version},
|
object::{Object, Version},
|
||||||
state::State,
|
state::State,
|
||||||
video::drm::sync_obj::SyncObj,
|
video::drm::syncobj::Syncobj,
|
||||||
wire::{WpLinuxDrmSyncobjManagerV1Id, wp_linux_drm_syncobj_manager_v1::*},
|
wire::{WpLinuxDrmSyncobjManagerV1Id, wp_linux_drm_syncobj_manager_v1::*},
|
||||||
},
|
},
|
||||||
std::rc::Rc,
|
std::rc::Rc,
|
||||||
|
|
@ -97,11 +97,11 @@ impl WpLinuxDrmSyncobjManagerV1RequestHandler for WpLinuxDrmSyncobjManagerV1 {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn import_timeline(&self, req: ImportTimeline, _slf: &Rc<Self>) -> Result<(), Self::Error> {
|
fn import_timeline(&self, req: ImportTimeline, _slf: &Rc<Self>) -> Result<(), Self::Error> {
|
||||||
let sync_obj = Rc::new(SyncObj::new(&req.fd));
|
let syncobj = Rc::new(Syncobj::new(&req.fd));
|
||||||
let sync = Rc::new(WpLinuxDrmSyncobjTimelineV1::new(
|
let sync = Rc::new(WpLinuxDrmSyncobjTimelineV1::new(
|
||||||
req.id,
|
req.id,
|
||||||
&self.client,
|
&self.client,
|
||||||
&sync_obj,
|
&syncobj,
|
||||||
self.version,
|
self.version,
|
||||||
));
|
));
|
||||||
track!(self.client, sync);
|
track!(self.client, sync);
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ use {
|
||||||
client::{Client, ClientError},
|
client::{Client, ClientError},
|
||||||
leaks::Tracker,
|
leaks::Tracker,
|
||||||
object::{Object, Version},
|
object::{Object, Version},
|
||||||
video::drm::sync_obj::SyncObj,
|
video::drm::syncobj::Syncobj,
|
||||||
wire::{WpLinuxDrmSyncobjTimelineV1Id, wp_linux_drm_syncobj_timeline_v1::*},
|
wire::{WpLinuxDrmSyncobjTimelineV1Id, wp_linux_drm_syncobj_timeline_v1::*},
|
||||||
},
|
},
|
||||||
std::rc::Rc,
|
std::rc::Rc,
|
||||||
|
|
@ -13,7 +13,7 @@ use {
|
||||||
pub struct WpLinuxDrmSyncobjTimelineV1 {
|
pub struct WpLinuxDrmSyncobjTimelineV1 {
|
||||||
id: WpLinuxDrmSyncobjTimelineV1Id,
|
id: WpLinuxDrmSyncobjTimelineV1Id,
|
||||||
client: Rc<Client>,
|
client: Rc<Client>,
|
||||||
pub sync_obj: Rc<SyncObj>,
|
pub syncobj: Rc<Syncobj>,
|
||||||
pub tracker: Tracker<Self>,
|
pub tracker: Tracker<Self>,
|
||||||
version: Version,
|
version: Version,
|
||||||
}
|
}
|
||||||
|
|
@ -22,14 +22,14 @@ impl WpLinuxDrmSyncobjTimelineV1 {
|
||||||
pub fn new(
|
pub fn new(
|
||||||
id: WpLinuxDrmSyncobjTimelineV1Id,
|
id: WpLinuxDrmSyncobjTimelineV1Id,
|
||||||
client: &Rc<Client>,
|
client: &Rc<Client>,
|
||||||
sync_obj: &Rc<SyncObj>,
|
syncobj: &Rc<Syncobj>,
|
||||||
version: Version,
|
version: Version,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Self {
|
Self {
|
||||||
id,
|
id,
|
||||||
client: client.clone(),
|
client: client.clone(),
|
||||||
tracker: Default::default(),
|
tracker: Default::default(),
|
||||||
sync_obj: sync_obj.clone(),
|
syncobj: syncobj.clone(),
|
||||||
version,
|
version,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@ use {
|
||||||
},
|
},
|
||||||
rect::{Rect, Region},
|
rect::{Rect, Region},
|
||||||
theme::Color,
|
theme::Color,
|
||||||
video::{LINEAR_MODIFIER, dmabuf::DmaBuf, drm::sync_obj::SyncObjCtx},
|
video::{LINEAR_MODIFIER, dmabuf::DmaBuf, drm::syncobj::SyncobjCtx},
|
||||||
},
|
},
|
||||||
ahash::AHashMap,
|
ahash::AHashMap,
|
||||||
indexmap::IndexSet,
|
indexmap::IndexSet,
|
||||||
|
|
@ -194,7 +194,7 @@ impl GfxContext for TestGfxCtx {
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn sync_obj_ctx(&self) -> Option<&Rc<SyncObjCtx>> {
|
fn syncobj_ctx(&self) -> Option<&Rc<SyncobjCtx>> {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@ use {
|
||||||
test_object::TestObject,
|
test_object::TestObject,
|
||||||
test_transport::TestTransport,
|
test_transport::TestTransport,
|
||||||
},
|
},
|
||||||
video::drm::sync_obj::SyncObj,
|
video::drm::syncobj::Syncobj,
|
||||||
wire::{WpLinuxDrmSyncobjManagerV1Id, wp_linux_drm_syncobj_manager_v1::*},
|
wire::{WpLinuxDrmSyncobjManagerV1Id, wp_linux_drm_syncobj_manager_v1::*},
|
||||||
},
|
},
|
||||||
std::{cell::Cell, rc::Rc},
|
std::{cell::Cell, rc::Rc},
|
||||||
|
|
@ -52,7 +52,7 @@ impl TestSyncobjManager {
|
||||||
Ok(obj)
|
Ok(obj)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn import_timeline(&self, syncobj: &SyncObj) -> TestResult<Rc<TestSyncobjTimeline>> {
|
pub fn import_timeline(&self, syncobj: &Syncobj) -> TestResult<Rc<TestSyncobjTimeline>> {
|
||||||
let obj = Rc::new(TestSyncobjTimeline {
|
let obj = Rc::new(TestSyncobjTimeline {
|
||||||
id: self.tran.id(),
|
id: self.tran.id(),
|
||||||
tran: self.tran.clone(),
|
tran: self.tran.clone(),
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ use {
|
||||||
it::{test_error::TestResult, testrun::TestRun},
|
it::{test_error::TestResult, testrun::TestRun},
|
||||||
theme::Color,
|
theme::Color,
|
||||||
utils::errorfmt::ErrorFmt,
|
utils::errorfmt::ErrorFmt,
|
||||||
video::drm::{DrmError, sync_obj::SyncObjPoint, wait_for_sync_obj::SyncObjWaiter},
|
video::drm::{DrmError, syncobj::SyncobjPoint, wait_for_syncobj::SyncobjWaiter},
|
||||||
},
|
},
|
||||||
std::{cell::Cell, rc::Rc},
|
std::{cell::Cell, rc::Rc},
|
||||||
};
|
};
|
||||||
|
|
@ -14,7 +14,7 @@ async fn test(run: Rc<TestRun>) -> TestResult {
|
||||||
let _ds = run.create_default_setup2(true).await?;
|
let _ds = run.create_default_setup2(true).await?;
|
||||||
|
|
||||||
struct Waiter(Cell<bool>);
|
struct Waiter(Cell<bool>);
|
||||||
impl SyncObjWaiter for Waiter {
|
impl SyncobjWaiter for Waiter {
|
||||||
fn done(self: Rc<Self>, result: Result<(), DrmError>) {
|
fn done(self: Rc<Self>, result: Result<(), DrmError>) {
|
||||||
result.unwrap();
|
result.unwrap();
|
||||||
self.0.set(true);
|
self.0.set(true);
|
||||||
|
|
@ -23,13 +23,13 @@ async fn test(run: Rc<TestRun>) -> TestResult {
|
||||||
let waiter = Rc::new(Waiter(Cell::new(false)));
|
let waiter = Rc::new(Waiter(Cell::new(false)));
|
||||||
|
|
||||||
let eng = run.state.render_ctx.get().unwrap();
|
let eng = run.state.render_ctx.get().unwrap();
|
||||||
let Some(ctx) = eng.sync_obj_ctx() else {
|
let Some(ctx) = eng.syncobj_ctx() else {
|
||||||
log::warn!(
|
log::warn!(
|
||||||
"Cannot test explicit sync on this system: render context does not support sync objects"
|
"Cannot test explicit sync on this system: render context does not support sync objects"
|
||||||
);
|
);
|
||||||
return Ok(());
|
return Ok(());
|
||||||
};
|
};
|
||||||
let syncobj = match ctx.create_sync_obj() {
|
let syncobj = match ctx.create_syncobj() {
|
||||||
Ok(s) => Rc::new(s),
|
Ok(s) => Rc::new(s),
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
log::warn!("Cannot test explicit sync on this system: {}", ErrorFmt(e));
|
log::warn!("Cannot test explicit sync on this system: {}", ErrorFmt(e));
|
||||||
|
|
@ -38,8 +38,8 @@ async fn test(run: Rc<TestRun>) -> TestResult {
|
||||||
};
|
};
|
||||||
let _wait_handle =
|
let _wait_handle =
|
||||||
run.state
|
run.state
|
||||||
.wait_for_sync_obj
|
.wait_for_syncobj
|
||||||
.wait(&syncobj, SyncObjPoint(2), true, waiter.clone())?;
|
.wait(&syncobj, SyncobjPoint(2), true, waiter.clone())?;
|
||||||
|
|
||||||
let client = run.create_client().await?;
|
let client = run.create_client().await?;
|
||||||
|
|
||||||
|
|
@ -62,7 +62,7 @@ async fn test(run: Rc<TestRun>) -> TestResult {
|
||||||
client.sync().await;
|
client.sync().await;
|
||||||
tassert_eq!(waiter.0.get(), false);
|
tassert_eq!(waiter.0.get(), false);
|
||||||
|
|
||||||
ctx.signal(&syncobj, SyncObjPoint(1))?;
|
ctx.signal(&syncobj, SyncobjPoint(1))?;
|
||||||
|
|
||||||
client.sync().await;
|
client.sync().await;
|
||||||
tassert_eq!(waiter.0.get(), true);
|
tassert_eq!(waiter.0.get(), true);
|
||||||
|
|
|
||||||
12
src/state.rs
12
src/state.rs
|
|
@ -121,7 +121,7 @@ use {
|
||||||
},
|
},
|
||||||
video::{
|
video::{
|
||||||
dmabuf::DmaBufIds,
|
dmabuf::DmaBufIds,
|
||||||
drm::{Drm, wait_for_sync_obj::WaitForSyncObj},
|
drm::{Drm, wait_for_syncobj::WaitForSyncobj},
|
||||||
},
|
},
|
||||||
wheel::Wheel,
|
wheel::Wheel,
|
||||||
wire::{
|
wire::{
|
||||||
|
|
@ -230,7 +230,7 @@ pub struct State {
|
||||||
pub double_click_distance: Cell<i32>,
|
pub double_click_distance: Cell<i32>,
|
||||||
pub create_default_seat: Cell<bool>,
|
pub create_default_seat: Cell<bool>,
|
||||||
pub subsurface_ids: SubsurfaceIds,
|
pub subsurface_ids: SubsurfaceIds,
|
||||||
pub wait_for_sync_obj: Rc<WaitForSyncObj>,
|
pub wait_for_syncobj: Rc<WaitForSyncobj>,
|
||||||
pub explicit_sync_enabled: Cell<bool>,
|
pub explicit_sync_enabled: Cell<bool>,
|
||||||
pub explicit_sync_supported: Cell<bool>,
|
pub explicit_sync_supported: Cell<bool>,
|
||||||
pub keyboard_state_ids: KeyboardStateIds,
|
pub keyboard_state_ids: KeyboardStateIds,
|
||||||
|
|
@ -627,8 +627,8 @@ impl State {
|
||||||
self.cursors.set(None);
|
self.cursors.set(None);
|
||||||
self.drm_feedback.set(None);
|
self.drm_feedback.set(None);
|
||||||
self.icons.clear();
|
self.icons.clear();
|
||||||
self.wait_for_sync_obj
|
self.wait_for_syncobj
|
||||||
.set_ctx(ctx.as_ref().and_then(|c| c.sync_obj_ctx().cloned()));
|
.set_ctx(ctx.as_ref().and_then(|c| c.syncobj_ctx().cloned()));
|
||||||
|
|
||||||
'handle_new_feedback: {
|
'handle_new_feedback: {
|
||||||
if let Some(ctx) = &ctx {
|
if let Some(ctx) = &ctx {
|
||||||
|
|
@ -705,7 +705,7 @@ impl State {
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(ctx) = &ctx {
|
if let Some(ctx) = &ctx {
|
||||||
if let Some(ctx) = ctx.sync_obj_ctx()
|
if let Some(ctx) = ctx.syncobj_ctx()
|
||||||
&& ctx.supports_async_wait()
|
&& ctx.supports_async_wait()
|
||||||
{
|
{
|
||||||
self.explicit_sync_supported.set(true);
|
self.explicit_sync_supported.set(true);
|
||||||
|
|
@ -1121,7 +1121,7 @@ impl State {
|
||||||
self.cursor_user_groups.clear();
|
self.cursor_user_groups.clear();
|
||||||
self.cursor_user_group_hardware_cursor.take();
|
self.cursor_user_group_hardware_cursor.take();
|
||||||
self.cpu_worker.clear();
|
self.cpu_worker.clear();
|
||||||
self.wait_for_sync_obj.clear();
|
self.wait_for_syncobj.clear();
|
||||||
self.xdg_surface_configure_events.clear();
|
self.xdg_surface_configure_events.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
pub mod sync_obj;
|
pub mod syncobj;
|
||||||
mod sys;
|
mod sys;
|
||||||
pub mod wait_for_sync_obj;
|
pub mod wait_for_syncobj;
|
||||||
pub use consts::*;
|
pub use consts::*;
|
||||||
|
|
||||||
use {
|
use {
|
||||||
|
|
@ -117,27 +117,27 @@ pub enum DrmError {
|
||||||
Version(#[source] OsError),
|
Version(#[source] OsError),
|
||||||
#[error("Format of IN_FORMATS property is invalid")]
|
#[error("Format of IN_FORMATS property is invalid")]
|
||||||
InFormats,
|
InFormats,
|
||||||
#[error("Could not import a sync obj")]
|
#[error("Could not import a syncobj")]
|
||||||
ImportSyncObj(#[source] OsError),
|
ImportSyncobj(#[source] OsError),
|
||||||
#[error("Could not create a sync obj")]
|
#[error("Could not create a syncobj")]
|
||||||
CreateSyncObj(#[source] OsError),
|
CreateSyncobj(#[source] OsError),
|
||||||
#[error("Could not export a sync obj")]
|
#[error("Could not export a syncobj")]
|
||||||
ExportSyncObj(#[source] OsError),
|
ExportSyncobj(#[source] OsError),
|
||||||
#[error("Could not register an eventfd with a sync obj")]
|
#[error("Could not register an eventfd with a syncobj")]
|
||||||
RegisterEventfd(#[source] OsError),
|
RegisterEventfd(#[source] OsError),
|
||||||
#[error("Could not create an eventfd")]
|
#[error("Could not create an eventfd")]
|
||||||
EventFd(#[source] OsError),
|
EventFd(#[source] OsError),
|
||||||
#[error("Could not read from an eventfd")]
|
#[error("Could not read from an eventfd")]
|
||||||
ReadEventFd(#[source] IoUringError),
|
ReadEventFd(#[source] IoUringError),
|
||||||
#[error("No sync obj context available")]
|
#[error("No syncobj context available")]
|
||||||
NoSyncObjContextAvailable,
|
NoSyncobjContextAvailable,
|
||||||
#[error("Could not signal the sync obj")]
|
#[error("Could not signal the syncobj")]
|
||||||
SignalSyncObj(#[source] OsError),
|
SignalSyncobj(#[source] OsError),
|
||||||
#[error("Could not transfer a sync obj point")]
|
#[error("Could not transfer a syncobj point")]
|
||||||
TransferPoint(#[source] OsError),
|
TransferPoint(#[source] OsError),
|
||||||
#[error("Could not merge two sync files")]
|
#[error("Could not merge two sync files")]
|
||||||
Merge(#[source] OsError),
|
Merge(#[source] OsError),
|
||||||
#[error("Could not import a sync file into a sync obj")]
|
#[error("Could not import a sync file into a syncobj")]
|
||||||
ImportSyncFile(#[source] OsError),
|
ImportSyncFile(#[source] OsError),
|
||||||
#[error("Could not create a lease")]
|
#[error("Could not create a lease")]
|
||||||
CreateLease(#[source] OsError),
|
CreateLease(#[source] OsError),
|
||||||
|
|
|
||||||
|
|
@ -15,9 +15,9 @@ use {
|
||||||
DRM_SYNCOBJ_CREATE_SIGNALED, DRM_SYNCOBJ_FD_TO_HANDLE_FLAGS_IMPORT_SYNC_FILE,
|
DRM_SYNCOBJ_CREATE_SIGNALED, DRM_SYNCOBJ_FD_TO_HANDLE_FLAGS_IMPORT_SYNC_FILE,
|
||||||
DRM_SYNCOBJ_FD_TO_HANDLE_FLAGS_TIMELINE,
|
DRM_SYNCOBJ_FD_TO_HANDLE_FLAGS_TIMELINE,
|
||||||
DRM_SYNCOBJ_HANDLE_TO_FD_FLAGS_EXPORT_SYNC_FILE,
|
DRM_SYNCOBJ_HANDLE_TO_FD_FLAGS_EXPORT_SYNC_FILE,
|
||||||
DRM_SYNCOBJ_WAIT_FLAGS_WAIT_AVAILABLE, sync_ioc_merge, sync_obj_create,
|
DRM_SYNCOBJ_WAIT_FLAGS_WAIT_AVAILABLE, sync_ioc_merge, syncobj_create,
|
||||||
sync_obj_destroy, sync_obj_eventfd, sync_obj_fd_to_handle, sync_obj_handle_to_fd,
|
syncobj_destroy, syncobj_eventfd, syncobj_fd_to_handle, syncobj_handle_to_fd,
|
||||||
sync_obj_signal, sync_obj_transfer,
|
syncobj_signal, syncobj_transfer,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
@ -32,26 +32,26 @@ use {
|
||||||
static SYNCOBJ_ID: AtomicU64 = AtomicU64::new(0);
|
static SYNCOBJ_ID: AtomicU64 = AtomicU64::new(0);
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]
|
#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]
|
||||||
pub struct SyncObjId(u64);
|
pub struct SyncobjId(u64);
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]
|
#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]
|
||||||
struct SyncObjHandle(u32);
|
struct SyncobjHandle(u32);
|
||||||
|
|
||||||
unsafe impl UnsafeCellCloneSafe for SyncObjHandle {}
|
unsafe impl UnsafeCellCloneSafe for SyncobjHandle {}
|
||||||
|
|
||||||
pub struct SyncObj {
|
pub struct Syncobj {
|
||||||
id: SyncObjId,
|
id: SyncobjId,
|
||||||
fd: Rc<OwnedFd>,
|
fd: Rc<OwnedFd>,
|
||||||
importers: LinkedList<Rc<Handles>>,
|
importers: LinkedList<Rc<Handles>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash, Ord, PartialOrd)]
|
#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash, Ord, PartialOrd)]
|
||||||
pub struct SyncObjPoint(pub u64);
|
pub struct SyncobjPoint(pub u64);
|
||||||
|
|
||||||
impl SyncObj {
|
impl Syncobj {
|
||||||
pub fn new(fd: &Rc<OwnedFd>) -> Self {
|
pub fn new(fd: &Rc<OwnedFd>) -> Self {
|
||||||
Self {
|
Self {
|
||||||
id: SyncObjId(SYNCOBJ_ID.fetch_add(1, Relaxed)),
|
id: SyncobjId(SYNCOBJ_ID.fetch_add(1, Relaxed)),
|
||||||
fd: fd.clone(),
|
fd: fd.clone(),
|
||||||
importers: Default::default(),
|
importers: Default::default(),
|
||||||
}
|
}
|
||||||
|
|
@ -63,7 +63,7 @@ impl SyncObj {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Drop for SyncObj {
|
impl Drop for Syncobj {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
let mut links = vec![];
|
let mut links = vec![];
|
||||||
for importer in self.importers.iter() {
|
for importer in self.importers.iter() {
|
||||||
|
|
@ -79,17 +79,17 @@ impl Drop for SyncObj {
|
||||||
|
|
||||||
struct Handles {
|
struct Handles {
|
||||||
drm: Rc<OwnedFd>,
|
drm: Rc<OwnedFd>,
|
||||||
handles: CopyHashMap<SyncObjId, SyncObjHandle>,
|
handles: CopyHashMap<SyncobjId, SyncobjHandle>,
|
||||||
links: CopyHashMap<SyncObjId, LinkedNode<Rc<Handles>>>,
|
links: CopyHashMap<SyncobjId, LinkedNode<Rc<Handles>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct SyncObjCtx {
|
pub struct SyncobjCtx {
|
||||||
inner: Rc<Handles>,
|
inner: Rc<Handles>,
|
||||||
dummy: CloneCell<Option<Rc<SyncObj>>>,
|
dummy: CloneCell<Option<Rc<Syncobj>>>,
|
||||||
supports_timeline_import: OnceCell<bool>,
|
supports_timeline_import: OnceCell<bool>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SyncObjCtx {
|
impl SyncobjCtx {
|
||||||
pub fn new(drm: &Rc<OwnedFd>) -> Self {
|
pub fn new(drm: &Rc<OwnedFd>) -> Self {
|
||||||
Self {
|
Self {
|
||||||
inner: Rc::new(Handles {
|
inner: Rc::new(Handles {
|
||||||
|
|
@ -102,45 +102,45 @@ impl SyncObjCtx {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_handle(&self, sync_obj: &SyncObj) -> Result<SyncObjHandle, DrmError> {
|
fn get_handle(&self, syncobj: &Syncobj) -> Result<SyncobjHandle, DrmError> {
|
||||||
if let Some(handle) = self.inner.handles.get(&sync_obj.id) {
|
if let Some(handle) = self.inner.handles.get(&syncobj.id) {
|
||||||
return Ok(handle);
|
return Ok(handle);
|
||||||
}
|
}
|
||||||
let handle = sync_obj_fd_to_handle(self.inner.drm.raw(), sync_obj.fd.raw(), 0, 0, 0)
|
let handle = syncobj_fd_to_handle(self.inner.drm.raw(), syncobj.fd.raw(), 0, 0, 0)
|
||||||
.map_err(DrmError::ImportSyncObj)?;
|
.map_err(DrmError::ImportSyncobj)?;
|
||||||
let handle = SyncObjHandle(handle);
|
let handle = SyncobjHandle(handle);
|
||||||
let link = sync_obj.importers.add_last(self.inner.clone());
|
let link = syncobj.importers.add_last(self.inner.clone());
|
||||||
self.inner.handles.set(sync_obj.id, handle);
|
self.inner.handles.set(syncobj.id, handle);
|
||||||
self.inner.links.set(sync_obj.id, link);
|
self.inner.links.set(syncobj.id, link);
|
||||||
Ok(handle)
|
Ok(handle)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn create_sync_obj(&self) -> Result<SyncObj, DrmError> {
|
pub fn create_syncobj(&self) -> Result<Syncobj, DrmError> {
|
||||||
let handle = sync_obj_create(self.inner.drm.raw(), 0).map_err(DrmError::CreateSyncObj)?;
|
let handle = syncobj_create(self.inner.drm.raw(), 0).map_err(DrmError::CreateSyncobj)?;
|
||||||
let handle = SyncObjHandle(handle);
|
let handle = SyncobjHandle(handle);
|
||||||
let fd = sync_obj_handle_to_fd(self.inner.drm.raw(), handle.0, 0);
|
let fd = syncobj_handle_to_fd(self.inner.drm.raw(), handle.0, 0);
|
||||||
if fd.is_err() {
|
if fd.is_err() {
|
||||||
destroy(&self.inner.drm, handle);
|
destroy(&self.inner.drm, handle);
|
||||||
}
|
}
|
||||||
let fd = fd.map_err(DrmError::ExportSyncObj).map(Rc::new)?;
|
let fd = fd.map_err(DrmError::ExportSyncobj).map(Rc::new)?;
|
||||||
let sync_obj = SyncObj::new(&fd);
|
let syncobj = Syncobj::new(&fd);
|
||||||
let link = sync_obj.importers.add_last(self.inner.clone());
|
let link = syncobj.importers.add_last(self.inner.clone());
|
||||||
self.inner.handles.set(sync_obj.id, handle);
|
self.inner.handles.set(syncobj.id, handle);
|
||||||
self.inner.links.set(sync_obj.id, link);
|
self.inner.links.set(syncobj.id, link);
|
||||||
Ok(sync_obj)
|
Ok(syncobj)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn create_signaled_sync_file(&self) -> Result<SyncFile, DrmError> {
|
pub fn create_signaled_sync_file(&self) -> Result<SyncFile, DrmError> {
|
||||||
let handle = sync_obj_create(self.inner.drm.raw(), DRM_SYNCOBJ_CREATE_SIGNALED)
|
let handle = syncobj_create(self.inner.drm.raw(), DRM_SYNCOBJ_CREATE_SIGNALED)
|
||||||
.map_err(DrmError::CreateSyncObj)?;
|
.map_err(DrmError::CreateSyncobj)?;
|
||||||
let handle = SyncObjHandle(handle);
|
let handle = SyncobjHandle(handle);
|
||||||
let fd = sync_obj_handle_to_fd(
|
let fd = syncobj_handle_to_fd(
|
||||||
self.inner.drm.raw(),
|
self.inner.drm.raw(),
|
||||||
handle.0,
|
handle.0,
|
||||||
DRM_SYNCOBJ_HANDLE_TO_FD_FLAGS_EXPORT_SYNC_FILE,
|
DRM_SYNCOBJ_HANDLE_TO_FD_FLAGS_EXPORT_SYNC_FILE,
|
||||||
);
|
);
|
||||||
destroy(&self.inner.drm, handle);
|
destroy(&self.inner.drm, handle);
|
||||||
fd.map_err(DrmError::ExportSyncObj)
|
fd.map_err(DrmError::ExportSyncobj)
|
||||||
.map(Rc::new)
|
.map(Rc::new)
|
||||||
.map(SyncFile)
|
.map(SyncFile)
|
||||||
}
|
}
|
||||||
|
|
@ -148,16 +148,16 @@ impl SyncObjCtx {
|
||||||
pub fn wait_for_point(
|
pub fn wait_for_point(
|
||||||
&self,
|
&self,
|
||||||
eventfd: &OwnedFd,
|
eventfd: &OwnedFd,
|
||||||
sync_obj: &SyncObj,
|
syncobj: &Syncobj,
|
||||||
point: SyncObjPoint,
|
point: SyncobjPoint,
|
||||||
signaled: bool,
|
signaled: bool,
|
||||||
) -> Result<(), DrmError> {
|
) -> Result<(), DrmError> {
|
||||||
let handle = self.get_handle(sync_obj)?;
|
let handle = self.get_handle(syncobj)?;
|
||||||
let flags = match signaled {
|
let flags = match signaled {
|
||||||
true => 0,
|
true => 0,
|
||||||
false => DRM_SYNCOBJ_WAIT_FLAGS_WAIT_AVAILABLE,
|
false => DRM_SYNCOBJ_WAIT_FLAGS_WAIT_AVAILABLE,
|
||||||
};
|
};
|
||||||
sync_obj_eventfd(
|
syncobj_eventfd(
|
||||||
self.inner.drm.raw(),
|
self.inner.drm.raw(),
|
||||||
eventfd.raw(),
|
eventfd.raw(),
|
||||||
handle.0,
|
handle.0,
|
||||||
|
|
@ -172,11 +172,11 @@ impl SyncObjCtx {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn supports_async_wait_(&self) -> Result<(), DrmError> {
|
fn supports_async_wait_(&self) -> Result<(), DrmError> {
|
||||||
let sync_obj = self.create_sync_obj()?;
|
let syncobj = self.create_syncobj()?;
|
||||||
let eventfd = uapi::eventfd(0, c::EFD_CLOEXEC)
|
let eventfd = uapi::eventfd(0, c::EFD_CLOEXEC)
|
||||||
.map_err(OsError::from)
|
.map_err(OsError::from)
|
||||||
.map_err(DrmError::EventFd)?;
|
.map_err(DrmError::EventFd)?;
|
||||||
self.wait_for_point(&eventfd, &sync_obj, SyncObjPoint(1), true)?;
|
self.wait_for_point(&eventfd, &syncobj, SyncobjPoint(1), true)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -199,40 +199,40 @@ impl SyncObjCtx {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn test_timeline_import(&self) -> Result<(), DrmError> {
|
fn test_timeline_import(&self) -> Result<(), DrmError> {
|
||||||
let sync_obj = self.create_sync_obj()?;
|
let syncobj = self.create_syncobj()?;
|
||||||
let sync_obj = self.get_handle(&sync_obj)?;
|
let syncobj = self.get_handle(&syncobj)?;
|
||||||
let sync_file = self.create_signaled_sync_file()?;
|
let sync_file = self.create_signaled_sync_file()?;
|
||||||
sync_obj_fd_to_handle(
|
syncobj_fd_to_handle(
|
||||||
self.inner.drm.raw(),
|
self.inner.drm.raw(),
|
||||||
sync_file.raw(),
|
sync_file.raw(),
|
||||||
DRM_SYNCOBJ_FD_TO_HANDLE_FLAGS_IMPORT_SYNC_FILE
|
DRM_SYNCOBJ_FD_TO_HANDLE_FLAGS_IMPORT_SYNC_FILE
|
||||||
| DRM_SYNCOBJ_FD_TO_HANDLE_FLAGS_TIMELINE,
|
| DRM_SYNCOBJ_FD_TO_HANDLE_FLAGS_TIMELINE,
|
||||||
sync_obj.0,
|
syncobj.0,
|
||||||
123,
|
123,
|
||||||
)
|
)
|
||||||
.map(drop)
|
.map(drop)
|
||||||
.map_err(DrmError::ImportSyncFile)
|
.map_err(DrmError::ImportSyncFile)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn signal(&self, sync_obj: &SyncObj, point: SyncObjPoint) -> Result<(), DrmError> {
|
pub fn signal(&self, syncobj: &Syncobj, point: SyncobjPoint) -> Result<(), DrmError> {
|
||||||
let handle = self.get_handle(sync_obj)?;
|
let handle = self.get_handle(syncobj)?;
|
||||||
sync_obj_signal(self.inner.drm.raw(), handle.0, point.0).map_err(DrmError::SignalSyncObj)
|
syncobj_signal(self.inner.drm.raw(), handle.0, point.0).map_err(DrmError::SignalSyncobj)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn import_sync_files<'a, I>(
|
pub fn import_sync_files<'a, I>(
|
||||||
&self,
|
&self,
|
||||||
sync_obj: &SyncObj,
|
syncobj: &Syncobj,
|
||||||
point: SyncObjPoint,
|
point: SyncobjPoint,
|
||||||
sync_files: I,
|
sync_files: I,
|
||||||
) -> Result<(), DrmError>
|
) -> Result<(), DrmError>
|
||||||
where
|
where
|
||||||
I: IntoIterator<Item = &'a SyncFile>,
|
I: IntoIterator<Item = &'a SyncFile>,
|
||||||
{
|
{
|
||||||
let Some(fd) = merge_sync_files(sync_files)? else {
|
let Some(fd) = merge_sync_files(sync_files)? else {
|
||||||
return self.signal(sync_obj, point);
|
return self.signal(syncobj, point);
|
||||||
};
|
};
|
||||||
let import = |flags: u32, handle: SyncObjHandle| {
|
let import = |flags: u32, handle: SyncobjHandle| {
|
||||||
sync_obj_fd_to_handle(
|
syncobj_fd_to_handle(
|
||||||
self.inner.drm.raw(),
|
self.inner.drm.raw(),
|
||||||
fd.raw(),
|
fd.raw(),
|
||||||
DRM_SYNCOBJ_FD_TO_HANDLE_FLAGS_IMPORT_SYNC_FILE | flags,
|
DRM_SYNCOBJ_FD_TO_HANDLE_FLAGS_IMPORT_SYNC_FILE | flags,
|
||||||
|
|
@ -245,24 +245,24 @@ impl SyncObjCtx {
|
||||||
if self.supports_timeline_import() {
|
if self.supports_timeline_import() {
|
||||||
return import(
|
return import(
|
||||||
DRM_SYNCOBJ_FD_TO_HANDLE_FLAGS_TIMELINE,
|
DRM_SYNCOBJ_FD_TO_HANDLE_FLAGS_TIMELINE,
|
||||||
self.get_handle(sync_obj)?,
|
self.get_handle(syncobj)?,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
let dummy = self.get_dummy()?;
|
let dummy = self.get_dummy()?;
|
||||||
import(0, self.get_handle(&dummy)?)?;
|
import(0, self.get_handle(&dummy)?)?;
|
||||||
self.transfer(&dummy, SyncObjPoint(0), sync_obj, point)
|
self.transfer(&dummy, SyncobjPoint(0), syncobj, point)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn transfer(
|
fn transfer(
|
||||||
&self,
|
&self,
|
||||||
src_sync_obj: &SyncObj,
|
src_syncobj: &Syncobj,
|
||||||
src_point: SyncObjPoint,
|
src_point: SyncobjPoint,
|
||||||
dst_sync_obj: &SyncObj,
|
dst_syncobj: &Syncobj,
|
||||||
dst_point: SyncObjPoint,
|
dst_point: SyncobjPoint,
|
||||||
) -> Result<(), DrmError> {
|
) -> Result<(), DrmError> {
|
||||||
let src_handle = self.get_handle(src_sync_obj)?;
|
let src_handle = self.get_handle(src_syncobj)?;
|
||||||
let dst_handle = self.get_handle(dst_sync_obj)?;
|
let dst_handle = self.get_handle(dst_syncobj)?;
|
||||||
sync_obj_transfer(
|
syncobj_transfer(
|
||||||
self.inner.drm.raw(),
|
self.inner.drm.raw(),
|
||||||
src_handle.0,
|
src_handle.0,
|
||||||
src_point.0,
|
src_point.0,
|
||||||
|
|
@ -273,11 +273,11 @@ impl SyncObjCtx {
|
||||||
.map_err(DrmError::TransferPoint)
|
.map_err(DrmError::TransferPoint)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_dummy(&self) -> Result<Rc<SyncObj>, DrmError> {
|
fn get_dummy(&self) -> Result<Rc<Syncobj>, DrmError> {
|
||||||
match self.dummy.get() {
|
match self.dummy.get() {
|
||||||
Some(d) => Ok(d),
|
Some(d) => Ok(d),
|
||||||
None => {
|
None => {
|
||||||
let d = Rc::new(self.create_sync_obj()?);
|
let d = Rc::new(self.create_syncobj()?);
|
||||||
self.dummy.set(Some(d.clone()));
|
self.dummy.set(Some(d.clone()));
|
||||||
Ok(d)
|
Ok(d)
|
||||||
}
|
}
|
||||||
|
|
@ -285,7 +285,7 @@ impl SyncObjCtx {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Drop for SyncObjCtx {
|
impl Drop for SyncobjCtx {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
self.inner.links.clear();
|
self.inner.links.clear();
|
||||||
let mut map = self.inner.handles.lock();
|
let mut map = self.inner.handles.lock();
|
||||||
|
|
@ -295,9 +295,9 @@ impl Drop for SyncObjCtx {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn destroy(drm: &OwnedFd, handle: SyncObjHandle) {
|
fn destroy(drm: &OwnedFd, handle: SyncobjHandle) {
|
||||||
if let Err(e) = sync_obj_destroy(drm.raw(), handle.0) {
|
if let Err(e) = syncobj_destroy(drm.raw(), handle.0) {
|
||||||
log::error!("Could not destroy sync obj: {}", ErrorFmt(e));
|
log::error!("Could not destroy syncobj: {}", ErrorFmt(e));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1195,7 +1195,7 @@ struct drm_syncobj_create {
|
||||||
|
|
||||||
const DRM_IOCTL_SYNCOBJ_CREATE: u64 = drm_iowr::<drm_syncobj_create>(0xBF);
|
const DRM_IOCTL_SYNCOBJ_CREATE: u64 = drm_iowr::<drm_syncobj_create>(0xBF);
|
||||||
|
|
||||||
pub fn sync_obj_create(drm: c::c_int, flags: u32) -> Result<u32, OsError> {
|
pub fn syncobj_create(drm: c::c_int, flags: u32) -> Result<u32, OsError> {
|
||||||
let mut res = drm_syncobj_create { handle: 0, flags };
|
let mut res = drm_syncobj_create { handle: 0, flags };
|
||||||
unsafe {
|
unsafe {
|
||||||
ioctl(drm, DRM_IOCTL_SYNCOBJ_CREATE, &mut res)?;
|
ioctl(drm, DRM_IOCTL_SYNCOBJ_CREATE, &mut res)?;
|
||||||
|
|
@ -1211,7 +1211,7 @@ struct drm_syncobj_destroy {
|
||||||
|
|
||||||
const DRM_IOCTL_SYNCOBJ_DESTROY: u64 = drm_iowr::<drm_syncobj_destroy>(0xC0);
|
const DRM_IOCTL_SYNCOBJ_DESTROY: u64 = drm_iowr::<drm_syncobj_destroy>(0xC0);
|
||||||
|
|
||||||
pub fn sync_obj_destroy(drm: c::c_int, handle: u32) -> Result<(), OsError> {
|
pub fn syncobj_destroy(drm: c::c_int, handle: u32) -> Result<(), OsError> {
|
||||||
let mut res = drm_syncobj_destroy { handle, pad: 0 };
|
let mut res = drm_syncobj_destroy { handle, pad: 0 };
|
||||||
unsafe {
|
unsafe {
|
||||||
ioctl(drm, DRM_IOCTL_SYNCOBJ_DESTROY, &mut res)?;
|
ioctl(drm, DRM_IOCTL_SYNCOBJ_DESTROY, &mut res)?;
|
||||||
|
|
@ -1236,7 +1236,7 @@ struct drm_syncobj_handle {
|
||||||
const DRM_IOCTL_SYNCOBJ_HANDLE_TO_FD: u64 = drm_iowr::<drm_syncobj_handle>(0xC1);
|
const DRM_IOCTL_SYNCOBJ_HANDLE_TO_FD: u64 = drm_iowr::<drm_syncobj_handle>(0xC1);
|
||||||
const DRM_IOCTL_SYNCOBJ_FD_TO_HANDLE: u64 = drm_iowr::<drm_syncobj_handle>(0xC2);
|
const DRM_IOCTL_SYNCOBJ_FD_TO_HANDLE: u64 = drm_iowr::<drm_syncobj_handle>(0xC2);
|
||||||
|
|
||||||
pub fn sync_obj_handle_to_fd(drm: c::c_int, handle: u32, flags: u32) -> Result<OwnedFd, OsError> {
|
pub fn syncobj_handle_to_fd(drm: c::c_int, handle: u32, flags: u32) -> Result<OwnedFd, OsError> {
|
||||||
let mut res = drm_syncobj_handle {
|
let mut res = drm_syncobj_handle {
|
||||||
handle,
|
handle,
|
||||||
flags,
|
flags,
|
||||||
|
|
@ -1250,7 +1250,7 @@ pub fn sync_obj_handle_to_fd(drm: c::c_int, handle: u32, flags: u32) -> Result<O
|
||||||
Ok(OwnedFd::new(res.fd))
|
Ok(OwnedFd::new(res.fd))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn sync_obj_fd_to_handle(
|
pub fn syncobj_fd_to_handle(
|
||||||
drm: c::c_int,
|
drm: c::c_int,
|
||||||
fd: c::c_int,
|
fd: c::c_int,
|
||||||
flags: u32,
|
flags: u32,
|
||||||
|
|
@ -1285,7 +1285,7 @@ struct drm_syncobj_eventfd {
|
||||||
|
|
||||||
const DRM_IOCTL_SYNCOBJ_EVENTFD: u64 = drm_iowr::<drm_syncobj_eventfd>(0xCF);
|
const DRM_IOCTL_SYNCOBJ_EVENTFD: u64 = drm_iowr::<drm_syncobj_eventfd>(0xCF);
|
||||||
|
|
||||||
pub fn sync_obj_eventfd(
|
pub fn syncobj_eventfd(
|
||||||
drm: c::c_int,
|
drm: c::c_int,
|
||||||
eventfd: c::c_int,
|
eventfd: c::c_int,
|
||||||
handle: u32,
|
handle: u32,
|
||||||
|
|
@ -1315,7 +1315,7 @@ struct drm_syncobj_timeline_array {
|
||||||
|
|
||||||
const DRM_IOCTL_SYNCOBJ_TIMELINE_SIGNAL: u64 = drm_iowr::<drm_syncobj_timeline_array>(0xCD);
|
const DRM_IOCTL_SYNCOBJ_TIMELINE_SIGNAL: u64 = drm_iowr::<drm_syncobj_timeline_array>(0xCD);
|
||||||
|
|
||||||
pub fn sync_obj_signal(drm: c::c_int, handle: u32, point: u64) -> Result<(), OsError> {
|
pub fn syncobj_signal(drm: c::c_int, handle: u32, point: u64) -> Result<(), OsError> {
|
||||||
let mut res = drm_syncobj_timeline_array {
|
let mut res = drm_syncobj_timeline_array {
|
||||||
handles: &handle as *const u32 as u64,
|
handles: &handle as *const u32 as u64,
|
||||||
points: &point as *const u64 as u64,
|
points: &point as *const u64 as u64,
|
||||||
|
|
@ -1340,7 +1340,7 @@ struct drm_syncobj_transfer {
|
||||||
|
|
||||||
const DRM_IOCTL_SYNCOBJ_TRANSFER: u64 = drm_iowr::<drm_syncobj_transfer>(0xCC);
|
const DRM_IOCTL_SYNCOBJ_TRANSFER: u64 = drm_iowr::<drm_syncobj_transfer>(0xCC);
|
||||||
|
|
||||||
pub fn sync_obj_transfer(
|
pub fn syncobj_transfer(
|
||||||
drm: c::c_int,
|
drm: c::c_int,
|
||||||
src_handle: u32,
|
src_handle: u32,
|
||||||
src_point: u64,
|
src_point: u64,
|
||||||
|
|
|
||||||
|
|
@ -8,19 +8,19 @@ use {
|
||||||
},
|
},
|
||||||
video::drm::{
|
video::drm::{
|
||||||
DrmError,
|
DrmError,
|
||||||
sync_obj::{SyncObj, SyncObjCtx, SyncObjPoint},
|
syncobj::{Syncobj, SyncobjCtx, SyncobjPoint},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
std::{cell::Cell, rc::Rc},
|
std::{cell::Cell, rc::Rc},
|
||||||
uapi::{OwnedFd, c},
|
uapi::{OwnedFd, c},
|
||||||
};
|
};
|
||||||
|
|
||||||
pub struct WaitForSyncObj {
|
pub struct WaitForSyncobj {
|
||||||
inner: Rc<Inner>,
|
inner: Rc<Inner>,
|
||||||
eng: Rc<AsyncEngine>,
|
eng: Rc<AsyncEngine>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait SyncObjWaiter {
|
pub trait SyncobjWaiter {
|
||||||
fn done(self: Rc<Self>, result: Result<(), DrmError>);
|
fn done(self: Rc<Self>, result: Result<(), DrmError>);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -28,13 +28,13 @@ pub trait SyncObjWaiter {
|
||||||
struct JobId(u64);
|
struct JobId(u64);
|
||||||
|
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub struct WaitForSyncObjHandle {
|
pub struct WaitForSyncobjHandle {
|
||||||
inner: Rc<Inner>,
|
inner: Rc<Inner>,
|
||||||
id: JobId,
|
id: JobId,
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Inner {
|
struct Inner {
|
||||||
ctx: CloneCell<Option<Rc<SyncObjCtx>>>,
|
ctx: CloneCell<Option<Rc<SyncobjCtx>>>,
|
||||||
next_id: NumCell<u64>,
|
next_id: NumCell<u64>,
|
||||||
ring: Rc<IoUring>,
|
ring: Rc<IoUring>,
|
||||||
busy: CopyHashMap<JobId, BusyWaiter>,
|
busy: CopyHashMap<JobId, BusyWaiter>,
|
||||||
|
|
@ -44,7 +44,7 @@ struct Inner {
|
||||||
struct BusyWaiter {
|
struct BusyWaiter {
|
||||||
waiter: Waiter,
|
waiter: Waiter,
|
||||||
job: Job,
|
job: Job,
|
||||||
sow: Rc<dyn SyncObjWaiter>,
|
sow: Rc<dyn SyncobjWaiter>,
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Waiter {
|
struct Waiter {
|
||||||
|
|
@ -55,8 +55,8 @@ struct Waiter {
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
struct Job {
|
struct Job {
|
||||||
id: JobId,
|
id: JobId,
|
||||||
sync_obj: Rc<SyncObj>,
|
syncobj: Rc<Syncobj>,
|
||||||
point: SyncObjPoint,
|
point: SyncobjPoint,
|
||||||
signaled: bool,
|
signaled: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -67,13 +67,13 @@ struct WaiterInner {
|
||||||
trigger: AsyncEvent,
|
trigger: AsyncEvent,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Drop for WaitForSyncObjHandle {
|
impl Drop for WaitForSyncobjHandle {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
let _ = self.inner.busy.remove(&self.id);
|
let _ = self.inner.busy.remove(&self.id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl WaitForSyncObj {
|
impl WaitForSyncobj {
|
||||||
pub fn new(ring: &Rc<IoUring>, eng: &Rc<AsyncEngine>) -> Self {
|
pub fn new(ring: &Rc<IoUring>, eng: &Rc<AsyncEngine>) -> Self {
|
||||||
Self {
|
Self {
|
||||||
inner: Rc::new(Inner {
|
inner: Rc::new(Inner {
|
||||||
|
|
@ -93,13 +93,13 @@ impl WaitForSyncObj {
|
||||||
self.inner.idle.take();
|
self.inner.idle.take();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_ctx(&self, ctx: Option<Rc<SyncObjCtx>>) {
|
pub fn set_ctx(&self, ctx: Option<Rc<SyncobjCtx>>) {
|
||||||
self.inner.ctx.set(ctx);
|
self.inner.ctx.set(ctx);
|
||||||
let busy_waiters: Vec<_> = self.inner.busy.lock().drain_values().collect();
|
let busy_waiters: Vec<_> = self.inner.busy.lock().drain_values().collect();
|
||||||
for waiter in busy_waiters {
|
for waiter in busy_waiters {
|
||||||
let res = self.submit_job(
|
let res = self.submit_job(
|
||||||
waiter.job.id,
|
waiter.job.id,
|
||||||
&waiter.job.sync_obj,
|
&waiter.job.syncobj,
|
||||||
waiter.job.point,
|
waiter.job.point,
|
||||||
waiter.job.signaled,
|
waiter.job.signaled,
|
||||||
waiter.sow.clone(),
|
waiter.sow.clone(),
|
||||||
|
|
@ -112,14 +112,14 @@ impl WaitForSyncObj {
|
||||||
|
|
||||||
pub fn wait(
|
pub fn wait(
|
||||||
&self,
|
&self,
|
||||||
sync_obj: &Rc<SyncObj>,
|
syncobj: &Rc<Syncobj>,
|
||||||
point: SyncObjPoint,
|
point: SyncobjPoint,
|
||||||
signaled: bool,
|
signaled: bool,
|
||||||
sow: Rc<dyn SyncObjWaiter>,
|
sow: Rc<dyn SyncobjWaiter>,
|
||||||
) -> Result<WaitForSyncObjHandle, DrmError> {
|
) -> Result<WaitForSyncobjHandle, DrmError> {
|
||||||
let job_id = JobId(self.inner.next_id.fetch_add(1));
|
let job_id = JobId(self.inner.next_id.fetch_add(1));
|
||||||
self.submit_job(job_id, sync_obj, point, signaled, sow)?;
|
self.submit_job(job_id, syncobj, point, signaled, sow)?;
|
||||||
Ok(WaitForSyncObjHandle {
|
Ok(WaitForSyncobjHandle {
|
||||||
inner: self.inner.clone(),
|
inner: self.inner.clone(),
|
||||||
id: job_id,
|
id: job_id,
|
||||||
})
|
})
|
||||||
|
|
@ -128,10 +128,10 @@ impl WaitForSyncObj {
|
||||||
fn submit_job(
|
fn submit_job(
|
||||||
&self,
|
&self,
|
||||||
job_id: JobId,
|
job_id: JobId,
|
||||||
sync_obj: &Rc<SyncObj>,
|
syncobj: &Rc<Syncobj>,
|
||||||
point: SyncObjPoint,
|
point: SyncobjPoint,
|
||||||
signaled: bool,
|
signaled: bool,
|
||||||
sow: Rc<dyn SyncObjWaiter>,
|
sow: Rc<dyn SyncobjWaiter>,
|
||||||
) -> Result<(), DrmError> {
|
) -> Result<(), DrmError> {
|
||||||
let waiter = match self.inner.idle.pop() {
|
let waiter = match self.inner.idle.pop() {
|
||||||
Some(w) => w,
|
Some(w) => w,
|
||||||
|
|
@ -146,14 +146,14 @@ impl WaitForSyncObj {
|
||||||
trigger: Default::default(),
|
trigger: Default::default(),
|
||||||
});
|
});
|
||||||
Waiter {
|
Waiter {
|
||||||
_task: self.eng.spawn("wait for sync obj", waiter.clone().run()),
|
_task: self.eng.spawn("wait for syncobj", waiter.clone().run()),
|
||||||
inner: waiter,
|
inner: waiter,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
let job = Job {
|
let job = Job {
|
||||||
id: job_id,
|
id: job_id,
|
||||||
sync_obj: sync_obj.clone(),
|
syncobj: syncobj.clone(),
|
||||||
point,
|
point,
|
||||||
signaled,
|
signaled,
|
||||||
};
|
};
|
||||||
|
|
@ -185,10 +185,10 @@ impl WaiterInner {
|
||||||
|
|
||||||
async fn wait(&self, buf: &mut Buf, job: &Job) -> Result<(), DrmError> {
|
async fn wait(&self, buf: &mut Buf, job: &Job) -> Result<(), DrmError> {
|
||||||
let ctx = match self.inner.ctx.get() {
|
let ctx = match self.inner.ctx.get() {
|
||||||
None => return Err(DrmError::NoSyncObjContextAvailable),
|
None => return Err(DrmError::NoSyncobjContextAvailable),
|
||||||
Some(c) => c,
|
Some(c) => c,
|
||||||
};
|
};
|
||||||
ctx.wait_for_point(&self.eventfd, &job.sync_obj, job.point, job.signaled)?;
|
ctx.wait_for_point(&self.eventfd, &job.syncobj, job.point, job.signaled)?;
|
||||||
self.inner
|
self.inner
|
||||||
.ring
|
.ring
|
||||||
.read(&self.eventfd, buf.clone())
|
.read(&self.eventfd, buf.clone())
|
||||||
Loading…
Add table
Add a link
Reference in a new issue