/
backend-context.ts
104 lines (95 loc) · 2.98 KB
/
backend-context.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
import { PAGModule } from '../pag-module';
import { WEBGL_CONTEXT_ATTRIBUTES } from '../constant';
export class BackendContext {
public static from(gl: WebGLRenderingContext | WebGL2RenderingContext | BackendContext): BackendContext {
if (gl instanceof BackendContext) {
return new BackendContext(gl.handle, true);
} else {
const majorVersion = globalThis.WebGL2RenderingContext && gl instanceof globalThis.WebGL2RenderingContext ? 2 : 1;
const { GL } = PAGModule;
let id = 0;
if (GL.contexts.length > 0) {
id = GL.contexts.findIndex((context) => context?.GLctx === gl);
}
if (id < 1) {
id = GL.registerContext(gl, {
majorVersion: majorVersion,
minorVersion: 0,
...WEBGL_CONTEXT_ATTRIBUTES,
});
return new BackendContext(id);
}
return new BackendContext(id, true);
}
}
public handle: number;
private adopted: boolean;
private isDestroyed = false;
private oldHandle = 0;
public constructor(handle: number, adopted = false) {
this.handle = handle;
this.adopted = adopted;
}
public getContext(): WebGLRenderingContext | null {
return PAGModule.GL.getContext(this.handle)!.GLctx;
}
public makeCurrent(): boolean {
if (this.isDestroyed) return false;
this.oldHandle = PAGModule.GL.currentContext?.handle || 0;
if (this.oldHandle === this.handle) return true;
return PAGModule.GL.makeContextCurrent(this.handle);
}
public clearCurrent() {
if (this.isDestroyed) return;
if (this.oldHandle === this.handle) return;
PAGModule.GL.makeContextCurrent(0);
if (this.oldHandle) {
PAGModule.GL.makeContextCurrent(this.oldHandle);
}
}
/**
* Register WebGLTexture in EmscriptenGL, And return handle.
*/
public registerTexture(texture: WebGLTexture) {
return this.register(PAGModule.GL.textures, texture);
}
/**
* Get WebGLTexture by handle.
*/
public getTexture(handled: number): WebGLTexture | null {
return PAGModule.GL.textures[handled];
}
/**
* Unregister WebGLTexture reference in EmscriptenGL.
*/
public unregisterTexture(handle: number) {
PAGModule.GL.textures[handle] = null;
}
/**
* Register WebGLFramebuffer in EmscriptenGL, And return handle.
*/
public registerRenderTarget(framebuffer: WebGLFramebuffer) {
return this.register(PAGModule.GL.framebuffers, framebuffer);
}
/**
* Get WebGLFramebuffer by handle.
*/
public getRenderTarget(handle: number): WebGLFramebuffer | null {
return PAGModule.GL.framebuffers[handle];
}
/**
* Unregister WebGLTexture reference in EmscriptenGL.
*/
public unregisterRenderTarget(handle: number) {
PAGModule.GL.framebuffers[handle] = null;
}
public destroy(): void {
if (this.adopted) return;
PAGModule.GL.deleteContext(this.handle);
}
private register<T>(table: (T | null)[], item: T): number {
const handle = PAGModule.GL.getNewId(table);
table[handle] = item;
return handle;
}
}