{"version":3,"file":"GraphicsPipe.mjs","sources":["../../../../src/scene/graphics/shared/GraphicsPipe.ts"],"sourcesContent":["import { ExtensionType } from '../../../extensions/Extensions';\nimport { State } from '../../../rendering/renderers/shared/state/State';\nimport { type Renderer } from '../../../rendering/renderers/types';\nimport { GCManagedHash } from '../../../utils/data/GCManagedHash';\nimport { BigPool } from '../../../utils/pool/PoolGroup';\nimport { type GPUData } from '../../view/ViewContainer';\nimport { color32BitToUniform } from '../gpu/colorToUniform';\nimport { BatchableGraphics } from './BatchableGraphics';\n\nimport type { InstructionSet } from '../../../rendering/renderers/shared/instructions/InstructionSet';\nimport type { RenderPipe } from '../../../rendering/renderers/shared/instructions/RenderPipe';\nimport type { Shader } from '../../../rendering/renderers/shared/shader/Shader';\nimport type { PoolItem } from '../../../utils/pool/Pool';\nimport type { Graphics } from './Graphics';\nimport type { GpuGraphicsContext, GraphicsContextSystem } from './GraphicsContextSystem';\n\n/** @internal */\nexport interface GraphicsPipeLike\n{\n    renderer: Renderer;\n    state: State;\n}\n\n/** @internal */\nexport interface GraphicsAdaptor\n{\n    shader: Shader;\n    contextChange(renderer: Renderer): void;\n    execute(graphicsPipe: GraphicsPipeLike, renderable: Graphics): void;\n    destroy(): void;\n}\n\n/** @internal */\nexport class GraphicsGpuData implements GPUData\n{\n    public batches: BatchableGraphics[] = [];\n    public batched = false;\n    public destroy()\n    {\n        this.batches.forEach((batch) =>\n        {\n            BigPool.return(batch as PoolItem);\n        });\n\n        this.batches.length = 0;\n    }\n}\n\n/** @internal */\nexport class GraphicsPipe implements RenderPipe<Graphics>\n{\n    /** @ignore */\n    public static extension = {\n        type: [\n            ExtensionType.WebGLPipes,\n            ExtensionType.WebGPUPipes,\n        ],\n        name: 'graphics',\n    } as const;\n\n    public renderer: Renderer;\n    public state: State = State.for2d();\n\n    private _adaptor: GraphicsAdaptor;\n    private readonly _managedGraphics: GCManagedHash<Graphics>;\n\n    constructor(renderer: Renderer, adaptor: GraphicsAdaptor)\n    {\n        this.renderer = renderer;\n        this._adaptor = adaptor;\n        this.renderer.runners.contextChange.add(this);\n        this._managedGraphics = new GCManagedHash({ renderer, type: 'renderable', priority: -1, name: 'graphics' });\n    }\n\n    public contextChange(): void\n    {\n        this._adaptor.contextChange(this.renderer);\n    }\n\n    public validateRenderable(graphics: Graphics): boolean\n    {\n        // assume context is dirty..\n        const context = graphics.context;\n\n        const wasBatched = !!graphics._gpuData;\n\n        const contextSystem = this.renderer.graphicsContext as GraphicsContextSystem;\n        const gpuContext = contextSystem.updateGpuContext(context);\n\n        if (gpuContext.isBatchable || wasBatched !== gpuContext.isBatchable)\n        {\n            // TODO what if they are the same size??\n            return true;\n        }\n\n        return false;\n    }\n\n    public addRenderable(graphics: Graphics, instructionSet: InstructionSet)\n    {\n        const contextSystem = this.renderer.graphicsContext as GraphicsContextSystem;\n        const gpuContext = contextSystem.updateGpuContext(graphics.context);\n\n        // need to get batches here.. as we need to know if we can batch or not..\n        // this also overrides the current batches..\n        if (graphics.didViewUpdate)\n        {\n            this._rebuild(graphics);\n        }\n\n        if (gpuContext.isBatchable)\n        {\n            this._addToBatcher(graphics, instructionSet);\n        }\n        else\n        {\n            this.renderer.renderPipes.batch.break(instructionSet);\n            instructionSet.add(graphics);\n        }\n    }\n\n    public updateRenderable(graphics: Graphics)\n    {\n        const gpuData = this._getGpuDataForRenderable(graphics);\n\n        const batches = gpuData.batches;\n\n        for (let i = 0; i < batches.length; i++)\n        {\n            const batch = batches[i];\n\n            batch._batcher.updateElement(batch);\n        }\n    }\n\n    public execute(graphics: Graphics)\n    {\n        if (!graphics.isRenderable) return;\n\n        const renderer = this.renderer;\n        const context = graphics.context;\n        const contextSystem = renderer.graphicsContext as GraphicsContextSystem;\n\n        // early out if there is no actual visual stuff...\n        if (!contextSystem.getGpuContext(context).batches.length)\n        { return; }\n\n        const shader = context.customShader || this._adaptor.shader;\n\n        this.state.blendMode = graphics.groupBlendMode;\n\n        const localUniforms = shader.resources.localUniforms.uniforms;\n\n        localUniforms.uTransformMatrix = graphics.groupTransform;\n        localUniforms.uRound = renderer._roundPixels | graphics._roundPixels;\n\n        color32BitToUniform(\n            graphics.groupColorAlpha,\n            localUniforms.uColor,\n            0,\n        );\n\n        this._adaptor.execute(this, graphics);\n    }\n\n    private _rebuild(graphics: Graphics)\n    {\n        const gpuData = this._getGpuDataForRenderable(graphics);\n\n        const contextSystem = this.renderer.graphicsContext as GraphicsContextSystem;\n        const gpuContext = contextSystem.updateGpuContext(graphics.context);\n\n        // free up the batches..\n        gpuData.destroy();\n\n        if (gpuContext.isBatchable)\n        {\n            this._updateBatchesForRenderable(graphics, gpuData);\n        }\n    }\n\n    private _addToBatcher(graphics: Graphics, instructionSet: InstructionSet)\n    {\n        const batchPipe = this.renderer.renderPipes.batch;\n\n        const batches = this._getGpuDataForRenderable(graphics).batches;\n\n        for (let i = 0; i < batches.length; i++)\n        {\n            const batch = batches[i];\n\n            batchPipe.addToBatch(batch, instructionSet);\n        }\n    }\n\n    private _getGpuDataForRenderable(graphics: Graphics): GraphicsGpuData\n    {\n        return graphics._gpuData[this.renderer.uid] || this._initGpuDataForRenderable(graphics);\n    }\n\n    private _initGpuDataForRenderable(graphics: Graphics): GraphicsGpuData\n    {\n        const gpuData = new GraphicsGpuData();\n\n        graphics._gpuData[this.renderer.uid] = gpuData;\n\n        this._managedGraphics.add(graphics);\n\n        return gpuData;\n    }\n\n    private _updateBatchesForRenderable(graphics: Graphics, gpuData: GraphicsGpuData)\n    {\n        const context = graphics.context;\n        const contextSystem = this.renderer.graphicsContext as GraphicsContextSystem;\n        const gpuContext: GpuGraphicsContext = contextSystem.getGpuContext(context);\n\n        const roundPixels = (this.renderer._roundPixels | graphics._roundPixels) as 0 | 1;\n\n        gpuData.batches = gpuContext.batches.map((batch) =>\n        {\n            const batchClone = BigPool.get(BatchableGraphics);\n\n            batch.copyTo(batchClone);\n\n            batchClone.renderable = graphics;\n\n            batchClone.roundPixels = roundPixels;\n\n            return batchClone;\n        });\n    }\n\n    public destroy()\n    {\n        this._managedGraphics.destroy();\n        this.renderer = null;\n\n        this._adaptor.destroy();\n        this._adaptor = null;\n        this.state = null;\n    }\n}\n"],"names":[],"mappings":"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"}