{"version":3,"file":"BufferSystem.mjs","sources":["../../src/geometry/BufferSystem.ts"],"sourcesContent":["import { extensions, ExtensionType } from 'pixijs/extensions';\nimport { GLBuffer } from './GLBuffer';\n\nimport type { BUFFER_TYPE } from 'pixijs/constants';\nimport type { ExtensionMetadata } from 'pixijs/extensions';\nimport type { IRenderingContext } from '../IRenderer';\nimport type { Renderer } from '../Renderer';\nimport type { ISystem } from '../system/ISystem';\nimport type { Buffer } from './Buffer';\n\n/**\n * System plugin to the renderer to manage buffers.\n *\n * WebGL uses Buffers as a way to store objects to the GPU.\n * This system makes working with them a lot easier.\n *\n * Buffers are used in three main places in WebGL\n * - geometry information\n * - Uniform information (via uniform buffer objects - a WebGL 2 only feature)\n * - Transform feedback information. (WebGL 2 only feature)\n *\n * This system will handle the binding of buffers to the GPU as well as uploading\n * them. With this system, you never need to work directly with GPU buffers, but instead work with\n * the PIXI.Buffer class.\n * @class\n * @memberof PIXI\n */\nexport class BufferSystem implements ISystem\n{\n    /** @ignore */\n    static extension: ExtensionMetadata = {\n        type: ExtensionType.RendererSystem,\n        name: 'buffer',\n    };\n\n    CONTEXT_UID: number;\n    gl: IRenderingContext;\n\n    /** Cache for all buffers by id, used in case renderer gets destroyed or for profiling */\n    readonly managedBuffers: {[key: number]: Buffer};\n\n    /** Cache keeping track of the base bound buffer bases */\n    readonly boundBufferBases: {[key: number]: Buffer};\n\n    private renderer: Renderer;\n\n    /**\n     * @param {PIXI.Renderer} renderer - The renderer this System works for.\n     */\n    constructor(renderer: Renderer)\n    {\n        this.renderer = renderer;\n        this.managedBuffers = {};\n        this.boundBufferBases = {};\n    }\n\n    /**\n     * @ignore\n     */\n    destroy(): void\n    {\n        this.renderer = null;\n    }\n\n    /** Sets up the renderer context and necessary buffers. */\n    protected contextChange(): void\n    {\n        this.disposeAll(true);\n\n        this.gl = this.renderer.gl;\n\n        // TODO fill out...\n        this.CONTEXT_UID = this.renderer.CONTEXT_UID;\n    }\n\n    /**\n     * This binds specified buffer. On first run, it will create the webGL buffers for the context too\n     * @param buffer - the buffer to bind to the renderer\n     */\n    bind(buffer: Buffer): void\n    {\n        const { gl, CONTEXT_UID } = this;\n\n        const glBuffer = buffer._glBuffers[CONTEXT_UID] || this.createGLBuffer(buffer);\n\n        gl.bindBuffer(buffer.type, glBuffer.buffer);\n    }\n\n    unbind(type: BUFFER_TYPE): void\n    {\n        const { gl } = this;\n\n        gl.bindBuffer(type, null);\n    }\n\n    /**\n     * Binds an uniform buffer to at the given index.\n     *\n     * A cache is used so a buffer will not be bound again if already bound.\n     * @param buffer - the buffer to bind\n     * @param index - the base index to bind it to.\n     */\n    bindBufferBase(buffer: Buffer, index: number): void\n    {\n        const { gl, CONTEXT_UID } = this;\n\n        if (this.boundBufferBases[index] !== buffer)\n        {\n            const glBuffer = buffer._glBuffers[CONTEXT_UID] || this.createGLBuffer(buffer);\n\n            this.boundBufferBases[index] = buffer;\n\n            gl.bindBufferBase(gl.UNIFORM_BUFFER, index, glBuffer.buffer);\n        }\n    }\n\n    /**\n     * Binds a buffer whilst also binding its range.\n     * This will make the buffer start from the offset supplied rather than 0 when it is read.\n     * @param buffer - the buffer to bind\n     * @param index - the base index to bind at, defaults to 0\n     * @param offset - the offset to bind at (this is blocks of 256). 0 = 0, 1 = 256, 2 = 512 etc\n     */\n    bindBufferRange(buffer: Buffer, index?: number, offset?: number): void\n    {\n        const { gl, CONTEXT_UID } = this;\n\n        offset = offset || 0;\n\n        const glBuffer = buffer._glBuffers[CONTEXT_UID] || this.createGLBuffer(buffer);\n\n        gl.bindBufferRange(gl.UNIFORM_BUFFER, index || 0, glBuffer.buffer, offset * 256, 256);\n    }\n\n    /**\n     * Will ensure the data in the buffer is uploaded to the GPU.\n     * @param {PIXI.Buffer} buffer - the buffer to update\n     */\n    update(buffer: Buffer): void\n    {\n        const { gl, CONTEXT_UID } = this;\n\n        const glBuffer = buffer._glBuffers[CONTEXT_UID] || this.createGLBuffer(buffer);\n\n        if (buffer._updateID === glBuffer.updateID)\n        {\n            return;\n        }\n\n        glBuffer.updateID = buffer._updateID;\n\n        gl.bindBuffer(buffer.type, glBuffer.buffer);\n\n        if (glBuffer.byteLength >= buffer.data.byteLength)\n        {\n            // offset is always zero for now!\n            gl.bufferSubData(buffer.type, 0, buffer.data);\n        }\n        else\n        {\n            const drawType = buffer.static ? gl.STATIC_DRAW : gl.DYNAMIC_DRAW;\n\n            glBuffer.byteLength = buffer.data.byteLength;\n            gl.bufferData(buffer.type, buffer.data, drawType);\n        }\n    }\n\n    /**\n     * Disposes buffer\n     * @param {PIXI.Buffer} buffer - buffer with data\n     * @param {boolean} [contextLost=false] - If context was lost, we suppress deleteVertexArray\n     */\n    dispose(buffer: Buffer, contextLost?: boolean): void\n    {\n        if (!this.managedBuffers[buffer.id])\n        {\n            return;\n        }\n\n        delete this.managedBuffers[buffer.id];\n\n        const glBuffer = buffer._glBuffers[this.CONTEXT_UID];\n        const gl = this.gl;\n\n        buffer.disposeRunner.remove(this);\n\n        if (!glBuffer)\n        {\n            return;\n        }\n\n        if (!contextLost)\n        {\n            gl.deleteBuffer(glBuffer.buffer);\n        }\n\n        delete buffer._glBuffers[this.CONTEXT_UID];\n    }\n\n    /**\n     * dispose all WebGL resources of all managed buffers\n     * @param {boolean} [contextLost=false] - If context was lost, we suppress `gl.delete` calls\n     */\n    disposeAll(contextLost?: boolean): void\n    {\n        const all: Array<any> = Object.keys(this.managedBuffers);\n\n        for (let i = 0; i < all.length; i++)\n        {\n            this.dispose(this.managedBuffers[all[i]], contextLost);\n        }\n    }\n\n    /**\n     * creates and attaches a GLBuffer object tied to the current context.\n     * @param buffer\n     * @protected\n     */\n    protected createGLBuffer(buffer: Buffer): GLBuffer\n    {\n        const { CONTEXT_UID, gl } = this;\n\n        buffer._glBuffers[CONTEXT_UID] = new GLBuffer(gl.createBuffer());\n\n        this.managedBuffers[buffer.id] = buffer;\n\n        buffer.disposeRunner.add(this);\n\n        return buffer._glBuffers[CONTEXT_UID];\n    }\n}\n\nextensions.add(BufferSystem);\n"],"names":[],"mappings":"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"}