summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrey Lihatskiy <alihatskiy@productengine.com>2025-03-11 05:10:11 +0200
committerAndrey Lihatskiy <alihatskiy@productengine.com>2025-03-11 05:10:11 +0200
commit4132a13972b3a76af22ba3d274be30be3680acc2 (patch)
tree31ae40090192ede34d1dcb00ecc254ebe203ef0a
parent573ca63e0f837fd52cbfc8adc3546d8971d21b12 (diff)
parent95a395de2287858aac39a41e1a360eab4ef7315f (diff)
Merge branch 'marchcat/maint-b-cherrypicks' into marchcat/2025.03-maint-b
-rw-r--r--indra/llappearance/llpolymesh.cpp2
-rw-r--r--indra/llmessage/llproxy.cpp4
-rw-r--r--indra/llxml/llxmltree.cpp13
-rw-r--r--indra/newview/llagent.cpp14
-rw-r--r--indra/newview/llaisapi.cpp2
-rw-r--r--indra/newview/llappviewer.cpp22
-rw-r--r--indra/newview/llfilepicker.cpp1
-rw-r--r--indra/newview/llfloatercreatelandmark.cpp7
-rw-r--r--indra/newview/llfloatercreatelandmark.h1
-rw-r--r--indra/newview/llfloateremojipicker.cpp59
-rw-r--r--indra/newview/llfloateremojipicker.h1
-rw-r--r--indra/newview/llfloaterperformance.cpp12
-rw-r--r--indra/newview/llfloaterperformance.h2
-rw-r--r--indra/newview/llfloaterpreference.cpp44
-rw-r--r--indra/newview/llfloaterpreference.h4
-rw-r--r--indra/newview/llfloaterpreferencesgraphicsadvanced.cpp5
-rw-r--r--indra/newview/llfloaterpreferencesgraphicsadvanced.h1
-rw-r--r--indra/newview/llglsandbox.cpp66
-rw-r--r--indra/newview/llinventorybridge.cpp22
-rw-r--r--indra/newview/llinventorybridge.h5
-rw-r--r--indra/newview/llinventorymodelbackgroundfetch.cpp17
-rw-r--r--indra/newview/lloutfitslist.cpp4
-rw-r--r--indra/newview/llpanelemojicomplete.cpp3
-rw-r--r--indra/newview/llviewerjointmesh.cpp14
-rw-r--r--indra/newview/llviewermedia.cpp3
-rw-r--r--indra/newview/llviewerobject.cpp146
-rw-r--r--indra/newview/llviewerobject.h2
-rwxr-xr-xindra/newview/llviewerregion.cpp1
-rw-r--r--indra/newview/llvoicevivox.cpp1
-rw-r--r--indra/newview/skins/default/xui/en/floater_emoji_picker.xml1
-rw-r--r--indra/newview/skins/default/xui/en/floater_fast_timers.xml2
-rw-r--r--indra/newview/skins/default/xui/en/floater_preferences_graphics_advanced.xml2
-rw-r--r--indra/newview/skins/default/xui/en/floater_world_map.xml3
-rw-r--r--indra/newview/skins/default/xui/en/menu_viewer.xml10
-rw-r--r--indra/newview/skins/default/xui/en/panel_preferences_graphics1.xml40
-rw-r--r--indra/newview/skins/default/xui/en/panel_region_environment.xml9
36 files changed, 381 insertions, 164 deletions
diff --git a/indra/llappearance/llpolymesh.cpp b/indra/llappearance/llpolymesh.cpp
index 97f9ca68b6..6bfb7456e8 100644
--- a/indra/llappearance/llpolymesh.cpp
+++ b/indra/llappearance/llpolymesh.cpp
@@ -981,7 +981,7 @@ void LLPolyMesh::initializeForMorph()
LLVector4a::memcpyNonAliased16((F32*) mScaledNormals, (F32*) mSharedData->mBaseNormals, sizeof(LLVector4a) * mSharedData->mNumVertices);
LLVector4a::memcpyNonAliased16((F32*) mBinormals, (F32*) mSharedData->mBaseNormals, sizeof(LLVector4a) * mSharedData->mNumVertices);
LLVector4a::memcpyNonAliased16((F32*) mScaledBinormals, (F32*) mSharedData->mBaseNormals, sizeof(LLVector4a) * mSharedData->mNumVertices);
- LLVector4a::memcpyNonAliased16((F32*) mTexCoords, (F32*) mSharedData->mTexCoords, sizeof(LLVector2) * (mSharedData->mNumVertices + mSharedData->mNumVertices%2));
+ memcpy((F32*) mTexCoords, (F32*) mSharedData->mTexCoords, sizeof(LLVector2) * (mSharedData->mNumVertices)); // allocated in LLPolyMeshSharedData::allocateVertexData
for (S32 i = 0; i < mSharedData->mNumVertices; ++i)
{
diff --git a/indra/llmessage/llproxy.cpp b/indra/llmessage/llproxy.cpp
index 864e68998c..d04ca52ad6 100644
--- a/indra/llmessage/llproxy.cpp
+++ b/indra/llmessage/llproxy.cpp
@@ -465,7 +465,7 @@ void LLProxy::applyProxySettings(CURL* handle)
/**
* @brief Send one TCP packet and receive one in return.
*
- * This operation is done synchronously with a 1000ms timeout. Therefore, it should not be used when a blocking
+ * This operation is done synchronously with a 100ms timeout. Therefore, it should not be used when a blocking
* operation would impact the operation of the viewer.
*
* @param handle_ptr Pointer to a connected LLSocket of type STREAM_TCP.
@@ -482,7 +482,7 @@ static apr_status_t tcp_blocking_handshake(LLSocket::ptr_t handle, char * dataou
apr_size_t expected_len = outlen;
- handle->setBlocking(1000);
+ handle->setBlocking(100000); // 100ms, 100000us. Should be sufficient for localhost, nearby network
rv = apr_socket_send(apr_socket, dataout, &outlen);
if (APR_SUCCESS != rv)
diff --git a/indra/llxml/llxmltree.cpp b/indra/llxml/llxmltree.cpp
index 164b3156e1..d66544d0f8 100644
--- a/indra/llxml/llxmltree.cpp
+++ b/indra/llxml/llxmltree.cpp
@@ -108,12 +108,15 @@ LLXmlTreeNode::LLXmlTreeNode( const std::string& name, LLXmlTreeNode* parent, LL
LLXmlTreeNode::~LLXmlTreeNode()
{
- attribute_map_t::iterator iter;
- for (iter=mAttributes.begin(); iter != mAttributes.end(); iter++)
- delete iter->second;
- for(LLXmlTreeNode* node : mChildren)
+ for (auto& attr : mAttributes)
+ {
+ delete attr.second;
+ }
+ mAttributes.clear();
+
+ for (auto& child : mChildren)
{
- delete node;
+ delete child;
}
mChildren.clear();
}
diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp
index a076594e0a..ed82f1db48 100644
--- a/indra/newview/llagent.cpp
+++ b/indra/newview/llagent.cpp
@@ -56,6 +56,7 @@
#include "llgroupmgr.h"
#include "llhudmanager.h"
#include "lljoystickbutton.h"
+#include "lllandmarkactions.h"
#include "llmorphview.h"
#include "llmoveview.h"
#include "llnavigationbar.h" // to show/hide navigation bar when changing mouse look state
@@ -4320,8 +4321,17 @@ void LLAgent::teleportViaLandmark(const LLUUID& landmark_asset_id)
void LLAgent::doTeleportViaLandmark(const LLUUID& landmark_asset_id)
{
- LLViewerRegion *regionp = getRegion();
- if(regionp && teleportCore())
+ bool is_local(false);
+ LLViewerRegion* regionp = getRegion();
+
+ if (LLLandmark* landmark = gLandmarkList.getAsset(landmark_asset_id, NULL))
+ {
+ LLVector3d pos_global;
+ landmark->getGlobalPos(pos_global);
+ is_local = (regionp->getHandle() == to_region_handle_global((F32)pos_global.mdV[VX], (F32)pos_global.mdV[VY]));
+ }
+
+ if(regionp && teleportCore(is_local))
{
LL_INFOS("Teleport") << "Sending TeleportLandmarkRequest. Current region handle " << regionp->getHandle()
<< " region id " << regionp->getRegionID()
diff --git a/indra/newview/llaisapi.cpp b/indra/newview/llaisapi.cpp
index ce4e8e9392..11c5ffecb6 100644
--- a/indra/newview/llaisapi.cpp
+++ b/indra/newview/llaisapi.cpp
@@ -1385,8 +1385,6 @@ void AISUpdate::parseCategory(const LLSD& category_map, S32 depth)
&& curr_cat->getVersion() > LLViewerInventoryCategory::VERSION_UNKNOWN
&& version > curr_cat->getVersion())
{
- // Potentially should new_cat->setVersion(unknown) here,
- // but might be waiting for a callback that would increment
LL_DEBUGS("Inventory") << "Category " << category_id
<< " is stale. Known version: " << curr_cat->getVersion()
<< " server version: " << version << LL_ENDL;
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index e8546d422b..a05c2376a0 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -2350,6 +2350,14 @@ void LLAppViewer::initLoggingAndGetLastDuration()
{
LL_WARNS("MarkerFile") << duration_log_msg << LL_ENDL;
}
+
+ std::string user_data_path_cef_log = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "cef.log");
+ if (gDirUtilp->fileExists(user_data_path_cef_log))
+ {
+ std::string user_data_path_cef_old = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "cef.old");
+ LLFile::remove(user_data_path_cef_old, ENOENT);
+ LLFile::rename(user_data_path_cef_log, user_data_path_cef_old);
+ }
}
}
@@ -2977,9 +2985,10 @@ void LLAppViewer::initStrings()
std::string strings_path_full = gDirUtilp->findSkinnedFilenameBaseLang(LLDir::XUI, strings_file);
if (strings_path_full.empty() || !LLFile::isfile(strings_path_full))
{
+ std::string crash_reason;
if (strings_path_full.empty())
{
- LL_WARNS() << "The file '" << strings_file << "' is not found" << LL_ENDL;
+ crash_reason = "The file '" + strings_file + "' is not found";
}
else
{
@@ -2987,24 +2996,23 @@ void LLAppViewer::initStrings()
int rc = LLFile::stat(strings_path_full, &st);
if (rc != 0)
{
- LL_WARNS() << "The file '" << strings_path_full << "' failed to get status. Error code: " << rc << LL_ENDL;
+ crash_reason = "The file '" + strings_path_full + "' failed to get status. Error code: " + std::to_string(rc);
}
else if (S_ISDIR(st.st_mode))
{
- LL_WARNS() << "The filename '" << strings_path_full << "' is a directory name" << LL_ENDL;
+ crash_reason = "The filename '" + strings_path_full + "' is a directory name";
}
else
{
- LL_WARNS() << "The filename '" << strings_path_full << "' doesn't seem to be a regular file name" << LL_ENDL;
+ crash_reason = "The filename '" + strings_path_full + "' doesn't seem to be a regular file name";
}
}
// initial check to make sure files are there failed
gDirUtilp->dumpCurrentDirectories(LLError::LEVEL_WARN);
LLError::LLUserWarningMsg::showMissingFiles();
- LL_ERRS() << "Viewer failed to find localization and UI files."
- << " Please reinstall viewer from https://secondlife.com/support/downloads"
- << " and contact https://support.secondlife.com if issue persists after reinstall." << LL_ENDL;
+ LL_ERRS() << "Viewer failed to open some of localization and UI files."
+ << " " << crash_reason << "." << LL_ENDL;
}
LLTransUtil::parseStrings(strings_file, default_trans_args);
LLTransUtil::parseLanguageStrings("language_settings.xml");
diff --git a/indra/newview/llfilepicker.cpp b/indra/newview/llfilepicker.cpp
index 0afb275d13..716e6cd9e3 100644
--- a/indra/newview/llfilepicker.cpp
+++ b/indra/newview/llfilepicker.cpp
@@ -670,6 +670,7 @@ std::unique_ptr<std::vector<std::string>> LLFilePicker::navOpenFilterProc(ELoadF
break;
case FFLOAD_HDRI:
allowedv->push_back("exr");
+ case FFLOAD_MODEL:
case FFLOAD_COLLADA:
allowedv->push_back("dae");
break;
diff --git a/indra/newview/llfloatercreatelandmark.cpp b/indra/newview/llfloatercreatelandmark.cpp
index 2ce8a7a212..5d525407fd 100644
--- a/indra/newview/llfloatercreatelandmark.cpp
+++ b/indra/newview/llfloatercreatelandmark.cpp
@@ -31,6 +31,7 @@
#include "llagent.h"
#include "llagentui.h"
#include "llcombobox.h"
+#include "llfloaterreg.h"
#include "llinventoryfunctions.h"
#include "llinventoryobserver.h"
#include "lllandmarkactions.h"
@@ -296,7 +297,7 @@ void LLFloaterCreateLandmark::onCreateFolderClicked()
void LLFloaterCreateLandmark::folderCreatedCallback(LLUUID folder_id)
{
- populateFoldersList(folder_id);
+ populateFoldersList(folder_id);
}
void LLFloaterCreateLandmark::onSaveClicked()
@@ -389,6 +390,7 @@ void LLFloaterCreateLandmark::setItem(const uuid_set_t& items)
{
mItem = item;
mAssetID = mItem->getAssetUUID();
+ mParentID = mItem->getParentUUID();
setVisibleAndFrontmost(true);
break;
}
@@ -418,8 +420,7 @@ void LLFloaterCreateLandmark::updateItem(const uuid_set_t& items, U32 mask)
closeFloater();
}
- LLUUID folder_id = mFolderCombo->getValue().asUUID();
- if (folder_id != mItem->getParentUUID())
+ if (mParentID != mItem->getParentUUID())
{
// user moved landmark in inventory,
// assume that we are done all other changes should already be commited
diff --git a/indra/newview/llfloatercreatelandmark.h b/indra/newview/llfloatercreatelandmark.h
index fa6d001b8e..f97ade2c1b 100644
--- a/indra/newview/llfloatercreatelandmark.h
+++ b/indra/newview/llfloatercreatelandmark.h
@@ -69,6 +69,7 @@ private:
LLTextEditor* mNotesEditor;
LLUUID mLandmarksID;
LLUUID mAssetID;
+ LLUUID mParentID;
LLLandmarksInventoryObserver* mInventoryObserver;
LLPointer<LLInventoryItem> mItem;
diff --git a/indra/newview/llfloateremojipicker.cpp b/indra/newview/llfloateremojipicker.cpp
index cc13e5d059..7e13503103 100644
--- a/indra/newview/llfloateremojipicker.cpp
+++ b/indra/newview/llfloateremojipicker.cpp
@@ -57,8 +57,7 @@ static const S32 USED_EMOJIS_IMAGE_INDEX = 0x23F2;
// https://www.compart.com/en/unicode/U+1F6D1
static const S32 EMPTY_LIST_IMAGE_INDEX = 0x1F6D1;
// The following categories should follow the required alphabetic order
-static const std::string RECENTLY_USED_CATEGORY = "1 recently used";
-static const std::string FREQUENTLY_USED_CATEGORY = "2 frequently used";
+static const std::string FREQUENTLY_USED_CATEGORY = "frequently used";
// Floater state related variables
static std::list<llwchar> sRecentlyUsed;
@@ -445,11 +444,10 @@ void LLFloaterEmojiPicker::fillGroups()
params.name = "all_categories";
createGroupButton(params, rect, ALL_EMOJIS_IMAGE_INDEX);
- // Create group and button for "Recently used" and/or "Frequently used"
- if (!sRecentlyUsed.empty() || !sFrequentlyUsed.empty())
+ // Create group and button for "Frequently used"
+ if (!sFrequentlyUsed.empty())
{
std::map<std::string, std::vector<LLEmojiSearchResult>> cats;
- fillCategoryRecentlyUsed(cats);
fillCategoryFrequentlyUsed(cats);
if (!cats.empty())
@@ -482,40 +480,6 @@ void LLFloaterEmojiPicker::fillGroups()
resizeGroupButtons();
}
-void LLFloaterEmojiPicker::fillCategoryRecentlyUsed(std::map<std::string, std::vector<LLEmojiSearchResult>>& cats)
-{
- if (sRecentlyUsed.empty())
- return;
-
- std::vector<LLEmojiSearchResult> emojis;
-
- // In case of empty mFilterPattern we'd use sRecentlyUsed directly
- if (!mFilterPattern.empty())
- {
- // List all emojis in "Recently used"
- const LLEmojiDictionary::emoji2descr_map_t& emoji2descr = LLEmojiDictionary::instance().getEmoji2Descr();
- std::size_t begin, end;
- for (llwchar emoji : sRecentlyUsed)
- {
- auto e2d = emoji2descr.find(emoji);
- if (e2d != emoji2descr.end() && !e2d->second->ShortCodes.empty())
- {
- for (const std::string& shortcode : e2d->second->ShortCodes)
- {
- if (LLEmojiDictionary::searchInShortCode(begin, end, shortcode, mFilterPattern))
- {
- emojis.emplace_back(emoji, shortcode, begin, end);
- }
- }
- }
- }
- if (emojis.empty())
- return;
- }
-
- cats.emplace(std::make_pair(RECENTLY_USED_CATEGORY, emojis));
-}
-
void LLFloaterEmojiPicker::fillCategoryFrequentlyUsed(std::map<std::string, std::vector<LLEmojiSearchResult>>& cats)
{
if (sFrequentlyUsed.empty())
@@ -756,7 +720,6 @@ void LLFloaterEmojiPicker::fillEmojisCategory(const std::vector<LLEmojiSearchRes
{
// Place the category title
std::string title =
- category == RECENTLY_USED_CATEGORY ? getString("title_for_recently_used") :
category == FREQUENTLY_USED_CATEGORY ? getString("title_for_frequently_used") :
isupper(category.front()) ? category : LLStringUtil::capitalize(category);
LLEmojiGridDivider* div = new LLEmojiGridDivider(row_panel_params, title);
@@ -769,21 +732,7 @@ void LLFloaterEmojiPicker::fillEmojisCategory(const std::vector<LLEmojiSearchRes
{
const LLEmojiDictionary::emoji2descr_map_t& emoji2descr = LLEmojiDictionary::instance().getEmoji2Descr();
LLEmojiSearchResult emoji { 0, "", 0, 0 };
- if (category == RECENTLY_USED_CATEGORY)
- {
- for (llwchar code : sRecentlyUsed)
- {
- const LLEmojiDictionary::emoji2descr_map_t::const_iterator& e2d = emoji2descr.find(code);
- if (e2d != emoji2descr.end() && !e2d->second->ShortCodes.empty())
- {
- emoji.Character = code;
- emoji.String = e2d->second->ShortCodes.front();
- createEmojiIcon(emoji, category, row_panel_params, row_list_params, icon_params,
- icon_rect, max_icons, bg, row, icon_index);
- }
- }
- }
- else if (category == FREQUENTLY_USED_CATEGORY)
+ if (category == FREQUENTLY_USED_CATEGORY)
{
for (const auto& code : sFrequentlyUsed)
{
diff --git a/indra/newview/llfloateremojipicker.h b/indra/newview/llfloateremojipicker.h
index 669683eb9e..b807adb67d 100644
--- a/indra/newview/llfloateremojipicker.h
+++ b/indra/newview/llfloateremojipicker.h
@@ -60,7 +60,6 @@ public:
private:
void initialize();
void fillGroups();
- void fillCategoryRecentlyUsed(std::map<std::string, std::vector<LLEmojiSearchResult>>& cats);
void fillCategoryFrequentlyUsed(std::map<std::string, std::vector<LLEmojiSearchResult>>& cats);
void fillGroupEmojis(std::map<std::string, std::vector<LLEmojiSearchResult>>& cats, U32 index);
void createGroupButton(LLButton::Params& params, const LLRect& rect, llwchar emoji);
diff --git a/indra/newview/llfloaterperformance.cpp b/indra/newview/llfloaterperformance.cpp
index 315508f22b..3eb0c849d3 100644
--- a/indra/newview/llfloaterperformance.cpp
+++ b/indra/newview/llfloaterperformance.cpp
@@ -115,12 +115,12 @@ bool LLFloaterPerformance::postBuild()
mHUDList = mHUDsPanel->getChild<LLNameListCtrl>("hud_list");
mHUDList->setNameListType(LLNameListCtrl::SPECIAL);
mHUDList->setHoverIconName("StopReload_Off");
- mHUDList->setIconClickedCallback(boost::bind(&LLFloaterPerformance::detachItem, this, _1));
+ mHUDList->setIconClickedCallback(boost::bind(&LLFloaterPerformance::detachObject, this, _1));
mObjectList = mComplexityPanel->getChild<LLNameListCtrl>("obj_list");
mObjectList->setNameListType(LLNameListCtrl::SPECIAL);
mObjectList->setHoverIconName("StopReload_Off");
- mObjectList->setIconClickedCallback(boost::bind(&LLFloaterPerformance::detachItem, this, _1));
+ mObjectList->setIconClickedCallback(boost::bind(&LLFloaterPerformance::detachObject, this, _1));
mSettingsPanel->getChild<LLButton>("advanced_btn")->setCommitCallback(boost::bind(&LLFloaterPerformance::onClickAdvanced, this));
mSettingsPanel->getChild<LLButton>("defaults_btn")->setCommitCallback(boost::bind(&LLFloaterPerformance::onClickDefaults, this));
@@ -527,9 +527,13 @@ void LLFloaterPerformance::setFPSText()
mTextFPSLabel->setValue(fps_text);
}
-void LLFloaterPerformance::detachItem(const LLUUID& item_id)
+void LLFloaterPerformance::detachObject(const LLUUID& obj_id)
{
- LLAppearanceMgr::instance().removeItemFromAvatar(item_id);
+ LLViewerObject* obj = gObjectList.findObject(obj_id);
+ if (obj)
+ {
+ LLAppearanceMgr::instance().removeItemFromAvatar(obj->getAttachmentItemID());
+ }
}
void LLFloaterPerformance::onClickAdvanced()
diff --git a/indra/newview/llfloaterperformance.h b/indra/newview/llfloaterperformance.h
index a7100eb350..6cca85a009 100644
--- a/indra/newview/llfloaterperformance.h
+++ b/indra/newview/llfloaterperformance.h
@@ -48,7 +48,7 @@ public:
void hidePanels();
void showAutoadjustmentsPanel();
- void detachItem(const LLUUID& item_id);
+ void detachObject(const LLUUID& obj_id);
void onAvatarListRightClick(LLUICtrl* ctrl, S32 x, S32 y);
diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp
index e673752986..ce1072a968 100644
--- a/indra/newview/llfloaterpreference.cpp
+++ b/indra/newview/llfloaterpreference.cpp
@@ -329,6 +329,7 @@ LLFloaterPreference::LLFloaterPreference(const LLSD& key)
mCommitCallbackRegistrar.add("Pref.AutoAdjustments", boost::bind(&LLFloaterPreference::onClickAutoAdjustments, this));
mCommitCallbackRegistrar.add("Pref.HardwareDefaults", boost::bind(&LLFloaterPreference::setHardwareDefaults, this));
mCommitCallbackRegistrar.add("Pref.AvatarImpostorsEnable", boost::bind(&LLFloaterPreference::onAvatarImpostorsEnable, this));
+ mCommitCallbackRegistrar.add("Pref.UpdateIndirectMaxNonImpostors", boost::bind(&LLFloaterPreference::updateMaxNonImpostors, this));
mCommitCallbackRegistrar.add("Pref.UpdateIndirectMaxComplexity", boost::bind(&LLFloaterPreference::updateMaxComplexity, this));
mCommitCallbackRegistrar.add("Pref.RenderOptionUpdate", boost::bind(&LLFloaterPreference::onRenderOptionEnable, this));
mCommitCallbackRegistrar.add("Pref.WindowedMod", boost::bind(&LLFloaterPreference::onCommitWindowedMode, this));
@@ -360,6 +361,7 @@ LLFloaterPreference::LLFloaterPreference(const LLSD& key)
LLAvatarPropertiesProcessor::getInstance()->addObserver( gAgent.getID(), this );
mComplexityChangedSignal = gSavedSettings.getControl("RenderAvatarMaxComplexity")->getCommitSignal()->connect(boost::bind(&LLFloaterPreference::updateComplexityText, this));
+ mImpostorsChangedSignal = gSavedSettings.getControl("RenderAvatarMaxNonImpostors")->getSignal()->connect(boost::bind(&LLFloaterPreference::updateIndirectMaxNonImpostors, this, _2));
mCommitCallbackRegistrar.add("Pref.ClearLog", boost::bind(&LLConversationLog::onClearLog, &LLConversationLog::instance()));
mCommitCallbackRegistrar.add("Pref.DeleteTranscripts", boost::bind(&LLFloaterPreference::onDeleteTranscripts, this));
@@ -543,6 +545,7 @@ LLFloaterPreference::~LLFloaterPreference()
{
LLConversationLog::instance().removeObserver(this);
mComplexityChangedSignal.disconnect();
+ mImpostorsChangedSignal.disconnect();
}
void LLFloaterPreference::draw()
@@ -1287,6 +1290,9 @@ void LLAvatarComplexityControls::setIndirectMaxArc()
void LLFloaterPreference::refresh()
{
LLPanel::refresh();
+ setMaxNonImpostorsText(
+ gSavedSettings.getU32("RenderAvatarMaxNonImpostors"),
+ getChild<LLTextBox>("IndirectMaxNonImpostorsText", true));
LLAvatarComplexityControls::setText(
gSavedSettings.getU32("RenderAvatarMaxComplexity"),
getChild<LLTextBox>("IndirectMaxComplexityText", true));
@@ -1561,6 +1567,44 @@ void LLAvatarComplexityControls::setRenderTimeText(F32 value, LLTextBox* text_bo
}
}
+void LLFloaterPreference::updateMaxNonImpostors()
+{
+ // Called when the IndirectMaxNonImpostors control changes
+ // Responsible for fixing the slider label (IndirectMaxNonImpostorsText) and setting RenderAvatarMaxNonImpostors
+ LLSliderCtrl* ctrl = getChild<LLSliderCtrl>("IndirectMaxNonImpostors", true);
+ U32 value = ctrl->getValue().asInteger();
+
+ if (0 == value || LLVOAvatar::NON_IMPOSTORS_MAX_SLIDER <= value)
+ {
+ value = 0;
+ }
+ gSavedSettings.setU32("RenderAvatarMaxNonImpostors", value);
+ LLVOAvatar::updateImpostorRendering(value); // make it effective immediately
+ setMaxNonImpostorsText(value, getChild<LLTextBox>("IndirectMaxNonImpostorsText"));
+}
+
+void LLFloaterPreference::updateIndirectMaxNonImpostors(const LLSD& newvalue)
+{
+ U32 value = newvalue.asInteger();
+ if ((value != 0) && (value != gSavedSettings.getU32("IndirectMaxNonImpostors")))
+ {
+ gSavedSettings.setU32("IndirectMaxNonImpostors", value);
+ }
+ setMaxNonImpostorsText(value, getChild<LLTextBox>("IndirectMaxNonImpostorsText"));
+}
+
+void LLFloaterPreference::setMaxNonImpostorsText(U32 value, LLTextBox* text_box)
+{
+ if (0 == value)
+ {
+ text_box->setText(LLTrans::getString("no_limit"));
+ }
+ else
+ {
+ text_box->setText(llformat("%d", value));
+ }
+}
+
void LLFloaterPreference::updateMaxComplexity()
{
// Called when the IndirectMaxComplexity control changes
diff --git a/indra/newview/llfloaterpreference.h b/indra/newview/llfloaterpreference.h
index 51ed3d8179..fa9c421a8f 100644
--- a/indra/newview/llfloaterpreference.h
+++ b/indra/newview/llfloaterpreference.h
@@ -206,6 +206,9 @@ private:
void onDeleteTranscripts();
void onDeleteTranscriptsResponse(const LLSD& notification, const LLSD& response);
void updateDeleteTranscriptsButton();
+ void updateMaxNonImpostors();
+ void updateIndirectMaxNonImpostors(const LLSD& newvalue);
+ void setMaxNonImpostorsText(U32 value, LLTextBox* text_box);
void updateMaxComplexity();
void updateComplexityText();
static bool loadFromFilename(const std::string& filename, std::map<std::string, std::string> &label_map);
@@ -234,6 +237,7 @@ private:
std::unique_ptr< ll::prefs::SearchData > mSearchData;
bool mSearchDataDirty;
+ boost::signals2::connection mImpostorsChangedSignal;
boost::signals2::connection mComplexityChangedSignal;
void onUpdateFilterTerm( bool force = false );
diff --git a/indra/newview/llfloaterpreferencesgraphicsadvanced.cpp b/indra/newview/llfloaterpreferencesgraphicsadvanced.cpp
index 8e8967ee3d..a8a1e507a8 100644
--- a/indra/newview/llfloaterpreferencesgraphicsadvanced.cpp
+++ b/indra/newview/llfloaterpreferencesgraphicsadvanced.cpp
@@ -51,6 +51,8 @@ LLFloaterPreferenceGraphicsAdvanced::LLFloaterPreferenceGraphicsAdvanced(const L
mCommitCallbackRegistrar.add("Pref.Cancel", boost::bind(&LLFloaterPreferenceGraphicsAdvanced::onBtnCancel, this, _2));
mCommitCallbackRegistrar.add("Pref.OK", boost::bind(&LLFloaterPreferenceGraphicsAdvanced::onBtnOK, this, _2));
+
+ mImpostorsChangedSignal = gSavedSettings.getControl("RenderAvatarMaxNonImpostors")->getSignal()->connect(boost::bind(&LLFloaterPreferenceGraphicsAdvanced::updateIndirectMaxNonImpostors, this, _2));
}
LLFloaterPreferenceGraphicsAdvanced::~LLFloaterPreferenceGraphicsAdvanced()
@@ -58,7 +60,6 @@ LLFloaterPreferenceGraphicsAdvanced::~LLFloaterPreferenceGraphicsAdvanced()
mComplexityChangedSignal.disconnect();
mComplexityModeChangedSignal.disconnect();
mLODFactorChangedSignal.disconnect();
- mNumImpostorsChangedSignal.disconnect();
}
bool LLFloaterPreferenceGraphicsAdvanced::postBuild()
@@ -254,8 +255,8 @@ void LLFloaterPreferenceGraphicsAdvanced::updateIndirectMaxNonImpostors(const LL
if ((value != 0) && (value != gSavedSettings.getU32("IndirectMaxNonImpostors")))
{
gSavedSettings.setU32("IndirectMaxNonImpostors", value);
- setMaxNonImpostorsText(value, getChild<LLTextBox>("IndirectMaxNonImpostorsText"));
}
+ setMaxNonImpostorsText(value, getChild<LLTextBox>("IndirectMaxNonImpostorsText"));
}
void LLFloaterPreferenceGraphicsAdvanced::setMaxNonImpostorsText(U32 value, LLTextBox* text_box)
diff --git a/indra/newview/llfloaterpreferencesgraphicsadvanced.h b/indra/newview/llfloaterpreferencesgraphicsadvanced.h
index 61203be068..a1a54f238d 100644
--- a/indra/newview/llfloaterpreferencesgraphicsadvanced.h
+++ b/indra/newview/llfloaterpreferencesgraphicsadvanced.h
@@ -61,6 +61,7 @@ protected:
void onBtnOK(const LLSD& userdata);
void onBtnCancel(const LLSD& userdata);
+ boost::signals2::connection mImpostorsChangedSignal;
boost::signals2::connection mComplexityChangedSignal;
boost::signals2::connection mComplexityModeChangedSignal;
boost::signals2::connection mLODFactorChangedSignal;
diff --git a/indra/newview/llglsandbox.cpp b/indra/newview/llglsandbox.cpp
index 5484ce6276..112008172e 100644
--- a/indra/newview/llglsandbox.cpp
+++ b/indra/newview/llglsandbox.cpp
@@ -903,39 +903,6 @@ private:
};
-F32 shader_timer_benchmark(std::vector<LLRenderTarget> & dest, TextureHolder & texHolder, U32 textures_count, LLVertexBuffer * buff, F32 &seconds)
-{
- // run GPU timer benchmark
-
- //number of samples to take
- const S32 samples = 64;
-
- {
- ShaderProfileHelper initProfile;
- dest[0].bindTarget();
- gBenchmarkProgram.bind();
- for (S32 c = 0; c < samples; ++c)
- {
- for (U32 i = 0; i < textures_count; ++i)
- {
- texHolder.bind(i);
- buff->setBuffer();
- buff->drawArrays(LLRender::TRIANGLES, 0, 3);
- }
- }
- gBenchmarkProgram.unbind();
- dest[0].flush();
- }
-
- F32 ms = gBenchmarkProgram.mTimeElapsed / 1000000.f;
- seconds = ms / 1000.f;
-
- F64 samples_drawn = (F64)gBenchmarkProgram.mSamplesDrawn;
- F64 gpixels_drawn = samples_drawn / 1000000000.0;
- F32 samples_sec = (F32)(gpixels_drawn / seconds);
- return samples_sec * 4; // 4 bytes per sample
-}
-
//-----------------------------------------------------------------------------
// gpu_benchmark()
// returns measured memory bandwidth of GPU in gigabytes per second
@@ -977,6 +944,9 @@ F32 gpu_benchmark()
//number of textures
const U32 count = 32;
+ //number of samples to take
+ const S32 samples = 64;
+
//time limit, allocation operations shouldn't take longer then 30 seconds, same for actual benchmark.
const F32 time_limit = 30;
@@ -1066,15 +1036,33 @@ F32 gpu_benchmark()
LLGLSLShader::unbind();
- // run GPU timer benchmark twice
- F32 seconds = 0;
- F32 gbps = shader_timer_benchmark(dest, texHolder, count, buff.get(), seconds);
+ // run GPU timer benchmark
+ {
+ ShaderProfileHelper initProfile;
+ dest[0].bindTarget();
+ gBenchmarkProgram.bind();
+ for (S32 c = 0; c < samples; ++c)
+ {
+ for (U32 i = 0; i < count; ++i)
+ {
+ texHolder.bind(i);
+ buff->setBuffer();
+ buff->drawArrays(LLRender::TRIANGLES, 0, 3);
+ }
+ }
+ gBenchmarkProgram.unbind();
+ dest[0].flush();
+ }
- LL_INFOS("Benchmark") << "Memory bandwidth, 1st run is " << llformat("%.3f", gbps) << " GB/sec according to ARB_timer_query, total time " << seconds << " seconds" << LL_ENDL;
+ F32 ms = gBenchmarkProgram.mTimeElapsed/1000000.f;
+ F32 seconds = ms/1000.f;
- gbps = shader_timer_benchmark(dest, texHolder, count, buff.get(), seconds);
+ F64 samples_drawn = (F64)gBenchmarkProgram.mSamplesDrawn;
+ F64 gpixels_drawn = samples_drawn / 1000000000.0;
+ F32 samples_sec = (F32)(gpixels_drawn/seconds);
+ F32 gbps = samples_sec*4; // 4 bytes per sample
- LL_INFOS("Benchmark") << "Memory bandwidth, final run is " << llformat("%.3f", gbps) << " GB/sec according to ARB_timer_query, total time " << seconds << " seconds" << LL_ENDL;
+ LL_INFOS("Benchmark") << "Memory bandwidth is " << llformat("%.3f", gbps) << " GB/sec according to ARB_timer_query, total time " << seconds << " seconds" << LL_ENDL;
return gbps;
}
diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp
index e7584018a8..479b7c19ac 100644
--- a/indra/newview/llinventorybridge.cpp
+++ b/indra/newview/llinventorybridge.cpp
@@ -844,7 +844,7 @@ void LLInvFVBridge::getClipboardEntries(bool show_asset_id,
disabled_items.push_back(std::string("Copy"));
}
- if (isAgentInventory() && !single_folder_root)
+ if (isAgentInventory() && !single_folder_root && !isMarketplaceListingsFolder())
{
items.push_back(std::string("New folder from selected"));
items.push_back(std::string("Subfolder Separator"));
@@ -5315,7 +5315,7 @@ void LLFolderBridge::dropToMyOutfits(LLInventoryCategory* inv_cat, LLPointer<LLI
// Note: creation will take time, so passing folder id to callback is slightly unreliable,
// but so is collecting and passing descendants' ids
- inventory_func_type func = boost::bind(&LLFolderBridge::outfitFolderCreatedCallback, this, inv_cat->getUUID(), _1, cb);
+ inventory_func_type func = boost::bind(outfitFolderCreatedCallback, inv_cat->getUUID(), _1, cb, mInventoryPanel);
gInventory.createNewCategory(dest_id,
LLFolderType::FT_OUTFIT,
inv_cat->getName(),
@@ -5323,11 +5323,25 @@ void LLFolderBridge::dropToMyOutfits(LLInventoryCategory* inv_cat, LLPointer<LLI
inv_cat->getThumbnailUUID());
}
-void LLFolderBridge::outfitFolderCreatedCallback(LLUUID cat_source_id, LLUUID cat_dest_id, LLPointer<LLInventoryCallback> cb)
+void LLFolderBridge::outfitFolderCreatedCallback(LLUUID cat_source_id,
+ LLUUID cat_dest_id,
+ LLPointer<LLInventoryCallback> cb,
+ LLHandle<LLInventoryPanel> inventory_panel)
{
LLInventoryModel::cat_array_t* categories;
LLInventoryModel::item_array_t* items;
- getInventoryModel()->getDirectDescendentsOf(cat_source_id, categories, items);
+
+ LLInventoryPanel* panel = inventory_panel.get();
+ if (!panel)
+ {
+ return;
+ }
+ LLInventoryModel* model = panel->getModel();
+ if (!model)
+ {
+ return;
+ }
+ model->getDirectDescendentsOf(cat_source_id, categories, items);
LLInventoryObject::const_object_list_t link_array;
diff --git a/indra/newview/llinventorybridge.h b/indra/newview/llinventorybridge.h
index 746b79ce87..3e7f74384b 100644
--- a/indra/newview/llinventorybridge.h
+++ b/indra/newview/llinventorybridge.h
@@ -378,7 +378,10 @@ public:
static void staticFolderOptionsMenu();
protected:
- void outfitFolderCreatedCallback(LLUUID cat_source_id, LLUUID cat_dest_id, LLPointer<LLInventoryCallback> cb);
+ static void outfitFolderCreatedCallback(LLUUID cat_source_id,
+ LLUUID cat_dest_id,
+ LLPointer<LLInventoryCallback> cb,
+ LLHandle<LLInventoryPanel> inventory_panel);
void callback_pasteFromClipboard(const LLSD& notification, const LLSD& response);
void perform_pasteFromClipboard();
void gatherMessage(std::string& message, S32 depth, LLError::ELevel log_level);
diff --git a/indra/newview/llinventorymodelbackgroundfetch.cpp b/indra/newview/llinventorymodelbackgroundfetch.cpp
index d8e6bf380e..2cf1554957 100644
--- a/indra/newview/llinventorymodelbackgroundfetch.cpp
+++ b/indra/newview/llinventorymodelbackgroundfetch.cpp
@@ -30,6 +30,7 @@
#include "llaisapi.h"
#include "llagent.h"
#include "llappviewer.h"
+#include "llappearancemgr.h"
#include "llcallbacklist.h"
#include "llinventorymodel.h"
#include "llinventorypanel.h"
@@ -470,6 +471,22 @@ void LLInventoryModelBackgroundFetch::fetchCOF(nullary_func_t callback)
callback();
LLUUID cat_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_CURRENT_OUTFIT);
LLInventoryModelBackgroundFetch::getInstance()->onAISFolderCalback(cat_id, id, FT_DEFAULT);
+
+ if (id.notNull())
+ {
+ // COF might have fetched base outfit folder through a link, but it hasn't
+ // fetched base outfit's content, which doesn't nessesary match COF,
+ // so make sure it's up to date
+ LLUUID baseoutfit_id = LLAppearanceMgr::getInstance()->getBaseOutfitUUID();
+ if (baseoutfit_id.notNull())
+ {
+ LLViewerInventoryCategory* cat = gInventory.getCategory(baseoutfit_id);
+ if (!cat || cat->getVersion() == LLViewerInventoryCategory::VERSION_UNKNOWN)
+ {
+ LLInventoryModelBackgroundFetch::getInstance()->fetchFolderAndLinks(baseoutfit_id, no_op);
+ }
+ }
+ }
});
// start idle loop to track completion
diff --git a/indra/newview/lloutfitslist.cpp b/indra/newview/lloutfitslist.cpp
index 0f5f7aebf8..6e666b8a4b 100644
--- a/indra/newview/lloutfitslist.cpp
+++ b/indra/newview/lloutfitslist.cpp
@@ -924,8 +924,8 @@ void LLOutfitListBase::onIdleRefreshList()
if (cat)
{
std::string name = cat->getName();
- updateChangedCategoryName(cat, name);
- }
+ updateChangedCategoryName(cat, name);
+ }
curent_time = LLTimer::getTotalSeconds();
if (curent_time >= end_time)
diff --git a/indra/newview/llpanelemojicomplete.cpp b/indra/newview/llpanelemojicomplete.cpp
index fc1bf6ca93..3a6a6a5ec3 100644
--- a/indra/newview/llpanelemojicomplete.cpp
+++ b/indra/newview/llpanelemojicomplete.cpp
@@ -68,6 +68,9 @@ LLPanelEmojiComplete::LLPanelEmojiComplete(const LLPanelEmojiComplete::Params& p
{
LLScrollbar::Params sbparams;
sbparams.orientation(LLScrollbar::VERTICAL);
+ sbparams.doc_size(static_cast<S32>(mTotalEmojis));
+ sbparams.doc_pos(0);
+ sbparams.page_size(static_cast<S32>(mVisibleEmojis));
sbparams.change_callback([this](S32 index, LLScrollbar*) { onScrollbarChange(index); });
mScrollbar = LLUICtrlFactory::create<LLScrollbar>(sbparams);
addChild(mScrollbar);
diff --git a/indra/newview/llviewerjointmesh.cpp b/indra/newview/llviewerjointmesh.cpp
index f0567b18c4..54b6c29e31 100644
--- a/indra/newview/llviewerjointmesh.cpp
+++ b/indra/newview/llviewerjointmesh.cpp
@@ -407,10 +407,16 @@ void LLViewerJointMesh::updateFaceData(LLFace *face, F32 pixel_area, bool damp_w
F32* vw = (F32*) vertex_weightsp.get();
F32* cw = (F32*) clothing_weightsp.get();
- S32 tc_size = (num_verts*2*sizeof(F32)+0xF) & ~0xF;
- LLVector4a::memcpyNonAliased16(tc, (F32*) mMesh->getTexCoords(), tc_size);
- S32 vw_size = (num_verts*sizeof(F32)+0xF) & ~0xF;
- LLVector4a::memcpyNonAliased16(vw, (F32*) mMesh->getWeights(), vw_size);
+ //S32 tc_size = (num_verts*2*sizeof(F32)+0xF) & ~0xF;
+ //LLVector4a::memcpyNonAliased16(tc, (F32*) mMesh->getTexCoords(), tc_size);
+ //S32 vw_size = (num_verts*sizeof(F32)+0xF) & ~0xF;
+ //LLVector4a::memcpyNonAliased16(vw, (F32*) mMesh->getWeights(), vw_size);
+
+ // Both allocated in LLPolyMeshSharedData::allocateVertexData(unsigned int)
+
+ memcpy(tc, mMesh->getTexCoords(), num_verts*2*sizeof(F32) );
+ memcpy(vw, mMesh->getWeights(), num_verts*sizeof(F32) );
+
LLVector4a::memcpyNonAliased16(cw, (F32*) mMesh->getClothingWeights(), num_verts*4*sizeof(F32));
}
diff --git a/indra/newview/llviewermedia.cpp b/indra/newview/llviewermedia.cpp
index d688d5930c..82a52e63f6 100644
--- a/indra/newview/llviewermedia.cpp
+++ b/indra/newview/llviewermedia.cpp
@@ -1730,8 +1730,6 @@ LLPluginClassMedia* LLViewerMediaImpl::newSourceFromMediaType(std::string media_
std::string user_data_path_cache = gDirUtilp->getCacheDir(false);
user_data_path_cache += gDirUtilp->getDirDelimiter();
- std::string user_data_path_cef_log = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "cef_log.txt");
-
// See if the plugin executable exists
llstat s;
if(LLFile::stat(launcher_name, &s))
@@ -1748,6 +1746,7 @@ LLPluginClassMedia* LLViewerMediaImpl::newSourceFromMediaType(std::string media_
{
media_source = new LLPluginClassMedia(owner);
media_source->setSize(default_width, default_height);
+ std::string user_data_path_cef_log = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "cef.log");
media_source->setUserDataPath(user_data_path_cache, gDirUtilp->getUserName(), user_data_path_cef_log);
media_source->setLanguageCode(LLUI::getLanguage());
media_source->setZoomFactor(zoom_factor);
diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp
index 74d795ea25..030dfeaa6f 100644
--- a/indra/newview/llviewerobject.cpp
+++ b/indra/newview/llviewerobject.cpp
@@ -2917,6 +2917,17 @@ void LLViewerObject::fetchInventoryFromServer()
delete mInventory;
mInventory = NULL;
+ // This will get reset by doInventoryCallback or processTaskInv
+ mInvRequestState = INVENTORY_REQUEST_PENDING;
+
+ if (mRegionp && !mRegionp->getCapability("RequestTaskInventory").empty())
+ {
+ LLCoros::instance().launch("LLViewerObject::fetchInventoryFromCapCoro()",
+ boost::bind(&LLViewerObject::fetchInventoryFromCapCoro, mID));
+ }
+ else
+ {
+ LL_WARNS() << "Using old task inventory path!" << LL_ENDL;
// Results in processTaskInv
LLMessageSystem* msg = gMessageSystem;
msg->newMessageFast(_PREHASH_RequestTaskInventory);
@@ -2926,15 +2937,13 @@ void LLViewerObject::fetchInventoryFromServer()
msg->nextBlockFast(_PREHASH_InventoryData);
msg->addU32Fast(_PREHASH_LocalID, mLocalID);
msg->sendReliable(mRegionp->getHost());
-
- // This will get reset by doInventoryCallback or processTaskInv
- mInvRequestState = INVENTORY_REQUEST_PENDING;
+ }
}
}
void LLViewerObject::fetchInventoryDelayed(const F64 &time_seconds)
{
- // unless already waiting, drop previous request and shedule an update
+ // unless already waiting, drop previous request and schedule an update
if (mInvRequestState != INVENTORY_REQUEST_WAIT)
{
if (mInvRequestXFerId != 0)
@@ -2965,6 +2974,80 @@ void LLViewerObject::fetchInventoryDelayedCoro(const LLUUID task_inv, const F64
}
}
+//static
+void LLViewerObject::fetchInventoryFromCapCoro(const LLUUID task_inv)
+{
+ LLViewerObject *obj = gObjectList.findObject(task_inv);
+ if (obj)
+ {
+ LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
+ LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
+ httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("TaskInventoryRequest", httpPolicy));
+ LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
+ std::string url = obj->mRegionp->getCapability("RequestTaskInventory") + "?task_id=" + obj->mID.asString();
+ // If we already have a copy of the inventory then add it so the server won't re-send something we already have.
+ // We expect this case to crop up in the case of failed inventory mutations, but it might happen otherwise as well.
+ if (obj->mInventorySerialNum && obj->mInventory)
+ url += "&inventory_serial=" + std::to_string(obj->mInventorySerialNum);
+
+ obj->mInvRequestState = INVENTORY_XFER;
+ LLSD result = httpAdapter->getAndSuspend(httpRequest, url);
+
+ LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
+ LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
+
+ // Object may have gone away while we were suspended, double-check that it still exists
+ obj = gObjectList.findObject(task_inv);
+ if (!obj)
+ {
+ LL_WARNS() << "Object " << task_inv << " went away while fetching inventory, dropping result" << LL_ENDL;
+ return;
+ }
+
+ bool potentially_stale = false;
+ if (status)
+ {
+ // Dealing with inventory serials is kind of funky. They're monotonically increasing and 16 bits,
+ // so we expect them to overflow, but we can use inv serial < expected serial as a signal that we may
+ // have mutated the task inventory since we kicked off the request, and those mutations may have not
+ // been taken into account yet. Of course, those mutations may have actually failed which would result
+ // in the inv serial never increasing.
+ //
+ // When we detect this case, set the expected inv serial to the inventory serial we actually received
+ // and kick off a re-request after a slight delay.
+ S16 serial = (S16)result["inventory_serial"].asInteger();
+ potentially_stale = serial < obj->mExpectedInventorySerialNum;
+ LL_INFOS() << "Inventory loaded for " << task_inv << LL_ENDL;
+ obj->mInventorySerialNum = serial;
+ obj->mExpectedInventorySerialNum = serial;
+ obj->loadTaskInvLLSD(result);
+ }
+ else if (status.getType() == 304)
+ {
+ LL_INFOS() << "Inventory wasn't changed on server!" << LL_ENDL;
+ obj->mInvRequestState = INVENTORY_REQUEST_STOPPED;
+ // Even though it wasn't necessary to send a response, we still may have mutated
+ // the inventory since we kicked off the request, check for that case.
+ potentially_stale = obj->mInventorySerialNum < obj->mExpectedInventorySerialNum;
+ // Set this to what we already have so that we don't re-request a second time.
+ obj->mExpectedInventorySerialNum = obj->mInventorySerialNum;
+ }
+ else
+ {
+ // Not sure that there's anything sensible we can do to recover here, retrying in a loop would be bad.
+ LL_WARNS() << "Error status while requesting task inventory: " << status.toString() << LL_ENDL;
+ obj->mInvRequestState = INVENTORY_REQUEST_STOPPED;
+ }
+
+ if (potentially_stale)
+ {
+ // Stale? I guess we can use what we got for now, but we'll have to re-request
+ LL_WARNS() << "Stale inv_serial? Re-requesting." << LL_ENDL;
+ obj->fetchInventoryDelayed(INVENTORY_UPDATE_WAIT_TIME_OUTDATED);
+ }
+ }
+}
+
LLControlAvatar *LLViewerObject::getControlAvatar()
{
return getRootEdit()->mControlAvatar.get();
@@ -3140,6 +3223,20 @@ void LLViewerObject::processTaskInv(LLMessageSystem* msg, void** user_data)
S16 serial = 0;
msg->getS16Fast(_PREHASH_InventoryData, _PREHASH_Serial, serial);
+ if (object->mRegionp && !object->mRegionp->getCapability("RequestTaskInventory").empty())
+ {
+ // It seems that simulator may ask us to re-download the task inventory if an update to the inventory
+ // happened out-of-band while we had the object selected (like if a script is saved.)
+ //
+ // If we're meant to use the HTTP capability, ignore the contents of the UDP message and fetch the
+ // inventory via the CAP so that we don't flow down the UDP inventory request path unconditionally here.
+ // We shouldn't need to wait, as any updates should already be ready to fetch by this point.
+ LL_INFOS() << "Handling unsolicited ReplyTaskInventory for " << task_id << LL_ENDL;
+ object->mExpectedInventorySerialNum = serial;
+ object->fetchInventoryFromServer();
+ return;
+ }
+
if (serial == object->mInventorySerialNum
&& serial < object->mExpectedInventorySerialNum)
{
@@ -3347,6 +3444,47 @@ bool LLViewerObject::loadTaskInvFile(const std::string& filename)
return true;
}
+void LLViewerObject::loadTaskInvLLSD(const LLSD& inv_result)
+{
+ if (inv_result.has("contents"))
+ {
+ if(mInventory)
+ {
+ mInventory->clear(); // will deref and delete it
+ }
+ else
+ {
+ mInventory = new LLInventoryObject::object_list_t;
+ }
+
+ // Synthesize the "Contents" category, the viewer expects it, but it isn't sent.
+ LLPointer<LLInventoryObject> inv = new LLInventoryObject(mID, LLUUID::null, LLAssetType::AT_CATEGORY, "Contents");
+ mInventory->push_front(inv);
+
+ const LLSD& inventory = inv_result["contents"];
+ for (const auto& inv_entry : llsd::inArray(inventory))
+ {
+ if (inv_entry.has("item_id"))
+ {
+ LLPointer<LLViewerInventoryItem> inv = new LLViewerInventoryItem;
+ inv->unpackMessage(inv_entry);
+ mInventory->push_front(inv);
+ }
+ else
+ {
+ LL_WARNS_ONCE() << "Unknown inventory entry while reading from inventory file. Entry: '"
+ << inv_entry << "'" << LL_ENDL;
+ }
+ }
+ }
+ else
+ {
+ LL_WARNS() << "unable to load task inventory: " << inv_result << LL_ENDL;
+ return;
+ }
+ doInventoryCallback();
+}
+
void LLViewerObject::doInventoryCallback()
{
for (callback_list_t::iterator iter = mInventoryCallbacks.begin();
diff --git a/indra/newview/llviewerobject.h b/indra/newview/llviewerobject.h
index 119b07b1f5..63458e60ea 100644
--- a/indra/newview/llviewerobject.h
+++ b/indra/newview/llviewerobject.h
@@ -688,6 +688,7 @@ private:
// forms task inventory request after some time passed, marks request as pending
void fetchInventoryDelayed(const F64 &time_seconds);
static void fetchInventoryDelayedCoro(const LLUUID task_inv, const F64 time_seconds);
+ static void fetchInventoryFromCapCoro(const LLUUID task_inv);
public:
//
@@ -826,6 +827,7 @@ protected:
static void processTaskInvFile(void** user_data, S32 error_code, LLExtStat ext_status);
bool loadTaskInvFile(const std::string& filename);
+ void loadTaskInvLLSD(const LLSD &inv_result);
void doInventoryCallback();
bool isOnMap();
diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp
index c21aeb1d57..697433148b 100755
--- a/indra/newview/llviewerregion.cpp
+++ b/indra/newview/llviewerregion.cpp
@@ -3239,6 +3239,7 @@ void LLViewerRegionImpl::buildCapabilityNames(LLSD& capabilityNames)
capabilityNames.append("FetchInventory2");
capabilityNames.append("FetchInventoryDescendents2");
capabilityNames.append("IncrementCOFVersion");
+ capabilityNames.append("RequestTaskInventory");
AISAPI::getCapNames(capabilityNames);
capabilityNames.append("InterestList");
diff --git a/indra/newview/llvoicevivox.cpp b/indra/newview/llvoicevivox.cpp
index 8792ae3285..6d29038a23 100644
--- a/indra/newview/llvoicevivox.cpp
+++ b/indra/newview/llvoicevivox.cpp
@@ -1014,6 +1014,7 @@ bool LLVivoxVoiceClient::startAndLaunchDaemon()
std::string old_log = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "SLVoice.old");
if (gDirUtilp->fileExists(new_log))
{
+ LLFile::remove(old_log, ENOENT);
LLFile::rename(new_log, old_log);
}
diff --git a/indra/newview/skins/default/xui/en/floater_emoji_picker.xml b/indra/newview/skins/default/xui/en/floater_emoji_picker.xml
index e4b8f13df7..f642ca93b7 100644
--- a/indra/newview/skins/default/xui/en/floater_emoji_picker.xml
+++ b/indra/newview/skins/default/xui/en/floater_emoji_picker.xml
@@ -13,7 +13,6 @@
chrome="true"
height="350"
width="304">
- <floater.string name="title_for_recently_used" value="Recently used"/>
<floater.string name="title_for_frequently_used" value="Frequently used"/>
<floater.string name="text_no_emoji_for_filter" value="No emoji found for '[FILTER]'"/>
<scroll_container
diff --git a/indra/newview/skins/default/xui/en/floater_fast_timers.xml b/indra/newview/skins/default/xui/en/floater_fast_timers.xml
index 00411ba20b..ae907bcb5f 100644
--- a/indra/newview/skins/default/xui/en/floater_fast_timers.xml
+++ b/indra/newview/skins/default/xui/en/floater_fast_timers.xml
@@ -75,7 +75,7 @@
step_size="16"
doc_pos="0"
doc_size="3000"
- page_size="0"
+ page_size="50"
/>
</layout_panel>
<layout_panel name="timers_panel"
diff --git a/indra/newview/skins/default/xui/en/floater_preferences_graphics_advanced.xml b/indra/newview/skins/default/xui/en/floater_preferences_graphics_advanced.xml
index 96de9e61cb..78d13293a8 100644
--- a/indra/newview/skins/default/xui/en/floater_preferences_graphics_advanced.xml
+++ b/indra/newview/skins/default/xui/en/floater_preferences_graphics_advanced.xml
@@ -257,7 +257,7 @@
height="16"
increment="1"
initial_value="12"
- label="Max. # of non-impostors:"
+ label="Max. # animated avatars:"
label_width="185"
layout="topleft"
left="30"
diff --git a/indra/newview/skins/default/xui/en/floater_world_map.xml b/indra/newview/skins/default/xui/en/floater_world_map.xml
index b0b818cde5..5ab0177de6 100644
--- a/indra/newview/skins/default/xui/en/floater_world_map.xml
+++ b/indra/newview/skins/default/xui/en/floater_world_map.xml
@@ -37,7 +37,8 @@
top="16"
left="0"
right="-1"
- bottom="-1">
+ bottom="-1"
+ orientation="horizontal">
<layout_panel
name="map_lp"
width="385"
diff --git a/indra/newview/skins/default/xui/en/menu_viewer.xml b/indra/newview/skins/default/xui/en/menu_viewer.xml
index 349c8d0e20..6fb92f7b99 100644
--- a/indra/newview/skins/default/xui/en/menu_viewer.xml
+++ b/indra/newview/skins/default/xui/en/menu_viewer.xml
@@ -4214,16 +4214,6 @@ function="World.EnvPreset"
<menu_item_separator/>
- <menu_item_check
- label="HTTP Textures"
- name="HTTP Textures">
- <menu_item_check.on_check
- function="CheckControl"
- parameter="ImagePipelineUseHTTP" />
- <menu_item_check.on_click
- function="ToggleControl"
- parameter="ImagePipelineUseHTTP" />
- </menu_item_check>
<menu_item_call
label="Compress Images"
name="Compress Images">
diff --git a/indra/newview/skins/default/xui/en/panel_preferences_graphics1.xml b/indra/newview/skins/default/xui/en/panel_preferences_graphics1.xml
index 248cb04e6f..7481e10ed2 100644
--- a/indra/newview/skins/default/xui/en/panel_preferences_graphics1.xml
+++ b/indra/newview/skins/default/xui/en/panel_preferences_graphics1.xml
@@ -210,26 +210,60 @@
increment="8"
initial_value="160"
label="Draw distance:"
- label_width="90"
+ label_width="187"
layout="topleft"
left="30"
min_val="64"
max_val="512"
name="DrawDistance"
top_delta="40"
- width="330" />
+ width="427" />
<text
type="string"
length="1"
follows="left|top"
height="12"
layout="topleft"
- left_delta="330"
+ left_delta="427"
name="DrawDistanceMeterText2"
top_delta="0"
width="128">
m
</text>
+ <slider
+ control_name="IndirectMaxNonImpostors"
+ name="IndirectMaxNonImpostors"
+ decimal_digits="0"
+ increment="1"
+ initial_value="12"
+ show_text="false"
+ min_val="1"
+ max_val="66"
+ label="Maximum number of animated avatars:"
+ follows="left|top"
+ layout="topleft"
+ height="16"
+ label_width="240"
+ left="30"
+ top_delta="40"
+ width="393">
+ <slider.commit_callback
+ function="Pref.UpdateIndirectMaxNonImpostors"
+ parameter="IndirectNonImpostorsText" />
+ </slider>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ top_delta="0"
+ left_delta="397"
+ text_readonly_color="LabelDisabledColor"
+ name="IndirectMaxNonImpostorsText"
+ width="65">
+ 0
+ </text>
<button
height="23"
diff --git a/indra/newview/skins/default/xui/en/panel_region_environment.xml b/indra/newview/skins/default/xui/en/panel_region_environment.xml
index 6d23592948..6531233696 100644
--- a/indra/newview/skins/default/xui/en/panel_region_environment.xml
+++ b/indra/newview/skins/default/xui/en/panel_region_environment.xml
@@ -264,8 +264,7 @@
top_pad="1"
halign="right"
name="txt_alt1">
- Sky [INDEX]
- [ALTITUDE]m
+ Sky [INDEX]&#xA;[ALTITUDE]m
</text>
<line_editor
follows="left|top"
@@ -310,8 +309,7 @@
top_pad="1"
halign="right"
name="txt_alt2">
- Sky [INDEX]
- [ALTITUDE]m
+ Sky [INDEX]&#xA;[ALTITUDE]m
</text>
<line_editor
follows="left|top"
@@ -356,8 +354,7 @@
top_pad="1"
halign="right"
name="txt_alt3">
- Sky [INDEX]
- [ALTITUDE]m
+ Sky [INDEX]&#xA;[ALTITUDE]m
</text>
<line_editor
follows="left|top"