@lightningjs/renderer 3.0.0-beta8 → 3.0.0-beta9
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/dist/src/core/CoreNode.js +6 -0
- package/dist/src/core/CoreNode.js.map +1 -1
- package/dist/src/core/CoreTextureManager.d.ts +4 -9
- package/dist/src/core/CoreTextureManager.js +37 -75
- package/dist/src/core/CoreTextureManager.js.map +1 -1
- package/dist/src/core/TextureMemoryManager.d.ts +1 -1
- package/dist/src/core/TextureMemoryManager.js +25 -2
- package/dist/src/core/TextureMemoryManager.js.map +1 -1
- package/dist/src/core/animations/CoreAnimationController.js +4 -3
- package/dist/src/core/animations/CoreAnimationController.js.map +1 -1
- package/dist/src/core/lib/WebGlContextWrapper.d.ts +19 -2
- package/dist/src/core/lib/WebGlContextWrapper.js +56 -25
- package/dist/src/core/lib/WebGlContextWrapper.js.map +1 -1
- package/dist/src/core/renderers/webgl/WebGlShaderProgram.d.ts +4 -2
- package/dist/src/core/renderers/webgl/WebGlShaderProgram.js +31 -13
- package/dist/src/core/renderers/webgl/WebGlShaderProgram.js.map +1 -1
- package/dist/src/core/textures/Texture.d.ts +4 -0
- package/dist/src/core/textures/Texture.js +9 -3
- package/dist/src/core/textures/Texture.js.map +1 -1
- package/dist/tsconfig.dist.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/src/core/CoreNode.ts +6 -0
- package/src/core/CoreTextureManager.ts +36 -96
- package/src/core/TextureMemoryManager.ts +31 -4
- package/src/core/animations/CoreAnimationController.ts +5 -3
- package/src/core/lib/WebGlContextWrapper.ts +69 -75
- package/src/core/renderers/webgl/WebGlShaderProgram.ts +37 -14
- package/src/core/textures/Texture.ts +12 -3
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
*/
|
|
19
19
|
import { isProductionEnvironment } from '../utils.js';
|
|
20
20
|
import type { Stage } from './Stage.js';
|
|
21
|
-
import { TextureType, type
|
|
21
|
+
import { Texture, TextureType, type TextureState } from './textures/Texture.js';
|
|
22
22
|
import { bytesToMb } from './utils.js';
|
|
23
23
|
|
|
24
24
|
export interface TextureMemoryManagerSettings {
|
|
@@ -237,6 +237,12 @@ export class TextureMemoryManager {
|
|
|
237
237
|
continue;
|
|
238
238
|
}
|
|
239
239
|
|
|
240
|
+
// Skip textures that are in transitional states - we only want to clean up
|
|
241
|
+
// textures that are in a stable state (loaded, failed, or freed)
|
|
242
|
+
if (Texture.TRANSITIONAL_TEXTURE_STATES.includes(texture.state)) {
|
|
243
|
+
continue;
|
|
244
|
+
}
|
|
245
|
+
|
|
240
246
|
this.destroyTexture(texture);
|
|
241
247
|
}
|
|
242
248
|
}
|
|
@@ -247,6 +253,12 @@ export class TextureMemoryManager {
|
|
|
247
253
|
* @param texture - The texture to destroy
|
|
248
254
|
*/
|
|
249
255
|
destroyTexture(texture: Texture) {
|
|
256
|
+
if (this.debugLogging === true) {
|
|
257
|
+
console.log(
|
|
258
|
+
`[TextureMemoryManager] Destroying texture. State: ${texture.state}`,
|
|
259
|
+
);
|
|
260
|
+
}
|
|
261
|
+
|
|
250
262
|
const txManager = this.stage.txManager;
|
|
251
263
|
txManager.removeTextureFromQueue(texture);
|
|
252
264
|
txManager.removeTextureFromCache(texture);
|
|
@@ -296,6 +308,12 @@ export class TextureMemoryManager {
|
|
|
296
308
|
break;
|
|
297
309
|
}
|
|
298
310
|
|
|
311
|
+
// Skip textures that are in transitional states - we only want to clean up
|
|
312
|
+
// textures that are in a stable state (loaded, failed, or freed)
|
|
313
|
+
if (Texture.TRANSITIONAL_TEXTURE_STATES.includes(texture.state)) {
|
|
314
|
+
break;
|
|
315
|
+
}
|
|
316
|
+
|
|
299
317
|
this.destroyTexture(texture);
|
|
300
318
|
}
|
|
301
319
|
}
|
|
@@ -320,6 +338,15 @@ export class TextureMemoryManager {
|
|
|
320
338
|
);
|
|
321
339
|
}
|
|
322
340
|
|
|
341
|
+
// Note: We skip textures in transitional states during cleanup:
|
|
342
|
+
// - 'initial': These textures haven't started loading yet
|
|
343
|
+
// - 'fetching': These textures are in the process of being fetched
|
|
344
|
+
// - 'fetched': These textures have been fetched but not yet uploaded to GPU
|
|
345
|
+
// - 'loading': These textures are being uploaded to the GPU
|
|
346
|
+
//
|
|
347
|
+
// For 'failed' and 'freed' states, we only remove them from the tracking
|
|
348
|
+
// arrays without trying to free GPU resources that don't exist.
|
|
349
|
+
|
|
323
350
|
// try a quick cleanup first
|
|
324
351
|
this.cleanupQuick(critical);
|
|
325
352
|
|
|
@@ -356,9 +383,9 @@ export class TextureMemoryManager {
|
|
|
356
383
|
const renderableMemUsed = [...this.loadedTextures.keys()].reduce(
|
|
357
384
|
(acc, texture) => {
|
|
358
385
|
renderableTexturesLoaded += texture.renderable ? 1 : 0;
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
);
|
|
386
|
+
// Get the memory used by the texture, defaulting to 0 if not found
|
|
387
|
+
const textureMemory = this.loadedTextures.get(texture) ?? 0;
|
|
388
|
+
return acc + (texture.renderable ? textureMemory : 0);
|
|
362
389
|
},
|
|
363
390
|
this.baselineMemoryAllocation,
|
|
364
391
|
);
|
|
@@ -125,7 +125,6 @@ export class CoreAnimationController
|
|
|
125
125
|
}
|
|
126
126
|
|
|
127
127
|
private onFinished(this: CoreAnimationController): void {
|
|
128
|
-
assertTruthy(this.stoppedResolve);
|
|
129
128
|
// If the animation is looping, then we need to restart it.
|
|
130
129
|
const { loop, stopMethod } = this.animation.settings;
|
|
131
130
|
|
|
@@ -143,8 +142,11 @@ export class CoreAnimationController
|
|
|
143
142
|
this.unregisterAnimation();
|
|
144
143
|
|
|
145
144
|
// resolve promise
|
|
146
|
-
this.stoppedResolve
|
|
147
|
-
|
|
145
|
+
if (this.stoppedResolve !== null) {
|
|
146
|
+
this.stoppedResolve();
|
|
147
|
+
this.stoppedResolve = null;
|
|
148
|
+
}
|
|
149
|
+
|
|
148
150
|
this.emit('stopped', this);
|
|
149
151
|
this.state = 'stopped';
|
|
150
152
|
}
|
|
@@ -50,6 +50,7 @@ export class WebGlContextWrapper {
|
|
|
50
50
|
private boundArrayBuffer: WebGLBuffer | null;
|
|
51
51
|
private boundElementArrayBuffer: WebGLBuffer | null;
|
|
52
52
|
private curProgram: WebGLProgram | null;
|
|
53
|
+
private curUniformLocations: Record<string, WebGLUniformLocation> = {};
|
|
53
54
|
//#endregion Cached WebGL State
|
|
54
55
|
|
|
55
56
|
//#region Canvas
|
|
@@ -689,16 +690,23 @@ export class WebGlContextWrapper {
|
|
|
689
690
|
* @param program
|
|
690
691
|
* @returns object with numbers
|
|
691
692
|
*/
|
|
692
|
-
getUniformLocations(
|
|
693
|
+
getUniformLocations(
|
|
694
|
+
program: WebGLProgram,
|
|
695
|
+
): Record<string, WebGLUniformLocation> {
|
|
693
696
|
const gl = this.gl;
|
|
694
697
|
const length = gl.getProgramParameter(
|
|
695
698
|
program,
|
|
696
699
|
gl.ACTIVE_UNIFORMS,
|
|
697
700
|
) as number;
|
|
698
|
-
const result = {} as Record<string,
|
|
701
|
+
const result = {} as Record<string, WebGLUniformLocation>;
|
|
699
702
|
for (let i = 0; i < length; i++) {
|
|
700
|
-
const
|
|
701
|
-
|
|
703
|
+
const info = gl.getActiveUniform(program, i) as WebGLActiveInfo;
|
|
704
|
+
//remove bracket + value from uniform name;
|
|
705
|
+
let name = info.name.replace(/\[.*?\]/g, '');
|
|
706
|
+
result[name] = gl.getUniformLocation(
|
|
707
|
+
program,
|
|
708
|
+
name,
|
|
709
|
+
) as WebGLUniformLocation;
|
|
702
710
|
}
|
|
703
711
|
return result;
|
|
704
712
|
}
|
|
@@ -730,12 +738,16 @@ export class WebGlContextWrapper {
|
|
|
730
738
|
* @param program
|
|
731
739
|
* @returns
|
|
732
740
|
*/
|
|
733
|
-
useProgram(
|
|
741
|
+
useProgram(
|
|
742
|
+
program: WebGLProgram | null,
|
|
743
|
+
uniformLocations: Record<string, WebGLUniformLocation>,
|
|
744
|
+
) {
|
|
734
745
|
if (this.curProgram === program) {
|
|
735
746
|
return;
|
|
736
747
|
}
|
|
737
748
|
this.gl.useProgram(program);
|
|
738
749
|
this.curProgram = program;
|
|
750
|
+
this.curUniformLocations = uniformLocations;
|
|
739
751
|
}
|
|
740
752
|
|
|
741
753
|
/**
|
|
@@ -745,10 +757,7 @@ export class WebGlContextWrapper {
|
|
|
745
757
|
* @param v0 - The value to set.
|
|
746
758
|
*/
|
|
747
759
|
uniform1f(location: string, v0: number) {
|
|
748
|
-
this.gl.uniform1f(
|
|
749
|
-
this.gl.getUniformLocation(this.curProgram!, location),
|
|
750
|
-
v0,
|
|
751
|
-
);
|
|
760
|
+
this.gl.uniform1f(this.curUniformLocations[location] || null, v0);
|
|
752
761
|
}
|
|
753
762
|
|
|
754
763
|
/**
|
|
@@ -758,10 +767,7 @@ export class WebGlContextWrapper {
|
|
|
758
767
|
* @param value - The array of values to set.
|
|
759
768
|
*/
|
|
760
769
|
uniform1fv(location: string, value: Float32Array) {
|
|
761
|
-
this.gl.uniform1fv(
|
|
762
|
-
this.gl.getUniformLocation(this.curProgram!, location),
|
|
763
|
-
value,
|
|
764
|
-
);
|
|
770
|
+
this.gl.uniform1fv(this.curUniformLocations[location] || null, value);
|
|
765
771
|
}
|
|
766
772
|
|
|
767
773
|
/**
|
|
@@ -771,10 +777,7 @@ export class WebGlContextWrapper {
|
|
|
771
777
|
* @param v0 - The value to set.
|
|
772
778
|
*/
|
|
773
779
|
uniform1i(location: string, v0: number) {
|
|
774
|
-
this.gl.uniform1i(
|
|
775
|
-
this.gl.getUniformLocation(this.curProgram!, location),
|
|
776
|
-
v0,
|
|
777
|
-
);
|
|
780
|
+
this.gl.uniform1i(this.curUniformLocations[location] || null, v0);
|
|
778
781
|
}
|
|
779
782
|
|
|
780
783
|
/**
|
|
@@ -784,10 +787,7 @@ export class WebGlContextWrapper {
|
|
|
784
787
|
* @param value - The array of values to set.
|
|
785
788
|
*/
|
|
786
789
|
uniform1iv(location: string, value: Int32Array) {
|
|
787
|
-
this.gl.uniform1iv(
|
|
788
|
-
this.gl.getUniformLocation(this.curProgram!, location),
|
|
789
|
-
value,
|
|
790
|
-
);
|
|
790
|
+
this.gl.uniform1iv(this.curUniformLocations[location] || null, value);
|
|
791
791
|
}
|
|
792
792
|
|
|
793
793
|
/**
|
|
@@ -798,11 +798,7 @@ export class WebGlContextWrapper {
|
|
|
798
798
|
* @param v1 - The second component of the vector.
|
|
799
799
|
*/
|
|
800
800
|
uniform2f(location: string, v0: number, v1: number) {
|
|
801
|
-
this.gl.uniform2f(
|
|
802
|
-
this.gl.getUniformLocation(this.curProgram!, location),
|
|
803
|
-
v0,
|
|
804
|
-
v1,
|
|
805
|
-
);
|
|
801
|
+
this.gl.uniform2f(this.curUniformLocations[location] || null, v0, v1);
|
|
806
802
|
}
|
|
807
803
|
|
|
808
804
|
/**
|
|
@@ -813,7 +809,7 @@ export class WebGlContextWrapper {
|
|
|
813
809
|
*/
|
|
814
810
|
uniform2fa(location: string, value: Vec2) {
|
|
815
811
|
this.gl.uniform2f(
|
|
816
|
-
this.
|
|
812
|
+
this.curUniformLocations[location] || null,
|
|
817
813
|
value[0],
|
|
818
814
|
value[1],
|
|
819
815
|
);
|
|
@@ -826,10 +822,7 @@ export class WebGlContextWrapper {
|
|
|
826
822
|
* @param value - The array of vec2 values to set.
|
|
827
823
|
*/
|
|
828
824
|
uniform2fv(location: string, value: Float32Array) {
|
|
829
|
-
this.gl.uniform2fv(
|
|
830
|
-
this.gl.getUniformLocation(this.curProgram!, location),
|
|
831
|
-
value,
|
|
832
|
-
);
|
|
825
|
+
this.gl.uniform2fv(this.curUniformLocations[location] || null, value);
|
|
833
826
|
}
|
|
834
827
|
|
|
835
828
|
/**
|
|
@@ -840,11 +833,7 @@ export class WebGlContextWrapper {
|
|
|
840
833
|
* @param v1 - The second component of the vector.
|
|
841
834
|
*/
|
|
842
835
|
uniform2i(location: string, v0: number, v1: number) {
|
|
843
|
-
this.gl.uniform2i(
|
|
844
|
-
this.gl.getUniformLocation(this.curProgram!, location),
|
|
845
|
-
v0,
|
|
846
|
-
v1,
|
|
847
|
-
);
|
|
836
|
+
this.gl.uniform2i(this.curUniformLocations[location] || null, v0, v1);
|
|
848
837
|
}
|
|
849
838
|
|
|
850
839
|
/**
|
|
@@ -854,10 +843,7 @@ export class WebGlContextWrapper {
|
|
|
854
843
|
* @param value - The array of ivec2 values to set.
|
|
855
844
|
*/
|
|
856
845
|
uniform2iv(location: string, value: Int32Array) {
|
|
857
|
-
this.gl.uniform2iv(
|
|
858
|
-
this.gl.getUniformLocation(this.curProgram!, location),
|
|
859
|
-
value,
|
|
860
|
-
);
|
|
846
|
+
this.gl.uniform2iv(this.curUniformLocations[location] || null, value);
|
|
861
847
|
}
|
|
862
848
|
|
|
863
849
|
/**
|
|
@@ -869,12 +855,7 @@ export class WebGlContextWrapper {
|
|
|
869
855
|
* @param v2 - The third component of the vector.
|
|
870
856
|
*/
|
|
871
857
|
uniform3f(location: string, v0: number, v1: number, v2: number) {
|
|
872
|
-
this.gl.uniform3f(
|
|
873
|
-
this.gl.getUniformLocation(this.curProgram!, location),
|
|
874
|
-
v0,
|
|
875
|
-
v1,
|
|
876
|
-
v2,
|
|
877
|
-
);
|
|
858
|
+
this.gl.uniform3f(this.curUniformLocations[location] || null, v0, v1, v2);
|
|
878
859
|
}
|
|
879
860
|
|
|
880
861
|
/**
|
|
@@ -885,7 +866,7 @@ export class WebGlContextWrapper {
|
|
|
885
866
|
*/
|
|
886
867
|
uniform3fa(location: string, value: Vec3) {
|
|
887
868
|
this.gl.uniform3f(
|
|
888
|
-
this.
|
|
869
|
+
this.curUniformLocations[location] || null,
|
|
889
870
|
value[0],
|
|
890
871
|
value[1],
|
|
891
872
|
value[2],
|
|
@@ -899,10 +880,7 @@ export class WebGlContextWrapper {
|
|
|
899
880
|
* @param value - The array of vec3 values to set.
|
|
900
881
|
*/
|
|
901
882
|
uniform3fv(location: string, value: Float32Array) {
|
|
902
|
-
this.gl.uniform3fv(
|
|
903
|
-
this.gl.getUniformLocation(this.curProgram!, location),
|
|
904
|
-
value,
|
|
905
|
-
);
|
|
883
|
+
this.gl.uniform3fv(this.curUniformLocations[location] || null, value);
|
|
906
884
|
}
|
|
907
885
|
|
|
908
886
|
/**
|
|
@@ -914,12 +892,7 @@ export class WebGlContextWrapper {
|
|
|
914
892
|
* @param v2 - The third component of the vector.
|
|
915
893
|
*/
|
|
916
894
|
uniform3i(location: string, v0: number, v1: number, v2: number) {
|
|
917
|
-
this.gl.uniform3i(
|
|
918
|
-
this.gl.getUniformLocation(this.curProgram!, location),
|
|
919
|
-
v0,
|
|
920
|
-
v1,
|
|
921
|
-
v2,
|
|
922
|
-
);
|
|
895
|
+
this.gl.uniform3i(this.curUniformLocations[location] || null, v0, v1, v2);
|
|
923
896
|
}
|
|
924
897
|
|
|
925
898
|
/**
|
|
@@ -929,10 +902,7 @@ export class WebGlContextWrapper {
|
|
|
929
902
|
* @param value - The array of ivec3 values to set.
|
|
930
903
|
*/
|
|
931
904
|
uniform3iv(location: string, value: Int32Array) {
|
|
932
|
-
this.gl.uniform3iv(
|
|
933
|
-
this.gl.getUniformLocation(this.curProgram!, location),
|
|
934
|
-
value,
|
|
935
|
-
);
|
|
905
|
+
this.gl.uniform3iv(this.curUniformLocations[location] || null, value);
|
|
936
906
|
}
|
|
937
907
|
|
|
938
908
|
/**
|
|
@@ -946,7 +916,7 @@ export class WebGlContextWrapper {
|
|
|
946
916
|
*/
|
|
947
917
|
uniform4f(location: string, v0: number, v1: number, v2: number, v3: number) {
|
|
948
918
|
this.gl.uniform4f(
|
|
949
|
-
this.
|
|
919
|
+
this.curUniformLocations[location] || null,
|
|
950
920
|
v0,
|
|
951
921
|
v1,
|
|
952
922
|
v2,
|
|
@@ -962,7 +932,7 @@ export class WebGlContextWrapper {
|
|
|
962
932
|
*/
|
|
963
933
|
uniform4fa(location: string, value: Vec4) {
|
|
964
934
|
this.gl.uniform4f(
|
|
965
|
-
this.
|
|
935
|
+
this.curUniformLocations[location] || null,
|
|
966
936
|
value[0],
|
|
967
937
|
value[1],
|
|
968
938
|
value[2],
|
|
@@ -977,10 +947,7 @@ export class WebGlContextWrapper {
|
|
|
977
947
|
* @param value - The array of vec4 values to set.
|
|
978
948
|
*/
|
|
979
949
|
uniform4fv(location: string, value: Float32Array) {
|
|
980
|
-
this.gl.uniform4fv(
|
|
981
|
-
this.gl.getUniformLocation(this.curProgram!, location),
|
|
982
|
-
value,
|
|
983
|
-
);
|
|
950
|
+
this.gl.uniform4fv(this.curUniformLocations[location] || null, value);
|
|
984
951
|
}
|
|
985
952
|
|
|
986
953
|
/**
|
|
@@ -994,7 +961,7 @@ export class WebGlContextWrapper {
|
|
|
994
961
|
*/
|
|
995
962
|
uniform4i(location: string, v0: number, v1: number, v2: number, v3: number) {
|
|
996
963
|
this.gl.uniform4i(
|
|
997
|
-
this.
|
|
964
|
+
this.curUniformLocations[location] || null,
|
|
998
965
|
v0,
|
|
999
966
|
v1,
|
|
1000
967
|
v2,
|
|
@@ -1009,10 +976,7 @@ export class WebGlContextWrapper {
|
|
|
1009
976
|
* @param value - The array of ivec4 values to set.
|
|
1010
977
|
*/
|
|
1011
978
|
uniform4iv(location: string, value: Int32Array) {
|
|
1012
|
-
this.gl.uniform4iv(
|
|
1013
|
-
this.gl.getUniformLocation(this.curProgram!, location),
|
|
1014
|
-
value,
|
|
1015
|
-
);
|
|
979
|
+
this.gl.uniform4iv(this.curUniformLocations[location] || null, value);
|
|
1016
980
|
}
|
|
1017
981
|
|
|
1018
982
|
/**
|
|
@@ -1024,7 +988,7 @@ export class WebGlContextWrapper {
|
|
|
1024
988
|
*/
|
|
1025
989
|
uniformMatrix2fv(location: string, value: Float32Array) {
|
|
1026
990
|
this.gl.uniformMatrix2fv(
|
|
1027
|
-
this.
|
|
991
|
+
this.curUniformLocations[location] || null,
|
|
1028
992
|
false,
|
|
1029
993
|
value,
|
|
1030
994
|
);
|
|
@@ -1037,7 +1001,7 @@ export class WebGlContextWrapper {
|
|
|
1037
1001
|
*/
|
|
1038
1002
|
uniformMatrix3fv(location: string, value: Float32Array) {
|
|
1039
1003
|
this.gl.uniformMatrix3fv(
|
|
1040
|
-
this.
|
|
1004
|
+
this.curUniformLocations[location] || null,
|
|
1041
1005
|
false,
|
|
1042
1006
|
value,
|
|
1043
1007
|
);
|
|
@@ -1050,7 +1014,7 @@ export class WebGlContextWrapper {
|
|
|
1050
1014
|
*/
|
|
1051
1015
|
uniformMatrix4fv(location: string, value: Float32Array) {
|
|
1052
1016
|
this.gl.uniformMatrix4fv(
|
|
1053
|
-
this.
|
|
1017
|
+
this.curUniformLocations[location] || null,
|
|
1054
1018
|
false,
|
|
1055
1019
|
value,
|
|
1056
1020
|
);
|
|
@@ -1319,6 +1283,36 @@ export class WebGlContextWrapper {
|
|
|
1319
1283
|
deleteShader(shader: WebGLShader) {
|
|
1320
1284
|
this.gl.deleteShader(shader);
|
|
1321
1285
|
}
|
|
1286
|
+
|
|
1287
|
+
/**
|
|
1288
|
+
* ```
|
|
1289
|
+
* gl.deleteBuffer(buffer);
|
|
1290
|
+
* ```
|
|
1291
|
+
*
|
|
1292
|
+
* @param buffer - The buffer to delete
|
|
1293
|
+
*/
|
|
1294
|
+
deleteBuffer(buffer: WebGLBuffer) {
|
|
1295
|
+
const { gl } = this;
|
|
1296
|
+
gl.deleteBuffer(buffer);
|
|
1297
|
+
|
|
1298
|
+
// Reset bound buffers if they match the deleted buffer
|
|
1299
|
+
if (this.boundArrayBuffer === buffer) {
|
|
1300
|
+
this.boundArrayBuffer = null;
|
|
1301
|
+
}
|
|
1302
|
+
}
|
|
1303
|
+
|
|
1304
|
+
/**
|
|
1305
|
+
* ```
|
|
1306
|
+
* gl.deleteVertexArray(vertexArray);
|
|
1307
|
+
* ```
|
|
1308
|
+
*
|
|
1309
|
+
* @param vertexArray - The vertex array object to delete
|
|
1310
|
+
*/
|
|
1311
|
+
deleteVertexArray(vertexArray: WebGLVertexArrayObject) {
|
|
1312
|
+
if (this.isWebGl2()) {
|
|
1313
|
+
(this.gl as WebGL2RenderingContext).deleteVertexArray(vertexArray);
|
|
1314
|
+
}
|
|
1315
|
+
}
|
|
1322
1316
|
}
|
|
1323
1317
|
|
|
1324
1318
|
// prettier-ignore
|
|
@@ -35,8 +35,7 @@ import {
|
|
|
35
35
|
} from './internal/ShaderUtils.js';
|
|
36
36
|
|
|
37
37
|
export class WebGlShaderProgram implements CoreShaderProgram {
|
|
38
|
-
protected
|
|
39
|
-
protected program: WebGLProgram;
|
|
38
|
+
protected program: WebGLProgram | null;
|
|
40
39
|
/**
|
|
41
40
|
* Vertex Array Object
|
|
42
41
|
*
|
|
@@ -47,9 +46,11 @@ export class WebGlShaderProgram implements CoreShaderProgram {
|
|
|
47
46
|
protected renderer: WebGlRenderer;
|
|
48
47
|
protected glw: WebGlContextWrapper;
|
|
49
48
|
protected attributeLocations: Record<string, number>;
|
|
49
|
+
protected uniformLocations: Record<string, WebGLUniformLocation> | null;
|
|
50
50
|
protected lifecycle: Pick<WebGlShaderType, 'update' | 'canBatch'>;
|
|
51
51
|
protected useSystemAlpha = false;
|
|
52
52
|
protected useSystemDimensions = false;
|
|
53
|
+
public isDestroyed = false;
|
|
53
54
|
supportsIndexedTextures = false;
|
|
54
55
|
|
|
55
56
|
constructor(
|
|
@@ -117,10 +118,10 @@ export class WebGlShaderProgram implements CoreShaderProgram {
|
|
|
117
118
|
this.program = program;
|
|
118
119
|
this.attributeLocations = glw.getAttributeLocations(program);
|
|
119
120
|
|
|
120
|
-
this.
|
|
121
|
-
|
|
122
|
-
this.
|
|
123
|
-
|
|
121
|
+
const uniLocs = (this.uniformLocations = glw.getUniformLocations(program));
|
|
122
|
+
|
|
123
|
+
this.useSystemAlpha = uniLocs['u_alpha'] !== undefined;
|
|
124
|
+
this.useSystemDimensions = uniLocs['u_dimensions'] !== undefined;
|
|
124
125
|
|
|
125
126
|
this.lifecycle = {
|
|
126
127
|
update: config.update,
|
|
@@ -133,7 +134,7 @@ export class WebGlShaderProgram implements CoreShaderProgram {
|
|
|
133
134
|
}
|
|
134
135
|
|
|
135
136
|
disableAttributes() {
|
|
136
|
-
const
|
|
137
|
+
const glw = this.glw;
|
|
137
138
|
const attribs = Object.keys(this.attributeLocations);
|
|
138
139
|
const attribLen = attribs.length;
|
|
139
140
|
for (let i = 0; i < attribLen; i++) {
|
|
@@ -221,13 +222,13 @@ export class WebGlShaderProgram implements CoreShaderProgram {
|
|
|
221
222
|
);
|
|
222
223
|
}
|
|
223
224
|
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
225
|
+
if (this.useSystemAlpha === true) {
|
|
226
|
+
this.glw.uniform1f('u_alpha', renderOp.alpha);
|
|
227
|
+
}
|
|
227
228
|
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
229
|
+
if (this.useSystemDimensions === true) {
|
|
230
|
+
this.glw.uniform2f('u_dimensions', renderOp.width, renderOp.height);
|
|
231
|
+
}
|
|
231
232
|
|
|
232
233
|
/**temporary fix to make sdf texts work */
|
|
233
234
|
if (renderOp.sdfShaderProps !== undefined) {
|
|
@@ -306,7 +307,10 @@ export class WebGlShaderProgram implements CoreShaderProgram {
|
|
|
306
307
|
}
|
|
307
308
|
|
|
308
309
|
attach(): void {
|
|
309
|
-
|
|
310
|
+
if (this.isDestroyed === true) {
|
|
311
|
+
return;
|
|
312
|
+
}
|
|
313
|
+
this.glw.useProgram(this.program, this.uniformLocations!);
|
|
310
314
|
if (this.glw.isWebGl2() && this.vao) {
|
|
311
315
|
this.glw.bindVertexArray(this.vao);
|
|
312
316
|
}
|
|
@@ -315,4 +319,23 @@ export class WebGlShaderProgram implements CoreShaderProgram {
|
|
|
315
319
|
detach(): void {
|
|
316
320
|
this.disableAttributes();
|
|
317
321
|
}
|
|
322
|
+
|
|
323
|
+
destroy() {
|
|
324
|
+
if (this.isDestroyed === true) {
|
|
325
|
+
return;
|
|
326
|
+
}
|
|
327
|
+
const glw = this.glw;
|
|
328
|
+
|
|
329
|
+
this.detach();
|
|
330
|
+
|
|
331
|
+
glw.deleteProgram(this.program!);
|
|
332
|
+
this.program = null;
|
|
333
|
+
this.uniformLocations = null;
|
|
334
|
+
|
|
335
|
+
const attribs = Object.keys(this.attributeLocations);
|
|
336
|
+
const attribLen = attribs.length;
|
|
337
|
+
for (let i = 0; i < attribLen; i++) {
|
|
338
|
+
this.glw.deleteBuffer(attribs[i]!);
|
|
339
|
+
}
|
|
340
|
+
}
|
|
318
341
|
}
|
|
@@ -144,6 +144,12 @@ export abstract class Texture extends EventEmitter {
|
|
|
144
144
|
private _dimensions: Dimensions | null = null;
|
|
145
145
|
private _error: Error | null = null;
|
|
146
146
|
|
|
147
|
+
/**
|
|
148
|
+
* Texture states that are considered transitional and should be skipped during cleanup
|
|
149
|
+
*/
|
|
150
|
+
public static readonly TRANSITIONAL_TEXTURE_STATES: readonly TextureState[] =
|
|
151
|
+
['fetching', 'fetched', 'loading'];
|
|
152
|
+
|
|
147
153
|
// aggregate state
|
|
148
154
|
public state: TextureState = 'initial';
|
|
149
155
|
|
|
@@ -258,10 +264,13 @@ export abstract class Texture extends EventEmitter {
|
|
|
258
264
|
* cleaned up.
|
|
259
265
|
*/
|
|
260
266
|
destroy(): void {
|
|
261
|
-
|
|
262
|
-
this.
|
|
267
|
+
// Only free GPU resources if we're in a state where they exist
|
|
268
|
+
if (this.state === 'loaded') {
|
|
269
|
+
this.free();
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
// Always free texture data regardless of state
|
|
263
273
|
this.freeTextureData();
|
|
264
|
-
this.renderableOwners.clear();
|
|
265
274
|
}
|
|
266
275
|
|
|
267
276
|
/**
|