From d06b3f0679401873cc5492f5f160431d14566f2c Mon Sep 17 00:00:00 2001
From: Rye Mutt <rye@alchemyviewer.org>
Date: Fri, 4 Mar 2022 23:49:39 -0500
Subject: [PATCH] Some hacks for BOM on opensim from beq

---
 indra/newview/app_settings/settings.xml       | 13 ++++++
 indra/newview/llagentwearables.cpp            |  9 ++++
 indra/newview/llviewerwearable.cpp            |  4 +-
 indra/newview/llvoavatar.cpp                  | 33 +++++++++++----
 indra/newview/llvoavatar.h                    |  1 +
 indra/newview/llvoavatarself.cpp              | 41 +++++++++++++++++--
 indra/newview/llvoavatarself.h                |  2 +
 .../skins/default/xui/en/notifications.xml    |  7 ++++
 8 files changed, 98 insertions(+), 12 deletions(-)

diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index 227b1c54619..2e13e91e16d 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -2609,6 +2609,19 @@
       <key>Value</key>
       <integer>1</integer>
     </map>
+	<key>CurrentlyUsingBakesOnMesh</key>
+	<map>
+		<key>Comment</key>
+		<string>Are we currently on a grid that uses bakes on mesh? Persisted to force rebakes on login to named grids.</string>
+		<key>Persist</key>
+		<integer>1</integer>
+		<key>Type</key>
+		<string>Boolean</string>
+		<key>Value</key>
+		<integer>1</integer>
+		<key>Backup</key>
+		<integer>0</integer>
+	</map>
     <key>CurrentGrid</key>
     <map>
       <key>Comment</key>
diff --git a/indra/newview/llagentwearables.cpp b/indra/newview/llagentwearables.cpp
index 9c49dd0aed4..13ab1f878c2 100644
--- a/indra/newview/llagentwearables.cpp
+++ b/indra/newview/llagentwearables.cpp
@@ -1035,6 +1035,15 @@ void LLAgentWearables::setWearableOutfit(const LLInventoryItem::item_array_t& it
 		LLPointer<LLInventoryItem> new_item = items[i];
 
 		const LLWearableType::EType type = new_wearable->getType();
+		if(!gAgent.getRegion()->bakesOnMeshEnabled())
+		{
+			if(type == LLWearableType::WT_UNIVERSAL)
+			{
+				LL_DEBUGS("Avatar") << "Universal wearable not supported on this region - ignoring." << LL_ENDL;
+				mismatched++;
+				continue;
+			}
+		}
 		if (type < 0 || type>=LLWearableType::WT_COUNT)
 		{
 			LL_WARNS() << "invalid type " << type << LL_ENDL;
diff --git a/indra/newview/llviewerwearable.cpp b/indra/newview/llviewerwearable.cpp
index c967c3be02b..abb3a4fa494 100644
--- a/indra/newview/llviewerwearable.cpp
+++ b/indra/newview/llviewerwearable.cpp
@@ -49,7 +49,7 @@ class LLOverrideBakedTextureUpdate
 public:
 	LLOverrideBakedTextureUpdate(bool temp_state)
 	{
-		U32 num_bakes = (U32) LLAvatarAppearanceDefines::BAKED_NUM_INDICES;
+		U32 num_bakes = (U32) gAgentAvatarp->getNumBakes();
 		for( U32 index = 0; index < num_bakes; ++index )
 		{
 			composite_enabled[index] = gAgentAvatarp->isCompositeUpdateEnabled(index);
@@ -59,7 +59,7 @@ class LLOverrideBakedTextureUpdate
 
 	~LLOverrideBakedTextureUpdate()
 	{
-		U32 num_bakes = (U32)LLAvatarAppearanceDefines::BAKED_NUM_INDICES;		
+		U32 num_bakes = (U32) gAgentAvatarp->getNumBakes();		
 		for( U32 index = 0; index < num_bakes; ++index )
 		{
 			gAgentAvatarp->setCompositeUpdatesEnabled(index, composite_enabled[index]);
diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp
index b08f7eba9b4..3423ad63649 100644
--- a/indra/newview/llvoavatar.cpp
+++ b/indra/newview/llvoavatar.cpp
@@ -86,6 +86,7 @@
 #include "llviewertexlayer.h"
 #include "llviewertexturelist.h"
 #include "llviewermenu.h"
+#include "llviewernetwork.h"
 #include "llviewerobjectlist.h"
 #include "llviewerparcelmgr.h"
 #include "llviewerregion.h"
@@ -763,6 +764,25 @@ LLVOAvatar::LLVOAvatar(const LLUUID& id,
 	mVisuallyMuteSetting = LLVOAvatar::VisualMuteSettings(LLRenderMuteList::getInstanceFast()->getSavedVisualMuteSetting(getID()));
 }
 
+S32 LLVOAvatar::getNumBakes() const 
+{
+	// BAKED_LEFT_ARM is equal to the pre-BOM BAKED_NUM_INDICES
+	if(getRegion())
+	{
+		// LL_INFOS("BOMOS") 
+		// 				<< getFullname()
+		// 				<< "Using avatar region settings [" << getRegion()->getName() << "]"
+		// 				<< " bakesOnMesh = " << static_cast<const char *>(getRegion()->bakesOnMeshEnabled()?"True":"False")
+		// 				<< LL_ENDL;
+		return getRegion()->getRegionMaxBakes();
+	}
+	// LL_INFOS("BOMOS") 
+	// 				<< " Using fallback settings"
+	// 				<< " bakesOnMesh = " << static_cast<const char *>(LLGridManager::instance().isInSecondLife()?"True":"False")
+	// 				<< LL_ENDL;
+	// fallback, in SL assume BOM, elsewhere assume not.
+	return LLGridManager::instanceFast().isInSecondlife() ? BAKED_NUM_INDICES : BAKED_LEFT_ARM;
+}
 std::string LLVOAvatar::avString() const
 {
     if (isControlAvatar())
@@ -848,7 +868,7 @@ BOOL LLVOAvatar::isFullyBaked()
 	if (mIsDummy) return TRUE;
 	if (getNumTEs() == 0) return FALSE;
 
-	for (U32 i = 0; i < mBakedTextureDatas.size(); i++)
+	for (U32 i = 0; i < getNumBakes(); i++)
 	{
 		if (!isTextureDefined(mBakedTextureDatas[i].mTextureIndex)
 			&& ((i != BAKED_SKIRT) || isWearingWearableType(LLWearableType::WT_SKIRT))
@@ -8628,7 +8648,7 @@ void LLVOAvatar::updateMeshTextures()
 
 	mBakedTextureDebugText += llformat("%06d\n",update_counter++);
 	mBakedTextureDebugText += "indx layerset linvld ltda ilb ulkg ltid\n";
-	for (U32 i=0; i < mBakedTextureDatas.size(); i++)
+	for (U32 i=0; i < getNumBakes(); i++)
 	{
 		is_layer_baked[i] = isTextureDefined(mBakedTextureDatas[i].mTextureIndex);
 		LLViewerTexLayerSet* layerset = NULL;
@@ -8676,8 +8696,7 @@ void LLVOAvatar::updateMeshTextures()
 										   use_lkg_baked_layer[i],
 										   last_id_string.c_str());
 	}
-
-	for (U32 i=0; i < mBakedTextureDatas.size(); i++)
+	for (U32 i=0; i < getNumBakes(); i++)
 	{
 		debugColorizeSubMeshes(i, LLColor4::white);
 
@@ -8943,7 +8962,7 @@ void LLVOAvatar::releaseComponentTextures()
 		}
 	}
 
-	for (U8 baked_index = 0; baked_index < BAKED_NUM_INDICES; baked_index++)
+	for (U8 baked_index = 0; baked_index < getNumBakes(); baked_index++)
 	{
 		const LLAvatarAppearanceDictionary::BakedEntry * bakedDicEntry = LLAvatarAppearance::getDictionary()->getBakedTexture((EBakedTextureIndex)baked_index);
 		// skip if this is a skirt and av is not wearing one, or if we don't have a baked texture UUID
@@ -9626,7 +9645,7 @@ void LLVOAvatar::applyParsedAppearanceMessage(LLAppearanceMessageContents& conte
 
 LLViewerTexture* LLVOAvatar::getBakedTexture(const U8 te)
 {
-	if (te < 0 || te >= BAKED_NUM_INDICES)
+	if (te < 0 || te >= getNumBakes())
 	{
 		return NULL;
 	}
@@ -10923,7 +10942,7 @@ void LLVOAvatar::calculateUpdateRenderComplexity()
 		LLVOVolume::texture_cost_t textures;
 		hud_complexity_list_t hud_complexity_list;
 
-		for (U8 baked_index = 0; baked_index < BAKED_NUM_INDICES; baked_index++)
+		for (U8 baked_index = 0; baked_index < getNumBakes(); baked_index++)
 		{
 		    const LLAvatarAppearanceDictionary::BakedEntry *baked_dict
 				= LLAvatarAppearance::getDictionary()->getBakedTexture((EBakedTextureIndex)baked_index);
diff --git a/indra/newview/llvoavatar.h b/indra/newview/llvoavatar.h
index dbf199ce92e..50e2faa60ad 100644
--- a/indra/newview/llvoavatar.h
+++ b/indra/newview/llvoavatar.h
@@ -364,6 +364,7 @@ class LLVOAvatar :
 	BOOL			hasGray() const; 
 	S32				getRezzedStatus() const; // 0 = cloud, 1 = gray, 2 = textured, 3 = textured and fully downloaded.
 	void			updateRezzedStatusTimers(S32 status);
+	S32 			getNumBakes() const;//<FS:Beq/> BOM bake limits
 
 	S32				mLastRezzedStatus;
 
diff --git a/indra/newview/llvoavatarself.cpp b/indra/newview/llvoavatarself.cpp
index dcbe9b2e414..e52f4a40db3 100644
--- a/indra/newview/llvoavatarself.cpp
+++ b/indra/newview/llvoavatarself.cpp
@@ -48,6 +48,7 @@
 #include "llviewercamera.h"
 #include "llviewercontrol.h"
 #include "llviewermenu.h"
+#include "llviewernetwork.h"
 #include "llviewerobjectlist.h"
 #include "llviewerstats.h"
 #include "llviewerregion.h"
@@ -908,11 +909,32 @@ void LLVOAvatarSelf::removeMissingBakedTextures()
 		updateMeshTextures();
 	}
 }
+// <FS:Beq> Check whether the BOM capability is different to last time we changed region (even across login)
+void LLVOAvatarSelf::checkBOMRebakeRequired()
+{
+	if(getRegion())
+	{
+		auto newBOMStatus = getRegion()->bakesOnMeshEnabled();
+		if((!gSavedSettings.getBool("CurrentlyUsingBakesOnMesh")) != newBOMStatus)
+		{
+			// force a rebake when the last grid we were on (including previous login) had different BOM support
+			// This replicates forceAppearanceUpdate rather than pulling in the whole of llavatarself.
+			if(!LLGridManager::instance().isInSecondlife())
+			{
+				doAfterInterval(boost::bind(&LLVOAvatarSelf::forceBakeAllTextures,	gAgentAvatarp.get(), true), 5.0);
+			}
+			// update the setting even if we are in SL so that switch SL to OS and back 
+			gSavedSettings.setBOOL("CurrentlyUsingBakesOnMesh", newBOMStatus);
+		}
+	}
+}
+// </FS:Beq>
 
 void LLVOAvatarSelf::onSimulatorFeaturesReceived(const LLUUID& region_id)
 {
 	LL_INFOS("Avatar") << "simulator features received, setting hover based on region props" << LL_ENDL;
 	setHoverIfRegionEnabled();
+	checkBOMRebakeRequired();// <FS:Beq/> BOM we may have stale cache, rebake may be needed
 }
 
 //virtual
@@ -939,6 +961,7 @@ void LLVOAvatarSelf::updateRegion(LLViewerRegion *regionp)
 		if (regionp->simulatorFeaturesReceived())
 		{
 			setHoverIfRegionEnabled();
+			checkBOMRebakeRequired();// <FS:Beq/> BOM we may have stale cache, rebake may be needed
 		}
 		else
 		{
@@ -2708,7 +2731,7 @@ LLViewerTexLayerSet* LLVOAvatarSelf::getLayerSet(EBakedTextureIndex baked_index)
                case TEX_HEAD_BAKED:
                case TEX_HEAD_BODYPAINT:
                        return mHeadLayerSet; */
-       if (baked_index >= 0 && baked_index < BAKED_NUM_INDICES)
+       if (baked_index >= 0 && baked_index < getNumBakes())
        {
 		   return  getTexLayerSet(baked_index);
        }
@@ -2783,7 +2806,17 @@ bool LLVOAvatarSelf::sendAppearanceMessage(LLMessageSystem *mesgsys) const
 	{
 		const ETextureIndex index = tex_pair.first;
 		const LLAvatarAppearanceDictionary::TextureEntry *texture_dict = tex_pair.second;
-		if (!texture_dict->mIsBakedTexture)
+		// <FS:Beq> hide the surplus bakes and universals from non-BOM
+		if( (index == TEX_SKIRT || index == TEX_SKIRT_TATTOO) && !gAgentAvatarp->isWearingWearableType(LLWearableType::WT_SKIRT) )
+		{
+			// TODO(BEQ): combine this with clause below once proven it works.
+			LL_DEBUGS("Avatar") << "Ignoring skirt related texture at index=" << index << LL_ENDL;
+			LLTextureEntry* entry = getTE((U8) index);
+			texture_id[index] = entry->getID();
+			entry->setID(IMG_DEFAULT_AVATAR);
+		}
+		if (!texture_dict->mIsBakedTexture || index >= getRegion()->getRegionMaxTEs())
+		// </FS:Beq>
 		{
 			LLTextureEntry* entry = getTE((U8) index);
 			texture_id[index] = entry->getID();
@@ -2798,7 +2831,9 @@ bool LLVOAvatarSelf::sendAppearanceMessage(LLMessageSystem *mesgsys) const
 	{
 		const ETextureIndex index = tex_pair.first;
 		const LLAvatarAppearanceDictionary::TextureEntry *texture_dict = tex_pair.second;
-		if (!texture_dict->mIsBakedTexture)
+		// <FS:Beq> hide the surplus bakes and universals from non-BOM
+		if (!texture_dict->mIsBakedTexture || index >= getRegion()->getRegionMaxTEs())
+		// </FS:Beq>
 		{
 			LLTextureEntry* entry = getTE((U8) index);
 			entry->setID(texture_id[index]);
diff --git a/indra/newview/llvoavatarself.h b/indra/newview/llvoavatarself.h
index 4436e511fb4..2c7e95a2ce5 100644
--- a/indra/newview/llvoavatarself.h
+++ b/indra/newview/llvoavatarself.h
@@ -399,6 +399,8 @@ class LLVOAvatarSelf final :
 	F32 					mDebugBakedTextureTimes[LLAvatarAppearanceDefines::BAKED_NUM_INDICES][2]; // time to start upload and finish upload of each baked texture
 	void					debugTimingLocalTexLoaded(BOOL success, LLViewerFetchedTexture *src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata);
 
+	void 					checkBOMRebakeRequired();
+
 // [SL:KB] - Patch: Appearance-TeleportAttachKill | Checked: Catznip-4.0
 //public:
 //	void addPendingDetach(const LLUUID& idObject);
diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml
index 14025a2f561..5d891ea24c3 100644
--- a/indra/newview/skins/default/xui/en/notifications.xml
+++ b/indra/newview/skins/default/xui/en/notifications.xml
@@ -9038,6 +9038,13 @@ You sent out an update of your appearance after [TIME] seconds.
 Avatar '[NAME]' became cloud.
   </notification>
 
+  <notification
+   icon="notifytip.tga"
+   name="AvatarRezSelfBakeForceUpdateNotification"
+   type="notifytip">
+The viewer has detected that you may appear as a cloud and is attempting to fix this automatically.
+  </notification>
+
   <notification
    icon="notifytip.tga"
    name="AvatarRezArrivedNotification"
-- 
GitLab