summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrey Kleshchev <andreykproductengine@lindenlab.com>2023-06-14 23:59:43 +0300
committerAndrey Kleshchev <andreykproductengine@lindenlab.com>2023-06-15 00:00:07 +0300
commit143e103bcf2b9be2b249ce96e7f84a52469174c7 (patch)
tree61e5a5e9d3c0e3ac5680723c17a59c13c91934da
parent3a359224565aabec518a097ae502735a0d8244b0 (diff)
SL-19686 WIP Switching single folder view for large inventories causes stalls #2
-rw-r--r--indra/newview/llinventorygallery.cpp34
-rw-r--r--indra/newview/llinventorygallery.h4
-rw-r--r--indra/newview/llinventorypanel.cpp45
-rw-r--r--indra/newview/llpanelmaininventory.cpp4
-rw-r--r--indra/newview/llsidepanelinventory.cpp3
5 files changed, 85 insertions, 5 deletions
diff --git a/indra/newview/llinventorygallery.cpp b/indra/newview/llinventorygallery.cpp
index 5edcb3148c..421949d9aa 100644
--- a/indra/newview/llinventorygallery.cpp
+++ b/indra/newview/llinventorygallery.cpp
@@ -85,6 +85,7 @@ LLInventoryGallery::LLInventoryGallery(const LLInventoryGallery::Params& p)
mRowPanWidthFactor(p.row_panel_width_factor),
mGalleryWidthFactor(p.gallery_width_factor),
mIsInitialized(false),
+ mRootDirty(false),
mNeedsArrange(false),
mSearchType(LLInventoryFilter::SEARCHTYPE_NAME)
{
@@ -188,7 +189,19 @@ void LLInventoryGallery::setRootFolder(const LLUUID cat_id)
mBackwardFolders.push_back(mFolderID);
}
mFolderID = cat_id;
- updateRootFolder();
+ dirtyRootFolder();
+}
+
+void LLInventoryGallery::dirtyRootFolder()
+{
+ if (getVisible())
+ {
+ updateRootFolder();
+ }
+ else
+ {
+ mRootDirty = true;
+ }
}
void LLInventoryGallery::updateRootFolder()
@@ -260,6 +273,7 @@ void LLInventoryGallery::updateRootFolder()
}
reArrangeRows();
mIsInitialized = true;
+ mRootDirty = false;
if (mScrollPanel)
{
@@ -305,6 +319,15 @@ void LLInventoryGallery::draw()
}
}
+void LLInventoryGallery::onVisibilityChange(BOOL new_visibility)
+{
+ if (new_visibility && mRootDirty)
+ {
+ updateRootFolder();
+ }
+ LLPanel::onVisibilityChange(new_visibility);
+}
+
bool LLInventoryGallery::updateRowsIfNeeded()
{
if(((getRect().getWidth() - mRowPanelWidth) > mItemWidth) && mRowCount > 1)
@@ -542,6 +565,7 @@ LLInventoryGalleryItem* LLInventoryGallery::buildGalleryItem(std::string name, L
void LLInventoryGallery::buildGalleryPanel(int row_count)
{
LLPanel::Params params;
+ params.use_bounding_rect = false;
mGalleryPanel = LLUICtrlFactory::create<LLPanel>(params);
reshapeGalleryPanel(row_count);
}
@@ -561,11 +585,12 @@ void LLInventoryGallery::reshapeGalleryPanel(int row_count)
LLPanel* LLInventoryGallery::buildItemPanel(int left)
{
- LLPanel::Params lpparams;
int top = 0;
LLPanel* lpanel = NULL;
if(mUnusedItemPanels.empty())
{
+ LLPanel::Params lpparams;
+ lpparams.use_bounding_rect = false;
lpanel = LLUICtrlFactory::create<LLPanel>(lpparams);
}
else
@@ -585,6 +610,7 @@ LLPanel* LLInventoryGallery::buildItemPanel(int left)
LLPanel* LLInventoryGallery::buildRowPanel(int left, int bottom)
{
LLPanel::Params sparams;
+ sparams.use_bounding_rect = false;
LLPanel* stack = NULL;
if(mUnusedRowPanels.empty())
{
@@ -1787,7 +1813,7 @@ void LLInventoryGallery::onForwardFolder()
mBackwardFolders.push_back(mFolderID);
mFolderID = mForwardFolders.back();
mForwardFolders.pop_back();
- updateRootFolder();
+ dirtyRootFolder();
}
}
@@ -1798,7 +1824,7 @@ void LLInventoryGallery::onBackwardFolder()
mForwardFolders.push_back(mFolderID);
mFolderID = mBackwardFolders.back();
mBackwardFolders.pop_back();
- updateRootFolder();
+ dirtyRootFolder();
}
}
diff --git a/indra/newview/llinventorygallery.h b/indra/newview/llinventorygallery.h
index 6fbd1556e5..8519ee0731 100644
--- a/indra/newview/llinventorygallery.h
+++ b/indra/newview/llinventorygallery.h
@@ -76,6 +76,7 @@ public:
BOOL postBuild() override;
void initGallery();
void draw() override;
+ void onVisibilityChange(BOOL new_visibility) override;
BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop, EDragAndDropType cargo_type,
void* cargo_data, EAcceptance* accept, std::string& tooltip_msg) override;
BOOL handleRightMouseDown(S32 x, S32 y, MASK mask) override;
@@ -103,6 +104,7 @@ public:
void setRootFolder(const LLUUID cat_id);
void updateRootFolder();
LLUUID getRootFolder() { return mFolderID; }
+ bool isRootDirty() { return mRootDirty; }
boost::signals2::connection setRootChangedCallback(callback_t cb);
void onForwardFolder();
void onBackwardFolder();
@@ -168,6 +170,7 @@ protected:
void applyFilter(LLInventoryGalleryItem* item, const std::string& filter_substring);
bool checkAgainstFilters(LLInventoryGalleryItem* item, const std::string& filter_substring);
static void onIdle(void* userdata);
+ void dirtyRootFolder();
LLInventoryCategoriesObserver* mCategoriesObserver;
LLThumbnailsObserver* mThumbnailsObserver;
@@ -176,6 +179,7 @@ protected:
LLUUID mSelectedItemID;
LLUUID mItemToSelect;
bool mIsInitialized;
+ bool mRootDirty;
selection_change_signal_t mSelectionChangeSignal;
boost::signals2::signal<void()> mRootChangedSignal;
diff --git a/indra/newview/llinventorypanel.cpp b/indra/newview/llinventorypanel.cpp
index ac156b9e72..f7a24a09c0 100644
--- a/indra/newview/llinventorypanel.cpp
+++ b/indra/newview/llinventorypanel.cpp
@@ -1177,7 +1177,7 @@ LLFolderViewItem* LLInventoryPanel::buildViewsTree(const LLUUID& id,
else
{
create_children = true;
- folder_view_item->setChildrenInited(true);
+ folder_view_item->setChildrenInited(mBuildChildrenViews);
}
break;
}
@@ -1218,6 +1218,11 @@ LLFolderViewItem* LLInventoryPanel::buildViewsTree(const LLUUID& id,
LLViewerInventoryItem::item_array_t* items;
mInventory->lockDirectDescendentArrays(id, categories, items);
+ // Make sure panel won't lock in a loop over existing items if
+ // folder is enormous and at least some work gets done
+ const S32 MIN_ITEMS_PER_CALL = 500;
+ const S32 starting_item_count = mItemMap.size();
+
LLFolderViewFolder *parentp = dynamic_cast<LLFolderViewFolder*>(folder_view_item);
if(categories)
@@ -1243,6 +1248,22 @@ LLFolderViewItem* LLInventoryPanel::buildViewsTree(const LLUUID& id,
buildViewsTree(cat->getUUID(), id, cat, NULL, parentp, (mode == BUILD_ONE_FOLDER ? BUILD_NO_CHILDREN : mode), depth);
}
}
+
+ if (!mBuildChildrenViews
+ && mode == BUILD_TIMELIMIT
+ && MIN_ITEMS_PER_CALL + starting_item_count < mItemMap.size())
+ {
+ // Single folder view, check if we still have time
+ //
+ // Todo: make sure this causes no dupplciates, breaks nothing,
+ // especially filters and arrange
+ F64 curent_time = LLTimer::getTotalSeconds();
+ if (mBuildViewsEndTime < curent_time)
+ {
+ mBuildViewsQueue.push_back(id);
+ break;
+ }
+ }
}
}
@@ -1262,8 +1283,30 @@ LLFolderViewItem* LLInventoryPanel::buildViewsTree(const LLUUID& id,
LLFolderViewItem* view_itemp = getItemByID(item->getUUID());
buildViewsTree(item->getUUID(), id, item, view_itemp, parentp, mode, depth);
}
+
+ if (!mBuildChildrenViews
+ && mode == BUILD_TIMELIMIT
+ && MIN_ITEMS_PER_CALL + starting_item_count < mItemMap.size())
+ {
+ // Single folder view, check if we still have time
+ //
+ // Todo: make sure this causes no dupplciates, breaks nothing,
+ // especially filters and arrange
+ F64 curent_time = LLTimer::getTotalSeconds();
+ if (mBuildViewsEndTime < curent_time)
+ {
+ mBuildViewsQueue.push_back(id);
+ break;
+ }
+ }
}
}
+
+ if (!mBuildChildrenViews)
+ {
+ // flat list is done initializing folder
+ folder_view_item->setChildrenInited(true);
+ }
mInventory->unlockDirectDescendentArrays(id);
}
diff --git a/indra/newview/llpanelmaininventory.cpp b/indra/newview/llpanelmaininventory.cpp
index eb0ed52317..a785d5adb7 100644
--- a/indra/newview/llpanelmaininventory.cpp
+++ b/indra/newview/llpanelmaininventory.cpp
@@ -2350,6 +2350,7 @@ void LLPanelMainInventory::updatePanelVisibility()
// visibility will be controled by updateCombinationVisibility()
mCombinationGalleryLayoutPanel->setVisible(true);
+ mCombinationGalleryPanel->setVisible(true);
mCombinationListLayoutPanel->setVisible(true);
}
else
@@ -2363,12 +2364,14 @@ void LLPanelMainInventory::updatePanelVisibility()
comb_gallery_filter.markDefault();
mCombinationGalleryLayoutPanel->setVisible(mSingleFolderMode && isGalleryViewMode());
+ mCombinationGalleryPanel->setVisible(mSingleFolderMode && isGalleryViewMode()); // to prevent or process updates
mCombinationListLayoutPanel->setVisible(mSingleFolderMode && isListViewMode());
}
}
else
{
mCombinationGalleryLayoutPanel->setVisible(false);
+ mCombinationGalleryPanel->setVisible(false); // to prevent updates
mCombinationListLayoutPanel->setVisible(false);
}
}
@@ -2380,6 +2383,7 @@ void LLPanelMainInventory::updateCombinationVisibility()
bool is_gallery_empty = !mCombinationGalleryPanel->hasVisibleItems();
bool show_inv_pane = mCombinationInventoryPanel->hasVisibleItems() || is_gallery_empty || mForceShowInvLayout;
mCombinationGalleryLayoutPanel->setVisible(!is_gallery_empty);
+ mCombinationGalleryPanel->setVisible(true); // to make sure root updates are getting processed
mCombinationListLayoutPanel->setVisible(show_inv_pane);
mCombinationInventoryPanel->getRootFolder()->setForceArrange(!show_inv_pane);
if(mCombinationInventoryPanel->hasVisibleItems())
diff --git a/indra/newview/llsidepanelinventory.cpp b/indra/newview/llsidepanelinventory.cpp
index 5f30ef3219..5eb853f44c 100644
--- a/indra/newview/llsidepanelinventory.cpp
+++ b/indra/newview/llsidepanelinventory.cpp
@@ -215,6 +215,9 @@ BOOL LLSidepanelInventory::postBuild()
LLFloater *floater = dynamic_cast<LLFloater*>(getParent());
if (floater && floater->getKey().isUndefined() && !sLoginCompleted)
{
+ // Prefill inventory for primary inventory floater
+ // Other floaters should fill on visibility change
+ //
// see get_instance_num();
// Primary inventory floater will have undefined key
initInventoryViews();