summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xdoc/contributions.txt2
-rw-r--r--indra/llcommon/llerror.cpp48
-rw-r--r--indra/llcommon/llsys.cpp24
-rw-r--r--indra/llprimitive/llmodel.h3
-rw-r--r--indra/llui/llcheckboxctrl.h2
-rw-r--r--indra/llui/lltexteditor.cpp22
-rw-r--r--indra/llwindow/llopenglview-objc.mm4
-rw-r--r--indra/llxml/llcontrol.cpp94
-rw-r--r--indra/llxml/llcontrol.h3
-rw-r--r--indra/newview/CMakeLists.txt2
-rw-r--r--indra/newview/app_settings/settings.xml11
-rw-r--r--indra/newview/installers/windows/installer_template.nsi4
-rw-r--r--indra/newview/installers/windows/lang_en-us.nsibin8734 -> 8814 bytes
-rw-r--r--indra/newview/llappviewer.cpp12
-rw-r--r--indra/newview/llappviewermacosx.cpp62
-rw-r--r--indra/newview/llappviewermacosx.h4
-rw-r--r--indra/newview/llautoreplace.cpp7
-rw-r--r--indra/newview/llfloateravatarpicker.cpp2
-rw-r--r--indra/newview/llfloatermodelpreview.cpp3
-rw-r--r--indra/newview/llfloaterpreference.cpp11
-rw-r--r--indra/newview/llfloateruipreview.cpp28
-rw-r--r--indra/newview/llimprocessing.cpp32
-rw-r--r--indra/newview/llmanip.cpp80
-rw-r--r--indra/newview/llmeshrepository.cpp39
-rw-r--r--indra/newview/llmoveview.cpp16
-rw-r--r--indra/newview/llmoveview.h2
-rw-r--r--indra/newview/llnotificationlistitem.cpp11
-rw-r--r--indra/newview/llpanelgroupgeneral.cpp5
-rw-r--r--indra/newview/lltexturecache.cpp8
-rw-r--r--indra/newview/lltoastgroupnotifypanel.cpp16
-rw-r--r--indra/newview/lltoastnotifypanel.cpp8
-rw-r--r--indra/newview/lltoastpanel.cpp3
-rw-r--r--indra/newview/lltoastpanel.h1
-rw-r--r--indra/newview/lltoastscripttextbox.cpp4
-rw-r--r--indra/newview/lltool.cpp4
-rw-r--r--indra/newview/lltoolpie.cpp33
-rw-r--r--indra/newview/llviewercontrol.cpp6
-rw-r--r--indra/newview/llviewermedia.cpp10
-rw-r--r--indra/newview/llviewerobject.cpp60
-rw-r--r--indra/newview/llviewerobject.h5
-rw-r--r--indra/newview/llviewerobjectlist.cpp2
-rw-r--r--indra/newview/llviewerparcelmgr.cpp147
-rw-r--r--indra/newview/llviewerparceloverlay.cpp17
-rw-r--r--indra/newview/llviewerparceloverlay.h2
-rw-r--r--indra/newview/llviewershadermgr.cpp3
-rw-r--r--indra/newview/llviewertexture.cpp138
-rw-r--r--indra/newview/llviewertexture.h7
-rw-r--r--indra/newview/llvoavatar.h2
-rw-r--r--indra/newview/llvovolume.cpp29
-rw-r--r--indra/newview/llvovolume.h2
-rw-r--r--indra/newview/llvowlsky.cpp3
-rw-r--r--indra/newview/llworldmapview.cpp9
-rw-r--r--indra/newview/llxmlrpctransaction.cpp28
-rw-r--r--indra/newview/skins/default/xui/en/floater_model_preview.xml29
-rw-r--r--indra/newview/skins/default/xui/en/language_settings.xml1
-rw-r--r--indra/newview/skins/default/xui/en/notifications.xml28
-rw-r--r--indra/newview/skins/default/xui/en/strings.xml25
-rw-r--r--indra/newview/skins/default/xui/zh/floater_tos.xml2
58 files changed, 710 insertions, 455 deletions
diff --git a/doc/contributions.txt b/doc/contributions.txt
index a09b6aff43..97c7ff1098 100755
--- a/doc/contributions.txt
+++ b/doc/contributions.txt
@@ -371,6 +371,7 @@ Cinder Roxley
STORM-2116
STORM-2127
STORM-2144
+ SL-3404
Clara Young
Coaldust Numbers
VWR-1095
@@ -776,6 +777,7 @@ Jonathan Yap
STORM-2100
STORM-2104
STORM-2142
+ SL-10089
Kadah Coba
STORM-1060
STORM-1843
diff --git a/indra/llcommon/llerror.cpp b/indra/llcommon/llerror.cpp
index 40eb7d9bac..17d8164289 100644
--- a/indra/llcommon/llerror.cpp
+++ b/indra/llcommon/llerror.cpp
@@ -382,15 +382,22 @@ namespace
{
llifstream file(filename().c_str());
- if (file.is_open())
+ if (!file.is_open())
{
- LLSDSerialize::fromXML(configuration, file);
+ LL_WARNS() << filename() << " failed to open file; not changing configuration" << LL_ENDL;
+ return false;
+ }
+
+ if (LLSDSerialize::fromXML(configuration, file) == LLSDParser::PARSE_FAILURE)
+ {
+ LL_WARNS() << filename() << " parcing error; not changing configuration" << LL_ENDL;
+ return false;
}
- if (configuration.isUndefined())
+ if (configuration.isUndefined() || !configuration.isMap() || configuration.emptyMap())
{
- LL_WARNS() << filename() << " missing, ill-formed,"
- " or simply undefined; not changing configuration"
+ LL_WARNS() << filename() << " missing, ill-formed, or simply undefined"
+ " content; not changing configuration"
<< LL_ENDL;
return false;
}
@@ -856,19 +863,24 @@ namespace LLError
setEnabledLogTypesMask(config["enabled-log-types-mask"].asInteger());
}
- LLSD sets = config["settings"];
- LLSD::array_const_iterator a, end;
- for (a = sets.beginArray(), end = sets.endArray(); a != end; ++a)
- {
- const LLSD& entry = *a;
-
- ELevel level = decodeLevel(entry["level"]);
-
- setLevels(s->mFunctionLevelMap, entry["functions"], level);
- setLevels(s->mClassLevelMap, entry["classes"], level);
- setLevels(s->mFileLevelMap, entry["files"], level);
- setLevels(s->mTagLevelMap, entry["tags"], level);
- }
+ if (config.has("settings") && config["settings"].isArray())
+ {
+ LLSD sets = config["settings"];
+ LLSD::array_const_iterator a, end;
+ for (a = sets.beginArray(), end = sets.endArray(); a != end; ++a)
+ {
+ const LLSD& entry = *a;
+ if (entry.isMap() && !entry.emptyMap())
+ {
+ ELevel level = decodeLevel(entry["level"]);
+
+ setLevels(s->mFunctionLevelMap, entry["functions"], level);
+ setLevels(s->mClassLevelMap, entry["classes"], level);
+ setLevels(s->mFileLevelMap, entry["files"], level);
+ setLevels(s->mTagLevelMap, entry["tags"], level);
+ }
+ }
+ }
}
}
diff --git a/indra/llcommon/llsys.cpp b/indra/llcommon/llsys.cpp
index 1ef6c538ba..1f8d558fbe 100644
--- a/indra/llcommon/llsys.cpp
+++ b/indra/llcommon/llsys.cpp
@@ -268,10 +268,32 @@ LLOSInfo::LLOSInfo() :
}
}
+ S32 ubr = 0; // Windows 10 Update Build Revision, can be retrieved from a registry
+ if (mMajorVer == 10)
+ {
+ DWORD cbData(sizeof(DWORD));
+ DWORD data(0);
+ HKEY key;
+ BOOL ret_code = RegOpenKeyExW(HKEY_LOCAL_MACHINE, TEXT("SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion"), 0, KEY_READ, &key);
+ if (ERROR_SUCCESS == ret_code)
+ {
+ ret_code = RegQueryValueExW(key, L"UBR", 0, NULL, reinterpret_cast<LPBYTE>(&data), &cbData);
+ if (ERROR_SUCCESS == ret_code)
+ {
+ ubr = data;
+ }
+ }
+ }
+
mOSString = mOSStringSimple;
if (mBuild > 0)
{
- mOSString += llformat("(Build %d)", mBuild);
+ mOSString += llformat("(Build %d", mBuild);
+ if (ubr > 0)
+ {
+ mOSString += llformat(".%d", ubr);
+ }
+ mOSString += ")";
}
LLStringUtil::trim(mOSStringSimple);
diff --git a/indra/llprimitive/llmodel.h b/indra/llprimitive/llmodel.h
index cf3288489a..51fa2f8079 100644
--- a/indra/llprimitive/llmodel.h
+++ b/indra/llprimitive/llmodel.h
@@ -154,7 +154,6 @@ public:
void ClearFacesAndMaterials() { mVolumeFaces.clear(); mMaterialList.clear(); }
std::string getName() const;
- std::string getMetric() const {return mMetric;}
EModelStatus getStatus() const {return mStatus;}
static std::string getStatusString(U32 status) ;
@@ -260,8 +259,6 @@ public:
std::string mRequestedLabel; // name requested in UI, if any.
std::string mLabel; // name computed from dae.
- std::string mMetric; // user-supplied metric data for upload
-
LLVector3 mNormalizedScale;
LLVector3 mNormalizedTranslation;
diff --git a/indra/llui/llcheckboxctrl.h b/indra/llui/llcheckboxctrl.h
index 5ce45b2135..71bdc32e66 100644
--- a/indra/llui/llcheckboxctrl.h
+++ b/indra/llui/llcheckboxctrl.h
@@ -92,6 +92,8 @@ public:
// LLCheckBoxCtrl interface
virtual BOOL toggle() { return mButton->toggleState(); } // returns new state
+ void setBtnFocus() { mButton->setFocus(TRUE); }
+
void setEnabledColor( const LLColor4 &color ) { mTextEnabledColor = color; }
void setDisabledColor( const LLColor4 &color ) { mTextDisabledColor = color; }
diff --git a/indra/llui/lltexteditor.cpp b/indra/llui/lltexteditor.cpp
index 134b76c720..137167db2a 100644
--- a/indra/llui/lltexteditor.cpp
+++ b/indra/llui/lltexteditor.cpp
@@ -732,14 +732,30 @@ BOOL LLTextEditor::handleRightMouseDown(S32 x, S32 y, MASK mask)
{
setFocus(TRUE);
}
+
+ bool show_menu = false;
+
// Prefer editor menu if it has selection. See EXT-6806.
- if (hasSelection() || !LLTextBase::handleRightMouseDown(x, y, mask))
+ if (hasSelection())
{
- if(getShowContextMenu())
+ S32 click_pos = getDocIndexFromLocalCoord(x, y, FALSE);
+ if (click_pos > mSelectionStart && click_pos < mSelectionEnd)
{
- showContextMenu(x, y);
+ show_menu = true;
}
}
+
+ // Let segments handle the click, if nothing does, show editor menu
+ if (!show_menu && !LLTextBase::handleRightMouseDown(x, y, mask))
+ {
+ show_menu = true;
+ }
+
+ if (show_menu && getShowContextMenu())
+ {
+ showContextMenu(x, y);
+ }
+
return TRUE;
}
diff --git a/indra/llwindow/llopenglview-objc.mm b/indra/llwindow/llopenglview-objc.mm
index c8c086d705..8923ea6458 100644
--- a/indra/llwindow/llopenglview-objc.mm
+++ b/indra/llwindow/llopenglview-objc.mm
@@ -322,6 +322,10 @@ attributedStringInfo getSegments(NSAttributedString *str)
- (void) mouseDown:(NSEvent *)theEvent
{
+ NSPoint mPoint = [theEvent locationInWindow];
+ mMousePos[0] = mPoint.x;
+ mMousePos[1] = mPoint.y;
+
// Apparently people still use this?
if ([theEvent modifierFlags] & NSCommandKeyMask &&
!([theEvent modifierFlags] & NSControlKeyMask) &&
diff --git a/indra/llxml/llcontrol.cpp b/indra/llxml/llcontrol.cpp
index 20ab1a7ad3..ccf4f3ddf5 100644
--- a/indra/llxml/llcontrol.cpp
+++ b/indra/llxml/llcontrol.cpp
@@ -43,6 +43,9 @@
#include "llrect.h"
#include "llxmltree.h"
#include "llsdserialize.h"
+#include "llfile.h"
+#include "lltimer.h"
+#include "lldir.h"
#if LL_RELEASE_WITH_DEBUG_INFO || LL_DEBUG
#define CONTROL_ERRS LL_ERRS("ControlErrors")
@@ -92,6 +95,17 @@ template <> LLSD convert_from_llsd<LLSD>(const LLSD& sd, eControlType type, cons
//this defines the current version of the settings file
const S32 CURRENT_VERSION = 101;
+// If you define the environment variable LL_SETTINGS_PROFILE to any value this will activate
+// the gSavedSettings profiling code. This code tracks the calls to get a saved (debug) setting.
+// When the viewer exits the results are written to the log directory to the file specified
+// by SETTINGS_PROFILE below. Only settings with an average access rate >= 2/second are output.
+typedef std::pair<std::string, U32> settings_pair_t;
+typedef std::vector<settings_pair_t> settings_vec_t;
+LLSD getCount;
+settings_vec_t getCount_v;
+F64 start_time = 0;
+std::string SETTINGS_PROFILE = "settings_profile.log";
+
bool LLControlVariable::llsd_compare(const LLSD& a, const LLSD & b)
{
bool result = false;
@@ -327,6 +341,11 @@ LLSD LLControlVariable::getSaveValue() const
LLPointer<LLControlVariable> LLControlGroup::getControl(const std::string& name)
{
+ if (mSettingsProfile)
+ {
+ incrCount(name);
+ }
+
ctrl_name_table_t::iterator iter = mNameTable.find(name);
return iter == mNameTable.end() ? LLPointer<LLControlVariable>() : iter->second;
}
@@ -349,8 +368,14 @@ const std::string LLControlGroup::mTypeString[TYPE_COUNT] = { "U32"
};
LLControlGroup::LLControlGroup(const std::string& name)
-: LLInstanceTracker<LLControlGroup, std::string>(name)
+: LLInstanceTracker<LLControlGroup, std::string>(name),
+ mSettingsProfile(false)
{
+
+ if (NULL != getenv("LL_SETTINGS_PROFILE"))
+ {
+ mSettingsProfile = true;
+ }
}
LLControlGroup::~LLControlGroup()
@@ -358,8 +383,66 @@ LLControlGroup::~LLControlGroup()
cleanup();
}
+static bool compareRoutine(settings_pair_t lhs, settings_pair_t rhs)
+{
+ return lhs.second > rhs.second;
+};
+
void LLControlGroup::cleanup()
{
+ if(mSettingsProfile && getCount.size() != 0)
+ {
+ std::string file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, SETTINGS_PROFILE);
+ LLFILE* out = LLFile::fopen(file, "w"); /* Flawfinder: ignore */
+ if(!out)
+ {
+ LL_WARNS("SettingsProfile") << "Error opening " << SETTINGS_PROFILE << LL_ENDL;
+ }
+ else
+ {
+ F64 end_time = LLTimer::getTotalSeconds();
+ U32 total_seconds = (U32)(end_time - start_time);
+
+ std::string msg = llformat("Runtime (seconds): %d\n\n No. accesses Avg. accesses/sec Name\n", total_seconds);
+ std::ostringstream data_msg;
+
+ data_msg << msg;
+ size_t data_size = data_msg.str().size();
+ if (fwrite(data_msg.str().c_str(), 1, data_size, out) != data_size)
+ {
+ LL_WARNS("SettingsProfile") << "Failed to write settings profile header" << LL_ENDL;
+ }
+
+ for (LLSD::map_const_iterator iter = getCount.beginMap(); iter != getCount.endMap(); ++iter)
+ {
+ getCount_v.push_back(settings_pair_t(iter->first, iter->second.asInteger()));
+ }
+ sort(getCount_v.begin(), getCount_v.end(), compareRoutine);
+
+ for (settings_vec_t::iterator iter = getCount_v.begin(); iter != getCount_v.end(); ++iter)
+ {
+ U32 access_rate = 0;
+ if (total_seconds != 0)
+ {
+ access_rate = iter->second / total_seconds;
+ }
+ if (access_rate >= 2)
+ {
+ std::ostringstream data_msg;
+ msg = llformat("%13d %7d %s", iter->second, access_rate, iter->first.c_str());
+ data_msg << msg << "\n";
+ size_t data_size = data_msg.str().size();
+ if (fwrite(data_msg.str().c_str(), 1, data_size, out) != data_size)
+ {
+ LL_WARNS("SettingsProfile") << "Failed to write settings profile" << LL_ENDL;
+ }
+ }
+ }
+ getCount = LLSD::emptyMap();
+ fclose(out);
+ }
+ }
+
mNameTable.clear();
}
@@ -460,6 +543,15 @@ LLControlVariable* LLControlGroup::declareLLSD(const std::string& name, const LL
return declareControl(name, TYPE_LLSD, initial_val, comment, persist);
}
+void LLControlGroup::incrCount(const std::string& name)
+{
+ if (0.0 == start_time)
+ {
+ start_time = LLTimer::getTotalSeconds();
+ }
+ getCount[name] = getCount[name].asInteger() + 1;
+}
+
BOOL LLControlGroup::getBOOL(const std::string& name)
{
return (BOOL)get<bool>(name);
diff --git a/indra/llxml/llcontrol.h b/indra/llxml/llcontrol.h
index 8136a3e88a..de0d366492 100644
--- a/indra/llxml/llcontrol.h
+++ b/indra/llxml/llcontrol.h
@@ -301,6 +301,9 @@ public:
U32 saveToFile(const std::string& filename, BOOL nondefault_only);
U32 loadFromFile(const std::string& filename, bool default_values = false, bool save_values = true);
void resetToDefaults();
+ void incrCount(const std::string& name);
+
+ bool mSettingsProfile;
};
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index ce8b662231..33886acb71 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -2074,7 +2074,7 @@ if (DARWIN)
set(MACOSX_BUNDLE_BUNDLE_NAME "SecondLife")
set(MACOSX_BUNDLE_SHORT_VERSION_STRING "${VIEWER_SHORT_VERSION}")
set(MACOSX_BUNDLE_BUNDLE_VERSION "${VIEWER_SHORT_VERSION}${VIEWER_MACOSX_PHASE}${VIEWER_REVISION}")
- set(MACOSX_BUNDLE_COPYRIGHT "Copyright © Linden Research, Inc. 2007")
+ set(MACOSX_BUNDLE_COPYRIGHT "Copyright © Linden Research, Inc. 2018")
set(MACOSX_BUNDLE_NSMAIN_NIB_FILE "SecondLife.nib")
set(MACOSX_BUNDLE_NSPRINCIPAL_CLASS "NSApplication")
diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index 3ad8b6cded..0eef5120eb 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -14068,6 +14068,17 @@
<key>Value</key>
<integer>1</integer>
</map>
+ <key>RegionCrossingInterpolationTime</key>
+ <map>
+ <key>Comment</key>
+ <string>How long to extrapolate object motion after crossing regions</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>F32</string>
+ <key>Value</key>
+ <integer>1</integer>
+ </map>
<key>VerboseLogs</key>
<map>
<key>Comment</key>
diff --git a/indra/newview/installers/windows/installer_template.nsi b/indra/newview/installers/windows/installer_template.nsi
index 14c8dba39f..d6e4b005df 100644
--- a/indra/newview/installers/windows/installer_template.nsi
+++ b/indra/newview/installers/windows/installer_template.nsi
@@ -651,9 +651,7 @@ RMDir "$INSTDIR"
IfFileExists "$INSTDIR" FOLDERFOUND NOFOLDER
FOLDERFOUND:
-# Silent uninstall always removes all files (/SD IDYES)
- MessageBox MB_YESNO $(DeleteProgramFilesMB) /SD IDYES IDNO NOFOLDER
- RMDir /r "$INSTDIR"
+ MessageBox MB_OK $(DeleteProgramFilesMB) /SD IDOK IDOK NOFOLDER
NOFOLDER:
diff --git a/indra/newview/installers/windows/lang_en-us.nsi b/indra/newview/installers/windows/lang_en-us.nsi
index 00aa47de69..f854f5db06 100644
--- a/indra/newview/installers/windows/lang_en-us.nsi
+++ b/indra/newview/installers/windows/lang_en-us.nsi
Binary files differ
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index 4374caacdf..7c79cc7ddf 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -568,12 +568,12 @@ static void settings_to_globals()
LLVertexBuffer::sUseVAO = gSavedSettings.getBOOL("RenderUseVAO");
LLImageGL::sGlobalUseAnisotropic = gSavedSettings.getBOOL("RenderAnisotropic");
LLImageGL::sCompressTextures = gSavedSettings.getBOOL("RenderCompressTextures");
- LLVOVolume::sLODFactor = gSavedSettings.getF32("RenderVolumeLODFactor");
+ LLVOVolume::sLODFactor = llclamp(gSavedSettings.getF32("RenderVolumeLODFactor"), 0.01f, MAX_LOD_FACTOR);
LLVOVolume::sDistanceFactor = 1.f-LLVOVolume::sLODFactor * 0.1f;
LLVolumeImplFlexible::sUpdateFactor = gSavedSettings.getF32("RenderFlexTimeFactor");
LLVOTree::sTreeFactor = gSavedSettings.getF32("RenderTreeLODFactor");
- LLVOAvatar::sLODFactor = gSavedSettings.getF32("RenderAvatarLODFactor");
- LLVOAvatar::sPhysicsLODFactor = gSavedSettings.getF32("RenderAvatarPhysicsLODFactor");
+ LLVOAvatar::sLODFactor = llclamp(gSavedSettings.getF32("RenderAvatarLODFactor"), 0.f, MAX_AVATAR_LOD_FACTOR);
+ LLVOAvatar::sPhysicsLODFactor = llclamp(gSavedSettings.getF32("RenderAvatarPhysicsLODFactor"), 0.f, MAX_AVATAR_LOD_FACTOR);
LLVOAvatar::updateImpostorRendering(gSavedSettings.getU32("RenderAvatarMaxNonImpostors"));
LLVOAvatar::sVisibleInFirstPerson = gSavedSettings.getBOOL("FirstPersonAvatarVisible");
// clamp auto-open time to some minimum usable value
@@ -5439,7 +5439,8 @@ void LLAppViewer::resumeMainloopTimeout(const std::string& state, F32 secs)
{
if(secs < 0.0f)
{
- secs = gSavedSettings.getF32("MainloopTimeoutDefault");
+ static LLCachedControl<F32> mainloop_timeout(gSavedSettings, "MainloopTimeoutDefault", 60);
+ secs = mainloop_timeout;
}
mMainloopTimeout->setTimeout(secs);
@@ -5466,7 +5467,8 @@ void LLAppViewer::pingMainloopTimeout(const std::string& state, F32 secs)
{
if(secs < 0.0f)
{
- secs = gSavedSettings.getF32("MainloopTimeoutDefault");
+ static LLCachedControl<F32> mainloop_timeout(gSavedSettings, "MainloopTimeoutDefault", 60);
+ secs = mainloop_timeout;
}
mMainloopTimeout->setTimeout(secs);
diff --git a/indra/newview/llappviewermacosx.cpp b/indra/newview/llappviewermacosx.cpp
index d472f8926b..1db48119aa 100644
--- a/indra/newview/llappviewermacosx.cpp
+++ b/indra/newview/llappviewermacosx.cpp
@@ -337,68 +337,6 @@ std::string LLAppViewerMacOSX::generateSerialNumber()
return serial_md5;
}
-static AudioDeviceID get_default_audio_output_device(void)
-{
- AudioDeviceID device = 0;
- UInt32 size = sizeof(device);
- AudioObjectPropertyAddress device_address = { kAudioHardwarePropertyDefaultOutputDevice,
- kAudioObjectPropertyScopeGlobal,
- kAudioObjectPropertyElementMaster };
-
- OSStatus err = AudioObjectGetPropertyData(kAudioObjectSystemObject, &device_address, 0, NULL, &size, &device);
- if(err != noErr)
- {
- LL_DEBUGS("SystemMute") << "Couldn't get default audio output device (0x" << std::hex << err << ")" << LL_ENDL;
- }
-
- return device;
-}
-
-//virtual
-void LLAppViewerMacOSX::setMasterSystemAudioMute(bool new_mute)
-{
- AudioDeviceID device = get_default_audio_output_device();
-
- if(device != 0)
- {
- UInt32 mute = new_mute;
- AudioObjectPropertyAddress device_address = { kAudioDevicePropertyMute,
- kAudioDevicePropertyScopeOutput,
- kAudioObjectPropertyElementMaster };
-
- OSStatus err = AudioObjectSetPropertyData(device, &device_address, 0, NULL, sizeof(mute), &mute);
- if(err != noErr)
- {
- LL_INFOS("SystemMute") << "Couldn't set audio mute property (0x" << std::hex << err << ")" << LL_ENDL;
- }
- }
-}
-
-//virtual
-bool LLAppViewerMacOSX::getMasterSystemAudioMute()
-{
- // Assume the system isn't muted
- UInt32 mute = 0;
-
- AudioDeviceID device = get_default_audio_output_device();
-
- if(device != 0)
- {
- UInt32 size = sizeof(mute);
- AudioObjectPropertyAddress device_address = { kAudioDevicePropertyMute,
- kAudioDevicePropertyScopeOutput,
- kAudioObjectPropertyElementMaster };
-
- OSStatus err = AudioObjectGetPropertyData(device, &device_address, 0, NULL, &size, &mute);
- if(err != noErr)
- {
- LL_DEBUGS("SystemMute") << "Couldn't get audio mute property (0x" << std::hex << err << ")" << LL_ENDL;
- }
- }
-
- return (mute != 0);
-}
-
void handleUrl(const char* url_utf8)
{
if (url_utf8 && gViewerAppPtr)
diff --git a/indra/newview/llappviewermacosx.h b/indra/newview/llappviewermacosx.h
index ebb41a495c..d5a80864be 100644
--- a/indra/newview/llappviewermacosx.h
+++ b/indra/newview/llappviewermacosx.h
@@ -42,10 +42,6 @@ public:
//
virtual bool init(); // Override to do application initialization
- // mute/unmute the system's master audio
- virtual void setMasterSystemAudioMute(bool mute);
- virtual bool getMasterSystemAudioMute();
-
protected:
virtual bool restoreErrorTrap();
virtual void initCrashReporting(bool reportFreeze);
diff --git a/indra/newview/llautoreplace.cpp b/indra/newview/llautoreplace.cpp
index dd9354fe3a..0516520c56 100644
--- a/indra/newview/llautoreplace.cpp
+++ b/indra/newview/llautoreplace.cpp
@@ -68,8 +68,8 @@ void LLAutoReplace::autoreplaceCallback(S32& replacement_start, S32& replacement
word_start--; // walk word_start back to the beginning of the word
}
LL_DEBUGS("AutoReplace") << "word_start: " << word_start << " word_end: " << word_end << LL_ENDL;
- std::string str_text = std::string(input_text.begin(), input_text.end());
- std::string last_word = str_text.substr(word_start, word_end - word_start + 1);
+ LLWString old_string = input_text.substr(word_start, word_end - word_start + 1);
+ std::string last_word = wstring_to_utf8str(old_string);
std::string replacement_word(mSettings.replaceWord(last_word));
if (replacement_word != last_word)
@@ -79,9 +79,8 @@ void LLAutoReplace::autoreplaceCallback(S32& replacement_start, S32& replacement
{
// return the replacement string
replacement_start = word_start;
- replacement_length = last_word.length();
+ replacement_length = word_end - word_start + 1;
replacement_string = utf8str_to_wstring(replacement_word);
- LLWString old_string = utf8str_to_wstring(last_word);
S32 size_change = replacement_string.size() - old_string.size();
cursor_pos += size_change;
}
diff --git a/indra/newview/llfloateravatarpicker.cpp b/indra/newview/llfloateravatarpicker.cpp
index c5561fe011..33099db1b9 100644
--- a/indra/newview/llfloateravatarpicker.cpp
+++ b/indra/newview/llfloateravatarpicker.cpp
@@ -812,7 +812,7 @@ bool LLFloaterAvatarPicker::isSelectBtnEnabled()
{
bool ret_val = visibleItemsSelected();
- if ( ret_val )
+ if ( ret_val && !isMinimized())
{
std::string acvtive_panel_name;
LLScrollListCtrl* list = NULL;
diff --git a/indra/newview/llfloatermodelpreview.cpp b/indra/newview/llfloatermodelpreview.cpp
index 268c646719..818d364c3e 100644
--- a/indra/newview/llfloatermodelpreview.cpp
+++ b/indra/newview/llfloatermodelpreview.cpp
@@ -1418,8 +1418,6 @@ void LLModelPreview::rebuildUploadData()
std::string requested_name = mFMP->getChild<LLUICtrl>("description_form")->getValue().asString();
- std::string metric = mFMP->getChild<LLUICtrl>("model_category_combo")->getValue().asString();
-
LLSpinCtrl* scale_spinner = mFMP->getChild<LLSpinCtrl>("import_scale");
F32 scale = scale_spinner->getValue().asReal();
@@ -1460,7 +1458,6 @@ void LLModelPreview::rebuildUploadData()
if (base_model && !requested_name.empty())
{
base_model->mRequestedLabel = requested_name;
- base_model->mMetric = metric;
}
for (int i = LLModel::NUM_LODS - 1; i >= LLModel::LOD_IMPOSTOR; i--)
diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp
index d63ee1b367..ac751a785d 100644
--- a/indra/newview/llfloaterpreference.cpp
+++ b/indra/newview/llfloaterpreference.cpp
@@ -2329,6 +2329,7 @@ BOOL LLPanelPreference::postBuild()
if (hasChild("mute_chb_label", TRUE))
{
getChild<LLTextBox>("mute_chb_label")->setShowCursorHand(false);
+ getChild<LLTextBox>("mute_chb_label")->setSoundFlags(LLView::MOUSE_UP);
getChild<LLTextBox>("mute_chb_label")->setClickedCallback(boost::bind(&toggleMuteWhenMinimized));
}
@@ -2452,6 +2453,11 @@ void LLPanelPreference::toggleMuteWhenMinimized()
{
std::string mute("MuteWhenMinimized");
gSavedSettings.setBOOL(mute, !gSavedSettings.getBOOL(mute));
+ LLFloaterPreference* instance = LLFloaterReg::findTypedInstance<LLFloaterPreference>("preferences");
+ if (instance)
+ {
+ instance->getChild<LLCheckBoxCtrl>("mute_when_minimized")->setBtnFocus();
+ }
}
void LLPanelPreference::cancel()
@@ -2600,6 +2606,11 @@ void LLPanelPreferenceGraphics::onPresetsListChange()
{
instance->saveSettings(); //make cancel work correctly after changing the preset
}
+ else
+ {
+ std::string dummy;
+ instance->saveGraphicsPreset(dummy);
+ }
}
void LLPanelPreferenceGraphics::setPresetText()
diff --git a/indra/newview/llfloateruipreview.cpp b/indra/newview/llfloateruipreview.cpp
index 76ad2146f1..db5a192287 100644
--- a/indra/newview/llfloateruipreview.cpp
+++ b/indra/newview/llfloateruipreview.cpp
@@ -60,6 +60,7 @@
#include "llfloaterreg.h"
#include "llscrollcontainer.h" // scroll container for overlapping elements
#include "lllivefile.h" // live file poll/stat/reload
+#include "llviewermenufile.h" // LLFilePickerReplyThread
// Boost (for linux/unix command-line execv)
#include <boost/tokenizer.hpp>
@@ -206,7 +207,9 @@ private:
void onClickSaveAll(S32 id);
void onClickEditFloater();
void onClickBrowseForEditor();
+ void getExecutablePath(const std::vector<std::string>& filenames);
void onClickBrowseForDiffs();
+ void getDiffsFilePath(const std::vector<std::string>& filenames);
void onClickToggleDiffHighlighting();
void onClickToggleOverlapping();
void onClickCloseDisplayedFloater(S32 id);
@@ -1019,15 +1022,14 @@ void LLFloaterUIPreview::onClickEditFloater()
// Respond to button click to browse for an executable with which to edit XML files
void LLFloaterUIPreview::onClickBrowseForEditor()
{
- // Let the user choose an executable through the file picker dialog box
- LLFilePicker& picker = LLFilePicker::instance();
- if (!picker.getOpenFile(LLFilePicker::FFLOAD_EXE))
- {
- return; // user cancelled -- do nothing
- }
+ // Let the user choose an executable through the file picker dialog box
+ (new LLFilePickerReplyThread(boost::bind(&LLFloaterUIPreview::getExecutablePath, this, _1), LLFilePicker::FFLOAD_EXE, false))->getFile();
+}
+void LLFloaterUIPreview::getExecutablePath(const std::vector<std::string>& filenames)
+{
// put the selected path into text field
- const std::string chosen_path = picker.getFirstFile();
+ const std::string chosen_path = filenames[0];
std::string executable_path = chosen_path;
#if LL_DARWIN
// on Mac, if it's an application bundle, figure out the actual path from the Info.plist file
@@ -1075,15 +1077,13 @@ void LLFloaterUIPreview::onClickBrowseForEditor()
void LLFloaterUIPreview::onClickBrowseForDiffs()
{
// create load dialog box
- LLFilePicker::ELoadFilter type = (LLFilePicker::ELoadFilter)((intptr_t)((void*)LLFilePicker::FFLOAD_XML)); // nothing for *.exe so just use all
- LLFilePicker& picker = LLFilePicker::instance();
- if (!picker.getOpenFile(type)) // user cancelled -- do nothing
- {
- return;
- }
+ (new LLFilePickerReplyThread(boost::bind(&LLFloaterUIPreview::getDiffsFilePath, this, _1), LLFilePicker::FFLOAD_XML, false))->getFile();
+}
+void LLFloaterUIPreview::getDiffsFilePath(const std::vector<std::string>& filenames)
+{
// put the selected path into text field
- const std::string chosen_path = picker.getFirstFile();
+ const std::string chosen_path = filenames[0];
mDiffPathTextBox->setText(std::string(chosen_path)); // copy the path to the executable to the textfield for display and later fetching
if(LLView::sHighlightingDiffs) // if we're already highlighting, toggle off and then on so we get the data from the new file
{
diff --git a/indra/newview/llimprocessing.cpp b/indra/newview/llimprocessing.cpp
index e76b3d118e..d59c301210 100644
--- a/indra/newview/llimprocessing.cpp
+++ b/indra/newview/llimprocessing.cpp
@@ -854,15 +854,33 @@ void LLIMProcessing::processNewMessage(LLUUID from_id,
}
else // IM_TASK_INVENTORY_OFFERED
{
- if (sizeof(S8) != binary_bucket_size)
+ if (offline == IM_OFFLINE && session_id.isNull() && aux_id.notNull() && binary_bucket_size > sizeof(S8)* 5)
{
- LL_WARNS("Messaging") << "Malformed inventory offer from object" << LL_ENDL;
- delete info;
- break;
+ // cap received offline message
+ std::string str_bucket = ll_safe_string((char*)binary_bucket, binary_bucket_size);
+ typedef boost::tokenizer<boost::char_separator<char> > tokenizer;
+ boost::char_separator<char> sep("|", "", boost::keep_empty_tokens);
+ tokenizer tokens(str_bucket, sep);
+ tokenizer::iterator iter = tokens.begin();
+
+ info->mType = (LLAssetType::EType)(atoi((*(iter++)).c_str()));
+ // Note There is more elements in 'tokens' ...
+
+ info->mObjectID = LLUUID::null;
+ info->mFromObject = TRUE;
+ }
+ else
+ {
+ if (sizeof(S8) != binary_bucket_size)
+ {
+ LL_WARNS("Messaging") << "Malformed inventory offer from object" << LL_ENDL;
+ delete info;
+ break;
+ }
+ info->mType = (LLAssetType::EType) binary_bucket[0];
+ info->mObjectID = LLUUID::null;
+ info->mFromObject = TRUE;
}
- info->mType = (LLAssetType::EType) binary_bucket[0];
- info->mObjectID = LLUUID::null;
- info->mFromObject = TRUE;
}
info->mIM = dialog;
diff --git a/indra/newview/llmanip.cpp b/indra/newview/llmanip.cpp
index 8567180dd6..6589aa477f 100644
--- a/indra/newview/llmanip.cpp
+++ b/indra/newview/llmanip.cpp
@@ -431,7 +431,6 @@ void LLManip::renderXYZ(const LLVector3 &vec)
{
const S32 PAD = 10;
std::string feedback_string;
- LLVector3 camera_pos = LLViewerCamera::getInstance()->getOrigin() + LLViewerCamera::getInstance()->getAtAxis();
S32 window_center_x = gViewerWindow->getWorldViewRectScaled().getWidth() / 2;
S32 window_center_y = gViewerWindow->getWorldViewRectScaled().getHeight() / 2;
S32 vertical_offset = window_center_y - VERTICAL_OFFSET;
@@ -442,46 +441,55 @@ void LLManip::renderXYZ(const LLVector3 &vec)
LLUIImagePtr imagep = LLUI::getUIImage("Rounded_Square");
gViewerWindow->setup2DRender();
const LLVector2& display_scale = gViewerWindow->getDisplayScale();
- gGL.scalef(display_scale.mV[VX], display_scale.mV[VY], 1.f);
gGL.color4f(0.f, 0.f, 0.f, 0.7f);
imagep->draw(
- window_center_x - 115,
- window_center_y + vertical_offset - PAD,
- 235,
- PAD * 2 + 10,
+ (window_center_x - 115) * display_scale.mV[VX],
+ (window_center_y + vertical_offset - PAD) * display_scale.mV[VY],
+ 235 * display_scale.mV[VX],
+ (PAD * 2 + 10) * display_scale.mV[VY],
LLColor4(0.f, 0.f, 0.f, 0.7f) );
- }
- gGL.popMatrix();
-
- gViewerWindow->setup3DRender();
- {
- LLFontGL* font = LLFontGL::getFontSansSerif();
- LLLocale locale(LLLocale::USER_LOCALE);
- LLGLDepthTest gls_depth(GL_FALSE);
- // render drop shadowed text
- feedback_string = llformat("X: %.3f", vec.mV[VX]);
- hud_render_text(utf8str_to_wstring(feedback_string), camera_pos, *font, LLFontGL::NORMAL, LLFontGL::NO_SHADOW, -102.f + 1.f, (F32)vertical_offset - 1.f, LLColor4::black, FALSE);
-
- feedback_string = llformat("Y: %.3f", vec.mV[VY]);
- hud_render_text(utf8str_to_wstring(feedback_string), camera_pos, *font, LLFontGL::NORMAL, LLFontGL::NO_SHADOW, -27.f + 1.f, (F32)vertical_offset - 1.f, LLColor4::black, FALSE);
-
- feedback_string = llformat("Z: %.3f", vec.mV[VZ]);
- hud_render_text(utf8str_to_wstring(feedback_string), camera_pos, *font, LLFontGL::NORMAL, LLFontGL::NO_SHADOW, 48.f + 1.f, (F32)vertical_offset - 1.f, LLColor4::black, FALSE);
-
- // render text on top
- feedback_string = llformat("X: %.3f", vec.mV[VX]);
- hud_render_text(utf8str_to_wstring(feedback_string), camera_pos, *font, LLFontGL::NORMAL, LLFontGL::NO_SHADOW, -102.f, (F32)vertical_offset, LLColor4(1.f, 0.5f, 0.5f, 1.f), FALSE);
-
- gGL.diffuseColor3f(0.5f, 1.f, 0.5f);
- feedback_string = llformat("Y: %.3f", vec.mV[VY]);
- hud_render_text(utf8str_to_wstring(feedback_string), camera_pos, *font, LLFontGL::NORMAL, LLFontGL::NO_SHADOW, -27.f, (F32)vertical_offset, LLColor4(0.5f, 1.f, 0.5f, 1.f), FALSE);
-
- gGL.diffuseColor3f(0.5f, 0.5f, 1.f);
- feedback_string = llformat("Z: %.3f", vec.mV[VZ]);
- hud_render_text(utf8str_to_wstring(feedback_string), camera_pos, *font, LLFontGL::NORMAL, LLFontGL::NO_SHADOW, 48.f, (F32)vertical_offset, LLColor4(0.5f, 0.5f, 1.f, 1.f), FALSE);
- }
+ LLFontGL* font = LLFontGL::getFontSansSerif();
+ LLLocale locale(LLLocale::USER_LOCALE);
+ LLGLDepthTest gls_depth(GL_FALSE);
+
+ // render drop shadowed text (manually because of bigger 'distance')
+ F32 right_x;
+ feedback_string = llformat("X: %.3f", vec.mV[VX]);
+ font->render(utf8str_to_wstring(feedback_string), 0, window_center_x - 102.f + 1.f, window_center_y + vertical_offset - 2.f, LLColor4::black,
+ LLFontGL::LEFT, LLFontGL::BASELINE,
+ LLFontGL::NORMAL, LLFontGL::NO_SHADOW, S32_MAX, 1000, &right_x);
+
+ feedback_string = llformat("Y: %.3f", vec.mV[VY]);
+ font->render(utf8str_to_wstring(feedback_string), 0, window_center_x - 27.f + 1.f, window_center_y + vertical_offset - 2.f, LLColor4::black,
+ LLFontGL::LEFT, LLFontGL::BASELINE,
+ LLFontGL::NORMAL, LLFontGL::NO_SHADOW, S32_MAX, 1000, &right_x);
+
+ feedback_string = llformat("Z: %.3f", vec.mV[VZ]);
+ font->render(utf8str_to_wstring(feedback_string), 0, window_center_x + 48.f + 1.f, window_center_y + vertical_offset - 2.f, LLColor4::black,
+ LLFontGL::LEFT, LLFontGL::BASELINE,
+ LLFontGL::NORMAL, LLFontGL::NO_SHADOW, S32_MAX, 1000, &right_x);
+
+ // render text on top
+ feedback_string = llformat("X: %.3f", vec.mV[VX]);
+ font->render(utf8str_to_wstring(feedback_string), 0, window_center_x - 102.f, window_center_y + vertical_offset, LLColor4(1.f, 0.5f, 0.5f, 1.f),
+ LLFontGL::LEFT, LLFontGL::BASELINE,
+ LLFontGL::NORMAL, LLFontGL::NO_SHADOW, S32_MAX, 1000, &right_x);
+
+ feedback_string = llformat("Y: %.3f", vec.mV[VY]);
+ font->render(utf8str_to_wstring(feedback_string), 0, window_center_x - 27.f, window_center_y + vertical_offset, LLColor4(0.5f, 1.f, 0.5f, 1.f),
+ LLFontGL::LEFT, LLFontGL::BASELINE,
+ LLFontGL::NORMAL, LLFontGL::NO_SHADOW, S32_MAX, 1000, &right_x);
+
+ feedback_string = llformat("Z: %.3f", vec.mV[VZ]);
+ font->render(utf8str_to_wstring(feedback_string), 0, window_center_x + 48.f, window_center_y + vertical_offset, LLColor4(0.5f, 0.5f, 1.f, 1.f),
+ LLFontGL::LEFT, LLFontGL::BASELINE,
+ LLFontGL::NORMAL, LLFontGL::NO_SHADOW, S32_MAX, 1000, &right_x);
+ }
+ gGL.popMatrix();
+
+ gViewerWindow->setup3DRender();
}
void LLManip::renderTickText(const LLVector3& pos, const std::string& text, const LLColor4 &color)
diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp
index e38bd8846d..f32dad7f55 100644
--- a/indra/newview/llmeshrepository.cpp
+++ b/indra/newview/llmeshrepository.cpp
@@ -2174,7 +2174,6 @@ void LLMeshUploadThread::wholeModelToLLSD(LLSD& dest, bool include_textures)
std::map<LLModel*,S32> mesh_index;
std::string model_name;
- std::string model_metric;
S32 instance_num = 0;
@@ -2204,11 +2203,6 @@ void LLMeshUploadThread::wholeModelToLLSD(LLSD& dest, bool include_textures)
model_name = data.mBaseModel->getName();
}
- if (model_metric.empty())
- {
- model_metric = data.mBaseModel->getMetric();
- }
-
std::stringstream ostr;
LLModel::Decomposition& decomp =
@@ -2363,11 +2357,6 @@ void LLMeshUploadThread::wholeModelToLLSD(LLSD& dest, bool include_textures)
model_name = data.mBaseModel->getName();
}
- if (model_metric.empty())
- {
- model_metric = data.mBaseModel->getMetric();
- }
-
std::stringstream ostr;
LLModel::Decomposition& decomp =
@@ -2498,8 +2487,7 @@ void LLMeshUploadThread::wholeModelToLLSD(LLSD& dest, bool include_textures)
if (model_name.empty()) model_name = "mesh model";
result["name"] = model_name;
- if (model_metric.empty()) model_metric = "MUT_Unspecified";
- res["metric"] = model_metric;
+ res["metric"] = "MUT_Unspecified";
result["asset_resources"] = res;
dump_llsd_to_file(result,make_dump_name("whole_model_",dump_num));
@@ -4302,10 +4290,13 @@ F32 LLMeshRepository::getStreamingCostLegacy(LLSD& header, F32 radius, S32* byte
F32 dlow = llmin(radius/0.06f, max_distance);
F32 dmid = llmin(radius/0.24f, max_distance);
- F32 METADATA_DISCOUNT = (F32) gSavedSettings.getU32("MeshMetaDataDiscount"); //discount 128 bytes to cover the cost of LLSD tags and compression domain overhead
- F32 MINIMUM_SIZE = (F32) gSavedSettings.getU32("MeshMinimumByteSize"); //make sure nothing is "free"
+ static LLCachedControl<U32> metadata_discount_ch(gSavedSettings, "MeshMetaDataDiscount", 384); //discount 128 bytes to cover the cost of LLSD tags and compression domain overhead
+ static LLCachedControl<U32> minimum_size_ch(gSavedSettings, "MeshMinimumByteSize", 16); //make sure nothing is "free"
+ static LLCachedControl<U32> bytes_per_triangle_ch(gSavedSettings, "MeshBytesPerTriangle", 16);
- F32 bytes_per_triangle = (F32) gSavedSettings.getU32("MeshBytesPerTriangle");
+ F32 metadata_discount = (F32)metadata_discount_ch;
+ F32 minimum_size = (F32)minimum_size_ch;
+ F32 bytes_per_triangle = (F32)bytes_per_triangle_ch;
S32 bytes_lowest = header["lowest_lod"]["size"].asInteger();
S32 bytes_low = header["low_lod"]["size"].asInteger();
@@ -4332,10 +4323,10 @@ F32 LLMeshRepository::getStreamingCostLegacy(LLSD& header, F32 radius, S32* byte
bytes_lowest = bytes_low;
}
- F32 triangles_lowest = llmax((F32) bytes_lowest-METADATA_DISCOUNT, MINIMUM_SIZE)/bytes_per_triangle;
- F32 triangles_low = llmax((F32) bytes_low-METADATA_DISCOUNT, MINIMUM_SIZE)/bytes_per_triangle;
- F32 triangles_mid = llmax((F32) bytes_mid-METADATA_DISCOUNT, MINIMUM_SIZE)/bytes_per_triangle;
- F32 triangles_high = llmax((F32) bytes_high-METADATA_DISCOUNT, MINIMUM_SIZE)/bytes_per_triangle;
+ F32 triangles_lowest = llmax((F32) bytes_lowest-metadata_discount, minimum_size)/bytes_per_triangle;
+ F32 triangles_low = llmax((F32) bytes_low-metadata_discount, minimum_size)/bytes_per_triangle;
+ F32 triangles_mid = llmax((F32) bytes_mid-metadata_discount, minimum_size)/bytes_per_triangle;
+ F32 triangles_high = llmax((F32) bytes_high-metadata_discount, minimum_size)/bytes_per_triangle;
if (bytes)
{
@@ -4429,13 +4420,13 @@ bool LLMeshCostData::init(const LLSD& header)
mSizeByLOD[2] = bytes_med;
mSizeByLOD[3] = bytes_high;
- F32 METADATA_DISCOUNT = (F32) gSavedSettings.getU32("MeshMetaDataDiscount"); //discount 128 bytes to cover the cost of LLSD tags and compression domain overhead
- F32 MINIMUM_SIZE = (F32) gSavedSettings.getU32("MeshMinimumByteSize"); //make sure nothing is "free"
- F32 bytes_per_triangle = (F32) gSavedSettings.getU32("MeshBytesPerTriangle");
+ static LLCachedControl<U32> metadata_discount(gSavedSettings, "MeshMetaDataDiscount", 384); //discount 128 bytes to cover the cost of LLSD tags and compression domain overhead
+ static LLCachedControl<U32> minimum_size(gSavedSettings, "MeshMinimumByteSize", 16); //make sure nothing is "free"
+ static LLCachedControl<U32> bytes_per_triangle(gSavedSettings, "MeshBytesPerTriangle", 16);
for (S32 i=0; i<4; i++)
{
- mEstTrisByLOD[i] = llmax((F32) mSizeByLOD[i]-METADATA_DISCOUNT, MINIMUM_SIZE)/bytes_per_triangle;
+ mEstTrisByLOD[i] = llmax((F32)mSizeByLOD[i] - (F32)metadata_discount, (F32)minimum_size) / (F32)bytes_per_triangle;
}
return true;
diff --git a/indra/newview/llmoveview.cpp b/indra/newview/llmoveview.cpp
index 301487b994..19f238d99a 100644
--- a/indra/newview/llmoveview.cpp
+++ b/indra/newview/llmoveview.cpp
@@ -702,11 +702,9 @@ void LLPanelStandStopFlying::updatePosition()
{
if (mAttached) return;
- S32 y_pos = 0;
S32 bottom_tb_center = 0;
if (LLToolBar* toolbar_bottom = gToolBarView->getToolbar(LLToolBarEnums::TOOLBAR_BOTTOM))
{
- y_pos = toolbar_bottom->getRect().getHeight();
bottom_tb_center = toolbar_bottom->getRect().getCenterX();
}
@@ -716,20 +714,6 @@ void LLPanelStandStopFlying::updatePosition()
left_tb_width = toolbar_left->getRect().getWidth();
}
- if (!mStateManagementButtons.get()) // Obsolete?!!
- {
- LLPanel* panel_ssf_container = gToolBarView->getChild<LLPanel>("state_management_buttons_container");
- if (panel_ssf_container)
- {
- mStateManagementButtons = panel_ssf_container->getHandle();
- }
- }
-
- if(LLPanel* panel_ssf_container = mStateManagementButtons.get())
- {
- panel_ssf_container->setOrigin(0, y_pos);
- }
-
if (gToolBarView != NULL && gToolBarView->getToolbar(LLToolBarEnums::TOOLBAR_LEFT)->hasButtons())
{
S32 x_pos = bottom_tb_center - getRect().getWidth() / 2 - left_tb_width;
diff --git a/indra/newview/llmoveview.h b/indra/newview/llmoveview.h
index 4a31f2a814..e8b9a6fdb2 100644
--- a/indra/newview/llmoveview.h
+++ b/indra/newview/llmoveview.h
@@ -172,8 +172,6 @@ private:
*/
LLHandle<LLPanel> mOriginalParent;
- LLHandle<LLPanel> mStateManagementButtons;
-
/**
* True if the panel is currently attached to the movement controls floater.
*
diff --git a/indra/newview/llnotificationlistitem.cpp b/indra/newview/llnotificationlistitem.cpp
index a5bc75e6bd..b405d3dca2 100644
--- a/indra/newview/llnotificationlistitem.cpp
+++ b/indra/newview/llnotificationlistitem.cpp
@@ -135,7 +135,8 @@ std::string LLNotificationListItem::buildNotificationDate(const LLDate& time_sta
+LLTrans::getString("TimeDay")+"]/["
+LLTrans::getString("TimeYear")+"] ["
+LLTrans::getString("TimeHour")+"]:["
- +LLTrans::getString("TimeMin")+"]";
+ +LLTrans::getString("TimeMin")+"] ["
+ +LLTrans::getString("TimeTimezone")+"]";
break;
}
LLSD substitution;
@@ -376,13 +377,13 @@ BOOL LLGroupNoticeNotificationListItem::postBuild()
mTitleBoxExp->setValue(mParams.subject);
mNoticeTextExp->setValue(mParams.message);
- mTimeBox->setValue(buildNotificationDate(mParams.time_stamp, UTC));
- mTimeBoxExp->setValue(buildNotificationDate(mParams.time_stamp, UTC));
+ mTimeBox->setValue(buildNotificationDate(mParams.time_stamp));
+ mTimeBoxExp->setValue(buildNotificationDate(mParams.time_stamp));
//Workaround: in case server timestamp is 0 - we use the time when notification was actually received
if (mParams.time_stamp.isNull())
{
- mTimeBox->setValue(buildNotificationDate(mParams.received_time, UTC));
- mTimeBoxExp->setValue(buildNotificationDate(mParams.received_time, UTC));
+ mTimeBox->setValue(buildNotificationDate(mParams.received_time));
+ mTimeBoxExp->setValue(buildNotificationDate(mParams.received_time));
}
setSender(mParams.sender);
diff --git a/indra/newview/llpanelgroupgeneral.cpp b/indra/newview/llpanelgroupgeneral.cpp
index f85a2ffbc1..b53cd222e7 100644
--- a/indra/newview/llpanelgroupgeneral.cpp
+++ b/indra/newview/llpanelgroupgeneral.cpp
@@ -461,11 +461,12 @@ bool LLPanelGroupGeneral::createGroupCallback(const LLSD& notification, const LL
// Yay! We are making a new group!
U32 enrollment_fee = (mCtrlEnrollmentFee->get() ?
(U32) mSpinEnrollmentFee->get() : 0);
-
+ LLUUID insignia_id = mInsignia->getImageItemID().isNull() ? LLUUID::null : mInsignia->getImageAssetID();
+
LLGroupMgr::getInstance()->sendCreateGroupRequest(mGroupNameEditor->getText(),
mEditCharter->getText(),
mCtrlShowInGroupList->get(),
- mInsignia->getImageAssetID(),
+ insignia_id,
enrollment_fee,
mCtrlOpenEnrollment->get(),
false,
diff --git a/indra/newview/lltexturecache.cpp b/indra/newview/lltexturecache.cpp
index 633e025478..eb4b914e18 100644
--- a/indra/newview/lltexturecache.cpp
+++ b/indra/newview/lltexturecache.cpp
@@ -1038,11 +1038,11 @@ S64 LLTextureCache::initCache(ELLPath location, S64 max_size, BOOL texture_cache
{
llassert_always(getPending() == 0) ; //should not start accessing the texture cache before initialized.
- S64 header_size = (max_size / 100) * 36; //0.36 * max_size
- S64 max_entries = header_size / (TEXTURE_CACHE_ENTRY_SIZE + TEXTURE_FAST_CACHE_ENTRY_SIZE);
+ S64 entries_size = (max_size * 36) / 100; //0.36 * max_size
+ S64 max_entries = entries_size / (TEXTURE_CACHE_ENTRY_SIZE + TEXTURE_FAST_CACHE_ENTRY_SIZE);
sCacheMaxEntries = (S32)(llmin((S64)sCacheMaxEntries, max_entries));
- header_size = sCacheMaxEntries * TEXTURE_CACHE_ENTRY_SIZE;
- max_size -= header_size;
+ entries_size = sCacheMaxEntries * (TEXTURE_CACHE_ENTRY_SIZE + TEXTURE_FAST_CACHE_ENTRY_SIZE);
+ max_size -= entries_size;
if (sCacheMaxTexturesSize > 0)
sCacheMaxTexturesSize = llmin(sCacheMaxTexturesSize, max_size);
else
diff --git a/indra/newview/lltoastgroupnotifypanel.cpp b/indra/newview/lltoastgroupnotifypanel.cpp
index f7dc32d0d7..817d1dd7b4 100644
--- a/indra/newview/lltoastgroupnotifypanel.cpp
+++ b/indra/newview/lltoastgroupnotifypanel.cpp
@@ -84,14 +84,14 @@ LLToastGroupNotifyPanel::LLToastGroupNotifyPanel(const LLNotificationPtr& notifi
//message body
const std::string& message = payload["message"].asString();
- std::string timeStr = "["+LLTrans::getString("UTCTimeWeek")+"],["
- +LLTrans::getString("UTCTimeDay")+"] ["
- +LLTrans::getString("UTCTimeMth")+"] ["
- +LLTrans::getString("UTCTimeYr")+"] ["
- +LLTrans::getString("UTCTimeHr")+"]:["
- +LLTrans::getString("UTCTimeMin")+"]:["
- +LLTrans::getString("UTCTimeSec")+"] ["
- +LLTrans::getString("UTCTimeTimezone")+"]";
+ std::string timeStr = "[" + LLTrans::getString("TimeWeek") + "], ["
+ + LLTrans::getString("TimeMonth") + "]/["
+ + LLTrans::getString("TimeDay") + "]/["
+ + LLTrans::getString("TimeYear") + "] ["
+ + LLTrans::getString("TimeHour") + "]:["
+ + LLTrans::getString("TimeMin") + "] ["
+ + LLTrans::getString("TimeTimezone") + "]";
+
const LLDate timeStamp = notification->getDate();
LLDate notice_date = timeStamp.notNull() ? timeStamp : payload["received_time"].asDate();
LLSD substitution;
diff --git a/indra/newview/lltoastnotifypanel.cpp b/indra/newview/lltoastnotifypanel.cpp
index e3a856be5c..a2116817a2 100644
--- a/indra/newview/lltoastnotifypanel.cpp
+++ b/indra/newview/lltoastnotifypanel.cpp
@@ -46,8 +46,6 @@
const S32 BOTTOM_PAD = VPAD * 3;
const S32 IGNORE_BTN_TOP_DELTA = 3*VPAD;//additional ignore_btn padding
S32 BUTTON_WIDTH = 90;
-// *TODO: magic numbers - copied from llnotify.cpp(250)
-const S32 MAX_LENGTH = 512 + 20 + DB_FIRST_NAME_BUF_SIZE + DB_LAST_NAME_BUF_SIZE + DB_INV_ITEM_NAME_BUF_SIZE;
//static
@@ -319,7 +317,7 @@ void LLToastNotifyPanel::init( LLRect rect, bool show_images )
mTextBox = getChild<LLTextEditor>("text_editor_box");
}
- mTextBox->setMaxTextLength(MAX_LENGTH);
+ mTextBox->setMaxTextLength(LLToastPanel::MAX_TEXT_LENGTH);
mTextBox->setVisible(TRUE);
mTextBox->setPlainText(!show_images);
mTextBox->setContentTrusted(is_content_trusted);
@@ -411,7 +409,7 @@ void LLToastNotifyPanel::init( LLRect rect, bool show_images )
//.xml file intially makes info panel only follow left/right/top. This is so that when control buttons are added the info panel
//can shift upward making room for the buttons inside mControlPanel. After the buttons are added, the info panel can then be set to follow 'all'.
mInfoPanel->setFollowsAll();
- snapToMessageHeight(mTextBox, MAX_LENGTH);
+ snapToMessageHeight(mTextBox, LLToastPanel::MAX_TEXT_LENGTH);
// reshape the panel to its previous size
if (current_rect.notEmpty())
@@ -472,7 +470,7 @@ void LLIMToastNotifyPanel::snapToMessageHeight()
//Add message height if it is visible
if (mTextBox->getVisible())
{
- S32 new_panel_height = computeSnappedToMessageHeight(mTextBox, MAX_LENGTH);
+ S32 new_panel_height = computeSnappedToMessageHeight(mTextBox, LLToastPanel::MAX_TEXT_LENGTH);
//reshape the panel with new height
if (new_panel_height != getRect().getHeight())
diff --git a/indra/newview/lltoastpanel.cpp b/indra/newview/lltoastpanel.cpp
index e1b764a943..7c624d5b50 100644
--- a/indra/newview/lltoastpanel.cpp
+++ b/indra/newview/lltoastpanel.cpp
@@ -26,6 +26,7 @@
#include "llviewerprecompiledheaders.h"
+#include "lldbstrings.h"
#include "llpanelgenerictip.h"
#include "llpanelonlinestatus.h"
#include "llnotifications.h"
@@ -35,6 +36,8 @@
//static
const S32 LLToastPanel::MIN_PANEL_HEIGHT = 40; // VPAD(4)*2 + ICON_HEIGHT(32)
+// 'magic numbers', consider initializing (512+20) part from xml/notifications
+const S32 LLToastPanel::MAX_TEXT_LENGTH = 512 + 20 + DB_FIRST_NAME_BUF_SIZE + DB_LAST_NAME_BUF_SIZE + DB_INV_ITEM_NAME_BUF_SIZE;
LLToastPanel::LLToastPanel(const LLNotificationPtr& notification)
{
diff --git a/indra/newview/lltoastpanel.h b/indra/newview/lltoastpanel.h
index 51630381f2..6a9b72a5ae 100644
--- a/indra/newview/lltoastpanel.h
+++ b/indra/newview/lltoastpanel.h
@@ -49,6 +49,7 @@ public:
virtual const LLUUID& getID();
static const S32 MIN_PANEL_HEIGHT;
+ static const S32 MAX_TEXT_LENGTH;
/**
* Builder method for constructing notification specific panels.
diff --git a/indra/newview/lltoastscripttextbox.cpp b/indra/newview/lltoastscripttextbox.cpp
index 518c6c0ee4..eb86a44055 100644
--- a/indra/newview/lltoastscripttextbox.cpp
+++ b/indra/newview/lltoastscripttextbox.cpp
@@ -36,8 +36,6 @@
#include "llviewertexteditor.h"
const S32 LLToastScriptTextbox::DEFAULT_MESSAGE_MAX_LINE_COUNT= 14;
-// *TODO: magic numbers - copied from lltoastnotifypanel.cpp(50) which was copied from llnotify.cpp(250)
-const S32 MAX_LENGTH = 512 + 20 + DB_FIRST_NAME_BUF_SIZE + DB_LAST_NAME_BUF_SIZE + DB_INV_ITEM_NAME_BUF_SIZE;
LLToastScriptTextbox::LLToastScriptTextbox(const LLNotificationPtr& notification)
: LLToastPanel(notification)
@@ -45,7 +43,7 @@ LLToastScriptTextbox::LLToastScriptTextbox(const LLNotificationPtr& notification
buildFromFile( "panel_notify_textbox.xml");
mInfoText = getChild<LLTextEditor>("text_editor_box");
- mInfoText->setMaxTextLength(MAX_LENGTH);
+ mInfoText->setMaxTextLength(LLToastPanel::MAX_TEXT_LENGTH);
mInfoText->setValue(notification->getMessage());
getChild<LLButton>("ignore_btn")->setClickedCallback(boost::bind(&LLToastScriptTextbox::onClickIgnore, this));
diff --git a/indra/newview/lltool.cpp b/indra/newview/lltool.cpp
index 4aad650b68..b5d78f3654 100644
--- a/indra/newview/lltool.cpp
+++ b/indra/newview/lltool.cpp
@@ -191,7 +191,9 @@ LLTool* LLTool::getOverrideTool(MASK mask)
{
return NULL;
}
- if (gSavedSettings.getBOOL("EnableAltZoom"))
+
+ static LLCachedControl<bool> alt_zoom(gSavedSettings, "EnableAltZoom", true);
+ if (alt_zoom)
{
if (mask & MASK_ALT)
{
diff --git a/indra/newview/lltoolpie.cpp b/indra/newview/lltoolpie.cpp
index 9e37ca0394..697db01d11 100644
--- a/indra/newview/lltoolpie.cpp
+++ b/indra/newview/lltoolpie.cpp
@@ -111,11 +111,24 @@ BOOL LLToolPie::handleMouseDown(S32 x, S32 y, MASK mask)
mMouseOutsideSlop = FALSE;
mMouseDownX = x;
mMouseDownY = y;
- LLTimer pick_timer;
- BOOL pick_rigged = false; //gSavedSettings.getBOOL("AnimatedObjectsAllowLeftClick");
- //left mouse down always picks transparent (but see handleMouseUp)
- mPick = gViewerWindow->pickImmediate(x, y, TRUE, pick_rigged);
- LL_INFOS() << "pick_rigged is " << (S32) pick_rigged << " pick time elapsed " << pick_timer.getElapsedTimeF32() << LL_ENDL;
+ LLTimer pick_timer;
+ BOOL pick_rigged = false; //gSavedSettings.getBOOL("AnimatedObjectsAllowLeftClick");
+ mPick = gViewerWindow->pickImmediate(x, y, FALSE, pick_rigged);
+ LLViewerObject *object = mPick.getObject();
+ LLViewerObject *parent = object ? object->getRootEdit() : NULL;
+ if (!object
+ || object->isAttachment()
+ || object->getClickAction() == CLICK_ACTION_DISABLED
+ || (!useClickAction(mask, object, parent) && !object->flagHandleTouch() && !(parent && parent->flagHandleTouch())))
+ {
+ // Unless we are hovering over actionable visible object
+ // left mouse down always picks transparent (but see handleMouseUp).
+ // Also see LLToolPie::handleHover() - priorities are a bit different there.
+ // Todo: we need a more consistent set of rules to work with
+ mPick = gViewerWindow->pickImmediate(x, y, TRUE /*transparent*/, pick_rigged);
+ }
+ LL_INFOS() << "pick_rigged is " << (S32) pick_rigged << " pick time elapsed " << pick_timer.getElapsedTimeF32() << LL_ENDL;
+
mPick.mKeyMask = mask;
mMouseButtonDown = true;
@@ -857,13 +870,11 @@ static bool needs_tooltip(LLSelectNode* nodep)
BOOL LLToolPie::handleTooltipLand(std::string line, std::string tooltip_msg)
{
- LLViewerParcelMgr::getInstance()->setHoverParcel( mHoverPick.mPosGlobal );
- //
- // Do not show hover for land unless prefs are set to allow it.
- //
-
+ // Do not show hover for land unless prefs are set to allow it.
if (!gSavedSettings.getBOOL("ShowLandHoverTip")) return TRUE;
-
+
+ LLViewerParcelMgr::getInstance()->setHoverParcel( mHoverPick.mPosGlobal );
+
// Didn't hit an object, but since we have a land point we
// must be hovering over land.
diff --git a/indra/newview/llviewercontrol.cpp b/indra/newview/llviewercontrol.cpp
index 88984d518a..a699491e1b 100644
--- a/indra/newview/llviewercontrol.cpp
+++ b/indra/newview/llviewercontrol.cpp
@@ -219,20 +219,20 @@ static bool handleAnisotropicChanged(const LLSD& newvalue)
static bool handleVolumeLODChanged(const LLSD& newvalue)
{
- LLVOVolume::sLODFactor = (F32) newvalue.asReal();
+ LLVOVolume::sLODFactor = llclamp((F32) newvalue.asReal(), 0.01f, MAX_LOD_FACTOR);
LLVOVolume::sDistanceFactor = 1.f-LLVOVolume::sLODFactor * 0.1f;
return true;
}
static bool handleAvatarLODChanged(const LLSD& newvalue)
{
- LLVOAvatar::sLODFactor = (F32) newvalue.asReal();
+ LLVOAvatar::sLODFactor = llclamp((F32) newvalue.asReal(), 0.f, MAX_AVATAR_LOD_FACTOR);
return true;
}
static bool handleAvatarPhysicsLODChanged(const LLSD& newvalue)
{
- LLVOAvatar::sPhysicsLODFactor = (F32) newvalue.asReal();
+ LLVOAvatar::sPhysicsLODFactor = llclamp((F32) newvalue.asReal(), 0.f, MAX_AVATAR_LOD_FACTOR);
return true;
}
diff --git a/indra/newview/llviewermedia.cpp b/indra/newview/llviewermedia.cpp
index 22a21c9ca3..f4e1524371 100644
--- a/indra/newview/llviewermedia.cpp
+++ b/indra/newview/llviewermedia.cpp
@@ -682,8 +682,8 @@ void LLViewerMedia::updateMedia(void *dummy_arg)
std::vector<LLViewerMediaImpl*> proximity_order;
- bool inworld_media_enabled = gSavedSettings.getBOOL("AudioStreamingMedia");
- bool inworld_audio_enabled = gSavedSettings.getBOOL("AudioStreamingMusic");
+ static LLCachedControl<bool> inworld_media_enabled(gSavedSettings, "AudioStreamingMedia", true);
+ static LLCachedControl<bool> inworld_audio_enabled(gSavedSettings, "AudioStreamingMusic", true);
U32 max_instances = gSavedSettings.getU32("PluginInstancesTotal");
U32 max_normal = gSavedSettings.getU32("PluginInstancesNormal");
U32 max_low = gSavedSettings.getU32("PluginInstancesLow");
@@ -941,7 +941,8 @@ void LLViewerMedia::setAllMediaEnabled(bool val)
LLViewerParcelMedia::play(LLViewerParcelMgr::getInstance()->getAgentParcel());
}
- if (gSavedSettings.getBOOL("AudioStreamingMusic") &&
+ static LLCachedControl<bool> audio_streaming_music(gSavedSettings, "AudioStreamingMusic", true);
+ if (audio_streaming_music &&
!LLViewerMedia::isParcelAudioPlaying() &&
gAudiop &&
LLViewerMedia::hasParcelAudio())
@@ -1012,7 +1013,8 @@ void LLViewerMedia::setAllMediaPaused(bool val)
LLViewerParcelMedia::play(LLViewerParcelMgr::getInstance()->getAgentParcel());
}
- if (gSavedSettings.getBOOL("AudioStreamingMusic") &&
+ static LLCachedControl<bool> audio_streaming_music(gSavedSettings, "AudioStreamingMusic", true);
+ if (audio_streaming_music &&
!LLViewerMedia::isParcelAudioPlaying() &&
gAudiop &&
LLViewerMedia::hasParcelAudio())
diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp
index 1e46a1cf9e..007adf2a72 100644
--- a/indra/newview/llviewerobject.cpp
+++ b/indra/newview/llviewerobject.cpp
@@ -127,6 +127,7 @@ BOOL LLViewerObject::sUseSharedDrawables(FALSE); // TRUE
// sMaxUpdateInterpolationTime must be greater than sPhaseOutUpdateInterpolationTime
F64Seconds LLViewerObject::sMaxUpdateInterpolationTime(3.0); // For motion interpolation: after X seconds with no updates, don't predict object motion
F64Seconds LLViewerObject::sPhaseOutUpdateInterpolationTime(2.0); // For motion interpolation: after Y seconds with no updates, taper off motion prediction
+F64Seconds LLViewerObject::sMaxRegionCrossingInterpolationTime(1.0);// For motion interpolation: don't interpolate over this time on region crossing
std::map<std::string, U32> LLViewerObject::sObjectDataMap;
@@ -260,6 +261,7 @@ LLViewerObject::LLViewerObject(const LLUUID &id, const LLPCode pcode, LLViewerRe
mLastInterpUpdateSecs(0.f),
mLastMessageUpdateSecs(0.f),
mLatestRecvPacketID(0),
+ mRegionCrossExpire(0),
mData(NULL),
mAudioSourcep(NULL),
mAudioGain(1.f),
@@ -2487,7 +2489,7 @@ void LLViewerObject::loadFlags(U32 flags)
return;
}
-void LLViewerObject::idleUpdate(LLAgent &agent, const F64 &time)
+void LLViewerObject::idleUpdate(LLAgent &agent, const F64 &frame_time)
{
//static LLTrace::BlockTimerStatHandle ftm("Viewer Object");
//LL_RECORD_BLOCK_TIME(ftm);
@@ -2498,19 +2500,19 @@ void LLViewerObject::idleUpdate(LLAgent &agent, const F64 &time)
{
// calculate dt from last update
F32 time_dilation = mRegionp ? mRegionp->getTimeDilation() : 1.0f;
- F32 dt_raw = ((F64Seconds)time - mLastInterpUpdateSecs).value();
+ F32 dt_raw = ((F64Seconds)frame_time - mLastInterpUpdateSecs).value();
F32 dt = time_dilation * dt_raw;
applyAngularVelocity(dt);
if (isAttachment())
{
- mLastInterpUpdateSecs = (F64Seconds)time;
+ mLastInterpUpdateSecs = (F64Seconds)frame_time;
return;
}
else
{ // Move object based on it's velocity and rotation
- interpolateLinearMotion(time, dt);
+ interpolateLinearMotion(frame_time, dt);
}
}
@@ -2520,7 +2522,7 @@ void LLViewerObject::idleUpdate(LLAgent &agent, const F64 &time)
// Move an object due to idle-time viewer side updates by interpolating motion
-void LLViewerObject::interpolateLinearMotion(const F64SecondsImplicit& time, const F32SecondsImplicit& dt_seconds)
+void LLViewerObject::interpolateLinearMotion(const F64SecondsImplicit& frame_time, const F32SecondsImplicit& dt_seconds)
{
// linear motion
// PHYSICS_TIMESTEP is used below to correct for the fact that the velocity in object
@@ -2532,7 +2534,7 @@ void LLViewerObject::interpolateLinearMotion(const F64SecondsImplicit& time, con
// zeroing it out
F32 dt = dt_seconds;
- F64Seconds time_since_last_update = time - mLastMessageUpdateSecs;
+ F64Seconds time_since_last_update = frame_time - mLastMessageUpdateSecs;
if (time_since_last_update <= (F64Seconds)0.0 || dt <= 0.f)
{
return;
@@ -2580,7 +2582,7 @@ void LLViewerObject::interpolateLinearMotion(const F64SecondsImplicit& time, con
(time_since_last_packet > sPhaseOutUpdateInterpolationTime))
{
// Start to reduce motion interpolation since we haven't seen a server update in a while
- F64Seconds time_since_last_interpolation = time - mLastInterpUpdateSecs;
+ F64Seconds time_since_last_interpolation = frame_time - mLastInterpUpdateSecs;
F64 phase_out = 1.0;
if (time_since_last_update > sMaxUpdateInterpolationTime)
{ // Past the time limit, so stop the object
@@ -2635,7 +2637,7 @@ void LLViewerObject::interpolateLinearMotion(const F64SecondsImplicit& time, con
new_pos.mV[VZ] = llmax(min_height, new_pos.mV[VZ]);
// Check to see if it's going off the region
- LLVector3 temp(new_pos);
+ LLVector3 temp(new_pos.mV[VX], new_pos.mV[VY], 0.f);
if (temp.clamp(0.f, mRegionp->getWidth()))
{ // Going off this region, so see if we might end up on another region
LLVector3d old_pos_global = mRegionp->getPosGlobalFromRegion(getPositionRegion());
@@ -2644,21 +2646,47 @@ void LLViewerObject::interpolateLinearMotion(const F64SecondsImplicit& time, con
// Clip the positions to known regions
LLVector3d clip_pos_global = LLWorld::getInstance()->clipToVisibleRegions(old_pos_global, new_pos_global);
if (clip_pos_global != new_pos_global)
- { // Was clipped, so this means we hit a edge where there is no region to enter
-
- //LL_INFOS() << "Hit empty region edge, clipped predicted position to " << mRegionp->getPosRegionFromGlobal(clip_pos_global)
- // << " from " << new_pos << LL_ENDL;
- new_pos = mRegionp->getPosRegionFromGlobal(clip_pos_global);
+ {
+ // Was clipped, so this means we hit a edge where there is no region to enter
+ LLVector3 clip_pos = mRegionp->getPosRegionFromGlobal(clip_pos_global);
+ LL_DEBUGS("Interpolate") << "Hit empty region edge, clipped predicted position to "
+ << clip_pos
+ << " from " << new_pos << LL_ENDL;
+ new_pos = clip_pos;
// Stop motion and get server update for bouncing on the edge
new_v.clear();
setAcceleration(LLVector3::zero);
}
else
- { // Let predicted movement cross into another region
- //LL_INFOS() << "Predicting region crossing to " << new_pos << LL_ENDL;
+ {
+ // Check for how long we are crossing.
+ // Note: theoretically we can find time from velocity, acceleration and
+ // distance from border to new position, but it is not going to work
+ // if 'phase_out' activates
+ if (mRegionCrossExpire == 0)
+ {
+ // Workaround: we can't accurately figure out time when we cross border
+ // so just write down time 'after the fact', it is far from optimal in
+ // case of lags, but for lags sMaxUpdateInterpolationTime will kick in first
+ LL_DEBUGS("Interpolate") << "Predicted region crossing, new position " << new_pos << LL_ENDL;
+ mRegionCrossExpire = frame_time + sMaxRegionCrossingInterpolationTime;
+ }
+ else if (frame_time > mRegionCrossExpire)
+ {
+ // Predicting crossing over 1s, stop motion
+ // Stop motion
+ LL_DEBUGS("Interpolate") << "Predicting region crossing for too long, stopping at " << new_pos << LL_ENDL;
+ new_v.clear();
+ setAcceleration(LLVector3::zero);
+ mRegionCrossExpire = 0;
+ }
}
}
+ else
+ {
+ mRegionCrossExpire = 0;
+ }
// Set new position and velocity
setPositionRegion(new_pos);
@@ -2669,7 +2697,7 @@ void LLViewerObject::interpolateLinearMotion(const F64SecondsImplicit& time, con
}
// Update the last time we did anything
- mLastInterpUpdateSecs = time;
+ mLastInterpUpdateSecs = frame_time;
}
diff --git a/indra/newview/llviewerobject.h b/indra/newview/llviewerobject.h
index d6c8b76147..8b1535851e 100644
--- a/indra/newview/llviewerobject.h
+++ b/indra/newview/llviewerobject.h
@@ -615,7 +615,7 @@ private:
U32 checkMediaURL(const std::string &media_url);
// Motion prediction between updates
- void interpolateLinearMotion(const F64SecondsImplicit & time, const F32SecondsImplicit & dt);
+ void interpolateLinearMotion(const F64SecondsImplicit & frame_time, const F32SecondsImplicit & dt);
static void initObjectDataMap();
@@ -772,6 +772,7 @@ protected:
F64Seconds mLastInterpUpdateSecs; // Last update for purposes of interpolation
F64Seconds mLastMessageUpdateSecs; // Last update from a message from the simulator
TPACKETID mLatestRecvPacketID; // Latest time stamp on message from simulator
+ F64SecondsImplicit mRegionCrossExpire; // frame time we detected region crossing in + wait time
// extra data sent from the sim...currently only used for tree species info
U8* mData;
@@ -851,6 +852,7 @@ protected:
static void setPhaseOutUpdateInterpolationTime(F32 value) { sPhaseOutUpdateInterpolationTime = (F64Seconds) value; }
static void setMaxUpdateInterpolationTime(F32 value) { sMaxUpdateInterpolationTime = (F64Seconds) value; }
+ static void setMaxRegionCrossingInterpolationTime(F32 value) { sMaxRegionCrossingInterpolationTime = (F64Seconds) value; }
static void setVelocityInterpolate(BOOL value) { sVelocityInterpolate = value; }
static void setPingInterpolate(BOOL value) { sPingInterpolate = value; }
@@ -860,6 +862,7 @@ private:
static F64Seconds sPhaseOutUpdateInterpolationTime; // For motion interpolation
static F64Seconds sMaxUpdateInterpolationTime; // For motion interpolation
+ static F64Seconds sMaxRegionCrossingInterpolationTime; // For motion interpolation
static BOOL sVelocityInterpolate;
static BOOL sPingInterpolate;
diff --git a/indra/newview/llviewerobjectlist.cpp b/indra/newview/llviewerobjectlist.cpp
index 2aff71367e..932759c86d 100644
--- a/indra/newview/llviewerobjectlist.cpp
+++ b/indra/newview/llviewerobjectlist.cpp
@@ -854,6 +854,7 @@ void LLViewerObjectList::update(LLAgent &agent)
F32 interp_time = gSavedSettings.getF32("InterpolationTime");
F32 phase_out_time = gSavedSettings.getF32("InterpolationPhaseOut");
+ F32 region_interp_time = llclamp(gSavedSettings.getF32("RegionCrossingInterpolationTime"), 0.5f, 5.f);
if (interp_time < 0.0 ||
phase_out_time < 0.0 ||
phase_out_time > interp_time)
@@ -864,6 +865,7 @@ void LLViewerObjectList::update(LLAgent &agent)
}
LLViewerObject::setPhaseOutUpdateInterpolationTime( interp_time );
LLViewerObject::setMaxUpdateInterpolationTime( phase_out_time );
+ LLViewerObject::setMaxRegionCrossingInterpolationTime(region_interp_time);
gAnimateTextures = gSavedSettings.getBOOL("AnimateTextures");
diff --git a/indra/newview/llviewerparcelmgr.cpp b/indra/newview/llviewerparcelmgr.cpp
index f4d14a39fe..416d5d8e2e 100644
--- a/indra/newview/llviewerparcelmgr.cpp
+++ b/indra/newview/llviewerparcelmgr.cpp
@@ -957,7 +957,7 @@ void LLViewerParcelMgr::sendParcelGodForceOwner(const LLUUID& owner_id)
return;
}
- LL_INFOS() << "Claiming " << mWestSouth << " to " << mEastNorth << LL_ENDL;
+ LL_INFOS("ParcelMgr") << "Claiming " << mWestSouth << " to " << mEastNorth << LL_ENDL;
// BUG: Only works for the region containing mWestSouthBottom
LLVector3d east_north_region_check( mEastNorth );
@@ -980,7 +980,7 @@ void LLViewerParcelMgr::sendParcelGodForceOwner(const LLUUID& owner_id)
return;
}
- LL_INFOS() << "Region " << region->getOriginGlobal() << LL_ENDL;
+ LL_INFOS("ParcelMgr") << "Region " << region->getOriginGlobal() << LL_ENDL;
LLSD payload;
payload["owner_id"] = owner_id;
@@ -1120,8 +1120,8 @@ LLViewerParcelMgr::ParcelBuyInfo* LLViewerParcelMgr::setupParcelBuy(
if (is_claim)
{
- LL_INFOS() << "Claiming " << mWestSouth << " to " << mEastNorth << LL_ENDL;
- LL_INFOS() << "Region " << region->getOriginGlobal() << LL_ENDL;
+ LL_INFOS("ParcelMgr") << "Claiming " << mWestSouth << " to " << mEastNorth << LL_ENDL;
+ LL_INFOS("ParcelMgr") << "Region " << region->getOriginGlobal() << LL_ENDL;
// BUG: Only works for the region containing mWestSouthBottom
LLVector3d east_north_region_check( mEastNorth );
@@ -1294,8 +1294,6 @@ void LLViewerParcelMgr::sendParcelPropertiesUpdate(LLParcel* parcel, bool use_ag
if (!region)
return;
- //LL_INFOS() << "found region: " << region->getName() << LL_ENDL;
-
LLSD body;
std::string url = region->getCapability("ParcelPropertiesUpdate");
if (!url.empty())
@@ -1304,7 +1302,7 @@ void LLViewerParcelMgr::sendParcelPropertiesUpdate(LLParcel* parcel, bool use_ag
U32 message_flags = 0x01;
body["flags"] = ll_sd_from_U32(message_flags);
parcel->packMessage(body);
- LL_INFOS() << "Sending parcel properties update via capability to: "
+ LL_INFOS("ParcelMgr") << "Sending parcel properties update via capability to: "
<< url << LL_ENDL;
LLCoreHttpUtil::HttpCoroutineAdapter::messageHttpPost(url, body,
@@ -1333,22 +1331,18 @@ void LLViewerParcelMgr::sendParcelPropertiesUpdate(LLParcel* parcel, bool use_ag
void LLViewerParcelMgr::setHoverParcel(const LLVector3d& pos)
{
static U32 last_west, last_south;
-
+ static LLUUID last_region;
// only request parcel info if position has changed outside of the
// last parcel grid step
- U32 west_parcel_step = (U32) floor( pos.mdV[VX] / PARCEL_GRID_STEP_METERS );
- U32 south_parcel_step = (U32) floor( pos.mdV[VY] / PARCEL_GRID_STEP_METERS );
-
+ const U32 west_parcel_step = (U32) floor( pos.mdV[VX] / PARCEL_GRID_STEP_METERS );
+ const U32 south_parcel_step = (U32) floor( pos.mdV[VY] / PARCEL_GRID_STEP_METERS );
+
if ((west_parcel_step == last_west) && (south_parcel_step == last_south))
{
+ // We are staying in same segment
return;
}
- else
- {
- last_west = west_parcel_step;
- last_south = south_parcel_step;
- }
LLViewerRegion* region = LLWorld::getInstance()->getRegionFromPosGlobal( pos );
if (!region)
@@ -1356,34 +1350,95 @@ void LLViewerParcelMgr::setHoverParcel(const LLVector3d& pos)
return;
}
+ LLUUID region_id = region->getRegionID();
+ LLVector3 pos_in_region = region->getPosRegionFromGlobal(pos);
- // Send a rectangle around the point.
- // This means the parcel sent back is at least a rectangle around the point,
- // which is more efficient for public land. Fewer requests are sent. JC
- LLVector3 wsb_region = region->getPosRegionFromGlobal( pos );
+ bool request_properties = false;
+ if (region_id != last_region)
+ {
+ request_properties = true;
+ }
+ else
+ {
+ // Check if new position is in same parcel.
+ // This check is not ideal, since it checks by way of straight lines.
+ // So sometimes (small parcel in the middle of large one) it can
+ // decide that parcel actually changed, but it still allows to
+ // reduce amount of requests significantly
- F32 west = PARCEL_GRID_STEP_METERS * floor( wsb_region.mV[VX] / PARCEL_GRID_STEP_METERS );
- F32 south = PARCEL_GRID_STEP_METERS * floor( wsb_region.mV[VY] / PARCEL_GRID_STEP_METERS );
+ S32 west_parcel_local = (S32)(pos_in_region.mV[VX] / PARCEL_GRID_STEP_METERS);
+ S32 south_parcel_local = (S32)(pos_in_region.mV[VY] / PARCEL_GRID_STEP_METERS);
- F32 east = west + PARCEL_GRID_STEP_METERS;
- F32 north = south + PARCEL_GRID_STEP_METERS;
+ LLViewerParcelOverlay* overlay = region->getParcelOverlay();
+ if (!overlay)
+ {
+ request_properties = true;
+ }
+ while (!request_properties && west_parcel_step < last_west)
+ {
+ S32 segment_shift = last_west - west_parcel_step;
+ request_properties = overlay->parcelLineFlags(south_parcel_local, west_parcel_local + segment_shift) & PARCEL_WEST_LINE;
+ last_west--;
+ }
+ while (!request_properties && south_parcel_step < last_south)
+ {
+ S32 segment_shift = last_south - south_parcel_step;
+ request_properties = overlay->parcelLineFlags(south_parcel_local + segment_shift, west_parcel_local) & PARCEL_SOUTH_LINE;
+ last_south--;
+ }
+ // Note: could have just swapped values, reused first two 'while' and set last_south, last_west separately,
+ // but this looks to be easier to understand/straightforward/less bulky
+ while (!request_properties && west_parcel_step > last_west)
+ {
+ S32 segment_shift = west_parcel_step - last_west;
+ request_properties = overlay->parcelLineFlags(south_parcel_local, west_parcel_local - segment_shift + 1) & PARCEL_WEST_LINE;
+ last_west++;
+ }
+ while (!request_properties && south_parcel_step > last_south)
+ {
+ S32 segment_shift = south_parcel_step - last_south;
+ request_properties = overlay->parcelLineFlags(south_parcel_local - segment_shift + 1, west_parcel_local) & PARCEL_SOUTH_LINE;
+ last_south++;
+ }
- // Send request message
- LLMessageSystem *msg = gMessageSystem;
- msg->newMessageFast(_PREHASH_ParcelPropertiesRequest);
- msg->nextBlockFast(_PREHASH_AgentData);
- msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID() );
- msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID() );
- msg->nextBlockFast(_PREHASH_ParcelData);
- msg->addS32Fast(_PREHASH_SequenceID, HOVERED_PARCEL_SEQ_ID );
- msg->addF32Fast(_PREHASH_West, west );
- msg->addF32Fast(_PREHASH_South, south );
- msg->addF32Fast(_PREHASH_East, east );
- msg->addF32Fast(_PREHASH_North, north );
- msg->addBOOL("SnapSelection", FALSE );
- msg->sendReliable( region->getHost() );
+ // if (!request_properties) last_south and last_west will be equal to new values
+ }
+
+ if (request_properties)
+ {
+ last_west = west_parcel_step;
+ last_south = south_parcel_step;
+ last_region = region_id;
- mHoverRequestResult = PARCEL_RESULT_NO_DATA;
+ LL_DEBUGS("ParcelMgr") << "Requesting parcel properties on hover, for " << pos << LL_ENDL;
+
+
+ // Send a rectangle around the point.
+ // This means the parcel sent back is at least a rectangle around the point,
+ // which is more efficient for public land. Fewer requests are sent. JC
+ F32 west = PARCEL_GRID_STEP_METERS * floor(pos_in_region.mV[VX] / PARCEL_GRID_STEP_METERS);
+ F32 south = PARCEL_GRID_STEP_METERS * floor(pos_in_region.mV[VY] / PARCEL_GRID_STEP_METERS);
+
+ F32 east = west + PARCEL_GRID_STEP_METERS;
+ F32 north = south + PARCEL_GRID_STEP_METERS;
+
+ // Send request message
+ LLMessageSystem *msg = gMessageSystem;
+ msg->newMessageFast(_PREHASH_ParcelPropertiesRequest);
+ msg->nextBlockFast(_PREHASH_AgentData);
+ msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
+ msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
+ msg->nextBlockFast(_PREHASH_ParcelData);
+ msg->addS32Fast(_PREHASH_SequenceID, HOVERED_PARCEL_SEQ_ID);
+ msg->addF32Fast(_PREHASH_West, west);
+ msg->addF32Fast(_PREHASH_South, south);
+ msg->addF32Fast(_PREHASH_East, east);
+ msg->addF32Fast(_PREHASH_North, north);
+ msg->addBOOL("SnapSelection", FALSE);
+ msg->sendReliable(region->getHost());
+
+ mHoverRequestResult = PARCEL_RESULT_NO_DATA;
+ }
}
@@ -1472,7 +1527,7 @@ void LLViewerParcelMgr::processParcelProperties(LLMessageSystem *msg, void **use
if (request_result == PARCEL_RESULT_NO_DATA)
{
// no valid parcel data
- LL_INFOS() << "no valid parcel data" << LL_ENDL;
+ LL_INFOS("ParcelMgr") << "no valid parcel data" << LL_ENDL;
return;
}
@@ -1504,7 +1559,7 @@ void LLViewerParcelMgr::processParcelProperties(LLMessageSystem *msg, void **use
}
else
{
- LL_INFOS() << "out of order agent parcel sequence id " << sequence_id
+ LL_INFOS("ParcelMgr") << "out of order agent parcel sequence id " << sequence_id
<< " last good " << parcel_mgr.mAgentParcelSequenceID
<< LL_ENDL;
return;
@@ -1552,6 +1607,8 @@ void LLViewerParcelMgr::processParcelProperties(LLMessageSystem *msg, void **use
msg->getS32("ParcelData", "OtherCleanTime", other_clean_time );
+ LL_DEBUGS("ParcelMgr") << "Processing parcel " << local_id << " update, target(sequence): " << sequence_id << LL_ENDL;
+
// Actually extract the data.
if (parcel)
{
@@ -1790,7 +1847,7 @@ void LLViewerParcelMgr::processParcelProperties(LLMessageSystem *msg, void **use
}
else
{
- LL_INFOS() << "Stopping parcel music (invalid audio stream URL)" << LL_ENDL;
+ LL_INFOS("ParcelMgr") << "Stopping parcel music (invalid audio stream URL)" << LL_ENDL;
// clears the URL
// null value causes fade out
LLViewerAudio::getInstance()->startInternetStreamWithAutoFade(LLStringUtil::null);
@@ -1798,7 +1855,7 @@ void LLViewerParcelMgr::processParcelProperties(LLMessageSystem *msg, void **use
}
else if (!gAudiop->getInternetStreamURL().empty())
{
- LL_INFOS() << "Stopping parcel music (parcel stream URL is empty)" << LL_ENDL;
+ LL_INFOS("ParcelMgr") << "Stopping parcel music (parcel stream URL is empty)" << LL_ENDL;
// null value causes fade out
LLViewerAudio::getInstance()->startInternetStreamWithAutoFade(LLStringUtil::null);
}
@@ -1827,7 +1884,7 @@ void LLViewerParcelMgr::optionally_start_music(const std::string& music_url)
gSavedSettings.getBOOL(LLViewerMedia::AUTO_PLAY_MEDIA_SETTING) &&
gSavedSettings.getBOOL("MediaTentativeAutoPlay")))
{
- LL_INFOS() << "Starting parcel music " << music_url << LL_ENDL;
+ LL_INFOS("ParcelMgr") << "Starting parcel music " << music_url << LL_ENDL;
LLViewerAudio::getInstance()->startInternetStreamWithAutoFade(music_url);
}
else
@@ -1855,7 +1912,7 @@ void LLViewerParcelMgr::processParcelAccessListReply(LLMessageSystem *msg, void
if (parcel_id != parcel->getLocalID())
{
- LL_WARNS_ONCE("") << "processParcelAccessListReply for parcel " << parcel_id
+ LL_WARNS_ONCE("ParcelMgr") << "processParcelAccessListReply for parcel " << parcel_id
<< " which isn't the selected parcel " << parcel->getLocalID()<< LL_ENDL;
return;
}
diff --git a/indra/newview/llviewerparceloverlay.cpp b/indra/newview/llviewerparceloverlay.cpp
index 4fd423b6f4..7c3dd00e1a 100644
--- a/indra/newview/llviewerparceloverlay.cpp
+++ b/indra/newview/llviewerparceloverlay.cpp
@@ -274,6 +274,23 @@ U8 LLViewerParcelOverlay::ownership( const LLVector3& pos) const
return ownership(row, column);
}
+U8 LLViewerParcelOverlay::parcelLineFlags(const LLVector3& pos) const
+{
+ S32 row = S32(pos.mV[VY] / PARCEL_GRID_STEP_METERS);
+ S32 column = S32(pos.mV[VX] / PARCEL_GRID_STEP_METERS);
+ return parcelLineFlags(row, column);
+}
+U8 LLViewerParcelOverlay::parcelLineFlags(S32 row, S32 col) const
+{
+ U8 flags = PARCEL_WEST_LINE | PARCEL_SOUTH_LINE;
+ if (row > mParcelGridsPerEdge || col > mParcelGridsPerEdge)
+ {
+ LL_WARNS() << "Attempted to get ownership out of region's overlay, row: " << row << " col: " << col << LL_ENDL;
+ return flags;
+ }
+ return mOwnership[row * mParcelGridsPerEdge + col] & flags;
+}
+
F32 LLViewerParcelOverlay::getOwnedRatio() const
{
S32 size = mParcelGridsPerEdge * mParcelGridsPerEdge;
diff --git a/indra/newview/llviewerparceloverlay.h b/indra/newview/llviewerparceloverlay.h
index 14a2af5354..e30dbf17b3 100644
--- a/indra/newview/llviewerparceloverlay.h
+++ b/indra/newview/llviewerparceloverlay.h
@@ -71,6 +71,8 @@ public:
S32 renderPropertyLines();
U8 ownership( const LLVector3& pos) const;
+ U8 parcelLineFlags( const LLVector3& pos) const;
+ U8 parcelLineFlags(S32 row, S32 col) const;
// MANIPULATE
void uncompressLandOverlay(S32 chunk, U8 *compressed_overlay);
diff --git a/indra/newview/llviewershadermgr.cpp b/indra/newview/llviewershadermgr.cpp
index ff7647a7e4..f610335b07 100644
--- a/indra/newview/llviewershadermgr.cpp
+++ b/indra/newview/llviewershadermgr.cpp
@@ -399,7 +399,8 @@ void LLViewerShaderMgr::setShaders()
return;
}
- LLGLSLShader::sIndexedTextureChannels = llmax(llmin(gGLManager.mNumTextureImageUnits, (S32) gSavedSettings.getU32("RenderMaxTextureIndex")), 1);
+ static LLCachedControl<U32> max_texture_index(gSavedSettings, "RenderMaxTextureIndex", 16);
+ LLGLSLShader::sIndexedTextureChannels = llmax(llmin(gGLManager.mNumTextureImageUnits, (S32) max_texture_index), 1);
//NEVER use more than 16 texture channels (work around for prevalent driver bug)
LLGLSLShader::sIndexedTextureChannels = llmin(LLGLSLShader::sIndexedTextureChannels, 16);
diff --git a/indra/newview/llviewertexture.cpp b/indra/newview/llviewertexture.cpp
index 41da58f94f..2c16c3c942 100644
--- a/indra/newview/llviewertexture.cpp
+++ b/indra/newview/llviewertexture.cpp
@@ -100,7 +100,7 @@ const S32 MAX_CACHED_RAW_TERRAIN_IMAGE_AREA = 128 * 128;
const S32 DEFAULT_ICON_DIMENTIONS = 32;
S32 LLViewerTexture::sMinLargeImageSize = 65536; //256 * 256.
S32 LLViewerTexture::sMaxSmallImageSize = MAX_CACHED_RAW_IMAGE_AREA;
-BOOL LLViewerTexture::sFreezeImageScalingDown = FALSE;
+bool LLViewerTexture::sFreezeImageUpdates = false;
F32 LLViewerTexture::sCurrentTime = 0.0f;
F32 LLViewerTexture::sTexelPixelRatio = 1.0f;
@@ -474,6 +474,7 @@ void LLViewerTexture::initClass()
// tuning params
const F32 discard_bias_delta = .25f;
const F32 discard_delta_time = 0.5f;
+const F32 GPU_MEMORY_CHECK_WAIT_TIME = 1.0f;
// non-const (used externally
F32 texmem_lower_bound_scale = 0.85f;
F32 texmem_middle_bound_scale = 0.925f;
@@ -483,53 +484,68 @@ static LLTrace::BlockTimerStatHandle FTM_TEXTURE_MEMORY_CHECK("Memory Check");
//static
bool LLViewerTexture::isMemoryForTextureLow()
{
- const F32 WAIT_TIME = 1.0f; //second
- static LLFrameTimer timer;
+ // Note: we need to figure out a better source for 'min' values,
+ // what is free for low end at minimal settings is 'nothing left'
+ // for higher end gpus at high settings.
+ const S32Megabytes MIN_FREE_TEXTURE_MEMORY(20);
+ const S32Megabytes MIN_FREE_MAIN_MEMORY(100);
- if(timer.getElapsedTimeF32() < WAIT_TIME) //call this once per second.
- {
- return false;
- }
- timer.reset();
+ S32Megabytes gpu;
+ S32Megabytes physical;
+ getGPUMemoryForTextures(gpu, physical);
- LL_RECORD_BLOCK_TIME(FTM_TEXTURE_MEMORY_CHECK);
+ return (gpu < MIN_FREE_TEXTURE_MEMORY) || (physical < MIN_FREE_MAIN_MEMORY);
+}
- const S32Megabytes MIN_FREE_TEXTURE_MEMORY(20); //MB Changed to 20 MB per MAINT-6882
- const S32Megabytes MIN_FREE_MAIN_MEMORY(100); //MB
+//static
+bool LLViewerTexture::isMemoryForTextureSuficientlyFree()
+{
+ const S32Megabytes DESIRED_FREE_TEXTURE_MEMORY(50);
+ const S32Megabytes DESIRED_FREE_MAIN_MEMORY(200);
- bool low_mem = false;
- if (gGLManager.mHasATIMemInfo)
- {
- S32 meminfo[4];
- glGetIntegerv(GL_TEXTURE_FREE_MEMORY_ATI, meminfo);
+ S32Megabytes gpu;
+ S32Megabytes physical;
+ getGPUMemoryForTextures(gpu, physical);
- if((S32Megabytes)meminfo[0] < MIN_FREE_TEXTURE_MEMORY)
- {
- low_mem = true;
- }
+ return (gpu > DESIRED_FREE_TEXTURE_MEMORY) && (physical > DESIRED_FREE_MAIN_MEMORY);
+}
- if(!low_mem) //check main memory, only works for windows.
- {
- LLMemory::updateMemoryInfo();
- if(LLMemory::getAvailableMemKB() < MIN_FREE_TEXTURE_MEMORY)
- {
- low_mem = true;
- }
- }
- }
- //Enabled this branch per MAINT-6882
- else if (gGLManager.mHasNVXMemInfo)
- {
- S32 free_memory;
- glGetIntegerv(GL_GPU_MEMORY_INFO_CURRENT_AVAILABLE_VIDMEM_NVX, &free_memory);
-
- if ((S32Megabytes)(free_memory / 1024) < MIN_FREE_TEXTURE_MEMORY)
- {
- low_mem = true;
- }
- }
+//static
+void LLViewerTexture::getGPUMemoryForTextures(S32Megabytes &gpu, S32Megabytes &physical)
+{
+ static LLFrameTimer timer;
+ static S32Megabytes gpu_res = S32Megabytes(S32_MAX);
+ static S32Megabytes physical_res = S32Megabytes(S32_MAX);
+
+ if (timer.getElapsedTimeF32() < GPU_MEMORY_CHECK_WAIT_TIME) //call this once per second.
+ {
+ gpu = gpu_res;
+ physical = physical_res;
+ return;
+ }
+ timer.reset();
+
+ LL_RECORD_BLOCK_TIME(FTM_TEXTURE_MEMORY_CHECK);
+
+ if (gGLManager.mHasATIMemInfo)
+ {
+ S32 meminfo[4];
+ glGetIntegerv(GL_TEXTURE_FREE_MEMORY_ATI, meminfo);
+ gpu_res = (S32Megabytes)meminfo[0];
+
+ //check main memory, only works for windows.
+ LLMemory::updateMemoryInfo();
+ physical_res = LLMemory::getAvailableMemKB();
+ }
+ else if (gGLManager.mHasNVXMemInfo)
+ {
+ S32 free_memory;
+ glGetIntegerv(GL_GPU_MEMORY_INFO_CURRENT_AVAILABLE_VIDMEM_NVX, &free_memory);
+ gpu_res = (S32Megabytes)(free_memory / 1024);
+ }
- return low_mem;
+ gpu = gpu_res;
+ physical = physical_res;
}
static LLTrace::BlockTimerStatHandle FTM_TEXTURE_UPDATE_MEDIA("Media");
@@ -572,15 +588,20 @@ void LLViewerTexture::updateClass(const F32 velocity, const F32 angular_velocity
sEvaluationTimer.reset();
}
}
- else if(sEvaluationTimer.getElapsedTimeF32() > discard_delta_time && isMemoryForTextureLow())
+ else if(isMemoryForTextureLow())
{
- sDesiredDiscardBias += discard_bias_delta;
- sEvaluationTimer.reset();
+ // Note: isMemoryForTextureLow() uses 1s delay, make sure we waited enough for it to recheck
+ if (sEvaluationTimer.getElapsedTimeF32() > GPU_MEMORY_CHECK_WAIT_TIME)
+ {
+ sDesiredDiscardBias += discard_bias_delta;
+ sEvaluationTimer.reset();
+ }
}
- else if (sDesiredDiscardBias > 0.0f &&
- sBoundTextureMemory < sMaxBoundTextureMemory * texmem_lower_bound_scale &&
- sTotalTextureMemory < sMaxTotalTextureMem * texmem_lower_bound_scale)
- {
+ else if (sDesiredDiscardBias > 0.0f
+ && sBoundTextureMemory < sMaxBoundTextureMemory * texmem_lower_bound_scale
+ && sTotalTextureMemory < sMaxTotalTextureMem * texmem_lower_bound_scale
+ && isMemoryForTextureSuficientlyFree())
+ {
// If we are using less texture memory than we should,
// scale down the desired discard level
if (sEvaluationTimer.getElapsedTimeF32() > discard_delta_time)
@@ -590,14 +611,8 @@ void LLViewerTexture::updateClass(const F32 velocity, const F32 angular_velocity
}
}
sDesiredDiscardBias = llclamp(sDesiredDiscardBias, desired_discard_bias_min, desired_discard_bias_max);
-
- F32 camera_moving_speed = LLViewerCamera::getInstance()->getAverageSpeed();
- F32 camera_angular_speed = LLViewerCamera::getInstance()->getAverageAngularSpeed();
- sCameraMovingBias = llmax(0.2f * camera_moving_speed, 2.0f * camera_angular_speed - 1);
- sCameraMovingDiscardBias = (S8)(sCameraMovingBias);
- LLViewerTexture::sFreezeImageScalingDown = (sBoundTextureMemory < 0.75f * sMaxBoundTextureMemory * texmem_middle_bound_scale) &&
- (sTotalTextureMemory < 0.75f * sMaxTotalTextureMem * texmem_middle_bound_scale);
+ LLViewerTexture::sFreezeImageUpdates = sDesiredDiscardBias > (desired_discard_bias_max - 1.0f);
}
//end of static functions
@@ -3117,9 +3132,9 @@ S8 LLViewerLODTexture::getType() const
return LLViewerTexture::LOD_TEXTURE;
}
-BOOL LLViewerLODTexture::isUpdateFrozen()
+bool LLViewerLODTexture::isUpdateFrozen()
{
- return LLViewerTexture::sFreezeImageScalingDown && !getDiscardLevel();
+ return LLViewerTexture::sFreezeImageUpdates;
}
// This is gauranteed to get called periodically for every texture
@@ -3245,9 +3260,16 @@ void LLViewerLODTexture::processTextureStats()
(!getBoundRecently() || mDesiredDiscardLevel >= mCachedRawDiscardLevel))
{
scaleDown();
-
}
}
+
+ if (isUpdateFrozen() // we are out of memory and nearing max allowed bias
+ && mBoostLevel < LLGLTexture::BOOST_SCULPTED
+ && mDesiredDiscardLevel < current_discard)
+ {
+ // stop requesting more
+ mDesiredDiscardLevel = current_discard;
+ }
}
if(mForceToSaveRawImage && mDesiredSavedRawDiscardLevel >= 0)
diff --git a/indra/newview/llviewertexture.h b/indra/newview/llviewertexture.h
index 5d89f9f029..7cbcc931b1 100644
--- a/indra/newview/llviewertexture.h
+++ b/indra/newview/llviewertexture.h
@@ -186,6 +186,9 @@ private:
virtual void switchToCachedImage();
static bool isMemoryForTextureLow() ;
+ static bool isMemoryForTextureSuficientlyFree();
+ static void getGPUMemoryForTextures(S32Megabytes &gpu, S32Megabytes &physical);
+
protected:
LLUUID mID;
S32 mTextureListType; // along with mID identifies where to search for this texture in TextureList
@@ -227,7 +230,7 @@ public:
static S32 sMaxSculptRez ;
static S32 sMinLargeImageSize ;
static S32 sMaxSmallImageSize ;
- static BOOL sFreezeImageScalingDown ;//do not scale down image res if set.
+ static bool sFreezeImageUpdates;
static F32 sCurrentTime ;
enum EDebugTexels
@@ -543,7 +546,7 @@ public:
/*virtual*/ S8 getType() const;
// Process image stats to determine priority/quality requirements.
/*virtual*/ void processTextureStats();
- BOOL isUpdateFrozen() ;
+ bool isUpdateFrozen() ;
private:
void init(bool firstinit) ;
diff --git a/indra/newview/llvoavatar.h b/indra/newview/llvoavatar.h
index deb22617a4..a4f8e95c65 100644
--- a/indra/newview/llvoavatar.h
+++ b/indra/newview/llvoavatar.h
@@ -75,6 +75,8 @@ class LLTexGlobalColor;
struct LLAppearanceMessageContents;
class LLViewerJointMesh;
+const F32 MAX_AVATAR_LOD_FACTOR = 1.0f;
+
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// LLVOAvatar
diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp
index 24726e61e8..3c487a112e 100644
--- a/indra/newview/llvovolume.cpp
+++ b/indra/newview/llvovolume.cpp
@@ -1380,7 +1380,8 @@ BOOL LLVOVolume::calcLOD()
mLODDistance = distance;
mLODRadius = radius;
- if (gSavedSettings.getBOOL("DebugObjectLODs"))
+ static LLCachedControl<bool> debug_lods(gSavedSettings, "DebugObjectLODs", false);
+ if (debug_lods)
{
if (getAvatar() && isRootEdit())
{
@@ -4276,10 +4277,16 @@ F32 LLVOVolume::getBinRadius()
F32 scale = 1.f;
- S32 size_factor = llmax(gSavedSettings.getS32("OctreeStaticObjectSizeFactor"), 1);
- S32 attachment_size_factor = llmax(gSavedSettings.getS32("OctreeAttachmentSizeFactor"), 1);
- LLVector3 distance_factor = gSavedSettings.getVector3("OctreeDistanceFactor");
- LLVector3 alpha_distance_factor = gSavedSettings.getVector3("OctreeAlphaDistanceFactor");
+ static LLCachedControl<S32> octree_size_factor(gSavedSettings, "OctreeStaticObjectSizeFactor", 3);
+ static LLCachedControl<S32> octree_attachment_size_factor(gSavedSettings, "OctreeAttachmentSizeFactor", 4);
+ static LLCachedControl<LLVector3> octree_distance_factor(gSavedSettings, "OctreeDistanceFactor", LLVector3(0.01f, 0.f, 0.f));
+ static LLCachedControl<LLVector3> octree_alpha_distance_factor(gSavedSettings, "OctreeAlphaDistanceFactor", LLVector3(0.1f, 0.f, 0.f));
+
+ S32 size_factor = llmax((S32)octree_size_factor, 1);
+ S32 attachment_size_factor = llmax((S32)octree_attachment_size_factor, 1);
+ LLVector3 distance_factor = octree_distance_factor;
+ LLVector3 alpha_distance_factor = octree_alpha_distance_factor;
+
const LLVector4a* ext = mDrawable->getSpatialExtents();
BOOL shrink_wrap = mDrawable->isAnimating();
@@ -5352,8 +5359,10 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
U32 useage = group->getSpatialPartition()->mBufferUsage;
- U32 max_vertices = (gSavedSettings.getS32("RenderMaxVBOSize")*1024)/LLVertexBuffer::calcVertexSize(group->getSpatialPartition()->mVertexDataMask);
- U32 max_total = (gSavedSettings.getS32("RenderMaxNodeSize")*1024)/LLVertexBuffer::calcVertexSize(group->getSpatialPartition()->mVertexDataMask);
+ LLCachedControl<S32> max_vbo_size(gSavedSettings, "RenderMaxVBOSize", 512);
+ LLCachedControl<S32> max_node_size(gSavedSettings, "RenderMaxNodeSize", 65536);
+ U32 max_vertices = (max_vbo_size * 1024)/LLVertexBuffer::calcVertexSize(group->getSpatialPartition()->mVertexDataMask);
+ U32 max_total = (max_node_size * 1024) / LLVertexBuffer::calcVertexSize(group->getSpatialPartition()->mVertexDataMask);
max_vertices = llmin(max_vertices, (U32) 65535);
U32 cur_total = 0;
@@ -6106,7 +6115,8 @@ U32 LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace
#endif
//calculate maximum number of vertices to store in a single buffer
- U32 max_vertices = (gSavedSettings.getS32("RenderMaxVBOSize")*1024)/LLVertexBuffer::calcVertexSize(group->getSpatialPartition()->mVertexDataMask);
+ LLCachedControl<S32> max_vbo_size(gSavedSettings, "RenderMaxVBOSize", 512);
+ U32 max_vertices = (max_vbo_size * 1024)/LLVertexBuffer::calcVertexSize(group->getSpatialPartition()->mVertexDataMask);
max_vertices = llmin(max_vertices, (U32) 65535);
{
@@ -6149,7 +6159,8 @@ U32 LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace
texture_index_channels = gDeferredAlphaProgram.mFeatures.mIndexedTextureChannels;
}
- texture_index_channels = llmin(texture_index_channels, (S32) gSavedSettings.getU32("RenderMaxTextureIndex"));
+ static LLCachedControl<U32> max_texture_index(gSavedSettings, "RenderMaxTextureIndex", 16);
+ texture_index_channels = llmin(texture_index_channels, (S32) max_texture_index);
//NEVER use more than 16 texture index channels (workaround for prevalent driver bug)
texture_index_channels = llmin(texture_index_channels, 16);
diff --git a/indra/newview/llvovolume.h b/indra/newview/llvovolume.h
index 0882fc095d..13db9c39b7 100644
--- a/indra/newview/llvovolume.h
+++ b/indra/newview/llvovolume.h
@@ -54,6 +54,8 @@ enum LLVolumeInterfaceType
INTERFACE_FLEXIBLE = 1,
};
+const F32 MAX_LOD_FACTOR = 4.0f;
+
class LLRiggedVolume : public LLVolume
{
diff --git a/indra/newview/llvowlsky.cpp b/indra/newview/llvowlsky.cpp
index 3b9b96e9f1..2cb5fc81b0 100644
--- a/indra/newview/llvowlsky.cpp
+++ b/indra/newview/llvowlsky.cpp
@@ -335,7 +335,8 @@ BOOL LLVOWLSky::updateGeometry(LLDrawable * drawable)
}
{
- const U32 max_buffer_bytes = gSavedSettings.getS32("RenderMaxVBOSize")*1024;
+ LLCachedControl<S32> max_vbo_size(gSavedSettings, "RenderMaxVBOSize", 512);
+ const U32 max_buffer_bytes = max_vbo_size * 1024;
const U32 data_mask = LLDrawPoolWLSky::SKY_VERTEX_DATA_MASK;
const U32 max_verts = max_buffer_bytes / LLVertexBuffer::calcVertexSize(data_mask);
diff --git a/indra/newview/llworldmapview.cpp b/indra/newview/llworldmapview.cpp
index 707fe76cef..b88631a71b 100644
--- a/indra/newview/llworldmapview.cpp
+++ b/indra/newview/llworldmapview.cpp
@@ -1751,9 +1751,12 @@ BOOL LLWorldMapView::handleDoubleClick( S32 x, S32 y, MASK mask )
case MAP_ITEM_LAND_FOR_SALE_ADULT:
{
LLVector3d pos_global = viewPosToGlobal(x, y);
- LLSimInfo* info = LLWorldMap::getInstance()->simInfoFromPosGlobal(pos_global);
- LLFloaterReg::hideInstance("world_map");
- LLFloaterReg::showInstance("search", LLSD().with("category", "land").with("query", info->getName()));
+ std::string sim_name;
+ if (LLWorldMap::getInstance()->simNameFromPosGlobal(pos_global, sim_name))
+ {
+ LLFloaterReg::hideInstance("world_map");
+ LLFloaterReg::showInstance("search", LLSD().with("category", "land").with("query", sim_name));
+ }
break;
}
case MAP_ITEM_CLASSIFIED:
diff --git a/indra/newview/llxmlrpctransaction.cpp b/indra/newview/llxmlrpctransaction.cpp
index 143c97fca4..cc223c1f48 100644
--- a/indra/newview/llxmlrpctransaction.cpp
+++ b/indra/newview/llxmlrpctransaction.cpp
@@ -483,38 +483,24 @@ void LLXMLRPCTransaction::Impl::setHttpStatus(const LLCore::HttpStatus &status)
{
CURLcode code = static_cast<CURLcode>(status.toULong());
std::string message;
- std::string uri = "http://secondlife.com/community/support.php";
+ std::string uri = "http://support.secondlife.com";
LLURI failuri(mURI);
-
+ LLStringUtil::format_map_t args;
switch (code)
{
case CURLE_COULDNT_RESOLVE_HOST:
- message =
- std::string("DNS could not resolve the host name(") + failuri.hostName() + ").\n"
- "Please verify that you can connect to the www.secondlife.com\n"
- "web site. If you can, but continue to receive this error,\n"
- "please go to the support section and report this problem.";
+ args["[HOSTNAME]"] = failuri.hostName();
+ message = LLTrans::getString("couldnt_resolve_host", args);
break;
case CURLE_SSL_PEER_CERTIFICATE:
- message =
- "The login server couldn't verify itself via SSL.\n"
- "If you continue to receive this error, please go\n"
- "to the Support section of the SecondLife.com web site\n"
- "and report the problem.";
+ message = LLTrans::getString("ssl_peer_certificate");
break;
case CURLE_SSL_CACERT:
- case CURLE_SSL_CONNECT_ERROR:
- message =
- "Often this means that your computer\'s clock is set incorrectly.\n"
- "Please go to Control Panels and make sure the time and date\n"
- "are set correctly.\n"
- "Also check that your network and firewall are set up correctly.\n"
- "If you continue to receive this error, please go\n"
- "to the Support section of the SecondLife.com web site\n"
- "and report the problem.";
+ case CURLE_SSL_CONNECT_ERROR:
+ message = LLTrans::getString("ssl_connect_error");
break;
default:
diff --git a/indra/newview/skins/default/xui/en/floater_model_preview.xml b/indra/newview/skins/default/xui/en/floater_model_preview.xml
index 3db431de1b..5a86eb06fb 100644
--- a/indra/newview/skins/default/xui/en/floater_model_preview.xml
+++ b/indra/newview/skins/default/xui/en/floater_model_preview.xml
@@ -73,35 +73,6 @@
prevalidate_callback="ascii"
top_pad="5"
width="290" />
- <text
- follows="left|top"
- height="15"
- layout="topleft"
- left_pad="15"
- name="model_category_label"
- text_color="White"
- top="0"
- width="200">
- This model represents...
- </text>
- <combo_box
- follows="left|top"
- height="23"
- left_pad="10"
- name="model_category_combo"
- top_pad="10"
- width="200">
- <combo_box.drop_down_button
- label_color="White"/>
- <combo_item name="Choose one" label="Choose One..." value="MUT_Unspecified"/>
- <combo_item name="Avatar shape" label="Avatar shape" value="MUT_AvatarShape"/>
- <combo_item name="Avatar attachment" label="Avatar attachment" value="MUT_AvatarAttachment"/>
- <combo_item name="Moving object (vehicle, animal)" label="Moving object (vehicle, animal)" value="MUT_MovingObject"/>
- <combo_item name="Building Component" label="Building Component" value="MUT_BuildingComponent"/>
- <combo_item name="Large, non moving etc" label="Large, non moving etc" value="MUT_LargeStationary"/>
- <combo_item name="Smaller, non-moving etc" label="Smaller, non-moving etc" value="MUT_SmallStationary"/>
- <combo_item name="Not really any of these" label="Not really any of these" value="MUT_Other"/>
- </combo_box>
</panel>
<tab_container
follows="top|left"
diff --git a/indra/newview/skins/default/xui/en/language_settings.xml b/indra/newview/skins/default/xui/en/language_settings.xml
index 51779e4bfd..d418fc38e3 100644
--- a/indra/newview/skins/default/xui/en/language_settings.xml
+++ b/indra/newview/skins/default/xui/en/language_settings.xml
@@ -42,6 +42,7 @@
<string name="TimeWeek">wkday,datetime,slt</string>
<string name="TimeAMPM">ampm,datetime,slt</string>
<string name="TimeHour12">hour12,datetime,slt</string>
+ <string name="TimeTimezone">timezone,datetime,slt</string>
<string name="LTimeMthNum">mthnum,datetime,local</string>
<string name="LTimeWeek">wkday,datetime,local</string>
diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml
index cc57e1375a..23a8d21f8a 100644
--- a/indra/newview/skins/default/xui/en/notifications.xml
+++ b/indra/newview/skins/default/xui/en/notifications.xml
@@ -1845,7 +1845,7 @@ You are not allowed to terraform parcel [PARCEL].
name="CannotCopyWarning"
type="alertmodal">
You do not have permission to copy the following items:
-[ITEMS]
+&lt;nolink&gt;[ITEMS]&lt;/nolink&gt;
and will lose it from your inventory if you give it away. Do you really want to offer these items?
<tag>confirm</tag>
<usetemplate
@@ -9479,7 +9479,7 @@ You Can't create trees and grass on land you don't own.
name="NoCopyPermsNoObject"
type="notify">
<tag>fail</tag>
-Copy failed because you lack permission to copy the object '[OBJ_NAME]'.
+Copy failed because you lack permission to copy the object &lt;nolink&gt;'[OBJ_NAME]'&lt;/nolink&gt;.
</notification>
<notification
@@ -9487,7 +9487,7 @@ Copy failed because you lack permission to copy the object '[OBJ_NAME]'.
name="NoTransPermsNoObject"
type="notify">
<tag>fail</tag>
-Copy failed because the object '[OBJ_NAME]' cannot be transferred to you.
+Copy failed because the object &lt;nolink&gt;'[OBJ_NAME]'&lt;/nolink&gt; cannot be transferred to you.
</notification>
<notification
@@ -9495,7 +9495,7 @@ Copy failed because the object '[OBJ_NAME]' cannot be transferred to you.
name="AddToNavMeshNoCopy"
type="notify">
<tag>fail</tag>
-Copy failed because the object '[OBJ_NAME]' contributes to navmesh.
+Copy failed because the object &lt;nolink&gt;'[OBJ_NAME]'&lt;/nolink&gt; contributes to navmesh.
</notification>
<notification
@@ -9619,7 +9619,7 @@ Save Back To Inventory has been disabled.
name="NoExistNoSaveToContents"
type="notify">
<tag>fail</tag>
-Cannot save '[OBJ_NAME]' to object contents because the object it was rezzed from no longer exists.
+Cannot save &lt;nolink&gt;'[OBJ_NAME]'&lt;/nolink&gt; to object contents because the object it was rezzed from no longer exists.
</notification>
<notification
@@ -9627,7 +9627,7 @@ Cannot save '[OBJ_NAME]' to object contents because the object it was rezzed fro
name="NoModNoSaveToContents"
type="notify">
<tag>fail</tag>
-Cannot save '[OBJ_NAME]' to object contents because you do not have permission to modify the object '[DEST_NAME]'.
+Cannot save &lt;nolink&gt;'[OBJ_NAME]'&lt;/nolink&gt; to object contents because you do not have permission to modify the object &lt;nolink&gt;'[DEST_NAME]'&lt;/nolink&gt;.
</notification>
<notification
@@ -9635,7 +9635,7 @@ Cannot save '[OBJ_NAME]' to object contents because you do not have permission t
name="NoSaveBackToInvDisabled"
type="notify">
<tag>fail</tag>
-Cannot save '[OBJ_NAME]' back to inventory -- this operation has been disabled.
+Cannot save &lt;nolink&gt;'[OBJ_NAME]'&lt;/nolink&gt; back to inventory -- this operation has been disabled.
</notification>
<notification
@@ -9643,7 +9643,7 @@ Cannot save '[OBJ_NAME]' back to inventory -- this operation has been disabled.
name="NoCopyNoSelCopy"
type="notify">
<tag>fail</tag>
-You cannot copy your selection because you do not have permission to copy the object '[OBJ_NAME]'.
+You cannot copy your selection because you do not have permission to copy the object &lt;nolink&gt;'[OBJ_NAME]'&lt;/nolink&gt;.
</notification>
<notification
@@ -9651,7 +9651,7 @@ You cannot copy your selection because you do not have permission to copy the ob
name="NoTransNoSelCopy"
type="notify">
<tag>fail</tag>
-You cannot copy your selection because the object '[OBJ_NAME]' is not transferrable.
+You cannot copy your selection because the object &lt;nolink&gt;'[OBJ_NAME]'&lt;/nolink&gt; is not transferrable.
</notification>
<notification
@@ -9659,7 +9659,7 @@ You cannot copy your selection because the object '[OBJ_NAME]' is not transferra
name="NoTransNoCopy"
type="notify">
<tag>fail</tag>
-You cannot copy your selection because the object '[OBJ_NAME]' is not transferrable.
+You cannot copy your selection because the object &lt;nolink&gt;'[OBJ_NAME]'&lt;/nolink&gt; is not transferrable.
</notification>
<notification
@@ -9667,7 +9667,7 @@ You cannot copy your selection because the object '[OBJ_NAME]' is not transferra
name="NoPermsNoRemoval"
type="notify">
<tag>fail</tag>
-Removal of the object '[OBJ_NAME]' from the simulator is disallowed by the permissions system.
+Removal of the object &lt;nolink&gt;'[OBJ_NAME]'&lt;/nolink&gt; from the simulator is disallowed by the permissions system.
</notification>
<notification
@@ -9675,7 +9675,7 @@ Removal of the object '[OBJ_NAME]' from the simulator is disallowed by the permi
name="NoModNoSaveSelection"
type="notify">
<tag>fail</tag>
-Cannot save your selection because you do not have permission to modify the object '[OBJ_NAME]'.
+Cannot save your selection because you do not have permission to modify the object &lt;nolink&gt;'[OBJ_NAME]'&lt;/nolink&gt;.
</notification>
<notification
@@ -9683,7 +9683,7 @@ Cannot save your selection because you do not have permission to modify the obje
name="NoCopyNoSaveSelection"
type="notify">
<tag>fail</tag>
-Cannot save your selection because the object '[OBJ_NAME]' is not copyable.
+Cannot save your selection because the object &lt;nolink&gt;'[OBJ_NAME]'&lt;/nolink&gt; is not copyable.
</notification>
<notification
@@ -9691,7 +9691,7 @@ Cannot save your selection because the object '[OBJ_NAME]' is not copyable.
name="NoModNoTaking"
type="notify">
<tag>fail</tag>
-You cannot take your selection because you do not have permission to modify the object '[OBJ_NAME]'.
+You cannot take your selection because you do not have permission to modify the object &lt;nolink&gt;'[OBJ_NAME]'&lt;/nolink&gt;.
</notification>
<notification
diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml
index f5f4b4acab..e8fdb2d5b1 100644
--- a/indra/newview/skins/default/xui/en/strings.xml
+++ b/indra/newview/skins/default/xui/en/strings.xml
@@ -4233,4 +4233,29 @@ Try enclosing path to the editor with double quotes.
The physics shape does not have correct version. Set the correct version for the physics model.
</string>
+ <!-- CURL error messages -->
+ <string name="couldnt_resolve_host">
+DNS could not resolve the host name([HOSTNAME]).
+Please verify that you can connect to the www.secondlife.com
+web site. If you can, but continue to receive this error,
+please go to the support section and report this problem.
+ </string>
+ <string name="ssl_peer_certificate">
+The login server couldn't verify itself via SSL.
+If you continue to receive this error, please go
+to the Support section of the SecondLife.com web site
+and report the problem.
+ </string>
+ <string name="ssl_connect_error">
+Often this means that your computer's clock is set incorrectly.
+Please go to Control Panels and make sure the time and date
+are set correctly.
+Also check that your network and firewall are set up correctly.
+If you continue to receive this error, please go
+to the Support section of the SecondLife.com web site
+and report the problem.
+
+[https://community.secondlife.com/knowledgebase/english/error-messages-r520/#Section__3 Knowledge Base]
+ </string>
+
</strings>
diff --git a/indra/newview/skins/default/xui/zh/floater_tos.xml b/indra/newview/skins/default/xui/zh/floater_tos.xml
index 4cac07cd21..2f02316fc0 100644
--- a/indra/newview/skins/default/xui/zh/floater_tos.xml
+++ b/indra/newview/skins/default/xui/zh/floater_tos.xml
@@ -4,7 +4,7 @@
http://secondlife.com/app/tos/
</floater.string>
<floater.string name="loading_url">
- data:text/html,%3Chtml%3E%3Chead%3E%3C/head%3E%3Cbody text=%22000000%22%3E%3Ch2%3E 正在載入 %3Ca%20target%3D%22_external%22%20href%3D%22http%3A//secondlife.com/app/tos/%22%3ETerms%20of%20Service%3C/a%3E...%3C/h2%3E %3C/body%3E %3C/html%3E
+ data:text/html;charset=utf-8,%3Chtml%3E%3Chead%3E%3C/head%3E%3Cbody text=%22000000%22%3E%3Ch2%3E 正在載入 %3Ca%20target%3D%22_external%22%20href%3D%22http%3A//secondlife.com/app/tos/%22%3ETerms%20of%20Service%3C/a%3E...%3C/h2%3E %3C/body%3E %3C/html%3E
</floater.string>
<text name="tos_heading">
請閱讀並遵守Second Life使用條款、隱私政策、服務條款,包括同意在發生爭議時接受仲裁並放棄採取集體或群體求訴的規定。 繼續登入[SECOND_LIFE]前,你必須同意這些條款。