summaryrefslogtreecommitdiff
path: root/indra
diff options
context:
space:
mode:
authorMnikolenko Productengine <mnikolenko@productengine.com>2020-06-26 15:10:46 +0300
committerDave Houlton <euclid@lindenlab.com>2020-07-09 12:15:03 -0600
commite1e25f9a0d8e8d6f7b89673183ca570854984685 (patch)
treee914eec97f8b6272a525f2ad7b189d8de703b4c7 /indra
parent3630beed07e5ad61a8afc199ae2541cbb3f2b69b (diff)
SL-13397 Reduce Viewer freeze when opening chat with a large group.
Diffstat (limited to 'indra')
-rw-r--r--indra/newview/llfloaterimcontainer.cpp50
-rw-r--r--indra/newview/llfloaterimcontainer.h4
-rw-r--r--indra/newview/llfloaterimsessiontab.cpp7
-rw-r--r--indra/newview/llfloaterimsessiontab.h2
4 files changed, 42 insertions, 21 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();