use crate::core::cache::{Cache, HasSize, HashLookup, Lru, MaxSize};
use crate::render::texture::{ColorFormat, Texture};
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub struct TextureKey {
ptr: usize,
len: usize,
width: u16,
height: u16,
format: ColorFormat,
}
impl TextureKey {
pub fn from(src: &Texture) -> Self {
let buf = src.buf.as_slice();
Self {
ptr: buf.as_ptr() as usize,
len: buf.len(),
width: src.width,
height: src.height,
format: src.format,
}
}
}
pub struct CachedTexture(pub wgpu::Texture);
impl HasSize for CachedTexture {
fn cache_size(&self) -> usize {
let size = self.0.size();
(size.width as usize) * (size.height as usize) * 4
}
}
const TEXTURE_BUDGET: usize = 16 * 1024 * 1024;
pub type TexturePool = Cache<TextureKey, CachedTexture, Lru, HashLookup<TextureKey>>;
pub fn new_pool() -> TexturePool {
Cache::builder()
.max_size(MaxSize::Bytes(TEXTURE_BUDGET))
.build()
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn key_collides_when_buffer_view_matches() {
let buf = [0u8; 16];
let a = Texture::from_ref(&buf, 2, 2, ColorFormat::RGBA8888);
let b = Texture::from_ref(&buf, 2, 2, ColorFormat::RGBA8888);
assert_eq!(TextureKey::from(&a), TextureKey::from(&b));
}
#[test]
fn transient_flag_survives_texture_construction() {
let buf = [0u8; 16];
let t = Texture::from_ref(&buf, 2, 2, ColorFormat::RGBA8888).with_transient(true);
assert!(t.transient);
let default = Texture::from_ref(&buf, 2, 2, ColorFormat::RGBA8888);
assert!(!default.transient);
}
}