{"version":3,"file":"GlShaderSystem.mjs","sources":["../../../../../src/rendering/renderers/gl/shader/GlShaderSystem.ts"],"sourcesContent":["import { ExtensionType } from '../../../../extensions/Extensions';\nimport { getMaxTexturesPerBatch } from '../../../batcher/gl/utils/maxRecommendedTextures';\nimport { generateShaderSyncCode } from './GenerateShaderSyncCode';\nimport { generateProgram } from './program/generateProgram';\n\nimport type { BufferResource } from '../../shared/buffer/BufferResource';\nimport type { Shader } from '../../shared/shader/Shader';\nimport type { ShaderSystem } from '../../shared/shader/ShaderSystem';\nimport type { UniformGroup } from '../../shared/shader/UniformGroup';\nimport type { GlRenderingContext } from '../context/GlRenderingContext';\nimport type { WebGLRenderer } from '../WebGLRenderer';\nimport type { GlProgram } from './GlProgram';\nimport type { GlProgramData } from './GlProgramData';\n\nexport interface ShaderSyncData\n{\n    textureCount: number;\n    blockIndex: number;\n}\n\nexport type ShaderSyncFunction = (renderer: WebGLRenderer, shader: Shader, syncData: ShaderSyncData) => void;\n\n// default sync data so we don't create a new one each time!\nconst defaultSyncData: ShaderSyncData = {\n    textureCount: 0,\n    blockIndex: 0,\n};\n\n/**\n * System plugin to the renderer to manage the shaders for WebGL.\n * @memberof rendering\n */\nexport class GlShaderSystem implements ShaderSystem\n{\n    /** @ignore */\n    public static extension = {\n        type: [\n            ExtensionType.WebGLSystem,\n        ],\n        name: 'shader',\n    } as const;\n\n    public maxTextures: number;\n\n    /**\n     * @internal\n     * @private\n     */\n    public _activeProgram: GlProgram = null;\n\n    private _programDataHash: Record<string, GlProgramData> = Object.create(null);\n    private readonly _renderer: WebGLRenderer;\n    public _gl: WebGL2RenderingContext;\n    private _maxBindings: number;\n    private _nextIndex = 0;\n    private _boundUniformsIdsToIndexHash: Record<number, number> = Object.create(null);\n    private _boundIndexToUniformsHash: Record<number, UniformGroup | BufferResource> = Object.create(null);\n    private _shaderSyncFunctions: Record<string, ShaderSyncFunction> = Object.create(null);\n\n    constructor(renderer: WebGLRenderer)\n    {\n        this._renderer = renderer;\n    }\n\n    protected contextChange(gl: GlRenderingContext): void\n    {\n        this._gl = gl;\n\n        this._maxBindings = gl.MAX_UNIFORM_BUFFER_BINDINGS ? gl.getParameter(gl.MAX_UNIFORM_BUFFER_BINDINGS) : 0;\n\n        this._programDataHash = Object.create(null);\n        this._boundUniformsIdsToIndexHash = Object.create(null);\n        this._boundIndexToUniformsHash = Object.create(null);\n        /**\n         * these need to also be cleared as internally some uniforms are set as an optimisation as the sync\n         * function is generated. Specifically the texture ints.\n         */\n        this._shaderSyncFunctions = Object.create(null);\n        this._activeProgram = null;\n\n        this.maxTextures = getMaxTexturesPerBatch();\n    }\n\n    /**\n     * Changes the current shader to the one given in parameter.\n     * @param shader - the new shader\n     * @param skipSync - false if the shader should automatically sync its uniforms.\n     * @returns the glProgram that belongs to the shader.\n     */\n    public bind(shader: Shader, skipSync?: boolean): void\n    {\n        this._setProgram(shader.glProgram);\n\n        if (skipSync) return;\n\n        defaultSyncData.textureCount = 0;\n        defaultSyncData.blockIndex = 0;\n\n        let syncFunction = this._shaderSyncFunctions[shader.glProgram._key];\n\n        if (!syncFunction)\n        {\n            syncFunction = this._shaderSyncFunctions[shader.glProgram._key] = this._generateShaderSync(shader, this);\n        }\n\n        syncFunction(this._renderer, shader, defaultSyncData);\n    }\n\n    /**\n     * Updates the uniform group.\n     * @param uniformGroup - the uniform group to update\n     */\n    public updateUniformGroup(uniformGroup: UniformGroup): void\n    {\n        this._renderer.uniformGroup.updateUniformGroup(uniformGroup, this._activeProgram, defaultSyncData);\n    }\n\n    /**\n     * Binds a uniform block to the shader.\n     * @param uniformGroup - the uniform group to bind\n     * @param name - the name of the uniform block\n     * @param index - the index of the uniform block\n     */\n    public bindUniformBlock(uniformGroup: UniformGroup | BufferResource, name: string, index = 0): void\n    {\n        const bufferSystem = this._renderer.buffer;\n        const programData = this._getProgramData(this._activeProgram);\n\n        const isBufferResource = (uniformGroup as BufferResource)._bufferResource;\n\n        if (isBufferResource)\n        {\n            this._renderer.ubo.updateUniformGroup(uniformGroup as UniformGroup);\n        }\n\n        bufferSystem.updateBuffer(uniformGroup.buffer);\n\n        let boundIndex = this._boundUniformsIdsToIndexHash[uniformGroup.uid];\n\n        // check if it is already bound..\n        if (boundIndex === undefined)\n        {\n            const nextIndex = this._nextIndex++ % this._maxBindings;\n\n            const currentBoundUniformGroup = this._boundIndexToUniformsHash[nextIndex];\n\n            if (currentBoundUniformGroup)\n            {\n                this._boundUniformsIdsToIndexHash[currentBoundUniformGroup.uid] = undefined;\n            }\n\n            // find a free slot..\n            boundIndex = this._boundUniformsIdsToIndexHash[uniformGroup.uid] = nextIndex;\n            this._boundIndexToUniformsHash[nextIndex] = uniformGroup;\n\n            if (isBufferResource)\n            {\n                bufferSystem.bindBufferRange(uniformGroup.buffer, nextIndex, (uniformGroup as BufferResource).offset);\n            }\n            else\n            {\n                bufferSystem.bindBufferBase(uniformGroup.buffer, nextIndex);\n            }\n        }\n\n        const gl = this._gl;\n\n        const uniformBlockIndex = this._activeProgram._uniformBlockData[name].index;\n\n        if (programData.uniformBlockBindings[index] === boundIndex) return;\n        programData.uniformBlockBindings[index] = boundIndex;\n\n        gl.uniformBlockBinding(programData.program, uniformBlockIndex, boundIndex);\n    }\n\n    private _setProgram(program: GlProgram)\n    {\n        if (this._activeProgram === program) return;\n\n        this._activeProgram = program;\n\n        const programData = this._getProgramData(program);\n\n        this._gl.useProgram(programData.program);\n    }\n\n    /**\n     * @param program - the program to get the data for\n     * @internal\n     * @private\n     */\n    public _getProgramData(program: GlProgram): GlProgramData\n    {\n        return this._programDataHash[program._key] || this._createProgramData(program);\n    }\n\n    private _createProgramData(program: GlProgram): GlProgramData\n    {\n        const key = program._key;\n\n        this._programDataHash[key] = generateProgram(this._gl, program);\n\n        return this._programDataHash[key];\n    }\n\n    public destroy(): void\n    {\n        for (const key of Object.keys(this._programDataHash))\n        {\n            const programData = this._programDataHash[key];\n\n            programData.destroy();\n            this._programDataHash[key] = null;\n        }\n\n        this._programDataHash = null;\n        this._boundUniformsIdsToIndexHash = null;\n    }\n\n    /**\n     * Creates a function that can be executed that will sync the shader as efficiently as possible.\n     * Overridden by the unsafe eval package if you don't want eval used in your project.\n     * @param shader - the shader to generate the sync function for\n     * @param shaderSystem - the shader system to use\n     * @returns - the generated sync function\n     * @ignore\n     */\n    public _generateShaderSync(shader: Shader, shaderSystem: GlShaderSystem): ShaderSyncFunction\n    {\n        return generateShaderSyncCode(shader, shaderSystem);\n    }\n}\n"],"names":[],"mappings":"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"}