{"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 { WebGPURenderer } from '../../rendering/renderers/gpu/WebGPURenderer';\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        ],\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 renderer = this._renderer as WebGLRenderer | WebGPURenderer;\n        const { shader } = this._getTilingSpriteData(tilingSprite);\n\n        shader.groups[0] = 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 = 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        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"],"names":[],"mappings":"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"}