1 | {"version":3,"file":"ShaderSystem.js","sources":["../../src/shader/ShaderSystem.ts"],"sourcesContent":["import { extensions, ExtensionType } from '@pixi/extensions';\nimport { generateUniformsSync, unsafeEvalSupported } from './utils';\nimport { generateProgram } from './utils/generateProgram';\nimport { generateUniformBufferSync } from './utils/generateUniformBufferSync';\n\nimport type { ExtensionMetadata } from '@pixi/extensions';\nimport type { Dict } from '@pixi/utils';\nimport type { IRenderingContext } from '../IRenderer';\nimport type { Renderer } from '../Renderer';\nimport type { ISystem } from '../system/ISystem';\nimport type { GLProgram } from './GLProgram';\nimport type { Program } from './Program';\nimport type { Shader } from './Shader';\nimport type { UniformGroup } from './UniformGroup';\nimport type { UniformsSyncCallback } from './utils';\n\nlet UID = 0;\n// default sync data so we don't create a new one each time!\nconst defaultSyncData = { textureCount: 0, uboCount: 0 };\n\n/**\n * System plugin to the renderer to manage shaders.\n * @memberof PIXI\n */\nexport class ShaderSystem implements ISystem\n{\n /** @ignore */\n static extension: ExtensionMetadata = {\n type: ExtensionType.RendererSystem,\n name: 'shader',\n };\n\n /**\n * The current WebGL rendering context.\n * @member {WebGLRenderingContext}\n */\n protected gl: IRenderingContext;\n\n public shader: Shader;\n public program: Program;\n public id: number;\n public destroyed = false;\n\n /** Cache to holds the generated functions. Stored against UniformObjects unique signature. */\n private cache: Dict<UniformsSyncCallback>;\n private _uboCache: Dict<{size: number, syncFunc: UniformsSyncCallback}>;\n private renderer: Renderer;\n\n /** @param renderer - The renderer this System works for. */\n constructor(renderer: Renderer)\n {\n this.renderer = renderer;\n\n // Validation check that this environment support `new Function`\n this.systemCheck();\n\n this.gl = null;\n\n this.shader = null;\n this.program = null;\n\n this.cache = {};\n this._uboCache = {};\n\n this.id = UID++;\n }\n\n /**\n * Overrideable function by `@pixi/unsafe-eval` to silence\n * throwing an error if platform doesn't support unsafe-evals.\n * @private\n */\n private systemCheck(): void\n {\n if (!unsafeEvalSupported())\n {\n throw new Error('Current environment does not allow unsafe-eval, '\n + 'please use @pixi/unsafe-eval module to enable support.');\n }\n }\n\n protected contextChange(gl: IRenderingContext): void\n {\n this.gl = gl;\n this.reset();\n }\n\n /**\n * Changes the current shader to the one given in parameter.\n * @param shader - the new shader\n * @param dontSync - false if the shader should automatically sync its uniforms.\n * @returns the glProgram that belongs to the shader.\n */\n bind(shader: Shader, dontSync?: boolean): GLProgram\n {\n shader.disposeRunner.add(this);\n\n shader.uniforms.globals = this.renderer.globalUniforms;\n\n const program = shader.program;\n const glProgram = program.glPrograms[this.renderer.CONTEXT_UID] || this.generateProgram(shader);\n\n this.shader = shader;\n\n // TODO - some current Pixi plugins bypass this.. so it not safe to use yet..\n if (this.program !== program)\n {\n this.program = program;\n this.gl.useProgram(glProgram.program);\n }\n\n if (!dontSync)\n {\n defaultSyncData.textureCount = 0;\n defaultSyncData.uboCount = 0;\n\n this.syncUniformGroup(shader.uniformGroup, defaultSyncData);\n }\n\n return glProgram;\n }\n\n /**\n * Uploads the uniforms values to the currently bound shader.\n * @param uniforms - the uniforms values that be applied to the current shader\n */\n setUniforms(uniforms: Dict<any>): void\n {\n const shader = this.shader.program;\n const glProgram = shader.glPrograms[this.renderer.CONTEXT_UID];\n\n shader.syncUniforms(glProgram.uniformData, uniforms, this.renderer);\n }\n\n /* eslint-disable @typescript-eslint/explicit-module-boundary-types */\n /**\n * Syncs uniforms on the group\n * @param group - the uniform group to sync\n * @param syncData - this is data that is passed to the sync function and any nested sync functions\n */\n syncUniformGroup(group: UniformGroup, syncData?: any): void\n {\n const glProgram = this.getGlProgram();\n\n if (!group.static || group.dirtyId !== glProgram.uniformDirtyGroups[group.id])\n {\n glProgram.uniformDirtyGroups[group.id] = group.dirtyId;\n\n this.syncUniforms(group, glProgram, syncData);\n }\n }\n\n /**\n * Overrideable by the @pixi/unsafe-eval package to use static syncUniforms instead.\n * @param group\n * @param glProgram\n * @param syncData\n */\n syncUniforms(group: UniformGroup, glProgram: GLProgram, syncData: any): void\n {\n const syncFunc = group.syncUniforms[this.shader.program.id] || this.createSyncGroups(group);\n\n syncFunc(glProgram.uniformData, group.uniforms, this.renderer, syncData);\n }\n\n createSyncGroups(group: UniformGroup): UniformsSyncCallback\n {\n const id = this.getSignature(group, this.shader.program.uniformData, 'u');\n\n if (!this.cache[id])\n {\n this.cache[id] = generateUniformsSync(group, this.shader.program.uniformData);\n }\n\n group.syncUniforms[this.shader.program.id] = this.cache[id];\n\n return group.syncUniforms[this.shader.program.id];\n }\n\n /**\n * Syncs uniform buffers\n * @param group - the uniform buffer group to sync\n * @param name - the name of the uniform buffer\n */\n syncUniformBufferGroup(group: UniformGroup, name?: string)\n {\n const glProgram = this.getGlProgram();\n\n if (!group.static || group.dirtyId !== 0 || !glProgram.uniformGroups[group.id])\n {\n group.dirtyId = 0;\n\n const syncFunc = glProgram.uniformGroups[group.id]\n || this.createSyncBufferGroup(group, glProgram, name);\n\n // TODO wrap update in a cache??\n group.buffer.update();\n\n syncFunc(glProgram.uniformData,\n group.uniforms,\n this.renderer,\n defaultSyncData,\n group.buffer\n );\n }\n\n this.renderer.buffer.bindBufferBase(group.buffer, glProgram.uniformBufferBindings[name]);\n }\n\n /**\n * Will create a function that uploads a uniform buffer using the STD140 standard.\n * The upload function will then be cached for future calls\n * If a group is manually managed, then a simple upload function is generated\n * @param group - the uniform buffer group to sync\n * @param glProgram - the gl program to attach the uniform bindings to\n * @param name - the name of the uniform buffer (must exist on the shader)\n */\n protected createSyncBufferGroup(group: UniformGroup, glProgram: GLProgram, name: string): UniformsSyncCallback\n {\n const { gl } = this.renderer;\n\n this.renderer.buffer.bind(group.buffer);\n\n // bind them...\n const uniformBlockIndex = this.gl.getUniformBlockIndex(glProgram.program, name);\n\n glProgram.uniformBufferBindings[name] = this.shader.uniformBindCount;\n\n gl.uniformBlockBinding(glProgram.program, uniformBlockIndex, this.shader.uniformBindCount);\n\n this.shader.uniformBindCount++;\n\n const id = this.getSignature(group, this.shader.program.uniformData, 'ubo');\n\n let uboData = this._uboCache[id];\n\n if (!uboData)\n {\n uboData = this._uboCache[id] = generateUniformBufferSync(group, this.shader.program.uniformData);\n }\n\n if (group.autoManage)\n {\n const data = new Float32Array(uboData.size / 4);\n\n group.buffer.update(data);\n }\n\n glProgram.uniformGroups[group.id] = uboData.syncFunc;\n\n return glProgram.uniformGroups[group.id];\n }\n\n /**\n * Takes a uniform group and data and generates a unique signature for them.\n * @param group - The uniform group to get signature of\n * @param group.uniforms\n * @param uniformData - Uniform information generated by the shader\n * @param preFix\n * @returns Unique signature of the uniform group\n */\n private getSignature(group: {uniforms: Dict<any>}, uniformData: Dict<any>, preFix: string): string\n {\n const uniforms = group.uniforms;\n\n const strings = [`${preFix}-`];\n\n for (const i in uniforms)\n {\n strings.push(i);\n\n if (uniformData[i])\n {\n strings.push(uniformData[i].type);\n }\n }\n\n return strings.join('-');\n }\n\n /**\n * Returns the underlying GLShade rof the currently bound shader.\n *\n * This can be handy for when you to have a little more control over the setting of your uniforms.\n * @returns The glProgram for the currently bound Shader for this context\n */\n getGlProgram(): GLProgram\n {\n if (this.shader)\n {\n return this.shader.program.glPrograms[this.renderer.CONTEXT_UID];\n }\n\n return null;\n }\n\n /**\n * Generates a glProgram version of the Shader provided.\n * @param shader - The shader that the glProgram will be based on.\n * @returns A shiny new glProgram!\n */\n generateProgram(shader: Shader): GLProgram\n {\n const gl = this.gl;\n const program = shader.program;\n\n const glProgram = generateProgram(gl, program);\n\n program.glPrograms[this.renderer.CONTEXT_UID] = glProgram;\n\n return glProgram;\n }\n\n /** Resets ShaderSystem state, does not affect WebGL state. */\n reset(): void\n {\n this.program = null;\n this.shader = null;\n }\n\n /**\n * Disposes shader.\n * If disposing one equals with current shader, set current as null.\n * @param shader - Shader object\n */\n disposeShader(shader: Shader): void\n {\n if (this.shader === shader)\n {\n this.shader = null;\n }\n }\n\n /** Destroys this System and removes all its textures. */\n destroy(): void\n {\n this.renderer = null;\n // TODO implement destroy method for ShaderSystem\n this.destroyed = true;\n }\n}\n\nextensions.add(ShaderSystem);\n"],"names":["unsafeEvalSupported","generateUniformsSync","generateUniformBufferSync","generateProgram","ExtensionType","extensions"],"mappings":"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"} |