summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrey Kleshchev <117672381+akleshchev@users.noreply.github.com>2025-11-14 17:18:15 +0200
committerAndrey Kleshchev <117672381+akleshchev@users.noreply.github.com>2025-11-15 01:17:41 +0200
commitd6d453be81742ac2400ede86ae5351c58cc8999c (patch)
tree7f6d9661aebe15fcd96563027a8b4fc20ccb280c
parent4b78edbd1cd62b34f0b3f2b98ab4398437c6bc4d (diff)
#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
-rw-r--r--indra/newview/gltf/asset.cpp35
-rw-r--r--indra/newview/gltf/asset.h2
-rw-r--r--indra/newview/lldrawpoolbump.cpp4
-rw-r--r--indra/newview/lldrawpoolbump.h2
4 files changed, 36 insertions, 7 deletions
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 <boost/url.hpp>
#include "llimagejpeg.h"
#include "../llskinningutil.h"
+#include <future>
+
using namespace LL::GLTF;
using namespace boost::json;
@@ -961,9 +962,41 @@ 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<bool> prep_promise;
+ std::future<bool> 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);
}
else if (mUri.find("data:") == 0)
diff --git a/indra/newview/gltf/asset.h b/indra/newview/gltf/asset.h
index b9554d753c..2802664ed3 100644
--- a/indra/newview/gltf/asset.h
+++ b/indra/newview/gltf/asset.h
@@ -320,6 +320,8 @@ namespace LL
void clearData(Asset& asset);
bool prep(Asset& asset, bool loadIntoVRAM);
+ private:
+ bool prepImpl(Asset& asset, const LLUUID& id);
};
// Render Batch -- vertex buffer and list of primitives to render using
diff --git a/indra/newview/lldrawpoolbump.cpp b/indra/newview/lldrawpoolbump.cpp
index bf593bff07..0578072bb2 100644
--- a/indra/newview/lldrawpoolbump.cpp
+++ b/indra/newview/lldrawpoolbump.cpp
@@ -55,8 +55,6 @@
// static
LLStandardBumpmap gStandardBumpmapList[TEM_BUMPMAP_COUNT];
-LL::WorkQueue::weak_t LLBumpImageList::sMainQueue;
-LL::WorkQueue::weak_t LLBumpImageList::sTexUpdateQueue;
LLRenderTarget LLBumpImageList::sRenderTarget;
// static
@@ -629,8 +627,6 @@ void LLBumpImageList::init()
llassert( mDarknessEntries.size() == 0 );
LLStandardBumpmap::restoreGL();
- sMainQueue = LL::WorkQueue::getInstance("mainloop");
- sTexUpdateQueue = LL::WorkQueue::getInstance("LLImageGL"); // Share work queue with tex loader.
}
void LLBumpImageList::clear()
diff --git a/indra/newview/lldrawpoolbump.h b/indra/newview/lldrawpoolbump.h
index 15976884ca..e1a468cd18 100644
--- a/indra/newview/lldrawpoolbump.h
+++ b/indra/newview/lldrawpoolbump.h
@@ -152,8 +152,6 @@ private:
typedef std::unordered_map<LLUUID, LLPointer<LLViewerTexture> > bump_image_map_t;
bump_image_map_t mBrightnessEntries;
bump_image_map_t mDarknessEntries;
- static LL::WorkQueue::weak_t sMainQueue;
- static LL::WorkQueue::weak_t sTexUpdateQueue;
static LLRenderTarget sRenderTarget;
};