webgl2 1.1.18 → 1.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/coverage.md +37 -32
- package/daebug.md +6 -7
- package/demo.js +2 -2
- package/index.js +404 -354
- package/package.json +1 -1
- package/src/webgl2_context.js +220 -30
- package/src/webgpu_context.js +272 -7
- package/webgl2.debug.wasm +0 -0
- package/webgl2.wasm +0 -0
package/package.json
CHANGED
package/src/webgl2_context.js
CHANGED
|
@@ -25,10 +25,12 @@ export class WasmWebGL2RenderingContext {
|
|
|
25
25
|
FRAGMENT_SHADER = 0x8B30;
|
|
26
26
|
VERTEX_SHADER = 0x8B31;
|
|
27
27
|
TRIANGLES = 0x0004;
|
|
28
|
+
TRIANGLE_STRIP = 0x0005;
|
|
28
29
|
COLOR_BUFFER_BIT = 0x00004000;
|
|
29
30
|
DEPTH_BUFFER_BIT = 0x00000100;
|
|
30
31
|
DEPTH_TEST = 0x0B71;
|
|
31
32
|
STENCIL_TEST = 0x0B90;
|
|
33
|
+
SCISSOR_TEST = 0x0C11;
|
|
32
34
|
STENCIL_BUFFER_BIT = 0x00000400;
|
|
33
35
|
COMPILE_STATUS = 0x8B81;
|
|
34
36
|
LINK_STATUS = 0x8B82;
|
|
@@ -36,6 +38,12 @@ export class WasmWebGL2RenderingContext {
|
|
|
36
38
|
VALIDATE_STATUS = 0x8B83;
|
|
37
39
|
ARRAY_BUFFER = 0x8892;
|
|
38
40
|
ELEMENT_ARRAY_BUFFER = 0x8893;
|
|
41
|
+
COPY_READ_BUFFER = 0x8F36;
|
|
42
|
+
COPY_WRITE_BUFFER = 0x8F37;
|
|
43
|
+
PIXEL_PACK_BUFFER = 0x88EB;
|
|
44
|
+
PIXEL_UNPACK_BUFFER = 0x88EC;
|
|
45
|
+
UNIFORM_BUFFER = 0x8A11;
|
|
46
|
+
TRANSFORM_FEEDBACK_BUFFER = 0x8C8E;
|
|
39
47
|
STATIC_DRAW = 0x88E4;
|
|
40
48
|
BYTE = 0x1400;
|
|
41
49
|
UNSIGNED_BYTE = 0x1401;
|
|
@@ -44,7 +52,6 @@ export class WasmWebGL2RenderingContext {
|
|
|
44
52
|
INT = 0x1404;
|
|
45
53
|
UNSIGNED_INT = 0x1405;
|
|
46
54
|
FLOAT = 0x1406;
|
|
47
|
-
RGBA = 0x1908;
|
|
48
55
|
FLOAT_VEC2 = 0x8B50;
|
|
49
56
|
FLOAT_VEC3 = 0x8B51;
|
|
50
57
|
FLOAT_VEC4 = 0x8B52;
|
|
@@ -59,6 +66,7 @@ export class WasmWebGL2RenderingContext {
|
|
|
59
66
|
FLOAT_MAT3 = 0x8B5B;
|
|
60
67
|
FLOAT_MAT4 = 0x8B5C;
|
|
61
68
|
SAMPLER_2D = 0x8B5E;
|
|
69
|
+
SAMPLER_3D = 0x8B5F;
|
|
62
70
|
SAMPLER_CUBE = 0x8B60;
|
|
63
71
|
ACTIVE_UNIFORMS = 0x8B86;
|
|
64
72
|
ACTIVE_ATTRIBUTES = 0x8B89;
|
|
@@ -107,6 +115,8 @@ export class WasmWebGL2RenderingContext {
|
|
|
107
115
|
|
|
108
116
|
RENDERBUFFER = 0x8D41;
|
|
109
117
|
FRAMEBUFFER = 0x8D40;
|
|
118
|
+
READ_FRAMEBUFFER = 0x8CA8;
|
|
119
|
+
DRAW_FRAMEBUFFER = 0x8CA9;
|
|
110
120
|
DEPTH_COMPONENT16 = 0x81A5;
|
|
111
121
|
DEPTH_STENCIL = 0x84F9;
|
|
112
122
|
RGBA4 = 0x8056;
|
|
@@ -141,10 +151,18 @@ export class WasmWebGL2RenderingContext {
|
|
|
141
151
|
FRONT_AND_BACK = 0x0408;
|
|
142
152
|
|
|
143
153
|
TEXTURE_2D = 0x0DE1;
|
|
154
|
+
TEXTURE_3D = 0x806F;
|
|
155
|
+
TEXTURE_2D_ARRAY = 0x8C1A;
|
|
144
156
|
TEXTURE_WRAP_S = 0x2802;
|
|
145
157
|
TEXTURE_WRAP_T = 0x2803;
|
|
158
|
+
TEXTURE_WRAP_R = 0x8072;
|
|
146
159
|
TEXTURE_MAG_FILTER = 0x2800;
|
|
147
160
|
TEXTURE_MIN_FILTER = 0x2801;
|
|
161
|
+
RGBA = 0x1908;
|
|
162
|
+
RED = 0x1903;
|
|
163
|
+
RG = 0x8227;
|
|
164
|
+
UNSIGNED_BYTE = 0x1401;
|
|
165
|
+
FLOAT = 0x1406;
|
|
148
166
|
NEAREST = 0x2600;
|
|
149
167
|
LINEAR = 0x2601;
|
|
150
168
|
NEAREST_MIPMAP_NEAREST = 0x2700;
|
|
@@ -212,14 +230,23 @@ export class WasmWebGL2RenderingContext {
|
|
|
212
230
|
/** @type {Map<number, WasmWebGL2RenderingContext>} */
|
|
213
231
|
static _contexts = new Map();
|
|
214
232
|
|
|
215
|
-
_executeShader(type, attrPtr, uniformPtr, varyingPtr, privatePtr, texturePtr) {
|
|
233
|
+
_executeShader(type, tableIdx, attrPtr, uniformPtr, varyingPtr, privatePtr, texturePtr) {
|
|
216
234
|
if (!this._currentProgram) {
|
|
217
235
|
return;
|
|
218
236
|
}
|
|
237
|
+
|
|
238
|
+
if (tableIdx > 0 && this._sharedTable) {
|
|
239
|
+
const func = this._sharedTable.get(tableIdx);
|
|
240
|
+
if (func) {
|
|
241
|
+
func(this._ctxHandle, type, tableIdx, attrPtr, uniformPtr, varyingPtr, privatePtr, texturePtr);
|
|
242
|
+
return;
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
|
|
219
246
|
const shaderInstance = type === this.VERTEX_SHADER ? this._currentProgram._vsInstance : this._currentProgram._fsInstance;
|
|
220
247
|
if (shaderInstance && shaderInstance.exports.main) {
|
|
221
248
|
// @ts-ignore
|
|
222
|
-
shaderInstance.exports.main(type, attrPtr, uniformPtr, varyingPtr, privatePtr, texturePtr);
|
|
249
|
+
shaderInstance.exports.main(this._ctxHandle, type, tableIdx, attrPtr, uniformPtr, varyingPtr, privatePtr, texturePtr);
|
|
223
250
|
}
|
|
224
251
|
}
|
|
225
252
|
|
|
@@ -292,8 +319,13 @@ export class WasmWebGL2RenderingContext {
|
|
|
292
319
|
}
|
|
293
320
|
|
|
294
321
|
let data = pixels;
|
|
295
|
-
if (!data)
|
|
296
|
-
|
|
322
|
+
if (!data) {
|
|
323
|
+
data = new Uint8Array(width * height * 4);
|
|
324
|
+
} else if (ArrayBuffer.isView(data)) {
|
|
325
|
+
data = new Uint8Array(data.buffer, data.byteOffset, data.byteLength);
|
|
326
|
+
} else if (data instanceof ArrayBuffer) {
|
|
327
|
+
data = new Uint8Array(data);
|
|
328
|
+
}
|
|
297
329
|
|
|
298
330
|
const len = data.length;
|
|
299
331
|
const ptr = ex.wasm_alloc(len);
|
|
@@ -328,6 +360,56 @@ export class WasmWebGL2RenderingContext {
|
|
|
328
360
|
}
|
|
329
361
|
}
|
|
330
362
|
|
|
363
|
+
texImage3D(target, level, internalFormat, width, height, depth, border, format, type_, pixels) {
|
|
364
|
+
this._assertNotDestroyed();
|
|
365
|
+
const ex = this._instance.exports;
|
|
366
|
+
if (!ex || typeof ex.wasm_ctx_tex_image_3d !== 'function') {
|
|
367
|
+
throw new Error('wasm_ctx_tex_image_3d not found');
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
let data = pixels;
|
|
371
|
+
if (!data) {
|
|
372
|
+
data = new Uint8Array(width * height * depth * 4);
|
|
373
|
+
} else if (ArrayBuffer.isView(data)) {
|
|
374
|
+
data = new Uint8Array(data.buffer, data.byteOffset, data.byteLength);
|
|
375
|
+
} else if (data instanceof ArrayBuffer) {
|
|
376
|
+
data = new Uint8Array(data);
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
const len = data.length;
|
|
380
|
+
const ptr = ex.wasm_alloc(len);
|
|
381
|
+
if (ptr === 0) throw new Error('Failed to allocate memory for pixel data');
|
|
382
|
+
|
|
383
|
+
try {
|
|
384
|
+
const mem = new Uint8Array(ex.memory.buffer);
|
|
385
|
+
mem.set(data, ptr);
|
|
386
|
+
|
|
387
|
+
const code = ex.wasm_ctx_tex_image_3d(
|
|
388
|
+
this._ctxHandle,
|
|
389
|
+
target >>> 0,
|
|
390
|
+
level >>> 0,
|
|
391
|
+
internalFormat >>> 0,
|
|
392
|
+
width >>> 0,
|
|
393
|
+
height >>> 0,
|
|
394
|
+
depth >>> 0,
|
|
395
|
+
border >>> 0,
|
|
396
|
+
format >>> 0,
|
|
397
|
+
type_ >>> 0,
|
|
398
|
+
ptr >>> 0,
|
|
399
|
+
len >>> 0
|
|
400
|
+
);
|
|
401
|
+
_checkErr(code, this._instance);
|
|
402
|
+
|
|
403
|
+
// Mirror texture data in JS for fast texel fetches by shader imports
|
|
404
|
+
this._textureData = this._textureData || new Map();
|
|
405
|
+
const handle = this._boundTexture || 0;
|
|
406
|
+
const copy = new Uint8Array(mem.slice(ptr, ptr + len));
|
|
407
|
+
this._textureData.set(handle, { width: width >>> 0, height: height >>> 0, depth: depth >>> 0, data: copy });
|
|
408
|
+
} finally {
|
|
409
|
+
ex.wasm_free(ptr);
|
|
410
|
+
}
|
|
411
|
+
}
|
|
412
|
+
|
|
331
413
|
copyTexImage2D(target, level, internalFormat, x, y, width, height, border) {
|
|
332
414
|
this._assertNotDestroyed();
|
|
333
415
|
const ex = this._instance.exports;
|
|
@@ -478,9 +560,18 @@ export class WasmWebGL2RenderingContext {
|
|
|
478
560
|
throw new Error('wasm_ctx_read_pixels not found');
|
|
479
561
|
}
|
|
480
562
|
|
|
481
|
-
|
|
482
|
-
if (
|
|
483
|
-
|
|
563
|
+
let bpp = 4;
|
|
564
|
+
if (type_ === 0x1406) { // GL_FLOAT
|
|
565
|
+
if (format === 0x1908) bpp = 16; // GL_RGBA
|
|
566
|
+
else if (format === 0x8227) bpp = 8; // GL_RG
|
|
567
|
+
else if (format === 0x1903) bpp = 4; // GL_RED
|
|
568
|
+
} else if (type_ === 0x1401) { // GL_UNSIGNED_BYTE
|
|
569
|
+
if (format === 0x1908) bpp = 4;
|
|
570
|
+
}
|
|
571
|
+
|
|
572
|
+
const len = width * height * bpp;
|
|
573
|
+
if (!out || out.byteLength < len) {
|
|
574
|
+
throw new Error(`output buffer too small (need ${len} bytes, have ${out ? out.byteLength : 0})`);
|
|
484
575
|
}
|
|
485
576
|
|
|
486
577
|
const ptr = ex.wasm_alloc(len);
|
|
@@ -489,8 +580,8 @@ export class WasmWebGL2RenderingContext {
|
|
|
489
580
|
try {
|
|
490
581
|
const code = ex.wasm_ctx_read_pixels(
|
|
491
582
|
this._ctxHandle,
|
|
492
|
-
x
|
|
493
|
-
y
|
|
583
|
+
x | 0,
|
|
584
|
+
y | 0,
|
|
494
585
|
width >>> 0,
|
|
495
586
|
height >>> 0,
|
|
496
587
|
format >>> 0,
|
|
@@ -502,7 +593,8 @@ export class WasmWebGL2RenderingContext {
|
|
|
502
593
|
|
|
503
594
|
const mem = new Uint8Array(ex.memory.buffer);
|
|
504
595
|
const src = mem.subarray(ptr, ptr + len);
|
|
505
|
-
out.
|
|
596
|
+
const out_bytes = new Uint8Array(out.buffer, out.byteOffset, len);
|
|
597
|
+
out_bytes.set(src);
|
|
506
598
|
} finally {
|
|
507
599
|
ex.wasm_free(ptr);
|
|
508
600
|
}
|
|
@@ -708,9 +800,6 @@ export class WasmWebGL2RenderingContext {
|
|
|
708
800
|
_checkErr(code, this._instance);
|
|
709
801
|
|
|
710
802
|
// After linking, we need to instantiate the WASM modules on the host.
|
|
711
|
-
// According to the WebGL 2.0 Spec (https://registry.khronos.org/webgl/specs/latest/2.0/#3.7.6),
|
|
712
|
-
// linkProgram sets the LINK_STATUS parameter. If linking fails, no executable is generated.
|
|
713
|
-
// We must check LINK_STATUS before attempting to instantiate the WASM, as getProgramWasm will return null.
|
|
714
803
|
if (program && typeof program === 'object') {
|
|
715
804
|
const linkStatus = this.getProgramParameter(program, this.LINK_STATUS);
|
|
716
805
|
if (linkStatus) {
|
|
@@ -723,6 +812,10 @@ export class WasmWebGL2RenderingContext {
|
|
|
723
812
|
const vsWasm = this.getProgramWasm(program, this.VERTEX_SHADER);
|
|
724
813
|
const fsWasm = this.getProgramWasm(program, this.FRAGMENT_SHADER);
|
|
725
814
|
|
|
815
|
+
if (!vsWasm || !fsWasm) {
|
|
816
|
+
return;
|
|
817
|
+
}
|
|
818
|
+
|
|
726
819
|
// Allocate table slots for both shaders
|
|
727
820
|
const vsIdx = this._tableAllocator ? this._tableAllocator.allocate() : null;
|
|
728
821
|
const fsIdx = this._tableAllocator ? this._tableAllocator.allocate() : null;
|
|
@@ -749,7 +842,6 @@ export class WasmWebGL2RenderingContext {
|
|
|
749
842
|
return {
|
|
750
843
|
debug_step: (line, funcIdx, resultPtr) => {
|
|
751
844
|
if (line === 999999) {
|
|
752
|
-
console.log(`DEBUG LOG: val=${funcIdx} (0x${(funcIdx >>> 0).toString(16)})`);
|
|
753
845
|
return;
|
|
754
846
|
}
|
|
755
847
|
const func = stubFuncs[line - 1];
|
|
@@ -775,13 +867,26 @@ export class WasmWebGL2RenderingContext {
|
|
|
775
867
|
const vsInstanceRef = { current: null };
|
|
776
868
|
const vsDebugEnv = createDebugEnv(this.VERTEX_SHADER, vsInstanceRef);
|
|
777
869
|
|
|
870
|
+
const env = {
|
|
871
|
+
memory: this._instance.exports.memory,
|
|
872
|
+
__indirect_function_table: this._sharedTable,
|
|
873
|
+
...vsDebugEnv
|
|
874
|
+
};
|
|
778
875
|
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
876
|
+
// Add math builtins from renderer (skipping host)
|
|
877
|
+
const mathFuncs = [
|
|
878
|
+
'gl_sin', 'gl_cos', 'gl_tan', 'gl_asin', 'gl_acos', 'gl_atan', 'gl_atan2',
|
|
879
|
+
'gl_exp', 'gl_exp2', 'gl_log', 'gl_log2', 'gl_pow',
|
|
880
|
+
'gl_sinh', 'gl_cosh', 'gl_tanh', 'gl_asinh', 'gl_acosh', 'gl_atanh'
|
|
881
|
+
];
|
|
882
|
+
for (const name of mathFuncs) {
|
|
883
|
+
if (this._instance.exports[name]) {
|
|
884
|
+
env[name] = this._instance.exports[name];
|
|
784
885
|
}
|
|
886
|
+
}
|
|
887
|
+
|
|
888
|
+
program._vsInstance = new WebAssembly.Instance(vsModule, {
|
|
889
|
+
env
|
|
785
890
|
});
|
|
786
891
|
vsInstanceRef.current = program._vsInstance;
|
|
787
892
|
|
|
@@ -796,13 +901,20 @@ export class WasmWebGL2RenderingContext {
|
|
|
796
901
|
const fsInstanceRef = { current: null };
|
|
797
902
|
const fsDebugEnv = createDebugEnv(this.FRAGMENT_SHADER, fsInstanceRef);
|
|
798
903
|
|
|
904
|
+
const fsEnv = {
|
|
905
|
+
memory: this._instance.exports.memory,
|
|
906
|
+
__indirect_function_table: this._sharedTable,
|
|
907
|
+
...fsDebugEnv
|
|
908
|
+
};
|
|
799
909
|
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
__indirect_function_table: this._sharedTable,
|
|
804
|
-
...fsDebugEnv
|
|
910
|
+
for (const name of mathFuncs) {
|
|
911
|
+
if (this._instance.exports[name]) {
|
|
912
|
+
fsEnv[name] = this._instance.exports[name];
|
|
805
913
|
}
|
|
914
|
+
}
|
|
915
|
+
|
|
916
|
+
program._fsInstance = new WebAssembly.Instance(fsModule, {
|
|
917
|
+
env: fsEnv
|
|
806
918
|
});
|
|
807
919
|
fsInstanceRef.current = program._fsInstance;
|
|
808
920
|
|
|
@@ -879,7 +991,7 @@ export class WasmWebGL2RenderingContext {
|
|
|
879
991
|
throw new Error('wasm_ctx_delete_program not found');
|
|
880
992
|
}
|
|
881
993
|
const programHandle = program && typeof program === 'object' && typeof program._handle === 'number' ? program._handle : (program >>> 0);
|
|
882
|
-
|
|
994
|
+
|
|
883
995
|
// Free table indices
|
|
884
996
|
if (program && typeof program === 'object') {
|
|
885
997
|
if (program._vsTableIndex !== undefined && this._tableAllocator) {
|
|
@@ -889,7 +1001,7 @@ export class WasmWebGL2RenderingContext {
|
|
|
889
1001
|
this._tableAllocator.free(program._fsTableIndex);
|
|
890
1002
|
}
|
|
891
1003
|
}
|
|
892
|
-
|
|
1004
|
+
|
|
893
1005
|
const code = ex.wasm_ctx_delete_program(this._ctxHandle, programHandle);
|
|
894
1006
|
_checkErr(code, this._instance);
|
|
895
1007
|
if (program && typeof program === 'object') {
|
|
@@ -1087,6 +1199,7 @@ export class WasmWebGL2RenderingContext {
|
|
|
1087
1199
|
stride >>> 0,
|
|
1088
1200
|
offset >>> 0
|
|
1089
1201
|
);
|
|
1202
|
+
if (code === 5) return; // ERR_GL
|
|
1090
1203
|
_checkErr(code, this._instance);
|
|
1091
1204
|
}
|
|
1092
1205
|
|
|
@@ -1104,6 +1217,7 @@ export class WasmWebGL2RenderingContext {
|
|
|
1104
1217
|
stride >>> 0,
|
|
1105
1218
|
offset >>> 0
|
|
1106
1219
|
);
|
|
1220
|
+
if (code === 5) return; // ERR_GL
|
|
1107
1221
|
_checkErr(code, this._instance);
|
|
1108
1222
|
}
|
|
1109
1223
|
|
|
@@ -1282,6 +1396,12 @@ export class WasmWebGL2RenderingContext {
|
|
|
1282
1396
|
}
|
|
1283
1397
|
|
|
1284
1398
|
const len = bytes.length;
|
|
1399
|
+
if (len === 0) {
|
|
1400
|
+
const code = ex.wasm_ctx_buffer_data(this._ctxHandle, target >>> 0, 0, 0, usage >>> 0);
|
|
1401
|
+
_checkErr(code, this._instance);
|
|
1402
|
+
return;
|
|
1403
|
+
}
|
|
1404
|
+
|
|
1285
1405
|
const ptr = ex.wasm_alloc(len);
|
|
1286
1406
|
if (ptr === 0) throw new Error('Failed to allocate memory for bufferData');
|
|
1287
1407
|
|
|
@@ -1321,7 +1441,22 @@ export class WasmWebGL2RenderingContext {
|
|
|
1321
1441
|
ex.wasm_free(ptr);
|
|
1322
1442
|
}
|
|
1323
1443
|
}
|
|
1324
|
-
copyBufferSubData(readTarget, writeTarget, readOffset, writeOffset, size) {
|
|
1444
|
+
copyBufferSubData(readTarget, writeTarget, readOffset, writeOffset, size) {
|
|
1445
|
+
this._assertNotDestroyed();
|
|
1446
|
+
const ex = this._instance.exports;
|
|
1447
|
+
if (!ex || typeof ex.wasm_ctx_copy_buffer_sub_data !== 'function') {
|
|
1448
|
+
throw new Error('wasm_ctx_copy_buffer_sub_data not found');
|
|
1449
|
+
}
|
|
1450
|
+
const code = ex.wasm_ctx_copy_buffer_sub_data(
|
|
1451
|
+
this._ctxHandle,
|
|
1452
|
+
readTarget >>> 0,
|
|
1453
|
+
writeTarget >>> 0,
|
|
1454
|
+
readOffset >>> 0,
|
|
1455
|
+
writeOffset >>> 0,
|
|
1456
|
+
size >>> 0
|
|
1457
|
+
);
|
|
1458
|
+
_checkErr(code, this._instance);
|
|
1459
|
+
}
|
|
1325
1460
|
getBufferParameter(target, pname) {
|
|
1326
1461
|
this._assertNotDestroyed();
|
|
1327
1462
|
const ex = this._instance.exports;
|
|
@@ -1508,10 +1643,65 @@ export class WasmWebGL2RenderingContext {
|
|
|
1508
1643
|
_checkErr(code, this._instance);
|
|
1509
1644
|
}
|
|
1510
1645
|
copyTexSubImage2D(target, level, xoffset, yoffset, x, y, width, height) { this._assertNotDestroyed(); throw new Error('not implemented'); }
|
|
1511
|
-
|
|
1646
|
+
texSubImage2D(target, level, xoffset, yoffset, width, height, format, type_, pixels) {
|
|
1647
|
+
this._assertNotDestroyed();
|
|
1648
|
+
const ex = this._instance.exports;
|
|
1649
|
+
if (!ex || typeof ex.wasm_ctx_tex_sub_image_2d !== 'function') {
|
|
1650
|
+
throw new Error('wasm_ctx_tex_sub_image_2d not found');
|
|
1651
|
+
}
|
|
1652
|
+
|
|
1653
|
+
let data = pixels;
|
|
1654
|
+
if (!data) return; // No-op if no data provided
|
|
1655
|
+
if (!(data instanceof Uint8Array)) {
|
|
1656
|
+
if (ArrayBuffer.isView(data)) {
|
|
1657
|
+
data = new Uint8Array(data.buffer, data.byteOffset, data.byteLength);
|
|
1658
|
+
} else {
|
|
1659
|
+
data = new Uint8Array(data);
|
|
1660
|
+
}
|
|
1661
|
+
}
|
|
1662
|
+
|
|
1663
|
+
const len = data.length;
|
|
1664
|
+
const ptr = ex.wasm_alloc(len);
|
|
1665
|
+
if (ptr === 0) throw new Error('Failed to allocate memory for sub-pixel data');
|
|
1666
|
+
|
|
1667
|
+
try {
|
|
1668
|
+
const mem = new Uint8Array(ex.memory.buffer);
|
|
1669
|
+
mem.set(data, ptr);
|
|
1670
|
+
|
|
1671
|
+
const code = ex.wasm_ctx_tex_sub_image_2d(
|
|
1672
|
+
this._ctxHandle,
|
|
1673
|
+
target >>> 0,
|
|
1674
|
+
level >>> 0,
|
|
1675
|
+
xoffset | 0,
|
|
1676
|
+
yoffset | 0,
|
|
1677
|
+
width >>> 0,
|
|
1678
|
+
height >>> 0,
|
|
1679
|
+
format >>> 0,
|
|
1680
|
+
type_ >>> 0,
|
|
1681
|
+
ptr >>> 0,
|
|
1682
|
+
len >>> 0
|
|
1683
|
+
);
|
|
1684
|
+
_checkErr(code, this._instance);
|
|
1685
|
+
} finally {
|
|
1686
|
+
ex.wasm_free(ptr);
|
|
1687
|
+
}
|
|
1688
|
+
}
|
|
1512
1689
|
|
|
1513
1690
|
checkFramebufferStatus(target) { this._assertNotDestroyed(); throw new Error('not implemented'); }
|
|
1514
|
-
blitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter) {
|
|
1691
|
+
blitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter) {
|
|
1692
|
+
this._assertNotDestroyed();
|
|
1693
|
+
const ex = this._instance.exports;
|
|
1694
|
+
if (!ex || typeof ex.wasm_ctx_blit_framebuffer !== 'function') {
|
|
1695
|
+
throw new Error('wasm_ctx_blit_framebuffer not found');
|
|
1696
|
+
}
|
|
1697
|
+
const code = ex.wasm_ctx_blit_framebuffer(
|
|
1698
|
+
this._ctxHandle,
|
|
1699
|
+
srcX0 | 0, srcY0 | 0, srcX1 | 0, srcY1 | 0,
|
|
1700
|
+
dstX0 | 0, dstY0 | 0, dstX1 | 0, dstY1 | 0,
|
|
1701
|
+
mask >>> 0, filter >>> 0
|
|
1702
|
+
);
|
|
1703
|
+
_checkErr(code, this._instance);
|
|
1704
|
+
}
|
|
1515
1705
|
readBuffer(src) { this._assertNotDestroyed(); throw new Error('not implemented'); }
|
|
1516
1706
|
|
|
1517
1707
|
pixelStorei(pname, param) { this._assertNotDestroyed(); throw new Error('not implemented'); }
|