Merge pull request #783 from mahkoh/jorth/sync-file-surface
wl_surface: add jay_sync_file_surface extension
This commit is contained in:
commit
fe8b51ffb6
13 changed files with 424 additions and 24 deletions
|
|
@ -24,6 +24,7 @@ use {
|
|||
jay_tree_query::JayTreeQuery,
|
||||
jay_workspace_watcher::JayWorkspaceWatcher,
|
||||
jay_xwayland::JayXwayland,
|
||||
wl_surface::jay_sync_file_surface::JaySyncFileSurface,
|
||||
},
|
||||
leaks::Tracker,
|
||||
object::{Object, Version},
|
||||
|
|
@ -76,7 +77,7 @@ global_base!(JayCompositorGlobal, JayCompositor, JayCompositorError);
|
|||
|
||||
impl Global for JayCompositorGlobal {
|
||||
fn version(&self) -> u32 {
|
||||
25
|
||||
26
|
||||
}
|
||||
|
||||
fn required_caps(&self) -> ClientCaps {
|
||||
|
|
@ -520,6 +521,18 @@ impl JayCompositorRequestHandler for JayCompositor {
|
|||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn get_sync_file_surface(
|
||||
&self,
|
||||
req: GetSyncFileSurface,
|
||||
_slf: &Rc<Self>,
|
||||
) -> Result<(), Self::Error> {
|
||||
let surface = self.client.lookup(req.surface)?;
|
||||
let obj = Rc::new(JaySyncFileSurface::new(req.id, self.version, &surface));
|
||||
track!(self.client, obj);
|
||||
self.client.add_client_obj(&obj)?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
object_base! {
|
||||
|
|
|
|||
|
|
@ -2,6 +2,8 @@ pub mod commit_timeline;
|
|||
pub mod cursor;
|
||||
pub mod dnd_icon;
|
||||
pub mod ext_session_lock_surface_v1;
|
||||
pub mod jay_sync_file_release;
|
||||
pub mod jay_sync_file_surface;
|
||||
pub mod tray;
|
||||
pub mod wl_subsurface;
|
||||
pub mod wp_alpha_modifier_surface_v1;
|
||||
|
|
@ -31,7 +33,7 @@ use {
|
|||
fixed::Fixed,
|
||||
gfx_api::{
|
||||
AlphaMode, AsyncShmGfxTexture, BufferResv, BufferResvUser, FdSync, GfxError,
|
||||
GfxStagingBuffer, ReleaseSync, SampleRect,
|
||||
GfxStagingBuffer, ReleaseSync, SampleRect, SyncFile,
|
||||
},
|
||||
ifs::{
|
||||
color_management::wp_color_management_surface_feedback_v1::WpColorManagementSurfaceFeedbackV1,
|
||||
|
|
@ -52,6 +54,7 @@ use {
|
|||
commit_timeline::{ClearReason, CommitTimeline, CommitTimelineError},
|
||||
cursor::CursorSurface,
|
||||
dnd_icon::DndIcon,
|
||||
jay_sync_file_release::SyncFileRelease,
|
||||
tray::TrayItemId,
|
||||
wl_subsurface::{PendingSubsurfaceData, SubsurfaceId, WlSubsurface},
|
||||
wp_alpha_modifier_surface_v1::WpAlphaModifierSurfaceV1,
|
||||
|
|
@ -90,7 +93,7 @@ use {
|
|||
},
|
||||
video::{
|
||||
dmabuf::DMA_BUF_SYNC_READ,
|
||||
drm::syncobj::{Syncobj, SyncobjPoint},
|
||||
drm::syncobj::{Syncobj, SyncobjPoint, merge_sync_files},
|
||||
},
|
||||
wire::{
|
||||
WlOutputId, WlSurfaceId, WpColorManagementSurfaceFeedbackV1Id, ZwpIdleInhibitorV1Id,
|
||||
|
|
@ -219,11 +222,20 @@ pub struct SurfaceBuffer {
|
|||
pub release_sync: ReleaseSync,
|
||||
release: Option<SyncobjRelease>,
|
||||
_surface_release: SmallVec<[SurfaceRelease; 1]>,
|
||||
sync_file_release: Option<SyncFileRelease>,
|
||||
}
|
||||
|
||||
impl Drop for SurfaceBuffer {
|
||||
fn drop(&mut self) {
|
||||
let syncs = self.syncs.take();
|
||||
if let Some(release) = &mut self.sync_file_release {
|
||||
let sync_file = merge_sync_files(syncs.iter().flat_map(|f| f.1.get_sync_file()))
|
||||
.unwrap_or_else(|e| {
|
||||
log::error!("Could not merge sync files: {}", ErrorFmt(e));
|
||||
None
|
||||
});
|
||||
release.done(sync_file.as_ref());
|
||||
}
|
||||
if let Some(release) = &mut self.release {
|
||||
release.signal(Some(&syncs));
|
||||
return;
|
||||
|
|
@ -456,8 +468,10 @@ struct PendingState {
|
|||
subsurfaces: AHashMap<SubsurfaceId, AttachedSubsurfaceState>,
|
||||
acquire_point: Option<(Rc<Syncobj>, SyncobjPoint)>,
|
||||
release_point: Option<SyncobjRelease>,
|
||||
sync_file_acquire: Option<Option<SyncFile>>,
|
||||
sync_file_release: Option<SyncFileRelease>,
|
||||
alpha_multiplier: Option<Option<f32>>,
|
||||
explicit_sync: bool,
|
||||
syncobj_sync: bool,
|
||||
fifo_barrier_set: bool,
|
||||
fifo_barrier_wait: bool,
|
||||
commit_time: Option<u64>,
|
||||
|
|
@ -485,8 +499,9 @@ impl PendingState {
|
|||
self.buffer = Some(buffer);
|
||||
self.acquire_point = next.acquire_point.take();
|
||||
self.release_point = next.release_point.take();
|
||||
self.explicit_sync = mem::take(&mut next.explicit_sync);
|
||||
self.syncobj_sync = mem::take(&mut next.syncobj_sync);
|
||||
self.surface_release = mem::take(&mut next.surface_release);
|
||||
self.sync_file_release = next.sync_file_release.take();
|
||||
}
|
||||
macro_rules! opt {
|
||||
($name:ident) => {
|
||||
|
|
@ -510,6 +525,7 @@ impl PendingState {
|
|||
opt!(color_description);
|
||||
opt!(serial);
|
||||
opt!(alpha_mode);
|
||||
opt!(sync_file_acquire);
|
||||
{
|
||||
let (dx1, dy1) = self.offset;
|
||||
let (dx2, dy2) = mem::take(&mut next.offset);
|
||||
|
|
@ -1094,16 +1110,20 @@ impl WlSurfaceRequestHandler for WlSurface {
|
|||
let pending = &mut *self.pending.borrow_mut();
|
||||
if let Some(Some(buffer)) = &mut pending.buffer
|
||||
&& pending.release_point.is_none()
|
||||
&& pending.sync_file_release.is_none()
|
||||
{
|
||||
buffer.send_release = true;
|
||||
}
|
||||
if let Some(release) = &mut pending.release_point {
|
||||
release.committed = true;
|
||||
}
|
||||
self.verify_explicit_sync(pending)?;
|
||||
self.verify_syncobj_sync(pending)?;
|
||||
if pending.surface_release.is_not_empty() && not_matches!(pending.buffer, Some(Some(_))) {
|
||||
return Err(WlSurfaceError::SurfaceReleaseWithoutAttach);
|
||||
}
|
||||
if pending.sync_file_release.is_some() && not_matches!(pending.buffer, Some(Some(_))) {
|
||||
return Err(WlSurfaceError::SyncFileReleaseWithoutAttach);
|
||||
}
|
||||
if ext.commit_requested(pending) == CommitAction::ContinueCommit {
|
||||
self.commit_timeline.commit(slf, pending)?;
|
||||
}
|
||||
|
|
@ -1227,16 +1247,17 @@ impl WlSurface {
|
|||
self.reset_shm_textures();
|
||||
}
|
||||
buffer.buf.update_texture_or_log(self, false);
|
||||
let release_sync = match pending.explicit_sync {
|
||||
false => ReleaseSync::Implicit,
|
||||
true => ReleaseSync::Explicit,
|
||||
};
|
||||
let mut release_sync = ReleaseSync::Implicit;
|
||||
if pending.syncobj_sync || pending.sync_file_release.is_some() {
|
||||
release_sync = ReleaseSync::Explicit;
|
||||
}
|
||||
let surface_buffer = SurfaceBuffer {
|
||||
buffer,
|
||||
syncs: Default::default(),
|
||||
release_sync,
|
||||
release: pending.release_point.take(),
|
||||
_surface_release: mem::take(&mut pending.surface_release),
|
||||
sync_file_release: pending.sync_file_release.take(),
|
||||
};
|
||||
self.buffer.set(Some(Rc::new(surface_buffer)));
|
||||
} else {
|
||||
|
|
@ -1542,9 +1563,9 @@ impl WlSurface {
|
|||
}
|
||||
}
|
||||
|
||||
fn verify_explicit_sync(&self, pending: &mut PendingState) -> Result<(), WlSurfaceError> {
|
||||
pending.explicit_sync = self.syncobj_surface.is_some();
|
||||
if !pending.explicit_sync {
|
||||
fn verify_syncobj_sync(&self, pending: &mut PendingState) -> Result<(), WlSurfaceError> {
|
||||
pending.syncobj_sync = self.syncobj_surface.is_some();
|
||||
if !pending.syncobj_sync {
|
||||
return Ok(());
|
||||
}
|
||||
let have_new_buffer = match &pending.buffer {
|
||||
|
|
@ -2171,6 +2192,8 @@ pub enum WlSurfaceError {
|
|||
RegisterCommitTimeout(#[source] IoUringError),
|
||||
#[error("Content update contains release callbacks but no non-null buffer")]
|
||||
SurfaceReleaseWithoutAttach,
|
||||
#[error("Content update contains sync file release but no non-null buffer")]
|
||||
SyncFileReleaseWithoutAttach,
|
||||
}
|
||||
efrom!(WlSurfaceError, ClientError);
|
||||
efrom!(WlSurfaceError, XdgSurfaceError);
|
||||
|
|
|
|||
|
|
@ -203,18 +203,18 @@ impl CommitTimeline {
|
|||
let mut collector = CommitDataCollector {
|
||||
acquire_points: Default::default(),
|
||||
shm_uploads: 0,
|
||||
implicit_dmabufs: Default::default(),
|
||||
acquire_files: Default::default(),
|
||||
commit_time: Default::default(),
|
||||
};
|
||||
collector.collect(pending);
|
||||
let points = collector.acquire_points;
|
||||
let pending_uploads = collector.shm_uploads;
|
||||
let implicit_dmabufs = collector.implicit_dmabufs;
|
||||
let acquire_files = collector.acquire_files;
|
||||
let commit_time = collector.commit_time;
|
||||
let has_commit_time = commit_time > 0;
|
||||
let has_dependencies = points.is_not_empty()
|
||||
|| pending_uploads > 0
|
||||
|| implicit_dmabufs.is_not_empty()
|
||||
|| acquire_files.is_not_empty()
|
||||
|| has_commit_time;
|
||||
let must_be_queued = has_dependencies
|
||||
|| self.own_timeline.entries.is_not_empty()
|
||||
|
|
@ -242,7 +242,7 @@ impl CommitTimeline {
|
|||
wait_handles: Cell::new(Default::default()),
|
||||
pending_uploads: NumCell::new(pending_uploads),
|
||||
shm_upload: RefCell::new(ShmUploadState::None),
|
||||
num_pending_polls: NumCell::new(implicit_dmabufs.len()),
|
||||
num_pending_polls: NumCell::new(acquire_files.len()),
|
||||
pending_polls: Cell::new(Default::default()),
|
||||
fifo_state: Cell::new(commit_fifo_state),
|
||||
commit_times: RefCell::new(CommitTimesState::Ready),
|
||||
|
|
@ -270,9 +270,9 @@ impl CommitTimeline {
|
|||
*commit.shm_upload.borrow_mut() = ShmUploadState::Todo(noderef.clone());
|
||||
needs_flush = true;
|
||||
}
|
||||
if implicit_dmabufs.is_not_empty() {
|
||||
if acquire_files.is_not_empty() {
|
||||
let mut pending_polls = SmallVec::new();
|
||||
for fd in implicit_dmabufs {
|
||||
for fd in acquire_files {
|
||||
let handle = self
|
||||
.shared
|
||||
.ring
|
||||
|
|
@ -692,7 +692,7 @@ type Point = (Rc<Syncobj>, SyncobjPoint);
|
|||
struct CommitDataCollector {
|
||||
acquire_points: SmallVec<[Point; 1]>,
|
||||
shm_uploads: usize,
|
||||
implicit_dmabufs: SmallVec<[Rc<OwnedFd>; 1]>,
|
||||
acquire_files: SmallVec<[Rc<OwnedFd>; 1]>,
|
||||
commit_time: u64,
|
||||
}
|
||||
|
||||
|
|
@ -703,14 +703,18 @@ impl CommitDataCollector {
|
|||
if buffer.is_shm() {
|
||||
self.shm_uploads += 1;
|
||||
}
|
||||
if !pending.explicit_sync
|
||||
if !pending.syncobj_sync
|
||||
&& pending.sync_file_acquire.is_none()
|
||||
&& let Some(dmabuf) = &buffer.client_dmabuf
|
||||
{
|
||||
for plane in &dmabuf.planes {
|
||||
self.implicit_dmabufs.push(plane.fd.clone());
|
||||
self.acquire_files.push(plane.fd.clone());
|
||||
}
|
||||
}
|
||||
}
|
||||
if let Some(Some(sf)) = pending.sync_file_acquire.take() {
|
||||
self.acquire_files.push(sf.0);
|
||||
}
|
||||
if let Some(point) = pending.acquire_point.take() {
|
||||
self.acquire_points.push(point);
|
||||
}
|
||||
|
|
|
|||
92
src/ifs/wl_surface/jay_sync_file_release.rs
Normal file
92
src/ifs/wl_surface/jay_sync_file_release.rs
Normal file
|
|
@ -0,0 +1,92 @@
|
|||
use {
|
||||
crate::{
|
||||
client::{Client, ClientError},
|
||||
gfx_api::SyncFile,
|
||||
leaks::Tracker,
|
||||
object::{Object, Version},
|
||||
wire::{JaySyncFileReleaseId, jay_sync_file_release::*},
|
||||
},
|
||||
std::{cell::Cell, rc::Rc},
|
||||
thiserror::Error,
|
||||
};
|
||||
|
||||
pub struct SyncFileRelease {
|
||||
pub release: Option<Rc<JaySyncFileRelease>>,
|
||||
}
|
||||
|
||||
impl SyncFileRelease {
|
||||
pub fn done(&mut self, sync_file: Option<&SyncFile>) {
|
||||
if let Some(release) = self.release.take() {
|
||||
release.done(sync_file);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for SyncFileRelease {
|
||||
fn drop(&mut self) {
|
||||
self.done(None);
|
||||
}
|
||||
}
|
||||
|
||||
pub struct JaySyncFileRelease {
|
||||
pub id: JaySyncFileReleaseId,
|
||||
pub client: Rc<Client>,
|
||||
pub tracker: Tracker<Self>,
|
||||
pub version: Version,
|
||||
pub destroyed: Cell<bool>,
|
||||
}
|
||||
|
||||
impl JaySyncFileRelease {
|
||||
pub fn new(client: &Rc<Client>, id: JaySyncFileReleaseId, version: Version) -> Self {
|
||||
Self {
|
||||
id,
|
||||
client: client.clone(),
|
||||
tracker: Default::default(),
|
||||
version,
|
||||
destroyed: Cell::new(false),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn done(&self, sync_file: Option<&SyncFile>) {
|
||||
if self.destroyed.get() {
|
||||
return;
|
||||
}
|
||||
match sync_file {
|
||||
None => {
|
||||
self.client.event(ReleaseImmediate { self_id: self.id });
|
||||
}
|
||||
Some(fd) => {
|
||||
self.client.event(ReleaseAsync {
|
||||
self_id: self.id,
|
||||
sync_file: fd.0.clone(),
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl JaySyncFileReleaseRequestHandler for JaySyncFileRelease {
|
||||
type Error = JaySyncFileReleaseError;
|
||||
|
||||
fn destroy(&self, _req: Destroy, _slf: &Rc<Self>) -> Result<(), Self::Error> {
|
||||
self.destroyed.set(true);
|
||||
self.client.remove_obj(self)?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
object_base! {
|
||||
self = JaySyncFileRelease;
|
||||
version = self.version;
|
||||
}
|
||||
|
||||
impl Object for JaySyncFileRelease {}
|
||||
|
||||
simple_add_obj!(JaySyncFileRelease);
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
pub enum JaySyncFileReleaseError {
|
||||
#[error(transparent)]
|
||||
ClientError(Box<ClientError>),
|
||||
}
|
||||
efrom!(JaySyncFileReleaseError, ClientError);
|
||||
92
src/ifs/wl_surface/jay_sync_file_surface.rs
Normal file
92
src/ifs/wl_surface/jay_sync_file_surface.rs
Normal file
|
|
@ -0,0 +1,92 @@
|
|||
use {
|
||||
crate::{
|
||||
client::{Client, ClientError},
|
||||
gfx_api::SyncFile,
|
||||
ifs::wl_surface::{
|
||||
WlSurface,
|
||||
jay_sync_file_release::{JaySyncFileRelease, SyncFileRelease},
|
||||
},
|
||||
leaks::Tracker,
|
||||
object::{Object, Version},
|
||||
wire::{JaySyncFileSurfaceId, jay_sync_file_surface::*},
|
||||
},
|
||||
std::rc::Rc,
|
||||
thiserror::Error,
|
||||
};
|
||||
|
||||
pub struct JaySyncFileSurface {
|
||||
pub id: JaySyncFileSurfaceId,
|
||||
pub client: Rc<Client>,
|
||||
pub surface: Rc<WlSurface>,
|
||||
pub tracker: Tracker<Self>,
|
||||
pub version: Version,
|
||||
}
|
||||
|
||||
impl JaySyncFileSurface {
|
||||
pub fn new(id: JaySyncFileSurfaceId, version: Version, surface: &Rc<WlSurface>) -> Self {
|
||||
Self {
|
||||
id,
|
||||
client: surface.client.clone(),
|
||||
surface: surface.clone(),
|
||||
tracker: Default::default(),
|
||||
version,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl JaySyncFileSurfaceRequestHandler for JaySyncFileSurface {
|
||||
type Error = JaySyncFileSurfaceError;
|
||||
|
||||
fn destroy(&self, _req: Destroy, _slf: &Rc<Self>) -> Result<(), Self::Error> {
|
||||
self.client.remove_obj(self)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn set_acquire_immediate(
|
||||
&self,
|
||||
_req: SetAcquireImmediate,
|
||||
_slf: &Rc<Self>,
|
||||
) -> Result<(), Self::Error> {
|
||||
self.surface.pending.borrow_mut().sync_file_acquire = Some(None);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn set_acquire_async(&self, req: SetAcquireAsync, _slf: &Rc<Self>) -> Result<(), Self::Error> {
|
||||
self.surface.pending.borrow_mut().sync_file_acquire = Some(Some(SyncFile(req.sync_file)));
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn get_release(&self, req: GetRelease, _slf: &Rc<Self>) -> Result<(), Self::Error> {
|
||||
let obj = Rc::new(JaySyncFileRelease::new(
|
||||
&self.client,
|
||||
req.release,
|
||||
self.version,
|
||||
));
|
||||
track!(self.client, obj);
|
||||
self.client.add_client_obj(&obj)?;
|
||||
let pending = &mut *self.surface.pending.borrow_mut();
|
||||
if pending.sync_file_release.is_some() {
|
||||
return Err(JaySyncFileSurfaceError::HasRelease);
|
||||
}
|
||||
pending.sync_file_release = Some(SyncFileRelease { release: Some(obj) });
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
object_base! {
|
||||
self = JaySyncFileSurface;
|
||||
version = self.version;
|
||||
}
|
||||
|
||||
impl Object for JaySyncFileSurface {}
|
||||
|
||||
simple_add_obj!(JaySyncFileSurface);
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
pub enum JaySyncFileSurfaceError {
|
||||
#[error(transparent)]
|
||||
ClientError(Box<ClientError>),
|
||||
#[error("The content update already has a release object")]
|
||||
HasRelease,
|
||||
}
|
||||
efrom!(JaySyncFileSurfaceError, ClientError);
|
||||
|
|
@ -352,7 +352,7 @@ fn destroy(drm: &OwnedFd, handle: SyncobjHandle) {
|
|||
}
|
||||
}
|
||||
|
||||
fn merge_sync_files<'a, I>(sync_files: I) -> Result<Option<SyncFile>, DrmError>
|
||||
pub fn merge_sync_files<'a, I>(sync_files: I) -> Result<Option<SyncFile>, DrmError>
|
||||
where
|
||||
I: IntoIterator<Item = &'a SyncFile>,
|
||||
{
|
||||
|
|
|
|||
|
|
@ -7,6 +7,8 @@ pub mod usr_jay_render_ctx;
|
|||
pub mod usr_jay_screencast;
|
||||
pub mod usr_jay_select_toplevel;
|
||||
pub mod usr_jay_select_workspace;
|
||||
pub mod usr_jay_sync_file_release;
|
||||
pub mod usr_jay_sync_file_surface;
|
||||
pub mod usr_jay_toplevel;
|
||||
pub mod usr_jay_workspace;
|
||||
pub mod usr_jay_workspace_watcher;
|
||||
|
|
|
|||
|
|
@ -12,8 +12,9 @@ use {
|
|||
usr_jay_screencast::UsrJayScreencast,
|
||||
usr_jay_select_toplevel::UsrJaySelectToplevel,
|
||||
usr_jay_select_workspace::UsrJaySelectWorkspace,
|
||||
usr_jay_sync_file_surface::UsrJaySyncFileSurface,
|
||||
usr_jay_workspace_watcher::UsrJayWorkspaceWatcher, usr_wl_output::UsrWlOutput,
|
||||
usr_wl_seat::UsrWlSeat,
|
||||
usr_wl_seat::UsrWlSeat, usr_wl_surface::UsrWlSurface,
|
||||
},
|
||||
usr_object::UsrObject,
|
||||
},
|
||||
|
|
@ -187,6 +188,22 @@ impl UsrJayCompositor {
|
|||
self.con.add_object(obj.clone());
|
||||
obj
|
||||
}
|
||||
|
||||
#[expect(dead_code)]
|
||||
pub fn get_sync_file_surface(&self, surface: &UsrWlSurface) -> Rc<UsrJaySyncFileSurface> {
|
||||
let obj = Rc::new(UsrJaySyncFileSurface {
|
||||
id: self.con.id(),
|
||||
con: self.con.clone(),
|
||||
version: self.version,
|
||||
});
|
||||
self.con.request(GetSyncFileSurface {
|
||||
self_id: self.id,
|
||||
id: obj.id,
|
||||
surface: surface.id,
|
||||
});
|
||||
self.con.add_object(obj.clone());
|
||||
obj
|
||||
}
|
||||
}
|
||||
|
||||
impl JayCompositorEventHandler for UsrJayCompositor {
|
||||
|
|
|
|||
60
src/wl_usr/usr_ifs/usr_jay_sync_file_release.rs
Normal file
60
src/wl_usr/usr_ifs/usr_jay_sync_file_release.rs
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
use {
|
||||
crate::{
|
||||
gfx_api::SyncFile,
|
||||
object::Version,
|
||||
utils::clonecell::CloneCell,
|
||||
wire::{JaySyncFileReleaseId, jay_sync_file_release::*},
|
||||
wl_usr::{UsrCon, usr_object::UsrObject},
|
||||
},
|
||||
std::{convert::Infallible, rc::Rc},
|
||||
uapi::OwnedFd,
|
||||
};
|
||||
|
||||
pub struct UsrJaySyncFileRelease {
|
||||
pub id: JaySyncFileReleaseId,
|
||||
pub con: Rc<UsrCon>,
|
||||
pub owner: CloneCell<Option<Rc<dyn UsrJaySyncFileReleaseOwner>>>,
|
||||
pub version: Version,
|
||||
}
|
||||
|
||||
pub trait UsrJaySyncFileReleaseOwner {
|
||||
fn release(&self, sync_file: Option<SyncFile>);
|
||||
}
|
||||
|
||||
impl UsrJaySyncFileRelease {
|
||||
fn release(&self, sf: Option<Rc<OwnedFd>>) {
|
||||
if let Some(owner) = self.owner.get() {
|
||||
owner.release(sf.map(SyncFile));
|
||||
}
|
||||
self.con.remove_obj(self);
|
||||
}
|
||||
}
|
||||
|
||||
impl JaySyncFileReleaseEventHandler for UsrJaySyncFileRelease {
|
||||
type Error = Infallible;
|
||||
|
||||
fn release_immediate(&self, _ev: ReleaseImmediate, _slf: &Rc<Self>) -> Result<(), Self::Error> {
|
||||
self.release(None);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn release_async(&self, ev: ReleaseAsync, _slf: &Rc<Self>) -> Result<(), Self::Error> {
|
||||
self.release(Some(ev.sync_file));
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
usr_object_base! {
|
||||
self = UsrJaySyncFileRelease = JaySyncFileRelease;
|
||||
version = self.version;
|
||||
}
|
||||
|
||||
impl UsrObject for UsrJaySyncFileRelease {
|
||||
fn destroy(&self) {
|
||||
self.con.request(Destroy { self_id: self.id });
|
||||
}
|
||||
|
||||
fn break_loops(&self) {
|
||||
self.owner.take();
|
||||
}
|
||||
}
|
||||
66
src/wl_usr/usr_ifs/usr_jay_sync_file_surface.rs
Normal file
66
src/wl_usr/usr_ifs/usr_jay_sync_file_surface.rs
Normal file
|
|
@ -0,0 +1,66 @@
|
|||
use {
|
||||
crate::{
|
||||
gfx_api::SyncFile,
|
||||
object::Version,
|
||||
wire::{JaySyncFileSurfaceId, jay_sync_file_surface::*},
|
||||
wl_usr::{
|
||||
UsrCon, usr_ifs::usr_jay_sync_file_release::UsrJaySyncFileRelease,
|
||||
usr_object::UsrObject,
|
||||
},
|
||||
},
|
||||
std::{convert::Infallible, rc::Rc},
|
||||
};
|
||||
|
||||
pub struct UsrJaySyncFileSurface {
|
||||
pub id: JaySyncFileSurfaceId,
|
||||
pub con: Rc<UsrCon>,
|
||||
pub version: Version,
|
||||
}
|
||||
|
||||
impl UsrJaySyncFileSurface {
|
||||
#[expect(dead_code)]
|
||||
pub fn set_acquire(&self, sf: Option<&SyncFile>) {
|
||||
match sf {
|
||||
None => {
|
||||
self.con.request(SetAcquireImmediate { self_id: self.id });
|
||||
}
|
||||
Some(sf) => {
|
||||
self.con.request(SetAcquireAsync {
|
||||
self_id: self.id,
|
||||
sync_file: sf.0.clone(),
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[expect(dead_code)]
|
||||
pub fn get_release(&self) -> Rc<UsrJaySyncFileRelease> {
|
||||
let obj = Rc::new(UsrJaySyncFileRelease {
|
||||
id: self.con.id(),
|
||||
con: self.con.clone(),
|
||||
owner: Default::default(),
|
||||
version: self.version,
|
||||
});
|
||||
self.con.request(GetRelease {
|
||||
self_id: self.id,
|
||||
release: obj.id,
|
||||
});
|
||||
self.con.add_object(obj.clone());
|
||||
obj
|
||||
}
|
||||
}
|
||||
|
||||
impl JaySyncFileSurfaceEventHandler for UsrJaySyncFileSurface {
|
||||
type Error = Infallible;
|
||||
}
|
||||
|
||||
usr_object_base! {
|
||||
self = UsrJaySyncFileSurface = JaySyncFileSurface;
|
||||
version = self.version;
|
||||
}
|
||||
|
||||
impl UsrObject for UsrJaySyncFileSurface {
|
||||
fn destroy(&self) {
|
||||
self.con.request(Destroy { self_id: self.id });
|
||||
}
|
||||
}
|
||||
|
|
@ -126,6 +126,11 @@ request get_tagged_acceptor (since = 25) {
|
|||
tag: str,
|
||||
}
|
||||
|
||||
request get_sync_file_surface (since = 26) {
|
||||
id: id(jay_sync_file_surface),
|
||||
surface: id(wl_surface),
|
||||
}
|
||||
|
||||
# events
|
||||
|
||||
event client_id {
|
||||
|
|
|
|||
11
wire/jay_sync_file_release.txt
Normal file
11
wire/jay_sync_file_release.txt
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
request destroy {
|
||||
|
||||
}
|
||||
|
||||
event release_immediate {
|
||||
|
||||
}
|
||||
|
||||
event release_async {
|
||||
sync_file: fd,
|
||||
}
|
||||
15
wire/jay_sync_file_surface.txt
Normal file
15
wire/jay_sync_file_surface.txt
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
request destroy {
|
||||
|
||||
}
|
||||
|
||||
request set_acquire_immediate {
|
||||
|
||||
}
|
||||
|
||||
request set_acquire_async {
|
||||
sync_file: fd,
|
||||
}
|
||||
|
||||
request get_release {
|
||||
release: id(jay_sync_file_release) (new),
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue