{"version":3,"file":"ContextSystem.mjs","sources":["../../src/context/ContextSystem.ts"],"sourcesContent":["import { ENV } from '@pixi/constants';\nimport { extensions, ExtensionType } from '@pixi/extensions';\nimport { settings } from '@pixi/settings';\n\nimport type { ExtensionMetadata } from '@pixi/extensions';\nimport type { ICanvas } from '@pixi/settings';\nimport type { IRenderingContext } from '../IRenderer';\nimport type { Renderer } from '../Renderer';\nimport type { ISystem } from '../system/ISystem';\nimport type { WebGLExtensions } from './WebGLExtensions';\n\nlet CONTEXT_UID_COUNTER = 0;\n\n/**\n * Options for the context system.\n * @memberof PIXI\n */\nexport interface ContextSystemOptions\n{\n    /**\n     * **Deprecated since 7.0.0, use `premultipliedAlpha` and `backgroundAlpha` instead.**\n     *\n     * Pass-through value for canvas' context attribute `alpha`. This option is for cases where the\n     * canvas needs to be opaque, possibly for performance reasons on some older devices.\n     * If you want to set transparency, please use `backgroundAlpha`.\n     *\n     * **WebGL Only:** When set to `'notMultiplied'`, the canvas' context attribute `alpha` will be\n     * set to `true` and `premultipliedAlpha` will be to `false`.\n     * @deprecated since 7.0.0\n     * @memberof PIXI.IRendererOptions\n     */\n    useContextAlpha?: boolean | 'notMultiplied';\n    /**\n     * **WebGL Only.** User-provided WebGL rendering context object.\n     * @memberof PIXI.IRendererOptions\n     */\n    context: IRenderingContext | null;\n    /**\n     * **WebGL Only.** Whether to enable anti-aliasing. This may affect performance.\n     * @memberof PIXI.IRendererOptions\n     */\n    antialias: boolean;\n    /**\n     * **WebGL Only.** A hint indicating what configuration of GPU is suitable for the WebGL context,\n     * can be `'default'`, `'high-performance'` or `'low-power'`.\n     * Setting to `'high-performance'` will prioritize rendering performance over power consumption,\n     * while setting to `'low-power'` will prioritize power saving over rendering performance.\n     * @memberof PIXI.IRendererOptions\n     */\n    powerPreference: WebGLPowerPreference;\n    /**\n     * **WebGL Only.** Whether the compositor will assume the drawing buffer contains colors with premultiplied alpha.\n     * @memberof PIXI.IRendererOptions\n     */\n    premultipliedAlpha: boolean;\n    /**\n     * **WebGL Only.** Whether to enable drawing buffer preservation. If enabled, the drawing buffer will preserve\n     * its value until cleared or overwritten. Enable this if you need to call `toDataUrl` on the WebGL context.\n     * @memberof PIXI.IRendererOptions\n     */\n    preserveDrawingBuffer: boolean;\n}\n\nexport interface ISupportDict\n{\n    uint32Indices: boolean;\n}\n\n/**\n * System plugin to the renderer to manage the context.\n * @memberof PIXI\n */\nexport class ContextSystem implements ISystem<ContextSystemOptions>\n{\n    /** @ignore */\n    static defaultOptions: ContextSystemOptions = {\n        /**\n         * {@link PIXI.IRendererOptions.context}\n         * @default null\n         * @memberof PIXI.settings.RENDER_OPTIONS\n         */\n        context: null,\n        /**\n         * {@link PIXI.IRendererOptions.antialias}\n         * @default false\n         * @memberof PIXI.settings.RENDER_OPTIONS\n         */\n        antialias: false,\n        /**\n         * {@link PIXI.IRendererOptions.premultipliedAlpha}\n         * @default true\n         * @memberof PIXI.settings.RENDER_OPTIONS\n         */\n        premultipliedAlpha: true,\n        /**\n         * {@link PIXI.IRendererOptions.preserveDrawingBuffer}\n         * @default false\n         * @memberof PIXI.settings.RENDER_OPTIONS\n         */\n        preserveDrawingBuffer: false,\n        /**\n         * {@link PIXI.IRendererOptions.powerPreference}\n         * @default default\n         * @memberof PIXI.settings.RENDER_OPTIONS\n         */\n        powerPreference: 'default',\n    };\n    /** @ignore */\n    static extension: ExtensionMetadata = {\n        type: ExtensionType.RendererSystem,\n        name: 'context',\n    };\n\n    /**\n     * Either 1 or 2 to reflect the WebGL version being used.\n     * @readonly\n     */\n    public webGLVersion: number;\n\n    /**\n     * Features supported by current context.\n     * @type {object}\n     * @readonly\n     * @property {boolean} uint32Indices - Support for 32-bit indices buffer.\n     */\n    readonly supports: ISupportDict;\n\n    preserveDrawingBuffer: boolean;\n    powerPreference: WebGLPowerPreference;\n\n    /**\n     * Pass-thru setting for the canvas' context `alpha` property. This is typically\n     * not something you need to fiddle with. If you want transparency, use `backgroundAlpha`.\n     * @member {boolean}\n     * @deprecated since 7.0.0\n     */\n    useContextAlpha: boolean | 'notMultiplied';\n\n    protected CONTEXT_UID: number;\n    protected gl: IRenderingContext;\n\n    /**\n     * Extensions available.\n     * @type {object}\n     * @readonly\n     * @property {WEBGL_draw_buffers} drawBuffers - WebGL v1 extension\n     * @property {WEBGL_depth_texture} depthTexture - WebGL v1 extension\n     * @property {OES_texture_float} floatTexture - WebGL v1 extension\n     * @property {WEBGL_lose_context} loseContext - WebGL v1 extension\n     * @property {OES_vertex_array_object} vertexArrayObject - WebGL v1 extension\n     * @property {EXT_texture_filter_anisotropic} anisotropicFiltering - WebGL v1 and v2 extension\n     */\n    public extensions: WebGLExtensions;\n\n    private renderer: Renderer;\n\n    /** @param renderer - The renderer this System works for. */\n    constructor(renderer: Renderer)\n    {\n        this.renderer = renderer;\n\n        this.webGLVersion = 1;\n        this.extensions = {};\n\n        this.supports = {\n            uint32Indices: false,\n        };\n\n        // Bind functions\n        this.handleContextLost = this.handleContextLost.bind(this);\n        this.handleContextRestored = this.handleContextRestored.bind(this);\n    }\n\n    /**\n     * `true` if the context is lost\n     * @readonly\n     */\n    get isLost(): boolean\n    {\n        return (!this.gl || this.gl.isContextLost());\n    }\n\n    /**\n     * Handles the context change event.\n     * @param {WebGLRenderingContext} gl - New WebGL context.\n     */\n    protected contextChange(gl: IRenderingContext): void\n    {\n        this.gl = gl;\n        this.renderer.gl = gl;\n        this.renderer.CONTEXT_UID = CONTEXT_UID_COUNTER++;\n    }\n\n    init(options: ContextSystemOptions): void\n    {\n        /*\n         * The options passed in to create a new WebGL context.\n         */\n        if (options.context)\n        {\n            this.initFromContext(options.context);\n        }\n        else\n        {\n            const alpha = this.renderer.background.alpha < 1;\n            const premultipliedAlpha = options.premultipliedAlpha;\n\n            this.preserveDrawingBuffer = options.preserveDrawingBuffer;\n            this.useContextAlpha = options.useContextAlpha;\n            this.powerPreference = options.powerPreference;\n\n            this.initFromOptions({\n                alpha,\n                premultipliedAlpha,\n                antialias: options.antialias,\n                stencil: true,\n                preserveDrawingBuffer: options.preserveDrawingBuffer,\n                powerPreference: options.powerPreference,\n            });\n        }\n    }\n\n    /**\n     * Initializes the context.\n     * @protected\n     * @param {WebGLRenderingContext} gl - WebGL context\n     */\n    initFromContext(gl: IRenderingContext): void\n    {\n        this.gl = gl;\n        this.validateContext(gl);\n        this.renderer.gl = gl;\n        this.renderer.CONTEXT_UID = CONTEXT_UID_COUNTER++;\n        this.renderer.runners.contextChange.emit(gl);\n\n        const view = this.renderer.view;\n\n        if (view.addEventListener !== undefined)\n        {\n            view.addEventListener('webglcontextlost', this.handleContextLost, false);\n            view.addEventListener('webglcontextrestored', this.handleContextRestored, false);\n        }\n    }\n\n    /**\n     * Initialize from context options\n     * @protected\n     * @see https://developer.mozilla.org/en-US/docs/Web/API/HTMLCanvasElement/getContext\n     * @param {object} options - context attributes\n     */\n    initFromOptions(options: WebGLContextAttributes): void\n    {\n        const gl = this.createContext(this.renderer.view, options);\n\n        this.initFromContext(gl);\n    }\n\n    /**\n     * Helper class to create a WebGL Context\n     * @param canvas - the canvas element that we will get the context from\n     * @param options - An options object that gets passed in to the canvas element containing the\n     *    context attributes\n     * @see https://developer.mozilla.org/en/docs/Web/API/HTMLCanvasElement/getContext\n     * @returns {WebGLRenderingContext} the WebGL context\n     */\n    createContext(canvas: ICanvas, options: WebGLContextAttributes): IRenderingContext\n    {\n        let gl;\n\n        if (settings.PREFER_ENV >= ENV.WEBGL2)\n        {\n            gl = canvas.getContext('webgl2', options);\n        }\n\n        if (gl)\n        {\n            this.webGLVersion = 2;\n        }\n        else\n        {\n            this.webGLVersion = 1;\n\n            gl = canvas.getContext('webgl', options) || canvas.getContext('experimental-webgl', options);\n\n            if (!gl)\n            {\n                // fail, not able to get a context\n                throw new Error('This browser does not support WebGL. Try using the canvas renderer');\n            }\n        }\n\n        this.gl = gl as IRenderingContext;\n\n        this.getExtensions();\n\n        return this.gl;\n    }\n\n    /** Auto-populate the {@link PIXI.ContextSystem.extensions extensions}. */\n    protected getExtensions(): void\n    {\n        // time to set up default extensions that Pixi uses.\n        const { gl } = this;\n\n        const common = {\n            loseContext: gl.getExtension('WEBGL_lose_context'),\n            anisotropicFiltering: gl.getExtension('EXT_texture_filter_anisotropic'),\n            floatTextureLinear: gl.getExtension('OES_texture_float_linear'),\n\n            s3tc: gl.getExtension('WEBGL_compressed_texture_s3tc'),\n            s3tc_sRGB: gl.getExtension('WEBGL_compressed_texture_s3tc_srgb'), // eslint-disable-line camelcase\n            etc: gl.getExtension('WEBGL_compressed_texture_etc'),\n            etc1: gl.getExtension('WEBGL_compressed_texture_etc1'),\n            pvrtc: gl.getExtension('WEBGL_compressed_texture_pvrtc')\n                || gl.getExtension('WEBKIT_WEBGL_compressed_texture_pvrtc'),\n            atc: gl.getExtension('WEBGL_compressed_texture_atc'),\n            astc: gl.getExtension('WEBGL_compressed_texture_astc')\n        };\n\n        if (this.webGLVersion === 1)\n        {\n            Object.assign(this.extensions, common, {\n                drawBuffers: gl.getExtension('WEBGL_draw_buffers'),\n                depthTexture: gl.getExtension('WEBGL_depth_texture'),\n                vertexArrayObject: gl.getExtension('OES_vertex_array_object')\n                    || gl.getExtension('MOZ_OES_vertex_array_object')\n                    || gl.getExtension('WEBKIT_OES_vertex_array_object'),\n                uint32ElementIndex: gl.getExtension('OES_element_index_uint'),\n                // Floats and half-floats\n                floatTexture: gl.getExtension('OES_texture_float'),\n                floatTextureLinear: gl.getExtension('OES_texture_float_linear'),\n                textureHalfFloat: gl.getExtension('OES_texture_half_float'),\n                textureHalfFloatLinear: gl.getExtension('OES_texture_half_float_linear'),\n            });\n        }\n        else if (this.webGLVersion === 2)\n        {\n            Object.assign(this.extensions, common, {\n                // Floats and half-floats\n                colorBufferFloat: gl.getExtension('EXT_color_buffer_float')\n            });\n        }\n    }\n\n    /**\n     * Handles a lost webgl context\n     * @param {WebGLContextEvent} event - The context lost event.\n     */\n    protected handleContextLost(event: WebGLContextEvent): void\n    {\n        // Prevent default to be able to restore the context\n        event.preventDefault();\n\n        // Restore the context after this event has exited\n        setTimeout(() =>\n        {\n            if (this.gl.isContextLost() && this.extensions.loseContext)\n            {\n                this.extensions.loseContext.restoreContext();\n            }\n        }, 0);\n    }\n\n    /** Handles a restored webgl context. */\n    protected handleContextRestored(): void\n    {\n        this.renderer.runners.contextChange.emit(this.gl);\n    }\n\n    destroy(): void\n    {\n        const view = this.renderer.view;\n\n        this.renderer = null;\n\n        // remove listeners\n        if (view.removeEventListener !== undefined)\n        {\n            view.removeEventListener('webglcontextlost', this.handleContextLost);\n            view.removeEventListener('webglcontextrestored', this.handleContextRestored);\n        }\n\n        this.gl.useProgram(null);\n\n        if (this.extensions.loseContext)\n        {\n            this.extensions.loseContext.loseContext();\n        }\n    }\n\n    /** Handle the post-render runner event. */\n    protected postrender(): void\n    {\n        if (this.renderer.objectRenderer.renderingToScreen)\n        {\n            this.gl.flush();\n        }\n    }\n\n    /**\n     * Validate context.\n     * @param {WebGLRenderingContext} gl - Render context.\n     */\n    protected validateContext(gl: IRenderingContext): void\n    {\n        const attributes = gl.getContextAttributes();\n\n        const isWebGl2 = 'WebGL2RenderingContext' in globalThis && gl instanceof globalThis.WebGL2RenderingContext;\n\n        if (isWebGl2)\n        {\n            this.webGLVersion = 2;\n        }\n\n        // this is going to be fairly simple for now.. but at least we have room to grow!\n        if (attributes && !attributes.stencil)\n        {\n            /* eslint-disable max-len, no-console */\n            console.warn('Provided WebGL context does not have a stencil buffer, masks may not render correctly');\n            /* eslint-enable max-len, no-console */\n        }\n\n        const hasuint32 = isWebGl2 || !!(gl as WebGLRenderingContext).getExtension('OES_element_index_uint');\n\n        this.supports.uint32Indices = hasuint32;\n\n        if (!hasuint32)\n        {\n            /* eslint-disable max-len, no-console */\n            console.warn('Provided WebGL context does not support 32 index buffer, complex graphics may not render correctly');\n            /* eslint-enable max-len, no-console */\n        }\n    }\n}\n\nextensions.add(ContextSystem);\n"],"names":[],"mappings":"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"}