diff --git a/indra/llmessage/lltemplatemessagebuilder.h b/indra/llmessage/lltemplatemessagebuilder.h index 855ea871448ccc2cda079ad5b9a6a23e3bfdaadb..1026594153c4e0766898ddff1897631e47f63681 100644 --- a/indra/llmessage/lltemplatemessagebuilder.h +++ b/indra/llmessage/lltemplatemessagebuilder.h @@ -41,7 +41,7 @@ class LLTemplateMessageBuilder final : public LLMessageBuilder { public: - typedef std::map<const char* , LLMessageTemplate*> message_template_name_map_t; + typedef boost::unordered_flat_map<const char* , LLMessageTemplate*> message_template_name_map_t; LLTemplateMessageBuilder(const message_template_name_map_t&); virtual ~LLTemplateMessageBuilder(); diff --git a/indra/llmessage/lltemplatemessagereader.h b/indra/llmessage/lltemplatemessagereader.h index 5b4c532bf5789dab2a1ccc927dee078451131575..c0fbc45620907de0eda70c37db0d005991eb70eb 100644 --- a/indra/llmessage/lltemplatemessagereader.h +++ b/indra/llmessage/lltemplatemessagereader.h @@ -36,7 +36,7 @@ class LLTemplateMessageReader : public LLMessageReader { public: - typedef std::map<U32, LLMessageTemplate*> message_template_number_map_t; + typedef boost::unordered_flat_map<U32, LLMessageTemplate*> message_template_number_map_t; LLTemplateMessageReader(message_template_number_map_t&); ~LLTemplateMessageReader() override; diff --git a/indra/llmessage/message.cpp b/indra/llmessage/message.cpp index 04e526bc18e32ea4fc345720141625a5677e357f..b6b51c2c37de86e5405e059cf5580ed7b9d0404a 100644 --- a/indra/llmessage/message.cpp +++ b/indra/llmessage/message.cpp @@ -323,7 +323,7 @@ void LLMessageSystem::loadTemplateFile(const std::string& filename, bool failure LLMessageSystem::~LLMessageSystem() { mMessageTemplates.clear(); // don't delete templates. - for_each(mMessageNumbers.begin(), mMessageNumbers.end(), DeletePairedPointer()); + std::for_each(mMessageNumbers.begin(), mMessageNumbers.end(), DeletePairedPointer()); mMessageNumbers.clear(); if (!mbError) @@ -1573,7 +1573,7 @@ void LLMessageSystem::disableCircuit(const LLHost &host) } U64 ip_port = 0; - std::map<U32, U64>::iterator iter = gMessageSystem->mCircuitCodeToIPPort.find(code); + auto iter = gMessageSystem->mCircuitCodeToIPPort.find(code); if (iter != gMessageSystem->mCircuitCodeToIPPort.end()) { ip_port = iter->second; diff --git a/indra/llmessage/message.h b/indra/llmessage/message.h index a4fda4e2527456ba149f20420c221a4755247ad9..d243db79409cb854ff2745cc9efcc23e9f405c3d 100644 --- a/indra/llmessage/message.h +++ b/indra/llmessage/message.h @@ -57,6 +57,7 @@ #include "llstoredmessage.h" +#include <boost/unordered/unordered_flat_map.hpp> #include <boost/signals2/connection.hpp> #include <boost/function.hpp> #include "llpounceable.h" @@ -303,8 +304,8 @@ class LLMessageSystem : public LLMessageSenderInterface F32 mMessageFileVersionNumber; - typedef std::map<const char *, LLMessageTemplate*> message_template_name_map_t; - typedef std::map<U32, LLMessageTemplate*> message_template_number_map_t; + typedef boost::unordered_flat_map<const char *, LLMessageTemplate*> message_template_name_map_t; + typedef boost::unordered_flat_map<U32, LLMessageTemplate*> message_template_number_map_t; message_template_name_map_t mMessageTemplates; message_template_number_map_t mMessageNumbers; @@ -354,8 +355,8 @@ class LLMessageSystem : public LLMessageSenderInterface F64Seconds mCircuitPrintTime; // used to print circuit debug info every couple minutes F32Seconds mCircuitPrintFreq; - std::map<U64, U32> mIPPortToCircuitCode; - std::map<U32, U64> mCircuitCodeToIPPort; + boost::unordered_flat_map<U64, U32> mIPPortToCircuitCode; + boost::unordered_flat_map<U32, U64> mCircuitCodeToIPPort; U32 mOurCircuitCode; S32 mSendPacketFailureCount; S32 mUnackedListDepth; @@ -841,7 +842,7 @@ class LLMessageSystem : public LLMessageSenderInterface // The mCircuitCodes is a map from circuit codes to session // ids. This allows us to verify sessions on connect. - typedef std::map<U32, LLUUID> code_session_map_t; + typedef boost::unordered_flat_map<U32, LLUUID> code_session_map_t; code_session_map_t mCircuitCodes; // Viewers need to track a process session in order to make sure diff --git a/indra/newview/lldrawable.h b/indra/newview/lldrawable.h index 1d364610179bd84feef1fd2170108bb86d174f4b..0c25756019bf7e3e32567983c2f0cdcf5c5069de 100644 --- a/indra/newview/lldrawable.h +++ b/indra/newview/lldrawable.h @@ -215,7 +215,7 @@ class LLDrawable friend class LLDrawPool; friend class LLSpatialBridge; - typedef std::unordered_set<LLPointer<LLDrawable> > drawable_set_t; + typedef boost::unordered_set<LLPointer<LLDrawable> > drawable_set_t; typedef std::set<LLPointer<LLDrawable> > ordered_drawable_set_t; typedef std::vector<LLPointer<LLDrawable> > drawable_vector_t; typedef std::list<LLPointer<LLDrawable> > drawable_list_t; diff --git a/indra/newview/lleasymessagesender.cpp b/indra/newview/lleasymessagesender.cpp index 681d3a8a1448e33ed63a6e6c41cb23d0ff53008d..c7ab8968f8bc4f233ff23a6df2eb4ecffe519fca 100644 --- a/indra/newview/lleasymessagesender.cpp +++ b/indra/newview/lleasymessagesender.cpp @@ -163,7 +163,7 @@ bool LLEasyMessageSender::sendLLUDPMessage(const LLHost& region_host, const std: //Make sure everything's kosher with the message we built //check if the message type is one that we know about - std::map<const char *, LLMessageTemplate*>::iterator template_iter= + auto template_iter= gMessageSystem->mMessageTemplates.find( LLMessageStringTable::getInstance()->getString(message.c_str()) ); if (template_iter == gMessageSystem->mMessageTemplates.end()) { diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp index 9b2f08c88f4b5a97a1ed28e2ef1587571e814681..fe61b91a7fa67eb1596f5888241cdd36e12a868b 100644 --- a/indra/newview/llmeshrepository.cpp +++ b/indra/newview/llmeshrepository.cpp @@ -3546,6 +3546,7 @@ void LLMeshRepository::unregisterMesh(LLVOVolume* vobj, const LLUUID& mesh_id) auto it = lod.find(mesh_id); if(it != lod.end()) { + vobj->decMeshCache(); it->second.erase(vobj); if (it->second.empty()) { @@ -3560,6 +3561,7 @@ void LLMeshRepository::unregisterSkin(LLVOVolume* vobj, const LLUUID& mesh_id) auto it = mLoadingSkins.find(mesh_id); if (it != mLoadingSkins.end()) { + vobj->decSkinCache(); it->second.erase(vobj); if(it->second.empty()) { @@ -3589,11 +3591,13 @@ S32 LLMeshRepository::loadMesh(LLVOVolume* vobj, const LLVolumeParams& mesh_para auto& obj_set = iter->second; auto it = obj_set.find(vobj); if (it == obj_set.end()) { + vobj->incMeshCache(); obj_set.insert(vobj); } } else { + vobj->incMeshCache(); LLMutexLock lock(mMeshMutex); //first request for this mesh mLoadingMeshes[detail][mesh_id].insert(vobj); @@ -3942,6 +3946,7 @@ void LLMeshRepository::notifySkinInfoReceived(LLMeshSkinInfo* info) { if (vobj) { + vobj->decSkinCache(); vobj->notifySkinInfoLoaded(info); } } @@ -3958,6 +3963,7 @@ void LLMeshRepository::notifySkinInfoUnavailable(const LLUUID& mesh_id) { if (vobj) { + vobj->decSkinCache(); vobj->notifySkinInfoUnavailable(); } } @@ -4040,6 +4046,7 @@ void LLMeshRepository::notifyMeshLoaded(const LLVolumeParams& mesh_params, LLVol { if (vobj) { + vobj->decMeshCache(); vobj->notifyMeshLoaded(); } } @@ -4070,6 +4077,8 @@ void LLMeshRepository::notifyMeshUnavailable(const LLVolumeParams& mesh_params, { if (vobj) { + vobj->decMeshCache(); + LLVolume* obj_volume = vobj->getVolume(); if (obj_volume && @@ -4111,11 +4120,14 @@ LLMeshSkinInfo* LLMeshRepository::getSkinInfo(const LLUUID& mesh_id, LLVOVolume* auto& obj_set = iter->second; auto it = obj_set.find(requesting_obj); if (it == obj_set.end()) { + requesting_obj->incSkinCache(); obj_set.insert(requesting_obj); } } else { + requesting_obj->incSkinCache(); + LLMutexLock lock(mMeshMutex); //first request for this mesh mLoadingSkins[mesh_id].insert(requesting_obj); diff --git a/indra/newview/llviewerobjectlist.cpp b/indra/newview/llviewerobjectlist.cpp index d9df459fdc937c49a27c0ca713d918f888de9b85..25a4f1f2afe7d4f87149023ec9ac549ec75acc30 100644 --- a/indra/newview/llviewerobjectlist.cpp +++ b/indra/newview/llviewerobjectlist.cpp @@ -1384,16 +1384,25 @@ void LLViewerObjectList::clearDebugText() void LLViewerObjectList::cleanupReferences(LLViewerObject *objectp) { LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK; - - bool new_dead_object = true; - if (mDeadObjects.find(objectp->mID) != mDeadObjects.end()) - { - LL_INFOS() << "Object " << objectp->mID << " already on dead list!" << LL_ENDL; - new_dead_object = false; - } - else - { - mDeadObjects.insert(objectp->mID); + // <FS:Beq> FIRE-30694 DeadObject Spam - handle new_dead_object properly and closer to source + // bool new_dead_object = true; + //if (mDeadObjects.find(objectp->mID) != mDeadObjects.end()) + //{ + //// <FS:Beq> FIRE-30694 DeadObject Spam + //// LL_INFOS() << "Object " << objectp->mID << " already on dead list!" << LL_ENDL; + //// new_dead_object = false; + // LL_DEBUGS() << "Object " << objectp->mID << " already on dead list!" << LL_ENDL; + //// </FS:Beq> + //} + //// <FS:Beq> detect but still delete dupes + //// else + { + // <FS:Beq> FIRE-30694 DeadObject Spam + // mDeadObjects.insert(objectp->mID); + mDeadObjects.insert( objectp->mID ); + mNumDeadObjects++; + llassert( mNumDeadObjects == mDeadObjects.size() ); + // </FS:Beq> } // Cleanup any references we have to this object @@ -1428,11 +1437,6 @@ void LLViewerObjectList::cleanupReferences(LLViewerObject *objectp) } // Don't clean up mObject references, these will be cleaned up more efficiently later! - - if(new_dead_object) - { - mNumDeadObjects++; - } } BOOL LLViewerObjectList::killObject(LLViewerObject *objectp) @@ -1527,7 +1531,11 @@ void LLViewerObjectList::cleanDeadObjects(BOOL use_timer) LL_PROFILE_ZONE_SCOPED; S32 num_removed = 0; + S32 num_divergent = 0; LLViewerObject *objectp; + + static const F64 max_time = 0.01; // Let's try 10ms per frame + LLTimer timer; vobj_list_t::reverse_iterator target = mObjects.rbegin(); @@ -1543,12 +1551,24 @@ void LLViewerObjectList::cleanDeadObjects(BOOL use_timer) if (objectp->isDead()) { + // mDeadObjects.erase(objectp->mID); // <FS:Ansariel> Use timer for cleaning up dead objects + auto delete_me = mDeadObjects.find(objectp->mID); + if( delete_me != mDeadObjects.end() ) + { + mDeadObjects.erase( delete_me ); + } + else + { + LL_WARNS() << "Attempt to delete object " << objectp->mID << " but object not in dead list" << LL_ENDL; + num_divergent++; // this is the number we are adrift in the count + } LLPointer<LLViewerObject>::swap(*iter, *target); *target = nullptr; ++target; num_removed++; - if (num_removed == mNumDeadObjects || iter->isNull()) + //if (num_removed == mNumDeadObjects || iter->isNull()) + if (num_removed == mNumDeadObjects || iter->isNull() || (use_timer && timer.getElapsedTimeF64() > max_time)) { // We've cleaned up all of the dead objects or caught up to the dead tail break; @@ -1560,15 +1580,25 @@ void LLViewerObjectList::cleanDeadObjects(BOOL use_timer) } } - llassert(num_removed == mNumDeadObjects); + // <FS:Ansariel> Use timer for cleaning up dead objects + //llassert(num_removed == mNumDeadObjects); //erase as a block - mObjects.erase(mObjects.begin()+(mObjects.size()-mNumDeadObjects), mObjects.end()); + //mObjects.erase(mObjects.begin()+(mObjects.size()-mNumDeadObjects), mObjects.end()); // We've cleaned the global object list, now let's do some paranoia testing on objects // before blowing away the dead list. - mDeadObjects.clear(); - mNumDeadObjects = 0; + //mDeadObjects.clear(); + //mNumDeadObjects = 0; + mObjects.erase(mObjects.begin()+(mObjects.size()-num_removed), mObjects.end()); + mNumDeadObjects -= num_removed; + + // TODO(Beq) If this still happens, we ought to realign at this point. Do a full sweep and reset. + if ( mNumDeadObjects != mDeadObjects.size() ) + { + LL_WARNS_ONCE() << "Num dead objects (" << mNumDeadObjects << ") != dead object list size (" << mDeadObjects.size() << "), deadlist discrepancy (" << num_divergent << ")" << LL_ENDL; + } + // </FS:Ansariel> } void LLViewerObjectList::removeFromActiveList(LLViewerObject* objectp) diff --git a/indra/newview/llviewerobjectlist.h b/indra/newview/llviewerobjectlist.h index bd814362b1ba6ef9d3bf9907ad61ac3b5d46d8b4..db4eaa456ad1b42a8d7ed1001f49c2ac581b05c0 100644 --- a/indra/newview/llviewerobjectlist.h +++ b/indra/newview/llviewerobjectlist.h @@ -209,7 +209,7 @@ class LLViewerObjectList vobj_list_t mMapObjects; - using uuid_hash_set_t = boost::unordered_set<LLUUID>; + using uuid_hash_set_t = boost::unordered_multiset<LLUUID>; uuid_hash_set_t mDeadObjects; boost::unordered_flat_map<LLUUID, LLPointer<LLViewerObject> > mUUIDObjectMap; diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index b699e6a3bf7793e55fb19311fa6ca75c780308aa..126ffa0b45a10b2bdeec9ca480f0c245a93e3857 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -10748,6 +10748,10 @@ void LLVOAvatar::updateRiggingInfo() static std::vector<LLVOVolume*> volumes; volumes.clear(); + if (volumes.capacity() < mLastAssocVolSize) + { + volumes.reserve(mLastAssocVolSize); + } getAssociatedVolumes(volumes); mLastAssocVolSize = volumes.size(); @@ -11273,9 +11277,6 @@ void LLVOAvatar::calculateUpdateRenderComplexity() F32 max_attachment_complexity = max_complexity_setting; max_attachment_complexity = llmax(max_attachment_complexity, DEFAULT_MAX_ATTACHMENT_COMPLEXITY); - // Diagnostic list of all textures on our avatar - static std::unordered_set<const LLViewerTexture*> all_textures; - std::map<LLUUID, U32> item_complexity; std::map<LLUUID, U32> temp_item_complexity; U32 body_parts_complexity; diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index c8b98a19dd81a0f7e14b5dbe68b2dc3bb74415eb..13505a5493bfb74a09f2626ae03bd9b78d0b77d3 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -258,8 +258,13 @@ LLVOVolume::~LLVOVolume() mSkinInfo = nullptr; + if (mFetchingMesh > 0) { gMeshRepo.unregisterMesh(this, getVolume()->getParams().getSculptID()); + } + + if(mFetchingSkinInfo > 0) + { gMeshRepo.unregisterSkin(this, getVolume()->getParams().getSculptID()); } diff --git a/indra/newview/llvovolume.h b/indra/newview/llvovolume.h index 2337c6abc0f6798e132a577abfaead7a69d97d3b..d17a7a95a589350d74d78beaf338a948f0d0f6eb 100644 --- a/indra/newview/llvovolume.h +++ b/indra/newview/llvovolume.h @@ -450,6 +450,11 @@ class LLVOVolume final : public LLViewerObject F32 mLODDistance; F32 mLODAdjustedDistance; F32 mLODRadius; + + void incMeshCache() { mFetchingMesh++; } + void incSkinCache() { mFetchingSkinInfo++; } + void decMeshCache() { mFetchingMesh--; } + void decSkinCache() { mFetchingSkinInfo--; } private: friend class LLDrawable; friend class LLFace; @@ -485,6 +490,8 @@ class LLVOVolume final : public LLViewerObject LLPointer<LLRiggedVolume> mRiggedVolume; + S32 mFetchingMesh = 0; + S32 mFetchingSkinInfo = 0; bool mSkinInfoUnavaliable; LLConstPointer<LLMeshSkinInfo> mSkinInfo; // statics diff --git a/indra/newview/skins/default/xui/en/floater_adjust_environment.xml b/indra/newview/skins/default/xui/en/floater_adjust_environment.xml index f1fd696ec6740988a6bc5964e2019615d0d10532..40c24b478d90ace3fe210d2177c453416146fc62 100644 --- a/indra/newview/skins/default/xui/en/floater_adjust_environment.xml +++ b/indra/newview/skins/default/xui/en/floater_adjust_environment.xml @@ -12,7 +12,7 @@ can_resize="false"> <string name="hdr_string">HDR Scale:</string> <string name="brightness_string">Brightness:</string> - <string name="hdr_tooltip">Intensity of lightning effects such as realistically bright skies and dynamic exposure. 1.0 is the default, 0 is off, values between 0 and 1 are mixing Ambient with HDR.</string> + <string name="hdr_tooltip">Intensity of lighting effects such as realistically bright skies and dynamic exposure. 1.0 is the default, 0 is off, values between 0 and 1 are mixing Ambient with HDR.</string> <layout_stack name="outer_stack" width="845" height="275" diff --git a/indra/newview/skins/default/xui/en/panel_settings_sky_atmos.xml b/indra/newview/skins/default/xui/en/panel_settings_sky_atmos.xml index 75d50b698a10c5715cbcfd17948caedd44f7d93c..41c48f8ca2991532b052a4bd59a578542383264e 100644 --- a/indra/newview/skins/default/xui/en/panel_settings_sky_atmos.xml +++ b/indra/newview/skins/default/xui/en/panel_settings_sky_atmos.xml @@ -9,7 +9,7 @@ top="0"> <string name="hdr_string">HDR Scale:</string> <string name="brightness_string">Brightness:</string> - <string name="hdr_tooltip">Intensity of lightning effects such as realistically bright skies and dynamic exposure. 1.0 is the default, 0 is off, values between 0 and 1 are mixing Ambient with HDR.</string> + <string name="hdr_tooltip">Intensity of lighting effects such as realistically bright skies and dynamic exposure. 1.0 is the default, 0 is off, values between 0 and 1 are mixing Ambient with HDR.</string> <layout_stack name="main_ls" follows="all"