@pixi/core
Version:
Core PixiJS
168 lines (165 loc) • 6.04 kB
JavaScript
import { ENV } from '@pixi/constants';
import { ExtensionType, extensions } from '@pixi/extensions';
import { settings } from '@pixi/settings';
let CONTEXT_UID_COUNTER = 0;
class ContextSystem {
constructor(renderer) {
this.renderer = renderer;
this.webGLVersion = 1;
this.extensions = {};
this.supports = {
uint32Indices: false
};
this.handleContextLost = this.handleContextLost.bind(this);
this.handleContextRestored = this.handleContextRestored.bind(this);
}
get isLost() {
return !this.gl || this.gl.isContextLost();
}
contextChange(gl) {
this.gl = gl;
this.renderer.gl = gl;
this.renderer.CONTEXT_UID = CONTEXT_UID_COUNTER++;
}
init(options) {
if (options.context) {
this.initFromContext(options.context);
} else {
const alpha = this.renderer.background.alpha < 1;
const premultipliedAlpha = options.premultipliedAlpha;
this.preserveDrawingBuffer = options.preserveDrawingBuffer;
this.useContextAlpha = options.useContextAlpha;
this.powerPreference = options.powerPreference;
this.initFromOptions({
alpha,
premultipliedAlpha,
antialias: options.antialias,
stencil: true,
preserveDrawingBuffer: options.preserveDrawingBuffer,
powerPreference: options.powerPreference
});
}
}
initFromContext(gl) {
this.gl = gl;
this.validateContext(gl);
this.renderer.gl = gl;
this.renderer.CONTEXT_UID = CONTEXT_UID_COUNTER++;
this.renderer.runners.contextChange.emit(gl);
const view = this.renderer.view;
if (view.addEventListener !== void 0) {
view.addEventListener("webglcontextlost", this.handleContextLost, false);
view.addEventListener("webglcontextrestored", this.handleContextRestored, false);
}
}
initFromOptions(options) {
const gl = this.createContext(this.renderer.view, options);
this.initFromContext(gl);
}
createContext(canvas, options) {
let gl;
if (settings.PREFER_ENV >= ENV.WEBGL2) {
gl = canvas.getContext("webgl2", options);
}
if (gl) {
this.webGLVersion = 2;
} else {
this.webGLVersion = 1;
gl = canvas.getContext("webgl", options) || canvas.getContext("experimental-webgl", options);
if (!gl) {
throw new Error("This browser does not support WebGL. Try using the canvas renderer");
}
}
this.gl = gl;
this.getExtensions();
return this.gl;
}
getExtensions() {
const { gl } = this;
const common = {
loseContext: gl.getExtension("WEBGL_lose_context"),
anisotropicFiltering: gl.getExtension("EXT_texture_filter_anisotropic"),
floatTextureLinear: gl.getExtension("OES_texture_float_linear"),
s3tc: gl.getExtension("WEBGL_compressed_texture_s3tc"),
s3tc_sRGB: gl.getExtension("WEBGL_compressed_texture_s3tc_srgb"),
etc: gl.getExtension("WEBGL_compressed_texture_etc"),
etc1: gl.getExtension("WEBGL_compressed_texture_etc1"),
pvrtc: gl.getExtension("WEBGL_compressed_texture_pvrtc") || gl.getExtension("WEBKIT_WEBGL_compressed_texture_pvrtc"),
atc: gl.getExtension("WEBGL_compressed_texture_atc"),
astc: gl.getExtension("WEBGL_compressed_texture_astc")
};
if (this.webGLVersion === 1) {
Object.assign(this.extensions, common, {
drawBuffers: gl.getExtension("WEBGL_draw_buffers"),
depthTexture: gl.getExtension("WEBGL_depth_texture"),
vertexArrayObject: gl.getExtension("OES_vertex_array_object") || gl.getExtension("MOZ_OES_vertex_array_object") || gl.getExtension("WEBKIT_OES_vertex_array_object"),
uint32ElementIndex: gl.getExtension("OES_element_index_uint"),
floatTexture: gl.getExtension("OES_texture_float"),
floatTextureLinear: gl.getExtension("OES_texture_float_linear"),
textureHalfFloat: gl.getExtension("OES_texture_half_float"),
textureHalfFloatLinear: gl.getExtension("OES_texture_half_float_linear")
});
} else if (this.webGLVersion === 2) {
Object.assign(this.extensions, common, {
colorBufferFloat: gl.getExtension("EXT_color_buffer_float")
});
}
}
handleContextLost(event) {
event.preventDefault();
setTimeout(() => {
if (this.gl.isContextLost() && this.extensions.loseContext) {
this.extensions.loseContext.restoreContext();
}
}, 0);
}
handleContextRestored() {
this.renderer.runners.contextChange.emit(this.gl);
}
destroy() {
const view = this.renderer.view;
this.renderer = null;
if (view.removeEventListener !== void 0) {
view.removeEventListener("webglcontextlost", this.handleContextLost);
view.removeEventListener("webglcontextrestored", this.handleContextRestored);
}
this.gl.useProgram(null);
if (this.extensions.loseContext) {
this.extensions.loseContext.loseContext();
}
}
postrender() {
if (this.renderer.objectRenderer.renderingToScreen) {
this.gl.flush();
}
}
validateContext(gl) {
const attributes = gl.getContextAttributes();
const isWebGl2 = "WebGL2RenderingContext" in globalThis && gl instanceof globalThis.WebGL2RenderingContext;
if (isWebGl2) {
this.webGLVersion = 2;
}
if (attributes && !attributes.stencil) {
console.warn("Provided WebGL context does not have a stencil buffer, masks may not render correctly");
}
const hasuint32 = isWebGl2 || !!gl.getExtension("OES_element_index_uint");
this.supports.uint32Indices = hasuint32;
if (!hasuint32) {
console.warn("Provided WebGL context does not support 32 index buffer, complex graphics may not render correctly");
}
}
}
ContextSystem.defaultOptions = {
context: null,
antialias: false,
premultipliedAlpha: true,
preserveDrawingBuffer: false,
powerPreference: "default"
};
ContextSystem.extension = {
type: ExtensionType.RendererSystem,
name: "context"
};
extensions.add(ContextSystem);
export { ContextSystem };
//# sourceMappingURL=ContextSystem.mjs.map