{"version":3,"file":"generateUniformBufferSync.mjs","sources":["../../../src/shader/utils/generateUniformBufferSync.ts"],"sourcesContent":["import { mapSize } from '../utils';\nimport { uniformParsers } from './uniformParsers';\n\nimport type { Dict } from '@pixi/utils';\nimport type { Buffer } from '../../geometry/Buffer';\nimport type { Renderer } from '../../Renderer';\nimport type { IUniformData } from '../Program';\nimport type { UniformGroup } from '../UniformGroup';\n\nexport type UniformsSyncCallback = (...args: any[]) => void;\n\nfunction uboUpdate(_ud: any, _uv: any, _renderer: Renderer, _syncData: any, buffer: Buffer): void\n{\n    _renderer.buffer.update(buffer);\n}\n\n// cv = CachedValue\n// v = value\n// ud = uniformData\n// uv = uniformValue\n// l = location\nconst UBO_TO_SINGLE_SETTERS: Dict<string> = {\n    float: `\n        data[offset] = v;\n    `,\n    vec2: `\n        data[offset] = v[0];\n        data[offset+1] = v[1];\n    `,\n    vec3: `\n        data[offset] = v[0];\n        data[offset+1] = v[1];\n        data[offset+2] = v[2];\n\n    `,\n    vec4: `\n        data[offset] = v[0];\n        data[offset+1] = v[1];\n        data[offset+2] = v[2];\n        data[offset+3] = v[3];\n    `,\n    mat2: `\n        data[offset] = v[0];\n        data[offset+1] = v[1];\n\n        data[offset+4] = v[2];\n        data[offset+5] = v[3];\n    `,\n    mat3: `\n        data[offset] = v[0];\n        data[offset+1] = v[1];\n        data[offset+2] = v[2];\n\n        data[offset + 4] = v[3];\n        data[offset + 5] = v[4];\n        data[offset + 6] = v[5];\n\n        data[offset + 8] = v[6];\n        data[offset + 9] = v[7];\n        data[offset + 10] = v[8];\n    `,\n    mat4: `\n        for(var i = 0; i < 16; i++)\n        {\n            data[offset + i] = v[i];\n        }\n    `\n};\n\nconst GLSL_TO_STD40_SIZE: Dict<number> = {\n    float:  4,\n    vec2:   8,\n    vec3:   12,\n    vec4:   16,\n\n    int:      4,\n    ivec2:    8,\n    ivec3:    12,\n    ivec4:    16,\n\n    uint:     4,\n    uvec2:    8,\n    uvec3:    12,\n    uvec4:    16,\n\n    bool:     4,\n    bvec2:    8,\n    bvec3:    12,\n    bvec4:    16,\n\n    mat2:     16 * 2,\n    mat3:     16 * 3,\n    mat4:     16 * 4,\n};\n\ninterface UBOElement\n{\n    data: IUniformData\n    offset: number,\n    dataLen: number,\n    dirty: number\n}\n\n/**\n * logic originally from here: https://github.com/sketchpunk/FunWithWebGL2/blob/master/lesson_022/Shaders.js\n * rewrote it, but this was a great starting point to get a solid understanding of whats going on :)\n * @ignore\n * @param uniformData\n */\nexport function createUBOElements(uniformData: IUniformData[]): {uboElements: UBOElement[], size: number}\n{\n    const uboElements: UBOElement[] = uniformData.map((data: IUniformData) =>\n        ({\n            data,\n            offset: 0,\n            dataLen: 0,\n            dirty: 0\n        }));\n\n    let size = 0;\n    let chunkSize = 0;\n    let offset = 0;\n\n    for (let i = 0; i < uboElements.length; i++)\n    {\n        const uboElement = uboElements[i];\n\n        size = GLSL_TO_STD40_SIZE[uboElement.data.type];\n\n        if (uboElement.data.size > 1)\n        {\n            size = Math.max(size, 16) * uboElement.data.size;\n        }\n\n        uboElement.dataLen = size;\n\n        // add some size offset..\n        // must align to the nearest 16 bytes or internally nearest round size\n\n        if (chunkSize % size !== 0 && chunkSize < 16)\n        {\n            // diff required to line up..\n            const lineUpValue = (chunkSize % size) % 16;\n\n            chunkSize += lineUpValue;\n            offset += lineUpValue;\n        }\n\n        if ((chunkSize + size) > 16)\n        {\n            offset = Math.ceil(offset / 16) * 16;\n            uboElement.offset = offset;\n            offset += size;\n            chunkSize = size;\n        }\n        else\n        {\n            uboElement.offset = offset;\n            chunkSize += size;\n            offset += size;\n        }\n    }\n\n    offset = Math.ceil(offset / 16) * 16;\n\n    return { uboElements, size: offset };\n}\n\nexport function getUBOData(uniforms: Dict<any>, uniformData: Dict<any>): any[]\n{\n    const usedUniformDatas = [];\n\n    // build..\n    for (const i in uniforms)\n    {\n        if (uniformData[i])\n        {\n            usedUniformDatas.push(uniformData[i]);\n        }\n    }\n\n    // sort them out by index!\n    usedUniformDatas.sort((a, b) => a.index - b.index);\n\n    return usedUniformDatas;\n}\n\nexport function generateUniformBufferSync(\n    group: UniformGroup,\n    uniformData: Dict<any>\n): {size: number, syncFunc: UniformsSyncCallback}\n{\n    if (!group.autoManage)\n    {\n        // if the group is nott automatically managed, we don't need to generate a special function for it...\n        return { size: 0, syncFunc: uboUpdate };\n    }\n\n    const usedUniformDatas = getUBOData(group.uniforms, uniformData);\n\n    const { uboElements, size } = createUBOElements(usedUniformDatas);\n\n    const funcFragments = [`\n    var v = null;\n    var v2 = null;\n    var cv = null;\n    var t = 0;\n    var gl = renderer.gl\n    var index = 0;\n    var data = buffer.data;\n    `];\n\n    for (let i = 0; i < uboElements.length; i++)\n    {\n        const uboElement = uboElements[i];\n        const uniform = group.uniforms[uboElement.data.name];\n\n        const name = uboElement.data.name;\n\n        let parsed = false;\n\n        for (let j = 0; j < uniformParsers.length; j++)\n        {\n            const uniformParser = uniformParsers[j];\n\n            if (uniformParser.codeUbo && uniformParser.test(uboElement.data, uniform))\n            {\n                funcFragments.push(\n                    `offset = ${uboElement.offset / 4};`,\n                    uniformParsers[j].codeUbo(uboElement.data.name, uniform));\n                parsed = true;\n\n                break;\n            }\n        }\n\n        if (!parsed)\n        {\n            if (uboElement.data.size > 1)\n            {\n                const size = mapSize(uboElement.data.type);\n                const rowSize = Math.max(GLSL_TO_STD40_SIZE[uboElement.data.type] / 16, 1);\n                const elementSize = size / rowSize;\n                const remainder = (4 - (elementSize % 4)) % 4;\n\n                funcFragments.push(`\n                cv = ud.${name}.value;\n                v = uv.${name};\n                offset = ${uboElement.offset / 4};\n\n                t = 0;\n\n                for(var i=0; i < ${uboElement.data.size * rowSize}; i++)\n                {\n                    for(var j = 0; j < ${elementSize}; j++)\n                    {\n                        data[offset++] = v[t++];\n                    }\n                    offset += ${remainder};\n                }\n\n                `);\n            }\n            else\n            {\n                const template = UBO_TO_SINGLE_SETTERS[uboElement.data.type];\n\n                funcFragments.push(`\n                cv = ud.${name}.value;\n                v = uv.${name};\n                offset = ${uboElement.offset / 4};\n                ${template};\n                `);\n            }\n        }\n    }\n\n    funcFragments.push(`\n       renderer.buffer.update(buffer);\n    `);\n\n    return {\n        size,\n        // eslint-disable-next-line no-new-func\n        syncFunc: new Function(\n            'ud',\n            'uv',\n            'renderer',\n            'syncData',\n            'buffer',\n            funcFragments.join('\\n')\n        ) as UniformsSyncCallback\n    };\n}\n"],"names":["size"],"mappings":"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"}