{"version":3,"file":"TransformFeedbackSystem.mjs","sources":["../../src/transformFeedback/TransformFeedbackSystem.ts"],"sourcesContent":["import { extensions, ExtensionType } from '@pixi/extensions';\n\nimport type { DRAW_MODES } from '@pixi/constants';\nimport type { ExtensionMetadata } from '@pixi/extensions';\nimport type { IRenderingContext } from '../IRenderer';\nimport type { Renderer } from '../Renderer';\nimport type { Shader } from '../shader/Shader';\nimport type { ISystem } from '../system/ISystem';\nimport type { TransformFeedback } from './TransformFeedback';\n\n/**\n * TransformFeedbackSystem provides TransformFeedback of WebGL2\n * https://developer.mozilla.org/en-US/docs/Web/API/WebGLTransformFeedback\n *\n * For example, you can use TransformFeedbackSystem to implement GPU Particle or\n * general purpose computing on GPU (aka GPGPU).\n *\n * It also manages a lifetime of GLTransformFeedback object\n * @memberof PIXI\n */\nexport class TransformFeedbackSystem implements ISystem\n{\n    /** @ignore */\n    static extension: ExtensionMetadata = {\n        type:  ExtensionType.RendererSystem,\n        name: 'transformFeedback',\n    };\n\n    CONTEXT_UID: number;\n    gl: IRenderingContext;\n\n    private renderer: Renderer;\n\n    /**\n     * @param renderer - The renderer this System works for.\n     */\n    constructor(renderer: Renderer)\n    {\n        this.renderer = renderer;\n    }\n\n    /** Sets up the renderer context and necessary buffers. */\n    protected contextChange(): void\n    {\n        this.gl = this.renderer.gl;\n\n        // TODO fill out...\n        this.CONTEXT_UID = this.renderer.CONTEXT_UID;\n    }\n\n    /**\n     * Bind TransformFeedback and buffers\n     * @param transformFeedback - TransformFeedback to bind\n     */\n    bind(transformFeedback: TransformFeedback)\n    {\n        const { gl, CONTEXT_UID } = this;\n\n        const glTransformFeedback = transformFeedback._glTransformFeedbacks[CONTEXT_UID]\n          || this.createGLTransformFeedback(transformFeedback);\n\n        gl.bindTransformFeedback(gl.TRANSFORM_FEEDBACK, glTransformFeedback);\n    }\n\n    /** Unbind TransformFeedback */\n    unbind()\n    {\n        const { gl } = this;\n\n        gl.bindTransformFeedback(gl.TRANSFORM_FEEDBACK, null);\n    }\n\n    /**\n     * Begin TransformFeedback\n     * @param drawMode - DrawMode for TransformFeedback\n     * @param shader - A Shader used by TransformFeedback. Current bound shader will be used if not provided.\n     */\n    beginTransformFeedback(drawMode: DRAW_MODES, shader?: Shader)\n    {\n        const { gl, renderer } = this;\n\n        if (shader)\n        {\n            renderer.shader.bind(shader);\n        }\n\n        gl.beginTransformFeedback(drawMode);\n    }\n\n    /** End TransformFeedback */\n    endTransformFeedback()\n    {\n        const { gl } = this;\n\n        gl.endTransformFeedback();\n    }\n\n    /**\n     * Create TransformFeedback and bind buffers\n     * @param tf - TransformFeedback\n     * @returns WebGLTransformFeedback\n     */\n    protected createGLTransformFeedback(tf: TransformFeedback)\n    {\n        const { gl, renderer, CONTEXT_UID } = this;\n\n        const glTransformFeedback = gl.createTransformFeedback();\n\n        tf._glTransformFeedbacks[CONTEXT_UID] = glTransformFeedback;\n        gl.bindTransformFeedback(gl.TRANSFORM_FEEDBACK, glTransformFeedback);\n        for (let i = 0; i < tf.buffers.length; i++)\n        {\n            const buffer = tf.buffers[i];\n\n            if (!buffer) continue;\n\n            renderer.buffer.update(buffer);\n            buffer._glBuffers[CONTEXT_UID].refCount++;\n\n            gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, i, buffer._glBuffers[CONTEXT_UID].buffer || null);\n        }\n        gl.bindTransformFeedback(gl.TRANSFORM_FEEDBACK, null);\n\n        tf.disposeRunner.add(this);\n\n        return glTransformFeedback;\n    }\n\n    /**\n     * Disposes TransfromFeedback\n     * @param {PIXI.TransformFeedback} tf - TransformFeedback\n     * @param {boolean} [contextLost=false] - If context was lost, we suppress delete TransformFeedback\n     */\n    disposeTransformFeedback(tf: TransformFeedback, contextLost?: boolean): void\n    {\n        const glTF = tf._glTransformFeedbacks[this.CONTEXT_UID];\n        const gl = this.gl;\n\n        tf.disposeRunner.remove(this);\n\n        const bufferSystem = this.renderer.buffer;\n\n        // bufferSystem may have already been destroyed..\n        // if this is the case, there is no need to destroy the geometry buffers...\n        // they already have been!\n        if (bufferSystem)\n        {\n            for (let i = 0; i < tf.buffers.length; i++)\n            {\n                const buffer = tf.buffers[i];\n\n                if (!buffer) continue;\n\n                const buf = buffer._glBuffers[this.CONTEXT_UID];\n\n                // my be null as context may have changed right before the dispose is called\n                if (buf)\n                {\n                    buf.refCount--;\n                    if (buf.refCount === 0 && !contextLost)\n                    {\n                        bufferSystem.dispose(buffer, contextLost);\n                    }\n                }\n            }\n        }\n\n        if (!glTF)\n        {\n            return;\n        }\n\n        if (!contextLost)\n        {\n            gl.deleteTransformFeedback(glTF);\n        }\n\n        delete tf._glTransformFeedbacks[this.CONTEXT_UID];\n    }\n\n    destroy(): void\n    {\n        // @TODO: Destroy managed TransformFeedbacks\n        this.renderer = null;\n    }\n}\n\nextensions.add(TransformFeedbackSystem);\n"],"names":[],"mappings":";AAoBO,MAAM,wBACb;AAAA;AAAA;AAAA;AAAA,EAeI,YAAY,UACZ;AACI,SAAK,WAAW;AAAA,EACpB;AAAA;AAAA,EAGU,gBACV;AACI,SAAK,KAAK,KAAK,SAAS,IAGxB,KAAK,cAAc,KAAK,SAAS;AAAA,EACrC;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,KAAK,mBACL;AACI,UAAM,EAAE,IAAI,gBAAgB,MAEtB,sBAAsB,kBAAkB,sBAAsB,WAAW,KAC1E,KAAK,0BAA0B,iBAAiB;AAElD,OAAA,sBAAsB,GAAG,oBAAoB,mBAAmB;AAAA,EACvE;AAAA;AAAA,EAGA,SACA;AACU,UAAA,EAAE,GAAO,IAAA;AAEZ,OAAA,sBAAsB,GAAG,oBAAoB,IAAI;AAAA,EACxD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,uBAAuB,UAAsB,QAC7C;AACU,UAAA,EAAE,IAAI,SAAa,IAAA;AAErB,cAEA,SAAS,OAAO,KAAK,MAAM,GAG/B,GAAG,uBAAuB,QAAQ;AAAA,EACtC;AAAA;AAAA,EAGA,uBACA;AACU,UAAA,EAAE,GAAO,IAAA;AAEf,OAAG,qBAAqB;AAAA,EAC5B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOU,0BAA0B,IACpC;AACU,UAAA,EAAE,IAAI,UAAU,YAAA,IAAgB,MAEhC,sBAAsB,GAAG;AAE5B,OAAA,sBAAsB,WAAW,IAAI,qBACxC,GAAG,sBAAsB,GAAG,oBAAoB,mBAAmB;AACnE,aAAS,IAAI,GAAG,IAAI,GAAG,QAAQ,QAAQ,KACvC;AACU,YAAA,SAAS,GAAG,QAAQ,CAAC;AAEtB,iBAEL,SAAS,OAAO,OAAO,MAAM,GAC7B,OAAO,WAAW,WAAW,EAAE,YAE/B,GAAG,eAAe,GAAG,2BAA2B,GAAG,OAAO,WAAW,WAAW,EAAE,UAAU,IAAI;AAAA,IACpG;AACG,WAAA,GAAA,sBAAsB,GAAG,oBAAoB,IAAI,GAEpD,GAAG,cAAc,IAAI,IAAI,GAElB;AAAA,EACX;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,yBAAyB,IAAuB,aAChD;AACI,UAAM,OAAO,GAAG,sBAAsB,KAAK,WAAW,GAChD,KAAK,KAAK;AAEb,OAAA,cAAc,OAAO,IAAI;AAEtB,UAAA,eAAe,KAAK,SAAS;AAK/B,QAAA;AAEA,eAAS,IAAI,GAAG,IAAI,GAAG,QAAQ,QAAQ,KACvC;AACU,cAAA,SAAS,GAAG,QAAQ,CAAC;AAE3B,YAAI,CAAC;AAAQ;AAEb,cAAM,MAAM,OAAO,WAAW,KAAK,WAAW;AAG1C,gBAEA,IAAI,YACA,IAAI,aAAa,KAAK,CAAC,eAEvB,aAAa,QAAQ,QAAQ,WAAW;AAAA,MAGpD;AAGC,aAKA,eAED,GAAG,wBAAwB,IAAI,GAGnC,OAAO,GAAG,sBAAsB,KAAK,WAAW;AAAA,EACpD;AAAA,EAEA,UACA;AAEI,SAAK,WAAW;AAAA,EACpB;AACJ;AArKa,wBAGF,YAA+B;AAAA,EAClC,MAAO,cAAc;AAAA,EACrB,MAAM;AACV;AAiKJ,WAAW,IAAI,uBAAuB;"}