From e453c948ccb1ec2cb8a7a649672cdbdd37dddbd1 Mon Sep 17 00:00:00 2001 From: froslanz Date: Thu, 22 Oct 2026 11:30:58 -0400 Subject: [PATCH] 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 --- .../java/cc/fros/util/render/FrosFont.java | 25 +++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/src/main/java/cc/fros/util/render/FrosFont.java b/src/main/java/cc/fros/util/render/FrosFont.java index 4dd1357..9802bb7 100644 --- a/src/main/java/cc/fros/util/render/FrosFont.java +++ b/src/main/java/cc/fros/util/render/FrosFont.java @@ -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 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 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) {