Merge branch 'DRTVWR-577-maint-S' of https://github.com/secondlife/viewer

# Conflicts:
#	indra/newview/app_settings/settings.xml
#	indra/newview/llappviewerwin32.cpp
#	indra/newview/skins/default/xui/en/floater_about_land.xml
#	indra/newview/skins/default/xui/en/panel_preferences_chat.xml
master
Ansariel 2023-03-07 14:21:43 +01:00
commit 1772ae4c6c
11 changed files with 176 additions and 114 deletions

View File

@ -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

View File

@ -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();

View File

@ -11187,6 +11187,17 @@ Change of this parameter will affect the layout of buttons in notification toast
<key>Value</key>
<integer>1</integer>
</map>
<key>NvAPISessionOverride</key>
<map>
<key>Comment</key>
<string>Override NvAPI driver setting for maxim performance (HACK!!!)</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
<integer>0</integer>
</map>
<key>PurgeCacheOnNextStartup</key>
<map>
<key>Comment</key>

View File

@ -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

View File

@ -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
// <FS:Ansariel> We fixed this the proper way and create an application profile instead of messing with the global settings
//static LLCachedControl<bool> 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;
// </FS:ND>
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;
// <FS:ND> 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
// </FS:ND>
DWORD dwAsk{ MDSF_NONINTERACTIVE };
if (nCrashSubmitBehavior == 0 /*CRASH_BEHAVIOR_ASK*/)
dwAsk = 0;
// </FS:ND>
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;
//}
// <FS:ND> 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
// </FS:ND>
// 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

View File

@ -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
{

View File

@ -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);
}

View File

@ -176,11 +176,18 @@ LLSLURL::LLSLURL(const std::string& slurl)
}
else
{
// it wasn't a /secondlife/<region> or /app/<params>, so it must be secondlife://<region>
if(slurl_uri.hostName() == LLSLURL::SLURL_APP_PATH)
{
mType = APP;
}
else
{
// it wasn't a /secondlife/<region> or /app/<params>, so it must be secondlife://<region>
// 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) ||

View File

@ -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)
{

View File

@ -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;

View File

@ -147,6 +147,7 @@ LLVoiceClient::LLVoiceClient(LLPumpIO *pump)
LLVoiceClient::~LLVoiceClient()
{
llassert(!mVoiceModule);
}
void LLVoiceClient::init(LLPumpIO *pump)