Skip to content

Commit c769105

Browse files
sergeystomagreggman
authored andcommitted
Track object creation (and texture update) stack trace and expose tracked textures in the extension info call.
1 parent a4e0db7 commit c769105

File tree

5 files changed

+57
-3
lines changed

5 files changed

+57
-3
lines changed

src/augment-api.js

+7
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@ import {
2929
getDrawingbufferInfo,
3030
isBufferSource,
3131
isNumber,
32+
getStackTrace,
33+
collectObjects,
3234
} from './utils.js';
3335

3436
//------------ [ from https://github.com/KhronosGroup/WebGLDeveloperTools ]
@@ -87,6 +89,7 @@ export function augmentAPI(ctx, nameOfClass, options = {}) {
8789
ctx: {
8890
getMemoryInfo() {
8991
const drawingbuffer = computeDrawingbufferSize(ctx, drawingBufferInfo);
92+
const textures = collectObjects(sharedState, 'WebGLTexture');
9093
return {
9194
memory: {
9295
...memory,
@@ -96,6 +99,7 @@ export function augmentAPI(ctx, nameOfClass, options = {}) {
9699
resources: {
97100
...resources,
98101
},
102+
textures,
99103
};
100104
},
101105
},
@@ -203,6 +207,7 @@ export function augmentAPI(ctx, nameOfClass, options = {}) {
203207
++resources[typeName];
204208
webglObjectToMemory.set(webglObj, {
205209
size: 0,
210+
stackCreated: getStackTrace(),
206211
});
207212
};
208213
}
@@ -314,6 +319,8 @@ export function augmentAPI(ctx, nameOfClass, options = {}) {
314319

315320
memory.texture -= oldSize;
316321
memory.texture += info.size;
322+
323+
info.stackUpdated = getStackTrace();
317324
}
318325

319326
function updateTexStorage(target, levels, internalFormat, width, height, depth) {

src/utils.js

+20
Original file line numberDiff line numberDiff line change
@@ -126,3 +126,23 @@ export function computeDrawingbufferSize(gl, drawingBufferInfo) {
126126
export function isNumber(v) {
127127
return typeof v === 'number';
128128
}
129+
130+
export function collectObjects(state, type) {
131+
const list = [...state.webglObjectToMemory.keys()]
132+
.filter((obj) => obj.constructor.name === type)
133+
.map((obj) => state.webglObjectToMemory.get(obj));
134+
135+
return list;
136+
}
137+
138+
function cleanStackLine(line) {
139+
return line.replace(/^\s*at\s+/, '');
140+
}
141+
142+
export function getStackTrace() {
143+
const stack = (new Error()).stack;
144+
const lines = stack.split('\n');
145+
// Remove the first two entries, the error message and this function itself, or the webgl-memory itself.
146+
const userLines = lines.slice(2).filter((l) => !l.includes('webgl-memory'));
147+
return userLines.map((l) => cleanStackLine(l));
148+
}

test/index.js

+1
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import './tests/sync-tests.js';
1111
import './tests/texture-tests.js';
1212
import './tests/transformfeedback-tests.js';
1313
import './tests/vertexarray-tests.js';
14+
import './tests/stack-tests.js';
1415

1516
const settings = Object.fromEntries(new URLSearchParams(window.location.search).entries());
1617
if (settings.reporter) {

test/tests/info-tests.js

+5-3
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ describe('info tests', () => {
2222
assertEqual(drawingbufferSize, canvasSize);
2323

2424
const info = ext.getMemoryInfo();
25-
const {memory, resources} = info;
25+
const {memory, resources, textures} = info;
2626

2727
assertEqual(memory.buffer, 0);
2828
assertEqual(memory.texture, 0);
@@ -40,14 +40,15 @@ describe('info tests', () => {
4040
assertEqual(resources.texture, 0);
4141
assertEqual(resources.transformFeedback, undefined);
4242
assertEqual(resources.vertexArray, undefined);
43+
assertEqual(textures.length, 0);
4344
});
4445

4546
it('test base state webgl2', () => {
4647
const {ext, drawingbufferSize} = createContext2();
4748
assertTruthy(ext, 'got extension');
4849

4950
const info = ext.getMemoryInfo();
50-
const {memory, resources} = info;
51+
const {memory, resources, textures} = info;
5152

5253
assertEqual(memory.buffer, 0);
5354
assertEqual(memory.texture, 0);
@@ -65,6 +66,7 @@ describe('info tests', () => {
6566
assertEqual(resources.texture, 0);
6667
assertEqual(resources.transformFeedback, 0);
6768
assertEqual(resources.vertexArray, 0);
69+
assertEqual(textures.length, 0);
6870
});
6971

7072
it('test canvas resize', () => {
@@ -92,4 +94,4 @@ describe('info tests', () => {
9294

9395
});
9496

95-
});
97+
});

test/tests/stack-tests.js

+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import {describe, it} from '../mocha-support.js';
2+
import {assertEqual, assertTruthy} from '../assert.js';
3+
import {createContext} from '../webgl.js';
4+
5+
describe('stack tests', () => {
6+
7+
it('test stack capture', () => {
8+
const {gl, ext} = createContext();
9+
10+
const tex1 = gl.createTexture();
11+
12+
gl.bindTexture(gl.TEXTURE_2D, tex1);
13+
gl.texImage2D(gl.TEXTURE_2D, 1, gl.RGBA, 16, 8, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
14+
15+
const info = ext.getMemoryInfo();
16+
const {textures} = info;
17+
18+
assertEqual(textures.length, 1);
19+
assertTruthy(textures[0].stackCreated);
20+
assertTruthy(textures[0].stackUpdated);
21+
22+
gl.deleteTexture(tex1);
23+
});
24+
});

0 commit comments

Comments
 (0)