diff --git a/src/backend/allocator/swapchain.rs b/src/backend/allocator/swapchain.rs index 8c1a50e..13d8ad3 100644 --- a/src/backend/allocator/swapchain.rs +++ b/src/backend/allocator/swapchain.rs @@ -1,3 +1,4 @@ +use std::convert::TryInto; use std::sync::{Arc, atomic::{AtomicBool, Ordering}}; use std::ops::Deref; @@ -5,14 +6,15 @@ use crate::backend::allocator::{Allocator, Buffer, Format}; pub const SLOT_CAP: usize = 3; -pub struct Swapchain, B: Buffer> { +pub struct Swapchain, B: Buffer + TryInto, D: Buffer = B> { 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 { @@ -51,10 +53,30 @@ impl Drop for Slot { } } -impl, B: Buffer> Swapchain { - pub fn new(allocator: A, width: u32, height: u32, format: Format) -> Swapchain { +#[derive(Debug, thiserror::Error)] +pub enum SwapchainError +where + E1: std::error::Error + 'static, + E2: std::error::Error + 'static, +{ + #[error("Failed to allocate a new buffer: {0}")] + AllocationError(#[source] E1), + #[error("Failed to convert a new buffer: {0}")] + ConversionError(#[source] E2), +} + +impl Swapchain +where + A: Allocator, + B: Buffer + TryInto, + D: Buffer, + E1: std::error::Error + 'static, + E2: std::error::Error + 'static, +{ + pub fn new(allocator: A, width: u32, height: u32, format: Format) -> Swapchain { Swapchain { allocator, + _original_buffer_format: std::marker::PhantomData, width, height, format, @@ -62,10 +84,14 @@ impl, B: Buffer> Swapchain { } } - pub fn acquire(&mut self) -> Result>, A::Error> { + 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(self.allocator.create_buffer(self.width, self.height, self.format)?)); + free_slot.buffer = Arc::new(Some( + self.allocator + .create_buffer(self.width, self.height, self.format).map_err(SwapchainError::AllocationError)? + .try_into().map_err(SwapchainError::ConversionError)? + )); } assert!(!free_slot.buffer.is_some());