import WebGLSystem from '../WebGLSystem'; import { GC_MODES } from '@pixi/constants'; import { settings } from '@pixi/settings'; /** * TextureGarbageCollector. This class manages the GPU and ensures that it does not get clogged * up with textures that are no longer being used. * * @class * @memberof PIXI */ export default class TextureGCSystem extends WebGLSystem { /** * @param {PIXI.Renderer} renderer - The renderer this System works for. */ constructor(renderer) { super(renderer); this.count = 0; this.checkCount = 0; this.maxIdle = settings.GC_MAX_IDLE; this.checkCountMax = settings.GC_MAX_CHECK_COUNT; this.mode = settings.GC_MODE; } /** * Checks to see when the last time a texture was used * if the texture has not been used for a specified amount of time it will be removed from the GPU */ postrender() { this.count++; if (this.mode === GC_MODES.MANUAL) { return; } this.checkCount++; if (this.checkCount > this.checkCountMax) { this.checkCount = 0; this.run(); } } /** * Checks to see when the last time a texture was used * if the texture has not been used for a specified amount of time it will be removed from the GPU */ run() { const tm = this.renderer.texture; const managedTextures = tm.managedTextures; let wasRemoved = false; for (let i = 0; i < managedTextures.length; i++) { const texture = managedTextures[i]; // only supports non generated textures at the moment! if (!texture.frameBuffer && this.count - texture.touched > this.maxIdle) { tm.destroyTexture(texture, true); managedTextures[i] = null; wasRemoved = true; } } if (wasRemoved) { let j = 0; for (let i = 0; i < managedTextures.length; i++) { if (managedTextures[i] !== null) { managedTextures[j++] = managedTextures[i]; } } managedTextures.length = j; } } /** * Removes all the textures within the specified displayObject and its children from the GPU * * @param {PIXI.DisplayObject} displayObject - the displayObject to remove the textures from. */ unload(displayObject) { const tm = this.renderer.textureSystem; // only destroy non generated textures if (displayObject._texture && displayObject._texture._glRenderTargets) { tm.destroyTexture(displayObject._texture, true); } for (let i = displayObject.children.length - 1; i >= 0; i--) { this.unload(displayObject.children[i]); } } }