diff --git a/indra/llcommon/lluuid.cpp b/indra/llcommon/lluuid.cpp index c8d18e32c9..a40bb0a238 100644 --- a/indra/llcommon/lluuid.cpp +++ b/indra/llcommon/lluuid.cpp @@ -44,6 +44,7 @@ #include "lltimer.h" #include "llthread.h" #include "llmutex.h" +#include "llmd5.h" #include "hbxxh.h" #include "llprofiler.h" @@ -404,11 +405,16 @@ LLUUID LLUUID::operator^(const LLUUID& rhs) const return id; } +// WARNING: this algorithm SHALL NOT be changed. It is also used by the server +// and plays a role in some assets validation (e.g. clothing items). Changing +// it would cause invalid assets. void LLUUID::combine(const LLUUID& other, LLUUID& result) const { - HBXXH128 hash((const void*)mData, 16, false); // false = do not finalize - hash.update((const void*)other.mData, 16); - hash.digest(result); + LLMD5 md5_uuid; + md5_uuid.update((unsigned char*)mData, 16); + md5_uuid.update((unsigned char*)other.mData, 16); + md5_uuid.finalize(); + md5_uuid.raw_digest(result.mData); } LLUUID LLUUID::combine(const LLUUID &other) const diff --git a/indra/llui/llfolderview.cpp b/indra/llui/llfolderview.cpp index 32538ab3fa..b6bd67dc8e 100644 --- a/indra/llui/llfolderview.cpp +++ b/indra/llui/llfolderview.cpp @@ -1894,14 +1894,14 @@ void LLFolderView::update() LLFolderViewItem* scroll_to_item = mSelectedItems.back(); scrollToShowItem(scroll_to_item, constraint_rect); // continue scrolling until animated layout change is done - bool selected_filter_finished = true; - if (scroll_to_item && scroll_to_item->getViewModelItem()) + bool selected_filter_finished = getRoot()->getViewModelItem()->getLastFilterGeneration() >= filter_object.getFirstSuccessGeneration(); + if (selected_filter_finished && scroll_to_item && scroll_to_item->getViewModelItem()) { selected_filter_finished = scroll_to_item->getViewModelItem()->getLastFilterGeneration() >= filter_object.getFirstSuccessGeneration(); } if (filter_finished && selected_filter_finished) { - bool needs_arrange = needsArrange(); + bool needs_arrange = needsArrange() || getRoot()->needsArrange(); if (mParentFolder) { needs_arrange |= (bool)mParentFolder->needsArrange(); diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 94b6e727e1..aa4bbf82f3 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -11187,6 +11187,17 @@ Change of this parameter will affect the layout of buttons in notification toast Value 1 + NvAPISessionOverride + + Comment + Override NvAPI driver setting for maxim performance (HACK!!!) + Persist + 1 + Type + Boolean + Value + 0 + PurgeCacheOnNextStartup Comment diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 13abaeb5f4..26d73f53d0 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -2557,6 +2557,7 @@ bool LLAppViewer::cleanup() LLSelectMgr::deleteSingleton(); LLViewerEventRecorder::deleteSingleton(); LLWorld::deleteSingleton(); + LLVoiceClient::deleteSingleton(); // It's not at first obvious where, in this long sequence, a generic cleanup // call OUGHT to go. So let's say this: as we migrate cleanup from diff --git a/indra/newview/llappviewerwin32.cpp b/indra/newview/llappviewerwin32.cpp index 0c59bcccf1..6e3d821858 100644 --- a/indra/newview/llappviewerwin32.cpp +++ b/indra/newview/llappviewerwin32.cpp @@ -509,26 +509,35 @@ int APIENTRY WINMAIN(HINSTANCE hInstance, return -1; } - NvAPI_Status status; - - // Initialize NVAPI - status = NvAPI_Initialize(); - NvDRSSessionHandle hSession = 0; + NvDRSSessionHandle hSession = 0; + // Viewer shouldn't need NvAPI and this implementation alters global + // settings instead of viewer-only ones (SL-4126) + // TODO: ideally this should be removed, but temporary disabling + // it with a way to turn it back on in case of issues + // We fixed this the proper way and create an application profile instead of messing with the global settings + //static LLCachedControl use_nv_api(gSavedSettings, "NvAPISessionOverride", false); + //if (use_nv_api) + { + NvAPI_Status status; - if (status == NVAPI_OK) - { - // Create the session handle to access driver settings - status = NvAPI_DRS_CreateSession(&hSession); - if (status != NVAPI_OK) - { - nvapi_error(status); - } - else - { - //override driver setting as needed - ll_nvapi_init(hSession); - } - } + // Initialize NVAPI + status = NvAPI_Initialize(); + + if (status == NVAPI_OK) + { + // Create the session handle to access driver settings + status = NvAPI_DRS_CreateSession(&hSession); + if (status != NVAPI_OK) + { + nvapi_error(status); + } + else + { + //override driver setting as needed + ll_nvapi_init(hSession); + } + } + } // Have to wait until after logging is initialized to display LFH info if (num_heaps > 0) @@ -788,101 +797,107 @@ bool LLAppViewerWin32::init() // LLFile::remove(log_file, ENOENT); //} - success = LLAppViewer::init(); - if (!success) - return false; + // Win7 is no longer supported + bool is_win_7_or_below = LLOSInfo::getInstance()->mMajorVer <= 6 && LLOSInfo::getInstance()->mMajorVer <= 1; - checkTemp(); // Always do and log this, no matter if using Bugsplat or not + if (!is_win_7_or_below) + { + success = LLAppViewer::init(); + if (!success) + return false; - // Save those early so we don't have to deal with the dynamic memory during in process crash handling. - FS::LogfileIn = ll_convert_string_to_wide(gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "Firestorm.log")); - FS::LogfileOut = ll_convert_string_to_wide(gDirUtilp->getExpandedFilename(LL_PATH_DUMP, "Firestorm.log")); - FS::DumpFile = ll_convert_string_to_wide(gDirUtilp->getExpandedFilename(LL_PATH_DUMP, "Firestorm.dmp")); + checkTemp(); // Always do and log this, no matter if using Bugsplat or not - S32 nCrashSubmitBehavior = gCrashSettings.getS32("CrashSubmitBehavior"); - // Don't ever send? bail out! - if (nCrashSubmitBehavior == 2 /*CRASH_BEHAVIOR_NEVER_SEND*/) - return success; + // Save those early so we don't have to deal with the dynamic memory during in process crash handling. + FS::LogfileIn = ll_convert_string_to_wide(gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "Firestorm.log")); + FS::LogfileOut = ll_convert_string_to_wide(gDirUtilp->getExpandedFilename(LL_PATH_DUMP, "Firestorm.log")); + FS::DumpFile = ll_convert_string_to_wide(gDirUtilp->getExpandedFilename(LL_PATH_DUMP, "Firestorm.dmp")); - DWORD dwAsk{ MDSF_NONINTERACTIVE }; - if (nCrashSubmitBehavior == 0 /*CRASH_BEHAVIOR_ASK*/) - dwAsk = 0; - // - - std::string build_data_fname( - gDirUtilp->getExpandedFilename(LL_PATH_EXECUTABLE, "build_data.json")); - // Use llifstream instead of std::ifstream because LL_PATH_EXECUTABLE - // could contain non-ASCII characters, which std::ifstream doesn't handle. - llifstream inf(build_data_fname.c_str()); - if (! inf.is_open()) - { - LL_WARNS("BUGSPLAT") << "Can't initialize BugSplat, can't read '" << build_data_fname - << "'" << LL_ENDL; - } - else - { - Json::Reader reader; - Json::Value build_data; - if (! reader.parse(inf, build_data, false)) // don't collect comments - { - // gah, the typo is baked into Json::Reader API - LL_WARNS("BUGSPLAT") << "Can't initialize BugSplat, can't parse '" << build_data_fname - << "': " << reader.getFormatedErrorMessages() << LL_ENDL; - } - else - { - Json::Value BugSplat_DB = build_data["BugSplat DB"]; - if (! BugSplat_DB) - { - LL_WARNS("BUGSPLAT") << "Can't initialize BugSplat, no 'BugSplat DB' entry in '" - << build_data_fname << "'" << LL_ENDL; - } - else - { - // Got BugSplat_DB, onward! - std::wstring version_string(WSTRINGIZE(LL_VIEWER_VERSION_MAJOR << '.' << - LL_VIEWER_VERSION_MINOR << '.' << - LL_VIEWER_VERSION_PATCH << '.' << - LL_VIEWER_VERSION_BUILD)); + S32 nCrashSubmitBehavior = gCrashSettings.getS32("CrashSubmitBehavior"); + // Don't ever send? bail out! + if (nCrashSubmitBehavior == 2 /*CRASH_BEHAVIOR_NEVER_SEND*/) + return success; - // Set up Bugsplat to ask or always send - //DWORD dwFlags = MDSF_NONINTERACTIVE | // automatically submit report without prompting - // MDSF_PREVENTHIJACKING; // disallow swiping Exception filter - DWORD dwFlags = dwAsk | - MDSF_PREVENTHIJACKING; // disallow swiping Exception filter - // + DWORD dwAsk{ MDSF_NONINTERACTIVE }; + if (nCrashSubmitBehavior == 0 /*CRASH_BEHAVIOR_ASK*/) + dwAsk = 0; + // + + std::string build_data_fname( + gDirUtilp->getExpandedFilename(LL_PATH_EXECUTABLE, "build_data.json")); + // Use llifstream instead of std::ifstream because LL_PATH_EXECUTABLE + // could contain non-ASCII characters, which std::ifstream doesn't handle. + llifstream inf(build_data_fname.c_str()); + if (! inf.is_open()) + { + LL_WARNS("BUGSPLAT") << "Can't initialize BugSplat, can't read '" << build_data_fname + << "'" << LL_ENDL; + } + else + { + Json::Reader reader; + Json::Value build_data; + if (! reader.parse(inf, build_data, false)) // don't collect comments + { + // gah, the typo is baked into Json::Reader API + LL_WARNS("BUGSPLAT") << "Can't initialize BugSplat, can't parse '" << build_data_fname + << "': " << reader.getFormatedErrorMessages() << LL_ENDL; + } + else + { + Json::Value BugSplat_DB = build_data["BugSplat DB"]; + if (! BugSplat_DB) + { + LL_WARNS("BUGSPLAT") << "Can't initialize BugSplat, no 'BugSplat DB' entry in '" + << build_data_fname << "'" << LL_ENDL; + } + else + { + // Got BugSplat_DB, onward! + std::wstring version_string(WSTRINGIZE(LL_VIEWER_VERSION_MAJOR << '.' << + LL_VIEWER_VERSION_MINOR << '.' << + LL_VIEWER_VERSION_PATCH << '.' << + LL_VIEWER_VERSION_BUILD)); - //bool needs_log_file = !isSecondInstance() && debugLoggingEnabled("BUGSPLAT"); - //if (needs_log_file) - //{ - // // Startup only! - // LL_INFOS("BUGSPLAT") << "Engaged BugSplat logging to bugsplat.log" << LL_ENDL; - // dwFlags |= MDSF_LOGFILE | MDSF_LOG_VERBOSE; - //} + // Set up Bugsplat to ask or always send + //DWORD dwFlags = MDSF_NONINTERACTIVE | // automatically submit report without prompting + // MDSF_PREVENTHIJACKING; // disallow swiping Exception filter + DWORD dwFlags = dwAsk | + MDSF_PREVENTHIJACKING; // disallow swiping Exception filter + // - // have to convert normal wide strings to strings of __wchar_t - sBugSplatSender = new MiniDmpSender( - WCSTR(BugSplat_DB.asString()), - WCSTR(LL_TO_WSTRING(LL_VIEWER_CHANNEL)), - WCSTR(version_string), - nullptr, // szAppIdentifier -- set later - dwFlags); + //bool needs_log_file = !isSecondInstance() && debugLoggingEnabled("BUGSPLAT"); + //if (needs_log_file) + //{ + // // Startup only! + // LL_INFOS("BUGSPLAT") << "Engaged BugSplat logging to bugsplat.log" << LL_ENDL; + // dwFlags |= MDSF_LOGFILE | MDSF_LOG_VERBOSE; + //} - sBugSplatSender->setCallback(bugsplatSendLog); + // have to convert normal wide strings to strings of __wchar_t + sBugSplatSender = new MiniDmpSender( + WCSTR(BugSplat_DB.asString()), + WCSTR(LL_TO_WSTRING(LL_VIEWER_CHANNEL)), + WCSTR(version_string), + nullptr, // szAppIdentifier -- set later + dwFlags); - //if (needs_log_file) - //{ - // // Log file will be created in %TEMP%, but it will be moved into logs folder in case of crash - // std::string log_file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "bugsplat.log"); - // sBugSplatSender->setLogFilePath(WCSTR(log_file)); - //} + sBugSplatSender->setCallback(bugsplatSendLog); - // engage stringize() overload that converts from wstring - LL_INFOS("BUGSPLAT") << "Engaged BugSplat(" << LL_TO_STRING(LL_VIEWER_CHANNEL) - << ' ' << stringize(version_string) << ')' << LL_ENDL; - } // got BugSplat_DB - } // parsed build_data.json - } // opened build_data.json + //if (needs_log_file) + //{ + // // Log file will be created in %TEMP%, but it will be moved into logs folder in case of crash + // std::string log_file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "bugsplat.log"); + // sBugSplatSender->setLogFilePath(WCSTR(log_file)); + //} + + // engage stringize() overload that converts from wstring + LL_INFOS("BUGSPLAT") << "Engaged BugSplat(" << LL_TO_STRING(LL_VIEWER_CHANNEL) + << ' ' << stringize(version_string) << ')' << LL_ENDL; + } // got BugSplat_DB + } // parsed build_data.json + } // opened build_data.json + } // !is_win_7_or_below #endif // LL_BUGSPLAT #endif // LL_SEND_CRASH_REPORTS diff --git a/indra/newview/llfeaturemanager.cpp b/indra/newview/llfeaturemanager.cpp index 0e0cf3c1a1..b6b01e87d3 100644 --- a/indra/newview/llfeaturemanager.cpp +++ b/indra/newview/llfeaturemanager.cpp @@ -500,6 +500,18 @@ bool LLFeatureManager::loadGPUClass() { mGPUClass = GPU_CLASS_5; } + + #if LL_WINDOWS + const F32Gigabytes MIN_PHYSICAL_MEMORY(2); + + LLMemory::updateMemoryInfo(); + F32Gigabytes physical_mem = LLMemory::getMaxMemKB(); + if (MIN_PHYSICAL_MEMORY > physical_mem && mGPUClass > GPU_CLASS_1) + { + // reduce quality on systems that don't have enough memory + mGPUClass = (EGPUClass)(mGPUClass - 1); + } + #endif //LL_WINDOWS } //end if benchmark else { diff --git a/indra/newview/llpanelpeople.cpp b/indra/newview/llpanelpeople.cpp index 107bd77601..770bb43f3e 100644 --- a/indra/newview/llpanelpeople.cpp +++ b/indra/newview/llpanelpeople.cpp @@ -368,7 +368,10 @@ public: { // will be deleted by ~LLInventoryModel //delete mInvObserver; - LLVoiceClient::getInstance()->removeObserver(this); + if (LLVoiceClient::instanceExists()) + { + LLVoiceClient::getInstance()->removeObserver(this); + } LLAvatarTracker::instance().removeObserver(this); } diff --git a/indra/newview/llslurl.cpp b/indra/newview/llslurl.cpp index 1d75ecd4eb..89ec482d5c 100644 --- a/indra/newview/llslurl.cpp +++ b/indra/newview/llslurl.cpp @@ -176,11 +176,18 @@ LLSLURL::LLSLURL(const std::string& slurl) } else { - // it wasn't a /secondlife/ or /app/, so it must be secondlife:// + if(slurl_uri.hostName() == LLSLURL::SLURL_APP_PATH) + { + mType = APP; + } + else + { + // it wasn't a /secondlife/ or /app/, so it must be secondlife:// // therefore the hostname will be the region name, and it's a location type mType = LOCATION; // 'normalize' it so the region name is in fact the head of the path_array path_array.insert(0, slurl_uri.hostName()); + } } } else if((slurl_uri.scheme() == LLSLURL::SLURL_HTTP_SCHEME) || diff --git a/indra/newview/llviewerhelp.cpp b/indra/newview/llviewerhelp.cpp index 096ea63e6e..1aa99ff382 100644 --- a/indra/newview/llviewerhelp.cpp +++ b/indra/newview/llviewerhelp.cpp @@ -44,7 +44,7 @@ class LLHelpHandler : public LLCommandHandler { public: // requests will be throttled from a non-trusted browser - LLHelpHandler() : LLCommandHandler("help", UNTRUSTED_THROTTLE) {} + LLHelpHandler() : LLCommandHandler("help", UNTRUSTED_CLICK_ONLY) {} bool handle(const LLSD& params, const LLSD& query_map, LLMediaCtrl* web) { diff --git a/indra/newview/llviewershadermgr.cpp b/indra/newview/llviewershadermgr.cpp index 5c24a07201..f33eaa3b22 100644 --- a/indra/newview/llviewershadermgr.cpp +++ b/indra/newview/llviewershadermgr.cpp @@ -35,6 +35,7 @@ #include "llrender.h" #include "llenvironment.h" +#include "llerrorcontrol.h" #include "llatmosphere.h" #include "llworld.h" #include "llsky.h" @@ -566,10 +567,15 @@ void LLViewerShaderMgr::setShaders() std::string shader_name = loadBasicShaders(); if (shader_name.empty()) { - LL_INFOS() << "Loaded basic shaders." << LL_ENDL; + LL_INFOS("Shader") << "Loaded basic shaders." << LL_ENDL; } else { + // "ShaderLoading" and "Shader" need to be logged + LLError::ELevel lvl = LLError::getDefaultLevel(); + LLError::setDefaultLevel(LLError::LEVEL_DEBUG); + loadBasicShaders(); + LLError::setDefaultLevel(lvl); LL_ERRS() << "Unable to load basic shader " << shader_name << ", verify graphics driver installed and current." << LL_ENDL; reentrance = false; // For hygiene only, re-try probably helps nothing return; diff --git a/indra/newview/llvoiceclient.cpp b/indra/newview/llvoiceclient.cpp index 571d46d719..0839133b47 100644 --- a/indra/newview/llvoiceclient.cpp +++ b/indra/newview/llvoiceclient.cpp @@ -147,6 +147,7 @@ LLVoiceClient::LLVoiceClient(LLPumpIO *pump) LLVoiceClient::~LLVoiceClient() { + llassert(!mVoiceModule); } void LLVoiceClient::init(LLPumpIO *pump)