drm: allow commit/page_flip calls to *not* trigger an event
This commit is contained in:
parent
c8b370a030
commit
93edc842b2
|
@ -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,14 +430,21 @@ impl<A: AsRawFd + 'static> AtomicDrmSurface<A> {
|
|||
debug!(self.logger, "Setting screen: {:?}", req);
|
||||
let result = self.fd
|
||||
.atomic_commit(
|
||||
&[
|
||||
// on the atomic api we can modeset and trigger a page_flip event on the same call!
|
||||
AtomicCommitFlags::PageFlipEvent,
|
||||
AtomicCommitFlags::AllowModeset,
|
||||
// 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,
|
||||
],
|
||||
if event {
|
||||
&[
|
||||
// on the atomic api we can modeset and trigger a page_flip event on the same call!
|
||||
AtomicCommitFlags::PageFlipEvent,
|
||||
AtomicCommitFlags::AllowModeset,
|
||||
// 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 {
|
||||
|
|
|
@ -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,26 +272,30 @@ impl<A: AsRawFd + 'static> LegacyDrmSurface<A> {
|
|||
|
||||
*current = pending.clone();
|
||||
|
||||
// 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
|
||||
// for `set_crtc`, but is necessary to drive the event loop and thus provide
|
||||
// a more consistent api.
|
||||
ControlDevice::page_flip(
|
||||
&*self.fd,
|
||||
self.crtc,
|
||||
framebuffer,
|
||||
&[PageFlipFlags::PageFlipEvent],
|
||||
None,
|
||||
)
|
||||
.map_err(|source| Error::Access {
|
||||
errmsg: "Failed to queue page flip",
|
||||
dev: self.fd.dev_path(),
|
||||
source,
|
||||
})
|
||||
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
|
||||
// for `set_crtc`, but is necessary to drive the event loop and thus provide
|
||||
// a more consistent api.
|
||||
ControlDevice::page_flip(
|
||||
&*self.fd,
|
||||
self.crtc,
|
||||
framebuffer,
|
||||
&[PageFlipFlags::PageFlipEvent],
|
||||
None,
|
||||
)
|
||||
.map_err(|source| Error::Access {
|
||||
errmsg: "Failed to queue page flip",
|
||||
dev: self.fd.dev_path(),
|
||||
source,
|
||||
})?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn page_flip(&self, framebuffer: framebuffer::Handle) -> Result<(), Error> {
|
||||
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 {
|
||||
|
|
|
@ -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),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue