SL-19686 WIP Switching single folder view for large inventories causes stalls #2

meow-7.2.2
Andrey Kleshchev 2023-06-14 23:59:43 +03:00
parent 3a35922456
commit 143e103bcf
5 changed files with 85 additions and 5 deletions

View File

@ -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();
}
}

View File

@ -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;

View File

@ -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);
}

View File

@ -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())

View File

@ -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();