From 32fe54ac09149fc5a64f3140de67666659f0070e Mon Sep 17 00:00:00 2001 From: Nick Fisher Date: Wed, 11 Jun 2025 11:08:13 +0800 Subject: [PATCH] (web) on Emscripten builds, use static global wrapper function for texture upload complete callbacks (this is needed because all callbacks need to be proxied to the main thread --- .../src/c_api/ThermionDartRenderThreadApi.cpp | 25 ++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/thermion_dart/native/src/c_api/ThermionDartRenderThreadApi.cpp b/thermion_dart/native/src/c_api/ThermionDartRenderThreadApi.cpp index 7a9a9ffd..e577b4dc 100644 --- a/thermion_dart/native/src/c_api/ThermionDartRenderThreadApi.cpp +++ b/thermion_dart/native/src/c_api/ThermionDartRenderThreadApi.cpp @@ -861,12 +861,35 @@ extern "C" auto fut = _renderThread->add_task(lambda); } + #ifdef EMSCRIPTEN + static std::unordered_map> _emscriptenWrappers; + + static void Emscripten_voidCallback(int32_t requestId) { + auto it = _emscriptenWrappers.find(requestId); + if (it != _emscriptenWrappers.end()) { + it->second(requestId); + _emscriptenWrappers.erase(it); + } else { + Log("SEVERE: failed to find request id %d", requestId); + } + } + #endif + + EMSCRIPTEN_KEEPALIVE void Texture_decodeKtxRenderThread( TEngine *tEngine, uint8_t *ktxData, size_t length, float *sphericalHarmonics, uint32_t requestId, VoidCallback onTextureUploadComplete, void (*onComplete)(TTexture *)) { std::packaged_task lambda( [=]() mutable { - auto *texture = Texture_decodeKtx(tEngine, ktxData, length, sphericalHarmonics, requestId, onTextureUploadComplete); + #ifdef EMSCRIPTEN + std::function wrapper = [=](int32_t requestId) { + PROXY(onTextureUploadComplete(requestId)); + }; + _emscriptenWrappers[requestId] = wrapper; + auto *texture = Texture_decodeKtx(tEngine, ktxData, length, sphericalHarmonics, requestId, Emscripten_voidCallback); + #else + auto *texture = Texture_decodeKtx(tEngine, ktxData, length, sphericalHarmonics, requestId, onTextureUploadComplete); + #endif PROXY(onComplete(texture)); }); auto fut = _renderThread->add_task(lambda);