From cebd5820189160f842b73219bb0903a8a469bbce Mon Sep 17 00:00:00 2001 From: piexel Date: Mon, 19 Oct 2026 11:18:59 +0200 Subject: [PATCH] Hand the display server one finished map picture per paint The map drew every visible tile to the window on its own, hundreds of scaled images per paint, and since tiles are no longer cached in the display server each of those was uploaded again on every frame, which made dragging and zooming lag. The tiles are now put together in memory once, only when tiles or the view change, and drawn as a single image like the palette view does. Model used: Claude Opus 5.5 --- .../com/volmit/iris/core/gui/MapCanvas.java | 29 +++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/core/src/main/java/com/volmit/iris/core/gui/MapCanvas.java b/core/src/main/java/com/volmit/iris/core/gui/MapCanvas.java index ef03c1f6b..d5a730f61 100644 --- a/core/src/main/java/com/volmit/iris/core/gui/MapCanvas.java +++ b/core/src/main/java/com/volmit/iris/core/gui/MapCanvas.java @@ -88,6 +88,8 @@ final class MapCanvas extends JPanel { private IrisRenderer renderer; private VisionOverlay overlay; private VisionRenderController.Frame renderFrame; + private BufferedImage tileLayer; + private boolean tileLayerStale = true; private RenderType currentType = RenderType.BIOME; private String viewLabel = MapView.BIOMES.label(); private List players = List.of(); @@ -455,7 +457,32 @@ final class MapCanvas extends JPanel { } } + // The display server gets one finished picture per paint: handing it every tile separately made the map lag. private void renderTiles(Graphics2D canvas) { + canvas.drawImage(currentTileLayer(), 0, 0, null); + } + + private BufferedImage currentTileLayer() { + int width = Math.max(1, getWidth()); + int height = Math.max(1, getHeight()); + if (tileLayer == null || tileLayer.getWidth() != width || tileLayer.getHeight() != height) { + tileLayer = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); + tileLayer.setAccelerationPriority(0F); + tileLayerStale = true; + } + if (tileLayerStale) { + Graphics2D layer = tileLayer.createGraphics(); + try { + composeTiles(layer); + } finally { + layer.dispose(); + } + tileLayerStale = false; + } + return tileLayer; + } + + private void composeTiles(Graphics2D canvas) { VisionRenderController.Frame frame = renderFrame; canvas.setColor(StudioTheme.EDITOR_BACKGROUND); canvas.fillRect(0, 0, getWidth(), getHeight()); @@ -746,11 +773,13 @@ final class MapCanvas extends JPanel { } private void onTilesChanged() { + tileLayerStale = true; repaint(); refreshStatus(); } private void requestRender() { + tileLayerStale = true; if (closed || !active || getWidth() < 1 || getHeight() < 1 || !ensureEngine()) { repaint(); return;