3535# include < sys/stat.h> // mkdir()
3636#endif
3737#include < memory> // std::unique_ptr
38+ #include < algorithm>
3839
3940#include " llviewermedia_streamingaudio.h"
4041#include " llaudioengine.h"
@@ -290,6 +291,7 @@ class LLAsyncInventorySkeletonLoader
290291 void markEssentialReady ();
291292 void markComplete ();
292293 void markFailed (const std::string& reason);
294+ bool hasFetchedCurrentOutfit () const ;
293295
294296 Phase mPhase = Phase::Idle;
295297 bool mForceAsync = false ;
@@ -302,6 +304,7 @@ class LLAsyncInventorySkeletonLoader
302304 std::set<LLUUID> mEssentialPending ;
303305
304306 U32 mMaxConcurrentFetches = 4 ;
307+ bool mSawCurrentOutfitFolder = false ;
305308
306309 LLFrameTimer mCapsTimer ;
307310 LLFrameTimer mFetchTimer ;
@@ -334,6 +337,10 @@ void LLAsyncInventorySkeletonLoader::reset()
334337 mFetchTimer .stop ();
335338 mTotalTimer .stop ();
336339 mEssentialTimer .stop ();
340+
341+ const U32 requested = gSavedSettings .getU32 (" AsyncInventoryMaxConcurrentFetches" );
342+ mMaxConcurrentFetches = std::clamp (requested, 1U , 8U );
343+ mSawCurrentOutfitFolder = false ;
337344}
338345
339346bool LLAsyncInventorySkeletonLoader::isRunning () const
@@ -352,6 +359,9 @@ void LLAsyncInventorySkeletonLoader::start(bool force_async)
352359 ensureCapsCallback ();
353360 ensureIdleCallback ();
354361
362+ LL_DEBUGS (" AppInit" ) << " Async skeleton loader concurrency limit set to "
363+ << mMaxConcurrentFetches << LL_ENDL;
364+
355365 if (AISAPI::isAvailable ())
356366 {
357367 LL_DEBUGS (" AppInit" ) << " Async skeleton loader detected AIS available at start; beginning fetch." << LL_ENDL;
@@ -606,6 +616,11 @@ void LLAsyncInventorySkeletonLoader::evaluateChildren(const FetchRequest& reques
606616 const bool child_is_library = request.mIsLibrary
607617 || (child->getOwnerID () == gInventory .getLibraryOwnerID ());
608618
619+ if (child->getPreferredType () == LLFolderType::FT_CURRENT_OUTFIT)
620+ {
621+ mSawCurrentOutfitFolder = true ;
622+ }
623+
609624 bool child_essential = false ;
610625 if (child->getUUID () == LLAppearanceMgr::instance ().getCOF ())
611626 {
@@ -648,6 +663,11 @@ void LLAsyncInventorySkeletonLoader::discoverEssentialFolders()
648663 continue ;
649664 }
650665
666+ if (type == LLFolderType::FT_CURRENT_OUTFIT)
667+ {
668+ mSawCurrentOutfitFolder = true ;
669+ }
670+
651671 LLViewerInventoryCategory* cat = gInventory .getCategory (cat_id);
652672 bool is_library = false ;
653673 if (cat)
@@ -668,6 +688,7 @@ void LLAsyncInventorySkeletonLoader::discoverEssentialFolders()
668688 && mQueuedCategories .count (cof_id) == 0
669689 && mActiveFetches .count (cof_id) == 0 )
670690 {
691+ mSawCurrentOutfitFolder = true ;
671692 enqueueFetch (cof_id, false , true , gInventory .getCachedCategoryVersion (cof_id));
672693 mEssentialPending .insert (cof_id);
673694 }
@@ -742,6 +763,33 @@ void LLAsyncInventorySkeletonLoader::markFailed(const std::string& reason)
742763 LL_WARNS (" AppInit" ) << " Async inventory skeleton loader failed: " << mFailureReason << LL_ENDL;
743764}
744765
766+ bool LLAsyncInventorySkeletonLoader::hasFetchedCurrentOutfit () const
767+ {
768+ if (!mSawCurrentOutfitFolder )
769+ {
770+ return true ;
771+ }
772+
773+ LLUUID cof_id = gInventory .findCategoryUUIDForType (LLFolderType::FT_CURRENT_OUTFIT);
774+ if (cof_id.isNull ())
775+ {
776+ return false ;
777+ }
778+
779+ if (mFetchedCategories .count (cof_id) == 0 )
780+ {
781+ return false ;
782+ }
783+
784+ const LLViewerInventoryCategory* cof = gInventory .getCategory (cof_id);
785+ if (!cof)
786+ {
787+ return false ;
788+ }
789+
790+ return cof->getVersion () != LLViewerInventoryCategory::VERSION_UNKNOWN;
791+ }
792+
745793void LLAsyncInventorySkeletonLoader::update ()
746794{
747795 if (mPhase == Phase::Idle || mPhase == Phase::Complete || mPhase == Phase::Failed)
@@ -766,7 +814,9 @@ void LLAsyncInventorySkeletonLoader::update()
766814
767815 processQueue ();
768816
769- if (!mEssentialReady && mEssentialPending .empty ())
817+ const bool current_outfit_ready = hasFetchedCurrentOutfit ();
818+
819+ if (!mEssentialReady && mEssentialPending .empty () && current_outfit_ready)
770820 {
771821 markEssentialReady ();
772822 }
0 commit comments