{"version":3,"file":"GlProgram.mjs","sources":["../../../../../src/rendering/renderers/gl/shader/GlProgram.ts"],"sourcesContent":["import { createIdFromString } from '../../shared/utils/createIdFromString';\nimport { getMaxFragmentPrecision } from './program/getMaxFragmentPrecision';\nimport { addProgramDefines } from './program/preprocessors/addProgramDefines';\nimport { ensurePrecision } from './program/preprocessors/ensurePrecision';\nimport { insertVersion } from './program/preprocessors/insertVersion';\nimport { setProgramName } from './program/preprocessors/setProgramName';\nimport { stripVersion } from './program/preprocessors/stripVersion';\n\nimport type { TypedArray } from '../../shared/buffer/Buffer';\nimport type { ExtractedAttributeData } from './program/extractAttributesFromGlProgram';\n\nexport interface GlAttributeData\n{\n    type: string;\n    size: number;\n    location: number;\n    name: string;\n}\n\nexport interface GlUniformData\n{\n    name: string;\n    index: number;\n    type: string;\n    size: number;\n    isArray: boolean;\n    value: any;\n}\n\nexport interface GlUniformBlockData\n{\n    index: number;\n    name: string;\n    size: number;\n    value?: TypedArray;\n}\n\n/**\n * The options for the gl program\n * @memberof rendering\n */\nexport interface GlProgramOptions\n{\n    /** The fragment glsl shader source. */\n    fragment: string;\n    /** The vertex glsl shader source. */\n    vertex: string;\n    /** the name of the program, defaults to 'pixi-program' */\n    name?: string;\n    /** the preferred vertex precision for the shader, this may not be used if the device does not support it  */\n    preferredVertexPrecision?: string;\n    /** the preferred fragment precision for the shader, this may not be used if the device does not support it  */\n    preferredFragmentPrecision?: string;\n}\n\nconst processes: Record<string, ((source: string, options: any, isFragment?: boolean) => string)> = {\n    // strips any version headers..\n    stripVersion,\n    // adds precision string if not already present\n    ensurePrecision,\n    // add some defines if WebGL1 to make it more compatible with WebGL2 shaders\n    addProgramDefines,\n    // add the program name to the shader\n    setProgramName,\n    // add the version string to the shader header\n    insertVersion,\n};\n\nconst programCache: Record<string, GlProgram> = Object.create(null);\n\n/**\n * A wrapper for a WebGL Program. You can create one and then pass it to a shader.\n * This will manage the WebGL program that is compiled and uploaded to the GPU.\n *\n * To get the most out of this class, you should be familiar with glsl shaders and how they work.\n * @see https://developer.mozilla.org/en-US/docs/Web/API/WebGLProgram\n * @example\n *\n * // Create a new program\n * const program = new GlProgram({\n *   vertex: '...',\n *   fragment: '...',\n * });\n *\n *\n * There are a few key things that pixi shader will do for you automatically:\n * <br>\n * - If no precision is provided in the shader, it will be injected into the program source for you.\n * This precision will be taken form the options provided, if none is provided,\n * then the program will default to the defaultOptions.\n * <br>\n * - It will inject the program name into the shader source if none is provided.\n * <br>\n *  - It will set the program version to 300 es.\n *\n * For optimal usage and best performance, its best to reuse programs as much as possible.\n * You should use the {@link GlProgram.from} helper function to create programs.\n * @class\n * @memberof rendering\n */\nexport class GlProgram\n{\n    /** The default options used by the program. */\n    public static defaultOptions: Partial<GlProgramOptions> = {\n        preferredVertexPrecision: 'highp',\n        preferredFragmentPrecision: 'mediump',\n    };\n\n    /** the fragment glsl shader source. */\n    public readonly fragment?: string;\n    /** the vertex glsl shader source */\n    public readonly vertex?: string;\n    /**\n     * attribute data extracted from the program once created this happens when the program is used for the first time\n     * @internal\n     * @ignore\n     */\n    public _attributeData: Record<string, ExtractedAttributeData>;\n    /**\n     * uniform data extracted from the program once created this happens when the program is used for the first time\n     * @internal\n     * @ignore\n     */\n    public _uniformData: Record<string, GlUniformData>;\n    /**\n     * uniform data extracted from the program once created this happens when the program is used for the first time\n     * @internal\n     * @ignore\n     */\n    public _uniformBlockData: Record<string, GlUniformBlockData>;\n    /** details on how to use this program with transform feedback */\n    public transformFeedbackVaryings?: {names: string[], bufferMode: 'separate' | 'interleaved'};\n    /**\n     * the key that identifies the program via its source vertex + fragment\n     * @internal\n     * @ignore\n     */\n    public readonly _key: number;\n\n    /**\n     * Creates a shiny new GlProgram. Used by WebGL renderer.\n     * @param options - The options for the program.\n     */\n    constructor(options: GlProgramOptions)\n    {\n        options = { ...GlProgram.defaultOptions, ...options };\n\n        // only need to check one as they both need to be the same or\n        // errors ensue!\n        const isES300 = options.fragment.indexOf('#version 300 es') !== -1;\n\n        const preprocessorOptions = {\n            stripVersion: isES300,\n            ensurePrecision: {\n                requestedFragmentPrecision: options.preferredFragmentPrecision,\n                requestedVertexPrecision: options.preferredVertexPrecision,\n                maxSupportedVertexPrecision: 'highp',\n                maxSupportedFragmentPrecision: getMaxFragmentPrecision(),\n            },\n            setProgramName: {\n                name: options.name,\n            },\n            addProgramDefines: isES300,\n            insertVersion: isES300\n        };\n\n        let fragment = options.fragment;\n        let vertex = options.vertex;\n\n        Object.keys(processes).forEach((processKey) =>\n        {\n            const processOptions = preprocessorOptions[processKey as keyof typeof preprocessorOptions];\n\n            fragment = processes[processKey](fragment, processOptions, true);\n            vertex = processes[processKey](vertex, processOptions, false);\n        });\n\n        this.fragment = fragment;\n        this.vertex = vertex;\n\n        this._key = createIdFromString(`${this.vertex}:${this.fragment}`, 'gl-program');\n    }\n\n    /** destroys the program */\n    public destroy(): void\n    {\n        (this.fragment as null) = null;\n        (this.vertex as null) = null;\n\n        this._attributeData = null;\n        this._uniformData = null;\n        this._uniformBlockData = null;\n\n        this.transformFeedbackVaryings = null;\n    }\n\n    /**\n     * Helper function that creates a program for a given source.\n     * It will check the program cache if the program has already been created.\n     * If it has that one will be returned, if not a new one will be created and cached.\n     * @param options - The options for the program.\n     * @returns A program using the same source\n     */\n    public static from(options: GlProgramOptions): GlProgram\n    {\n        const key = `${options.vertex}:${options.fragment}`;\n\n        if (!programCache[key])\n        {\n            programCache[key] = new GlProgram(options);\n        }\n\n        return programCache[key];\n    }\n}\n"],"names":[],"mappings":"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"}