Skip to content

Commit e69775a

Browse files
committed
WIP OUT_FENCE_FD; always signalled in fence
1 parent 8c5c02f commit e69775a

File tree

4 files changed

+69
-17
lines changed

4 files changed

+69
-17
lines changed

src/backend/drm/compositor/mod.rs

+34-8
Original file line numberDiff line numberDiff line change
@@ -124,14 +124,14 @@ use std::{
124124
collections::{HashMap, HashSet},
125125
fmt::Debug,
126126
io::ErrorKind,
127-
os::unix::io::{AsFd, OwnedFd},
127+
os::unix::io::{AsFd, BorrowedFd, OwnedFd},
128128
rc::Rc,
129129
sync::{Arc, Mutex},
130130
};
131131

132132
use ::gbm::{BufferObject, BufferObjectFlags};
133133
use drm::{
134-
control::{connector, crtc, framebuffer, plane, Mode, PlaneType},
134+
control::{connector, crtc, Device as _, framebuffer, plane, Mode, PlaneType},
135135
Device, DriverCapability,
136136
};
137137
use drm_fourcc::{DrmFormat, DrmFourcc, DrmModifier};
@@ -634,7 +634,7 @@ impl<B: Framebuffer> FrameState<B> {
634634
let backup = current_config.clone();
635635
*current_config = state;
636636

637-
let res = surface.test_state(self.build_planes(surface, supports_fencing, true), allow_modeset);
637+
let res = surface.test_state(self.build_planes(surface, supports_fencing, true, None), allow_modeset);
638638

639639
if res.is_err() {
640640
// test failed, restore previous state
@@ -674,7 +674,7 @@ impl<B: Framebuffer> FrameState<B> {
674674
}
675675

676676
let res = surface.test_state(
677-
self.build_planes(surface, supports_fencing, allow_partial_update),
677+
self.build_planes(surface, supports_fencing, allow_partial_update, None),
678678
allow_modeset,
679679
);
680680

@@ -694,11 +694,14 @@ impl<B: Framebuffer> FrameState<B> {
694694
supports_fencing: bool,
695695
allow_partial_update: bool,
696696
event: bool,
697+
out_fence_fd: &mut Option<OwnedFd>,
698+
signalled_sync_file: Option<BorrowedFd<'_>>, // XXX
697699
) -> Result<(), crate::backend::drm::error::Error> {
698700
debug_assert!(!self.planes.iter().any(|(_, state)| state.needs_test));
699701
surface.commit(
700-
self.build_planes(surface, supports_fencing, allow_partial_update),
702+
self.build_planes(surface, supports_fencing, allow_partial_update, signalled_sync_file),
701703
event,
704+
Some(out_fence_fd),
702705
)
703706
}
704707

@@ -709,11 +712,14 @@ impl<B: Framebuffer> FrameState<B> {
709712
supports_fencing: bool,
710713
allow_partial_update: bool,
711714
event: bool,
715+
out_fence_fd: &mut Option<OwnedFd>,
716+
signalled_sync_file: Option<BorrowedFd<'_>>, // XXX
712717
) -> Result<(), crate::backend::drm::error::Error> {
713718
debug_assert!(!self.planes.iter().any(|(_, state)| state.needs_test));
714719
surface.page_flip(
715-
self.build_planes(surface, supports_fencing, allow_partial_update),
720+
self.build_planes(surface, supports_fencing, allow_partial_update, signalled_sync_file),
716721
event,
722+
Some(out_fence_fd)
717723
)
718724
}
719725

@@ -723,6 +729,7 @@ impl<B: Framebuffer> FrameState<B> {
723729
surface: &'a DrmSurface,
724730
supports_fencing: bool,
725731
allow_partial_update: bool,
732+
signalled_sync_file: Option<BorrowedFd<'a>>, // XXX
726733
) -> impl IntoIterator<Item = super::PlaneState<'a>> {
727734
for (_, state) in self.planes.iter_mut().filter(|(_, state)| !state.skip) {
728735
if let Some(config) = state.config.as_mut() {
@@ -759,10 +766,14 @@ impl<B: Framebuffer> FrameState<B> {
759766
transform: config.properties.transform,
760767
damage_clips: config.damage_clips.as_ref().map(|d| d.blob()),
761768
fb: *config.buffer.as_ref(),
769+
// XXX
770+
fence: signalled_sync_file
771+
/*
762772
fence: config
763773
.sync
764774
.as_ref()
765775
.and_then(|(_, fence)| fence.as_ref().map(|fence| fence.as_fd())),
776+
*/
766777
}),
767778
})
768779
}
@@ -1514,6 +1525,8 @@ where
15141525

15151526
debug_flags: DebugFlags,
15161527
span: tracing::Span,
1528+
1529+
signalled_sync_file: Option<OwnedFd>,
15171530
}
15181531

15191532
impl<A, F, U, G> DrmCompositor<A, F, U, G>
@@ -1600,6 +1613,14 @@ where
16001613
})?
16011614
&& plane_has_property(&*surface, surface.plane(), "IN_FENCE_FD")?;
16021615

1616+
let mut signalled_sync_file = None;
1617+
if supports_fencing {
1618+
// XXX unwrap
1619+
let syncobj = surface.device_fd().create_syncobj(true).unwrap();
1620+
signalled_sync_file = Some(surface.device_fd().syncobj_to_fd(syncobj, true).unwrap());
1621+
surface.device_fd().destroy_syncobj(syncobj).unwrap();
1622+
}
1623+
16031624
for format in color_formats {
16041625
debug!("Testing color format: {}", format);
16051626
match Self::find_supported_format(
@@ -1663,6 +1684,7 @@ where
16631684
supports_fencing,
16641685
debug_flags: DebugFlags::empty(),
16651686
span,
1687+
signalled_sync_file,
16661688
};
16671689

16681690
return Ok(drm_renderer);
@@ -2558,16 +2580,20 @@ where
25582580
} = self.queued_frame.take().unwrap();
25592581

25602582
let allow_partial_update = prepared_frame.kind == PreparedFrameKind::Partial;
2583+
let mut out_fence_fd = None;
2584+
let signalled_sync_file = self.signalled_sync_file.as_ref().map(|x| x.as_fd());
25612585
let flip = if self.surface.commit_pending() {
25622586
prepared_frame
25632587
.frame
2564-
.commit(&self.surface, self.supports_fencing, allow_partial_update, true)
2588+
.commit(&self.surface, self.supports_fencing, allow_partial_update, true, &mut out_fence_fd, signalled_sync_file)
25652589
} else {
25662590
prepared_frame
25672591
.frame
2568-
.page_flip(&self.surface, self.supports_fencing, allow_partial_update, true)
2592+
.page_flip(&self.surface, self.supports_fencing, allow_partial_update, true, &mut out_fence_fd, signalled_sync_file)
25692593
};
25702594

2595+
dbg!(out_fence_fd);
2596+
25712597
match flip {
25722598
Ok(_) => {
25732599
if prepared_frame.kind == PreparedFrameKind::Full {

src/backend/drm/surface/atomic.rs

+28-4
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use drm::control::{
55
};
66

77
use std::collections::HashSet;
8-
use std::os::unix::io::AsRawFd;
8+
use std::os::unix::io::{AsRawFd, OwnedFd};
99
use std::sync::Mutex;
1010
use std::sync::{
1111
atomic::{AtomicBool, Ordering},
@@ -344,6 +344,7 @@ impl AtomicDrmSurface {
344344
}),
345345
}],
346346
Some(pending.blob),
347+
None,
347348
)?;
348349
self.fd
349350
.atomic_commit(
@@ -396,6 +397,7 @@ impl AtomicDrmSurface {
396397
}),
397398
}],
398399
Some(pending.blob),
400+
None,
399401
)?;
400402
self.fd
401403
.atomic_commit(
@@ -450,6 +452,7 @@ impl AtomicDrmSurface {
450452
}),
451453
}],
452454
Some(pending.blob),
455+
None,
453456
)?;
454457

455458
self.fd
@@ -502,6 +505,7 @@ impl AtomicDrmSurface {
502505
}),
503506
}],
504507
Some(new_blob),
508+
None,
505509
)?;
506510
if let Err(err) = self
507511
.fd
@@ -547,7 +551,7 @@ impl AtomicDrmSurface {
547551
let mut removed = current_conns.difference(&pending_conns);
548552
let mut added = pending_conns.difference(&current_conns);
549553

550-
let req = self.build_request(&mut added, &mut removed, &*planes, Some(pending.blob))?;
554+
let req = self.build_request(&mut added, &mut removed, &*planes, Some(pending.blob), None)?;
551555

552556
let flags = if allow_modeset {
553557
AtomicCommitFlags::ALLOW_MODESET | AtomicCommitFlags::TEST_ONLY
@@ -569,6 +573,7 @@ impl AtomicDrmSurface {
569573
&self,
570574
planes: impl IntoIterator<Item = PlaneState<'a>>,
571575
event: bool,
576+
out_fence_fd: Option<&mut Option<OwnedFd>>,
572577
) -> Result<(), Error> {
573578
if !self.active.load(Ordering::SeqCst) {
574579
return Err(Error::DeviceInactive);
@@ -611,7 +616,13 @@ impl AtomicDrmSurface {
611616

612617
// test the new config and return the request if it would be accepted by the driver.
613618
let req = {
614-
let req = self.build_request(&mut added, &mut removed, &*planes, Some(pending.blob))?;
619+
let req = self.build_request(
620+
&mut added,
621+
&mut removed,
622+
&*planes,
623+
Some(pending.blob),
624+
out_fence_fd,
625+
)?;
615626

616627
if let Err(err) = self.fd.atomic_commit(
617628
AtomicCommitFlags::ALLOW_MODESET | AtomicCommitFlags::TEST_ONLY,
@@ -680,6 +691,7 @@ impl AtomicDrmSurface {
680691
&self,
681692
planes: impl IntoIterator<Item = PlaneState<'a>>,
682693
event: bool,
694+
out_fence_fd: Option<&mut Option<OwnedFd>>,
683695
) -> Result<(), Error> {
684696
if !self.active.load(Ordering::SeqCst) {
685697
return Err(Error::DeviceInactive);
@@ -689,7 +701,7 @@ impl AtomicDrmSurface {
689701
let planes = planes.into_iter().collect::<Vec<_>>();
690702

691703
// page flips work just like commits with fewer parameters..
692-
let req = self.build_request(&mut [].iter(), &mut [].iter(), &*planes, None)?;
704+
let req = self.build_request(&mut [].iter(), &mut [].iter(), &*planes, None, out_fence_fd)?;
693705

694706
// .. and without `AtomicCommitFlags::AllowModeset`.
695707
// If we would set anything here, that would require a modeset, this would fail,
@@ -735,6 +747,7 @@ impl AtomicDrmSurface {
735747
removed_connectors: &mut dyn Iterator<Item = &connector::Handle>,
736748
planes: impl IntoIterator<Item = &'a PlaneState<'a>>,
737749
blob: Option<property::Value<'static>>,
750+
out_fence_fd: Option<&mut Option<OwnedFd>>,
738751
) -> Result<AtomicModeReq, Error> {
739752
let prop_mapping = self.prop_mapping.read().unwrap();
740753

@@ -781,6 +794,17 @@ impl AtomicDrmSurface {
781794
property::Value::Boolean(true),
782795
);
783796

797+
if let Some(out_fence_fd) = out_fence_fd {
798+
if let Ok(prop) = crtc_prop_handle(&prop_mapping, self.crtc, "OUT_FENCE_PTR") {
799+
// TODO Strict pointer provenance?
800+
req.add_property(
801+
self.crtc,
802+
prop,
803+
property::Value::UnsignedRange(out_fence_fd as *mut _ as _),
804+
);
805+
}
806+
}
807+
784808
for plane_state in planes.into_iter() {
785809
let handle = &plane_state.handle;
786810

src/backend/drm/surface/gbm.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -399,9 +399,9 @@ where
399399
};
400400

401401
let flip = if self.drm.commit_pending() {
402-
self.drm.commit([plane_state], true)
402+
self.drm.commit([plane_state], true, None)
403403
} else {
404-
self.drm.page_flip([plane_state], true)
404+
self.drm.page_flip([plane_state], true, None)
405405
};
406406
if flip.is_ok() {
407407
self.pending_fb = Some((slot, user_data));

src/backend/drm/surface/mod.rs

+5-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use std::io;
2-
use std::os::unix::io::{AsFd, BorrowedFd};
2+
use std::os::unix::io::{AsFd, BorrowedFd, OwnedFd};
33
use std::sync::atomic::Ordering;
44
use std::sync::Arc;
55

@@ -352,9 +352,10 @@ impl DrmSurface {
352352
&self,
353353
planes: impl IntoIterator<Item = PlaneState<'a>>,
354354
event: bool,
355+
out_fence_fd: Option<&mut Option<OwnedFd>>,
355356
) -> Result<(), Error> {
356357
match &*self.internal {
357-
DrmSurfaceInternal::Atomic(surf) => surf.commit(planes, event),
358+
DrmSurfaceInternal::Atomic(surf) => surf.commit(planes, event, out_fence_fd),
358359
DrmSurfaceInternal::Legacy(surf) => {
359360
let fb = ensure_legacy_planes(self, planes)?;
360361
surf.commit(fb, event)
@@ -374,9 +375,10 @@ impl DrmSurface {
374375
&self,
375376
planes: impl IntoIterator<Item = PlaneState<'a>>,
376377
event: bool,
378+
out_fence_fd: Option<&mut Option<OwnedFd>>,
377379
) -> Result<(), Error> {
378380
match &*self.internal {
379-
DrmSurfaceInternal::Atomic(surf) => surf.page_flip(planes, event),
381+
DrmSurfaceInternal::Atomic(surf) => surf.page_flip(planes, event, out_fence_fd),
380382
DrmSurfaceInternal::Legacy(surf) => {
381383
let fb = ensure_legacy_planes(self, planes)?;
382384
surf.page_flip(fb, event)

0 commit comments

Comments
 (0)