{"version":3,"file":"StencilSystem.mjs","sources":["../../src/mask/StencilSystem.ts"],"sourcesContent":["import { extensions, ExtensionType } from 'pixijs/extensions';\nimport { settings } from 'pixijs/settings';\nimport { AbstractMaskSystem } from './AbstractMaskSystem';\n\nimport type { ExtensionMetadata } from 'pixijs/extensions';\nimport type { Renderer } from '../Renderer';\nimport type { IMaskTarget, MaskData } from './MaskData';\n\n/**\n * System plugin to the renderer to manage stencils (used for masks).\n * @memberof PIXI\n */\nexport class StencilSystem extends AbstractMaskSystem\n{\n    /** @ignore */\n    static extension: ExtensionMetadata = {\n        type: ExtensionType.RendererSystem,\n        name: 'stencil',\n    };\n\n    /**\n     * @param renderer - The renderer this System works for.\n     */\n    constructor(renderer: Renderer)\n    {\n        super(renderer);\n\n        this.glConst = settings.ADAPTER.getWebGLRenderingContext().STENCIL_TEST;\n    }\n\n    getStackLength(): number\n    {\n        const maskData = this.maskStack[this.maskStack.length - 1];\n\n        if (maskData)\n        {\n            return maskData._stencilCounter;\n        }\n\n        return 0;\n    }\n\n    /**\n     * Applies the Mask and adds it to the current stencil stack.\n     * @param maskData - The mask data\n     */\n    push(maskData: MaskData): void\n    {\n        const maskObject = maskData.maskObject;\n        const { gl } = this.renderer;\n        const prevMaskCount = maskData._stencilCounter;\n\n        if (prevMaskCount === 0)\n        {\n            // force use stencil texture in current framebuffer\n            this.renderer.framebuffer.forceStencil();\n            gl.clearStencil(0);\n            gl.clear(gl.STENCIL_BUFFER_BIT);\n            gl.enable(gl.STENCIL_TEST);\n        }\n\n        maskData._stencilCounter++;\n\n        const colorMask = maskData._colorMask;\n\n        if (colorMask !== 0)\n        {\n            maskData._colorMask = 0;\n            gl.colorMask(false, false, false, false);\n        }\n\n        // Increment the reference stencil value where the new mask overlaps with the old ones.\n        gl.stencilFunc(gl.EQUAL, prevMaskCount, 0xFFFFFFFF);\n        gl.stencilOp(gl.KEEP, gl.KEEP, gl.INCR);\n\n        maskObject.renderable = true;\n        maskObject.render(this.renderer);\n        this.renderer.batch.flush();\n        maskObject.renderable = false;\n\n        if (colorMask !== 0)\n        {\n            maskData._colorMask = colorMask;\n            gl.colorMask(\n                (colorMask & 1) !== 0,\n                (colorMask & 2) !== 0,\n                (colorMask & 4) !== 0,\n                (colorMask & 8) !== 0\n            );\n        }\n\n        this._useCurrent();\n    }\n\n    /**\n     * Pops stencil mask. MaskData is already removed from stack\n     * @param {PIXI.DisplayObject} maskObject - object of popped mask data\n     */\n    pop(maskObject: IMaskTarget): void\n    {\n        const gl = this.renderer.gl;\n\n        if (this.getStackLength() === 0)\n        {\n            // the stack is empty!\n            gl.disable(gl.STENCIL_TEST);\n        }\n        else\n        {\n            const maskData = this.maskStack.length !== 0 ? this.maskStack[this.maskStack.length - 1] : null;\n            const colorMask = maskData ? maskData._colorMask : 0xf;\n\n            if (colorMask !== 0)\n            {\n                maskData._colorMask = 0;\n                gl.colorMask(false, false, false, false);\n            }\n\n            // Decrement the reference stencil value where the popped mask overlaps with the other ones\n            gl.stencilOp(gl.KEEP, gl.KEEP, gl.DECR);\n\n            maskObject.renderable = true;\n            maskObject.render(this.renderer);\n            this.renderer.batch.flush();\n            maskObject.renderable = false;\n\n            if (colorMask !== 0)\n            {\n                maskData._colorMask = colorMask;\n                gl.colorMask(\n                    (colorMask & 0x1) !== 0,\n                    (colorMask & 0x2) !== 0,\n                    (colorMask & 0x4) !== 0,\n                    (colorMask & 0x8) !== 0\n                );\n            }\n\n            this._useCurrent();\n        }\n    }\n\n    /**\n     * Setup renderer to use the current stencil data.\n     * @private\n     */\n    _useCurrent(): void\n    {\n        const gl = this.renderer.gl;\n\n        gl.stencilFunc(gl.EQUAL, this.getStackLength(), 0xFFFFFFFF);\n        gl.stencilOp(gl.KEEP, gl.KEEP, gl.KEEP);\n    }\n}\n\nextensions.add(StencilSystem);\n"],"names":[],"mappings":";;;;AAYO,MAAM,sBAAsB,kBACnC,CAAA;AAAA,EAUI,YAAY,QACZ,EAAA;AACI,IAAA,KAAA,CAAM,QAAQ,CAAA,CAAA;AAEd,IAAA,IAAA,CAAK,OAAU,GAAA,QAAA,CAAS,OAAQ,CAAA,wBAAA,EAA2B,CAAA,YAAA,CAAA;AAAA,GAC/D;AAAA,EAEA,cACA,GAAA;AACI,IAAA,MAAM,QAAW,GAAA,IAAA,CAAK,SAAU,CAAA,IAAA,CAAK,UAAU,MAAS,GAAA,CAAA,CAAA,CAAA;AAExD,IAAA,IAAI,QACJ,EAAA;AACI,MAAA,OAAO,QAAS,CAAA,eAAA,CAAA;AAAA,KACpB;AAEA,IAAO,OAAA,CAAA,CAAA;AAAA,GACX;AAAA,EAMA,KAAK,QACL,EAAA;AACI,IAAA,MAAM,aAAa,QAAS,CAAA,UAAA,CAAA;AAC5B,IAAM,MAAA,EAAE,OAAO,IAAK,CAAA,QAAA,CAAA;AACpB,IAAA,MAAM,gBAAgB,QAAS,CAAA,eAAA,CAAA;AAE/B,IAAA,IAAI,kBAAkB,CACtB,EAAA;AAEI,MAAK,IAAA,CAAA,QAAA,CAAS,YAAY,YAAa,EAAA,CAAA;AACvC,MAAA,EAAA,CAAG,aAAa,CAAC,CAAA,CAAA;AACjB,MAAG,EAAA,CAAA,KAAA,CAAM,GAAG,kBAAkB,CAAA,CAAA;AAC9B,MAAG,EAAA,CAAA,MAAA,CAAO,GAAG,YAAY,CAAA,CAAA;AAAA,KAC7B;AAEA,IAAS,QAAA,CAAA,eAAA,EAAA,CAAA;AAET,IAAA,MAAM,YAAY,QAAS,CAAA,UAAA,CAAA;AAE3B,IAAA,IAAI,cAAc,CAClB,EAAA;AACI,MAAA,QAAA,CAAS,UAAa,GAAA,CAAA,CAAA;AACtB,MAAA,EAAA,CAAG,SAAU,CAAA,KAAA,EAAO,KAAO,EAAA,KAAA,EAAO,KAAK,CAAA,CAAA;AAAA,KAC3C;AAGA,IAAA,EAAA,CAAG,WAAY,CAAA,EAAA,CAAG,KAAO,EAAA,aAAA,EAAe,UAAU,CAAA,CAAA;AAClD,IAAA,EAAA,CAAG,UAAU,EAAG,CAAA,IAAA,EAAM,EAAG,CAAA,IAAA,EAAM,GAAG,IAAI,CAAA,CAAA;AAEtC,IAAA,UAAA,CAAW,UAAa,GAAA,IAAA,CAAA;AACxB,IAAW,UAAA,CAAA,MAAA,CAAO,KAAK,QAAQ,CAAA,CAAA;AAC/B,IAAK,IAAA,CAAA,QAAA,CAAS,MAAM,KAAM,EAAA,CAAA;AAC1B,IAAA,UAAA,CAAW,UAAa,GAAA,KAAA,CAAA;AAExB,IAAA,IAAI,cAAc,CAClB,EAAA;AACI,MAAA,QAAA,CAAS,UAAa,GAAA,SAAA,CAAA;AACtB,MAAA,EAAA,CAAG,SACE,CAAA,CAAA,SAAA,GAAY,CAAO,MAAA,CAAA,EACnB,CAAY,SAAA,GAAA,CAAA,MAAO,CACnB,EAAA,CAAA,SAAA,GAAY,CAAO,MAAA,CAAA,EACnB,CAAY,SAAA,GAAA,CAAA,MAAO,CACxB,CAAA,CAAA;AAAA,KACJ;AAEA,IAAA,IAAA,CAAK,WAAY,EAAA,CAAA;AAAA,GACrB;AAAA,EAMA,IAAI,UACJ,EAAA;AACI,IAAM,MAAA,EAAA,GAAK,KAAK,QAAS,CAAA,EAAA,CAAA;AAEzB,IAAI,IAAA,IAAA,CAAK,cAAe,EAAA,KAAM,CAC9B,EAAA;AAEI,MAAG,EAAA,CAAA,OAAA,CAAQ,GAAG,YAAY,CAAA,CAAA;AAAA,KAG9B,MAAA;AACI,MAAM,MAAA,QAAA,GAAW,IAAK,CAAA,SAAA,CAAU,MAAW,KAAA,CAAA,GAAI,KAAK,SAAU,CAAA,IAAA,CAAK,SAAU,CAAA,MAAA,GAAS,CAAK,CAAA,GAAA,IAAA,CAAA;AAC3F,MAAM,MAAA,SAAA,GAAY,QAAW,GAAA,QAAA,CAAS,UAAa,GAAA,EAAA,CAAA;AAEnD,MAAA,IAAI,cAAc,CAClB,EAAA;AACI,QAAA,QAAA,CAAS,UAAa,GAAA,CAAA,CAAA;AACtB,QAAA,EAAA,CAAG,SAAU,CAAA,KAAA,EAAO,KAAO,EAAA,KAAA,EAAO,KAAK,CAAA,CAAA;AAAA,OAC3C;AAGA,MAAA,EAAA,CAAG,UAAU,EAAG,CAAA,IAAA,EAAM,EAAG,CAAA,IAAA,EAAM,GAAG,IAAI,CAAA,CAAA;AAEtC,MAAA,UAAA,CAAW,UAAa,GAAA,IAAA,CAAA;AACxB,MAAW,UAAA,CAAA,MAAA,CAAO,KAAK,QAAQ,CAAA,CAAA;AAC/B,MAAK,IAAA,CAAA,QAAA,CAAS,MAAM,KAAM,EAAA,CAAA;AAC1B,MAAA,UAAA,CAAW,UAAa,GAAA,KAAA,CAAA;AAExB,MAAA,IAAI,cAAc,CAClB,EAAA;AACI,QAAA,QAAA,CAAS,UAAa,GAAA,SAAA,CAAA;AACtB,QAAA,EAAA,CAAG,SACE,CAAA,CAAA,SAAA,GAAY,CAAS,MAAA,CAAA,EACrB,CAAY,SAAA,GAAA,CAAA,MAAS,CACrB,EAAA,CAAA,SAAA,GAAY,CAAS,MAAA,CAAA,EACrB,CAAY,SAAA,GAAA,CAAA,MAAS,CAC1B,CAAA,CAAA;AAAA,OACJ;AAEA,MAAA,IAAA,CAAK,WAAY,EAAA,CAAA;AAAA,KACrB;AAAA,GACJ;AAAA,EAMA,WACA,GAAA;AACI,IAAM,MAAA,EAAA,GAAK,KAAK,QAAS,CAAA,EAAA,CAAA;AAEzB,IAAA,EAAA,CAAG,YAAY,EAAG,CAAA,KAAA,EAAO,IAAK,CAAA,cAAA,IAAkB,UAAU,CAAA,CAAA;AAC1D,IAAA,EAAA,CAAG,UAAU,EAAG,CAAA,IAAA,EAAM,EAAG,CAAA,IAAA,EAAM,GAAG,IAAI,CAAA,CAAA;AAAA,GAC1C;AACJ,CAAA;AA5Ia,cAGF,SAA+B,GAAA;AAAA,EAClC,MAAM,aAAc,CAAA,cAAA;AAAA,EACpB,IAAM,EAAA,SAAA;AACV,CAAA,CAAA;AAwIJ,UAAA,CAAW,IAAI,aAAa,CAAA;;;;"}