{"version":3,"file":"FilterSystem.mjs","sources":["../../src/filters/FilterSystem.ts"],"sourcesContent":["import { ExtensionType } from '../extensions/Extensions';\nimport { Matrix } from '../maths/matrix/Matrix';\nimport { Point } from '../maths/point/Point';\nimport { BindGroup } from '../rendering/renderers/gpu/shader/BindGroup';\nimport { Geometry } from '../rendering/renderers/shared/geometry/Geometry';\nimport { UniformGroup } from '../rendering/renderers/shared/shader/UniformGroup';\nimport { Texture } from '../rendering/renderers/shared/texture/Texture';\nimport { TexturePool } from '../rendering/renderers/shared/texture/TexturePool';\nimport { type Renderer, RendererType } from '../rendering/renderers/types';\nimport { Bounds } from '../scene/container/bounds/Bounds';\nimport { getFastGlobalBounds } from '../scene/container/bounds/getFastGlobalBounds';\nimport { getGlobalRenderableBounds } from '../scene/container/bounds/getRenderableBounds';\nimport { warn } from '../utils/logging/warn';\n\nimport type { WebGLRenderer } from '../rendering/renderers/gl/WebGLRenderer';\nimport type { WebGPURenderer } from '../rendering/renderers/gpu/WebGPURenderer';\nimport type { Instruction } from '../rendering/renderers/shared/instructions/Instruction';\nimport type { Renderable } from '../rendering/renderers/shared/Renderable';\nimport type { RenderTarget } from '../rendering/renderers/shared/renderTarget/RenderTarget';\nimport type { RenderSurface } from '../rendering/renderers/shared/renderTarget/RenderTargetSystem';\nimport type { System } from '../rendering/renderers/shared/system/System';\nimport type { Container } from '../scene/container/Container';\nimport type { Sprite } from '../scene/sprite/Sprite';\nimport type { Filter } from './Filter';\nimport type { FilterEffect } from './FilterEffect';\n\ntype FilterAction = 'pushFilter' | 'popFilter';\n\n//\nconst quadGeometry = new Geometry({\n    attributes: {\n        aPosition: {\n            buffer: new Float32Array([0, 0, 1, 0, 1, 1, 0, 1]),\n            format: 'float32x2',\n            stride: 2 * 4,\n            offset: 0,\n        },\n    },\n    indexBuffer: new Uint32Array([0, 1, 2, 0, 2, 3]),\n});\n\n/**\n * The filter pipeline is responsible for applying filters scene items!\n *\n * KNOWN BUGS:\n * 1. Global bounds calculation is incorrect if it is used when flip flopping filters. The maths can be found below\n * eg: filters [noiseFilter, blurFilter] noiseFilter will calculate the global bounds incorrectly.\n *\n * 2. RenderGroups do not work with filters. This is because the renderGroup matrix is not currently taken into account.\n *\n * Implementation notes:\n * 1. Gotcha - nesting filters that require blending will not work correctly. This creates a chicken and egg problem\n * the complexity and performance required to do this is not worth it i feel.. but lets see if others agree!\n *\n * 2. Filters are designed to be changed on the fly, this is means that changing filter information each frame will\n * not trigger an instruction rebuild. If you are constantly turning a filter on and off.. its therefore better to set\n * enabled to true or false on the filter. Or setting an empty array.\n *\n * 3. Need to look at perhaps aliasing when flip flopping filters. Really we should only need to antialias the FIRST\n * Texture we render too. The rest can be non aliased. This might help performance.\n * Currently we flip flop with an antialiased texture if antialiasing is enabled on the filter.\n */\nexport interface FilterInstruction extends Instruction\n{\n    renderPipeId: 'filter',\n    action: FilterAction,\n    container?: Container,\n    renderables?: Renderable[],\n    filterEffect: FilterEffect,\n}\n\nexport interface FilterData\n{\n    skip: boolean;\n    enabledLength?: number;\n    inputTexture: Texture\n    bounds: Bounds,\n    blendRequired: boolean,\n    container: Container,\n    filterEffect: FilterEffect,\n    previousRenderSurface: RenderSurface,\n    backTexture?: Texture,\n}\n\n/**\n * System that manages the filter pipeline\n * @memberof rendering\n */\nexport class FilterSystem implements System\n{\n    /** @ignore */\n    public static extension = {\n        type: [\n            ExtensionType.WebGLSystem,\n            ExtensionType.WebGPUSystem,\n        ],\n        name: 'filter',\n    } as const;\n\n    public readonly renderer: Renderer;\n\n    private _filterStackIndex = 0;\n    private _filterStack: FilterData[] = [];\n\n    private readonly _filterGlobalUniforms = new UniformGroup({\n        uInputSize: { value: new Float32Array(4), type: 'vec4<f32>' },\n        uInputPixel: { value: new Float32Array(4), type: 'vec4<f32>' },\n        uInputClamp: { value: new Float32Array(4), type: 'vec4<f32>' },\n        uOutputFrame: { value: new Float32Array(4), type: 'vec4<f32>' },\n        uGlobalFrame: { value: new Float32Array(4), type: 'vec4<f32>' },\n        uOutputTexture: { value: new Float32Array(4), type: 'vec4<f32>' },\n    });\n\n    private readonly _globalFilterBindGroup: BindGroup = new BindGroup({});\n    private _activeFilterData: FilterData;\n\n    constructor(renderer: Renderer)\n    {\n        this.renderer = renderer;\n    }\n\n    /**\n     * The back texture of the currently active filter. Requires the filter to have `blendRequired` set to true.\n     * @readonly\n     */\n    public get activeBackTexture(): Texture | undefined\n    {\n        return this._activeFilterData?.backTexture;\n    }\n\n    public push(instruction: FilterInstruction)\n    {\n        const renderer = this.renderer;\n\n        const filters = instruction.filterEffect.filters;\n\n        if (!this._filterStack[this._filterStackIndex])\n        {\n            this._filterStack[this._filterStackIndex] = this._getFilterData();\n        }\n\n        // get a filter data from the stack. They can be reused multiple times each frame,\n        // so we don't need to worry about overwriting them in a single pass.\n        const filterData = this._filterStack[this._filterStackIndex];\n\n        this._filterStackIndex++;\n\n        // if there are no filters, we skip the pass\n        if (filters.length === 0)\n        {\n            filterData.skip = true;\n\n            return;\n        }\n\n        const bounds: Bounds = filterData.bounds;\n\n        // this path is used by the blend modes mostly!\n        // they collect all renderables and push them into a list.\n        // this list is then used to calculate the bounds of the filter area\n        if (instruction.renderables)\n        {\n            getGlobalRenderableBounds(instruction.renderables, bounds);\n        }\n        // if a filterArea is provided, we save our selves some measuring and just use that area supplied\n        else if (instruction.filterEffect.filterArea)\n        {\n            bounds.clear();\n\n            // transform the filterArea into global space..\n            bounds.addRect(instruction.filterEffect.filterArea);\n\n            // new for v8, we transform the bounds into the space of the container\n            bounds.applyMatrix(instruction.container.worldTransform);\n        }\n        // classic filter path, we get the bounds of the container and use it by recursively\n        // measuring.\n        else\n        {\n            getFastGlobalBounds(instruction.container, bounds);\n        }\n        // get GLOBAL bounds of the item we are going to apply the filter to\n\n        const colorTextureSource = renderer.renderTarget.renderTarget.colorTexture.source;\n\n        // next we get the settings for the filter\n        // we need to find the LOWEST resolution for the filter list\n        let resolution = Infinity;\n        // Padding is additive to add padding to our padding\n        let padding = 0;\n        // if this is true for all filter, it should be true, and otherwise false\n        let antialias = true;\n        // true if any filter requires the previous render target\n        let blendRequired = false;\n        // true if any filter in the list is enabled\n        let enabled = false;\n\n        for (let i = 0; i < filters.length; i++)\n        {\n            const filter = filters[i];\n\n            resolution = Math.min(resolution, filter.resolution === 'inherit'\n                ? colorTextureSource._resolution : filter.resolution);\n            padding += filter.padding;\n\n            if (filter.antialias === 'off')\n            {\n                antialias = false;\n            }\n            else if (filter.antialias === 'inherit')\n            {\n                antialias &&= colorTextureSource.antialias;\n            }\n\n            const isCompatible = !!(filter.compatibleRenderers & renderer.type);\n\n            if (!isCompatible)\n            {\n                enabled = false;\n                break;\n            }\n\n            if (filter.blendRequired && !((renderer as WebGLRenderer).backBuffer?.useBackBuffer ?? true))\n            {\n                // #if _DEBUG\n                // eslint-disable-next-line max-len\n                warn('Blend filter requires backBuffer on WebGL renderer to be enabled. Set `useBackBuffer: true` in the renderer options.');\n                // #endif\n\n                enabled = false;\n                break;\n            }\n\n            enabled = filter.enabled || enabled;\n            blendRequired = blendRequired || filter.blendRequired;\n        }\n\n        // if no filters are enabled lets skip!\n        if (!enabled)\n        {\n            filterData.skip = true;\n\n            return;\n        }\n\n        const viewPort = renderer.renderTarget.rootViewPort;\n\n        // here we constrain the bounds to the viewport we will render too\n        // this should not take into account the x, y offset of the viewport - as this is\n        // handled by the viewport on the gpu.\n        // need to factor in resolutions also..\n        bounds.scale(resolution)\n            .fitBounds(0, viewPort.width, 0, viewPort.height)\n            .scale(1 / resolution)\n            .pad(padding)\n            .ceil();\n\n        // skip if the bounds are negative or zero as this means they are\n        // not visible on the screen\n        if (!bounds.isPositive)\n        {\n            filterData.skip = true;\n\n            return;\n        }\n\n        // set all the filter data\n        filterData.skip = false;\n\n        filterData.bounds = bounds;\n        filterData.blendRequired = blendRequired;\n        filterData.container = instruction.container;\n        filterData.filterEffect = instruction.filterEffect;\n\n        filterData.previousRenderSurface = renderer.renderTarget.renderSurface;\n\n        // bind...\n        // get a P02 texture from our pool...\n        filterData.inputTexture = TexturePool.getOptimalTexture(\n            bounds.width,\n            bounds.height,\n            resolution,\n            antialias,\n        );\n\n        renderer.renderTarget.bind(filterData.inputTexture, true);\n        // set the global uniforms to take into account the bounds offset required\n\n        renderer.globalUniforms.push({\n            offset: bounds,\n        });\n    }\n\n    public pop()\n    {\n        const renderer = this.renderer;\n\n        this._filterStackIndex--;\n        const filterData = this._filterStack[this._filterStackIndex];\n\n        // if we are skipping this filter then we just do nothing :D\n        if (filterData.skip)\n        {\n            return;\n        }\n\n        this._activeFilterData = filterData;\n\n        const inputTexture = filterData.inputTexture;\n\n        const bounds = filterData.bounds;\n\n        let backTexture = Texture.EMPTY;\n\n        renderer.renderTarget.finishRenderPass();\n\n        if (filterData.blendRequired)\n        {\n            // this actually forces the current commandQueue to render everything so far.\n            // if we don't do this, we won't be able to copy pixels for the background\n            const previousBounds = this._filterStackIndex > 0 ? this._filterStack[this._filterStackIndex - 1].bounds : null;\n\n            const renderTarget = renderer.renderTarget.getRenderTarget(filterData.previousRenderSurface);\n\n            backTexture = this.getBackTexture(renderTarget, bounds, previousBounds);\n        }\n\n        filterData.backTexture = backTexture;\n\n        const filters = filterData.filterEffect.filters;\n\n        // get a BufferResource from the uniformBatch.\n        // this will batch the shader uniform data and give us a buffer resource we can\n        // set on our globalUniform Bind Group\n        // eslint-disable-next-line max-len\n\n        // update the resources on the bind group...\n        this._globalFilterBindGroup.setResource(inputTexture.source.style, 2);\n        this._globalFilterBindGroup.setResource(backTexture.source, 3);\n\n        renderer.globalUniforms.pop();\n\n        if (filters.length === 1)\n        {\n            // render a single filter...\n            // this.applyFilter(filters[0], inputTexture, filterData.previousRenderSurface, false);\n            filters[0].apply(this, inputTexture, filterData.previousRenderSurface, false);\n\n            // return the texture to the pool so we can reuse the next frame\n            TexturePool.returnTexture(inputTexture);\n        }\n        else\n        {\n            let flip = filterData.inputTexture;\n\n            // get another texture that we will render the next filter too\n            let flop = TexturePool.getOptimalTexture(\n                bounds.width,\n                bounds.height,\n                flip.source._resolution,\n                false\n            );\n\n            let i = 0;\n\n            // loop and apply the filters, omitting the last one as we will render that to the final target\n            for (i = 0; i < filters.length - 1; ++i)\n            {\n                const filter = filters[i];\n\n                filter.apply(this, flip, flop, true);\n                const t = flip;\n\n                flip = flop;\n                flop = t;\n            }\n\n            filters[i].apply(this, flip, filterData.previousRenderSurface, false);\n\n            // return those textures for later!\n            TexturePool.returnTexture(flip);\n            TexturePool.returnTexture(flop);\n        }\n\n        // if we made a background texture, lets return that also\n        if (filterData.blendRequired)\n        {\n            TexturePool.returnTexture(backTexture);\n        }\n    }\n\n    public getBackTexture(lastRenderSurface: RenderTarget, bounds: Bounds, previousBounds?: Bounds)\n    {\n        const backgroundResolution = lastRenderSurface.colorTexture.source._resolution;\n\n        const backTexture = TexturePool.getOptimalTexture(\n            bounds.width,\n            bounds.height,\n            backgroundResolution,\n            false,\n        );\n\n        let x = bounds.minX;\n        let y = bounds.minY;\n\n        if (previousBounds)\n        {\n            x -= previousBounds.minX;\n            y -= previousBounds.minY;\n        }\n\n        x = Math.floor(x * backgroundResolution);\n        y = Math.floor(y * backgroundResolution);\n\n        const width = Math.ceil(bounds.width * backgroundResolution);\n        const height = Math.ceil(bounds.height * backgroundResolution);\n\n        this.renderer.renderTarget.copyToTexture(\n            lastRenderSurface,\n            backTexture,\n            { x, y },\n            { width, height },\n            { x: 0, y: 0 }\n        );\n\n        return backTexture;\n    }\n\n    public applyFilter(filter: Filter, input: Texture, output: RenderSurface, clear: boolean)\n    {\n        const renderer = this.renderer;\n\n        const filterData = this._filterStack[this._filterStackIndex];\n\n        const bounds = filterData.bounds;\n\n        const offset = Point.shared;\n        const previousRenderSurface = filterData.previousRenderSurface;\n\n        const isFinalTarget = previousRenderSurface === output;\n\n        let resolution = this.renderer.renderTarget.rootRenderTarget.colorTexture.source._resolution;\n\n        // to find the previous resolution we need to account for the skipped filters\n        // the following will find the last non skipped filter...\n        let currentIndex = this._filterStackIndex - 1;\n\n        while (currentIndex > 0 && this._filterStack[currentIndex].skip)\n        {\n            --currentIndex;\n        }\n\n        if (currentIndex > 0)\n        {\n            resolution = this._filterStack[currentIndex].inputTexture.source._resolution;\n        }\n\n        const filterUniforms = this._filterGlobalUniforms;\n        const uniforms = filterUniforms.uniforms;\n\n        const outputFrame = uniforms.uOutputFrame;\n        const inputSize = uniforms.uInputSize;\n        const inputPixel = uniforms.uInputPixel;\n        const inputClamp = uniforms.uInputClamp;\n        const globalFrame = uniforms.uGlobalFrame;\n        const outputTexture = uniforms.uOutputTexture;\n\n        // are we rendering back to the original surface?\n        if (isFinalTarget)\n        {\n            let lastIndex = this._filterStackIndex;\n\n            // get previous bounds.. we must take into account skipped filters also..\n            while (lastIndex > 0)\n            {\n                lastIndex--;\n                const filterData = this._filterStack[this._filterStackIndex - 1];\n\n                if (!filterData.skip)\n                {\n                    offset.x = filterData.bounds.minX;\n                    offset.y = filterData.bounds.minY;\n\n                    break;\n                }\n            }\n\n            outputFrame[0] = bounds.minX - offset.x;\n            outputFrame[1] = bounds.minY - offset.y;\n        }\n        else\n        {\n            outputFrame[0] = 0;\n            outputFrame[1] = 0;\n        }\n\n        outputFrame[2] = input.frame.width;\n        outputFrame[3] = input.frame.height;\n\n        inputSize[0] = input.source.width;\n        inputSize[1] = input.source.height;\n        inputSize[2] = 1 / inputSize[0];\n        inputSize[3] = 1 / inputSize[1];\n\n        inputPixel[0] = input.source.pixelWidth;\n        inputPixel[1] = input.source.pixelHeight;\n        inputPixel[2] = 1.0 / inputPixel[0];\n        inputPixel[3] = 1.0 / inputPixel[1];\n\n        inputClamp[0] = 0.5 * inputPixel[2];\n        inputClamp[1] = 0.5 * inputPixel[3];\n        inputClamp[2] = (input.frame.width * inputSize[2]) - (0.5 * inputPixel[2]);\n        inputClamp[3] = (input.frame.height * inputSize[3]) - (0.5 * inputPixel[3]);\n\n        const rootTexture = this.renderer.renderTarget.rootRenderTarget.colorTexture;\n\n        globalFrame[0] = offset.x * resolution;\n        globalFrame[1] = offset.y * resolution;\n\n        globalFrame[2] = rootTexture.source.width * resolution;\n        globalFrame[3] = rootTexture.source.height * resolution;\n\n        // set the output texture - this is where we are going to render to\n\n        const renderTarget = this.renderer.renderTarget.getRenderTarget(output);\n\n        renderer.renderTarget.bind(output, !!clear);\n\n        if (output instanceof Texture)\n        {\n            outputTexture[0] = output.frame.width;\n            outputTexture[1] = output.frame.height;\n        }\n        else\n        {\n            // this means a renderTarget was passed directly\n            outputTexture[0] = renderTarget.width;\n            outputTexture[1] = renderTarget.height;\n        }\n\n        outputTexture[2] = renderTarget.isRoot ? -1 : 1;\n        filterUniforms.update();\n\n        // TODO - should prolly use a adaptor...\n        if ((renderer as WebGPURenderer).renderPipes.uniformBatch)\n        {\n            const batchUniforms = (renderer as WebGPURenderer).renderPipes.uniformBatch\n                .getUboResource(filterUniforms);\n\n            this._globalFilterBindGroup.setResource(batchUniforms, 0);\n        }\n        else\n        {\n            this._globalFilterBindGroup.setResource(filterUniforms, 0);\n        }\n\n        // now lets update the output texture...\n\n        // set bind group..\n        this._globalFilterBindGroup.setResource(input.source, 1);\n        this._globalFilterBindGroup.setResource(input.source.style, 2);\n\n        filter.groups[0] = this._globalFilterBindGroup;\n\n        renderer.encoder.draw({\n            geometry: quadGeometry,\n            shader: filter,\n            state: filter._state,\n            topology: 'triangle-list'\n        });\n\n        // WebGPU blit's automatically, but WebGL does not!\n        if (renderer.type === RendererType.WEBGL)\n        {\n            renderer.renderTarget.finishRenderPass();\n        }\n    }\n\n    private _getFilterData(): FilterData\n    {\n        return {\n            skip: false,\n            inputTexture: null,\n            bounds: new Bounds(),\n            container: null,\n            filterEffect: null,\n            blendRequired: false,\n            previousRenderSurface: null,\n        };\n    }\n\n    /**\n     * Multiply _input normalized coordinates_ to this matrix to get _sprite texture normalized coordinates_.\n     *\n     * Use `outputMatrix * vTextureCoord` in the shader.\n     * @param outputMatrix - The matrix to output to.\n     * @param {Sprite} sprite - The sprite to map to.\n     * @returns The mapped matrix.\n     */\n    public calculateSpriteMatrix(outputMatrix: Matrix, sprite: Sprite): Matrix\n    {\n        const data = this._activeFilterData;\n\n        const mappedMatrix = outputMatrix.set(\n            data.inputTexture._source.width,\n            0, 0,\n            data.inputTexture._source.height,\n            data.bounds.minX, data.bounds.minY\n        );\n\n        const worldTransform = sprite.worldTransform.copyTo(Matrix.shared);\n\n        worldTransform.invert();\n        mappedMatrix.prepend(worldTransform);\n        mappedMatrix.scale(\n            1.0 / sprite.texture.frame.width,\n            1.0 / sprite.texture.frame.height\n        );\n\n        mappedMatrix.translate(sprite.anchor.x, sprite.anchor.y);\n\n        return mappedMatrix;\n    }\n\n    public destroy?: () => void;\n}\n"],"names":["filterData"],"mappings":"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"}