@@ -30,7 +30,12 @@ Then in your code
3030const ext = gl .getExtension (' GMAN_webgl_memory' );
3131...
3232if (ext) {
33+ // memory info
3334 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 );
3439}
3540```
3641
@@ -60,6 +65,35 @@ The info returned is
6065}
6166```
6267
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+
6397## Caveats
6498
65991. You must have WebGL error free code.
@@ -85,8 +119,73 @@ The info returned is
85119 the issue by watching your resources counts climb.
86120
87121 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 `
90189
91190 Be aware that ` texImage2D/ 3D ` *may* require double the memory of
92191 ` texStorage2D/ 3D ` .
@@ -109,7 +208,7 @@ The info returned is
109208 you can just upload the new image to the existing texture. With ` texStorage`
110209 you'd be required to create a new texture.
111210
112- 4 . ` ELEMENT_ARRAY_BUFFER `
211+ 5 . ` ELEMENT_ARRAY_BUFFER `
113212
114213 Buffers used with ` ELEMENT_ARRAY_BUFFER ` may need a second copy in ram.
115214 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
209308I structured it this way just because I used [webgl- lint](https: // greggman.github.io/webgl-lint) as
210309the basis to get this working.
211310
212- ## Licence
311+ ## License
213312
214313[MIT ](https: // github.com/greggman/webgl-memory/blob/main/LICENCE.md)
0 commit comments