import { ExtensionType } from '../../../../extensions/Extensions.mjs'; "use strict"; const _RenderableGCSystem = class _RenderableGCSystem { /** @param renderer - The renderer this System works for. */ constructor(renderer) { this._managedRenderables = []; this._renderer = renderer; } init(options) { options = { ..._RenderableGCSystem.defaultOptions, ...options }; this.maxUnusedTime = options.renderableGCMaxUnusedTime; this._frequency = options.renderableGCFrequency; this.enabled = options.renderableGCActive; } get enabled() { return !!this._handler; } set enabled(value) { if (this.enabled === value) return; if (value) { this._handler = this._renderer.scheduler.repeat( () => this.run(), this._frequency ); } else { this._renderer.scheduler.cancel(this._handler); } } prerender() { this._now = performance.now(); } addRenderable(renderable, instructionSet) { if (!this.enabled) return; renderable._lastUsed = this._now; if (renderable._lastInstructionTick === -1) { this._managedRenderables.push(renderable); renderable.once("destroyed", this._removeRenderable, this); } renderable._lastInstructionTick = instructionSet.tick; } /** Runs the scheduled garbage collection */ run() { const now = performance.now(); const managedRenderables = this._managedRenderables; const renderPipes = this._renderer.renderPipes; let offset = 0; for (let i = 0; i < managedRenderables.length; i++) { const renderable = managedRenderables[i]; if (renderable === null) { offset++; continue; } const renderGroup = renderable.renderGroup ?? renderable.parentRenderGroup; const currentIndex = renderGroup?.instructionSet?.tick ?? -1; if (renderable._lastInstructionTick !== currentIndex && now - renderable._lastUsed > this.maxUnusedTime) { if (!renderable.destroyed) { const rp = renderPipes; rp[renderable.renderPipeId].destroyRenderable(renderable); } renderable._lastInstructionTick = -1; offset++; renderable.off("destroyed", this._removeRenderable, this); } else { managedRenderables[i - offset] = renderable; } } managedRenderables.length = managedRenderables.length - offset; } destroy() { this.enabled = false; this._renderer = null; this._managedRenderables.length = 0; } _removeRenderable(renderable) { const index = this._managedRenderables.indexOf(renderable); if (index >= 0) { renderable.off("destroyed", this._removeRenderable, this); this._managedRenderables[index] = null; } } }; /** @ignore */ _RenderableGCSystem.extension = { type: [ ExtensionType.WebGLSystem, ExtensionType.WebGPUSystem ], name: "renderableGC" }; /** default options for the renderableGCSystem */ _RenderableGCSystem.defaultOptions = { /** * If set to true, this will enable the garbage collector on the GPU. * @default true */ renderableGCActive: true, /** * The maximum idle frames before a texture is destroyed by garbage collection. * @default 60 * 60 */ renderableGCMaxUnusedTime: 6e4, /** * Frames between two garbage collections. * @default 600 */ renderableGCFrequency: 3e4 }; let RenderableGCSystem = _RenderableGCSystem; export { RenderableGCSystem }; //# sourceMappingURL=RenderableGCSystem.mjs.map