From aad49bd41461269bc3294df73050a2dd4fc76fe1 Mon Sep 17 00:00:00 2001 From: Rye Date: Sun, 11 Jan 2026 13:09:02 -0500 Subject: Introduced Tracy instrumentation to app initialization --- indra/newview/llviewermenu.cpp | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'indra/newview/llviewermenu.cpp') diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index f29760c824..5af6a41c11 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -473,6 +473,8 @@ void check_merchant_status(bool force) void init_menus() { + LL_PROFILE_ZONE_SCOPED; + // Initialize actions initialize_menus(); @@ -9689,6 +9691,8 @@ void initialize_spellcheck_menu() void initialize_menus() { + LL_PROFILE_ZONE_SCOPED; + // A parameterized event handler used as ctrl-8/9/0 zoom controls below. class LLZoomer : public view_listener_t { -- cgit v1.3 From 76a80b6787290dc8a950b43b67e5b4cd6238014f Mon Sep 17 00:00:00 2001 From: Rye Date: Sat, 10 Jan 2026 04:54:16 -0500 Subject: Replace usage of remaining boost::unordered containers with std Replace LLUUID and LLMaterialID container hashing functions with more collision resistant versions Utilize boost::hash_combine for TEMaterialPair to generate good hash distribution Generalize is_in_map and get_if_there for usage with all mapped types --- indra/llcommon/llpounceable.h | 4 +- indra/llcommon/llsingleton.h | 4 +- indra/llcommon/llstaticstringtable.h | 5 +- indra/llcommon/llstl.h | 18 +++---- indra/llcommon/lluuid.h | 19 ++++++-- indra/llprimitive/llmaterialid.h | 30 +++++++----- indra/llrender/llfontfreetype.h | 5 +- indra/llrender/llgl.cpp | 6 +-- indra/llrender/llgl.h | 4 +- indra/newview/llmaterialmgr.h | 76 +++++++++++++----------------- indra/newview/llmeshrepository.h | 2 +- indra/newview/llperfstats.h | 2 +- indra/newview/llviewermenu.cpp | 8 ++-- indra/newview/llviewerprecompiledheaders.h | 2 - 14 files changed, 97 insertions(+), 88 deletions(-) (limited to 'indra/newview/llviewermenu.cpp') diff --git a/indra/llcommon/llpounceable.h b/indra/llcommon/llpounceable.h index e86098f20b..20561b0c65 100644 --- a/indra/llcommon/llpounceable.h +++ b/indra/llcommon/llpounceable.h @@ -38,9 +38,9 @@ #include "llsingleton.h" #include #include -#include #include +#include #include // Forward declare the user template, since we want to be able to point to it @@ -86,7 +86,7 @@ class LLPounceableQueueSingleton: // instance will call on the SAME LLPounceableQueueSingleton instance -- // given how class statics work. We must keep a separate queue for each // LLPounceable instance. Use a hash map for that. - typedef boost::unordered_map map_t; + typedef std::unordered_map map_t; public: // Disambiguate queues belonging to different LLPounceables. diff --git a/indra/llcommon/llsingleton.h b/indra/llcommon/llsingleton.h index 3fba8602ee..e6989211ae 100644 --- a/indra/llcommon/llsingleton.h +++ b/indra/llcommon/llsingleton.h @@ -25,10 +25,10 @@ #ifndef LLSINGLETON_H #define LLSINGLETON_H -#include #include #include #include +#include #include #include "mutex.h" #include "lockstatic.h" @@ -61,7 +61,7 @@ private: static vec_t dep_sort(); // we directly depend on these other LLSingletons - typedef boost::unordered_set set_t; + typedef std::unordered_set set_t; set_t mDepends; protected: diff --git a/indra/llcommon/llstaticstringtable.h b/indra/llcommon/llstaticstringtable.h index 66ba3487c4..edff955ee7 100644 --- a/indra/llcommon/llstaticstringtable.h +++ b/indra/llcommon/llstaticstringtable.h @@ -29,9 +29,10 @@ #define LL_STATIC_STRING_TABLE_H #include "lldefs.h" -#include #include "llstl.h" +#include + class LLStaticHashedString { public: @@ -74,7 +75,7 @@ struct LLStaticStringHasher template< typename MappedObject > class LL_COMMON_API LLStaticStringTable - : public boost::unordered_map< LLStaticHashedString, MappedObject, LLStaticStringHasher > + : public std::unordered_map< LLStaticHashedString, MappedObject, LLStaticStringHasher > { }; diff --git a/indra/llcommon/llstl.h b/indra/llcommon/llstl.h index 7d41c42ba7..9f3587886c 100644 --- a/indra/llcommon/llstl.h +++ b/indra/llcommon/llstl.h @@ -229,12 +229,10 @@ void delete_and_clear_array(T*& ptr) template inline typename T::mapped_type get_ptr_in_map(const T& inmap, typename T::key_type const& key) { - // Typedef here avoids warnings because of new c++ naming rules. - typedef typename T::const_iterator map_iter; - map_iter iter = inmap.find(key); + auto iter = inmap.find(key); if(iter == inmap.end()) { - return NULL; + return nullptr; } else { @@ -243,8 +241,8 @@ inline typename T::mapped_type get_ptr_in_map(const T& inmap, typename T::key_ty }; // helper function which returns true if key is in inmap. -template -inline bool is_in_map(const std::map& inmap, const K& key) +template +inline bool is_in_map(const T& inmap, typename T::key_type const& key) { if(inmap.find(key) == inmap.end()) { @@ -260,12 +258,10 @@ inline bool is_in_map(const std::map& inmap, const K& key) // To replace LLSkipMap getIfThere, use: // get_if_there(map, key, 0) // WARNING: Make sure default_value (generally 0) is not a valid map entry! -template -inline T get_if_there(const std::map& inmap, const K& key, T default_value) +template +inline typename T::mapped_type get_if_there(const T& inmap, typename T::key_type const& key, typename T::mapped_type default_value) { - // Typedef here avoids warnings because of new c++ naming rules. - typedef typename std::map::const_iterator map_iter; - map_iter iter = inmap.find(key); + auto iter = inmap.find(key); if(iter == inmap.end()) { return default_value; diff --git a/indra/llcommon/lluuid.h b/indra/llcommon/lluuid.h index ca1cf03c4d..f91aadccc0 100644 --- a/indra/llcommon/lluuid.h +++ b/indra/llcommon/lluuid.h @@ -26,6 +26,7 @@ #ifndef LL_LLUUID_H #define LL_LLUUID_H +#include #include #include #include @@ -176,15 +177,27 @@ namespace std { inline size_t operator()(const LLUUID& id) const noexcept { - return (size_t)id.getDigest64(); + size_t h = 0; + // Golden ratio hash with avalanche mixing + // Process 8 bytes at a time by manually constructing 64-bit values + // Shift by 31: mixes upper half into lower half for better bit distribution + // Shift by 47: ensures highest bits influence final hash output + for (int i = 0; i < UUID_BYTES; i += 8) { + size_t chunk = (size_t)id.mData[i] | ((size_t)id.mData[i+1] << 8) | + ((size_t)id.mData[i+2] << 16) | ((size_t)id.mData[i+3] << 24) | + ((size_t)id.mData[i+4] << 32) | ((size_t)id.mData[i+5] << 40) | + ((size_t)id.mData[i+6] << 48) | ((size_t)id.mData[i+7] << 56); + h ^= (chunk * 0x9e3779b97f4a7c15ULL) ^ (h >> 31) ^ (h >> 47); + } + return h; } }; } -// For use with boost containers. +// For use with boost::container_hash inline size_t hash_value(const LLUUID& id) noexcept { - return (size_t)id.getDigest64(); + return std::hash{}(id); } #endif // LL_LLUUID_H diff --git a/indra/llprimitive/llmaterialid.h b/indra/llprimitive/llmaterialid.h index bd6256d961..41dd5a8710 100644 --- a/indra/llprimitive/llmaterialid.h +++ b/indra/llprimitive/llmaterialid.h @@ -67,15 +67,11 @@ public: static const LLMaterialID null; - // Returns a 64 bits digest of the material Id, by XORing its two 64 bits - // long words. HB - inline U64 getDigest64() const - { - U64* tmp = (U64*)mID; - return tmp[0] ^ tmp[1]; - } - private: + // definitions follow class + friend std::hash; + friend size_t hash_value(const LLMaterialID&) noexcept; + void parseFromBinary(const LLSD::Binary& pMaterialID); void copyFromOtherMaterialID(const LLMaterialID& pOtherMaterialID); int compareToOtherMaterialID(const LLMaterialID& pOtherMaterialID) const; @@ -90,15 +86,27 @@ namespace std { inline size_t operator()(const LLMaterialID& id) const noexcept { - return (size_t)id.getDigest64(); + size_t h = 0; + // Golden ratio hash with avalanche mixing + // Process 8 bytes at a time by manually constructing 64-bit values + // Shift by 31: mixes upper half into lower half for better bit distribution + // Shift by 47: ensures highest bits influence final hash output + for (int i = 0; i < MATERIAL_ID_SIZE; i += 8) { + size_t chunk = (size_t)id.mID[i] | ((size_t)id.mID[i + 1] << 8) | + ((size_t)id.mID[i+2] << 16) | ((size_t)id.mID[i+3] << 24) | + ((size_t)id.mID[i+4] << 32) | ((size_t)id.mID[i+5] << 40) | + ((size_t)id.mID[i + 6] << 48) | ((size_t)id.mID[i + 7] << 56); + h ^= (chunk * 0x9e3779b97f4a7c15ULL) ^ (h >> 31) ^ (h >> 47); + } + return h; } }; } -// For use with boost containers. +// For use with boost::container_hash inline size_t hash_value(const LLMaterialID& id) noexcept { - return (size_t)id.getDigest64(); + return std::hash{}(id); } #endif // LL_LLMATERIALID_H diff --git a/indra/llrender/llfontfreetype.h b/indra/llrender/llfontfreetype.h index a9b3a944ee..f7600e40a3 100644 --- a/indra/llrender/llfontfreetype.h +++ b/indra/llrender/llfontfreetype.h @@ -27,13 +27,14 @@ #ifndef LL_LLFONTFREETYPE_H #define LL_LLFONTFREETYPE_H -#include #include "llpointer.h" #include "llstl.h" #include "llimagegl.h" #include "llfontbitmapcache.h" +#include + // Hack. FT_Face is just a typedef for a pointer to a struct, // but there's no simple forward declarations file for FreeType, // and the main include file is 200K. @@ -184,7 +185,7 @@ private: fallback_font_vector_t mFallbackFonts; // A list of fallback fonts to look for glyphs in (for Unicode chars) // *NOTE: the same glyph can be present with multiple representations (but the pointer is always unique) - typedef boost::unordered_multimap char_glyph_info_map_t; + typedef std::unordered_multimap char_glyph_info_map_t; mutable char_glyph_info_map_t mCharGlyphInfoMap; // Information about glyph location in bitmap mutable LLFontBitmapCache* mFontBitmapCachep; diff --git a/indra/llrender/llgl.cpp b/indra/llrender/llgl.cpp index d13b98e274..4584ed1d86 100644 --- a/indra/llrender/llgl.cpp +++ b/indra/llrender/llgl.cpp @@ -2376,7 +2376,7 @@ void clear_glerror() // // Static members -boost::unordered_map LLGLState::sStateMap; +std::unordered_map LLGLState::sStateMap; GLboolean LLGLDepthTest::sDepthEnabled = GL_FALSE; // OpenGL default GLenum LLGLDepthTest::sDepthFunc = GL_LESS; // OpenGL default @@ -2419,7 +2419,7 @@ void LLGLState::resetTextureStates() void LLGLState::dumpStates() { LL_INFOS("RenderState") << "GL States:" << LL_ENDL; - for (boost::unordered_map::iterator iter = sStateMap.begin(); + for (std::unordered_map::iterator iter = sStateMap.begin(); iter != sStateMap.end(); ++iter) { LL_INFOS("RenderState") << llformat(" 0x%04x : %s",(S32)iter->first,iter->second?"true":"false") << LL_ENDL; @@ -2451,7 +2451,7 @@ void LLGLState::checkStates(GLboolean writeAlpha) //llassert_always(colorMask[2]); // llassert_always(colorMask[3] == writeAlpha); - for (boost::unordered_map::iterator iter = sStateMap.begin(); + for (std::unordered_map::iterator iter = sStateMap.begin(); iter != sStateMap.end(); ++iter) { LLGLenum state = iter->first; diff --git a/indra/llrender/llgl.h b/indra/llrender/llgl.h index d19825d9ca..e1ab2a49e6 100644 --- a/indra/llrender/llgl.h +++ b/indra/llrender/llgl.h @@ -31,7 +31,7 @@ #include #include -#include +#include #include #include "llerror.h" @@ -246,7 +246,7 @@ public: static void checkStates(GLboolean writeAlpha = GL_TRUE); protected: - static boost::unordered_map sStateMap; + static std::unordered_map sStateMap; public: enum { CURRENT_STATE = -2, DISABLED_STATE = 0, ENABLED_STATE = 1 }; diff --git a/indra/newview/llmaterialmgr.h b/indra/newview/llmaterialmgr.h index 1279b77ad4..c04f874923 100644 --- a/indra/newview/llmaterialmgr.h +++ b/indra/newview/llmaterialmgr.h @@ -33,9 +33,42 @@ #include "httprequest.h" #include "httpheaders.h" #include "httpoptions.h" +#include class LLViewerRegion; +// struct for TE-specific material ID query +class TEMaterialPair +{ +public: + U32 te; + LLMaterialID materialID; + + bool operator==(const TEMaterialPair& b) const { return (materialID == b.materialID) && (te == b.te); } +}; + +inline bool operator<(const TEMaterialPair& lhs, const TEMaterialPair& rhs) +{ + return (lhs.te < rhs.te) ? true : (lhs.materialID < rhs.materialID); +} + +// std::hash implementation for TEMaterialPair +namespace std +{ + template<> + struct hash + { + inline size_t operator()(const TEMaterialPair& p) const noexcept + { + // Utilize boost::hash_combine to generate a good hash + size_t seed = 0; + boost::hash_combine(seed, p.te + 1); + boost::hash_combine(seed, p.materialID); + return seed; + } + }; +} // namespace std + class LLMaterialMgr : public LLSingleton { LLSINGLETON(LLMaterialMgr); @@ -83,29 +116,6 @@ private: void onRegionRemoved(LLViewerRegion* regionp); private: - // struct for TE-specific material ID query - class TEMaterialPair - { - public: - - U32 te; - LLMaterialID materialID; - - bool operator==(const TEMaterialPair& b) const { return (materialID == b.materialID) && (te == b.te); } - }; - - // definitions follow class - friend std::hash; - friend size_t hash_value(const TEMaterialPair&) noexcept; - - friend inline bool operator<( - const LLMaterialMgr::TEMaterialPair& lhs, - const LLMaterialMgr::TEMaterialPair& rhs) - { - return (lhs.te < rhs.te) ? true : - (lhs.materialID < rhs.materialID); - } - typedef std::set material_queue_t; typedef std::map get_queue_t; typedef std::pair pending_material_t; @@ -113,7 +123,7 @@ private: typedef std::map get_callback_map_t; - typedef boost::unordered_map get_callback_te_map_t; + typedef std::unordered_map get_callback_te_map_t; typedef std::set getall_queue_t; typedef std::map getall_pending_map_t; typedef std::map getall_callback_map_t; @@ -142,23 +152,5 @@ private: U32 getMaxEntries(const LLViewerRegion* regionp); }; -// std::hash implementation for TEMaterialPair -namespace std -{ - template<> struct hash - { - inline size_t operator()(const LLMaterialMgr::TEMaterialPair& p) const noexcept - { - return size_t((p.te + 1) * p.materialID.getDigest64()); - } - }; -} - -// For use with boost containers. -inline size_t hash_value(const LLMaterialMgr::TEMaterialPair& p) noexcept -{ - return size_t((p.te + 1) * p.materialID.getDigest64()); -} - #endif // LL_LLMATERIALMGR_H diff --git a/indra/newview/llmeshrepository.h b/indra/newview/llmeshrepository.h index 56ad8297c7..061b4b5428 100644 --- a/indra/newview/llmeshrepository.h +++ b/indra/newview/llmeshrepository.h @@ -442,7 +442,7 @@ public: LLCondition* mSignal; //map of known mesh headers - typedef boost::unordered_map mesh_header_map; // pair is header_size and data + typedef std::unordered_map mesh_header_map; // pair is header_size and data mesh_header_map mMeshHeader; class HeaderRequest : public RequestStats diff --git a/indra/newview/llperfstats.h b/indra/newview/llperfstats.h index 1a2098ec7e..38deb87237 100644 --- a/indra/newview/llperfstats.h +++ b/indra/newview/llperfstats.h @@ -223,7 +223,7 @@ namespace LLPerfStats static void updateMeanFrameTime(U64 tot_frame_time_raw); // StatsArray is a uint64_t for each possible statistic type. using StatsArray = std::array(LLPerfStats::StatType_t::STATS_COUNT)>; - using StatsMap = std::unordered_map>; + using StatsMap = std::unordered_map; using StatsTypeMatrix = std::array(LLPerfStats::ObjType_t::OT_COUNT)>; using StatsSummaryArray = std::array(LLPerfStats::ObjType_t::OT_COUNT)>; diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index 5af6a41c11..f88f49d8d7 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -140,7 +140,7 @@ #include "llwindow.h" #include "llpathfindingmanager.h" #include "llstartup.h" -#include "boost/unordered_map.hpp" +#include #include #include #include @@ -153,7 +153,7 @@ using namespace LLAvatarAppearanceDefines; typedef LLPointer LLViewerObjectPtr; -static boost::unordered_map sDefaultItemLabels; +static std::unordered_map sDefaultItemLabels; LLVOAvatar* find_avatar_from_object(LLViewerObject* object); LLVOAvatar* find_avatar_from_object(const LLUUID& object_id); @@ -2965,7 +2965,7 @@ void handle_object_show_original() static void init_default_item_label(LLUICtrl* ctrl) { const std::string& item_name = ctrl->getName(); - boost::unordered_map::iterator it = sDefaultItemLabels.find(item_name); + std::unordered_map::iterator it = sDefaultItemLabels.find(item_name); if (it == sDefaultItemLabels.end()) { // *NOTE: This will not work for items of type LLMenuItemCheckGL because they return boolean value @@ -2981,7 +2981,7 @@ static void init_default_item_label(LLUICtrl* ctrl) static LLStringExplicit get_default_item_label(const std::string& item_name) { LLStringExplicit res(""); - boost::unordered_map::iterator it = sDefaultItemLabels.find(item_name); + std::unordered_map::iterator it = sDefaultItemLabels.find(item_name); if (it != sDefaultItemLabels.end()) { res = it->second; diff --git a/indra/newview/llviewerprecompiledheaders.h b/indra/newview/llviewerprecompiledheaders.h index f6ee00cb25..d33d426769 100644 --- a/indra/newview/llviewerprecompiledheaders.h +++ b/indra/newview/llviewerprecompiledheaders.h @@ -126,8 +126,6 @@ #include "llfloater.h" #include -#include -#include #include #include "glm/glm.hpp" -- cgit v1.3 From b5a57a7c283d50001ec5ae221e9cb9ecd061c975 Mon Sep 17 00:00:00 2001 From: Rye Date: Sun, 11 Jan 2026 13:09:42 -0500 Subject: Reduce tens of thousands of recursive calls during menu initialization --- indra/newview/llviewermenu.cpp | 17 ++++++----------- indra/newview/llviewerwindow.cpp | 6 ++---- indra/newview/llviewerwindow.h | 6 ++++++ 3 files changed, 14 insertions(+), 15 deletions(-) (limited to 'indra/newview/llviewermenu.cpp') diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index f88f49d8d7..1b496ccd27 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -413,7 +413,7 @@ static LLSLMMenuUpdater* gSLMMenuUpdater = NULL; LLSLMMenuUpdater::LLSLMMenuUpdater() { - mMarketplaceListingsItem = gMenuHolder->getChild("MarketplaceListings")->getHandle(); + mMarketplaceListingsItem = gMenuHolder->getChild("Me")->getChild("MarketplaceListings")->getHandle(); } void LLSLMMenuUpdater::setMerchantMenu() { @@ -551,7 +551,7 @@ void init_menus() color = LLUIColorTable::instance().getColor( "MenuNonProductionBgColor" ); } - LLView* menu_bar_holder = gViewerWindow->getRootView()->getChildView("menu_bar_holder"); + LLView* menu_bar_holder = gViewerWindow->getMainView()->findChildView("menu_stack")->findChildView("status_bar_container")->getChildView("menu_bar_holder"); gMenuBarView = LLUICtrlFactory::getInstance()->createFromFile("menu_viewer.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); gMenuBarView->setRect(LLRect(0, menu_bar_holder->getRect().mTop, 0, menu_bar_holder->getRect().mTop - MENU_BAR_HEIGHT)); @@ -565,8 +565,10 @@ void init_menus() // *TODO:Also fix cost in llfolderview.cpp for Inventory menus const std::string sound_upload_cost_str = std::to_string(LLAgentBenefitsMgr::current().getSoundUploadCost()); const std::string animation_upload_cost_str = std::to_string(LLAgentBenefitsMgr::current().getAnimationUploadCost()); - gMenuHolder->childSetLabelArg("Upload Sound", "[COST]", sound_upload_cost_str); - gMenuHolder->childSetLabelArg("Upload Animation", "[COST]", animation_upload_cost_str); + + LLView* main_upload_menu = gMenuHolder->findChild("Upload"); + main_upload_menu->findChild("Upload Sound")->setLabelArg("[COST]", sound_upload_cost_str); + main_upload_menu->findChild("Upload Animation")->setLabelArg("[COST]", animation_upload_cost_str); gAttachSubMenu = gMenuBarView->findChildMenuByName("Attach Object", true); gDetachSubMenu = gMenuBarView->findChildMenuByName("Detach Object", true); @@ -574,13 +576,6 @@ void init_menus() gDetachAvatarMenu = gMenuHolder->getChild("Avatar Detach", true); gDetachHUDAvatarMenu = gMenuHolder->getChild("Avatar Detach HUD", true); - // Don't display the Memory console menu if the feature is turned off - LLMenuItemCheckGL *memoryMenu = gMenuBarView->getChild("Memory", true); - if (memoryMenu) - { - memoryMenu->setVisible(false); - } - gMenuBarView->createJumpKeys(); // Let land based option enable when parcel changes diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index ee7b1fb693..725178c1b9 100644 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -2075,10 +2075,6 @@ void LLViewerWindow::initGLDefaults() gBox.prerender(); } -struct MainPanel : public LLPanel -{ -}; - void LLViewerWindow::initBase() { S32 height = getWindowHeightScaled(); @@ -2117,6 +2113,8 @@ void LLViewerWindow::initBase() main_view->setShape(full_window); getRootView()->addChild(main_view); + mMainView = main_view; + // placeholder widget that controls where "world" is rendered mWorldViewPlaceholder = main_view->getChildView("world_view_rect")->getHandle(); mPopupView = main_view->getChild("popup_holder"); diff --git a/indra/newview/llviewerwindow.h b/indra/newview/llviewerwindow.h index f3c7ef3289..da2371f6fe 100644 --- a/indra/newview/llviewerwindow.h +++ b/indra/newview/llviewerwindow.h @@ -144,6 +144,10 @@ private: }; +struct MainPanel : public LLPanel +{ +}; + static const U32 MAX_SNAPSHOT_IMAGE_SIZE = 7680; // max snapshot image size 7680 * 7680 UHDTV2 class LLViewerWindow : public LLWindowCallbacks @@ -248,6 +252,7 @@ public: // ACCESSORS // LLRootView* getRootView() const; + MainPanel* getMainView() const { return mMainView; } // 3D world area in scaled pixels (via UI scale), use for most UI computations LLRect getWorldViewRectScaled() const; @@ -501,6 +506,7 @@ private: LLRect mWorldViewRectRaw; // area of screen for 3D world LLRect mWorldViewRectScaled; // area of screen for 3D world scaled by UI size LLRootView* mRootView; // a view of size mWindowRectRaw, containing all child views + MainPanel* mMainView; // a view of size mWindowRectRaw, directly containing the base elements of the ui tree LLView* mFloaterSnapRegion = nullptr; LLView* mNavBarContainer = nullptr; LLPanel* mStatusBarContainer = nullptr; -- cgit v1.3 From 0b2f7fcc6b67f629b41a804f77214d51497127a7 Mon Sep 17 00:00:00 2001 From: Rye Date: Mon, 12 Jan 2026 18:33:39 -0500 Subject: Address feedback from review Move LLSD string->real conversion function to shared impl and utilize in xml parsing Introducing additional error handling to menu init Cleanup comments and trace tagging Remove dead Memory menu entry --- indra/llcommon/llsd.cpp | 29 +++++---- indra/llcommon/llsd.h | 2 + indra/llcommon/llsdserialize_xml.cpp | 37 ++++-------- indra/newview/llinventorymodel.cpp | 2 +- indra/newview/llviewermenu.cpp | 69 ++++++++++++++++++++-- indra/newview/skins/default/xui/en/menu_viewer.xml | 12 ---- 6 files changed, 95 insertions(+), 56 deletions(-) (limited to 'indra/newview/llviewermenu.cpp') diff --git a/indra/llcommon/llsd.cpp b/indra/llcommon/llsd.cpp index 6bc2841081..ce39bc7af3 100644 --- a/indra/llcommon/llsd.cpp +++ b/indra/llcommon/llsd.cpp @@ -351,18 +351,7 @@ namespace LLSD::Real ImplString::asReal() const { - F64 v = 0.0; - boost::iostreams::stream i_stream(mValue.data(), mValue.size()); - i_stream >> v; - - // we would probably like to ignore all trailing whitespace as - // well, but for now, simply eat the next character, and make - // sure we reached the end of the string. - // *NOTE: gcc 2.95 does not generate an eof() event on the - // stream operation above, so we manually get here to force it - // across platforms. - int c = i_stream.get(); - return ((EOF ==c) ? v : 0.0); + return llsd::string_to_real(mValue); } @@ -1264,6 +1253,22 @@ LLSD::reverse_array_iterator LLSD::rendArray() { return makeArray(impl) namespace llsd { +LLSD::Real string_to_real(std::string_view in_string) +{ + LLSD::Real v = 0.0; + boost::iostreams::stream i_stream(in_string.data(), in_string.size()); + i_stream >> v; + + // we would probably like to ignore all trailing whitespace as + // well, but for now, simply eat the next character, and make + // sure we reached the end of the string. + // *NOTE: gcc 2.95 does not generate an eof() event on the + // stream operation above, so we manually get here to force it + // across platforms. + int c = i_stream.get(); + return ((EOF == c) ? v : 0.0); +} + U32 allocationCount() { return LLSD::Impl::sAllocationCount; } U32 outstandingCount() { return LLSD::Impl::sOutstandingCount; } diff --git a/indra/llcommon/llsd.h b/indra/llcommon/llsd.h index c62f2ef1ca..afe35a65ba 100644 --- a/indra/llcommon/llsd.h +++ b/indra/llcommon/llsd.h @@ -545,6 +545,8 @@ LL_COMMON_API std::ostream& operator<<(std::ostream& s, const LLSD& llsd); namespace llsd { + // Used by LLSD::ImplString to convert string type to real + LLSD::Real string_to_real(std::string_view in_string); #ifdef LLSD_DEBUG_INFO /** @name Unit Testing Interface */ diff --git a/indra/llcommon/llsdserialize_xml.cpp b/indra/llcommon/llsdserialize_xml.cpp index c28efa3aad..f399c51608 100644 --- a/indra/llcommon/llsdserialize_xml.cpp +++ b/indra/llcommon/llsdserialize_xml.cpp @@ -712,7 +712,7 @@ void LLSDXMLParser::Impl::endElementHandler(const XML_Char* name) case ELEMENT_KEY: mCurrentKey = std::move(mCurrentContent); // This is safe to move as we are in the end element handler - mCurrentContent.clear(); // Clear to reset to valid state + mCurrentContent.clear(); // Ensure mCurrentContent is empty for subsequent use return; default: @@ -745,38 +745,21 @@ void LLSDXMLParser::Impl::endElementHandler(const XML_Char* name) } else { - // This implementation is copied from llsd.cpp - F64 v = 0.0; - boost::iostreams::stream i_stream(mCurrentContent.data(), mCurrentContent.size()); - i_stream >> v; - - // we would probably like to ignore all trailing whitespace as - // well, but for now, simply eat the next character, and make - // sure we reached the end of the string. - // *NOTE: gcc 2.95 does not generate an eof() event on the - // stream operation above, so we manually get here to force it - // across platforms. - int c = i_stream.get(); - value = (int)((EOF == c) ? v : 0.0); + // This must treat "1.23" not as an error, but as a number, which is + // then truncated down to an integer. Hence, this code doesn't call + // std::istringstream::operator>>(int&), which would not consume the + // ".23" portion. + + // Utilizes implementation used internally by LLSD::ImplString::asInteger + value = (int)llsd::string_to_real(mCurrentContent); } } break; case ELEMENT_REAL: { - // This implementation is copied from llsd.cpp - F64 v = 0.0; - boost::iostreams::stream i_stream(mCurrentContent.data(), mCurrentContent.size()); - i_stream >> v; - - // we would probably like to ignore all trailing whitespace as - // well, but for now, simply eat the next character, and make - // sure we reached the end of the string. - // *NOTE: gcc 2.95 does not generate an eof() event on the - // stream operation above, so we manually get here to force it - // across platforms. - int c = i_stream.get(); - value = ((EOF == c) ? v : 0.0); + // Utilizes implementation used internally by LLSD::ImplString::asReal + value = llsd::string_to_real(mCurrentContent); // removed since this breaks when locale has decimal separator that isn't '.' // investigated changing local to something compatible each time but deemed higher diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp index e80c506bc0..c2f9c483c0 100644 --- a/indra/newview/llinventorymodel.cpp +++ b/indra/newview/llinventorymodel.cpp @@ -3456,7 +3456,7 @@ bool LLInventoryModel::loadFromFile(const std::string& filename, } { - LL_PROFILE_ZONE_NAMED("inventory load from file - categories"); + LL_PROFILE_ZONE_NAMED("inventory load from file - items"); const LLSD& llsd_items = inventory["items"]; if (llsd_items.isArray()) { diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index 1b496ccd27..5799e23ca5 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -413,7 +413,23 @@ static LLSLMMenuUpdater* gSLMMenuUpdater = NULL; LLSLMMenuUpdater::LLSLMMenuUpdater() { - mMarketplaceListingsItem = gMenuHolder->getChild("Me")->getChild("MarketplaceListings")->getHandle(); + LLView* me_menu = gMenuHolder->findChild("Me"); + if (!me_menu) + { + LLError::LLUserWarningMsg::showMissingFiles(); + LL_ERRS() << "Can't find 'Me' menu in 'menu_viewer'" << LL_ENDL; + return; + } + + LLView* marketplace_listings = me_menu->findChild("MarketplaceListings"); + if (!marketplace_listings) + { + LLError::LLUserWarningMsg::showMissingFiles(); + LL_ERRS() << "Can't find 'MarketplaceListings' in 'Me' menu" << LL_ENDL; + return; + } + + mMarketplaceListingsItem = marketplace_listings->getHandle(); } void LLSLMMenuUpdater::setMerchantMenu() { @@ -551,7 +567,29 @@ void init_menus() color = LLUIColorTable::instance().getColor( "MenuNonProductionBgColor" ); } - LLView* menu_bar_holder = gViewerWindow->getMainView()->findChildView("menu_stack")->findChildView("status_bar_container")->getChildView("menu_bar_holder"); + LLView* menu_stack = gViewerWindow->getMainView()->findChildView("menu_stack"); + if (!menu_stack) + { + LLError::LLUserWarningMsg::showMissingFiles(); + LL_ERRS() << "Can't find menu_stack in main_view" << LL_ENDL; + return; + } + + LLView* status_bar_container = menu_stack->findChildView("status_bar_container"); + if (!status_bar_container) + { + LLError::LLUserWarningMsg::showMissingFiles(); + LL_ERRS() << "Can't find status_bar_container in main_view" << LL_ENDL; + return; + } + + LLView* menu_bar_holder = status_bar_container->findChildView("menu_bar_holder"); + if (!menu_bar_holder) + { + LLError::LLUserWarningMsg::showMissingFiles(); + LL_ERRS() << "Can't find status_bar_container in main_view" << LL_ENDL; + return; + } gMenuBarView = LLUICtrlFactory::getInstance()->createFromFile("menu_viewer.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); gMenuBarView->setRect(LLRect(0, menu_bar_holder->getRect().mTop, 0, menu_bar_holder->getRect().mTop - MENU_BAR_HEIGHT)); @@ -567,8 +605,31 @@ void init_menus() const std::string animation_upload_cost_str = std::to_string(LLAgentBenefitsMgr::current().getAnimationUploadCost()); LLView* main_upload_menu = gMenuHolder->findChild("Upload"); - main_upload_menu->findChild("Upload Sound")->setLabelArg("[COST]", sound_upload_cost_str); - main_upload_menu->findChild("Upload Animation")->setLabelArg("[COST]", animation_upload_cost_str); + if (!main_upload_menu) + { + LLError::LLUserWarningMsg::showMissingFiles(); + LL_ERRS() << "Can't find 'Upload' menu in 'menu_viewer'" << LL_ENDL; + return; + } + + LLView* upload_sound = main_upload_menu->findChild("Upload Sound"); + if (!upload_sound) + { + LLError::LLUserWarningMsg::showMissingFiles(); + LL_ERRS() << "Can't find 'Upload Sound' menu item in 'Upload' menu" << LL_ENDL; + return; + } + upload_sound->setLabelArg("[COST]", sound_upload_cost_str); + + LLView* upload_anim = main_upload_menu->findChild("Upload Animation"); + if (!upload_anim) + { + LLError::LLUserWarningMsg::showMissingFiles(); + LL_ERRS() << "Can't find 'Upload Animation' menu item in 'Upload' menu" << LL_ENDL; + return; + } + upload_anim->setLabelArg("[COST]", animation_upload_cost_str); + gAttachSubMenu = gMenuBarView->findChildMenuByName("Attach Object", true); gDetachSubMenu = gMenuBarView->findChildMenuByName("Detach Object", true); diff --git a/indra/newview/skins/default/xui/en/menu_viewer.xml b/indra/newview/skins/default/xui/en/menu_viewer.xml index c93cb7822e..ba43e80eda 100644 --- a/indra/newview/skins/default/xui/en/menu_viewer.xml +++ b/indra/newview/skins/default/xui/en/menu_viewer.xml @@ -2600,18 +2600,6 @@ function="World.EnvPreset" function="Advanced.ToggleConsole" parameter="fast timers" /> - - - - -- cgit v1.3