diff options
43 files changed, 580 insertions, 379 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/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 Binary files differindex 00aa47de69..f854f5db06 100644 --- a/indra/newview/installers/windows/lang_en-us.nsi +++ b/indra/newview/installers/windows/lang_en-us.nsi 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/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..1dc03123eb 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; @@ -451,37 +450,47 @@ void LLManip::renderXYZ(const LLVector3 &vec) 235, PAD * 2 + 10, 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/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/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/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/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/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]前,你必須同意這些條款。 |