From 359af0e8e15cc5a866cf0de8b5977d6ee2e052a7 Mon Sep 17 00:00:00 2001
From: Rye Mutt <rye@alchemyviewer.org>
Date: Tue, 20 Jul 2021 12:08:12 -0400
Subject: [PATCH] Optimize rigging key update(from 0.11ms per frame to 0.013ms
 for single avatar)

---
 indra/newview/llvoavatar.cpp | 48 ++++++++++++++++++++----------------
 indra/newview/llvoavatar.h   |  4 ++-
 2 files changed, 30 insertions(+), 22 deletions(-)

diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp
index 46ef9a5ac89..1de302c283c 100644
--- a/indra/newview/llvoavatar.cpp
+++ b/indra/newview/llvoavatar.cpp
@@ -10360,29 +10360,35 @@ void LLVOAvatar::updateRiggingInfo()
 		getAssociatedVolumes(volumes);
 	}
 
-	std::map<LLUUID,S32> curr_rigging_info_key;
-	{
-		LL_RECORD_BLOCK_TIME(FTM_AVATAR_RIGGING_KEY_UPDATE);
-		// Get current rigging info key
-		for (LLVOVolume* vol : volumes)
-		{
-			if (vol->isRiggedMesh() && vol->getVolume() && vol->getVolume()->isMeshAssetLoaded())
-			{
-				const LLUUID& mesh_id = vol->getVolume()->getParams().getSculptID();
-				S32 max_lod = llmax(vol->getLOD(), vol->mLastRiggingInfoLOD);
-				curr_rigging_info_key[mesh_id] = max_lod;
-			}
-		}
-		
-		// Check for key change, which indicates some change in volume composition or LOD.
-		if (curr_rigging_info_key == mLastRiggingInfoKey)
-		{
-			return;
-		}
-	}
+    size_t rig_hash;
+    size_t rig_count;
+    {
+        LL_RECORD_BLOCK_TIME(FTM_AVATAR_RIGGING_KEY_UPDATE);
+        
+        // Get current rigging info key
+        rigging_info_hash_vec_t curr_rigging_info_key;
+        curr_rigging_info_key.reserve(mLastRiggingInfoMeshCount);
+        for (LLVOVolume *vol : volumes)
+        {
+            if (vol->isRiggedMesh() && vol->getVolume() && vol->getVolume()->isMeshAssetLoaded())
+            {
+                const LLUUID& mesh_id = vol->getVolume()->getParams().getSculptID();
+                S32 max_lod = llmax(vol->getLOD(), vol->mLastRiggingInfoLOD);
+                curr_rigging_info_key.emplace_back(mesh_id, max_lod);
+            }
+        }
+        rig_count =curr_rigging_info_key.size();
+        rig_hash = absl::Hash<rigging_info_hash_vec_t>{}(curr_rigging_info_key);
+        // Check for key change, which indicates some change in volume composition or LOD.
+        if (rig_hash == mLastRiggingInfoKeyHash)
+        {
+            return;
+        }
+    }
 
 	// Something changed. Update.
-	mLastRiggingInfoKey = std::move(curr_rigging_info_key);
+	mLastRiggingInfoKeyHash = rig_hash;
+    mLastRiggingInfoMeshCount = rig_count;
     mJointRiggingInfoTab.clear();
     for (LLVOVolume* vol : volumes)
     {
diff --git a/indra/newview/llvoavatar.h b/indra/newview/llvoavatar.h
index 110138a0046..3fd1975e9d2 100644
--- a/indra/newview/llvoavatar.h
+++ b/indra/newview/llvoavatar.h
@@ -225,7 +225,9 @@ class LLVOAvatar :
     // virtual
     void 					updateRiggingInfo();
 	// This encodes mesh id and LOD, so we can see whether display is up-to-date.
-	std::map<LLUUID,S32>	mLastRiggingInfoKey;
+    using rigging_info_hash_vec_t = std::vector<std::pair<LLUUID, S32>>;
+	size_t mLastRiggingInfoKeyHash = 0;
+    size_t mLastRiggingInfoMeshCount = 0;
 	
     std::set<LLUUID>		mActiveOverrideMeshes;
     virtual void			onActiveOverrideMeshesChanged();
-- 
GitLab