swapchain: Support buffer age

This commit is contained in:
Victor Brekenfeld 2021-11-23 17:23:39 +01:00
parent 643ff5395d
commit 6c57e27e5e
1 changed files with 34 additions and 1 deletions

View File

@ -1,6 +1,6 @@
use std::ops::Deref;
use std::sync::{
atomic::{AtomicBool, Ordering},
atomic::{AtomicBool, AtomicU8, Ordering},
Arc,
};
@ -60,6 +60,7 @@ pub struct Slot<B: Buffer>(Arc<InternalSlot<B>>);
struct InternalSlot<B: Buffer> {
buffer: Option<B>,
acquired: AtomicBool,
age: AtomicU8,
userdata: UserDataMap,
}
@ -68,6 +69,11 @@ impl<B: Buffer> Slot<B> {
pub fn userdata(&self) -> &UserDataMap {
&self.0.userdata
}
/// Retrieve the age of the buffer
pub fn age(&self) -> u8 {
self.0.age.load(Ordering::SeqCst)
}
}
impl<B: Buffer> Default for InternalSlot<B> {
@ -75,6 +81,7 @@ impl<B: Buffer> Default for InternalSlot<B> {
InternalSlot {
buffer: None,
acquired: AtomicBool::new(false),
age: AtomicU8::new(0),
userdata: UserDataMap::new(),
}
}
@ -144,6 +151,27 @@ where
Ok(None)
}
/// Mark a given buffer as submitted.
///
/// This might effect internal data (e.g. buffer age) and may only be called,
/// if the buffer was actually used for display.
/// Buffers can always just be safely discarded by dropping them, but not
/// calling this function may affect performance characteristics
/// (e.g. by not tracking the buffer age).
pub fn submitted(&self, slot: Slot<B>) {
// don't mess up the state, if the user submitted and old buffer, after e.g. a resize
if !self.slots.iter().any(|other| Arc::ptr_eq(&slot.0, other)) {
return;
}
slot.0.age.store(1, Ordering::SeqCst);
for other_slot in &self.slots {
if !Arc::ptr_eq(other_slot, &slot.0) {
other_slot.age.fetch_add(1, Ordering::SeqCst);
}
}
}
/// Change the dimensions of newly returned buffers.
///
/// Already obtained buffers are unaffected and will be cleaned up on drop.
@ -156,4 +184,9 @@ where
self.height = height;
self.slots = Default::default();
}
/// Remove all internally cached buffers to e.g. reset age values
pub fn reset_buffers(&mut self) {
self.slots = Default::default();
}
}