{"version":3,"file":"RenderTargetSystem.mjs","sources":["../../../../../src/rendering/renderers/shared/renderTarget/RenderTargetSystem.ts"],"sourcesContent":["import { Matrix } from '../../../../maths/matrix/Matrix';\nimport { Rectangle } from '../../../../maths/shapes/Rectangle';\nimport { CLEAR } from '../../gl/const';\nimport { calculateProjection } from '../../gpu/renderTarget/calculateProjection';\nimport { SystemRunner } from '../system/SystemRunner';\nimport { CanvasSource } from '../texture/sources/CanvasSource';\nimport { TextureSource } from '../texture/sources/TextureSource';\nimport { Texture } from '../texture/Texture';\nimport { getCanvasTexture } from '../texture/utils/getCanvasTexture';\nimport { isRenderingToScreen } from './isRenderingToScreen';\nimport { RenderTarget } from './RenderTarget';\n\nimport type { RgbaArray } from '../../../../color/Color';\nimport type { ICanvas } from '../../../../environment/canvas/ICanvas';\nimport type { CLEAR_OR_BOOL } from '../../gl/const';\nimport type { GlRenderTarget } from '../../gl/GlRenderTarget';\nimport type { GpuRenderTarget } from '../../gpu/renderTarget/GpuRenderTarget';\nimport type { Renderer } from '../../types';\nimport type { System } from '../system/System';\nimport type { BindableTexture } from '../texture/Texture';\n\n/**\n * A render surface is a texture, canvas, or render target\n * @memberof rendering\n * @see environment.ICanvas\n * @see rendering.Texture\n * @see rendering.RenderTarget\n */\nexport type RenderSurface = ICanvas | BindableTexture | RenderTarget;\n\n/**\n * stores a render target and its frame\n * @ignore\n */\ninterface RenderTargetAndFrame\n{\n    /** the render target */\n    renderTarget: RenderTarget;\n    /** the frame to use when using the render target */\n    frame: Rectangle\n}\n\n/**\n * An adaptor interface for RenderTargetSystem to support WebGL and WebGPU.\n * This is used internally by the renderer, and is not intended to be used directly.\n * @ignore\n */\nexport interface RenderTargetAdaptor<RENDER_TARGET extends GlRenderTarget | GpuRenderTarget>\n{\n    init(\n        /** the renderer */\n        renderer: Renderer,\n        /** the render target system */\n        renderTargetSystem: RenderTargetSystem<RENDER_TARGET>\n    ): void\n\n    /** A function copies the contents of a render surface to a texture */\n    copyToTexture(\n        /** the render surface to copy from  */\n        sourceRenderSurfaceTexture: RenderTarget,\n        /** the texture to copy to */\n        destinationTexture: Texture,\n        /** the origin of the copy */\n        originSrc: { x: number; y: number },\n        /** the size of the copy */\n        size: { width: number; height: number },\n        /** the destination origin (top left to paste from!) */\n        originDest?: { x: number; y: number },\n    ): Texture\n\n    /** starts a render pass on the render target */\n    startRenderPass(\n        /** the render target to start the render pass on */\n        renderTarget: RenderTarget,\n        /* the clear mode to use. Can be true or a CLEAR number 'COLOR | DEPTH | STENCIL' 0b111* */\n        clear: CLEAR_OR_BOOL,\n        /** the color to clear to */\n        clearColor?: RgbaArray,\n        /** the viewport to use */\n        viewport?: Rectangle\n    ): void\n\n    /** clears the current render target to the specified color */\n    clear(\n        /** the render target to clear */\n        renderTarget: RenderTarget,\n        /** the clear mode to use. Can be true or a CLEAR number 'COLOR | DEPTH | STENCIL' 0b111 */\n        clear: CLEAR_OR_BOOL,\n        /** the color to clear to   */\n        clearColor?: RgbaArray,\n        /** the viewport to use */\n        viewport?: Rectangle\n    ): void\n\n    /** finishes the current render pass */\n    finishRenderPass(renderTarget: RenderTarget): void\n\n    /**\n     * initializes a gpu render target. Both renderers use this function to initialize a gpu render target\n     * Its different type of object depending on the renderer.\n     */\n    initGpuRenderTarget(\n        /** the render target to initialize */\n        renderTarget: RenderTarget\n    ): RENDER_TARGET\n\n    /** called when a render target is resized */\n    resizeGpuRenderTarget(\n        /** the render target to resize */\n        renderTarget: RenderTarget\n    ): void\n\n    /** destroys the gpu render target */\n    destroyGpuRenderTarget(\n        /** the render target to destroy */\n        gpuRenderTarget: RENDER_TARGET\n    ): void\n}\n\n/**\n * A system that manages render targets. A render target is essentially a place where the shaders can color in the pixels.\n * The render target system is responsible for binding the render target to the renderer, and managing the viewport.\n * Render targets can be pushed and popped.\n *\n * To make it easier, you can also bind textures and canvases too. This will automatically create a render target for you.\n * The render target itself is a lot more powerful than just a texture or canvas,\n * as it can have multiple textures attached to it.\n * It will also give ou fine grain control over the stencil buffer / depth texture.\n * @example\n *\n * ```js\n *\n * // create a render target\n * const renderTarget = new RenderTarget({\n *   colorTextures: [new TextureSource({ width: 100, height: 100 })],\n * });\n *\n * // bind the render target\n * renderer.renderTarget.bind(renderTarget);\n *\n * // draw something!\n * ```\n * @memberof rendering\n */\nexport class RenderTargetSystem<RENDER_TARGET extends GlRenderTarget | GpuRenderTarget> implements System\n{\n    /** When rendering of a scene begins, this is where the root render surface is stored */\n    public rootRenderTarget: RenderTarget;\n    /** This is the root viewport for the render pass*/\n    public rootViewPort = new Rectangle();\n    /** A boolean that lets the dev know if the current render pass is rendering to the screen. Used by some plugins */\n    public renderingToScreen: boolean;\n    /** the current active render target */\n    public renderTarget: RenderTarget;\n    /** the current active render surface that the render target is created from */\n    public renderSurface: RenderSurface;\n    /** the current viewport that the gpu is using */\n    public readonly viewport = new Rectangle();\n    /**\n     * a runner that lets systems know if the active render target has changed.\n     * Eg the Stencil System needs to know so it can manage the stencil buffer\n     */\n    public readonly onRenderTargetChange = new SystemRunner('onRenderTargetChange');\n    /** the projection matrix that is used by the shaders based on the active render target and the viewport */\n    public readonly projectionMatrix = new Matrix();\n    /** the default clear color for render targets */\n    public readonly defaultClearColor: RgbaArray = [0, 0, 0, 0];\n    /** a reference to the adaptor that interfaces with WebGL / WebGP */\n    public readonly adaptor: RenderTargetAdaptor<RENDER_TARGET>;\n    /**\n     * a hash that stores the render target for a given render surface. When you pass in a texture source,\n     * a render target is created for it. This map stores and makes it easy to retrieve the render target\n     */\n    private readonly _renderSurfaceToRenderTargetHash: Map<RenderSurface, RenderTarget>\n        = new Map();\n    /** A hash that stores a gpu render target for a given render target. */\n    private _gpuRenderTargetHash: Record<number, RENDER_TARGET> = Object.create(null);\n    /**\n     * A stack that stores the render target and frame that is currently being rendered to.\n     * When push is called, the current render target is stored in this stack.\n     * When pop is called, the previous render target is restored.\n     */\n    private readonly _renderTargetStack: RenderTargetAndFrame[] = [];\n    /** A reference to the renderer */\n    private readonly _renderer: Renderer;\n\n    constructor(renderer: Renderer)\n    {\n        this._renderer = renderer;\n    }\n\n    /** called when dev wants to finish a render pass */\n    public finishRenderPass()\n    {\n        this.adaptor.finishRenderPass(this.renderTarget);\n    }\n\n    /**\n     * called when the renderer starts to render a scene.\n     * @param options\n     * @param options.target - the render target to render to\n     * @param options.clear - the clear mode to use. Can be true or a CLEAR number 'COLOR | DEPTH | STENCIL' 0b111\n     * @param options.clearColor - the color to clear to\n     * @param options.frame - the frame to render to\n     */\n    public renderStart({\n        target,\n        clear,\n        clearColor,\n        frame\n    }: {\n        target: RenderSurface;\n        clear: CLEAR_OR_BOOL;\n        clearColor: RgbaArray;\n        frame?: Rectangle\n    }): void\n    {\n        // TODO no need to reset this - use optimised index instead\n        this._renderTargetStack.length = 0;\n\n        this.push(\n            target,\n            clear,\n            clearColor,\n            frame\n        );\n\n        this.rootViewPort.copyFrom(this.viewport);\n        this.rootRenderTarget = this.renderTarget;\n        this.renderingToScreen = isRenderingToScreen(this.rootRenderTarget);\n    }\n\n    /**\n     * Binding a render surface! This is the main function of the render target system.\n     * It will take the RenderSurface (which can be a texture, canvas, or render target) and bind it to the renderer.\n     * Once bound all draw calls will be rendered to the render surface.\n     *\n     * If a frame is not provide and the render surface is a texture, the frame of the texture will be used.\n     * @param renderSurface - the render surface to bind\n     * @param clear - the clear mode to use. Can be true or a CLEAR number 'COLOR | DEPTH | STENCIL' 0b111\n     * @param clearColor - the color to clear to\n     * @param frame - the frame to render to\n     * @returns the render target that was bound\n     */\n    public bind(\n        renderSurface: RenderSurface,\n        clear: CLEAR_OR_BOOL = true,\n        clearColor?: RgbaArray,\n        frame?: Rectangle\n    ): RenderTarget\n    {\n        const renderTarget = this.getRenderTarget(renderSurface);\n\n        const didChange = this.renderTarget !== renderTarget;\n\n        this.renderTarget = renderTarget;\n        this.renderSurface = renderSurface;\n\n        const gpuRenderTarget = this.getGpuRenderTarget(renderTarget);\n\n        if (renderTarget.pixelWidth !== gpuRenderTarget.width\n            || renderTarget.pixelHeight !== gpuRenderTarget.height)\n        {\n            this.adaptor.resizeGpuRenderTarget(renderTarget);\n\n            gpuRenderTarget.width = renderTarget.pixelWidth;\n            gpuRenderTarget.height = renderTarget.pixelHeight;\n        }\n\n        const source = renderTarget.colorTexture;\n        const viewport = this.viewport;\n\n        const pixelWidth = source.pixelWidth;\n        const pixelHeight = source.pixelHeight;\n\n        if (!frame && renderSurface instanceof Texture)\n        {\n            frame = renderSurface.frame;\n        }\n\n        if (frame)\n        {\n            const resolution = source._resolution;\n\n            viewport.x = ((frame.x * resolution) + 0.5) | 0;\n            viewport.y = ((frame.y * resolution) + 0.5) | 0;\n            viewport.width = ((frame.width * resolution) + 0.5) | 0;\n            viewport.height = ((frame.height * resolution) + 0.5) | 0;\n        }\n        else\n        {\n            viewport.x = 0;\n            viewport.y = 0;\n            viewport.width = pixelWidth;\n            viewport.height = pixelHeight;\n        }\n\n        calculateProjection(\n            this.projectionMatrix,\n            0, 0,\n            viewport.width / source.resolution,\n            viewport.height / source.resolution,\n            !renderTarget.isRoot\n        );\n\n        this.adaptor.startRenderPass(renderTarget, clear, clearColor, viewport);\n\n        if (didChange)\n        {\n            this.onRenderTargetChange.emit(renderTarget);\n        }\n\n        return renderTarget;\n    }\n\n    public clear(\n        target?: RenderSurface,\n        clear: CLEAR_OR_BOOL = CLEAR.ALL,\n        clearColor?: RgbaArray,\n    )\n    {\n        if (!clear) return;\n\n        if (target)\n        {\n            target = this.getRenderTarget(target);\n        }\n\n        this.adaptor.clear(\n            (target as RenderTarget) || this.renderTarget,\n            clear,\n            clearColor,\n            this.viewport\n        );\n    }\n\n    protected contextChange(): void\n    {\n        this._gpuRenderTargetHash = Object.create(null);\n    }\n\n    /**\n     * Push a render surface to the renderer. This will bind the render surface to the renderer,\n     * @param renderSurface - the render surface to push\n     * @param clear - the clear mode to use. Can be true or a CLEAR number 'COLOR | DEPTH | STENCIL' 0b111\n     * @param clearColor - the color to clear to\n     * @param frame - the frame to use when rendering to the render surface\n     */\n    public push(\n        renderSurface: RenderSurface,\n        clear: CLEAR | boolean = CLEAR.ALL,\n        clearColor?: RgbaArray,\n        frame?: Rectangle\n    )\n    {\n        const renderTarget = this.bind(renderSurface, clear, clearColor, frame);\n\n        this._renderTargetStack.push({\n            renderTarget,\n            frame,\n        });\n\n        return renderTarget;\n    }\n\n    /** Pops the current render target from the renderer and restores the previous render target. */\n    public pop()\n    {\n        this._renderTargetStack.pop();\n\n        const currentRenderTargetData = this._renderTargetStack[this._renderTargetStack.length - 1];\n\n        this.bind(currentRenderTargetData.renderTarget, false, null, currentRenderTargetData.frame);\n    }\n\n    /**\n     * Gets the render target from the provide render surface. Eg if its a texture,\n     * it will return the render target for the texture.\n     * If its a render target, it will return the same render target.\n     * @param renderSurface - the render surface to get the render target for\n     * @returns the render target for the render surface\n     */\n    public getRenderTarget(renderSurface: RenderSurface): RenderTarget\n    {\n        if (((renderSurface as Texture).isTexture))\n        {\n            renderSurface = (renderSurface as Texture).source;\n        }\n\n        return this._renderSurfaceToRenderTargetHash.get(renderSurface)\n        ?? this._initRenderTarget(renderSurface);\n    }\n\n    /**\n     * Copies a render surface to another texture\n     * @param sourceRenderSurfaceTexture - the render surface to copy from\n     * @param destinationTexture - the texture to copy to\n     * @param originSrc - the origin of the copy\n     * @param originSrc.x - the x origin of the copy\n     * @param originSrc.y - the y origin of the copy\n     * @param size - the size of the copy\n     * @param size.width - the width of the copy\n     * @param size.height - the height of the copy\n     * @param originDest - the destination origin (top left to paste from!)\n     * @param originDest.x - the x origin of the paste\n     * @param originDest.y - the y origin of the paste\n     */\n    public copyToTexture(\n        sourceRenderSurfaceTexture: RenderTarget,\n        destinationTexture: Texture,\n        originSrc: { x: number; y: number },\n        size: { width: number; height: number },\n        originDest: { x: number; y: number; },\n    )\n    {\n        // fit the size to the source we don't want to go out of bounds\n\n        if (originSrc.x < 0)\n        {\n            size.width += originSrc.x;\n            originDest.x -= originSrc.x;\n            originSrc.x = 0;\n        }\n\n        if (originSrc.y < 0)\n        {\n            size.height += originSrc.y;\n            originDest.y -= originSrc.y;\n            originSrc.y = 0;\n        }\n\n        const { pixelWidth, pixelHeight } = sourceRenderSurfaceTexture;\n\n        size.width = Math.min(size.width, pixelWidth - originSrc.x);\n        size.height = Math.min(size.height, pixelHeight - originSrc.y);\n\n        return this.adaptor.copyToTexture(\n            sourceRenderSurfaceTexture,\n            destinationTexture,\n            originSrc,\n            size,\n            originDest\n        );\n    }\n\n    /**\n     * ensures that we have a depth stencil buffer available to render to\n     * This is used by the mask system to make sure we have a stencil buffer.\n     */\n    public ensureDepthStencil()\n    {\n        if (!this.renderTarget.stencil)\n        {\n            this.renderTarget.stencil = true;\n\n            this.adaptor.startRenderPass(this.renderTarget, false, null, this.viewport);\n        }\n    }\n\n    /** nukes the render target system */\n    public destroy()\n    {\n        (this._renderer as null) = null;\n\n        this._renderSurfaceToRenderTargetHash.forEach((renderTarget, key) =>\n        {\n            if (renderTarget !== key)\n            {\n                renderTarget.destroy();\n            }\n        });\n\n        this._renderSurfaceToRenderTargetHash.clear();\n\n        this._gpuRenderTargetHash = Object.create(null);\n    }\n\n    private _initRenderTarget(renderSurface: RenderSurface): RenderTarget\n    {\n        let renderTarget: RenderTarget = null;\n\n        if (CanvasSource.test(renderSurface))\n        {\n            renderSurface = getCanvasTexture(renderSurface as ICanvas).source;\n        }\n\n        if (renderSurface instanceof RenderTarget)\n        {\n            renderTarget = renderSurface;\n        }\n        else if (renderSurface instanceof TextureSource)\n        {\n            renderTarget = new RenderTarget({\n                colorTextures: [renderSurface],\n            });\n\n            if (CanvasSource.test(renderSurface.source.resource))\n            {\n                renderTarget.isRoot = true;\n            }\n\n            // TODO add a test for this\n            renderSurface.once('destroy', () =>\n            {\n                renderTarget.destroy();\n\n                this._renderSurfaceToRenderTargetHash.delete(renderSurface);\n\n                const gpuRenderTarget = this._gpuRenderTargetHash[renderTarget.uid];\n\n                if (gpuRenderTarget)\n                {\n                    this._gpuRenderTargetHash[renderTarget.uid] = null;\n                    this.adaptor.destroyGpuRenderTarget(gpuRenderTarget);\n                }\n            });\n        }\n\n        this._renderSurfaceToRenderTargetHash.set(renderSurface, renderTarget);\n\n        return renderTarget;\n    }\n\n    public getGpuRenderTarget(renderTarget: RenderTarget)\n    {\n        return this._gpuRenderTargetHash[renderTarget.uid]\n        || (this._gpuRenderTargetHash[renderTarget.uid] = this.adaptor.initGpuRenderTarget(renderTarget));\n    }\n}\n"],"names":[],"mappings":"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"}