diff --git a/src/backend/allocator/swapchain.rs b/src/backend/allocator/swapchain.rs index 7fcc779..95081ec 100644 --- a/src/backend/allocator/swapchain.rs +++ b/src/backend/allocator/swapchain.rs @@ -1,55 +1,72 @@ use std::convert::TryInto; -use std::sync::{Arc, atomic::{AtomicBool, Ordering}}; +use std::sync::{Arc, Mutex, MutexGuard, atomic::{AtomicBool, Ordering}}; use std::ops::Deref; use crate::backend::allocator::{Allocator, Buffer, Format}; pub const SLOT_CAP: usize = 4; -pub struct Swapchain, B: Buffer + TryInto, D: Buffer = B> { - allocator: A, +pub struct Swapchain, B: Buffer + TryInto, U: 'static, D: Buffer = B> { + pub allocator: A, _original_buffer_format: std::marker::PhantomData, width: u32, height: u32, format: Format, - slots: [Slot; SLOT_CAP], + slots: [Slot; SLOT_CAP], } -pub struct Slot { +pub struct Slot { buffer: Arc>, acquired: Arc, + userdata: Arc>>, } -impl Default for Slot { +impl Slot { + pub fn set_userdata(&self, data: U) -> Option { + self.userdata.lock().unwrap().replace(data) + } + + pub fn userdata(&self) -> MutexGuard<'_, Option> { + self.userdata.lock().unwrap() + } + + pub fn clear_userdata(&self) -> Option { + self.userdata.lock().unwrap().take() + } +} + +impl Default for Slot { fn default() -> Self { Slot { buffer: Arc::new(None), acquired: Arc::new(AtomicBool::new(false)), + userdata: Arc::new(Mutex::new(None)), } } } -impl Clone for Slot { +impl Clone for Slot { fn clone(&self) -> Self { Slot { buffer: self.buffer.clone(), acquired: self.acquired.clone(), + userdata: self.userdata.clone(), } } } -impl Deref for Slot { +impl Deref for Slot { type Target = B; fn deref(&self) -> &B { Option::as_ref(&*self.buffer).unwrap() } } -impl Drop for Slot { +impl Drop for Slot { fn drop(&mut self) { - self.acquired.store(false, Ordering::AcqRel); + self.acquired.store(false, Ordering::SeqCst); } } @@ -65,15 +82,16 @@ where ConversionError(#[source] E2), } -impl Swapchain +impl Swapchain where A: Allocator, B: Buffer + TryInto, D: Buffer, E1: std::error::Error + 'static, E2: std::error::Error + 'static, + U: 'static { - pub fn new(allocator: A, width: u32, height: u32, format: Format) -> Swapchain { + pub fn new(allocator: A, width: u32, height: u32, format: Format) -> Swapchain { Swapchain { allocator, _original_buffer_format: std::marker::PhantomData, @@ -84,7 +102,7 @@ where } } - pub fn acquire(&mut self) -> Result>, SwapchainError> { + pub fn acquire(&mut self) -> Result>, SwapchainError> { if let Some(free_slot) = self.slots.iter_mut().filter(|s| !s.acquired.load(Ordering::SeqCst)).next() { if free_slot.buffer.is_none() { free_slot.buffer = Arc::new(Some( @@ -93,9 +111,9 @@ where .try_into().map_err(SwapchainError::ConversionError)? )); } - assert!(!free_slot.buffer.is_some()); + assert!(free_slot.buffer.is_some()); - if !free_slot.acquired.swap(true, Ordering::AcqRel) { + if !free_slot.acquired.swap(true, Ordering::SeqCst) { return Ok(Some(free_slot.clone())); }