Skip to content

fix(gsplat): free SOG bundle archive memory after texture upload#8972

Merged
mvaligursky merged 1 commit into
mainfrom
mv-sog-free-archive-memory
Jun 26, 2026
Merged

fix(gsplat): free SOG bundle archive memory after texture upload#8972
mvaligursky merged 1 commit into
mainfrom
mv-sog-free-archive-memory

Conversation

@mvaligursky

@mvaligursky mvaligursky commented Jun 26, 2026

Copy link
Copy Markdown
Contributor

Summary

SogBundleParser keeps the downloaded .sog zip archive ArrayBuffer alive after parsing: each embedded texture Asset is created with contents: file.data, and for stored (non-deflate) entries file.data is a Uint8Array view into the archive buffer. As long as those assets retain file.contents, the whole archive cannot be garbage collected — duplicating the CPU footprint of the splat.

This nulls each embedded texture asset's file.contents once the textures have been decoded and uploaded (await Promise.allSettled(promises)), letting the archive buffer be freed.

The decoded source kept by each texture (for re-upload on device context loss) is standard engine behaviour for all textures and is intentionally left untouched, so context restore is unaffected.

Fixes #8080.

Testing

Verified on the shadow-soft example (bicycle.sog, 14.8 MB archive):

  • Baseline retained 14.1 MB of encoded file.contents across the 7 embedded textures.
  • With the fix: 0 bytes retained; used JS heap ~10 MB lower; rendering intact.

The embedded texture assets created by SogBundleParser retain `file.contents`,
which are views into the downloaded zip archive ArrayBuffer. Null them once the
textures are decoded and uploaded, so the whole archive can be garbage collected.
The decoded ImageBitmap kept by each texture (for re-upload on device context
loss) is a separate copy and is unaffected.

Relates to #8080.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown

Build size report

This PR changes the size of the minified bundles.

Bundle Minified Gzip Brotli
playcanvas.min.js 2262.6 KB (+0.1 KB, +0.00%) 582.1 KB (+0.0 KB, +0.00%) 452.6 KB (−0.2 KB, −0.03%)
playcanvas.min.mjs 2260.0 KB (+0.1 KB, +0.00%) 581.1 KB (+0.0 KB, +0.00%) 451.7 KB (−0.4 KB, −0.08%)

@mvaligursky mvaligursky merged commit 3e0f450 into main Jun 26, 2026
10 checks passed
@mvaligursky mvaligursky deleted the mv-sog-free-archive-memory branch June 26, 2026 09:55
mvaligursky added a commit that referenced this pull request Jun 26, 2026
The embedded texture assets created by SogBundleParser retain `file.contents`,
which are views into the downloaded zip archive ArrayBuffer. Null them once the
textures are decoded and uploaded, so the whole archive can be garbage collected.
The decoded ImageBitmap kept by each texture (for re-upload on device context
loss) is a separate copy and is unaffected.

Relates to #8080.

Co-authored-by: Martin Valigursky <mvaligursky@snapchat.com>
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

SogBundleParser keeps raw file data allocated

1 participant