diff options
author | Andrey Kleshchev <andreykproductengine@lindenlab.com> | 2025-03-21 16:22:47 +0200 |
---|---|---|
committer | Andrey Kleshchev <117672381+akleshchev@users.noreply.github.com> | 2025-03-21 18:00:04 +0200 |
commit | 0ec9bfaabde12d82ba6b840589f849b7cf279417 (patch) | |
tree | e6e879e5d4732232da10eb751516656226c61e16 /indra | |
parent | 32c7d3064f04899547ee4dea48969c6ceb8554e9 (diff) |
#3713 Crash at updateGLTFMaterials
Diffstat (limited to 'indra')
-rw-r--r-- | indra/newview/llfetchedgltfmaterial.cpp | 1 | ||||
-rw-r--r-- | indra/newview/lllocalbitmaps.cpp | 72 | ||||
-rw-r--r-- | indra/newview/lllocalbitmaps.h | 2 |
3 files changed, 39 insertions, 36 deletions
diff --git a/indra/newview/llfetchedgltfmaterial.cpp b/indra/newview/llfetchedgltfmaterial.cpp index c2821d56d6..558fc92018 100644 --- a/indra/newview/llfetchedgltfmaterial.cpp +++ b/indra/newview/llfetchedgltfmaterial.cpp @@ -199,6 +199,7 @@ bool LLFetchedGLTFMaterial::replaceLocalTexture(const LLUUID& tracking_id, const { mTrackingIdToLocalTexture.erase(tracking_id); } + updateLocalTexDataDigest(); return res; } diff --git a/indra/newview/lllocalbitmaps.cpp b/indra/newview/lllocalbitmaps.cpp index 31c9eb8966..f08582e860 100644 --- a/indra/newview/lllocalbitmaps.cpp +++ b/indra/newview/lllocalbitmaps.cpp @@ -293,8 +293,9 @@ void LLLocalBitmap::addGLTFMaterial(LLGLTFMaterial* mat) return; } - mat_list_t::iterator end = mGLTFMaterialWithLocalTextures.end(); - for (mat_list_t::iterator it = mGLTFMaterialWithLocalTextures.begin(); it != end;) + mat->addLocalTextureTracking(getTrackingID(), getWorldID()); + + for (mat_list_t::iterator it = mGLTFMaterialWithLocalTextures.begin(); it != mGLTFMaterialWithLocalTextures.end();) { if (it->get() == mat) { @@ -304,15 +305,12 @@ void LLLocalBitmap::addGLTFMaterial(LLGLTFMaterial* mat) if ((*it)->getNumRefs() == 1) { it = mGLTFMaterialWithLocalTextures.erase(it); - end = mGLTFMaterialWithLocalTextures.end(); } else { it++; } } - - mat->addLocalTextureTracking(getTrackingID(), getWorldID()); mGLTFMaterialWithLocalTextures.push_back(mat); } @@ -628,16 +626,16 @@ void LLLocalBitmap::updateUserLayers(LLUUID old_id, LLUUID new_id, LLWearableTyp void LLLocalBitmap::updateGLTFMaterials(LLUUID old_id, LLUUID new_id) { // Might be a better idea to hold this in LLGLTFMaterialList - mat_list_t::iterator end = mGLTFMaterialWithLocalTextures.end(); - for (mat_list_t::iterator it = mGLTFMaterialWithLocalTextures.begin(); it != end;) + for (mat_list_t::iterator it = mGLTFMaterialWithLocalTextures.begin(); it != mGLTFMaterialWithLocalTextures.end();) { if ((*it)->getNumRefs() == 1) { // render and override materials are often recreated, // clean up any remains it = mGLTFMaterialWithLocalTextures.erase(it); - end = mGLTFMaterialWithLocalTextures.end(); } + // Render material consists of base and override materials, make sure replaceLocalTexture + // gets called for base and override before applyOverride else if ((*it)->replaceLocalTexture(mTrackingID, old_id, new_id)) { it++; @@ -647,43 +645,47 @@ void LLLocalBitmap::updateGLTFMaterials(LLUUID old_id, LLUUID new_id) // Matching id not found, no longer in use // material would clean itself, remove from the list it = mGLTFMaterialWithLocalTextures.erase(it); - end = mGLTFMaterialWithLocalTextures.end(); } } - // Render material consists of base and override materials, make sure replaceLocalTexture - // gets called for base and override before applyOverride - end = mGLTFMaterialWithLocalTextures.end(); - for (mat_list_t::iterator it = mGLTFMaterialWithLocalTextures.begin(); it != end;) + // Updating render materials calls updateTextureTracking which can modify + // mGLTFMaterialWithLocalTextures, so precollect all entries that need to be updated + std::set<LLTextureEntry*> update_entries; + for (LLGLTFMaterial* mat : mGLTFMaterialWithLocalTextures) { - LLFetchedGLTFMaterial* fetched_mat = dynamic_cast<LLFetchedGLTFMaterial*>((*it).get()); + // mGLTFMaterialWithLocalTextures includes overrides that are not 'fetched' + // and don't have texture entries (they don't need to since render material does). + LLFetchedGLTFMaterial* fetched_mat = dynamic_cast<LLFetchedGLTFMaterial*>(mat); if (fetched_mat) { for (LLTextureEntry* entry : fetched_mat->mTextureEntires) { - // Normally a change in applied material id is supposed to - // drop overrides thus reset material, but local materials - // currently reuse their existing asset id, and purpose is - // to preview how material will work in-world, overrides - // included, so do an override to render update instead. - LLGLTFMaterial* override_mat = entry->getGLTFMaterialOverride(); - if (override_mat) - { - // do not create a new material, reuse existing pointer - LLFetchedGLTFMaterial* render_mat = dynamic_cast<LLFetchedGLTFMaterial*>(entry->getGLTFRenderMaterial()); - if (render_mat) - { - *render_mat = *fetched_mat; - render_mat->applyOverride(*override_mat); - } - else - { - LL_WARNS_ONCE() << "Failed to apply local material override, render material not found" << LL_ENDL; - } - } + update_entries.insert(entry); + } + } + } + + + for (LLTextureEntry* entry : update_entries) + { + // Normally a change in applied material id is supposed to + // drop overrides thus reset material, but local materials + // currently reuse their existing asset id, and purpose is + // to preview how material will work in-world, overrides + // included, so do an override to render update instead. + LLGLTFMaterial* override_mat = entry->getGLTFMaterialOverride(); + LLGLTFMaterial* mat = entry->getGLTFMaterial(); + if (override_mat && mat) + { + // do not create a new material, reuse existing pointer + // so that mTextureEntires remains untouched + LLGLTFMaterial* render_mat = entry->getGLTFRenderMaterial(); + if (render_mat) + { + *render_mat = *mat; + render_mat->applyOverride(*override_mat); // can update mGLTFMaterialWithLocalTextures } } - ++it; } } diff --git a/indra/newview/lllocalbitmaps.h b/indra/newview/lllocalbitmaps.h index e169f96e70..de2dcb3467 100644 --- a/indra/newview/lllocalbitmaps.h +++ b/indra/newview/lllocalbitmaps.h @@ -106,7 +106,7 @@ class LLLocalBitmap // Store a list of accosiated materials // Might be a better idea to hold this in LLGLTFMaterialList - typedef std::vector<LLPointer<LLGLTFMaterial> > mat_list_t; + typedef std::list<LLPointer<LLGLTFMaterial> > mat_list_t; mat_list_t mGLTFMaterialWithLocalTextures; }; |