mirror of
https://github.com/bilawalsidhu/gods-eye-view.git
synced 2026-11-14 23:32:20 +00:00
Dispose a Navara layer effect's pass when the layer detaches so engine switches stop retaining its material and textures
Layers re-create their ground effects on every attach. Navara's removePass leaves the EffectPass undisposed, so each switch kept its EffectMaterial in three's program and material caches, together with the uniforms' DataTextures and their Float32Array data (earthquakes: about 47 KB of buffers and one WebGL program per switch). engine.LayerEffectDesc now disposes the raw pass on delete, as the app's own effects do.
This commit is contained in:
1 parent
726e201314
commit
ebc717df8b
3 files changed
+59
-3
No files matched your search
@@ -1,6 +1,10 @@
|
||||
import assert from 'node:assert/strict';
|
||||
import test from 'node:test';
|
||||
import { withFrameUpdates, withPassDisposal } from './frameDescriptor.js';
|
||||
import {
|
||||
layerEffectDesc,
|
||||
withFrameUpdates,
|
||||
withPassDisposal,
|
||||
} from './frameDescriptor.js';
|
||||
|
||||
test('deleting a descriptor unsubscribes only that renderer from the warm view', () => {
|
||||
const frames = new Set();
|
||||
@@ -77,3 +81,46 @@ test('a deleted effect disposes the pass the composer no longer holds', () => {
|
||||
assert.throws(() => new (withPassDisposal(Failing))().onDestroy(), /removal/);
|
||||
assert.deepEqual(events, ['dispose']);
|
||||
});
|
||||
|
||||
test('a layer effect re-created on every attach leaves no pass, material or frame callback behind', () => {
|
||||
const frames = new Set();
|
||||
const view = {
|
||||
on: (name, cb) => frames.add(cb),
|
||||
off: (name, cb) => frames.delete(cb),
|
||||
};
|
||||
const live = new Set();
|
||||
class EffectDesc {
|
||||
view = view;
|
||||
onCreate() {
|
||||
const pass = {
|
||||
material: {},
|
||||
dispose: () => live.delete(pass),
|
||||
};
|
||||
live.add(pass);
|
||||
this._instance = { rawPass: pass };
|
||||
}
|
||||
get raw() {
|
||||
return this._instance;
|
||||
}
|
||||
onDestroy() {
|
||||
// Navara's removePass: out of the composer, not disposed.
|
||||
this._instance = undefined;
|
||||
}
|
||||
}
|
||||
// As the earthquakes ground effect: disposes its own effect, then super.
|
||||
class LayerEffect extends layerEffectDesc(EffectDesc) {
|
||||
updateFrame() {}
|
||||
onDestroy() {
|
||||
this.effectDisposed = true;
|
||||
super.onDestroy();
|
||||
}
|
||||
}
|
||||
for (let attach = 0; attach < 50; attach++) {
|
||||
const effect = new LayerEffect();
|
||||
effect.onCreate();
|
||||
effect.onDestroy();
|
||||
assert.equal(effect.effectDisposed, true);
|
||||
}
|
||||
assert.equal(live.size, 0, 'every pass of a deleted effect is disposed');
|
||||
assert.equal(frames.size, 0, 'no frame callback outlives its effect');
|
||||
});
|
||||
Reference in new issue
Block a user