swapchain: handle buffer conversion for the user
This commit is contained in:
parent
84439e5400
commit
a74aa728f7
|
@ -1,3 +1,4 @@
|
||||||
|
use std::convert::TryInto;
|
||||||
use std::sync::{Arc, atomic::{AtomicBool, Ordering}};
|
use std::sync::{Arc, atomic::{AtomicBool, Ordering}};
|
||||||
use std::ops::Deref;
|
use std::ops::Deref;
|
||||||
|
|
||||||
|
@ -5,14 +6,15 @@ use crate::backend::allocator::{Allocator, Buffer, Format};
|
||||||
|
|
||||||
pub const SLOT_CAP: usize = 3;
|
pub const SLOT_CAP: usize = 3;
|
||||||
|
|
||||||
pub struct Swapchain<A: Allocator<B>, B: Buffer> {
|
pub struct Swapchain<A: Allocator<B>, B: Buffer + TryInto<B>, D: Buffer = B> {
|
||||||
allocator: A,
|
allocator: A,
|
||||||
|
_original_buffer_format: std::marker::PhantomData<B>,
|
||||||
|
|
||||||
width: u32,
|
width: u32,
|
||||||
height: u32,
|
height: u32,
|
||||||
format: Format,
|
format: Format,
|
||||||
|
|
||||||
slots: [Slot<B>; SLOT_CAP],
|
slots: [Slot<D>; SLOT_CAP],
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Slot<B: Buffer> {
|
pub struct Slot<B: Buffer> {
|
||||||
|
@ -51,10 +53,30 @@ impl<B: Buffer> Drop for Slot<B> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<A: Allocator<B>, B: Buffer> Swapchain<A, B> {
|
#[derive(Debug, thiserror::Error)]
|
||||||
pub fn new(allocator: A, width: u32, height: u32, format: Format) -> Swapchain<A, B> {
|
pub enum SwapchainError<E1, E2>
|
||||||
|
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<A, B, D, E1, E2> Swapchain<A, B, D>
|
||||||
|
where
|
||||||
|
A: Allocator<B, Error=E1>,
|
||||||
|
B: Buffer + TryInto<D, Error=E2>,
|
||||||
|
D: Buffer,
|
||||||
|
E1: std::error::Error + 'static,
|
||||||
|
E2: std::error::Error + 'static,
|
||||||
|
{
|
||||||
|
pub fn new(allocator: A, width: u32, height: u32, format: Format) -> Swapchain<A, B, D> {
|
||||||
Swapchain {
|
Swapchain {
|
||||||
allocator,
|
allocator,
|
||||||
|
_original_buffer_format: std::marker::PhantomData,
|
||||||
width,
|
width,
|
||||||
height,
|
height,
|
||||||
format,
|
format,
|
||||||
|
@ -62,10 +84,14 @@ impl<A: Allocator<B>, B: Buffer> Swapchain<A, B> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn acquire(&mut self) -> Result<Option<Slot<B>>, A::Error> {
|
pub fn acquire(&mut self) -> Result<Option<Slot<D>>, SwapchainError<E1, E2>> {
|
||||||
if let Some(free_slot) = self.slots.iter_mut().filter(|s| !s.acquired.load(Ordering::SeqCst)).next() {
|
if let Some(free_slot) = self.slots.iter_mut().filter(|s| !s.acquired.load(Ordering::SeqCst)).next() {
|
||||||
if free_slot.buffer.is_none() {
|
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());
|
assert!(!free_slot.buffer.is_some());
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue