From 8025997c894955ccad2cded21b5dff27494bcc4e Mon Sep 17 00:00:00 2001
From: "Nyx (Neal Orman)" <nyx@lindenlab.com>
Date: Mon, 24 May 2010 13:48:52 -0400
Subject: [PATCH] AVP-91 WIP Fix baked texture hashing

First pass at fixing baked texture hashing - unified the hash code to one
function, made sure all messages pass correct texture indices.

Initial code review by Vir
---
 indra/newview/llagent.cpp          | 66 +++++++++++++-----------------
 indra/newview/llagentwearables.cpp | 62 +++++++++++++++++-----------
 indra/newview/llagentwearables.h   |  2 +
 3 files changed, 68 insertions(+), 62 deletions(-)

diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp
index f96a59e97a0..9eea4eace46 100644
--- a/indra/newview/llagent.cpp
+++ b/indra/newview/llagent.cpp
@@ -3088,21 +3088,29 @@ void LLAgent::processAgentCachedTextureResponse(LLMessageSystem *mesgsys, void *
 		mesgsys->getUUIDFast(_PREHASH_WearableData, _PREHASH_TextureID, texture_id, texture_block);
 		mesgsys->getU8Fast(_PREHASH_WearableData, _PREHASH_TextureIndex, texture_index, texture_block);
 
-		if ((S32)texture_index < BAKED_NUM_INDICES 
-			&& gAgentQueryManager.mActiveCacheQueries[texture_index] == query_id)
-		{
-			if (texture_id.notNull())
-			{
-				//llinfos << "Received cached texture " << (U32)texture_index << ": " << texture_id << llendl;
-				gAgentAvatarp->setCachedBakedTexture(LLVOAvatarDictionary::bakedToLocalTextureIndex((EBakedTextureIndex)texture_index), texture_id);
-				//gAgentAvatarp->setTETexture( LLVOAvatar::sBakedTextureIndices[texture_index], texture_id );
-				gAgentQueryManager.mActiveCacheQueries[texture_index] = 0;
-				num_results++;
-			}
-			else
+
+		if ((S32)texture_index < TEX_NUM_INDICES )
+		{	
+			const LLVOAvatarDictionary::TextureEntry *texture_entry = LLVOAvatarDictionary::instance().getTexture((ETextureIndex)texture_index);
+			if (texture_entry)
 			{
-				// no cache of this bake. request upload.
-				gAgentAvatarp->requestLayerSetUpload((EBakedTextureIndex)texture_index);
+				EBakedTextureIndex baked_index = texture_entry->mBakedTextureIndex;
+				if (gAgentQueryManager.mActiveCacheQueries[baked_index] == query_id)
+				{
+					if (texture_id.notNull())
+					{
+						//llinfos << "Received cached texture " << (U32)texture_index << ": " << texture_id << llendl;
+						gAgentAvatarp->setCachedBakedTexture((ETextureIndex)texture_index, texture_id);
+						//gAgentAvatarp->setTETexture( LLVOAvatar::sBakedTextureIndices[texture_index], texture_id );
+						gAgentQueryManager.mActiveCacheQueries[baked_index] = 0;
+						num_results++;
+					}
+					else
+					{
+						// no cache of this bake. request upload.
+						gAgentAvatarp->requestLayerSetUpload(baked_index);
+					}
+				}
 			}
 		}
 	}
@@ -3526,7 +3534,6 @@ void LLAgent::sendAgentSetAppearance()
 		return;
 	}
 
-
 	llinfos << "TAT: Sent AgentSetAppearance: " << gAgentAvatarp->getBakedStatusForPrintout() << llendl;
 	//dumpAvatarTEs( "sendAgentSetAppearance()" );
 
@@ -3577,32 +3584,15 @@ void LLAgent::sendAgentSetAppearance()
 		llinfos << "TAT: Sending cached texture data" << llendl;
 		for (U8 baked_index = 0; baked_index < BAKED_NUM_INDICES; baked_index++)
 		{
-			const LLVOAvatarDictionary::BakedEntry *baked_dict = LLVOAvatarDictionary::getInstance()->getBakedTexture((EBakedTextureIndex)baked_index);
-			LLUUID hash;
-			for (U8 i=0; i < baked_dict->mWearables.size(); i++)
-			{
-				// LLWearableType::EType wearable_type = gBakedWearableMap[baked_index][wearable_num];
-				const LLWearableType::EType wearable_type = baked_dict->mWearables[i];
-                                for (U8 wearable_index =0; wearable_index < gAgentWearables.getWearableCount(wearable_type); ++wearable_index)
-                                {
-                                       const LLWearable* wearable = gAgentWearables.getWearable(wearable_type,wearable_index);
-                                       if (wearable)
-                                       {
-                                               // MULTI-WEARABLE: make order-dependent (use MD5 hash)
-						hash ^= wearable->getAssetID();
-                                       }
-                                }
-			}
+			LLUUID hash = gAgentWearables.computeBakedTextureHash((EBakedTextureIndex) baked_index);
+
 			if (hash.notNull())
 			{
-				hash ^= baked_dict->mWearablesHashID;
+				ETextureIndex texture_index = LLVOAvatarDictionary::bakedToLocalTextureIndex((EBakedTextureIndex) baked_index);
+				msg->nextBlockFast(_PREHASH_WearableData);
+				msg->addUUIDFast(_PREHASH_CacheID, hash);
+				msg->addU8Fast(_PREHASH_TextureIndex, (U8)texture_index);
 			}
-
-			const ETextureIndex texture_index = LLVOAvatarDictionary::bakedToLocalTextureIndex((EBakedTextureIndex)baked_index);
-
-			msg->nextBlockFast(_PREHASH_WearableData);
-			msg->addUUIDFast(_PREHASH_CacheID, hash);
-			msg->addU8Fast(_PREHASH_TextureIndex, (U8)texture_index);
 		}
 		msg->nextBlockFast(_PREHASH_ObjectData);
 		gAgentAvatarp->sendAppearanceMessage( gMessageSystem );
diff --git a/indra/newview/llagentwearables.cpp b/indra/newview/llagentwearables.cpp
index 545c5b845ba..6b5e43973ea 100644
--- a/indra/newview/llagentwearables.cpp
+++ b/indra/newview/llagentwearables.cpp
@@ -1565,37 +1565,18 @@ void LLAgentWearables::queryWearableCache()
 	S32 num_queries = 0;
 	for (U8 baked_index = 0; baked_index < BAKED_NUM_INDICES; baked_index++)
 	{
-		const LLVOAvatarDictionary::BakedEntry *baked_dict = LLVOAvatarDictionary::getInstance()->getBakedTexture((EBakedTextureIndex)baked_index);
-		LLMD5 hash;
-		bool hash_computed = false;
-		for (U8 i=0; i < baked_dict->mWearables.size(); i++)
+		LLUUID hash_id = computeBakedTextureHash((EBakedTextureIndex) baked_index);
+		if (hash_id.notNull())
 		{
-			const LLWearableType::EType baked_type = baked_dict->mWearables[i];
-			const U32 num_wearables = getWearableCount(baked_type);
-			for (U32 index = 0; index < num_wearables; ++index)
-			{
-				const LLWearable* wearable = getWearable(baked_type,index);
-				if (wearable)
-				{
-					LLUUID asset_id = wearable->getAssetID();
-					hash.update((const unsigned char*)asset_id.mData, UUID_BYTES);
-					hash_computed = true;
-				}
-			}
-		}
-		hash.finalize();
-		if (hash_computed)
-		{
-			LLUUID hash_id;
-			hash.raw_digest(hash_id.mData);
-			hash_id ^= baked_dict->mWearablesHashID;
 			num_queries++;
 			// *NOTE: make sure at least one request gets packed
 
+			ETextureIndex te_index = LLVOAvatarDictionary::bakedToLocalTextureIndex((EBakedTextureIndex)baked_index);
+
 			//llinfos << "Requesting texture for hash " << hash << " in baked texture slot " << baked_index << llendl;
 			gMessageSystem->nextBlockFast(_PREHASH_WearableData);
 			gMessageSystem->addUUIDFast(_PREHASH_ID, hash_id);
-			gMessageSystem->addU8Fast(_PREHASH_TextureIndex, (U8)baked_index);
+			gMessageSystem->addU8Fast(_PREHASH_TextureIndex, (U8)te_index);
 		}
 
 		gAgentQueryManager.mActiveCacheQueries[baked_index] = gAgentQueryManager.mWearablesCacheQueryID;
@@ -1607,6 +1588,39 @@ void LLAgentWearables::queryWearableCache()
 	gAgentQueryManager.mWearablesCacheQueryID++;
 }
 
+LLUUID LLAgentWearables::computeBakedTextureHash(LLVOAvatarDefines::EBakedTextureIndex index)
+{
+	LLUUID hash_id;
+	bool hash_computed = false;
+	LLMD5 hash;
+
+	const LLVOAvatarDictionary::BakedEntry *baked_dict = LLVOAvatarDictionary::getInstance()->getBakedTexture(index);
+
+	for (U8 i=0; i < baked_dict->mWearables.size(); i++)
+	{
+		const LLWearableType::EType baked_type = baked_dict->mWearables[i];
+		const U32 num_wearables = getWearableCount(baked_type);
+		for (U32 index = 0; index < num_wearables; ++index)
+		{
+			const LLWearable* wearable = getWearable(baked_type,index);
+			if (wearable)
+			{
+				LLUUID asset_id = wearable->getAssetID();
+				hash.update((const unsigned char*)asset_id.mData, UUID_BYTES);
+				hash_computed = true;
+			}
+		}
+	}
+	if (hash_computed)
+	{
+		hash.update((const unsigned char*)baked_dict->mWearablesHashID.mData, UUID_BYTES);
+		hash.finalize();
+		hash.raw_digest(hash_id.mData);
+	}
+
+	return hash_id;
+}
+
 // User has picked "remove from avatar" from a menu.
 // static
 void LLAgentWearables::userRemoveWearable(const LLWearableType::EType &type, const U32 &index)
diff --git a/indra/newview/llagentwearables.h b/indra/newview/llagentwearables.h
index 27453b5b251..734bd9fd47a 100644
--- a/indra/newview/llagentwearables.h
+++ b/indra/newview/llagentwearables.h
@@ -150,6 +150,8 @@ class LLAgentWearables
 public:
 	// Processes the initial wearables update message (if necessary, since the outfit folder makes it redundant)
 	static void		processAgentInitialWearablesUpdate(LLMessageSystem* mesgsys, void** user_data);
+	LLUUID			computeBakedTextureHash(LLVOAvatarDefines::EBakedTextureIndex index);
+
 protected:
 	void			sendAgentWearablesUpdate();
 	void			sendAgentWearablesRequest();
-- 
GitLab