use std::collections::HashMap;
use std::fmt;
use std::sync::{atomic, Arc};
use crate::gfx;
use crate::gfx::{Image, Rgba8};
use crate::math::{Size, Transform};
use crate::platform::{self, LogicalSize};
#[derive(Debug, Hash, PartialEq, Eq, PartialOrd, Ord, Copy, Clone)]
pub struct TextureId(u64);
impl TextureId {
pub const fn default_font() -> Self {
Self(0)
}
pub fn next() -> Self {
static NEXT: atomic::AtomicU64 = atomic::AtomicU64::new(2);
Self(NEXT.fetch_add(1, atomic::Ordering::SeqCst))
}
}
impl fmt::Display for TextureId {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "TextureId#{}", self.0)
}
}
impl From<u64> for TextureId {
fn from(id: u64) -> Self {
Self(id)
}
}
#[derive(PartialEq, Eq, Clone, Copy, Debug, Default)]
pub enum Blending {
#[default]
Alpha,
Constant,
}
#[derive(Debug)]
pub enum Paint {
Shape {
transform: Transform,
vertices: Vec<gfx::shape2d::Vertex>,
target: Option<TextureId>,
},
Sprite {
transform: Transform,
vertices: Vec<gfx::sprite2d::Vertex>,
texture: TextureId,
target: Option<TextureId>,
},
}
#[derive(Debug)]
pub enum Effect {
Paint { paint: Paint, blending: Blending },
Clear { id: TextureId, color: Rgba8 },
Texture {
id: TextureId,
image: Image,
offscreen: bool,
},
Resize { id: TextureId, size: Size<u32> },
Upload { id: TextureId, texels: Arc<[Rgba8]> },
}
impl From<Paint> for Effect {
fn from(paint: Paint) -> Self {
Self::Paint {
paint,
blending: Blending::default(),
}
}
}
pub trait TextureStore {
fn put(&mut self, texture_id: TextureId, image: Image);
}
impl TextureStore for HashMap<TextureId, Image> {
fn put(&mut self, texture_id: TextureId, image: Image) {
self.insert(texture_id, image);
}
}
pub trait Renderer: Sized {
type Error;
fn new(
win: &mut platform::backend::Window,
win_size: LogicalSize,
win_scale: f64,
ui_scale: f32,
) -> Result<Self, Self::Error>;
fn frame<E, T>(&mut self, effects: E, store: &mut T) -> Result<(), Self::Error>
where
E: Iterator<Item = Effect>,
T: TextureStore;
fn scale(&mut self, factor: f32) -> f32;
fn handle_scale_factor_changed(&mut self, scale_factor: f64);
}