From 81398f965263b867dffc99801f596a5fe0f6dab6 Mon Sep 17 00:00:00 2001 From: Erik Kundiman Date: Wed, 15 May 2024 12:35:33 +0800 Subject: Reapply "SL-20411 Don't load all thumnails at once for large folders #2" This reverts commit 05475f8cfab81fe70b87b24031a12465cfbf492e. --- indra/newview/llinventorygallery.cpp | 26 ++++++++++-- indra/newview/llinventorygallery.h | 4 ++ indra/newview/llthumbnailctrl.cpp | 77 ++++++++++++++++++++++++++---------- indra/newview/llthumbnailctrl.h | 8 ++++ 4 files changed, 90 insertions(+), 25 deletions(-) diff --git a/indra/newview/llinventorygallery.cpp b/indra/newview/llinventorygallery.cpp index 19fa19827b..230ee86fb7 100644 --- a/indra/newview/llinventorygallery.cpp +++ b/indra/newview/llinventorygallery.cpp @@ -58,6 +58,7 @@ static LLPanelInjector t_inventory_gallery("inventory_gallery"); const S32 GALLERY_ITEMS_PER_ROW_MIN = 2; +const S32 FAST_LOAD_THUMBNAIL_TRSHOLD = 50; // load folders below this value immediately // Helper dnd functions BOOL dragCategoryIntoFolder(LLUUID dest_id, LLInventoryCategory* inv_cat, BOOL drop, std::string& tooltip_msg, BOOL is_link); @@ -106,6 +107,7 @@ LLInventoryGallery::LLInventoryGallery(const LLInventoryGallery::Params& p) mGalleryWidthFactor(p.gallery_width_factor), mIsInitialized(false), mRootDirty(false), + mLoadThumbnailsImmediately(true), mNeedsArrange(false), mSearchType(LLInventoryFilter::SEARCHTYPE_NAME), mSortOrder(LLInventoryFilter::SO_DATE) @@ -540,6 +542,12 @@ void LLInventoryGallery::addToGallery(LLInventoryGalleryItem* item) int n_prev = n - 1; int row_count_prev = (n_prev % mItemsInRow) == 0 ? n_prev / mItemsInRow : n_prev / mItemsInRow + 1; + // Avoid loading too many items. + // Intent is for small folders to display all content fast + // and for large folders to load content mostly as needed + // Todo: ideally needs to unload images outside visible area + mLoadThumbnailsImmediately = mItemsAddedCount < FAST_LOAD_THUMBNAIL_TRSHOLD; + bool add_row = row_count != row_count_prev; int pos = 0; if (add_row) @@ -573,6 +581,8 @@ void LLInventoryGallery::removeFromGalleryLast(LLInventoryGalleryItem* item, boo mItemsAddedCount--; mIndexToItemMap.erase(mItemsAddedCount); + mLoadThumbnailsImmediately = mItemsAddedCount < FAST_LOAD_THUMBNAIL_TRSHOLD; + bool remove_row = row_count != row_count_prev; removeFromLastRow(mItems[mItemsAddedCount]); mItems.pop_back(); @@ -636,6 +646,7 @@ LLInventoryGalleryItem* LLInventoryGallery::buildGalleryItem(std::string name, L gitem->setUUID(item_id); gitem->setGallery(this); gitem->setType(type, inventory_type, flags, is_link); + gitem->setLoadImmediately(mLoadThumbnailsImmediately); gitem->setThumbnail(thumbnail_id); gitem->setWorn(is_worn); gitem->setCreatorName(get_searchable_creator_name(&gInventory, item_id)); @@ -997,6 +1008,7 @@ void LLInventoryGallery::updateItemThumbnail(LLUUID item_id) if (mItemMap[item_id]) { + mItemMap[item_id]->setLoadImmediately(mLoadThumbnailsImmediately); mItemMap[item_id]->setThumbnail(thumbnail_id); bool passes_filter = checkAgainstFilters(mItemMap[item_id], mFilterSubString); @@ -2573,6 +2585,7 @@ BOOL LLInventoryGalleryItem::postBuild() { mNameText = getChild("item_name"); mTextBgPanel = getChild("text_bg_panel"); + mThumbnailCtrl = getChild("preview_thumbnail"); return TRUE; } @@ -2648,14 +2661,19 @@ void LLInventoryGalleryItem::setThumbnail(LLUUID id) mDefaultImage = id.isNull(); if(mDefaultImage) { - getChild("preview_thumbnail")->clearTexture(); + mThumbnailCtrl->clearTexture(); } else { - getChild("preview_thumbnail")->setValue(id); + mThumbnailCtrl->setValue(id); } } +void LLInventoryGalleryItem::setLoadImmediately(bool val) +{ + mThumbnailCtrl->setInitImmediately(val); +} + void LLInventoryGalleryItem::draw() { if (isFadeItem()) @@ -2670,7 +2688,7 @@ void LLInventoryGalleryItem::draw() // Draw border LLUIColor border_color = LLUIColorTable::instance().getColor(mSelected ? "MenuItemHighlightBgColor" : "TextFgTentativeColor", LLColor4::white); - LLRect border = getChildView("preview_thumbnail")->getRect(); + LLRect border = mThumbnailCtrl->getRect(); border.mRight = border.mRight + 1; border.mTop = border.mTop + 1; gl_rect_2d(border, border_color.get(), FALSE); @@ -2892,7 +2910,7 @@ void LLInventoryGalleryItem::updateNameText() mNameText->setFont(getTextFont()); mNameText->setText(mItemName + mPermSuffix + mWornSuffix); mNameText->setToolTip(mItemName + mPermSuffix + mWornSuffix); - getChild("preview_thumbnail")->setToolTip(mItemName + mPermSuffix + mWornSuffix); + mThumbnailCtrl->setToolTip(mItemName + mPermSuffix + mWornSuffix); } bool LLInventoryGalleryItem::isFadeItem() diff --git a/indra/newview/llinventorygallery.h b/indra/newview/llinventorygallery.h index 9b3f12701f..0c52e7b713 100644 --- a/indra/newview/llinventorygallery.h +++ b/indra/newview/llinventorygallery.h @@ -39,6 +39,7 @@ class LLInventoryGalleryItem; class LLScrollContainer; class LLTextBox; class LLThumbnailsObserver; +class LLThumbnailCtrl; class LLGalleryGestureObserver; class LLInventoryGalleryContextMenu; @@ -246,6 +247,7 @@ private: int mRowCount; int mItemsAddedCount; bool mGalleryCreated; + bool mLoadThumbnailsImmediately; bool mNeedsArrange; /* Params */ @@ -342,6 +344,7 @@ public: LLAssetType::EType getAssetType() { return mType; } void setThumbnail(LLUUID id); void setGallery(LLInventoryGallery* gallery) { mGallery = gallery; } + void setLoadImmediately(bool val); bool isFolder() { return mIsFolder; } bool isLink() { return mIsLink; } EInventorySortGroup getSortGroup() { return mSortGroup; } @@ -354,6 +357,7 @@ private: LLUUID mUUID; LLTextBox* mNameText; LLPanel* mTextBgPanel; + LLThumbnailCtrl* mThumbnailCtrl; bool mSelected; bool mWorn; bool mDefaultImage; diff --git a/indra/newview/llthumbnailctrl.cpp b/indra/newview/llthumbnailctrl.cpp index 72818cf991..78204204af 100644 --- a/indra/newview/llthumbnailctrl.cpp +++ b/indra/newview/llthumbnailctrl.cpp @@ -57,6 +57,8 @@ LLThumbnailCtrl::LLThumbnailCtrl(const LLThumbnailCtrl::Params& p) , mFallbackImagep(p.fallback_image) , mInteractable(p.interactable()) , mShowLoadingPlaceholder(p.show_loading()) +, mInited(false) +, mInitImmediately(true) { mLoadingPlaceholderString = LLTrans::getString("texture_loading"); @@ -83,6 +85,10 @@ LLThumbnailCtrl::~LLThumbnailCtrl() void LLThumbnailCtrl::draw() { + if (!mInited) + { + initImage(); + } LLRect draw_rect = getLocalRect(); if (mBorderVisible) @@ -170,11 +176,19 @@ void LLThumbnailCtrl::draw() LLUICtrl::draw(); } +void LLThumbnailCtrl::setVisible(BOOL visible) +{ + if (!visible && mInited) + { + unloadImage(); + } + LLUICtrl::setVisible(visible); +} + void LLThumbnailCtrl::clearTexture() { - mImageAssetID = LLUUID::null; - mTexturep = nullptr; - mImagep = nullptr; + setValue(LLSD()); + mInited = true; // nothing to do } // virtual @@ -190,33 +204,56 @@ void LLThumbnailCtrl::setValue(const LLSD& value) LLUICtrl::setValue(tvalue); - mImageAssetID = LLUUID::null; - mTexturep = nullptr; - mImagep = nullptr; - - if (tvalue.isUUID()) - { + unloadImage(); + + if (mInitImmediately) + { + initImage(); + } +} + +BOOL LLThumbnailCtrl::handleHover(S32 x, S32 y, MASK mask) +{ + if (mInteractable && getEnabled()) + { + getWindow()->setCursor(UI_CURSOR_HAND); + return TRUE; + } + return LLUICtrl::handleHover(x, y, mask); +} + +void LLThumbnailCtrl::initImage() +{ + if (mInited) + { + return; + } + mInited = true; + LLSD tvalue = getValue(); + + if (tvalue.isUUID()) + { mImageAssetID = tvalue.asUUID(); if (mImageAssetID.notNull()) { // Should it support baked textures? mTexturep = LLViewerTextureManager::getFetchedTexture(mImageAssetID, FTT_DEFAULT, MIPMAP_YES, LLGLTexture::BOOST_THUMBNAIL); - + mTexturep->forceToSaveRawImage(0); - + S32 desired_draw_width = mTexturep->getWidth(); S32 desired_draw_height = mTexturep->getHeight(); - + mTexturep->setKnownDrawSize(desired_draw_width, desired_draw_height); } - } + } else if (tvalue.isString()) { mImagep = LLUI::getUIImage(tvalue.asString(), LLGLTexture::BOOST_UI); if (mImagep) { LLViewerFetchedTexture* texture = dynamic_cast(mImagep->getImage().get()); - if(texture) + if (texture) { mImageAssetID = texture->getID(); } @@ -224,14 +261,12 @@ void LLThumbnailCtrl::setValue(const LLSD& value) } } -BOOL LLThumbnailCtrl::handleHover(S32 x, S32 y, MASK mask) +void LLThumbnailCtrl::unloadImage() { - if (mInteractable && getEnabled()) - { - getWindow()->setCursor(UI_CURSOR_HAND); - return TRUE; - } - return LLUICtrl::handleHover(x, y, mask); + mImageAssetID = LLUUID::null; + mTexturep = nullptr; + mImagep = nullptr; + mInited = false; } diff --git a/indra/newview/llthumbnailctrl.h b/indra/newview/llthumbnailctrl.h index 70f56c429c..f84a583271 100644 --- a/indra/newview/llthumbnailctrl.h +++ b/indra/newview/llthumbnailctrl.h @@ -64,16 +64,24 @@ public: virtual ~LLThumbnailCtrl(); virtual void draw() override; + void setVisible(BOOL visible) override; virtual void setValue(const LLSD& value ) override; + void setInitImmediately(bool val) { mInitImmediately = val; } void clearTexture(); virtual BOOL handleHover(S32 x, S32 y, MASK mask) override; + +protected: + void initImage(); + void unloadImage(); private: bool mBorderVisible; bool mInteractable; bool mShowLoadingPlaceholder; + bool mInited; + bool mInitImmediately; std::string mLoadingPlaceholderString; LLUUID mImageAssetID; LLViewBorder* mBorder; -- cgit v1.2.3