diff --git a/.gitignore b/.gitignore index a8c150ae66..f94d376ae5 100755 --- a/.gitignore +++ b/.gitignore @@ -106,3 +106,5 @@ my_autobuild.xml *.srctrlprj compile_commands.json +# ignore tracy for now +indra/tracy \ No newline at end of file diff --git a/indra/llui/llscrolllistctrl.cpp b/indra/llui/llscrolllistctrl.cpp index f5206462a4..8b6e01a9ca 100644 --- a/indra/llui/llscrolllistctrl.cpp +++ b/indra/llui/llscrolllistctrl.cpp @@ -2915,10 +2915,20 @@ void LLScrollListCtrl::sortByColumnIndex(U32 column, BOOL ascending) updateSort(); } +// FIRE-30667 et al. Group hang issues (grab settings) +extern LLControlGroup gSavedSettings; void LLScrollListCtrl::updateSort() const { - if (hasSortOrder() && !isSorted()) + // FIRE-30667 et al. Group hang issues + // if (hasSortOrder() && !isSorted()) + // { + static LLCachedControl sortDeferFrameCount( gSavedSettings, "FSSortDeferalFrames" ); + if ( hasSortOrder() && !isSorted() && ( mLastUpdateFrame > 1 && ( LLFrameTimer::getFrameCount() - mLastUpdateFrame ) >= sortDeferFrameCount ) ) + // encoding two (unlikely) special values into mLastUpdateFrame 1 means we've sorted and 0 means we've nothing new to do. + // 0 is set after sorting, 1 can be set by a parent for any post sorting action. { + mLastUpdateFrame=0; + // // do stable sort to preserve any previous sorts std::stable_sort( mItemList.begin(), diff --git a/indra/llui/llscrolllistctrl.h b/indra/llui/llscrolllistctrl.h index 0b36bc204d..b6cc6590ed 100644 --- a/indra/llui/llscrolllistctrl.h +++ b/indra/llui/llscrolllistctrl.h @@ -412,7 +412,9 @@ public: void sortOnce(S32 column, BOOL ascending); // manually call this whenever editing list items in place to flag need for resorting - void setNeedsSort(bool val = true) { mSorted = !val; } + // FIRE-30667 et al. Avoid hangs on large list updates + // void setNeedsSort(bool val = true) { mSorted = !val; } + void setNeedsSort(bool val = true) { mSorted = !val; mLastUpdateFrame = LLFrameTimer::getFrameCount(); } void dirtyColumns(); // some operation has potentially affected column layout or ordering boost::signals2::connection setSortCallback(sort_signal_t::slot_type cb ) @@ -452,6 +454,8 @@ protected: public: void updateLineHeight(); + // FIRE-30667 et al. Avoid hangs on large list updates + mutable U32 mLastUpdateFrame; private: void selectPrevItem(BOOL extend_selection); @@ -478,6 +482,7 @@ private: static void copyNameToClipboard(std::string id, bool is_group); static void copySLURLToClipboard(std::string id, bool is_group); + S32 mLineHeight; // the max height of a single line S32 mScrollLines; // how many lines we've scrolled down S32 mPageLines; // max number of lines is it possible to see on the screen given mRect and mLineHeight diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 36d3d5ce87..333e1eaa20 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -344,6 +344,17 @@ Value 0 + FSSortDeferalFrames + + Comment + How many frames after an update should we wait before sorting + Persist + 1 + Type + U32 + Value + 2 + FSGroupNotifyNoTransparency Comment diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 9623545256..d7da392112 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -6137,6 +6137,7 @@ void LLAppViewer::idleNameCache() #ifdef TIME_THROTTLE_MESSAGES #define CHECK_MESSAGES_DEFAULT_MAX_TIME .020f // 50 ms = 50 fps (just for messages!) +#define CHECK_MESSAGES_MAX_TIME_LIMIT 1.0f // 1 second, a long time but still able to stay connected static F32 CheckMessagesMaxTime = CHECK_MESSAGES_DEFAULT_MAX_TIME; #endif @@ -6202,11 +6203,24 @@ void LLAppViewer::idleNetwork() #ifdef TIME_THROTTLE_MESSAGES if (total_time >= CheckMessagesMaxTime) { - // Increase CheckMessagesMaxTime so that we will eventually catch up - CheckMessagesMaxTime *= 1.035f; // 3.5% ~= x2 in 20 frames, ~8x in 60 frames + // Don't allow busy network to excessively starve rendering loop + // // Increase CheckMessagesMaxTime so that we will eventually catch up + // CheckMessagesMaxTime *= 1.035f; // 3.5% ~= x2 in 20 frames, ~8x in 60 frames + // } + // else + // { + if( CheckMessagesMaxTime < CHECK_MESSAGES_MAX_TIME_LIMIT ) // cap the increase to avoid logout through ping starvation + {// Increase CheckMessagesMaxTime so that we will eventually catch up + CheckMessagesMaxTime *= 1.035f; // 3.5% ~= x2 in 20 frames, ~8x in 60 frames + } + else + { + CheckMessagesMaxTime = CHECK_MESSAGES_MAX_TIME_LIMIT; + } } else { + // // Reset CheckMessagesMaxTime to default value CheckMessagesMaxTime = CHECK_MESSAGES_DEFAULT_MAX_TIME; } diff --git a/indra/newview/llpanelgroup.cpp b/indra/newview/llpanelgroup.cpp index 8c0d9c3915..7fc3ffc80d 100644 --- a/indra/newview/llpanelgroup.cpp +++ b/indra/newview/llpanelgroup.cpp @@ -667,6 +667,13 @@ void LLPanelGroup::draw() { LLPanel::draw(); + // FIRE-30667 - group hang fixes + LLPanelGroupNotices* panel_notices = findChild("group_notices_tab_panel"); + if(panel_notices) + { + panel_notices->updateSelected(); + } + // if (mRefreshTimer.hasExpired()) { mRefreshTimer.stop(); diff --git a/indra/newview/llpanelgroupnotices.cpp b/indra/newview/llpanelgroupnotices.cpp index 227e021a94..253e5aa8b0 100644 --- a/indra/newview/llpanelgroupnotices.cpp +++ b/indra/newview/llpanelgroupnotices.cpp @@ -473,6 +473,8 @@ void LLPanelGroupNotices::clearNoticeList() { mPrevSelectedNotice = mNoticesList->getStringUUIDSelectedItem(); mNoticesList->deleteAllItems(); + // FIRE-30766 group hang prevention. + mNoticeIDs.clear(); } void LLPanelGroupNotices::onClickRefreshNotices(void* data) @@ -536,7 +538,8 @@ void LLPanelGroupNotices::processNotices(LLMessageSystem* msg) //save sort state and set unsorted state to prevent unnecessary //sorting while adding notices - bool save_sort = mNoticesList->isSorted(); + // FIRE-30667 et al. we will need sorting at the end + // bool save_sort = mNoticesList->isSorted(); mNoticesList->setNeedsSort(false); for (;igetItemIndex(id); - - if(pos!=-1)//if items with this ID already in the list - skip it + // FIRE-30667 et al. add a set for tracking to avoid the linear time lookup + // S32 pos = mNoticesList->getItemIndex(id); + // if(pos!=-1)//if items with this ID already in the list - skip it + auto exists = mNoticeIDs.emplace(id); + if (!exists.second) + // continue; msg->getString("Data","Subject",subj,i); @@ -596,15 +602,32 @@ void LLPanelGroupNotices::processNotices(LLMessageSystem* msg) mNoticesList->addElement(row, ADD_BOTTOM); } - mNoticesList->setNeedsSort(save_sort); - mNoticesList->updateSort(); - if (mPanelViewNotice->getVisible()) + mNoticesList->setNeedsSort(true); + // FIRE-30667 et al. defer sorting and updating selection + // mNoticesList->updateSort(); + // if (mPanelViewNotice->getVisible()) + // { + // if (!mNoticesList->selectByID(mPrevSelectedNotice)) + // { + // mNoticesList->selectFirstItem(); + // } + // } +} + +void LLPanelGroupNotices::updateSelected() +{ + if( mNoticesList->mLastUpdateFrame == 0 ) { - if (!mNoticesList->selectByID(mPrevSelectedNotice)) + if (mPanelViewNotice->getVisible()) { - mNoticesList->selectFirstItem(); + if (!mNoticesList->selectByID(mPrevSelectedNotice)) + { + mNoticesList->selectFirstItem(); + } } + mNoticesList->mLastUpdateFrame = 1; } + // } void LLPanelGroupNotices::onSelectNotice(LLUICtrl* ctrl, void* data) diff --git a/indra/newview/llpanelgroupnotices.h b/indra/newview/llpanelgroupnotices.h index 01b35e0007..3eafdd3e36 100644 --- a/indra/newview/llpanelgroupnotices.h +++ b/indra/newview/llpanelgroupnotices.h @@ -64,6 +64,7 @@ public: LLOfferInfo* inventory_offer); void refreshNotices(); + void updateSelected(); // FS:Beq FIRE-30667 group notices hang void clearNoticeList(); @@ -111,6 +112,7 @@ private: //LLIconCtrl *mViewInventoryIcon; LLScrollListCtrl *mNoticesList; + std::set mNoticeIDs; // FS:Beq FIRE-30667 group notices hang std::string mNoNoticesStr;