Merge pull request #425 from Smithay/fixup/buffer_age

Fixup for #419 and #421
This commit is contained in:
Victoria Brekenfeld 2021-11-29 18:27:27 +01:00 committed by GitHub
commit f3ae4581c7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 34 additions and 21 deletions

View File

@ -306,7 +306,9 @@ pub fn run_x11(log: Logger) {
} }
// Submit the buffer // Submit the buffer
backend_data.surface.submit(); if let Err(err) = backend_data.surface.submit() {
error!(log, "Error submitting buffer for display: {}", err);
}
} }
Err(err) => { Err(err) => {

View File

@ -166,8 +166,17 @@ where
slot.0.age.store(1, Ordering::SeqCst); slot.0.age.store(1, Ordering::SeqCst);
for other_slot in &self.slots { for other_slot in &self.slots {
if !Arc::ptr_eq(other_slot, &slot.0) { if !Arc::ptr_eq(other_slot, &slot.0) && other_slot.buffer.is_some() {
other_slot.age.fetch_add(1, Ordering::SeqCst); assert!(other_slot
.age
.fetch_update(Ordering::SeqCst, Ordering::SeqCst, |age| {
if age > 0 {
Some(age + 1)
} else {
Some(0)
}
})
.is_ok());
} }
} }
} }

View File

@ -349,8 +349,7 @@ pub struct X11Surface {
format: DrmFourcc, format: DrmFourcc,
width: u16, width: u16,
height: u16, height: u16,
current: Option<Slot<BufferObject<()>>>, buffer: Option<Slot<BufferObject<()>>>,
next: Option<Slot<BufferObject<()>>>,
} }
#[derive(Debug, thiserror::Error)] #[derive(Debug, thiserror::Error)]
@ -467,8 +466,7 @@ impl X11Surface {
format, format,
width: size.w, width: size.w,
height: size.h, height: size.h,
current: None, buffer: None,
next: None,
resize: recv, resize: recv,
}) })
} }
@ -493,8 +491,8 @@ impl X11Surface {
self.resize(new_size)?; self.resize(new_size)?;
} }
if self.next.is_none() { if self.buffer.is_none() {
self.next = Some( self.buffer = Some(
self.swapchain self.swapchain
.acquire() .acquire()
.map_err(Into::<AllocateBuffersError>::into)? .map_err(Into::<AllocateBuffersError>::into)?
@ -502,7 +500,7 @@ impl X11Surface {
); );
} }
let slot = self.next.as_ref().unwrap(); let slot = self.buffer.as_ref().unwrap();
let age = slot.age(); let age = slot.age();
match slot.userdata().get::<Dmabuf>() { match slot.userdata().get::<Dmabuf>() {
Some(dmabuf) => Ok((dmabuf.clone(), age)), Some(dmabuf) => Ok((dmabuf.clone(), age)),
@ -515,41 +513,45 @@ impl X11Surface {
} }
/// Consume and submit the buffer to the window. /// Consume and submit the buffer to the window.
pub fn submit(&mut self) { pub fn submit(&mut self) -> Result<(), AllocateBuffersError> {
if let Some(connection) = self.connection.upgrade() { if let Some(connection) = self.connection.upgrade() {
// Get a new buffer
let mut next = self
.swapchain
.acquire()
.map_err(Into::<AllocateBuffersError>::into)?
.ok_or(AllocateBuffersError::NoFreeSlots)?;
// Swap the buffers // Swap the buffers
if let Some(mut next) = self.next.take() { if let Some(current) = self.buffer.as_mut() {
if let Some(current) = self.current.as_mut() {
mem::swap(&mut next, current); mem::swap(&mut next, current);
self.swapchain.submitted(next);
} else {
self.current = Some(next);
}
} }
if let Ok(pixmap) = PixmapWrapper::with_dmabuf( if let Ok(pixmap) = PixmapWrapper::with_dmabuf(
&*connection, &*connection,
&self.window, &self.window,
self.current.as_ref().unwrap().userdata().get::<Dmabuf>().unwrap(), next.userdata().get::<Dmabuf>().unwrap(),
) { ) {
// Now present the current buffer // Now present the current buffer
let _ = pixmap.present(&*connection, &self.window); let _ = pixmap.present(&*connection, &self.window);
} }
self.swapchain.submitted(next);
// Flush the connection after presenting to the window to ensure we don't run out of buffer space in the X11 connection. // Flush the connection after presenting to the window to ensure we don't run out of buffer space in the X11 connection.
let _ = connection.flush(); let _ = connection.flush();
} }
Ok(())
} }
/// Resets the internal buffers, e.g. to reset age values /// Resets the internal buffers, e.g. to reset age values
pub fn reset_buffers(&mut self) { pub fn reset_buffers(&mut self) {
self.swapchain.reset_buffers(); self.swapchain.reset_buffers();
self.next = None; self.buffer = None;
} }
fn resize(&mut self, size: Size<u16, Logical>) -> Result<(), AllocateBuffersError> { fn resize(&mut self, size: Size<u16, Logical>) -> Result<(), AllocateBuffersError> {
self.swapchain.resize(size.w as u32, size.h as u32); self.swapchain.resize(size.w as u32, size.h as u32);
self.next = None; self.buffer = None;
self.width = size.w; self.width = size.w;
self.height = size.h; self.height = size.h;