fix: harden GIF support — ref-counted sources, defensive detection, play budget

1. Move GIF loading behind TextureManager.loadGif/releaseGif with
   ref-counting (fixes shared-source invalidation on duplicate GIFs)
2. Strip query strings/fragments before .gif extension check
3. GIFs now load paused — separate MAX_PLAYING_GIFS=8 budget in
   culling system, only nearest N animate (others show static frame)
This commit is contained in:
Hiren Kangad
2026-03-10 19:41:50 +05:30
parent 5a64708bd4
commit e45fce3e67
4 changed files with 122 additions and 15 deletions
+13 -1
View File
@@ -27,6 +27,18 @@ import type {
SceneObject,
} from './scene-format';
// ---------------------------------------------------------------------------
// GIF detection
// ---------------------------------------------------------------------------
/** Check if an asset key points to a GIF file.
* Strips query strings and fragments before checking extension. */
function isGifAsset(asset: string): boolean {
// Strip query string and fragment
const clean = asset.split('?')[0].split('#')[0];
return clean.toLowerCase().endsWith('.gif');
}
// ---------------------------------------------------------------------------
// SceneItem
// ---------------------------------------------------------------------------
@@ -276,7 +288,7 @@ export class SceneManager {
switch (data.type) {
case 'image': {
const imgData = data as ImageObject;
if (imgData.asset.toLowerCase().endsWith('.gif')) {
if (isGifAsset(imgData.asset)) {
displayObject = new AnimatedGifSprite(imgData.asset, imgData.w, imgData.h, this.textures);
} else {
displayObject = new ImageSprite(imgData.asset, imgData.w, imgData.h, this.textures);