Skip to content

Commit 59dda76

Browse files
mvaligurskyMartin Valigursky
andauthored
Fixes to SOGS data unloading (#7951)
* Fixes to SOGS data unloading * one more * some more * cleanup * simplified * inlined * fix --------- Co-authored-by: Martin Valigursky <[email protected]>
1 parent 24ca7b3 commit 59dda76

File tree

5 files changed

+42
-5
lines changed

5 files changed

+42
-5
lines changed

src/framework/asset/asset.js

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -623,10 +623,7 @@ class Asset extends EventHandler {
623623

624624
// destroy resources
625625
for (let i = 0; i < old.length; ++i) {
626-
const resource = old[i];
627-
if (resource && resource.destroy) {
628-
resource.destroy();
629-
}
626+
old[i]?.destroy?.();
630627
}
631628
}
632629

src/framework/parsers/sogs.js

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,17 @@ class SogsParser {
135135

136136
const textureAssets = subs.map(sub => textures[sub]).flat();
137137

138+
// When the parent gsplat asset unloads, remove and unload child texture assets
139+
asset.once('unload', () => {
140+
textureAssets.forEach((t) => {
141+
// remove from registry
142+
assets.remove(t);
143+
144+
// destroys resource
145+
t.unload();
146+
});
147+
});
148+
138149
combineProgress(asset, textureAssets);
139150

140151
textureAssets.forEach(t => assets.load(t));
@@ -157,10 +168,14 @@ class SogsParser {
157168
const decompress = asset.data?.decompress;
158169

159170
if (!decompress) {
171+
if (!this.app?.graphicsDevice || this.app?.graphicsDevice?._destroyed) return;
172+
160173
// no need to prepare gpu data if decompressing
161174
await data.prepareGpuData();
162175
}
163176

177+
if (!this.app?.graphicsDevice || this.app?.graphicsDevice?._destroyed) return;
178+
164179
const resource = decompress ?
165180
new GSplatResource(this.app.graphicsDevice, await data.decompress()) :
166181
new GSplatSogsResource(this.app.graphicsDevice, data);

src/platform/graphics/graphics-device.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -389,6 +389,12 @@ class GraphicsDevice extends EventHandler {
389389
*/
390390
gpuProfiler;
391391

392+
/**
393+
* @type {boolean}
394+
* @ignore
395+
*/
396+
_destroyed = false;
397+
392398
defaultClearOptions = {
393399
color: [0, 0, 0, 1],
394400
depth: 1,
@@ -539,6 +545,8 @@ class GraphicsDevice extends EventHandler {
539545

540546
this.gpuProfiler?.destroy();
541547
this.gpuProfiler = null;
548+
549+
this._destroyed = true;
542550
}
543551

544552
onDestroyShader(shader) {

src/platform/graphics/webgl/webgl-graphics-device.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2021,6 +2021,9 @@ class WebglGraphicsDevice extends GraphicsDevice {
20212021
return new Promise((resolve, reject) => {
20222022
this.readPixelsAsync(x, y, width, height, data).then((data) => {
20232023

2024+
// return if the device was destroyed
2025+
if (this._destroyed) return;
2026+
20242027
// destroy RT if we created it
20252028
if (!options.renderTarget) {
20262029
renderTarget.destroy();

src/scene/gsplat/gsplat-sogs-data.js

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,10 @@ class GSplatSogsData {
167167

168168
packedShN;
169169

170-
destroy() {
170+
// Marked when resource is destroyed, to abort any in-flight async preparation
171+
destroyed = false;
172+
173+
_destroyGpuResources() {
171174
this.means_l?.destroy();
172175
this.means_u?.destroy();
173176
this.quats?.destroy();
@@ -180,6 +183,11 @@ class GSplatSogsData {
180183
this.packedShN?.destroy();
181184
}
182185

186+
destroy() {
187+
this.destroyed = true;
188+
this._destroyGpuResources();
189+
}
190+
183191
createIter(p, r, s, c, sh) {
184192
return new GSplatSogsIterator(this, p, r, s, c, sh);
185193
}
@@ -438,9 +446,13 @@ class GSplatSogsData {
438446
const { device, height, width } = this.means_l;
439447

440448
// copy back means_l and means_u data so cpu reorder has access to it
449+
if (this.destroyed || device._destroyed) return; // skip the rest if the resource was destroyed
441450
this.means_l._levels[0] = await readImageDataAsync(this.means_l);
451+
452+
if (this.destroyed || device._destroyed) return; // skip the rest if the resource was destroyed
442453
this.means_u._levels[0] = await readImageDataAsync(this.means_u);
443454

455+
if (this.destroyed || device._destroyed) return; // skip the rest if the resource was destroyed
444456
this.packedTexture = new Texture(device, {
445457
name: 'sogsPackedTexture',
446458
width,
@@ -472,8 +484,10 @@ class GSplatSogsData {
472484
}
473485
});
474486

487+
if (this.destroyed || device._destroyed) return; // skip the rest if the resource was destroyed
475488
this.packGpuMemory();
476489
if (this.packedShN) {
490+
if (this.destroyed || device._destroyed) return; // skip the rest if the resource was destroyed
477491
this.packShMemory();
478492
}
479493
}

0 commit comments

Comments
 (0)