summaryrefslogtreecommitdiff
path: root/indra/newview/llmeshrepository.cpp
diff options
context:
space:
mode:
authorCosmic Linden <cosmic@lindenlab.com>2024-09-11 17:10:48 -0700
committerCosmic Linden <cosmic@lindenlab.com>2024-09-19 17:26:12 -0700
commitcae279b6e1019319f9186c2cea1127b9df149a7b (patch)
tree28b2d17f855e2c7ee92f7c5827137a16541e11f6 /indra/newview/llmeshrepository.cpp
parent9ce23ccc5ea75442fd44173befdadaf6cc9d2ec2 (diff)
secondlife/viewer#2462: Optimize unloading of prims
Diffstat (limited to 'indra/newview/llmeshrepository.cpp')
-rw-r--r--indra/newview/llmeshrepository.cpp81
1 files changed, 78 insertions, 3 deletions
diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp
index 26e2d8f319..2ca94390e5 100644
--- a/indra/newview/llmeshrepository.cpp
+++ b/indra/newview/llmeshrepository.cpp
@@ -3651,20 +3651,95 @@ S32 LLMeshRepository::update()
return static_cast<S32>(size);
}
-void LLMeshRepository::unregisterMesh(LLVOVolume* vobj)
+#ifdef SHOW_ASSERT
+// Brute-force remove the object from all loading queues. Returns true if
+// something was removed.
+// This function is used in a debug assert to ensure unregisterMesh and
+// unregisterSkinInfo are called as intended.
+// *TODO: Consider removing at some point if we feel confident about the code
+// working as intended.
+bool LLMeshRepository::forceUnregisterMesh(LLVOVolume* vobj)
{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME;
+
+ bool found = false;
+
for (auto& lod : mLoadingMeshes)
{
for (auto& param : lod)
{
- vector_replace_with_last(param.second, vobj);
+ llassert(std::find(param.second.begin(), param.second.end(), vobj) == param.second.end());
+ found = found || vector_replace_with_last(param.second, vobj);
}
}
for (auto& skin_pair : mLoadingSkins)
{
- vector_replace_with_last(skin_pair.second, vobj);
+ llassert(std::find(skin_pair.second.begin(), skin_pair.second.end(), vobj) == skin_pair.second.end());
+ found = found || vector_replace_with_last(skin_pair.second, vobj);
+ }
+
+ return found;
+}
+#endif
+
+void LLMeshRepository::unregisterMesh(LLVOVolume* vobj, const LLVolumeParams& mesh_params, S32 detail)
+{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME;
+
+ llassert((mesh_params.getSculptType() & LL_SCULPT_TYPE_MASK) == LL_SCULPT_TYPE_MESH);
+ llassert(mesh_params.getSculptID().notNull());
+ auto& lod = mLoadingMeshes[detail];
+ auto param_iter = lod.find(mesh_params.getSculptID());
+ if (param_iter != lod.end())
+ {
+ vector_replace_with_last(param_iter->second, vobj);
+ llassert(!vector_replace_with_last(param_iter->second, vobj));
+ if (param_iter->second.empty())
+ {
+ lod.erase(param_iter);
+ }
+ }
+}
+
+void LLMeshRepository::unregisterSkinInfo(const LLUUID& mesh_id, LLVOVolume* vobj)
+{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME;
+
+ llassert(mesh_id.notNull());
+ auto skin_pair_iter = mLoadingSkins.find(mesh_id);
+ if (skin_pair_iter != mLoadingSkins.end())
+ {
+ vector_replace_with_last(skin_pair_iter->second, vobj);
+ llassert(!vector_replace_with_last(skin_pair_iter->second, vobj));
+ if (skin_pair_iter->second.empty())
+ {
+ mLoadingSkins.erase(skin_pair_iter);
+ }
+ }
+}
+
+// Lots of dead objects make expensive calls to
+// LLMeshRepository::unregisterMesh which may delay shutdown. Avoid this by
+// preemptively unregistering all meshes.
+// We can also do this safely if all objects are confirmed dead for some other
+// reason.
+void LLMeshRepository::unregisterAllMeshes()
+{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME;
+
+ // The size of mLoadingMeshes and mLoadingSkins may be large and thus
+ // expensive to iterate over in LLVOVolume::~LLVOVolume.
+ // This is unnecessary during shutdown, so we ignore the referenced objects in the
+ // least expensive way which is still safe: by clearing these containers.
+ // Clear now and not in LLMeshRepository::shutdown because
+ // LLMeshRepository::notifyLoadedMeshes could (depending on invocation
+ // order) reference a pointer to an object after it has been deleted.
+ for (auto& lod : mLoadingMeshes)
+ {
+ lod.clear();
}
+ mLoadingSkins.clear();
}
S32 LLMeshRepository::loadMesh(LLVOVolume* vobj, const LLVolumeParams& mesh_params, S32 detail, S32 last_lod)