From 5a0ba25d83862e7d220c1ae62173b537b7db5b52 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev <117672381+akleshchev@users.noreply.github.com> Date: Tue, 28 Oct 2025 19:29:54 +0200 Subject: #4882 Log textures that failed to be created A bunch of 36x36 failed to create, there shouldn't have been any 36x36 textures, log the ids/type. --- indra/newview/lldrawpoolbump.cpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'indra/newview/lldrawpoolbump.cpp') diff --git a/indra/newview/lldrawpoolbump.cpp b/indra/newview/lldrawpoolbump.cpp index bf593bff07..69003f88fd 100644 --- a/indra/newview/lldrawpoolbump.cpp +++ b/indra/newview/lldrawpoolbump.cpp @@ -802,7 +802,10 @@ void LLBumpImageList::onSourceStandardLoaded( bool success, LLViewerFetchedTextu } src_vi->setExplicitFormat(GL_RGBA, GL_RGBA); { - src_vi->createGLTexture(src_vi->getDiscardLevel(), nrm_image); + if (!src_vi->createGLTexture(src_vi->getDiscardLevel(), nrm_image)) + { + LL_WARNS() << "Failed to create bump image texture for image " << src_vi->getID() << LL_ENDL; + } } } } @@ -896,7 +899,10 @@ void LLBumpImageList::onSourceUpdated(LLViewerTexture* src, EBumpEffect bump_cod LLImageGL* src_img = src->getGLTexture(); LLImageGL* dst_img = bump->getGLTexture(); - dst_img->setSize(src->getWidth(), src->getHeight(), 4, 0); + if (!dst_img->setSize(src->getWidth(), src->getHeight(), 4, 0)) + { + LL_WARNS() << "Failed to setSize for image " << bump->getID() << LL_ENDL; + } dst_img->setUseMipMaps(true); dst_img->setDiscardLevel(0); dst_img->createGLTexture(); -- cgit v1.3 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 ++++++++++++++++++++++++++++++++++- indra/newview/gltf/asset.h | 2 ++ indra/newview/lldrawpoolbump.cpp | 4 ---- indra/newview/lldrawpoolbump.h | 2 -- 4 files changed, 36 insertions(+), 7 deletions(-) (limited to 'indra/newview/lldrawpoolbump.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); } 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 > 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; }; -- cgit v1.3