drm: fixup test_buffer
This commit is contained in:
parent
93edc842b2
commit
cb825910a6
|
@ -56,7 +56,7 @@ impl<A: AsRawFd + 'static> AtomicDrmSurface<A> {
|
||||||
source,
|
source,
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
// If we have no current mode, we create a fake one, which will not match (and thus gets overriden on the commit below).
|
// If we have no current mode, we create a fake one, which will not match (and thus gets overridden on the commit below).
|
||||||
// A better fix would probably be making mode an `Option`, but that would mean
|
// A better fix would probably be making mode an `Option`, but that would mean
|
||||||
// we need to be sure, we require a mode to always be set without relying on the compiler.
|
// we need to be sure, we require a mode to always be set without relying on the compiler.
|
||||||
// So we cheat, because it works and is easier to handle later.
|
// So we cheat, because it works and is easier to handle later.
|
||||||
|
@ -509,9 +509,17 @@ impl<A: AsRawFd + 'static> AtomicDrmSurface<A> {
|
||||||
source,
|
source,
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
|
let current = self.state.read().unwrap();
|
||||||
|
let pending = self.pending.read().unwrap();
|
||||||
|
|
||||||
|
let current_conns = current.connectors.clone();
|
||||||
|
let pending_conns = pending.connectors.clone();
|
||||||
|
let mut removed = current_conns.difference(&pending_conns);
|
||||||
|
let mut added = pending_conns.difference(¤t_conns);
|
||||||
|
|
||||||
let req = self.build_request(
|
let req = self.build_request(
|
||||||
&mut [].iter(),
|
&mut added,
|
||||||
&mut [].iter(),
|
&mut removed,
|
||||||
self.plane,
|
self.plane,
|
||||||
Some(fb),
|
Some(fb),
|
||||||
Some(*mode),
|
Some(*mode),
|
||||||
|
@ -519,11 +527,6 @@ impl<A: AsRawFd + 'static> AtomicDrmSurface<A> {
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
let result = self.fd.atomic_commit(&[AtomicCommitFlags::AllowModeset, AtomicCommitFlags::TestOnly], req).is_ok();
|
let result = self.fd.atomic_commit(&[AtomicCommitFlags::AllowModeset, AtomicCommitFlags::TestOnly], req).is_ok();
|
||||||
|
|
||||||
if let Err(err) = self.fd.destroy_framebuffer(fb) {
|
|
||||||
debug!(self.logger, "Failed to destroy framebuffer({:?}): {}", fb, err);
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(result)
|
Ok(result)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -321,12 +321,18 @@ impl<A: AsRawFd + 'static> LegacyDrmSurface<A> {
|
||||||
return Err(Error::DeviceInactive);
|
return Err(Error::DeviceInactive);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let pending = self.pending.read().unwrap();
|
||||||
|
|
||||||
debug!(self.logger, "Setting screen for buffer *testing*");
|
debug!(self.logger, "Setting screen for buffer *testing*");
|
||||||
Ok(self.fd.set_crtc(
|
Ok(self.fd.set_crtc(
|
||||||
self.crtc,
|
self.crtc,
|
||||||
Some(fb),
|
Some(fb),
|
||||||
(0, 0),
|
(0, 0),
|
||||||
&[],
|
&pending
|
||||||
|
.connectors
|
||||||
|
.iter()
|
||||||
|
.copied()
|
||||||
|
.collect::<Vec<connector::Handle>>(),
|
||||||
Some(*mode),
|
Some(*mode),
|
||||||
).is_ok())
|
).is_ok())
|
||||||
}
|
}
|
||||||
|
|
|
@ -185,64 +185,12 @@ impl<A: AsRawFd + 'static> DrmSurface<A> {
|
||||||
&self.formats
|
&self.formats
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn test_buffer<B>(&self, buffer: &B, bpp: u32, modifier: Option<[Modifier; 4]>, mode: &Mode, allow_screen_change: bool) -> Result<Option<framebuffer::Handle>, Error>
|
pub fn test_buffer(&self, fb: framebuffer::Handle, mode: &Mode, allow_screen_change: bool) -> Result<bool, Error> {
|
||||||
where
|
match &*self.internal {
|
||||||
B: drm::buffer::Buffer + drm::buffer::PlanarBuffer
|
|
||||||
{
|
|
||||||
use std::sync::atomic::Ordering;
|
|
||||||
|
|
||||||
let (active, logger) = match &*self.internal {
|
|
||||||
DrmSurfaceInternal::Atomic(surf) => (surf.active.load(Ordering::SeqCst), surf.logger.clone()),
|
|
||||||
DrmSurfaceInternal::Legacy(surf) => (surf.active.load(Ordering::SeqCst), surf.logger.clone()),
|
|
||||||
};
|
|
||||||
|
|
||||||
if !active {
|
|
||||||
return Err(Error::DeviceInactive);
|
|
||||||
}
|
|
||||||
|
|
||||||
let fb = match
|
|
||||||
if let Some(mods) = modifier {
|
|
||||||
self.add_planar_framebuffer(buffer, unsafe {
|
|
||||||
std::mem::transmute::<&[Modifier; 4], &[Option<Modifier>; 4]>(&mods)
|
|
||||||
}, drm_ffi::DRM_MODE_FB_MODIFIERS)
|
|
||||||
} else {
|
|
||||||
self.add_planar_framebuffer(buffer, &[None, None, None, None], 0)
|
|
||||||
}
|
|
||||||
{
|
|
||||||
Ok(fb) => fb,
|
|
||||||
Err(_) => {
|
|
||||||
// We only support this as a fallback of last resort for ARGB8888 visuals,
|
|
||||||
// like xf86-video-modesetting does.
|
|
||||||
if drm::buffer::Buffer::format(buffer) != Fourcc::Argb8888
|
|
||||||
|| buffer.handles()[1].is_some() {
|
|
||||||
return Ok(false);
|
|
||||||
}
|
|
||||||
debug!(logger, "Failed to add framebuffer, trying legacy method");
|
|
||||||
self.add_framebuffer(buffer, bpp, 32).map_err(|source| Error::Access {
|
|
||||||
errmsg: "Failed to add framebuffer",
|
|
||||||
dev: self.dev_path(),
|
|
||||||
source,
|
|
||||||
})?
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
let result = match &*self.internal {
|
|
||||||
DrmSurfaceInternal::Atomic(surf) => surf.test_buffer(fb, mode),
|
DrmSurfaceInternal::Atomic(surf) => surf.test_buffer(fb, mode),
|
||||||
DrmSurfaceInternal::Legacy(surf) => if allow_screen_change {
|
DrmSurfaceInternal::Legacy(surf) => if allow_screen_change {
|
||||||
surf.test_buffer(fb, mode)
|
surf.test_buffer(fb, mode)
|
||||||
} else { Ok(false) } // There is no test-commiting with the legacy interface
|
} else { Ok(false) } // There is no test-commiting with the legacy interface
|
||||||
};
|
|
||||||
|
|
||||||
if !result.unwrap_or(false) {
|
|
||||||
if let Err(err) = self.destroy_framebuffer(fb) {
|
|
||||||
debug!(logger, "Failed to destroy framebuffer({:?}): {}", fb, err);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
result.map(|x| if x {
|
|
||||||
Some(fb)
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
Reference in New Issue