{"version":3,"file":"CanvasTextPipe.mjs","sources":["../../../../src/scene/text/canvas/CanvasTextPipe.ts"],"sourcesContent":["import { ExtensionType } from '../../../extensions/Extensions';\nimport { GCManagedHash } from '../../../utils/data/GCManagedHash';\nimport { updateTextBounds } from '../utils/updateTextBounds';\nimport { BatchableText } from './BatchableText';\n\nimport type { InstructionSet } from '../../../rendering/renderers/shared/instructions/InstructionSet';\nimport type { RenderPipe } from '../../../rendering/renderers/shared/instructions/RenderPipe';\nimport type { Renderer } from '../../../rendering/renderers/types';\nimport type { Text } from '../Text';\n\n/** @internal */\nexport class CanvasTextPipe implements RenderPipe<Text>\n{\n    /** @ignore */\n    public static extension = {\n        type: [\n            ExtensionType.WebGLPipes,\n            ExtensionType.WebGPUPipes,\n            ExtensionType.CanvasPipes,\n        ],\n        name: 'text',\n    } as const;\n\n    private _renderer: Renderer;\n    private readonly _managedTexts: GCManagedHash<Text>;\n\n    constructor(renderer: Renderer)\n    {\n        this._renderer = renderer;\n        renderer.runners.resolutionChange.add(this);\n        this._managedTexts = new GCManagedHash({\n            renderer,\n            type: 'renderable',\n            onUnload: this.onTextUnload.bind(this),\n            name: 'canvasText'\n        });\n    }\n\n    protected resolutionChange()\n    {\n        for (const key in this._managedTexts.items)\n        {\n            const text = this._managedTexts.items[key];\n\n            if (text?._autoResolution) text.onViewUpdate();\n        }\n    }\n\n    public validateRenderable(text: Text): boolean\n    {\n        const gpuText = this._getGpuText(text);\n\n        const newKey = text.styleKey;\n\n        if (gpuText.currentKey !== newKey) return true;\n\n        return text._didTextUpdate;\n    }\n\n    public addRenderable(text: Text, instructionSet: InstructionSet)\n    {\n        const batchableText = this._getGpuText(text);\n\n        if (text._didTextUpdate)\n        {\n            const resolution = text._autoResolution ? this._renderer.resolution : text.resolution;\n\n            if (batchableText.currentKey !== text.styleKey || text._resolution !== resolution)\n            {\n                // If the text has changed, we need to update the GPU text\n                this._updateGpuText(text);\n            }\n\n            text._didTextUpdate = false;\n\n            updateTextBounds(batchableText, text);\n        }\n\n        this._renderer.renderPipes.batch.addToBatch(batchableText, instructionSet);\n    }\n\n    public updateRenderable(text: Text)\n    {\n        const batchableText = this._getGpuText(text);\n\n        batchableText._batcher.updateElement(batchableText);\n    }\n\n    private _updateGpuText(text: Text)\n    {\n        const batchableText = this._getGpuText(text);\n\n        if (batchableText.texture)\n        {\n            this._renderer.canvasText.decreaseReferenceCount(batchableText.currentKey);\n        }\n\n        text._resolution = text._autoResolution ? this._renderer.resolution : text.resolution;\n\n        batchableText.texture = this._renderer.canvasText.getManagedTexture(text);\n        batchableText.currentKey = text.styleKey;\n    }\n\n    private _getGpuText(text: Text)\n    {\n        return text._gpuData[this._renderer.uid] || this.initGpuText(text);\n    }\n\n    public initGpuText(text: Text)\n    {\n        const batchableText = new BatchableText();\n\n        batchableText.currentKey = '--';\n        batchableText.renderable = text;\n        batchableText.transform = text.groupTransform;\n        batchableText.bounds = { minX: 0, maxX: 1, minY: 0, maxY: 0 };\n        batchableText.roundPixels = (this._renderer._roundPixels | text._roundPixels) as 0 | 1;\n\n        text._gpuData[this._renderer.uid] = batchableText;\n        this._managedTexts.add(text);\n\n        return batchableText;\n    }\n\n    protected onTextUnload(text: Text)\n    {\n        const gpuData = text._gpuData[this._renderer.uid];\n\n        if (!gpuData) return;\n\n        const { canvasText } = this._renderer;\n        const refCount = canvasText.getReferenceCount(gpuData.currentKey);\n\n        if (refCount > 0)\n        {\n            canvasText.decreaseReferenceCount(gpuData.currentKey);\n        }\n        else if (gpuData.texture)\n        {\n            canvasText.returnTexture(gpuData.texture);\n        }\n    }\n\n    public destroy()\n    {\n        this._managedTexts.destroy();\n        this._renderer = null;\n    }\n}\n"],"names":[],"mappings":"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"}