perf: reduce texture atlas memory

Dedupe still textures by a hashed key instead of storing their full
frame bytes, and avoid retaining intermediate paletted atlas frames.

Co-Authored-By: Claude Code <[email protected]>
This commit is contained in:
gorkandClaude Code committed 2026-11-04 00:22:27 +01:00
1 parent ba5ba8b00a
commit d874278161
2 files changed
+23 -9

No files matched your search

@@ -379,14 +379,17 @@ pub fn generate(
let (_, _, key) = load(palette_key, "textures/palettes")?;
let (_, _, target) = load(palette, "textures/palettes")?;
let mut mapped = argb(&pixels);
apply_palette(&mut mapped, &argb(&key), &argb(&target))?;
let out = mapped
let key = argb(&key);
let target = argb(&target);
apply_palette(&mut mapped, &key, &target)?;
let out: Vec<u8> = mapped
.iter()
.flat_map(|p| {
let [a, r, g, b] = p.to_be_bytes();
[r, g, b, a]
})
.collect();
drop(mapped);
Some((w, h, out))
}
}
+18 -7
View File
@@ -62,6 +62,15 @@ impl SpriteAnimation {
}
}
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
struct StillKey {
frame: u64,
pbr: u64,
side: u32,
settings: [u32; 2],
flags: [bool; 4],
}
#[derive(Default)]
pub struct Sprites {
/// Edge length of every array layer and the layers' current frames, set
@@ -90,7 +99,7 @@ pub struct Sprites {
/// Still textures by their pixels, their LabPBR maps and mip settings: mods copy vanilla's
/// textures under their own names, and one layer serves them all (the GPU's array may
/// hold as few as 2048).
still: std::collections::HashMap<(Vec<u8>, u64, u32, [u32; 2], [bool; 4]), u32>,
still: std::collections::HashMap<StillKey, u32>,
/// Decoded textures kept on disk between launches ([`Sprites::with_disk_cache`]).
disk: Option<crate::sprite_cache::SpriteCache>,
/// Textures [`Sprites::prefetch`] decoded ahead of their insert, by sprite name or
@@ -647,18 +656,20 @@ impl Sprites {
};
let still = (animation.is_none() && frames.len() == 1).then(|| {
use std::hash::{Hash, Hasher};
let mut frame = std::collections::hash_map::DefaultHasher::new();
frames[0].hash(&mut frame);
let mut maps = std::collections::hash_map::DefaultHasher::new();
pbr.hash(&mut maps);
(
frames[0].clone(),
maps.finish(),
StillKey {
frame: frame.finish(),
pbr: maps.finish(),
side,
[
settings: [
settings.strategy as u32,
settings.alpha_cutoff_bias.to_bits(),
],
[settings.has_transparent, settings.item, opaque, translucent],
)
flags: [settings.has_transparent, settings.item, opaque, translucent],
}
});
if let Some(&same) = still.as_ref().and_then(|k| self.still.get(k)) {
self.layers.insert(name.to_owned(), same);