diff options
-rw-r--r-- | indra/newview/llfloaterimcontainer.cpp | 50 | ||||
-rw-r--r-- | indra/newview/llfloaterimcontainer.h | 4 | ||||
-rw-r--r-- | indra/newview/llfloaterimsessiontab.cpp | 7 | ||||
-rw-r--r-- | indra/newview/llfloaterimsessiontab.h | 2 | ||||
-rw-r--r-- | indra/newview/llgroupmgr.cpp | 14 | ||||
-rw-r--r-- | indra/newview/llviewermessage.cpp | 4 | ||||
-rw-r--r-- | indra/newview/llviewerregion.cpp | 26 | ||||
-rw-r--r-- | indra/newview/llviewerregion.h | 6 | ||||
-rw-r--r-- | indra/newview/llworld.cpp | 20 |
9 files changed, 106 insertions, 27 deletions
diff --git a/indra/newview/llfloaterimcontainer.cpp b/indra/newview/llfloaterimcontainer.cpp index 21420b122b..feb8cf4277 100644 --- a/indra/newview/llfloaterimcontainer.cpp +++ b/indra/newview/llfloaterimcontainer.cpp @@ -57,6 +57,9 @@ #include "llviewerobjectlist.h" #include "boost/foreach.hpp" + +const S32 EVENTS_PER_IDLE_LOOP = 100; + // // LLFloaterIMContainer // @@ -66,7 +69,8 @@ LLFloaterIMContainer::LLFloaterIMContainer(const LLSD& seed, const Params& param mConversationsRoot(NULL), mConversationsEventStream("ConversationsEvents"), mInitialized(false), - mIsFirstLaunch(true) + mIsFirstLaunch(true), + mConversationEventQueue() { mEnableCallbackRegistrar.add("IMFloaterContainer.Check", boost::bind(&LLFloaterIMContainer::isActionChecked, this, _2)); mCommitCallbackRegistrar.add("IMFloaterContainer.Action", boost::bind(&LLFloaterIMContainer::onCustomAction, this, _2)); @@ -424,7 +428,9 @@ void LLFloaterIMContainer::idle(void* user_data) { LLFloaterIMContainer* self = static_cast<LLFloaterIMContainer*>(user_data); - if (!self->getVisible() || self->isMinimized()) + self->idleProcessEvents(); + + if (!self->getVisible() || self->isMinimized()) { return; } @@ -485,13 +491,28 @@ void LLFloaterIMContainer::idleUpdate() } } +void LLFloaterIMContainer::idleProcessEvents() +{ + if (!mConversationEventQueue.empty()) + { + S32 events_to_handle = llmin((S32)mConversationEventQueue.size(), EVENTS_PER_IDLE_LOOP); + for (S32 i = 0; i < events_to_handle; i++) + { + handleConversationModelEvent(mConversationEventQueue.back()); + mConversationEventQueue.pop_back(); + } + } +} + bool LLFloaterIMContainer::onConversationModelEvent(const LLSD& event) { - // For debug only - //std::ostringstream llsd_value; - //llsd_value << LLSDOStreamer<LLSDNotationFormatter>(event) << std::endl; - //LL_INFOS() << "LLFloaterIMContainer::onConversationModelEvent, event = " << llsd_value.str() << LL_ENDL; - // end debug + mConversationEventQueue.push_front(event); + return true; +} + + +void LLFloaterIMContainer::handleConversationModelEvent(const LLSD& event) +{ // Note: In conversations, the model is not responsible for creating the view, which is a good thing. This means that // the model could change substantially and the view could echo only a portion of this model (though currently the @@ -508,7 +529,7 @@ bool LLFloaterIMContainer::onConversationModelEvent(const LLSD& event) if (!session_view) { // We skip events that are not associated with a session - return false; + return; } LLConversationViewParticipant* participant_view = session_view->findParticipant(participant_id); LLFloaterIMSessionTab *conversation_floater = (session_id.isNull() ? @@ -535,9 +556,9 @@ bool LLFloaterIMContainer::onConversationModelEvent(const LLSD& event) { LLConversationItemSession* session_model = dynamic_cast<LLConversationItemSession*>(mConversationsItems[session_id]); LLConversationItemParticipant* participant_model = (session_model ? session_model->findParticipant(participant_id) : NULL); + LLIMModel::LLIMSession * im_sessionp = LLIMModel::getInstance()->findIMSession(session_id); if (!participant_view && session_model && participant_model) - { - LLIMModel::LLIMSession * im_sessionp = LLIMModel::getInstance()->findIMSession(session_id); + { if (session_id.isNull() || (im_sessionp && !im_sessionp->isP2PSessionType())) { participant_view = createConversationViewParticipant(participant_model); @@ -548,7 +569,8 @@ bool LLFloaterIMContainer::onConversationModelEvent(const LLSD& event) // Add a participant view to the conversation floater if (conversation_floater && participant_model) { - conversation_floater->addConversationViewParticipant(participant_model); + bool skip_updating = im_sessionp && im_sessionp->isGroupChat(); + conversation_floater->addConversationViewParticipant(participant_model, !skip_updating); } } else if (type == "update_participant") @@ -571,12 +593,6 @@ bool LLFloaterIMContainer::onConversationModelEvent(const LLSD& event) mConversationViewModel.requestSortAll(); mConversationsRoot->arrangeAll(); - if (conversation_floater) - { - conversation_floater->refreshConversation(); - } - - return false; } void LLFloaterIMContainer::draw() diff --git a/indra/newview/llfloaterimcontainer.h b/indra/newview/llfloaterimcontainer.h index 78b3572111..530a8e66c8 100644 --- a/indra/newview/llfloaterimcontainer.h +++ b/indra/newview/llfloaterimcontainer.h @@ -181,6 +181,7 @@ private: bool isParticipantListExpanded(); void idleUpdate(); // for convenience (self) from static idle + void idleProcessEvents(); LLButton* mExpandCollapseBtn; LLButton* mStubCollapseBtn; @@ -220,6 +221,7 @@ private: LLConversationViewSession* createConversationItemWidget(LLConversationItem* item); LLConversationViewParticipant* createConversationViewParticipant(LLConversationItem* item); bool onConversationModelEvent(const LLSD& event); + void handleConversationModelEvent(const LLSD& event); // Conversation list data LLPanel* mConversationsListPanel; // This is the main widget we add conversation widget to @@ -229,6 +231,8 @@ private: LLFolderView* mConversationsRoot; LLEventStream mConversationsEventStream; + std::deque<LLSD> mConversationEventQueue; + LLTimer mParticipantRefreshTimer; }; diff --git a/indra/newview/llfloaterimsessiontab.cpp b/indra/newview/llfloaterimsessiontab.cpp index 3aee08482b..6d326f6850 100644 --- a/indra/newview/llfloaterimsessiontab.cpp +++ b/indra/newview/llfloaterimsessiontab.cpp @@ -465,9 +465,10 @@ void LLFloaterIMSessionTab::appendMessage(const LLChat& chat, const LLSD &args) } } - +static LLTrace::BlockTimerStatHandle FTM_BUILD_CONVERSATION_VIEW_PARTICIPANT("Build Conversation View"); void LLFloaterIMSessionTab::buildConversationViewParticipant() { + LL_RECORD_BLOCK_TIME(FTM_BUILD_CONVERSATION_VIEW_PARTICIPANT); // Clear the widget list since we are rebuilding afresh from the model conversations_widgets_map::iterator widget_it = mConversationsWidgets.begin(); while (widget_it != mConversationsWidgets.end()) @@ -496,14 +497,14 @@ void LLFloaterIMSessionTab::buildConversationViewParticipant() } } -void LLFloaterIMSessionTab::addConversationViewParticipant(LLConversationItem* participant_model) +void LLFloaterIMSessionTab::addConversationViewParticipant(LLConversationItem* participant_model, bool update_view) { // Check if the model already has an associated view LLUUID uuid = participant_model->getUUID(); LLFolderViewItem* widget = get_ptr_in_map(mConversationsWidgets,uuid); // If not already present, create the participant view and attach it to the root, otherwise, just refresh it - if (widget) + if (widget && update_view) { updateConversationViewParticipant(uuid); // overkill? } diff --git a/indra/newview/llfloaterimsessiontab.h b/indra/newview/llfloaterimsessiontab.h index 1b4922fd73..5357a14ab9 100644 --- a/indra/newview/llfloaterimsessiontab.h +++ b/indra/newview/llfloaterimsessiontab.h @@ -84,7 +84,7 @@ public: /*virtual*/ void setFocus(BOOL focus); // Handle the left hand participant list widgets - void addConversationViewParticipant(LLConversationItem* item); + void addConversationViewParticipant(LLConversationItem* item, bool update_view = true); void removeConversationViewParticipant(const LLUUID& participant_id); void updateConversationViewParticipant(const LLUUID& participant_id); void refreshConversation(); diff --git a/indra/newview/llgroupmgr.cpp b/indra/newview/llgroupmgr.cpp index dbf7639539..3ef7b749a6 100644 --- a/indra/newview/llgroupmgr.cpp +++ b/indra/newview/llgroupmgr.cpp @@ -944,9 +944,13 @@ static void formatDateString(std::string &date_string) } } +static LLTrace::BlockTimerStatHandle FTM_PROCESS_GROUP_MEMBERS_REPLY("Process Group Members"); + // static void LLGroupMgr::processGroupMembersReply(LLMessageSystem* msg, void** data) { + LL_RECORD_BLOCK_TIME(FTM_PROCESS_GROUP_MEMBERS_REPLY); + LL_DEBUGS() << "LLGroupMgr::processGroupMembersReply" << LL_ENDL; LLUUID agent_id; msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_AgentID, agent_id ); @@ -1050,9 +1054,13 @@ void LLGroupMgr::processGroupMembersReply(LLMessageSystem* msg, void** data) LLGroupMgr::getInstance()->notifyObservers(GC_MEMBER_DATA); } +static LLTrace::BlockTimerStatHandle FTM_PROCESS_GROUP_PROPERTIES_REPLY("Process Group Properties"); + //static void LLGroupMgr::processGroupPropertiesReply(LLMessageSystem* msg, void** data) { + LL_RECORD_BLOCK_TIME(FTM_PROCESS_GROUP_PROPERTIES_REPLY); + LL_DEBUGS() << "LLGroupMgr::processGroupPropertiesReply" << LL_ENDL; if (!msg) { @@ -1122,9 +1130,12 @@ void LLGroupMgr::processGroupPropertiesReply(LLMessageSystem* msg, void** data) LLGroupMgr::getInstance()->notifyObservers(GC_PROPERTIES); } +static LLTrace::BlockTimerStatHandle FTM_PROCESS_GROUP_ROLE_DATA_REPLY("Process Group Role Data"); // static void LLGroupMgr::processGroupRoleDataReply(LLMessageSystem* msg, void** data) { + LL_RECORD_BLOCK_TIME(FTM_PROCESS_GROUP_ROLE_DATA_REPLY); + LL_DEBUGS() << "LLGroupMgr::processGroupRoleDataReply" << LL_ENDL; LLUUID agent_id; msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_AgentID, agent_id ); @@ -1207,9 +1218,12 @@ void LLGroupMgr::processGroupRoleDataReply(LLMessageSystem* msg, void** data) LLGroupMgr::getInstance()->notifyObservers(GC_ROLE_DATA); } +static LLTrace::BlockTimerStatHandle FTM_PROCESS_GROUP_ROLE_MEMBERS_REPLY("Process Group Role Members"); // static void LLGroupMgr::processGroupRoleMembersReply(LLMessageSystem* msg, void** data) { + LL_RECORD_BLOCK_TIME(FTM_PROCESS_GROUP_ROLE_MEMBERS_REPLY); + LL_DEBUGS() << "LLGroupMgr::processGroupRoleMembersReply" << LL_ENDL; LLUUID agent_id; msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_AgentID, agent_id ); diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp index e077626461..e1c44d6be8 100644 --- a/indra/newview/llviewermessage.cpp +++ b/indra/newview/llviewermessage.cpp @@ -2220,8 +2220,12 @@ protected: } }; +static LLTrace::BlockTimerStatHandle FTM_PROCESS_IMPROVED_IM("Process IM"); + void process_improved_im(LLMessageSystem *msg, void **user_data) { + LL_RECORD_BLOCK_TIME(FTM_PROCESS_IMPROVED_IM); + LLUUID from_id; BOOL from_group; LLUUID to_id; diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp index d56408939e..896896d7b9 100644 --- a/indra/newview/llviewerregion.cpp +++ b/indra/newview/llviewerregion.cpp @@ -102,6 +102,7 @@ const U32 DEFAULT_MAX_REGION_WIDE_PRIM_COUNT = 15000; BOOL LLViewerRegion::sVOCacheCullingEnabled = FALSE; S32 LLViewerRegion::sLastCameraUpdated = 0; S32 LLViewerRegion::sNewObjectCreationThrottle = -1; +LLViewerRegion::vocache_entry_map_t LLViewerRegion::sRegionCacheCleanup; typedef std::map<std::string, std::string> CapabilityMap; @@ -635,6 +636,9 @@ void LLViewerRegion::initStats() mAlive = false; // can become false if circuit disconnects } +static LLTrace::BlockTimerStatHandle FTM_CLEANUP_REGION_OBJECTS("Cleanup Region Objects"); +static LLTrace::BlockTimerStatHandle FTM_SAVE_REGION_CACHE("Save Region Cache"); + LLViewerRegion::~LLViewerRegion() { mDead = TRUE; @@ -649,7 +653,10 @@ LLViewerRegion::~LLViewerRegion() disconnectAllNeighbors(); LLViewerPartSim::getInstance()->cleanupRegion(this); - gObjectList.killObjects(this); + { + LL_RECORD_BLOCK_TIME(FTM_CLEANUP_REGION_OBJECTS); + gObjectList.killObjects(this); + } delete mImpl->mCompositionp; delete mParcelOverlay; @@ -660,7 +667,10 @@ LLViewerRegion::~LLViewerRegion() #endif std::for_each(mImpl->mObjectPartition.begin(), mImpl->mObjectPartition.end(), DeletePointer()); - saveObjectCache(); + { + LL_RECORD_BLOCK_TIME(FTM_SAVE_REGION_CACHE); + saveObjectCache(); + } delete mImpl; mImpl = NULL; @@ -729,6 +739,8 @@ void LLViewerRegion::saveObjectCache() mCacheDirty = FALSE; } + // Map of LLVOCacheEntry takes time to release, store map for cleanup on idle + sRegionCacheCleanup.insert(mImpl->mCacheMap.begin(), mImpl->mCacheMap.end()); mImpl->mCacheMap.clear(); } @@ -1490,6 +1502,16 @@ void LLViewerRegion::idleUpdate(F32 max_update_time) return; } +// static +void LLViewerRegion::idleCleanup(F32 max_update_time) +{ + LLTimer update_timer; + while (!sRegionCacheCleanup.empty() && (max_update_time - update_timer.getElapsedTimeF32() > 0)) + { + sRegionCacheCleanup.erase(sRegionCacheCleanup.begin()); + } +} + //update the throttling number for new object creation void LLViewerRegion::calcNewObjectCreationThrottle() { diff --git a/indra/newview/llviewerregion.h b/indra/newview/llviewerregion.h index f7c50e4de5..477aabb971 100644 --- a/indra/newview/llviewerregion.h +++ b/indra/newview/llviewerregion.h @@ -232,6 +232,9 @@ public: F32 getWidth() const { return mWidth; } + // regions are expensive to release, this function gradually releases cache from memory + static void idleCleanup(F32 max_update_time); + void idleUpdate(F32 max_update_time); void lightIdleUpdate(); bool addVisibleGroup(LLViewerOctreeGroup* group); @@ -550,6 +553,9 @@ private: LLSD mSimulatorFeatures; + typedef std::map<U32, LLPointer<LLVOCacheEntry> > vocache_entry_map_t; + static vocache_entry_map_t sRegionCacheCleanup; + // the materials capability throttle LLFrameTimer mMaterialsCapThrottleTimer; LLFrameTimer mRenderInfoRequestTimer; diff --git a/indra/newview/llworld.cpp b/indra/newview/llworld.cpp index 8989bae96a..a1a1db35d6 100644 --- a/indra/newview/llworld.cpp +++ b/indra/newview/llworld.cpp @@ -730,11 +730,20 @@ void LLWorld::updateRegions(F32 max_update_time) { //perform some necessary but very light updates. (*iter)->lightIdleUpdate(); - } + } + } + + if(max_time > 0.f) + { + max_time = llmin((F32)(max_update_time - update_timer.getElapsedTimeF32()), max_update_time * 0.25f); + } + if(max_time > 0.f) + { + LLViewerRegion::idleCleanup(max_time); } sample(sNumActiveCachedObjects, mNumOfActiveCachedObjects); - } +} void LLWorld::clearAllVisibleObjects() { @@ -1208,11 +1217,14 @@ public: } }; +static LLTrace::BlockTimerStatHandle FTM_DISABLE_REGION("Disable Region"); // disable the circuit to this simulator // Called in response to "DisableSimulator" message. void process_disable_simulator(LLMessageSystem *mesgsys, void **user_data) -{ - LLHost host = mesgsys->getSender(); +{ + LL_RECORD_BLOCK_TIME(FTM_DISABLE_REGION); + + LLHost host = mesgsys->getSender(); //LL_INFOS() << "Disabling simulator with message from " << host << LL_ENDL; LLWorld::getInstance()->removeRegion(host); |