extern crate alloc;
use alloc::boxed::Box;
use waterui_core::{layout::StretchAxis, raw_view};
#[must_use]
pub fn preferred_surface_format(caps: &wgpu::SurfaceCapabilities) -> wgpu::TextureFormat {
let hdr = wgpu::TextureFormat::Rgba16Float;
if caps.formats.contains(&hdr) {
return hdr;
}
if let Some(fmt) = caps
.formats
.iter()
.copied()
.find(wgpu::TextureFormat::is_srgb)
{
return fmt;
}
caps.formats
.first()
.copied()
.unwrap_or(wgpu::TextureFormat::Bgra8UnormSrgb)
}
pub struct GpuContext<'a> {
pub device: &'a wgpu::Device,
pub queue: &'a wgpu::Queue,
pub surface_format: wgpu::TextureFormat,
}
impl core::fmt::Debug for GpuContext<'_> {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
f.debug_struct("GpuContext")
.field("surface_format", &self.surface_format)
.finish_non_exhaustive()
}
}
impl GpuContext<'_> {
#[must_use]
pub const fn is_hdr(&self) -> bool {
matches!(
self.surface_format,
wgpu::TextureFormat::Rgba16Float | wgpu::TextureFormat::Rgba32Float
)
}
}
pub struct GpuFrame<'a> {
pub device: &'a wgpu::Device,
pub queue: &'a wgpu::Queue,
pub texture: &'a wgpu::Texture,
pub view: wgpu::TextureView,
pub format: wgpu::TextureFormat,
pub width: u32,
pub height: u32,
}
impl core::fmt::Debug for GpuFrame<'_> {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
f.debug_struct("GpuFrame")
.field("format", &self.format)
.field("width", &self.width)
.field("height", &self.height)
.finish_non_exhaustive()
}
}
impl GpuFrame<'_> {
#[must_use]
pub const fn is_hdr(&self) -> bool {
matches!(
self.format,
wgpu::TextureFormat::Rgba16Float | wgpu::TextureFormat::Rgba32Float
)
}
}
pub trait GpuRenderer: Send + 'static {
fn setup(&mut self, ctx: &GpuContext);
fn render(&mut self, frame: &GpuFrame);
fn resize(&mut self, _width: u32, _height: u32) {}
}
pub struct GpuSurface {
pub renderer: Box<dyn GpuRenderer>,
}
impl core::fmt::Debug for GpuSurface {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
f.debug_struct("GpuSurface").finish_non_exhaustive()
}
}
impl GpuSurface {
#[must_use]
pub fn new<R: GpuRenderer>(renderer: R) -> Self {
Self {
renderer: Box::new(renderer),
}
}
}
raw_view!(GpuSurface, StretchAxis::Both);