use crate::gpu::context::Error;
use raw_window_handle::{HasDisplayHandle, HasWindowHandle};
use std::num::NonZeroU32;
pub trait Presenter {
fn present(&mut self, width: u32, height: u32, draw: &mut dyn FnMut(&mut [u32])) -> Result<(), Error>;
}
pub struct SoftbufferPresenter<D, W> {
surface: softbuffer::Surface<D, W>,
}
impl<D: HasDisplayHandle, W: HasWindowHandle> SoftbufferPresenter<D, W> {
pub fn new(display: D, window: W) -> Result<Self, Error> {
let context = softbuffer::Context::new(display).map_err(|error| Error(error.to_string()))?;
let surface = softbuffer::Surface::new(&context, window).map_err(|error| Error(error.to_string()))?;
Ok(Self { surface })
}
}
impl<D: HasDisplayHandle, W: HasWindowHandle> Presenter for SoftbufferPresenter<D, W> {
fn present(&mut self, width: u32, height: u32, draw: &mut dyn FnMut(&mut [u32])) -> Result<(), Error> {
let (Some(width), Some(height)) = (NonZeroU32::new(width), NonZeroU32::new(height)) else { return Ok(()) };
self.surface.resize(width, height).map_err(|error| Error(error.to_string()))?;
let mut buffer = self.surface.buffer_mut().map_err(|error| Error(error.to_string()))?;
draw(&mut buffer);
buffer.present().map_err(|error| Error(error.to_string()))
}
}