{"version":3,"file":"GlStencilSystem.mjs","sources":["../../../../src/rendering/renderers/gl/GlStencilSystem.ts"],"sourcesContent":["import { ExtensionType } from '../../../extensions/Extensions';\nimport { GpuStencilModesToPixi } from '../gpu/state/GpuStencilModesToPixi';\nimport { STENCIL_MODES } from '../shared/state/const';\n\nimport type { RenderTarget } from '../shared/renderTarget/RenderTarget';\nimport type { System } from '../shared/system/System';\nimport type { WebGLRenderer } from './WebGLRenderer';\n\n/**\n * This manages the stencil buffer. Used primarily for masking\n * @memberof rendering\n */\nexport class GlStencilSystem implements System\n{\n    /** @ignore */\n    public static extension = {\n        type: [\n            ExtensionType.WebGLSystem,\n        ],\n        name: 'stencil',\n    } as const;\n\n    private _gl: WebGLRenderingContext;\n\n    private readonly _stencilCache = {\n        enabled: false,\n        stencilReference: 0,\n        stencilMode: STENCIL_MODES.NONE,\n    };\n\n    private _renderTargetStencilState: Record<number, {\n        stencilMode: STENCIL_MODES;\n        stencilReference: number;\n    }> = Object.create(null);\n\n    private _stencilOpsMapping: {\n        keep: number;\n        zero: number;\n        replace: number;\n        invert: number;\n        'increment-clamp': number;\n        'decrement-clamp': number;\n        'increment-wrap': number;\n        'decrement-wrap': number;\n    };\n\n    private _comparisonFuncMapping: {\n        always: number;\n        never: number;\n        equal: number;\n        'not-equal': number;\n        less: number;\n        'less-equal': number;\n        greater: number;\n        'greater-equal': number;\n    };\n\n    private _activeRenderTarget: RenderTarget;\n\n    constructor(renderer: WebGLRenderer)\n    {\n        renderer.renderTarget.onRenderTargetChange.add(this);\n    }\n\n    protected contextChange(gl: WebGLRenderingContext)\n    {\n        // TODO - this could be declared in a gl const\n        // we know the numbers don't tend to change!\n        this._gl = gl;\n\n        this._comparisonFuncMapping = {\n            always: gl.ALWAYS,\n            never: gl.NEVER,\n            equal: gl.EQUAL,\n            'not-equal': gl.NOTEQUAL,\n            less: gl.LESS,\n            'less-equal': gl.LEQUAL,\n            greater: gl.GREATER,\n            'greater-equal': gl.GEQUAL,\n        };\n\n        this._stencilOpsMapping = {\n            keep: gl.KEEP,\n            zero: gl.ZERO,\n            replace: gl.REPLACE,\n            invert: gl.INVERT,\n            'increment-clamp': gl.INCR,\n            'decrement-clamp': gl.DECR,\n            'increment-wrap': gl.INCR_WRAP,\n            'decrement-wrap': gl.DECR_WRAP,\n        };\n\n        // reset stencil cache\n        this._stencilCache.enabled = false;\n        this._stencilCache.stencilMode = STENCIL_MODES.NONE;\n        this._stencilCache.stencilReference = 0;\n    }\n\n    protected onRenderTargetChange(renderTarget: RenderTarget)\n    {\n        if (this._activeRenderTarget === renderTarget) return;\n\n        this._activeRenderTarget = renderTarget;\n\n        let stencilState = this._renderTargetStencilState[renderTarget.uid];\n\n        if (!stencilState)\n        {\n            stencilState = this._renderTargetStencilState[renderTarget.uid] = {\n                stencilMode: STENCIL_MODES.DISABLED,\n                stencilReference: 0,\n            };\n        }\n\n        // restore the current render targets stencil state..\n        this.setStencilMode(stencilState.stencilMode, stencilState.stencilReference);\n    }\n\n    public setStencilMode(stencilMode: STENCIL_MODES, stencilReference: number)\n    {\n        const stencilState = this._renderTargetStencilState[this._activeRenderTarget.uid];\n\n        const gl = this._gl;\n        const mode = GpuStencilModesToPixi[stencilMode];\n\n        const _stencilCache = this._stencilCache;\n\n        // store the stencil state for restoration later, if a render target changes\n        stencilState.stencilMode = stencilMode;\n        stencilState.stencilReference = stencilReference;\n\n        if (stencilMode === STENCIL_MODES.DISABLED)\n        {\n            if (this._stencilCache.enabled)\n            {\n                this._stencilCache.enabled = false;\n\n                gl.disable(gl.STENCIL_TEST);\n            }\n\n            return;\n        }\n\n        if (!this._stencilCache.enabled)\n        {\n            this._stencilCache.enabled = true;\n            gl.enable(gl.STENCIL_TEST);\n        }\n\n        if (stencilMode !== _stencilCache.stencilMode || _stencilCache.stencilReference !== stencilReference)\n        {\n            _stencilCache.stencilMode = stencilMode;\n            _stencilCache.stencilReference = stencilReference;\n\n            // this is pretty simple mapping.\n            // will work for pixi's simple mask cases.\n            // although a true mapping of the GPU state to webGL state should be done\n            gl.stencilFunc(this._comparisonFuncMapping[mode.stencilBack.compare], stencilReference, 0xFF);\n            gl.stencilOp(gl.KEEP, gl.KEEP, this._stencilOpsMapping[mode.stencilBack.passOp]);\n        }\n    }\n\n    public destroy?: () => void;\n}\n"],"names":[],"mappings":"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"}