commit_timeline: wait for implicit sync dmabufs
This commit is contained in:
parent
c22af6efb7
commit
04343c96d6
7 changed files with 199 additions and 15 deletions
|
|
@ -168,7 +168,10 @@ impl Clients {
|
||||||
last_xwayland_serial: Cell::new(0),
|
last_xwayland_serial: Cell::new(0),
|
||||||
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(&global.wait_for_sync_obj)),
|
commit_timelines: Rc::new(CommitTimelines::new(
|
||||||
|
&global.wait_for_sync_obj,
|
||||||
|
&global.ring,
|
||||||
|
)),
|
||||||
});
|
});
|
||||||
track!(data, data);
|
track!(data, data);
|
||||||
let display = Rc::new(WlDisplay::new(&data));
|
let display = Rc::new(WlDisplay::new(&data));
|
||||||
|
|
|
||||||
|
|
@ -23,8 +23,8 @@ use {
|
||||||
drm_feedback::DrmFeedback,
|
drm_feedback::DrmFeedback,
|
||||||
fixed::Fixed,
|
fixed::Fixed,
|
||||||
gfx_api::{
|
gfx_api::{
|
||||||
AcquireSync, AsyncShmGfxTexture, BufferResv, BufferResvUser, GfxError, ReleaseSync,
|
AsyncShmGfxTexture, BufferResv, BufferResvUser, GfxError, ReleaseSync, SampleRect,
|
||||||
SampleRect, SyncFile,
|
SyncFile,
|
||||||
},
|
},
|
||||||
ifs::{
|
ifs::{
|
||||||
wl_buffer::WlBuffer,
|
wl_buffer::WlBuffer,
|
||||||
|
|
@ -190,7 +190,6 @@ struct SurfaceBufferExplicitRelease {
|
||||||
pub struct SurfaceBuffer {
|
pub struct SurfaceBuffer {
|
||||||
pub buffer: Rc<WlBuffer>,
|
pub buffer: Rc<WlBuffer>,
|
||||||
sync_files: SmallMap<BufferResvUser, SyncFile, 1>,
|
sync_files: SmallMap<BufferResvUser, SyncFile, 1>,
|
||||||
pub sync: AcquireSync,
|
|
||||||
pub release_sync: ReleaseSync,
|
pub release_sync: ReleaseSync,
|
||||||
release: Option<SurfaceBufferExplicitRelease>,
|
release: Option<SurfaceBufferExplicitRelease>,
|
||||||
}
|
}
|
||||||
|
|
@ -1093,9 +1092,9 @@ impl WlSurface {
|
||||||
self.reset_shm_textures();
|
self.reset_shm_textures();
|
||||||
}
|
}
|
||||||
buffer.update_texture_or_log(self, false);
|
buffer.update_texture_or_log(self, false);
|
||||||
let (sync, release_sync) = match pending.explicit_sync {
|
let release_sync = match pending.explicit_sync {
|
||||||
false => (AcquireSync::Implicit, ReleaseSync::Implicit),
|
false => ReleaseSync::Implicit,
|
||||||
true => (AcquireSync::Unnecessary, ReleaseSync::Explicit),
|
true => ReleaseSync::Explicit,
|
||||||
};
|
};
|
||||||
let release = pending
|
let release = pending
|
||||||
.release_point
|
.release_point
|
||||||
|
|
@ -1104,7 +1103,6 @@ impl WlSurface {
|
||||||
let surface_buffer = SurfaceBuffer {
|
let surface_buffer = SurfaceBuffer {
|
||||||
buffer,
|
buffer,
|
||||||
sync_files: Default::default(),
|
sync_files: Default::default(),
|
||||||
sync,
|
|
||||||
release_sync,
|
release_sync,
|
||||||
release,
|
release,
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -5,12 +5,14 @@ use {
|
||||||
wl_buffer::WlBufferStorage,
|
wl_buffer::WlBufferStorage,
|
||||||
wl_surface::{PendingState, WlSurface, WlSurfaceError},
|
wl_surface::{PendingState, WlSurface, WlSurfaceError},
|
||||||
},
|
},
|
||||||
|
io_uring::{IoUring, IoUringError, PendingPoll, PollCallback},
|
||||||
utils::{
|
utils::{
|
||||||
clonecell::CloneCell,
|
clonecell::CloneCell,
|
||||||
copyhashmap::CopyHashMap,
|
copyhashmap::CopyHashMap,
|
||||||
hash_map_ext::HashMapExt,
|
hash_map_ext::HashMapExt,
|
||||||
linkedlist::{LinkedList, LinkedNode, NodeRef},
|
linkedlist::{LinkedList, LinkedNode, NodeRef},
|
||||||
numcell::NumCell,
|
numcell::NumCell,
|
||||||
|
oserror::OsError,
|
||||||
},
|
},
|
||||||
video::drm::{
|
video::drm::{
|
||||||
sync_obj::{SyncObj, SyncObjPoint},
|
sync_obj::{SyncObj, SyncObjPoint},
|
||||||
|
|
@ -28,6 +30,7 @@ use {
|
||||||
slice,
|
slice,
|
||||||
},
|
},
|
||||||
thiserror::Error,
|
thiserror::Error,
|
||||||
|
uapi::{c::c_short, OwnedFd},
|
||||||
};
|
};
|
||||||
|
|
||||||
const MAX_TIMELINE_DEPTH: usize = 256;
|
const MAX_TIMELINE_DEPTH: usize = 256;
|
||||||
|
|
@ -37,6 +40,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>,
|
||||||
depth: NumCell<usize>,
|
depth: NumCell<usize>,
|
||||||
gc: CopyHashMap<CommitTimelineId, LinkedList<Entry>>,
|
gc: CopyHashMap<CommitTimelineId, LinkedList<Entry>>,
|
||||||
}
|
}
|
||||||
|
|
@ -83,15 +87,20 @@ pub enum CommitTimelineError {
|
||||||
Depth,
|
Depth,
|
||||||
#[error("Could not upload a shm texture")]
|
#[error("Could not upload a shm texture")]
|
||||||
ShmUpload(#[source] GfxError),
|
ShmUpload(#[source] GfxError),
|
||||||
|
#[error("Could not register an implicit-sync wait")]
|
||||||
|
RegisterImplicitPoll(#[source] IoUringError),
|
||||||
|
#[error("Could not wait for a dmabuf to become idle")]
|
||||||
|
PollDmabuf(#[source] OsError),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CommitTimelines {
|
impl CommitTimelines {
|
||||||
pub fn new(wfs: &Rc<WaitForSyncObj>) -> Self {
|
pub fn new(wfs: &Rc<WaitForSyncObj>, ring: &Rc<IoUring>) -> Self {
|
||||||
Self {
|
Self {
|
||||||
next_id: Default::default(),
|
next_id: Default::default(),
|
||||||
depth: NumCell::new(0),
|
depth: NumCell::new(0),
|
||||||
wfs: wfs.clone(),
|
wfs: wfs.clone(),
|
||||||
gc: Default::default(),
|
gc: Default::default(),
|
||||||
|
ring: ring.clone(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -127,6 +136,7 @@ fn break_loops(list: &LinkedList<Entry>) {
|
||||||
if let EntryKind::Commit(c) = &entry.kind {
|
if let EntryKind::Commit(c) = &entry.kind {
|
||||||
c.wait_handles.take();
|
c.wait_handles.take();
|
||||||
*c.shm_upload.borrow_mut() = ShmUploadState::None;
|
*c.shm_upload.borrow_mut() = ShmUploadState::None;
|
||||||
|
c.pending_polls.take();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -153,8 +163,15 @@ impl CommitTimeline {
|
||||||
) -> Result<(), CommitTimelineError> {
|
) -> Result<(), CommitTimelineError> {
|
||||||
let mut points = SmallVec::new();
|
let mut points = SmallVec::new();
|
||||||
let mut pending_uploads = 0;
|
let mut pending_uploads = 0;
|
||||||
collect_commit_data(pending, &mut points, &mut pending_uploads);
|
let mut implicit_dmabufs = SmallVec::new();
|
||||||
let has_dependencies = points.is_not_empty() || pending_uploads > 0;
|
collect_commit_data(
|
||||||
|
pending,
|
||||||
|
&mut points,
|
||||||
|
&mut pending_uploads,
|
||||||
|
&mut implicit_dmabufs,
|
||||||
|
);
|
||||||
|
let has_dependencies =
|
||||||
|
points.is_not_empty() || pending_uploads > 0 || implicit_dmabufs.is_not_empty();
|
||||||
if !has_dependencies && self.own_timeline.entries.is_empty() {
|
if !has_dependencies && self.own_timeline.entries.is_empty() {
|
||||||
return surface
|
return surface
|
||||||
.apply_state(pending)
|
.apply_state(pending)
|
||||||
|
|
@ -174,6 +191,8 @@ impl CommitTimeline {
|
||||||
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),
|
||||||
|
num_pending_polls: NumCell::new(implicit_dmabufs.len()),
|
||||||
|
pending_polls: Cell::new(Default::default()),
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
let mut needs_flush = false;
|
let mut needs_flush = false;
|
||||||
|
|
@ -198,6 +217,18 @@ impl CommitTimeline {
|
||||||
*commit.shm_upload.borrow_mut() = ShmUploadState::Todo(noderef.clone());
|
*commit.shm_upload.borrow_mut() = ShmUploadState::Todo(noderef.clone());
|
||||||
needs_flush = true;
|
needs_flush = true;
|
||||||
}
|
}
|
||||||
|
if implicit_dmabufs.is_not_empty() {
|
||||||
|
let mut pending_polls = SmallVec::new();
|
||||||
|
for fd in implicit_dmabufs {
|
||||||
|
let handle = self
|
||||||
|
.shared
|
||||||
|
.ring
|
||||||
|
.readable_external(&fd, noderef.clone())
|
||||||
|
.map_err(CommitTimelineError::RegisterImplicitPoll)?;
|
||||||
|
pending_polls.push(handle);
|
||||||
|
}
|
||||||
|
commit.pending_polls.set(pending_polls);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if needs_flush && noderef.prev().is_none() {
|
if needs_flush && noderef.prev().is_none() {
|
||||||
flush_from(noderef.clone()).map_err(CommitTimelineError::DelayedCommit)?;
|
flush_from(noderef.clone()).map_err(CommitTimelineError::DelayedCommit)?;
|
||||||
|
|
@ -246,6 +277,23 @@ impl AsyncShmGfxTextureCallback for NodeRef<Entry> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl PollCallback for NodeRef<Entry> {
|
||||||
|
fn completed(self: Rc<Self>, res: Result<c_short, OsError>) {
|
||||||
|
let EntryKind::Commit(commit) = &self.kind else {
|
||||||
|
unreachable!();
|
||||||
|
};
|
||||||
|
if let Err(e) = res {
|
||||||
|
commit
|
||||||
|
.surface
|
||||||
|
.client
|
||||||
|
.error(CommitTimelineError::PollDmabuf(e));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
commit.num_pending_polls.fetch_sub(1);
|
||||||
|
flush_commit(&self, commit);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
struct Entry {
|
struct Entry {
|
||||||
link: Cell<Option<LinkedNode<Entry>>>,
|
link: Cell<Option<LinkedNode<Entry>>>,
|
||||||
shared: Rc<CommitTimelines>,
|
shared: Rc<CommitTimelines>,
|
||||||
|
|
@ -272,6 +320,8 @@ struct Commit {
|
||||||
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>,
|
||||||
|
pending_polls: Cell<SmallVec<[PendingPoll; 1]>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn flush_from(mut point: NodeRef<Entry>) -> Result<(), WlSurfaceError> {
|
fn flush_from(mut point: NodeRef<Entry>) -> Result<(), WlSurfaceError> {
|
||||||
|
|
@ -304,6 +354,9 @@ impl NodeRef<Entry> {
|
||||||
has_unmet_dependencies = true;
|
has_unmet_dependencies = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if c.num_pending_polls.get() > 0 {
|
||||||
|
has_unmet_dependencies = true;
|
||||||
|
}
|
||||||
if has_unmet_dependencies {
|
if has_unmet_dependencies {
|
||||||
return Ok(false);
|
return Ok(false);
|
||||||
}
|
}
|
||||||
|
|
@ -417,18 +470,26 @@ fn collect_commit_data(
|
||||||
pending: &mut PendingState,
|
pending: &mut PendingState,
|
||||||
acquire_points: &mut SmallVec<[Point; 1]>,
|
acquire_points: &mut SmallVec<[Point; 1]>,
|
||||||
shm_uploads: &mut usize,
|
shm_uploads: &mut usize,
|
||||||
|
implicit_dmabufs: &mut SmallVec<[Rc<OwnedFd>; 1]>,
|
||||||
) {
|
) {
|
||||||
if let Some(Some(buffer)) = &pending.buffer {
|
if let Some(Some(buffer)) = &pending.buffer {
|
||||||
if buffer.is_shm() {
|
if buffer.is_shm() {
|
||||||
*shm_uploads += 1;
|
*shm_uploads += 1;
|
||||||
}
|
}
|
||||||
|
if !pending.explicit_sync {
|
||||||
|
if let Some(dmabuf) = &buffer.dmabuf {
|
||||||
|
for plane in &dmabuf.planes {
|
||||||
|
implicit_dmabufs.push(plane.fd.clone());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if let Some(point) = pending.acquire_point.take() {
|
if let Some(point) = pending.acquire_point.take() {
|
||||||
acquire_points.push(point);
|
acquire_points.push(point);
|
||||||
}
|
}
|
||||||
for ss in pending.subsurfaces.values_mut() {
|
for ss in pending.subsurfaces.values_mut() {
|
||||||
if let Some(state) = &mut ss.pending.state {
|
if let Some(state) = &mut ss.pending.state {
|
||||||
collect_commit_data(state, acquire_points, shm_uploads);
|
collect_commit_data(state, acquire_points, shm_uploads, implicit_dmabufs);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,14 @@
|
||||||
pub use ops::TaskResultExt;
|
pub use ops::{
|
||||||
|
poll_external::{PendingPoll, PollCallback},
|
||||||
|
TaskResultExt,
|
||||||
|
};
|
||||||
use {
|
use {
|
||||||
crate::{
|
crate::{
|
||||||
async_engine::AsyncEngine,
|
async_engine::AsyncEngine,
|
||||||
io_uring::{
|
io_uring::{
|
||||||
ops::{
|
ops::{
|
||||||
accept::AcceptTask, async_cancel::AsyncCancelTask, connect::ConnectTask,
|
accept::AcceptTask, async_cancel::AsyncCancelTask, connect::ConnectTask,
|
||||||
poll::PollTask, read_write::ReadWriteTask,
|
poll::PollTask, poll_external::PollExternalTask, read_write::ReadWriteTask,
|
||||||
read_write_no_cancel::ReadWriteNoCancelTask, recvmsg::RecvmsgTask,
|
read_write_no_cancel::ReadWriteNoCancelTask, recvmsg::RecvmsgTask,
|
||||||
sendmsg::SendmsgTask, timeout::TimeoutTask, timeout_link::TimeoutLinkTask,
|
sendmsg::SendmsgTask, timeout::TimeoutTask, timeout_link::TimeoutLinkTask,
|
||||||
},
|
},
|
||||||
|
|
@ -209,6 +212,7 @@ impl IoUring {
|
||||||
cached_read_writes_no_cancel: Default::default(),
|
cached_read_writes_no_cancel: Default::default(),
|
||||||
cached_cancels: Default::default(),
|
cached_cancels: Default::default(),
|
||||||
cached_polls: Default::default(),
|
cached_polls: Default::default(),
|
||||||
|
cached_polls_external: Default::default(),
|
||||||
cached_sendmsg: Default::default(),
|
cached_sendmsg: Default::default(),
|
||||||
cached_recvmsg: Default::default(),
|
cached_recvmsg: Default::default(),
|
||||||
cached_timeouts: Default::default(),
|
cached_timeouts: Default::default(),
|
||||||
|
|
@ -270,6 +274,7 @@ struct IoUringData {
|
||||||
cached_read_writes_no_cancel: Stack<Box<ReadWriteNoCancelTask>>,
|
cached_read_writes_no_cancel: Stack<Box<ReadWriteNoCancelTask>>,
|
||||||
cached_cancels: Stack<Box<AsyncCancelTask>>,
|
cached_cancels: Stack<Box<AsyncCancelTask>>,
|
||||||
cached_polls: Stack<Box<PollTask>>,
|
cached_polls: Stack<Box<PollTask>>,
|
||||||
|
cached_polls_external: Stack<Box<PollExternalTask>>,
|
||||||
cached_sendmsg: Stack<Box<SendmsgTask>>,
|
cached_sendmsg: Stack<Box<SendmsgTask>>,
|
||||||
cached_recvmsg: Stack<Box<RecvmsgTask>>,
|
cached_recvmsg: Stack<Box<RecvmsgTask>>,
|
||||||
cached_timeouts: Stack<Box<TimeoutTask>>,
|
cached_timeouts: Stack<Box<TimeoutTask>>,
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@ pub mod accept;
|
||||||
pub mod async_cancel;
|
pub mod async_cancel;
|
||||||
pub mod connect;
|
pub mod connect;
|
||||||
pub mod poll;
|
pub mod poll;
|
||||||
|
pub mod poll_external;
|
||||||
pub mod read_write;
|
pub mod read_write;
|
||||||
pub mod read_write_no_cancel;
|
pub mod read_write_no_cancel;
|
||||||
pub mod recvmsg;
|
pub mod recvmsg;
|
||||||
|
|
|
||||||
116
src/io_uring/ops/poll_external.rs
Normal file
116
src/io_uring/ops/poll_external.rs
Normal file
|
|
@ -0,0 +1,116 @@
|
||||||
|
use {
|
||||||
|
crate::{
|
||||||
|
io_uring::{
|
||||||
|
sys::{io_uring_sqe, IORING_OP_POLL_ADD},
|
||||||
|
IoUring, IoUringData, IoUringError, IoUringTaskId, Task,
|
||||||
|
},
|
||||||
|
utils::oserror::OsError,
|
||||||
|
},
|
||||||
|
std::{cell::Cell, rc::Rc},
|
||||||
|
uapi::{c, OwnedFd},
|
||||||
|
};
|
||||||
|
|
||||||
|
pub trait PollCallback {
|
||||||
|
fn completed(self: Rc<Self>, res: Result<c::c_short, OsError>);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct PendingPoll {
|
||||||
|
data: Rc<IoUringData>,
|
||||||
|
shared: Rc<PollExternalTaskShared>,
|
||||||
|
id: IoUringTaskId,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Drop for PendingPoll {
|
||||||
|
fn drop(&mut self) {
|
||||||
|
if self.shared.id.get() != self.id {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
self.shared.callback.take();
|
||||||
|
self.data.cancel_task(self.id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl IoUring {
|
||||||
|
pub fn poll_external(
|
||||||
|
&self,
|
||||||
|
fd: &Rc<OwnedFd>,
|
||||||
|
events: c::c_short,
|
||||||
|
callback: Rc<dyn PollCallback>,
|
||||||
|
) -> Result<PendingPoll, IoUringError> {
|
||||||
|
self.ring.check_destroyed()?;
|
||||||
|
let mut pw = self.ring.cached_polls_external.pop().unwrap_or_default();
|
||||||
|
pw.shared.id.set(self.ring.id_raw());
|
||||||
|
pw.shared.callback.set(Some(callback));
|
||||||
|
pw.fd = fd.raw() as _;
|
||||||
|
pw.events = events as _;
|
||||||
|
pw.data = Some(Data { _fd: fd.clone() });
|
||||||
|
let pending = PendingPoll {
|
||||||
|
data: self.ring.clone(),
|
||||||
|
shared: pw.shared.clone(),
|
||||||
|
id: pw.shared.id.get(),
|
||||||
|
};
|
||||||
|
self.ring.schedule(pw);
|
||||||
|
Ok(pending)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn readable_external(
|
||||||
|
&self,
|
||||||
|
fd: &Rc<OwnedFd>,
|
||||||
|
callback: Rc<dyn PollCallback>,
|
||||||
|
) -> Result<PendingPoll, IoUringError> {
|
||||||
|
self.poll_external(fd, c::POLLIN, callback)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[expect(dead_code)]
|
||||||
|
pub fn writable_external(
|
||||||
|
&self,
|
||||||
|
fd: &Rc<OwnedFd>,
|
||||||
|
callback: Rc<dyn PollCallback>,
|
||||||
|
) -> Result<PendingPoll, IoUringError> {
|
||||||
|
self.poll_external(fd, c::POLLOUT, callback)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Data {
|
||||||
|
_fd: Rc<OwnedFd>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Default)]
|
||||||
|
struct PollExternalTaskShared {
|
||||||
|
id: Cell<IoUringTaskId>,
|
||||||
|
callback: Cell<Option<Rc<dyn PollCallback>>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Default)]
|
||||||
|
pub struct PollExternalTask {
|
||||||
|
shared: Rc<PollExternalTaskShared>,
|
||||||
|
events: u16,
|
||||||
|
fd: i32,
|
||||||
|
data: Option<Data>,
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe impl Task for PollExternalTask {
|
||||||
|
fn id(&self) -> IoUringTaskId {
|
||||||
|
self.shared.id.get()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn complete(mut self: Box<Self>, ring: &IoUringData, res: i32) {
|
||||||
|
self.data.take();
|
||||||
|
self.shared.id.set(Default::default());
|
||||||
|
if let Some(cb) = self.shared.callback.take() {
|
||||||
|
let res = if res < 0 {
|
||||||
|
Err(OsError::from(-res as c::c_int))
|
||||||
|
} else {
|
||||||
|
Ok(res as _)
|
||||||
|
};
|
||||||
|
cb.completed(res)
|
||||||
|
}
|
||||||
|
ring.cached_polls_external.push(self);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn encode(&self, sqe: &mut io_uring_sqe) {
|
||||||
|
sqe.opcode = IORING_OP_POLL_ADD;
|
||||||
|
sqe.fd = self.fd;
|
||||||
|
sqe.u3.poll_events = self.events;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -472,7 +472,7 @@ impl Renderer<'_> {
|
||||||
self.base.scale,
|
self.base.scale,
|
||||||
bounds,
|
bounds,
|
||||||
Some(buffer.clone()),
|
Some(buffer.clone()),
|
||||||
buffer.sync.clone(),
|
AcquireSync::Unnecessary,
|
||||||
buffer.release_sync,
|
buffer.release_sync,
|
||||||
);
|
);
|
||||||
} else if let Some(color) = &buffer.buffer.color {
|
} else if let Some(color) = &buffer.buffer.color {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue