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

master
Andrey Kleshchev 2023-06-14 02:03:38 +03:00
parent 14eadadf99
commit 71534d8fa7
7 changed files with 64 additions and 21 deletions

View File

@ -162,7 +162,8 @@ LLInventoryPanel::LLInventoryPanel(const LLInventoryPanel::Params& p) :
mInventoryViewModel(p.name),
mGroupedItemBridge(new LLFolderViewGroupedItemBridge),
mFocusSelection(false),
mBuildChildrenViews(true)
mBuildChildrenViews(true),
mRootInited(false)
{
mInvFVBridgeBuilder = &INVENTORY_BRIDGE_BUILDER;
@ -286,6 +287,7 @@ void LLInventoryPanel::initFolderRoot()
// build the views starting with that folder.
LLFolderView* folder_view = createFolderRoot(root_id);
mFolderRoot = folder_view->getHandle();
mRootInited = true;
addItemID(root_id, mFolderRoot.get());
}
@ -318,22 +320,9 @@ void LLInventoryPanel::initFolderRoot()
mCompletionObserver = new LLInvPanelComplObserver(boost::bind(&LLInventoryPanel::onItemsCompletion, this));
mInventory->addObserver(mCompletionObserver);
if (mBuildViewsOnInit && mViewsInitialized == VIEWS_UNINITIALIZED)
if (mBuildViewsOnInit)
{
// Build view of inventory if we need default full hierarchy and inventory is ready, otherwise do in onIdle.
// Initializing views takes a while so always do it onIdle if viewer already loaded.
if (mInventory->isInventoryUsable()
&& LLStartUp::getStartupState() <= STATE_WEARABLES_WAIT)
{
// Usually this happens on login, so we have less time constraits, but too long and we can cause a disconnect
const F64 max_time = 20.f;
initializeViews(max_time);
}
else
{
mViewsInitialized = VIEWS_INITIALIZING;
gIdleCallbacks.addFunction(onIdle, (void*)this);
}
initializeViewBuilding();
}
if (mSortOrderSetting != INHERIT_SORT_ORDER)
@ -366,13 +355,38 @@ void LLInventoryPanel::initFolderRoot()
mClipboardState = LLClipboard::instance().getGeneration();
}
void LLInventoryPanel::initializeViewBuilding()
{
if (mViewsInitialized == VIEWS_UNINITIALIZED)
{
LL_DEBUGS("Inventory") << "Setting views for " << getName() << " to initialize" << LL_ENDL;
// Build view of inventory if we need default full hierarchy and inventory is ready, otherwise do in onIdle.
// Initializing views takes a while so always do it onIdle if viewer already loaded.
if (mInventory->isInventoryUsable()
&& LLStartUp::getStartupState() <= STATE_WEARABLES_WAIT)
{
// Usually this happens on login, so we have less time constraits, but too long and we can cause a disconnect
const F64 max_time = 20.f;
initializeViews(max_time);
}
else
{
mViewsInitialized = VIEWS_INITIALIZING;
gIdleCallbacks.addFunction(onIdle, (void*)this);
}
}
}
/*virtual*/
void LLInventoryPanel::onVisibilityChange(BOOL new_visibility)
{
if (new_visibility && mViewsInitialized == VIEWS_UNINITIALIZED)
{
mViewsInitialized = VIEWS_INITIALIZING;
gIdleCallbacks.addFunction(onIdle, (void*)this);
// first call can be from tab initialization
if (gFloaterView->getParentFloater(this) != NULL)
{
initializeViewBuilding();
}
}
LLPanel::onVisibilityChange(new_visibility);
}
@ -893,6 +907,7 @@ void LLInventoryPanel::idle(void* user_data)
void LLInventoryPanel::initializeViews(F64 max_time)
{
if (!gInventory.isInventoryUsable()) return;
if (!mRootInited) return;
mViewsInitialized = VIEWS_BUILDING;
@ -1063,7 +1078,7 @@ LLFolderViewItem* LLInventoryPanel::buildViewsTree(const LLUUID& id,
if (objectp->getType() >= LLAssetType::AT_COUNT)
{
// Example: Happens when we add assets of new, not yet supported type to library
LL_DEBUGS() << "LLInventoryPanel::buildViewsTree called with unknown objectp->mType : "
LL_DEBUGS("Inventory") << "LLInventoryPanel::buildViewsTree called with unknown objectp->mType : "
<< ((S32) objectp->getType()) << " name " << objectp->getName() << " UUID " << objectp->getUUID()
<< LL_ENDL;
@ -2134,7 +2149,6 @@ LLInventorySingleFolderPanel::LLInventorySingleFolderPanel(const Params& params)
: LLInventoryPanel(params)
{
mBuildChildrenViews = false;
mRootInited = false;
getFilter().setSingleFolderMode(true);
getFilter().setEmptyLookupMessage("InventorySingleFolderNoMatches");
getFilter().setDefaultEmptyLookupMessage("InventorySingleFolderEmpty");

View File

@ -269,6 +269,7 @@ public:
void changeFolderRoot(const LLUUID& new_id) {};
void initFolderRoot();
void initializeViewBuilding();
protected:
void openStartFolderOrMyInventory(); // open the first level of inventory
@ -306,7 +307,7 @@ protected:
*/
const LLInventoryFolderViewModelBuilder* mInvFVBridgeBuilder;
bool mBuildChildrenViews;
bool mBuildChildrenViews; // build root and children
bool mRootInited;

View File

@ -1530,6 +1530,16 @@ void LLPanelMainInventory::initSingleFolderRoot(const LLUUID& start_folder_id)
mCombinationInventoryPanel->initFolderRoot(start_folder_id);
}
void LLPanelMainInventory::initInventoryViews()
{
LLInventoryPanel* all_item = getChild<LLInventoryPanel>(ALL_ITEMS);
all_item->initializeViewBuilding();
LLInventoryPanel* recent_item = getChild<LLInventoryPanel>(RECENT_ITEMS);
recent_item->initializeViewBuilding();
LLInventoryPanel* worn_item = getChild<LLInventoryPanel>(WORN_ITEMS);
worn_item->initializeViewBuilding();
}
void LLPanelMainInventory::toggleViewMode()
{
if(mSingleFolderMode && isCombinationViewMode())

View File

@ -116,6 +116,7 @@ public:
void onViewModeClick();
void toggleViewMode();
void initSingleFolderRoot(const LLUUID& start_folder_id = LLUUID::null);
void initInventoryViews();
void onUpFolderClicked();
void onBackFolderClicked();
void onForwardFolderClicked();

View File

@ -212,6 +212,14 @@ BOOL LLSidepanelInventory::postBuild()
gSavedSettings.getControl("InventoryDisplayInbox")->getCommitSignal()->connect(boost::bind(&handleInventoryDisplayInboxChanged));
LLFloater *floater = dynamic_cast<LLFloater*>(getParent());
if (floater && floater->getKey().isUndefined() && !sLoginCompleted)
{
// see get_instance_num();
// Primary inventory floater will have undefined key
initInventoryViews();
}
return TRUE;
}
@ -425,6 +433,11 @@ void LLSidepanelInventory::showInventoryPanel()
mInventoryPanel->setVisible(TRUE);
}
void LLSidepanelInventory::initInventoryViews()
{
mPanelMainInventory->initInventoryViews();
}
bool LLSidepanelInventory::canShare()
{
LLInventoryPanel* inbox = mInventoryPanelInbox.get();

View File

@ -67,6 +67,7 @@ public:
std::set<LLFolderViewItem*> getInboxSelectionList();
void showInventoryPanel();
void initInventoryViews();
// checks can share selected item(s)
bool canShare();

View File

@ -234,6 +234,7 @@
name="All Items"
sort_order_setting="InventorySortOrder"
show_item_link_overlays="true"
preinitialize_views="false"
top="16"
width="288">
<folder double_click_override="true"/>
@ -252,6 +253,7 @@
left_delta="0"
name="Recent Items"
show_item_link_overlays="true"
preinitialize_views="false"
width="290">
<folder double_click_override="true"/>
</recent_inventory_panel>
@ -265,6 +267,7 @@
bg_opaque_color="DkGray2"
bg_alpha_color="DkGray2"
background_visible="true"
preinitialize_views="false"
border="false"
bevel_style="none"
scroll.reserve_scroll_corner="false">