In my ever going quest to improve performance (and keep memory flat), I started experimenting with SharedArrayBuffer(SAB) and having glb assets downloaded and pre-processed much as possible before being added into the buffer for Babylon to load.
For the first phase, I was just trying to get the glb binary data across and loaded by Babylon and further pre-processing in the worker would be a next step.
I got pretty far but running into one issue at the end that I have a question about. The steps I took so far:
Fork GLTFFileLoader, call it SABGLBLoader and register it as a plugin
Make a SAB and pass it to the plugin. Modify createPlugin to pass the SAB in.
Load a glb buffer in the worker and put it into SAB at appropriate offset
Return true from canDirectLoad
Trick SceneLoader.LoadAssetContainerAsync into using directLoad by passing data:sabglb for the rooturl.
SABGLBLoader directLoad passes the SAB into readAsync, offset needed and length
In _unpackBinaryV2Async JSON needs to be copied to new Buffer/TypedArray because Decode throws this: failed to execute 'decode' on 'textdecoder' the provided arraybufferview value must not be shared
Everything loads from there until I made it to the Blobs It’s a similar issue to using Decode on the json. Failed to construct 'Blob': The provided ArrayBufferView value must not be shared.
( funfact there is exactly 1 google result for this error, in the webkit source/tests itself. This is either really dumb or pushing whats possible here haha)
Is this the end of this exact path for me or can anyone think of something different ?
I see I could possibly store then as base64 strings in the buffer and load that way instead ? I did not see a way I could hack that in without getting into BabylonJS code itself. I am not sure about if this would double memory for an asset or not either
That said, I’m not exactly sure what you are trying to do. Are you trying to do as much work as possible off of the main thread?
Yes, in particular downloading a glb and then decoding the images. I don’t think SAB is the only option for this, I would look into transferring individual array buffers next if SAB can’t be done. One large SAB interests me because of the fixed size. I have a feeling that for applications that load/unload massive amounts of data, iOSs memory sheriff called Jetsam will be much happier with this pattern. There is also a cost to using postMessage with Transfer that SAB does not incur if used correctly with Atomics
The fixed size memory for assets is appealing as well though. Do you have any thoughts on the part I am stuck at now with SAB ? I think basically the question now is: Could decoded images be stored as base64 strings to be read from the SAB by Babylon. ( Since Blobs are not allowed to be used with SAB it turns out )