Skip to content

Commit 0ec9bfa

Browse files
committed
#3713 Crash at updateGLTFMaterials
1 parent 32c7d30 commit 0ec9bfa

File tree

3 files changed

+39
-36
lines changed

3 files changed

+39
-36
lines changed

indra/newview/llfetchedgltfmaterial.cpp

+1
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,7 @@ bool LLFetchedGLTFMaterial::replaceLocalTexture(const LLUUID& tracking_id, const
199199
{
200200
mTrackingIdToLocalTexture.erase(tracking_id);
201201
}
202+
updateLocalTexDataDigest();
202203

203204
return res;
204205
}

indra/newview/lllocalbitmaps.cpp

+37-35
Original file line numberDiff line numberDiff line change
@@ -293,8 +293,9 @@ void LLLocalBitmap::addGLTFMaterial(LLGLTFMaterial* mat)
293293
return;
294294
}
295295

296-
mat_list_t::iterator end = mGLTFMaterialWithLocalTextures.end();
297-
for (mat_list_t::iterator it = mGLTFMaterialWithLocalTextures.begin(); it != end;)
296+
mat->addLocalTextureTracking(getTrackingID(), getWorldID());
297+
298+
for (mat_list_t::iterator it = mGLTFMaterialWithLocalTextures.begin(); it != mGLTFMaterialWithLocalTextures.end();)
298299
{
299300
if (it->get() == mat)
300301
{
@@ -304,15 +305,12 @@ void LLLocalBitmap::addGLTFMaterial(LLGLTFMaterial* mat)
304305
if ((*it)->getNumRefs() == 1)
305306
{
306307
it = mGLTFMaterialWithLocalTextures.erase(it);
307-
end = mGLTFMaterialWithLocalTextures.end();
308308
}
309309
else
310310
{
311311
it++;
312312
}
313313
}
314-
315-
mat->addLocalTextureTracking(getTrackingID(), getWorldID());
316314
mGLTFMaterialWithLocalTextures.push_back(mat);
317315
}
318316

@@ -628,16 +626,16 @@ void LLLocalBitmap::updateUserLayers(LLUUID old_id, LLUUID new_id, LLWearableTyp
628626
void LLLocalBitmap::updateGLTFMaterials(LLUUID old_id, LLUUID new_id)
629627
{
630628
// Might be a better idea to hold this in LLGLTFMaterialList
631-
mat_list_t::iterator end = mGLTFMaterialWithLocalTextures.end();
632-
for (mat_list_t::iterator it = mGLTFMaterialWithLocalTextures.begin(); it != end;)
629+
for (mat_list_t::iterator it = mGLTFMaterialWithLocalTextures.begin(); it != mGLTFMaterialWithLocalTextures.end();)
633630
{
634631
if ((*it)->getNumRefs() == 1)
635632
{
636633
// render and override materials are often recreated,
637634
// clean up any remains
638635
it = mGLTFMaterialWithLocalTextures.erase(it);
639-
end = mGLTFMaterialWithLocalTextures.end();
640636
}
637+
// Render material consists of base and override materials, make sure replaceLocalTexture
638+
// gets called for base and override before applyOverride
641639
else if ((*it)->replaceLocalTexture(mTrackingID, old_id, new_id))
642640
{
643641
it++;
@@ -647,43 +645,47 @@ void LLLocalBitmap::updateGLTFMaterials(LLUUID old_id, LLUUID new_id)
647645
// Matching id not found, no longer in use
648646
// material would clean itself, remove from the list
649647
it = mGLTFMaterialWithLocalTextures.erase(it);
650-
end = mGLTFMaterialWithLocalTextures.end();
651648
}
652649
}
653650

654-
// Render material consists of base and override materials, make sure replaceLocalTexture
655-
// gets called for base and override before applyOverride
656-
end = mGLTFMaterialWithLocalTextures.end();
657-
for (mat_list_t::iterator it = mGLTFMaterialWithLocalTextures.begin(); it != end;)
651+
// Updating render materials calls updateTextureTracking which can modify
652+
// mGLTFMaterialWithLocalTextures, so precollect all entries that need to be updated
653+
std::set<LLTextureEntry*> update_entries;
654+
for (LLGLTFMaterial* mat : mGLTFMaterialWithLocalTextures)
658655
{
659-
LLFetchedGLTFMaterial* fetched_mat = dynamic_cast<LLFetchedGLTFMaterial*>((*it).get());
656+
// mGLTFMaterialWithLocalTextures includes overrides that are not 'fetched'
657+
// and don't have texture entries (they don't need to since render material does).
658+
LLFetchedGLTFMaterial* fetched_mat = dynamic_cast<LLFetchedGLTFMaterial*>(mat);
660659
if (fetched_mat)
661660
{
662661
for (LLTextureEntry* entry : fetched_mat->mTextureEntires)
663662
{
664-
// Normally a change in applied material id is supposed to
665-
// drop overrides thus reset material, but local materials
666-
// currently reuse their existing asset id, and purpose is
667-
// to preview how material will work in-world, overrides
668-
// included, so do an override to render update instead.
669-
LLGLTFMaterial* override_mat = entry->getGLTFMaterialOverride();
670-
if (override_mat)
671-
{
672-
// do not create a new material, reuse existing pointer
673-
LLFetchedGLTFMaterial* render_mat = dynamic_cast<LLFetchedGLTFMaterial*>(entry->getGLTFRenderMaterial());
674-
if (render_mat)
675-
{
676-
*render_mat = *fetched_mat;
677-
render_mat->applyOverride(*override_mat);
678-
}
679-
else
680-
{
681-
LL_WARNS_ONCE() << "Failed to apply local material override, render material not found" << LL_ENDL;
682-
}
683-
}
663+
update_entries.insert(entry);
664+
}
665+
}
666+
}
667+
668+
669+
for (LLTextureEntry* entry : update_entries)
670+
{
671+
// Normally a change in applied material id is supposed to
672+
// drop overrides thus reset material, but local materials
673+
// currently reuse their existing asset id, and purpose is
674+
// to preview how material will work in-world, overrides
675+
// included, so do an override to render update instead.
676+
LLGLTFMaterial* override_mat = entry->getGLTFMaterialOverride();
677+
LLGLTFMaterial* mat = entry->getGLTFMaterial();
678+
if (override_mat && mat)
679+
{
680+
// do not create a new material, reuse existing pointer
681+
// so that mTextureEntires remains untouched
682+
LLGLTFMaterial* render_mat = entry->getGLTFRenderMaterial();
683+
if (render_mat)
684+
{
685+
*render_mat = *mat;
686+
render_mat->applyOverride(*override_mat); // can update mGLTFMaterialWithLocalTextures
684687
}
685688
}
686-
++it;
687689
}
688690
}
689691

indra/newview/lllocalbitmaps.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ class LLLocalBitmap
106106

107107
// Store a list of accosiated materials
108108
// Might be a better idea to hold this in LLGLTFMaterialList
109-
typedef std::vector<LLPointer<LLGLTFMaterial> > mat_list_t;
109+
typedef std::list<LLPointer<LLGLTFMaterial> > mat_list_t;
110110
mat_list_t mGLTFMaterialWithLocalTextures;
111111

112112
};

0 commit comments

Comments
 (0)