summaryrefslogtreecommitdiff
path: root/indra/newview
diff options
context:
space:
mode:
authorandreykproductengine <akleshchev@productengine.com>2016-09-26 21:29:20 +0300
committerandreykproductengine <akleshchev@productengine.com>2016-09-26 21:29:20 +0300
commitb7b98918eb36a1b69ef987a0b1fe8861a39b25b9 (patch)
tree9c0f8d258534adf11772e0b21b3c7aa368e8716d /indra/newview
parentb941de80dbe15a20a0eaea795d1282cf36306c30 (diff)
MAINT-4950 Appearance panel performance improvements.
Diffstat (limited to 'indra/newview')
-rw-r--r--indra/newview/llfilteredwearablelist.cpp5
-rw-r--r--indra/newview/llfilteredwearablelist.h5
-rw-r--r--indra/newview/llinventoryitemslist.cpp207
-rw-r--r--indra/newview/llinventoryitemslist.h28
-rw-r--r--indra/newview/llpaneloutfitedit.cpp4
-rw-r--r--indra/newview/llwearableitemslist.cpp24
-rw-r--r--indra/newview/llwearableitemslist.h2
7 files changed, 180 insertions, 95 deletions
diff --git a/indra/newview/llfilteredwearablelist.cpp b/indra/newview/llfilteredwearablelist.cpp
index a29ccf2b6d..f2af9b5300 100644
--- a/indra/newview/llfilteredwearablelist.cpp
+++ b/indra/newview/llfilteredwearablelist.cpp
@@ -93,4 +93,9 @@ void LLFilteredWearableListManager::populateList()
mWearableList->refreshList(item_array);
}
+void LLFilteredWearableListManager::holdProgress()
+{
+ mWearableList->setForceRefresh(false);
+}
+
// EOF
diff --git a/indra/newview/llfilteredwearablelist.h b/indra/newview/llfilteredwearablelist.h
index c21458ca98..f44ab1466f 100644
--- a/indra/newview/llfilteredwearablelist.h
+++ b/indra/newview/llfilteredwearablelist.h
@@ -56,6 +56,11 @@ public:
*/
void populateList();
+ /**
+ * Drop operation
+ */
+ void holdProgress();
+
private:
LLInventoryItemsList* mWearableList;
LLInventoryCollectFunctor* mCollector;
diff --git a/indra/newview/llinventoryitemslist.cpp b/indra/newview/llinventoryitemslist.cpp
index 36e1cc97d1..1dc1aa395e 100644
--- a/indra/newview/llinventoryitemslist.cpp
+++ b/indra/newview/llinventoryitemslist.cpp
@@ -45,7 +45,7 @@ LLInventoryItemsList::Params::Params()
LLInventoryItemsList::LLInventoryItemsList(const LLInventoryItemsList::Params& p)
: LLFlatListViewEx(p)
-, mNeedsRefresh(false)
+, mRefreshState(REFRESH_COMPLETE)
, mForceRefresh(false)
{
// TODO: mCommitOnSelectionChange is set to "false" in LLFlatListView
@@ -66,13 +66,13 @@ LLInventoryItemsList::~LLInventoryItemsList()
void LLInventoryItemsList::refreshList(const LLInventoryModel::item_array_t item_array)
{
- getIDs().clear();
+ getIDs().clear();
LLInventoryModel::item_array_t::const_iterator it = item_array.begin();
for( ; item_array.end() != it; ++it)
{
getIDs().push_back((*it)->getUUID());
}
- mNeedsRefresh = true;
+ mRefreshState = REFRESH_ALL;
}
boost::signals2::connection LLInventoryItemsList::setRefreshCompleteCallback(const commit_signal_t::slot_type& cb)
@@ -113,9 +113,9 @@ void LLInventoryItemsList::updateSelection()
void LLInventoryItemsList::doIdle()
{
- if (!mNeedsRefresh) return;
+ if (mRefreshState == REFRESH_COMPLETE) return;
- if (isInVisibleChain() || mForceRefresh)
+ if (isInVisibleChain() || mForceRefresh )
{
refresh();
@@ -137,54 +137,130 @@ LLTrace::BlockTimerStatHandle FTM_INVENTORY_ITEMS_REFRESH("Inventory List Refres
void LLInventoryItemsList::refresh()
{
- LL_RECORD_BLOCK_TIME(FTM_INVENTORY_ITEMS_REFRESH);
- static const unsigned ADD_LIMIT = 20;
-
- uuid_vec_t added_items;
- uuid_vec_t removed_items;
-
- computeDifference(getIDs(), added_items, removed_items);
-
- bool add_limit_exceeded = false;
- unsigned int nadded = 0;
-
- uuid_vec_t::const_iterator it = added_items.begin();
- for( ; added_items.end() != it; ++it)
- {
- if(nadded >= ADD_LIMIT)
- {
- add_limit_exceeded = true;
- break;
- }
- LLViewerInventoryItem* item = gInventory.getItem(*it);
- // Do not rearrange items on each adding, let's do that on filter call
- llassert(item);
- if (item)
- {
- addNewItem(item, false);
- ++nadded;
- }
- }
-
- it = removed_items.begin();
- for( ; removed_items.end() != it; ++it)
- {
- // don't filter items right away
- removeItemByUUID(*it, false);
- }
-
- // Filter, rearrange and notify parent about shape changes
- filterItems();
-
- bool needs_refresh = add_limit_exceeded;
- setNeedsRefresh(needs_refresh);
- setForceRefresh(needs_refresh);
-
- // After list building completed, select items that had been requested to select before list was build
- if(!needs_refresh)
- {
- updateSelection();
- }
+ LL_RECORD_BLOCK_TIME(FTM_INVENTORY_ITEMS_REFRESH);
+
+ switch (mRefreshState)
+ {
+ case REFRESH_ALL:
+ {
+ mAddedItems.clear();
+ mRemovedItems.clear();
+ computeDifference(getIDs(), mAddedItems, mRemovedItems);
+ if (mRemovedItems.size() > 0)
+ {
+ mRefreshState = REFRESH_LIST_ERASE;
+ }
+ else if (mAddedItems.size() > 0)
+ {
+ mRefreshState = REFRESH_LIST_APPEND;
+ }
+ else
+ {
+ mRefreshState = REFRESH_LIST_SORT;
+ }
+
+ rearrangeItems();
+ notifyParentItemsRectChanged();
+ break;
+ }
+ case REFRESH_LIST_ERASE:
+ {
+ uuid_vec_t::const_iterator it = mRemovedItems.begin();
+ for (; mRemovedItems.end() != it; ++it)
+ {
+ // don't filter items right away
+ removeItemByUUID(*it, false);
+ }
+ mRemovedItems.clear();
+ mRefreshState = REFRESH_LIST_SORT; // fix visibility and arrange
+ break;
+ }
+ case REFRESH_LIST_APPEND:
+ {
+ static const unsigned ADD_LIMIT = 25; // Note: affects perfomance
+
+ unsigned int nadded = 0;
+
+ // form a list to add
+ uuid_vec_t::iterator it = mAddedItems.begin();
+ pairs_list_t panel_list;
+ while(mAddedItems.size() > 0 && nadded < ADD_LIMIT)
+ {
+ LLViewerInventoryItem* item = gInventory.getItem(*it);
+ llassert(item);
+ if (item)
+ {
+ LLPanel *list_item = createNewItem(item);
+ if (list_item)
+ {
+ item_pair_t* new_pair = new item_pair_t(list_item, item->getUUID());
+ panel_list.push_back(new_pair);
+ ++nadded;
+ }
+ }
+
+ it = mAddedItems.erase(it);
+ }
+
+ // add the list
+ // Note: usually item pairs are sorted with std::sort, but we are calling
+ // this function on idle and pairs' list can take a lot of time to sort
+ // through, so we are sorting items into list while adding them
+ addItemPairs(panel_list, false);
+
+ // update visibility of items in the list
+ std::string cur_filter = getFilterSubString();
+ LLStringUtil::toUpper(cur_filter);
+ LLSD action;
+ action.with("match_filter", cur_filter);
+
+ pairs_const_iterator_t pair_it = panel_list.begin();
+ for (; pair_it != panel_list.end(); ++pair_it)
+ {
+ item_pair_t* item_pair = *pair_it;
+ if (item_pair->first->getParent() != NULL)
+ {
+ updateItemVisibility(item_pair->first, action);
+ }
+ }
+
+ rearrangeItems();
+ notifyParentItemsRectChanged();
+
+ if (mAddedItems.size() > 0)
+ {
+ mRefreshState = REFRESH_LIST_APPEND;
+ }
+ else
+ {
+ // Note: while we do sort and check visibility at REFRESH_LIST_APPEND, update
+ // could have changed something about existing items so redo checks for all items.
+ mRefreshState = REFRESH_LIST_SORT;
+ }
+ break;
+ }
+ case REFRESH_LIST_SORT:
+ {
+ // Filter, sort, rearrange and notify parent about shape changes
+ filterItems();
+
+ if (mAddedItems.size() == 0)
+ {
+ // After list building completed, select items that had been requested to select before list was build
+ updateSelection();
+ mRefreshState = REFRESH_COMPLETE;
+ }
+ else
+ {
+ mRefreshState = REFRESH_LIST_APPEND;
+ }
+ break;
+ }
+ default:
+ break;
+ }
+
+ setForceRefresh(mRefreshState != REFRESH_COMPLETE);
}
void LLInventoryItemsList::computeDifference(
@@ -204,24 +280,15 @@ void LLInventoryItemsList::computeDifference(
LLCommonUtils::computeDifference(vnew, vcur, vadded, vremoved);
}
-void LLInventoryItemsList::addNewItem(LLViewerInventoryItem* item, bool rearrange /*= true*/)
+LLPanel* LLInventoryItemsList::createNewItem(LLViewerInventoryItem* item)
{
- if (!item)
- {
- LL_WARNS() << "No inventory item. Couldn't create flat list item." << LL_ENDL;
- llassert(item != NULL);
- }
-
- LLPanelInventoryListItemBase *list_item = LLPanelInventoryListItemBase::create(item);
- if (!list_item)
- return;
-
- bool is_item_added = addItem(list_item, item->getUUID(), ADD_BOTTOM, rearrange);
- if (!is_item_added)
- {
- LL_WARNS() << "Couldn't add flat list item." << LL_ENDL;
- llassert(is_item_added);
- }
+ if (!item)
+ {
+ LL_WARNS() << "No inventory item. Couldn't create flat list item." << LL_ENDL;
+ llassert(item != NULL);
+ return NULL;
+ }
+ return LLPanelInventoryListItemBase::create(item);
}
// EOF
diff --git a/indra/newview/llinventoryitemslist.h b/indra/newview/llinventoryitemslist.h
index 1aa230df99..fe05c2ed7c 100644
--- a/indra/newview/llinventoryitemslist.h
+++ b/indra/newview/llinventoryitemslist.h
@@ -51,9 +51,9 @@ public:
/**
* Let list know items need to be refreshed in next doIdle()
*/
- void setNeedsRefresh(bool needs_refresh){ mNeedsRefresh = needs_refresh; }
+ void setNeedsRefresh(bool needs_refresh){ mRefreshState = needs_refresh ? REFRESH_ALL : REFRESH_COMPLETE; }
- bool getNeedsRefresh(){ return mNeedsRefresh; }
+ U32 getNeedsRefresh(){ return mRefreshState; }
/**
* Sets the flag indicating that the list needs to be refreshed even if it is
@@ -71,7 +71,7 @@ public:
* This is needed for example to filter items of the list hidden by closed
* accordion tab.
*/
- void doIdle(); // Real idle routine
+ virtual void doIdle(); // Real idle routine
static void idle(void* user_data); // static glue to doIdle()
protected:
@@ -94,17 +94,29 @@ protected:
void computeDifference(const uuid_vec_t& vnew, uuid_vec_t& vadded, uuid_vec_t& vremoved);
/**
- * Add an item to the list
- */
- virtual void addNewItem(LLViewerInventoryItem* item, bool rearrange = true);
+ * Create panel(item) from inventory item
+ */
+ virtual LLPanel* createNewItem(LLViewerInventoryItem* item);
+
+protected:
+ enum ERefreshStates
+ {
+ REFRESH_COMPLETE = 0,
+ REFRESH_LIST_SORT,
+ REFRESH_LIST_APPEND,
+ REFRESH_LIST_ERASE,
+ REFRESH_ALL
+ };
+
+ ERefreshStates mRefreshState;
private:
uuid_vec_t mIDs; // IDs of items that were added in refreshList().
// Will be used in refresh() to determine added and removed ids
uuid_vec_t mSelectTheseIDs; // IDs that will be selected if list is not loaded till now
-
- bool mNeedsRefresh;
+ uuid_vec_t mAddedItems;
+ uuid_vec_t mRemovedItems;
bool mForceRefresh;
diff --git a/indra/newview/llpaneloutfitedit.cpp b/indra/newview/llpaneloutfitedit.cpp
index 8b9941c0ca..d897449310 100644
--- a/indra/newview/llpaneloutfitedit.cpp
+++ b/indra/newview/llpaneloutfitedit.cpp
@@ -779,6 +779,10 @@ void LLPanelOutfitEdit::onVisibilityChanged(const LLSD &in_visible_chain)
{
update();
}
+ else
+ {
+ mWearableListManager->holdProgress(); //list population restarts with visibility
+ }
}
void LLPanelOutfitEdit::onAddWearableClicked(void)
diff --git a/indra/newview/llwearableitemslist.cpp b/indra/newview/llwearableitemslist.cpp
index f8981d0c51..ee2270c323 100644
--- a/indra/newview/llwearableitemslist.cpp
+++ b/indra/newview/llwearableitemslist.cpp
@@ -653,24 +653,16 @@ LLWearableItemsList::~LLWearableItemsList()
{}
// virtual
-void LLWearableItemsList::addNewItem(LLViewerInventoryItem* item, bool rearrange /*= true*/)
+LLPanel* LLWearableItemsList::createNewItem(LLViewerInventoryItem* item)
{
- if (!item)
- {
- LL_WARNS() << "No inventory item. Couldn't create flat list item." << LL_ENDL;
- llassert(item != NULL);
- }
-
- LLPanelWearableOutfitItem *list_item = LLPanelWearableOutfitItem::create(item, mWornIndicationEnabled);
- if (!list_item)
- return;
+ if (!item)
+ {
+ LL_WARNS() << "No inventory item. Couldn't create flat list item." << LL_ENDL;
+ llassert(item != NULL);
+ return NULL;
+ }
- bool is_item_added = addItem(list_item, item->getUUID(), ADD_BOTTOM, rearrange);
- if (!is_item_added)
- {
- LL_WARNS() << "Couldn't add flat list item." << LL_ENDL;
- llassert(is_item_added);
- }
+ return LLPanelWearableOutfitItem::create(item, mWornIndicationEnabled);
}
void LLWearableItemsList::updateList(const LLUUID& category_id)
diff --git a/indra/newview/llwearableitemslist.h b/indra/newview/llwearableitemslist.h
index 18a30f083b..63e3e9dbc9 100644
--- a/indra/newview/llwearableitemslist.h
+++ b/indra/newview/llwearableitemslist.h
@@ -453,7 +453,7 @@ public:
virtual ~LLWearableItemsList();
- /*virtual*/ void addNewItem(LLViewerInventoryItem* item, bool rearrange = true);
+ /*virtual*/ LLPanel* createNewItem(LLViewerInventoryItem* item);
void updateList(const LLUUID& category_id);