drm: allow commit/page_flip calls to *not* trigger an event

This commit is contained in:
Victor Brekenfeld 2021-04-25 23:36:15 +02:00
parent c8b370a030
commit 93edc842b2
3 changed files with 52 additions and 37 deletions

View File

@ -350,7 +350,7 @@ impl<A: AsRawFd + 'static> AtomicDrmSurface<A> {
*self.pending.read().unwrap() != *self.state.read().unwrap()
}
pub fn commit(&self, framebuffer: framebuffer::Handle) -> Result<(), Error> {
pub fn commit(&self, framebuffer: framebuffer::Handle, event: bool) -> Result<(), Error> {
if !self.active.load(Ordering::SeqCst) {
return Err(Error::DeviceInactive);
}
@ -430,6 +430,7 @@ impl<A: AsRawFd + 'static> AtomicDrmSurface<A> {
debug!(self.logger, "Setting screen: {:?}", req);
let result = self.fd
.atomic_commit(
if event {
&[
// on the atomic api we can modeset and trigger a page_flip event on the same call!
AtomicCommitFlags::PageFlipEvent,
@ -437,7 +438,13 @@ impl<A: AsRawFd + 'static> AtomicDrmSurface<A> {
// we also do not need to wait for completion, like with `set_crtc`.
// and have tested this already, so we do not expect any errors later down the line.
AtomicCommitFlags::Nonblock,
],
]
} else {
&[
AtomicCommitFlags::AllowModeset,
AtomicCommitFlags::Nonblock,
]
},
req,
)
.map_err(|source| Error::Access {
@ -453,7 +460,7 @@ impl<A: AsRawFd + 'static> AtomicDrmSurface<A> {
result
}
pub fn page_flip(&self, framebuffer: framebuffer::Handle) -> Result<(), Error> {
pub fn page_flip(&self, framebuffer: framebuffer::Handle, event: bool) -> Result<(), Error> {
if !self.active.load(Ordering::SeqCst) {
return Err(Error::DeviceInactive);
}
@ -473,7 +480,11 @@ impl<A: AsRawFd + 'static> AtomicDrmSurface<A> {
// indicating a problem in our assumptions.
trace!(self.logger, "Queueing page flip: {:?}", req);
self.fd.atomic_commit(
&[AtomicCommitFlags::PageFlipEvent, AtomicCommitFlags::Nonblock],
if event {
&[AtomicCommitFlags::PageFlipEvent, AtomicCommitFlags::Nonblock]
} else {
&[AtomicCommitFlags::Nonblock]
},
req,
)
.map_err(|source| Error::Access {

View File

@ -202,7 +202,7 @@ impl<A: AsRawFd + 'static> LegacyDrmSurface<A> {
*self.pending.read().unwrap() != *self.state.read().unwrap()
}
pub fn commit(&self, framebuffer: framebuffer::Handle) -> Result<(), Error> {
pub fn commit(&self, framebuffer: framebuffer::Handle, event: bool) -> Result<(), Error> {
if !self.active.load(Ordering::SeqCst) {
return Err(Error::DeviceInactive);
}
@ -272,6 +272,7 @@ impl<A: AsRawFd + 'static> LegacyDrmSurface<A> {
*current = pending.clone();
if event {
// set crtc does not trigger page_flip events, so we immediately queue a flip
// with the same framebuffer.
// this will result in wasting a frame, because this flip will need to wait
@ -288,10 +289,13 @@ impl<A: AsRawFd + 'static> LegacyDrmSurface<A> {
errmsg: "Failed to queue page flip",
dev: self.fd.dev_path(),
source,
})
})?;
}
pub fn page_flip(&self, framebuffer: framebuffer::Handle) -> Result<(), Error> {
Ok(())
}
pub fn page_flip(&self, framebuffer: framebuffer::Handle, event: bool) -> Result<(), Error> {
trace!(self.logger, "Queueing Page flip");
if !self.active.load(Ordering::SeqCst) {
@ -302,7 +306,7 @@ impl<A: AsRawFd + 'static> LegacyDrmSurface<A> {
&*self.fd,
self.crtc,
framebuffer,
&[PageFlipFlags::PageFlipEvent],
if event { &[PageFlipFlags::PageFlipEvent] } else { &[] },
None,
)
.map_err(|source| Error::Access {

View File

@ -159,10 +159,10 @@ impl<A: AsRawFd + 'static> DrmSurface<A> {
/// but will trigger a `vblank` event once done.
/// Make sure to [set a `DeviceHandler`](Device::set_handler) and
/// [register the belonging `Device`](device_bind) before to receive the event in time.
pub fn commit(&self, framebuffer: framebuffer::Handle) -> Result<(), Error> {
pub fn commit(&self, framebuffer: framebuffer::Handle, event: bool) -> Result<(), Error> {
match &*self.internal {
DrmSurfaceInternal::Atomic(surf) => surf.commit(framebuffer),
DrmSurfaceInternal::Legacy(surf) => surf.commit(framebuffer),
DrmSurfaceInternal::Atomic(surf) => surf.commit(framebuffer, event),
DrmSurfaceInternal::Legacy(surf) => surf.commit(framebuffer, event),
}
}
@ -174,10 +174,10 @@ impl<A: AsRawFd + 'static> DrmSurface<A> {
/// This operation is not blocking and will produce a `vblank` event once swapping is done.
/// Make sure to [set a `DeviceHandler`](Device::set_handler) and
/// [register the belonging `Device`](device_bind) before to receive the event in time.
pub fn page_flip(&self, framebuffer: framebuffer::Handle) -> Result<(), Error> {
pub fn page_flip(&self, framebuffer: framebuffer::Handle, event: bool) -> Result<(), Error> {
match &*self.internal {
DrmSurfaceInternal::Atomic(surf) => surf.page_flip(framebuffer),
DrmSurfaceInternal::Legacy(surf) => surf.page_flip(framebuffer)
DrmSurfaceInternal::Atomic(surf) => surf.page_flip(framebuffer, event),
DrmSurfaceInternal::Legacy(surf) => surf.page_flip(framebuffer, event),
}
}