UNPKG

6.04 kBJavaScriptView Raw
1import { ENV } from '@pixi/constants';
2import { ExtensionType, extensions } from '@pixi/extensions';
3import { settings } from '@pixi/settings';
4
5let CONTEXT_UID_COUNTER = 0;
6class ContextSystem {
7 constructor(renderer) {
8 this.renderer = renderer;
9 this.webGLVersion = 1;
10 this.extensions = {};
11 this.supports = {
12 uint32Indices: false
13 };
14 this.handleContextLost = this.handleContextLost.bind(this);
15 this.handleContextRestored = this.handleContextRestored.bind(this);
16 }
17 get isLost() {
18 return !this.gl || this.gl.isContextLost();
19 }
20 contextChange(gl) {
21 this.gl = gl;
22 this.renderer.gl = gl;
23 this.renderer.CONTEXT_UID = CONTEXT_UID_COUNTER++;
24 }
25 init(options) {
26 if (options.context) {
27 this.initFromContext(options.context);
28 } else {
29 const alpha = this.renderer.background.alpha < 1;
30 const premultipliedAlpha = options.premultipliedAlpha;
31 this.preserveDrawingBuffer = options.preserveDrawingBuffer;
32 this.useContextAlpha = options.useContextAlpha;
33 this.powerPreference = options.powerPreference;
34 this.initFromOptions({
35 alpha,
36 premultipliedAlpha,
37 antialias: options.antialias,
38 stencil: true,
39 preserveDrawingBuffer: options.preserveDrawingBuffer,
40 powerPreference: options.powerPreference
41 });
42 }
43 }
44 initFromContext(gl) {
45 this.gl = gl;
46 this.validateContext(gl);
47 this.renderer.gl = gl;
48 this.renderer.CONTEXT_UID = CONTEXT_UID_COUNTER++;
49 this.renderer.runners.contextChange.emit(gl);
50 const view = this.renderer.view;
51 if (view.addEventListener !== void 0) {
52 view.addEventListener("webglcontextlost", this.handleContextLost, false);
53 view.addEventListener("webglcontextrestored", this.handleContextRestored, false);
54 }
55 }
56 initFromOptions(options) {
57 const gl = this.createContext(this.renderer.view, options);
58 this.initFromContext(gl);
59 }
60 createContext(canvas, options) {
61 let gl;
62 if (settings.PREFER_ENV >= ENV.WEBGL2) {
63 gl = canvas.getContext("webgl2", options);
64 }
65 if (gl) {
66 this.webGLVersion = 2;
67 } else {
68 this.webGLVersion = 1;
69 gl = canvas.getContext("webgl", options) || canvas.getContext("experimental-webgl", options);
70 if (!gl) {
71 throw new Error("This browser does not support WebGL. Try using the canvas renderer");
72 }
73 }
74 this.gl = gl;
75 this.getExtensions();
76 return this.gl;
77 }
78 getExtensions() {
79 const { gl } = this;
80 const common = {
81 loseContext: gl.getExtension("WEBGL_lose_context"),
82 anisotropicFiltering: gl.getExtension("EXT_texture_filter_anisotropic"),
83 floatTextureLinear: gl.getExtension("OES_texture_float_linear"),
84 s3tc: gl.getExtension("WEBGL_compressed_texture_s3tc"),
85 s3tc_sRGB: gl.getExtension("WEBGL_compressed_texture_s3tc_srgb"),
86 etc: gl.getExtension("WEBGL_compressed_texture_etc"),
87 etc1: gl.getExtension("WEBGL_compressed_texture_etc1"),
88 pvrtc: gl.getExtension("WEBGL_compressed_texture_pvrtc") || gl.getExtension("WEBKIT_WEBGL_compressed_texture_pvrtc"),
89 atc: gl.getExtension("WEBGL_compressed_texture_atc"),
90 astc: gl.getExtension("WEBGL_compressed_texture_astc")
91 };
92 if (this.webGLVersion === 1) {
93 Object.assign(this.extensions, common, {
94 drawBuffers: gl.getExtension("WEBGL_draw_buffers"),
95 depthTexture: gl.getExtension("WEBGL_depth_texture"),
96 vertexArrayObject: gl.getExtension("OES_vertex_array_object") || gl.getExtension("MOZ_OES_vertex_array_object") || gl.getExtension("WEBKIT_OES_vertex_array_object"),
97 uint32ElementIndex: gl.getExtension("OES_element_index_uint"),
98 floatTexture: gl.getExtension("OES_texture_float"),
99 floatTextureLinear: gl.getExtension("OES_texture_float_linear"),
100 textureHalfFloat: gl.getExtension("OES_texture_half_float"),
101 textureHalfFloatLinear: gl.getExtension("OES_texture_half_float_linear")
102 });
103 } else if (this.webGLVersion === 2) {
104 Object.assign(this.extensions, common, {
105 colorBufferFloat: gl.getExtension("EXT_color_buffer_float")
106 });
107 }
108 }
109 handleContextLost(event) {
110 event.preventDefault();
111 setTimeout(() => {
112 if (this.gl.isContextLost() && this.extensions.loseContext) {
113 this.extensions.loseContext.restoreContext();
114 }
115 }, 0);
116 }
117 handleContextRestored() {
118 this.renderer.runners.contextChange.emit(this.gl);
119 }
120 destroy() {
121 const view = this.renderer.view;
122 this.renderer = null;
123 if (view.removeEventListener !== void 0) {
124 view.removeEventListener("webglcontextlost", this.handleContextLost);
125 view.removeEventListener("webglcontextrestored", this.handleContextRestored);
126 }
127 this.gl.useProgram(null);
128 if (this.extensions.loseContext) {
129 this.extensions.loseContext.loseContext();
130 }
131 }
132 postrender() {
133 if (this.renderer.objectRenderer.renderingToScreen) {
134 this.gl.flush();
135 }
136 }
137 validateContext(gl) {
138 const attributes = gl.getContextAttributes();
139 const isWebGl2 = "WebGL2RenderingContext" in globalThis && gl instanceof globalThis.WebGL2RenderingContext;
140 if (isWebGl2) {
141 this.webGLVersion = 2;
142 }
143 if (attributes && !attributes.stencil) {
144 console.warn("Provided WebGL context does not have a stencil buffer, masks may not render correctly");
145 }
146 const hasuint32 = isWebGl2 || !!gl.getExtension("OES_element_index_uint");
147 this.supports.uint32Indices = hasuint32;
148 if (!hasuint32) {
149 console.warn("Provided WebGL context does not support 32 index buffer, complex graphics may not render correctly");
150 }
151 }
152}
153ContextSystem.defaultOptions = {
154 context: null,
155 antialias: false,
156 premultipliedAlpha: true,
157 preserveDrawingBuffer: false,
158 powerPreference: "default"
159};
160ContextSystem.extension = {
161 type: ExtensionType.RendererSystem,
162 name: "context"
163};
164extensions.add(ContextSystem);
165
166export { ContextSystem };
167//# sourceMappingURL=ContextSystem.mjs.map