{"version":3,"file":"TextureSystem.mjs","sources":["../../src/textures/TextureSystem.ts"],"sourcesContent":["import { MIPMAP_MODES, SAMPLER_TYPES, SCALE_MODES, TYPES, WRAP_MODES } from '@pixi/constants';\nimport { extensions, ExtensionType } from '@pixi/extensions';\nimport { removeItems } from '@pixi/utils';\nimport { BaseTexture } from './BaseTexture';\nimport { GLTexture } from './GLTexture';\nimport { mapInternalFormatToSamplerType } from './utils/mapInternalFormatToSamplerType';\nimport { mapTypeAndFormatToInternalFormat } from './utils/mapTypeAndFormatToInternalFormat';\n\nimport type { ExtensionMetadata } from '@pixi/extensions';\nimport type { IRenderingContext } from '../IRenderer';\nimport type { Renderer } from '../Renderer';\nimport type { ISystem } from '../system/ISystem';\nimport type { Texture } from './Texture';\n\n/**\n * System plugin to the renderer to manage textures.\n * @memberof PIXI\n */\nexport class TextureSystem implements ISystem\n{\n    /** @ignore */\n    static extension: ExtensionMetadata = {\n        type: ExtensionType.RendererSystem,\n        name: 'texture',\n    };\n\n    /**\n     * Bound textures.\n     * @readonly\n     */\n    public boundTextures: BaseTexture[];\n\n    /**\n     * List of managed textures.\n     * @readonly\n     */\n    public managedTextures: Array<BaseTexture>;\n\n    /** Whether glTexture with int/uint sampler type was uploaded. */\n    protected hasIntegerTextures: boolean;\n    protected CONTEXT_UID: number;\n    protected gl: IRenderingContext;\n    protected internalFormats: { [type: number]: { [format: number]: number } };\n    protected samplerTypes: Record<number, SAMPLER_TYPES>;\n    protected webGLVersion: number;\n\n    /**\n     * BaseTexture value that shows that we don't know what is bound.\n     * @readonly\n     */\n    protected unknownTexture: BaseTexture;\n\n    /**\n     * Did someone temper with textures state? We'll overwrite them when we need to unbind something.\n     * @private\n     */\n    protected _unknownBoundTextures: boolean;\n\n    /**\n     * Current location.\n     * @readonly\n     */\n    currentLocation: number;\n    emptyTextures: {[key: number]: GLTexture};\n    private renderer: Renderer;\n\n    /**\n     * @param renderer - The renderer this system works for.\n     */\n    constructor(renderer: Renderer)\n    {\n        this.renderer = renderer;\n\n        // TODO set to max textures...\n        this.boundTextures = [];\n        this.currentLocation = -1;\n        this.managedTextures = [];\n\n        this._unknownBoundTextures = false;\n        this.unknownTexture = new BaseTexture();\n\n        this.hasIntegerTextures = false;\n    }\n\n    /** Sets up the renderer context and necessary buffers. */\n    contextChange(): void\n    {\n        const gl = this.gl = this.renderer.gl;\n\n        this.CONTEXT_UID = this.renderer.CONTEXT_UID;\n\n        this.webGLVersion = this.renderer.context.webGLVersion;\n\n        this.internalFormats = mapTypeAndFormatToInternalFormat(gl);\n        this.samplerTypes = mapInternalFormatToSamplerType(gl);\n\n        const maxTextures = gl.getParameter(gl.MAX_TEXTURE_IMAGE_UNITS);\n\n        this.boundTextures.length = maxTextures;\n\n        for (let i = 0; i < maxTextures; i++)\n        {\n            this.boundTextures[i] = null;\n        }\n\n        // TODO move this.. to a nice make empty textures class..\n        this.emptyTextures = {};\n\n        const emptyTexture2D = new GLTexture(gl.createTexture());\n\n        gl.bindTexture(gl.TEXTURE_2D, emptyTexture2D.texture);\n        gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE, new Uint8Array(4));\n\n        this.emptyTextures[gl.TEXTURE_2D] = emptyTexture2D;\n        this.emptyTextures[gl.TEXTURE_CUBE_MAP] = new GLTexture(gl.createTexture());\n\n        gl.bindTexture(gl.TEXTURE_CUBE_MAP, this.emptyTextures[gl.TEXTURE_CUBE_MAP].texture);\n\n        for (let i = 0; i < 6; i++)\n        {\n            gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, gl.RGBA, 1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);\n        }\n\n        gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MAG_FILTER, gl.LINEAR);\n        gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MIN_FILTER, gl.LINEAR);\n\n        for (let i = 0; i < this.boundTextures.length; i++)\n        {\n            this.bind(null, i);\n        }\n    }\n\n    /**\n     * Bind a texture to a specific location\n     *\n     * If you want to unbind something, please use `unbind(texture)` instead of `bind(null, textureLocation)`\n     * @param texture - Texture to bind\n     * @param [location=0] - Location to bind at\n     */\n    bind(texture: Texture | BaseTexture, location = 0): void\n    {\n        const { gl } = this;\n\n        texture = texture?.castToBaseTexture();\n\n        // cannot bind partial texture\n        // TODO: report a warning\n        if (texture?.valid && !texture.parentTextureArray)\n        {\n            texture.touched = this.renderer.textureGC.count;\n\n            const glTexture = texture._glTextures[this.CONTEXT_UID] || this.initTexture(texture);\n\n            if (this.boundTextures[location] !== texture)\n            {\n                if (this.currentLocation !== location)\n                {\n                    this.currentLocation = location;\n                    gl.activeTexture(gl.TEXTURE0 + location);\n                }\n\n                gl.bindTexture(texture.target, glTexture.texture);\n            }\n\n            if (glTexture.dirtyId !== texture.dirtyId)\n            {\n                if (this.currentLocation !== location)\n                {\n                    this.currentLocation = location;\n                    gl.activeTexture(gl.TEXTURE0 + location);\n                }\n                this.updateTexture(texture);\n            }\n            else if (glTexture.dirtyStyleId !== texture.dirtyStyleId)\n            {\n                this.updateTextureStyle(texture);\n            }\n\n            this.boundTextures[location] = texture;\n        }\n        else\n        {\n            if (this.currentLocation !== location)\n            {\n                this.currentLocation = location;\n                gl.activeTexture(gl.TEXTURE0 + location);\n            }\n\n            gl.bindTexture(gl.TEXTURE_2D, this.emptyTextures[gl.TEXTURE_2D].texture);\n            this.boundTextures[location] = null;\n        }\n    }\n\n    /** Resets texture location and bound textures Actual `bind(null, i)` calls will be performed at next `unbind()` call */\n    reset(): void\n    {\n        this._unknownBoundTextures = true;\n        this.hasIntegerTextures = false;\n        this.currentLocation = -1;\n\n        for (let i = 0; i < this.boundTextures.length; i++)\n        {\n            this.boundTextures[i] = this.unknownTexture;\n        }\n    }\n\n    /**\n     * Unbind a texture.\n     * @param texture - Texture to bind\n     */\n    unbind(texture?: BaseTexture): void\n    {\n        const { gl, boundTextures } = this;\n\n        if (this._unknownBoundTextures)\n        {\n            this._unknownBoundTextures = false;\n            // someone changed webGL state,\n            // we have to be sure that our texture does not appear in multi-texture renderer samplers\n            for (let i = 0; i < boundTextures.length; i++)\n            {\n                if (boundTextures[i] === this.unknownTexture)\n                {\n                    this.bind(null, i);\n                }\n            }\n        }\n\n        for (let i = 0; i < boundTextures.length; i++)\n        {\n            if (boundTextures[i] === texture)\n            {\n                if (this.currentLocation !== i)\n                {\n                    gl.activeTexture(gl.TEXTURE0 + i);\n                    this.currentLocation = i;\n                }\n\n                gl.bindTexture(texture.target, this.emptyTextures[texture.target].texture);\n                boundTextures[i] = null;\n            }\n        }\n    }\n\n    /**\n     * Ensures that current boundTextures all have FLOAT sampler type,\n     * see {@link PIXI.SAMPLER_TYPES} for explanation.\n     * @param maxTextures - number of locations to check\n     */\n    ensureSamplerType(maxTextures: number): void\n    {\n        const { boundTextures, hasIntegerTextures, CONTEXT_UID } = this;\n\n        if (!hasIntegerTextures)\n        {\n            return;\n        }\n\n        for (let i = maxTextures - 1; i >= 0; --i)\n        {\n            const tex = boundTextures[i];\n\n            if (tex)\n            {\n                const glTexture = tex._glTextures[CONTEXT_UID];\n\n                if (glTexture.samplerType !== SAMPLER_TYPES.FLOAT)\n                {\n                    this.renderer.texture.unbind(tex);\n                }\n            }\n        }\n    }\n\n    /**\n     * Initialize a texture\n     * @private\n     * @param texture - Texture to initialize\n     */\n    initTexture(texture: BaseTexture): GLTexture\n    {\n        const glTexture = new GLTexture(this.gl.createTexture());\n\n        // guarantee an update..\n        glTexture.dirtyId = -1;\n\n        texture._glTextures[this.CONTEXT_UID] = glTexture;\n\n        this.managedTextures.push(texture);\n        texture.on('dispose', this.destroyTexture, this);\n\n        return glTexture;\n    }\n\n    initTextureType(texture: BaseTexture, glTexture: GLTexture): void\n    {\n        glTexture.internalFormat = this.internalFormats[texture.type]?.[texture.format] ?? texture.format;\n        glTexture.samplerType = this.samplerTypes[glTexture.internalFormat] ?? SAMPLER_TYPES.FLOAT;\n\n        if (this.webGLVersion === 2 && texture.type === TYPES.HALF_FLOAT)\n        {\n            // TYPES.HALF_FLOAT is WebGL1 HALF_FLOAT_OES\n            // we have to convert it to WebGL HALF_FLOAT\n            glTexture.type = this.gl.HALF_FLOAT;\n        }\n        else\n        {\n            glTexture.type = texture.type;\n        }\n    }\n\n    /**\n     * Update a texture\n     * @private\n     * @param {PIXI.BaseTexture} texture - Texture to initialize\n     */\n    updateTexture(texture: BaseTexture): void\n    {\n        const glTexture = texture._glTextures[this.CONTEXT_UID];\n\n        if (!glTexture)\n        {\n            return;\n        }\n\n        const renderer = this.renderer;\n\n        this.initTextureType(texture, glTexture);\n\n        if (texture.resource?.upload(renderer, texture, glTexture))\n        {\n            // texture is uploaded, dont do anything!\n            if (glTexture.samplerType !== SAMPLER_TYPES.FLOAT)\n            {\n                this.hasIntegerTextures = true;\n            }\n        }\n        else\n        {\n            // default, renderTexture-like logic\n            const width = texture.realWidth;\n            const height = texture.realHeight;\n            const gl = renderer.gl;\n\n            if (glTexture.width !== width\n                || glTexture.height !== height\n                || glTexture.dirtyId < 0)\n            {\n                glTexture.width = width;\n                glTexture.height = height;\n\n                gl.texImage2D(texture.target, 0,\n                    glTexture.internalFormat,\n                    width,\n                    height,\n                    0,\n                    texture.format,\n                    glTexture.type,\n                    null);\n            }\n        }\n\n        // lets only update what changes..\n        if (texture.dirtyStyleId !== glTexture.dirtyStyleId)\n        {\n            this.updateTextureStyle(texture);\n        }\n        glTexture.dirtyId = texture.dirtyId;\n    }\n\n    /**\n     * Deletes the texture from WebGL\n     * @private\n     * @param texture - the texture to destroy\n     * @param [skipRemove=false] - Whether to skip removing the texture from the TextureManager.\n     */\n    destroyTexture(texture: BaseTexture | Texture, skipRemove?: boolean): void\n    {\n        const { gl } = this;\n\n        texture = texture.castToBaseTexture();\n\n        if (texture._glTextures[this.CONTEXT_UID])\n        {\n            this.unbind(texture);\n\n            gl.deleteTexture(texture._glTextures[this.CONTEXT_UID].texture);\n            texture.off('dispose', this.destroyTexture, this);\n\n            delete texture._glTextures[this.CONTEXT_UID];\n\n            if (!skipRemove)\n            {\n                const i = this.managedTextures.indexOf(texture);\n\n                if (i !== -1)\n                {\n                    removeItems(this.managedTextures, i, 1);\n                }\n            }\n        }\n    }\n\n    /**\n     * Update texture style such as mipmap flag\n     * @private\n     * @param {PIXI.BaseTexture} texture - Texture to update\n     */\n    updateTextureStyle(texture: BaseTexture): void\n    {\n        const glTexture = texture._glTextures[this.CONTEXT_UID];\n\n        if (!glTexture)\n        {\n            return;\n        }\n\n        if ((texture.mipmap === MIPMAP_MODES.POW2 || this.webGLVersion !== 2) && !texture.isPowerOfTwo)\n        {\n            glTexture.mipmap = false;\n        }\n        else\n        {\n            glTexture.mipmap = texture.mipmap >= 1;\n        }\n\n        if (this.webGLVersion !== 2 && !texture.isPowerOfTwo)\n        {\n            glTexture.wrapMode = WRAP_MODES.CLAMP;\n        }\n        else\n        {\n            glTexture.wrapMode = texture.wrapMode;\n        }\n\n        if (texture.resource?.style(this.renderer, texture, glTexture))\n        {\n            // style is set, dont do anything!\n        }\n        else\n        {\n            this.setStyle(texture, glTexture);\n        }\n\n        glTexture.dirtyStyleId = texture.dirtyStyleId;\n    }\n\n    /**\n     * Set style for texture\n     * @private\n     * @param texture - Texture to update\n     * @param glTexture\n     */\n    setStyle(texture: BaseTexture, glTexture: GLTexture): void\n    {\n        const gl = this.gl;\n\n        if (glTexture.mipmap && texture.mipmap !== MIPMAP_MODES.ON_MANUAL)\n        {\n            gl.generateMipmap(texture.target);\n        }\n\n        gl.texParameteri(texture.target, gl.TEXTURE_WRAP_S, glTexture.wrapMode);\n        gl.texParameteri(texture.target, gl.TEXTURE_WRAP_T, glTexture.wrapMode);\n\n        if (glTexture.mipmap)\n        {\n            /* eslint-disable max-len */\n            gl.texParameteri(texture.target, gl.TEXTURE_MIN_FILTER, texture.scaleMode === SCALE_MODES.LINEAR ? gl.LINEAR_MIPMAP_LINEAR : gl.NEAREST_MIPMAP_NEAREST);\n            /* eslint-disable max-len */\n\n            const anisotropicExt = this.renderer.context.extensions.anisotropicFiltering;\n\n            if (anisotropicExt && texture.anisotropicLevel > 0 && texture.scaleMode === SCALE_MODES.LINEAR)\n            {\n                const level = Math.min(texture.anisotropicLevel, gl.getParameter(anisotropicExt.MAX_TEXTURE_MAX_ANISOTROPY_EXT));\n\n                gl.texParameterf(texture.target, anisotropicExt.TEXTURE_MAX_ANISOTROPY_EXT, level);\n            }\n        }\n        else\n        {\n            gl.texParameteri(texture.target, gl.TEXTURE_MIN_FILTER, texture.scaleMode === SCALE_MODES.LINEAR ? gl.LINEAR : gl.NEAREST);\n        }\n\n        gl.texParameteri(texture.target, gl.TEXTURE_MAG_FILTER, texture.scaleMode === SCALE_MODES.LINEAR ? gl.LINEAR : gl.NEAREST);\n    }\n\n    destroy(): void\n    {\n        this.renderer = null;\n    }\n}\n\nextensions.add(TextureSystem);\n"],"names":[],"mappings":"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"}