{"version":3,"file":"BatcherPipe.mjs","sources":["../../../../src/rendering/batcher/shared/BatcherPipe.ts"],"sourcesContent":["import { extensions, ExtensionType } from '../../../extensions/Extensions';\nimport { State } from '../../renderers/shared/state/State';\nimport { DefaultBatcher } from './DefaultBatcher';\n\nimport type { Geometry } from '../../renderers/shared/geometry/Geometry';\nimport type { InstructionSet } from '../../renderers/shared/instructions/InstructionSet';\nimport type { BatchPipe, InstructionPipe } from '../../renderers/shared/instructions/RenderPipe';\nimport type { Shader } from '../../renderers/shared/shader/Shader';\nimport type { Renderer } from '../../renderers/types';\nimport type { Batch, BatchableElement, Batcher } from './Batcher';\n\n/** @internal */\nexport interface BatcherAdaptor\n{\n    start(batchPipe: BatcherPipe, geometry: Geometry, shader: Shader): void\n    init?(batchPipe: BatcherPipe): void;\n    execute(batchPipe: BatcherPipe, batch: Batch): void\n    contextChange?(): void;\n}\n\n/**\n * A pipe that batches elements into batches and sends them to the renderer.\n *\n * You can install new Batchers using ExtensionType.Batcher. Each render group will\n * have a default batcher and any required ones will be created on demand.\n * @category rendering\n * @advanced\n */\nexport class BatcherPipe implements InstructionPipe<Batch>, BatchPipe\n{\n    /** @ignore */\n    public static extension = {\n        type: [\n            ExtensionType.WebGLPipes,\n            ExtensionType.WebGPUPipes,\n            ExtensionType.CanvasPipes,\n        ],\n        name: 'batch',\n    } as const;\n\n    public state: State = State.for2d();\n    public renderer: Renderer;\n\n    private readonly _batchersByInstructionSet: Record<number, Record<string, Batcher>> = Object.create(null);\n\n    private _adaptor: BatcherAdaptor;\n\n    /** A record of all active batchers, keyed by their names */\n    private _activeBatches: Record<string, Batcher> = Object.create(null);\n\n    /** The currently active batcher being used to batch elements */\n    private _activeBatch: Batcher;\n\n    public static _availableBatchers: Record<string, new () => Batcher> = Object.create(null);\n\n    public static getBatcher(name: string): Batcher\n    {\n        return new this._availableBatchers[name as keyof typeof this._availableBatchers]();\n    }\n\n    constructor(renderer: Renderer, adaptor: BatcherAdaptor)\n    {\n        this.renderer = renderer;\n        this._adaptor = adaptor;\n\n        this._adaptor.init?.(this);\n    }\n\n    public buildStart(instructionSet: InstructionSet)\n    {\n        let batchers = this._batchersByInstructionSet[instructionSet.uid];\n\n        if (!batchers)\n        {\n            batchers = this._batchersByInstructionSet[instructionSet.uid] = Object.create(null);\n            batchers.default ||= new DefaultBatcher({\n                maxTextures: this.renderer.limits.maxBatchableTextures,\n            });\n        }\n\n        this._activeBatches = batchers;\n\n        this._activeBatch = this._activeBatches.default;\n\n        for (const i in this._activeBatches)\n        {\n            this._activeBatches[i].begin();\n        }\n    }\n\n    public addToBatch(batchableObject: BatchableElement, instructionSet: InstructionSet)\n    {\n        if (this._activeBatch.name !== batchableObject.batcherName)\n        {\n            this._activeBatch.break(instructionSet);\n\n            let batch = this._activeBatches[batchableObject.batcherName];\n\n            if (!batch)\n            {\n                batch = this._activeBatches[batchableObject.batcherName]\n                    = BatcherPipe.getBatcher(batchableObject.batcherName);\n                batch.begin();\n            }\n\n            this._activeBatch = batch;\n        }\n\n        this._activeBatch.add(batchableObject);\n    }\n\n    public break(instructionSet: InstructionSet)\n    {\n        this._activeBatch.break(instructionSet);\n    }\n\n    public buildEnd(instructionSet: InstructionSet)\n    {\n        this._activeBatch.break(instructionSet);\n\n        const batches = this._activeBatches;\n\n        for (const i in batches)\n        {\n            const batch = batches[i as keyof typeof batches];\n            const geometry = batch.geometry;\n\n            geometry.indexBuffer.setDataWithSize(batch.indexBuffer, batch.indexSize, true);\n\n            geometry.buffers[0].setDataWithSize(batch.attributeBuffer.float32View, batch.attributeSize, false);\n        }\n    }\n\n    public upload(instructionSet: InstructionSet)\n    {\n        const batchers = this._batchersByInstructionSet[instructionSet.uid];\n\n        for (const i in batchers)\n        {\n            const batcher = batchers[i as keyof typeof batchers];\n            const geometry = batcher.geometry;\n\n            if (batcher.dirty)\n            {\n                batcher.dirty = false;\n\n                geometry.buffers[0].update(batcher.attributeSize * 4);\n            }\n        }\n    }\n\n    public execute(batch: Batch)\n    {\n        if (batch.action === 'startBatch')\n        {\n            const batcher = batch.batcher;\n            const geometry = batcher.geometry;\n            const shader = batcher.shader;\n\n            this._adaptor.start(this, geometry, shader);\n        }\n\n        this._adaptor.execute(this, batch);\n    }\n\n    public destroy()\n    {\n        this.state = null;\n        this.renderer = null;\n\n        this._adaptor = null;\n\n        for (const i in this._activeBatches)\n        {\n            this._activeBatches[i].destroy();\n        }\n\n        this._activeBatches = null;\n    }\n}\n\nextensions.handleByMap(ExtensionType.Batcher, BatcherPipe._availableBatchers);\n\nextensions.add(DefaultBatcher);\n"],"names":[],"mappings":"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"}