From d6d453be81742ac2400ede86ae5351c58cc8999c Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev <117672381+akleshchev@users.noreply.github.com> Date: Fri, 14 Nov 2025 17:18:15 +0200 Subject: #4980 Crashes when uploading a glTF model Functions used in Image::prep aren't thread safe, pass them to main thread and wait for a result --- indra/newview/gltf/asset.cpp | 35 ++++++++++++++++++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) (limited to 'indra/newview/gltf/asset.cpp') diff --git a/indra/newview/gltf/asset.cpp b/indra/newview/gltf/asset.cpp index 28f30ae1c9..51fb019e93 100644 --- a/indra/newview/gltf/asset.cpp +++ b/indra/newview/gltf/asset.cpp @@ -33,10 +33,11 @@ #include "../llviewertexturelist.h" #include "../pipeline.h" #include "buffer_util.h" -#include #include "llimagejpeg.h" #include "../llskinningutil.h" +#include + using namespace LL::GLTF; using namespace boost::json; @@ -961,8 +962,40 @@ LLViewerFetchedTexture* fetch_texture(const LLUUID& id); bool Image::prep(Asset& asset, bool loadIntoVRAM) { mLoadIntoTexturePipe = loadIntoVRAM; + LLUUID id; if (mUri.size() == UUID_STR_SIZE && LLUUID::parseUUID(mUri, &id) && id.notNull()) + { // loaded from an asset, fetch the texture from the asset system + LL_DEBUGS("GLTF") << "Loading image from an id" << id<< LL_ENDL; + } + else if (mUri.find("data:") == 0) + { // embedded in a data URI, load the texture from the URI + LL_WARNS("GLTF") << "Data URIs not yet supported" << LL_ENDL; + return false; + } + + // Image::prepImpl containes code that must run on the main thread + std::promise prep_promise; + std::future prep_future = prep_promise.get_future(); + + LLAppViewer::instance()->postToMainCoro([this, &asset, id, &prep_promise]() mutable { + try { + bool result = prepImpl(asset, id); + prep_promise.set_value(result); + } + catch (...) { + // Propagate exception to the waiting thread + prep_promise.set_exception(std::current_exception()); + } + }); + + // Block until prep is done on the main thread + return prep_future.get(); +} + +bool Image::prepImpl(Asset& asset, const LLUUID& id) +{ + if (id.notNull()) { // loaded from an asset, fetch the texture from the asset system mTexture = fetch_texture(id); } -- cgit v1.3