From 494b409f55dc78c4c038f6ebcfefa5de311fafc8 Mon Sep 17 00:00:00 2001 From: David <122132914+EnderBoy9217@users.noreply.github.com> Date: Sat, 4 Apr 2026 15:46:30 -0400 Subject: [PATCH] Cap StructureLayer Maximum Texture Size (#3574) Resolves #3569 ## Description: While browsers like Firefox will report their maximum texture size of 16384, going over 8192 causes extreme VRAM usage and massive FPS drops, even when no structures are actually being rendered (I experienced ~60ms rendering time on this layer with no structures present). This PR sets the StructureLayer texture size to cap at 8192, while keeping near-exact scales. The result is increased performance, reduced VRAM Usage, (especially in larger maps), and the resolution of the unplayable performance issues when StructureLayer is present, with zero noticeable degradation. VRAM Usage also no longer rises when zoomed in (Sitting at around a constant 40MB no matter zoom level, previously it would rise to over 160MB when StructureLayer was present). All tested on Giant World, where the issues were first spotted, but applies to all maps. Discord: @enderboy9217 --- src/client/graphics/layers/StructureLayer.ts | 21 +++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/src/client/graphics/layers/StructureLayer.ts b/src/client/graphics/layers/StructureLayer.ts index 32d836256..5bc165b92 100644 --- a/src/client/graphics/layers/StructureLayer.ts +++ b/src/client/graphics/layers/StructureLayer.ts @@ -130,12 +130,27 @@ export class StructureLayer implements Layer { if (context === null) throw new Error("2d context not supported"); this.context = context; + // Firefox's GPU limit is 8192, only known browser issue + const maxTextureSize = 8192; + const scaleX = maxTextureSize / this.game.width(); + const scaleY = maxTextureSize / this.game.height(); + const targetScale = Math.min(2, scaleX, scaleY); + this.canvas.width = Math.max( + 1, + Math.floor(this.game.width() * targetScale), + ); + this.canvas.height = Math.max( + 1, + Math.floor(this.game.height() * targetScale), + ); + // Enable smooth scaling this.context.imageSmoothingEnabled = true; this.context.imageSmoothingQuality = "high"; - - this.canvas.width = this.game.width() * 2; - this.canvas.height = this.game.height() * 2; + this.context.scale( + this.canvas.width / (this.game.width() * 2), + this.canvas.height / (this.game.height() * 2), + ); Promise.all( Array.from(this.unitIcons.values()).map((img) =>