defer font texture releases by 250ms

evicted glyph textures may still be referenced by the current frame's
queued gui draws, so release them only after the frame has flushed
This commit is contained in:
froslanz
2026-10-22 11:30:58 -04:00
parent 8eaec3cc4f
commit e453c948cc
@@ -23,6 +23,7 @@ import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Objects;
@@ -53,11 +54,16 @@ public final class FrosFont {
@Override
protected boolean removeEldestEntry(Map.Entry<Key, Glyph> eldest) {
if (size() <= MAX_CACHE) return false;
mc.getTextureManager().release(eldest.getValue().id());
queueRelease(eldest.getValue().id());
return true;
}
};
// textures still referenced by this frame's queued draws are only
// released a moment later, once the frame has been flushed
private static final List<Identifier> PENDING_RELEASE = new ArrayList<>();
private static long lastQueuedAt;
private record Key(int color, String text) {
}
@@ -204,14 +210,29 @@ public final class FrosFont {
private static void clearGlyphs() {
for (Glyph glyph : new ArrayList<>(GLYPHS.values())) {
mc.getTextureManager().release(glyph.id());
queueRelease(glyph.id());
}
GLYPHS.clear();
}
private static void queueRelease(Identifier id) {
lastQueuedAt = System.currentTimeMillis();
PENDING_RELEASE.add(id);
}
private static void flushReleases() {
if (PENDING_RELEASE.isEmpty()) return;
if (System.currentTimeMillis() - lastQueuedAt < 250) return;
for (Identifier id : PENDING_RELEASE) {
mc.getTextureManager().release(id);
}
PENDING_RELEASE.clear();
}
// --- rasterizing ---
private static void drawGlyphs(GuiGraphics context, String text, int x, int y, int color) {
flushReleases();
Key key = new Key(color, text);
Glyph glyph = GLYPHS.get(key);
if (glyph == null) {