@@ -30,7 +30,12 @@ Then in your code
30
30
const ext = gl .getExtension (' GMAN_webgl_memory' );
31
31
...
32
32
if (ext) {
33
+ // memory info
33
34
const info = ext .getMemoryInfo ();
35
+ // every texture, it's size, a stack of where it was created and a stack of where it was last updated.
36
+ const textures = ext .getResourcesInfo (WebGLTexture );
37
+ // every buffer, it's size, a stack of where it was created and a stack of where it was last updated.
38
+ const buffers = ext .getResourcesInfo (WebGLBuffer );
34
39
}
35
40
```
36
41
@@ -60,6 +65,35 @@ The info returned is
60
65
}
61
66
```
62
67
68
+ The data for textures and buffers
69
+
70
+ ``` js
71
+ const ext = gl .getExtension (' GMAN_webgl_memory' );
72
+ ...
73
+ if (ext) {
74
+ const tex = gl .createTexture (); // 1
75
+ gl .bindTexture (gl .TEXTURE_2D , tex);
76
+ gl .texStorage2D (gl .TEXTURE_2D , 1 , gl .RGBA8 , 4 , 1 ); // 2
77
+
78
+ const buf = gl .createBuffer (); // 3
79
+ gl .bindBuffer (gl .ARRAY_BUFFER );
80
+ gl .bufferData (gl .ARRAY_BUFFER , 32 , gl .STATIC_DRAW ); // 4
81
+
82
+
83
+ const textures = ext .getResourcesInfo (WebGLTexture );
84
+ const buffers = ext .getResourcesInfo (WebGLBuffer );
85
+ ` ` `
86
+
87
+ ` ` ` js
88
+ textures = [
89
+ { size: 16 , stackCreated: ' ...1...' , stackUpdated: ' ...2...' }
90
+ ]
91
+
92
+ buffers = [
93
+ { size: 32 , stackCreated: ' ...3' ' ' ., stackUpdated: ' ...4...' }
94
+ ]
95
+ ` ` `
96
+
63
97
## Caveats
64
98
65
99
1. You must have WebGL error free code.
@@ -85,8 +119,73 @@ The info returned is
85
119
the issue by watching your resources counts climb.
86
120
87
121
Given that it seemed okay to skip this for now.
88
-
89
- 3 . ` texImage2D/3D ` vs ` texStorage2D/3D `
122
+
123
+ 3. Deletion by Garbage Collection (GC) is not supported
124
+
125
+ In JavaScript and WebGL, it's possible to let things get auto deleted by GC.
126
+
127
+ ` ` ` js
128
+ {
129
+ const buf = gl .createBuffer ();
130
+ gl .bindBuffer (gl .ARRAY_BUFFER , buf);
131
+ gl .bufferData (gl .ARRAY_BUFFER , 1024 * 1024 * 256 , gl .STATIC_DRAW );
132
+ gl .bindBuffer (gl .ARRAY_BUFFER , null );
133
+ }
134
+ ` ` `
135
+
136
+ Given the code above, buffer will, at some point in the future, get automatically
137
+ deleted. The problem is you have no idea when. JavaScript does know now the size of
138
+ VRAM nor does it have any concept of the size of the WebGL buffer (256meg in this case).
139
+ All JavaScript has is a tiny object that holds an ID for the actual OpenGL buffer
140
+ and maybe a little metadata.
141
+
142
+ That means there's absolutely no pressure to delete the buffer above in a timely
143
+ manner nor either is there any way for JavaScript to know that releasing that
144
+ object would free up VRAM.
145
+
146
+ In other words. Let's say you had a total of 384meg of ram. You'd expect this to
147
+ work.
148
+
149
+ ` ` ` js
150
+ {
151
+ const a = new Uint32Array (256 * 1024 * 1024 )
152
+ }
153
+ {
154
+ const b = new Uint32Array (256 * 1024 * 1024 )
155
+ }
156
+ ` ` `
157
+
158
+ The code above allocates 512meg. Given we were pretending the system only has 384meg,
159
+ JavaScript will likely free ` a` to make room for ` b`
160
+
161
+ Now, Let's do the WebGL case and assume 384meg of VRAM
162
+
163
+ ` ` ` js
164
+ {
165
+ const a = gl .createBuffer ();
166
+ gl .bindBuffer (gl .ARRAY_BUFFER , buf);
167
+ gl .bufferData (gl .ARRAY_BUFFER , 1024 * 1024 * 256 , gl .STATIC_DRAW );
168
+ gl .bindBuffer (gl .ARRAY_BUFFER , null );
169
+ }
170
+ {
171
+ const b = gl .createBuffer ();
172
+ gl .bindBuffer (gl .ARRAY_BUFFER , buf);
173
+ gl .bufferData (gl .ARRAY_BUFFER , 1024 * 1024 * 256 , gl .STATIC_DRAW );
174
+ gl .bindBuffer (gl .ARRAY_BUFFER , null );
175
+ }
176
+ ` ` `
177
+
178
+ In this case, JavaScript only sees ` a` as taking a few bytes (the object that tracks
179
+ the OpenGL resource) so it has no idea that it needs to free ` a` to make room for ` b` .
180
+ This could would fail, ideally with ` gl .OUT_OF_MEMORY ` .
181
+
182
+ That was the long way of saying, you should never count on GC for WebGL!
183
+ Free your resources explicitly!
184
+
185
+ That's also part of the reason why we don't support this case because
186
+ counting on GC is not a useful solution.
187
+
188
+ 4. ` texImage2D/ 3D ` vs ` texStorage2D/ 3D `
90
189
91
190
Be aware that ` texImage2D/ 3D ` *may* require double the memory of
92
191
` texStorage2D/ 3D ` .
@@ -109,7 +208,7 @@ The info returned is
109
208
you can just upload the new image to the existing texture. With ` texStorage`
110
209
you'd be required to create a new texture.
111
210
112
- 4 . ` ELEMENT_ARRAY_BUFFER `
211
+ 5 . ` ELEMENT_ARRAY_BUFFER `
113
212
114
213
Buffers used with ` ELEMENT_ARRAY_BUFFER ` may need a second copy in ram.
115
214
This is because WebGL requires no out of bounds memory access (eg,
@@ -209,6 +308,6 @@ vs just some library you call like `webglMemoryTracker.init(someWebGLRenderingCo
209
308
I structured it this way just because I used [webgl- lint](https: // greggman.github.io/webgl-lint) as
210
309
the basis to get this working.
211
310
212
- ## Licence
311
+ ## License
213
312
214
313
[MIT ](https: // github.com/greggman/webgl-memory/blob/main/LICENCE.md)
0 commit comments