{"version":3,"file":"TilingSpritePipe.mjs","sources":["../../../src/scene/sprite-tiling/TilingSpritePipe.ts"],"sourcesContent":["import { ExtensionType } from '../../extensions/Extensions';\nimport { getAdjustedBlendModeBlend } from '../../rendering/renderers/shared/state/getAdjustedBlendModeBlend';\nimport { State } from '../../rendering/renderers/shared/state/State';\nimport { type Renderer, RendererType } from '../../rendering/renderers/types';\nimport { GCManagedHash } from '../../utils/data/GCManagedHash';\nimport { color32BitToUniform } from '../graphics/gpu/colorToUniform';\nimport { BatchableMesh } from '../mesh/shared/BatchableMesh';\nimport { MeshGeometry } from '../mesh/shared/MeshGeometry';\nimport { type GPUData } from '../view/ViewContainer';\nimport { TilingSpriteShader } from './shader/TilingSpriteShader';\nimport { QuadGeometry } from './utils/QuadGeometry';\nimport { setPositions } from './utils/setPositions';\nimport { setUvs } from './utils/setUvs';\n\nimport type { WebGLRenderer } from '../../rendering/renderers/gl/WebGLRenderer';\nimport type { InstructionSet } from '../../rendering/renderers/shared/instructions/InstructionSet';\nimport type { RenderPipe } from '../../rendering/renderers/shared/instructions/RenderPipe';\nimport type { TilingSprite } from './TilingSprite';\n\nconst sharedQuad = new QuadGeometry();\n\n/** @internal */\nexport class TilingSpriteGpuData implements GPUData\n{\n    public canBatch: boolean = true;\n    public renderable: TilingSprite;\n    public batchableMesh?: BatchableMesh;\n    public geometry?: MeshGeometry;\n    public shader?: TilingSpriteShader;\n\n    constructor()\n    {\n        this.geometry = new MeshGeometry({\n            indices: sharedQuad.indices.slice(),\n            positions: sharedQuad.positions.slice(),\n            uvs: sharedQuad.uvs.slice(),\n        });\n    }\n\n    public destroy()\n    {\n        this.geometry.destroy();\n        this.shader?.destroy();\n    }\n}\n\n/**\n * The TilingSpritePipe is a render pipe for rendering TilingSprites.\n * It handles the batching and rendering of TilingSprites using a shader.\n * @internal\n */\nexport class TilingSpritePipe implements RenderPipe<TilingSprite>\n{\n    /** @ignore */\n    public static extension = {\n        type: [\n            ExtensionType.WebGLPipes,\n            ExtensionType.WebGPUPipes,\n            ExtensionType.CanvasPipes,\n        ],\n        name: 'tilingSprite',\n    } as const;\n\n    private _renderer: Renderer;\n    private readonly _state: State = State.default2d;\n    private readonly _managedTilingSprites: GCManagedHash<TilingSprite>;\n\n    constructor(renderer: Renderer)\n    {\n        this._renderer = renderer;\n        this._managedTilingSprites = new GCManagedHash({ renderer, type: 'renderable', name: 'tilingSprite' });\n    }\n\n    public validateRenderable(renderable: TilingSprite): boolean\n    {\n        const tilingSpriteData = this._getTilingSpriteData(renderable);\n\n        const couldBatch = tilingSpriteData.canBatch;\n\n        this._updateCanBatch(renderable);\n\n        const canBatch = tilingSpriteData.canBatch;\n\n        if (canBatch && canBatch === couldBatch)\n        {\n            const { batchableMesh } = tilingSpriteData;\n\n            return !batchableMesh._batcher.checkAndUpdateTexture(\n                batchableMesh,\n                renderable.texture\n            );\n        }\n\n        return (couldBatch !== canBatch);\n\n        // // TODO - only update if required?\n        // // only texture\n        // // only uvs\n        // // only positions?\n    }\n\n    public addRenderable(tilingSprite: TilingSprite, instructionSet: InstructionSet)\n    {\n        const batcher = this._renderer.renderPipes.batch;\n\n        // init\n        this._updateCanBatch(tilingSprite);\n\n        const tilingSpriteData = this._getTilingSpriteData(tilingSprite);\n\n        const { geometry, canBatch } = tilingSpriteData;\n\n        if (canBatch)\n        {\n            tilingSpriteData.batchableMesh ||= new BatchableMesh();\n\n            const batchableMesh = tilingSpriteData.batchableMesh;\n\n            if (tilingSprite.didViewUpdate)\n            {\n                this._updateBatchableMesh(tilingSprite);\n\n                batchableMesh.geometry = geometry;\n                batchableMesh.renderable = tilingSprite;\n                batchableMesh.transform = tilingSprite.groupTransform;\n                batchableMesh.setTexture(tilingSprite._texture);\n            }\n\n            batchableMesh.roundPixels = (this._renderer._roundPixels | tilingSprite._roundPixels) as 0 | 1;\n\n            batcher.addToBatch(batchableMesh, instructionSet);\n        }\n        else\n        {\n            batcher.break(instructionSet);\n\n            tilingSpriteData.shader ||= new TilingSpriteShader();\n\n            this.updateRenderable(tilingSprite);\n\n            instructionSet.add(tilingSprite);\n        }\n    }\n\n    public execute(tilingSprite: TilingSprite)\n    {\n        const { shader } = this._getTilingSpriteData(tilingSprite);\n\n        shader.groups[0] = this._renderer.globalUniforms.bindGroup;\n\n        // deal with local uniforms...\n        const localUniforms = shader.resources.localUniforms.uniforms;\n\n        localUniforms.uTransformMatrix = tilingSprite.groupTransform;\n        localUniforms.uRound = this._renderer._roundPixels | tilingSprite._roundPixels;\n\n        color32BitToUniform(\n            tilingSprite.groupColorAlpha,\n            localUniforms.uColor,\n            0\n        );\n\n        this._state.blendMode = getAdjustedBlendModeBlend(tilingSprite.groupBlendMode, tilingSprite.texture._source);\n\n        this._renderer.encoder.draw({\n            geometry: sharedQuad,\n            shader,\n            state: this._state,\n        });\n    }\n\n    public updateRenderable(tilingSprite: TilingSprite)\n    {\n        const tilingSpriteData = this._getTilingSpriteData(tilingSprite);\n\n        const { canBatch } = tilingSpriteData;\n\n        if (canBatch)\n        {\n            const { batchableMesh } = tilingSpriteData;\n\n            if (tilingSprite.didViewUpdate) this._updateBatchableMesh(tilingSprite);\n\n            batchableMesh._batcher.updateElement(batchableMesh);\n        }\n        else if (tilingSprite.didViewUpdate)\n        {\n            const { shader } = tilingSpriteData;\n            // now update uniforms...\n\n            shader.updateUniforms(\n                tilingSprite.width,\n                tilingSprite.height,\n                tilingSprite._tileTransform.matrix,\n                tilingSprite.anchor.x,\n                tilingSprite.anchor.y,\n                tilingSprite.texture,\n            );\n        }\n    }\n\n    private _getTilingSpriteData(renderable: TilingSprite): TilingSpriteGpuData\n    {\n        return renderable._gpuData[this._renderer.uid] || this._initTilingSpriteData(renderable);\n    }\n\n    private _initTilingSpriteData(tilingSprite: TilingSprite): TilingSpriteGpuData\n    {\n        const gpuData = new TilingSpriteGpuData();\n\n        gpuData.renderable = tilingSprite;\n        tilingSprite._gpuData[this._renderer.uid] = gpuData;\n\n        this._managedTilingSprites.add(tilingSprite);\n\n        return gpuData;\n    }\n\n    private _updateBatchableMesh(tilingSprite: TilingSprite)\n    {\n        const renderableData = this._getTilingSpriteData(tilingSprite);\n\n        const { geometry } = renderableData;\n\n        const style = tilingSprite.texture.source.style;\n\n        if (style.addressMode !== 'repeat')\n        {\n            style.addressMode = 'repeat';\n            style.update();\n        }\n\n        setUvs(tilingSprite, geometry.uvs);\n        setPositions(tilingSprite, geometry.positions);\n    }\n\n    public destroy()\n    {\n        this._managedTilingSprites.destroy();\n        this._renderer = null;\n    }\n\n    private _updateCanBatch(tilingSprite: TilingSprite)\n    {\n        const renderableData = this._getTilingSpriteData(tilingSprite);\n        const texture = tilingSprite.texture;\n\n        let _nonPowOf2wrapping = true;\n\n        if (this._renderer.type === RendererType.WEBGL)\n        {\n            _nonPowOf2wrapping = (this._renderer as WebGLRenderer).context.supports.nonPowOf2wrapping;\n        }\n\n        renderableData.canBatch = texture.textureMatrix.isSimple && (_nonPowOf2wrapping || texture.source.isPowerOfTwo);\n\n        return renderableData.canBatch;\n    }\n}\n\n"],"names":[],"mappings":"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"}