UNPKG

14.4 kBSource Map (JSON)View Raw
1{"version":3,"file":"ShaderSystem.mjs","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":[],"mappings":"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"}
\No newline at end of file