1 | {"version":3,"file":"StencilSystem.js","sources":["../../src/mask/StencilSystem.ts"],"sourcesContent":["import { extensions, ExtensionType } from '@pixi/extensions';\nimport { settings } from '@pixi/settings';\nimport { AbstractMaskSystem } from './AbstractMaskSystem';\n\nimport type { ExtensionMetadata } from '@pixi/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":["AbstractMaskSystem","settings","ExtensionType","extensions"],"mappings":";;AAYO,MAAM,sBAAsBA,mBAAAA,mBACnC;AAAA;AAAA;AAAA;AAAA,EAUI,YAAY,UACZ;AACI,UAAM,QAAQ,GAEd,KAAK,UAAUC,SAAAA,SAAS,QAAQ,yBAA2B,EAAA;AAAA,EAC/D;AAAA,EAEA,iBACA;AACI,UAAM,WAAW,KAAK,UAAU,KAAK,UAAU,SAAS,CAAC;AAErD,WAAA,WAEO,SAAS,kBAGb;AAAA,EACX;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,KAAK,UACL;AACU,UAAA,aAAa,SAAS,YACtB,EAAE,OAAO,KAAK,UACd,gBAAgB,SAAS;AAE3B,sBAAkB,MAGlB,KAAK,SAAS,YAAY,aAAa,GACvC,GAAG,aAAa,CAAC,GACjB,GAAG,MAAM,GAAG,kBAAkB,GAC9B,GAAG,OAAO,GAAG,YAAY,IAG7B,SAAS;AAET,UAAM,YAAY,SAAS;AAEvB,kBAAc,MAEd,SAAS,aAAa,GACtB,GAAG,UAAU,IAAO,IAAO,IAAO,EAAK,IAI3C,GAAG,YAAY,GAAG,OAAO,eAAe,UAAU,GAClD,GAAG,UAAU,GAAG,MAAM,GAAG,MAAM,GAAG,IAAI,GAEtC,WAAW,aAAa,IACxB,WAAW,OAAO,KAAK,QAAQ,GAC/B,KAAK,SAAS,MAAM,MACpB,GAAA,WAAW,aAAa,IAEpB,cAAc,MAEd,SAAS,aAAa,WACtB,GAAG;AAAA,OACE,YAAY,OAAO;AAAA,OACnB,YAAY,OAAO;AAAA,OACnB,YAAY,OAAO;AAAA,OACnB,YAAY,OAAO;AAAA,IAAA,IAI5B,KAAK;EACT;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,IAAI,YACJ;AACU,UAAA,KAAK,KAAK,SAAS;AAErB,QAAA,KAAK,qBAAqB;AAGvB,SAAA,QAAQ,GAAG,YAAY;AAAA,SAG9B;AACI,YAAM,WAAW,KAAK,UAAU,WAAW,IAAI,KAAK,UAAU,KAAK,UAAU,SAAS,CAAC,IAAI,MACrF,YAAY,WAAW,SAAS,aAAa;AAE/C,oBAAc,MAEd,SAAS,aAAa,GACtB,GAAG,UAAU,IAAO,IAAO,IAAO,EAAK,IAI3C,GAAG,UAAU,GAAG,MAAM,GAAG,MAAM,GAAG,IAAI,GAEtC,WAAW,aAAa,IACxB,WAAW,OAAO,KAAK,QAAQ,GAC/B,KAAK,SAAS,MAAM,MACpB,GAAA,WAAW,aAAa,IAEpB,cAAc,MAEd,SAAS,aAAa,WACtB,GAAG;AAAA,SACE,YAAY,OAAS;AAAA,SACrB,YAAY,OAAS;AAAA,SACrB,YAAY,OAAS;AAAA,SACrB,YAAY,OAAS;AAAA,MAAA,IAI9B,KAAK;IACT;AAAA,EACJ;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,cACA;AACU,UAAA,KAAK,KAAK,SAAS;AAEzB,OAAG,YAAY,GAAG,OAAO,KAAK,eAAkB,GAAA,UAAU,GAC1D,GAAG,UAAU,GAAG,MAAM,GAAG,MAAM,GAAG,IAAI;AAAA,EAC1C;AACJ;AA5Ia,cAGF,YAA+B;AAAA,EAClC,MAAMC,WAAc,cAAA;AAAA,EACpB,MAAM;AACV;AAwIJC,WAAAA,WAAW,IAAI,aAAa;;"} |