-
-
Notifications
You must be signed in to change notification settings - Fork 35.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add ZSTDDecoder, add ZSTD support to KTX2Loader. #19932
Conversation
I tried |
@donmccurdy I might have used -Os. If you need malloc/free you should explicitly export them via -s EXPORTED_FUNCTIONS. You should also enable emmalloc (don’t remember the command line OTOH). |
Ok, thanks! I'd tried including malloc/free with exported functions but didn't prefix them with |
I've also published this to npm, as |
|
FWIW the only way to avoid extra copies with the existing Wasm capabilities is to fuse the zstd decoder and transcoder into a single .wasm module. You will still get 2 copies - one copying the source buffer into Wasm memory, and one copying the resulting texture out of Wasm memory - but if you have two separate Wasm modules, you will need a third copy. |
@donmccurdy, one other thing. You should be cautious of using the uncompressedByteLengths in a KTX file in case of a malicious file. That goes for the size returned by findDecompressedSize too in case someone crafts a file to expand enormously. |
@zeux, since the 3rd copy is the same regardless, I was ignoring it in my comment. The 2 copies I referred to are source buffer to zstd and zstd to transcoder. I believe it may be possible to construct the zstd decoder as a side module (-s SIDE_MODULE) which makes it essentially a dll that could be loaded by the transcoder and will use the same HEAP8. I have not yet had time to try this. Perhaps @donmccurdy can give it a try. If it is not, then the decoder and transcoder should be combined into a single module. |
@MarkCallow You can not load two different Wasm modules into a single Wasm instance with the browser API (this may be possible in other Wasm environments, but that's not material here). |
According to https://github.com/emscripten-core/emscripten/wiki/Linking, Emscripten has support for dynamic linking of Modules and Side Modules. It does not mention anything about using Browser APIs or limitations using this with browsers except that Chromium does not support compiling more that 4kb of wasm on the main thread for which the page offers workarounds. That said, there is probably little practical benefit to using a side module vs making the zstd decoder part of msc_basis_transcoder. |
This might be a question for Rich... would a container-agnostic transcoder in the basis_universal repository have zstd support? It would probably save 5-10kb to combine them, which is nice. I'm inclined to wait on this decision until we've figured out whether the
I think we probably should, but let's discuss this on Wednesday. My main question is whether we'd be publishing it from the KTX-Software repository or the basis_universal repository, or somewhere else. |
The browser should handle this gracefully enough: worst case, we crash the tab, but it's not possible to detect the browser tab's memory limit anyway. I'm less sure about Node.js. I understand WebAssembly has a memory limit of 4GB in v8, perhaps we should enforce a limit around 2GB, in case Node.js is less secure than the browser? Or perhaps we allow the user to pass a max acceptable uncompressed size? I'd rather not deal with WASM side modules at this point... The practical benefit seems small compared to other remaining work for |
re: Wasm side modules - ah, I stand corrected. I think this is possible by instantiating both modules to share the WebAssembly.Memory object, which would maintain the pointer identity across them. Presumably this is what Emscripten's JS wrappers do as well - I don't think it's worth the trouble in this case but it's good to know this is possible in theory. |
Thanks! |
Adds a standalone ZSTD decoder, built from source as explained in the header:
The ZSTD decoder is 28kb gzipped here — @zeux it sounded like your build was smaller (KhronosGroup/glTF#1751 (comment)). Do you think that's a compilation mistake on my part, or something to do with compiling alone, and not as part of a larger WASM library?/cc @MarkCallow