{"version":3,"file":"GraphicsContextSystem.mjs","sources":["../../../../src/scene/graphics/shared/GraphicsContextSystem.ts"],"sourcesContent":["import { ExtensionType } from '../../../extensions/Extensions';\nimport { getTextureBatchBindGroup } from '../../../rendering/batcher/gpu/getTextureBatchBindGroup';\nimport { Batcher } from '../../../rendering/batcher/shared/Batcher';\nimport { BatchGeometry } from '../../../rendering/batcher/shared/BatchGeometry';\nimport { InstructionSet } from '../../../rendering/renderers/shared/instructions/InstructionSet';\nimport { BigPool } from '../../../utils/pool/PoolGroup';\nimport { buildContextBatches } from './utils/buildContextBatches';\n\nimport type { System } from '../../../rendering/renderers/shared/system/System';\nimport type { PoolItem } from '../../../utils/pool/Pool';\nimport type { BatchableGraphics } from './BatchableGraphics';\nimport type { GraphicsContext } from './GraphicsContext';\n\ninterface GeometryData\n{\n    vertices: number[];\n    uvs: number[];\n    indices: number[];\n}\n\n/**\n * A class that holds batchable graphics data for a GraphicsContext.\n * @memberof rendering\n * @ignore\n */\nexport class GpuGraphicsContext\n{\n    public isBatchable: boolean;\n    public context: GraphicsContext;\n    public batcher: Batcher = new Batcher();\n    public batches: BatchableGraphics[] = [];\n    public geometryData: GeometryData = {\n        vertices: [],\n        uvs: [],\n        indices: [],\n    };\n    public graphicsData: GraphicsContextRenderData;\n}\n\n/**\n * A class that holds the render data for a GraphicsContext.\n * @memberof rendering\n * @ignore\n */\nexport class GraphicsContextRenderData\n{\n    public geometry = new BatchGeometry();\n    public instructions = new InstructionSet();\n\n    public init()\n    {\n        this.instructions.reset();\n    }\n}\n\n/**\n * Options for the GraphicsContextSystem.\n * @memberof rendering\n */\nexport interface GraphicsContextSystemOptions\n{\n    /** A value from 0 to 1 that controls the smoothness of bezier curves (the higher the smoother) */\n    bezierSmoothness?: number;\n}\n\n/**\n * A system that manages the rendering of GraphicsContexts.\n * @memberof rendering\n */\nexport class GraphicsContextSystem implements System<GraphicsContextSystemOptions>\n{\n    /** @ignore */\n    public static extension = {\n        type: [\n            ExtensionType.WebGLSystem,\n            ExtensionType.WebGPUSystem,\n            ExtensionType.CanvasSystem,\n        ],\n        name: 'graphicsContext'\n    } as const;\n\n    /** The default options for the GraphicsContextSystem. */\n    public static readonly defaultOptions: GraphicsContextSystemOptions = {\n        /**\n         * A value from 0 to 1 that controls the smoothness of bezier curves (the higher the smoother)\n         * @default 0.5\n         */\n        bezierSmoothness: 0.5,\n    };\n\n    // the root context batches, used to either make a batch or geometry\n    // all graphics use this as a base\n    private _gpuContextHash: Record<number, GpuGraphicsContext> = {};\n    // used for non-batchable graphics\n    private _graphicsDataContextHash: Record<number, GraphicsContextRenderData> = Object.create(null);\n\n    /**\n     * Runner init called, update the default options\n     * @ignore\n     */\n    public init(options?: GraphicsContextSystemOptions)\n    {\n        GraphicsContextSystem.defaultOptions.bezierSmoothness = options?.bezierSmoothness\n            ?? GraphicsContextSystem.defaultOptions.bezierSmoothness;\n    }\n\n    public getContextRenderData(context: GraphicsContext): GraphicsContextRenderData\n    {\n        return this._graphicsDataContextHash[context.uid] || this._initContextRenderData(context);\n    }\n\n    // Context management functions\n    public updateGpuContext(context: GraphicsContext)\n    {\n        let gpuContext: GpuGraphicsContext = this._gpuContextHash[context.uid]\n\n            || this._initContext(context);\n\n        if (context.dirty)\n        {\n            if (gpuContext)\n            {\n                this._cleanGraphicsContextData(context);\n            }\n            else\n            {\n                gpuContext = this._initContext(context);\n            }\n\n            buildContextBatches(context, gpuContext);\n\n            const batchMode = context.batchMode;\n\n            if (context.customShader || batchMode === 'no-batch')\n            {\n                gpuContext.isBatchable = false;\n            }\n            else if (batchMode === 'auto')\n            {\n                gpuContext.isBatchable = (gpuContext.geometryData.vertices.length < 400);\n            }\n\n            context.dirty = false;\n        }\n\n        return gpuContext;\n    }\n\n    public getGpuContext(context: GraphicsContext): GpuGraphicsContext\n    {\n        return this._gpuContextHash[context.uid] || this._initContext(context);\n    }\n\n    private _initContextRenderData(context: GraphicsContext): GraphicsContextRenderData\n    {\n        const graphicsData: GraphicsContextRenderData = BigPool.get(GraphicsContextRenderData);// ();\n\n        const { batches, geometryData, batcher } = this._gpuContextHash[context.uid];\n\n        const vertexSize = geometryData.vertices.length;\n        const indexSize = geometryData.indices.length;\n\n        for (let i = 0; i < batches.length; i++)\n        {\n            batches[i].applyTransform = false;\n        }\n\n        // TODO we can pool buffers here eventually..\n        batcher.ensureAttributeBuffer(vertexSize);\n        batcher.ensureIndexBuffer(indexSize);\n\n        batcher.begin();\n\n        for (let i = 0; i < batches.length; i++)\n        {\n            const batch = batches[i];\n\n            batcher.add(batch);\n        }\n\n        batcher.finish(graphicsData.instructions);\n\n        const geometry = graphicsData.geometry;\n\n        // not to self - this works as we are assigning the batchers array buffer\n        // once its up loaded - this buffer is then put back in the pool to be reused.\n        // this mean we don't have to creating new Batchers for each graphics items\n        geometry.indexBuffer.setDataWithSize(batcher.indexBuffer, batcher.indexSize, true);\n        geometry.buffers[0].setDataWithSize(batcher.attributeBuffer.float32View, batcher.attributeSize, true);\n\n        const drawBatches = batcher.batches;\n\n        for (let i = 0; i < drawBatches.length; i++)\n        {\n            const batch = drawBatches[i];\n\n            batch.bindGroup = getTextureBatchBindGroup(batch.textures.textures, batch.textures.count);\n        }\n\n        this._graphicsDataContextHash[context.uid] = graphicsData;\n\n        return graphicsData;\n    }\n\n    private _initContext(context: GraphicsContext): GpuGraphicsContext\n    {\n        const gpuContext = new GpuGraphicsContext();\n\n        gpuContext.context = context;\n\n        this._gpuContextHash[context.uid] = gpuContext;\n\n        context.on('destroy', this.onGraphicsContextDestroy, this);\n\n        return this._gpuContextHash[context.uid];\n    }\n\n    protected onGraphicsContextDestroy(context: GraphicsContext)\n    {\n        this._cleanGraphicsContextData(context);\n\n        context.off('destroy', this.onGraphicsContextDestroy, this);\n\n        this._gpuContextHash[context.uid] = null;\n    }\n\n    private _cleanGraphicsContextData(context: GraphicsContext)\n    {\n        const gpuContext: GpuGraphicsContext = this._gpuContextHash[context.uid];\n\n        if (!gpuContext.isBatchable)\n        {\n            if (this._graphicsDataContextHash[context.uid])\n            {\n                BigPool.return(this.getContextRenderData(context) as PoolItem);\n\n                // we will rebuild this...\n                this._graphicsDataContextHash[context.uid] = null;\n            }\n        }\n\n        if (gpuContext.batches)\n        {\n            gpuContext.batches.forEach((batch) =>\n            {\n                BigPool.return(batch as PoolItem);\n            });\n        }\n    }\n\n    public destroy()\n    {\n        // Clean up all graphics contexts\n\n        for (const i in this._gpuContextHash)\n        {\n            if (this._gpuContextHash[i])\n            {\n                this.onGraphicsContextDestroy(this._gpuContextHash[i].context);\n            }\n        }\n    }\n}\n"],"names":[],"mappings":"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"}