summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDave Houlton <euclid@lindenlab.com>2021-02-02 16:11:44 +0000
committerDave Houlton <euclid@lindenlab.com>2021-02-02 16:11:44 +0000
commitde711c213820521aa8afcf991b4af561db54aede (patch)
tree108e7d0dcb12f6f827d78a0a30b28e33a8cb95f0
parent25186d07acdeb3ba079594f8f0f8677626b1baf6 (diff)
parent7af677ab442b4bb28f009f3715b8913aecd565fa (diff)
Merged in DV528-rebase-6.4.13 (pull request #461)
DRTVWR-528 rebase to 6.4.13
-rw-r--r--autobuild.xml20
-rwxr-xr-xbuild.sh2
-rwxr-xr-xdoc/contributions.txt3
-rw-r--r--indra/llappearance/llavatarappearance.cpp50
-rw-r--r--indra/llappearance/llavatarappearance.h9
-rw-r--r--indra/llappearance/llavatarappearancedefines.cpp18
-rw-r--r--indra/llappearance/llavatarappearancedefines.h15
-rw-r--r--indra/llappearance/lltexlayer.cpp6
-rw-r--r--indra/llappearance/llwearable.cpp4
-rw-r--r--indra/llappearance/llwearabledata.cpp4
-rw-r--r--indra/llcorehttp/_httpoprequest.cpp14
-rw-r--r--indra/llimage/llimage.cpp34
-rw-r--r--indra/llimage/llimage.h32
-rw-r--r--indra/llimage/llimagej2c.cpp4
-rw-r--r--indra/llinventory/llinventory.h2
-rw-r--r--indra/llmath/llvolume.cpp6
-rw-r--r--indra/llmessage/llavatarnamecache.cpp17
-rw-r--r--indra/llmessage/llavatarnamecache.h4
-rw-r--r--indra/llmessage/llproxy.cpp45
-rw-r--r--indra/llmessage/llproxy.h8
-rw-r--r--indra/llplugin/llpluginprocessparent.cpp14
-rw-r--r--indra/llprimitive/lldaeloader.cpp3
-rw-r--r--indra/llrender/llfontregistry.cpp3
-rw-r--r--indra/llrender/llgl.cpp73
-rw-r--r--indra/llrender/llgl.h2
-rw-r--r--indra/llrender/llimagegl.cpp9
-rw-r--r--indra/llrender/llimagegl.h3
-rw-r--r--indra/llrender/llrender2dutils.h1
-rw-r--r--indra/llui/llfloater.cpp10
-rw-r--r--indra/llui/llfolderviewmodel.h2
-rw-r--r--indra/llui/llscrolllistctrl.cpp64
-rw-r--r--indra/llui/llurlentry.cpp39
-rw-r--r--indra/llui/llurlentry.h13
-rw-r--r--indra/llui/llurlregistry.cpp1
-rw-r--r--indra/llui/tests/llurlentry_test.cpp34
-rw-r--r--indra/llwindow/llwindow.h4
-rw-r--r--indra/llwindow/llwindowwin32.cpp41
-rw-r--r--indra/llwindow/llwindowwin32.h3
-rw-r--r--indra/llxml/llcontrol.cpp18
-rw-r--r--indra/llxml/llcontrol.h2
-rw-r--r--indra/newview/VIEWER_VERSION.txt2
-rw-r--r--indra/newview/app_settings/settings.xml24
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/sunDiscF.glsl4
-rw-r--r--indra/newview/app_settings/shaders/class1/windlight/sunDiscF.glsl1
-rw-r--r--indra/newview/app_settings/shaders/class2/windlight/cloudsF.glsl8
-rw-r--r--indra/newview/llagent.cpp24
-rw-r--r--indra/newview/llagent.h2
-rw-r--r--indra/newview/llappearancemgr.cpp4
-rw-r--r--indra/newview/llappearancemgr.h2
-rw-r--r--indra/newview/llappviewer.cpp234
-rw-r--r--indra/newview/llappviewer.h13
-rw-r--r--indra/newview/llcurrencyuimanager.cpp5
-rw-r--r--indra/newview/llcurrencyuimanager.h2
-rw-r--r--indra/newview/lldrawpoolwlsky.cpp13
-rw-r--r--indra/newview/lldrawpoolwlsky.h4
-rw-r--r--indra/newview/llenvironment.cpp13
-rw-r--r--indra/newview/lleventpoll.cpp10
-rw-r--r--indra/newview/llfloateravatartextures.cpp8
-rw-r--r--indra/newview/llfloaterbuycurrency.cpp1
-rw-r--r--indra/newview/llfloaterdeleteprefpreset.cpp13
-rw-r--r--indra/newview/llfloaterimcontainer.cpp26
-rw-r--r--indra/newview/llfloaterimsession.cpp1
-rw-r--r--indra/newview/llfloaterjoystick.cpp148
-rw-r--r--indra/newview/llfloaterjoystick.h9
-rw-r--r--indra/newview/llfloaterloadprefpreset.cpp14
-rw-r--r--indra/newview/llfloatersidepanelcontainer.cpp14
-rw-r--r--indra/newview/llfloatersidepanelcontainer.h2
-rw-r--r--indra/newview/llgiveinventory.cpp13
-rw-r--r--indra/newview/llimview.cpp62
-rw-r--r--indra/newview/llinventorybridge.cpp7
-rw-r--r--indra/newview/llinventorybridge.h2
-rw-r--r--indra/newview/llinventoryfunctions.cpp17
-rw-r--r--indra/newview/llinventorypanel.cpp46
-rw-r--r--indra/newview/llinventorypanel.h21
-rw-r--r--indra/newview/lllocationinputctrl.cpp6
-rw-r--r--indra/newview/lllocationinputctrl.h1
-rw-r--r--indra/newview/lllogininstance.cpp1
-rw-r--r--indra/newview/llmutelist.cpp82
-rw-r--r--indra/newview/llmutelist.h6
-rw-r--r--indra/newview/lloutputmonitorctrl.cpp10
-rw-r--r--indra/newview/lloutputmonitorctrl.h3
-rw-r--r--indra/newview/llpanelgroupnotices.cpp9
-rw-r--r--indra/newview/llpanellogin.cpp4
-rw-r--r--indra/newview/llpanelmaininventory.cpp1
-rw-r--r--indra/newview/llpaneloutfitedit.cpp7
-rw-r--r--indra/newview/llpanelpermissions.cpp38
-rw-r--r--indra/newview/llpreviewscript.cpp8
-rw-r--r--indra/newview/llpreviewscript.h1
-rw-r--r--indra/newview/llpreviewtexture.cpp2
-rw-r--r--indra/newview/llprogressview.cpp3
-rw-r--r--indra/newview/llscenemonitor.cpp19
-rw-r--r--indra/newview/llsidepanelappearance.cpp2
-rw-r--r--indra/newview/llspatialpartition.cpp119
-rw-r--r--indra/newview/lltexturecache.cpp77
-rw-r--r--indra/newview/lltextureview.cpp4
-rw-r--r--indra/newview/llviewerassetupload.cpp11
-rw-r--r--indra/newview/llviewerjoystick.cpp358
-rw-r--r--indra/newview/llviewerjoystick.h10
-rw-r--r--indra/newview/llviewermedia.cpp3
-rw-r--r--indra/newview/llviewermediafocus.cpp9
-rw-r--r--indra/newview/llviewermenu.cpp4
-rw-r--r--indra/newview/llviewermenufile.cpp13
-rw-r--r--indra/newview/llviewermessage.cpp7
-rw-r--r--indra/newview/llviewerregion.cpp18
-rw-r--r--indra/newview/llviewerregion.h2
-rw-r--r--indra/newview/llviewerstats.cpp23
-rw-r--r--indra/newview/llviewerstats.h2
-rw-r--r--indra/newview/llviewertexture.cpp20
-rw-r--r--indra/newview/llviewerwearable.cpp17
-rw-r--r--indra/newview/llviewerwindow.h2
-rw-r--r--indra/newview/llvoavatar.cpp56
-rw-r--r--indra/newview/llvoavatar.h3
-rw-r--r--indra/newview/llvoavatarself.cpp78
-rw-r--r--indra/newview/llvovolume.cpp8
-rw-r--r--indra/newview/llwearableitemslist.cpp58
-rw-r--r--indra/newview/llwearableitemslist.h7
-rw-r--r--indra/newview/llwlhandlers.cpp2
-rw-r--r--indra/newview/pipeline.cpp2
-rw-r--r--indra/newview/skins/default/xui/en/floater_joystick.xml165
-rw-r--r--indra/newview/skins/default/xui/en/menu_wearable_list_item.xml12
-rw-r--r--indra/newview/skins/default/xui/en/notifications.xml4
-rw-r--r--indra/newview/skins/default/xui/en/panel_group_notices.xml3
-rw-r--r--indra/newview/skins/default/xui/en/panel_outfit_edit.xml1
-rw-r--r--indra/newview/skins/default/xui/en/panel_script_ed.xml4
-rwxr-xr-xindra/newview/viewer_manifest.py6
125 files changed, 1973 insertions, 743 deletions
diff --git a/autobuild.xml b/autobuild.xml
index a8203bb643..08233ef403 100644
--- a/autobuild.xml
+++ b/autobuild.xml
@@ -244,9 +244,9 @@
<key>archive</key>
<map>
<key>hash</key>
- <string>322dd6c45c384d454ae14ef127984a4e</string>
+ <string>ae90d19cdcddf539f6d0b41cab12f918</string>
<key>url</key>
- <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/65457/612879/bugsplat-1.0.7.546418-darwin64-546418.tar.bz2</string>
+ <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/72773/702861/bugsplat-1.0.7.552580-darwin64-552580.tar.bz2</string>
</map>
<key>name</key>
<string>darwin64</string>
@@ -256,9 +256,9 @@
<key>archive</key>
<map>
<key>hash</key>
- <string>010a0e73c0fddaa2316411803fad8e69</string>
+ <string>f5936eceb6a33ff0f1cc31996a40f29c</string>
<key>url</key>
- <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/65456/612876/bugsplat-3.6.0.8.546418-windows-546418.tar.bz2</string>
+ <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/72774/702905/bugsplat-3.6.0.8.552580-windows-552580.tar.bz2</string>
</map>
<key>name</key>
<string>windows</string>
@@ -268,16 +268,16 @@
<key>archive</key>
<map>
<key>hash</key>
- <string>7e8530762e7b50663708a888c23b8780</string>
+ <string>9cd940754e53e0670030b3da5ba8f373</string>
<key>url</key>
- <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/65455/612874/bugsplat-3.6.0.8.546418-windows64-546418.tar.bz2</string>
+ <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/72775/702906/bugsplat-3.6.0.8.552580-windows64-552580.tar.bz2</string>
</map>
<key>name</key>
<string>windows64</string>
</map>
</map>
<key>version</key>
- <string>3.6.0.8.546418</string>
+ <string>3.6.0.8.552580</string>
</map>
<key>colladadom</key>
<map>
@@ -2187,18 +2187,18 @@
<key>archive</key>
<map>
<key>hash</key>
- <string>9f4687d7d328b0c13a9e651e805e880a</string>
+ <string>c541838a933e0714a954e9ef6c89345d</string>
<key>hash_algorithm</key>
<string>md5</string>
<key>url</key>
- <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/71501/691487/llca-202011010215.551526-common-551526.tar.bz2</string>
+ <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/73387/708088/llca-202012011600.553112-common-553112.tar.bz2</string>
</map>
<key>name</key>
<string>common</string>
</map>
</map>
<key>version</key>
- <string>202011010215.551526</string>
+ <string>202012011600.553112</string>
</map>
<key>llphysicsextensions_source</key>
<map>
diff --git a/build.sh b/build.sh
index 545c913f92..3b0cf97731 100755
--- a/build.sh
+++ b/build.sh
@@ -480,10 +480,12 @@ then
fi
# Run upload extensions
+ # Ex: bugsplat
if [ -d ${build_dir}/packages/upload-extensions ]; then
for extension in ${build_dir}/packages/upload-extensions/*.sh; do
begin_section "Upload Extension $extension"
. $extension
+ [ $? -eq 0 ] || fatal "Upload of extension $extension failed"
end_section "Upload Extension $extension"
done
fi
diff --git a/doc/contributions.txt b/doc/contributions.txt
index 81c44d2961..f10b4d418c 100755
--- a/doc/contributions.txt
+++ b/doc/contributions.txt
@@ -1355,7 +1355,10 @@ Sovereign Engineer
OPEN-343
SL-11625
SL-14705
+ SL-14706
SL-14707
+ SL-14731
+ SL-14732
SpacedOut Frye
VWR-34
VWR-45
diff --git a/indra/llappearance/llavatarappearance.cpp b/indra/llappearance/llavatarappearance.cpp
index f7fbb6fda1..90dfa04f28 100644
--- a/indra/llappearance/llavatarappearance.cpp
+++ b/indra/llappearance/llavatarappearance.cpp
@@ -171,10 +171,9 @@ LLAvatarAppearance::LLAvatarXmlInfo::~LLAvatarXmlInfo()
//-----------------------------------------------------------------------------
// Static Data
//-----------------------------------------------------------------------------
-LLXmlTree LLAvatarAppearance::sXMLTree;
-LLXmlTree LLAvatarAppearance::sSkeletonXMLTree;
LLAvatarSkeletonInfo* LLAvatarAppearance::sAvatarSkeletonInfo = NULL;
LLAvatarAppearance::LLAvatarXmlInfo* LLAvatarAppearance::sAvatarXmlInfo = NULL;
+LLAvatarAppearanceDefines::LLAvatarAppearanceDictionary* LLAvatarAppearance::sAvatarDictionary = NULL;
LLAvatarAppearance::LLAvatarAppearance(LLWearableData* wearable_data) :
@@ -202,7 +201,7 @@ LLAvatarAppearance::LLAvatarAppearance(LLWearableData* wearable_data) :
mBakedTextureDatas[i].mIsLoaded = false;
mBakedTextureDatas[i].mIsUsed = false;
mBakedTextureDatas[i].mMaskTexName = 0;
- mBakedTextureDatas[i].mTextureIndex = LLAvatarAppearanceDefines::LLAvatarAppearanceDictionary::bakedToLocalTextureIndex((LLAvatarAppearanceDefines::EBakedTextureIndex)i);
+ mBakedTextureDatas[i].mTextureIndex = sAvatarDictionary->bakedToLocalTextureIndex((LLAvatarAppearanceDefines::EBakedTextureIndex)i);
}
}
@@ -215,8 +214,8 @@ void LLAvatarAppearance::initInstance()
mRoot = createAvatarJoint();
mRoot->setName( "mRoot" );
- for (LLAvatarAppearanceDictionary::MeshEntries::const_iterator iter = LLAvatarAppearanceDictionary::getInstance()->getMeshEntries().begin();
- iter != LLAvatarAppearanceDictionary::getInstance()->getMeshEntries().end();
+ for (LLAvatarAppearanceDictionary::MeshEntries::const_iterator iter = sAvatarDictionary->getMeshEntries().begin();
+ iter != sAvatarDictionary->getMeshEntries().end();
++iter)
{
const EMeshIndex mesh_index = iter->first;
@@ -261,8 +260,8 @@ void LLAvatarAppearance::initInstance()
//-------------------------------------------------------------------------
// associate baked textures with meshes
//-------------------------------------------------------------------------
- for (LLAvatarAppearanceDictionary::MeshEntries::const_iterator iter = LLAvatarAppearanceDictionary::getInstance()->getMeshEntries().begin();
- iter != LLAvatarAppearanceDictionary::getInstance()->getMeshEntries().end();
+ for (LLAvatarAppearanceDictionary::MeshEntries::const_iterator iter = sAvatarDictionary->getMeshEntries().begin();
+ iter != sAvatarDictionary->getMeshEntries().end();
++iter)
{
const EMeshIndex mesh_index = iter->first;
@@ -336,6 +335,12 @@ void LLAvatarAppearance::initClass()
//static
void LLAvatarAppearance::initClass(const std::string& avatar_file_name_arg, const std::string& skeleton_file_name_arg)
{
+ // init dictionary (don't repeat on second login attempt)
+ if (!sAvatarDictionary)
+ {
+ sAvatarDictionary = new LLAvatarAppearanceDefines::LLAvatarAppearanceDictionary();
+ }
+
std::string avatar_file_name;
if (!avatar_file_name_arg.empty())
@@ -346,14 +351,15 @@ void LLAvatarAppearance::initClass(const std::string& avatar_file_name_arg, cons
{
avatar_file_name = gDirUtilp->getExpandedFilename(LL_PATH_CHARACTER,AVATAR_DEFAULT_CHAR + "_lad.xml");
}
- BOOL success = sXMLTree.parseFile( avatar_file_name, FALSE );
+ LLXmlTree xml_tree;
+ BOOL success = xml_tree.parseFile( avatar_file_name, FALSE );
if (!success)
{
LL_ERRS() << "Problem reading avatar configuration file:" << avatar_file_name << LL_ENDL;
}
// now sanity check xml file
- LLXmlTreeNode* root = sXMLTree.getRoot();
+ LLXmlTreeNode* root = xml_tree.getRoot();
if (!root)
{
LL_ERRS() << "No root node found in avatar configuration file: " << avatar_file_name << LL_ENDL;
@@ -400,8 +406,9 @@ void LLAvatarAppearance::initClass(const std::string& avatar_file_name_arg, cons
}
std::string skeleton_path;
+ LLXmlTree skeleton_xml_tree;
skeleton_path = gDirUtilp->getExpandedFilename(LL_PATH_CHARACTER,skeleton_file_name);
- if (!parseSkeletonFile(skeleton_path))
+ if (!parseSkeletonFile(skeleton_path, skeleton_xml_tree))
{
LL_ERRS() << "Error parsing skeleton file: " << skeleton_path << LL_ENDL;
}
@@ -414,7 +421,7 @@ void LLAvatarAppearance::initClass(const std::string& avatar_file_name_arg, cons
delete sAvatarSkeletonInfo;
}
sAvatarSkeletonInfo = new LLAvatarSkeletonInfo;
- if (!sAvatarSkeletonInfo->parseXml(sSkeletonXMLTree.getRoot()))
+ if (!sAvatarSkeletonInfo->parseXml(skeleton_xml_tree.getRoot()))
{
LL_ERRS() << "Error parsing skeleton XML file: " << skeleton_path << LL_ENDL;
}
@@ -453,9 +460,8 @@ void LLAvatarAppearance::initClass(const std::string& avatar_file_name_arg, cons
void LLAvatarAppearance::cleanupClass()
{
delete_and_clear(sAvatarXmlInfo);
- // *TODO: What about sAvatarSkeletonInfo ???
- sSkeletonXMLTree.cleanup();
- sXMLTree.cleanup();
+ delete_and_clear(sAvatarDictionary);
+ delete_and_clear(sAvatarSkeletonInfo);
}
using namespace LLAvatarAppearanceDefines;
@@ -577,12 +583,12 @@ void LLAvatarAppearance::computeBodySize()
//-----------------------------------------------------------------------------
// parseSkeletonFile()
//-----------------------------------------------------------------------------
-BOOL LLAvatarAppearance::parseSkeletonFile(const std::string& filename)
+BOOL LLAvatarAppearance::parseSkeletonFile(const std::string& filename, LLXmlTree& skeleton_xml_tree)
{
//-------------------------------------------------------------------------
// parse the file
//-------------------------------------------------------------------------
- BOOL parsesuccess = sSkeletonXMLTree.parseFile( filename, FALSE );
+ BOOL parsesuccess = skeleton_xml_tree.parseFile( filename, FALSE );
if (!parsesuccess)
{
@@ -591,7 +597,7 @@ BOOL LLAvatarAppearance::parseSkeletonFile(const std::string& filename)
}
// now sanity check xml file
- LLXmlTreeNode* root = sSkeletonXMLTree.getRoot();
+ LLXmlTreeNode* root = skeleton_xml_tree.getRoot();
if (!root)
{
LL_ERRS() << "No root node found in avatar skeleton file: " << filename << LL_ENDL;
@@ -999,7 +1005,7 @@ BOOL LLAvatarAppearance::loadAvatar()
{
LLAvatarXmlInfo::LLAvatarMorphInfo *info = *iter;
- EBakedTextureIndex baked = LLAvatarAppearanceDictionary::findBakedByRegionName(info->mRegion);
+ EBakedTextureIndex baked = sAvatarDictionary->findBakedByRegionName(info->mRegion);
if (baked != BAKED_NUM_INDICES)
{
LLVisualParam* morph_param;
@@ -1135,8 +1141,8 @@ BOOL LLAvatarAppearance::loadMeshNodes()
switch(lod)
case 0:
mesh = &mHairMesh0; */
- for (LLAvatarAppearanceDictionary::MeshEntries::const_iterator mesh_iter = LLAvatarAppearanceDictionary::getInstance()->getMeshEntries().begin();
- mesh_iter != LLAvatarAppearanceDictionary::getInstance()->getMeshEntries().end();
+ for (LLAvatarAppearanceDictionary::MeshEntries::const_iterator mesh_iter = sAvatarDictionary->getMeshEntries().begin();
+ mesh_iter != sAvatarDictionary->getMeshEntries().end();
++mesh_iter)
{
const EMeshIndex mesh_index = mesh_iter->first;
@@ -1264,8 +1270,8 @@ BOOL LLAvatarAppearance::loadLayersets()
// scan baked textures and associate the layerset with the appropriate one
EBakedTextureIndex baked_index = BAKED_NUM_INDICES;
- for (LLAvatarAppearanceDictionary::BakedTextures::const_iterator baked_iter = LLAvatarAppearanceDictionary::getInstance()->getBakedTextures().begin();
- baked_iter != LLAvatarAppearanceDictionary::getInstance()->getBakedTextures().end();
+ for (LLAvatarAppearanceDictionary::BakedTextures::const_iterator baked_iter = sAvatarDictionary->getBakedTextures().begin();
+ baked_iter != sAvatarDictionary->getBakedTextures().end();
++baked_iter)
{
const LLAvatarAppearanceDictionary::BakedEntry *baked_dict = baked_iter->second;
diff --git a/indra/llappearance/llavatarappearance.h b/indra/llappearance/llavatarappearance.h
index 6a4dbf3726..b1c70f9064 100644
--- a/indra/llappearance/llavatarappearance.h
+++ b/indra/llappearance/llavatarappearance.h
@@ -156,7 +156,7 @@ public:
protected:
- static BOOL parseSkeletonFile(const std::string& filename);
+ static BOOL parseSkeletonFile(const std::string& filename, LLXmlTree& skeleton_xml_tree);
virtual void buildCharacter();
virtual BOOL loadAvatar();
@@ -211,9 +211,6 @@ public:
// XML parse tree
//--------------------------------------------------------------------
protected:
- static LLXmlTree sXMLTree; // avatar config file
- static LLXmlTree sSkeletonXMLTree; // avatar skeleton file
-
static LLAvatarSkeletonInfo* sAvatarSkeletonInfo;
static LLAvatarXmlInfo* sAvatarXmlInfo;
@@ -255,6 +252,7 @@ public:
public:
virtual void updateMeshTextures() = 0;
virtual void dirtyMesh() = 0; // Dirty the avatar mesh
+ static const LLAvatarAppearanceDefines::LLAvatarAppearanceDictionary *getDictionary() { return sAvatarDictionary; }
protected:
virtual void dirtyMesh(S32 priority) = 0; // Dirty the avatar mesh, with priority
@@ -263,6 +261,9 @@ protected:
polymesh_map_t mPolyMeshes;
avatar_joint_list_t mMeshLOD;
+ // mesh entries and backed textures
+ static LLAvatarAppearanceDefines::LLAvatarAppearanceDictionary* sAvatarDictionary;
+
/** Meshes
** **
*******************************************************************************/
diff --git a/indra/llappearance/llavatarappearancedefines.cpp b/indra/llappearance/llavatarappearancedefines.cpp
index c72943bb82..9398ce3822 100644
--- a/indra/llappearance/llavatarappearancedefines.cpp
+++ b/indra/llappearance/llavatarappearancedefines.cpp
@@ -258,19 +258,17 @@ LLAvatarAppearanceDictionary::BakedEntry::BakedEntry(ETextureIndex tex_index,
}
}
-// static
-ETextureIndex LLAvatarAppearanceDictionary::bakedToLocalTextureIndex(EBakedTextureIndex index)
+ETextureIndex LLAvatarAppearanceDictionary::bakedToLocalTextureIndex(EBakedTextureIndex index) const
{
- return LLAvatarAppearanceDictionary::getInstance()->getBakedTexture(index)->mTextureIndex;
+ return getBakedTexture(index)->mTextureIndex;
}
-// static
EBakedTextureIndex LLAvatarAppearanceDictionary::findBakedByRegionName(std::string name)
{
U8 index = 0;
while (index < BAKED_NUM_INDICES)
{
- const BakedEntry *be = LLAvatarAppearanceDictionary::getInstance()->getBakedTexture((EBakedTextureIndex) index);
+ const BakedEntry *be = getBakedTexture((EBakedTextureIndex) index);
if (be && be->mName.compare(name) == 0)
{
// baked texture found
@@ -282,16 +280,15 @@ EBakedTextureIndex LLAvatarAppearanceDictionary::findBakedByRegionName(std::stri
return BAKED_NUM_INDICES;
}
-// static
EBakedTextureIndex LLAvatarAppearanceDictionary::findBakedByImageName(std::string name)
{
U8 index = 0;
while (index < BAKED_NUM_INDICES)
{
- const BakedEntry *be = LLAvatarAppearanceDictionary::getInstance()->getBakedTexture((EBakedTextureIndex) index);
+ const BakedEntry *be = getBakedTexture((EBakedTextureIndex) index);
if (be)
{
- const TextureEntry *te = LLAvatarAppearanceDictionary::getInstance()->getTexture(be->mTextureIndex);
+ const TextureEntry *te = getTexture(be->mTextureIndex);
if (te && te->mDefaultImageName.compare(name) == 0)
{
// baked texture found
@@ -304,10 +301,9 @@ EBakedTextureIndex LLAvatarAppearanceDictionary::findBakedByImageName(std::strin
return BAKED_NUM_INDICES;
}
-// static
-LLWearableType::EType LLAvatarAppearanceDictionary::getTEWearableType(ETextureIndex index )
+LLWearableType::EType LLAvatarAppearanceDictionary::getTEWearableType(ETextureIndex index ) const
{
- return getInstance()->getTexture(index)->mWearableType;
+ return getTexture(index)->mWearableType;
}
// static
diff --git a/indra/llappearance/llavatarappearancedefines.h b/indra/llappearance/llavatarappearancedefines.h
index 5663d24293..8968187531 100644
--- a/indra/llappearance/llavatarappearancedefines.h
+++ b/indra/llappearance/llavatarappearancedefines.h
@@ -143,13 +143,14 @@ typedef std::vector<LLWearableType::EType> wearables_vec_t;
//
// This holds const data - it is initialized once and the contents never change after that.
//------------------------------------------------------------------------
-class LLAvatarAppearanceDictionary : public LLSingleton<LLAvatarAppearanceDictionary>
+class LLAvatarAppearanceDictionary
{
//--------------------------------------------------------------------
// Constructors and Destructors
//--------------------------------------------------------------------
- LLSINGLETON(LLAvatarAppearanceDictionary);
- virtual ~LLAvatarAppearanceDictionary();
+public:
+ LLAvatarAppearanceDictionary();
+ ~LLAvatarAppearanceDictionary();
private:
void createAssociations();
@@ -235,14 +236,14 @@ public:
//--------------------------------------------------------------------
public:
// Convert from baked texture to associated texture; e.g. BAKED_HEAD -> TEX_HEAD_BAKED
- static ETextureIndex bakedToLocalTextureIndex(EBakedTextureIndex t);
+ ETextureIndex bakedToLocalTextureIndex(EBakedTextureIndex t) const;
// find a baked texture index based on its name
- static EBakedTextureIndex findBakedByRegionName(std::string name);
- static EBakedTextureIndex findBakedByImageName(std::string name);
+ EBakedTextureIndex findBakedByRegionName(std::string name);
+ EBakedTextureIndex findBakedByImageName(std::string name);
// Given a texture entry, determine which wearable type owns it.
- static LLWearableType::EType getTEWearableType(ETextureIndex index);
+ LLWearableType::EType getTEWearableType(ETextureIndex index) const;
static BOOL isBakedImageId(const LLUUID& id);
static EBakedTextureIndex assetIdToBakedTextureIndex(const LLUUID& id);
diff --git a/indra/llappearance/lltexlayer.cpp b/indra/llappearance/lltexlayer.cpp
index c90b11ae71..e5039141de 100644
--- a/indra/llappearance/lltexlayer.cpp
+++ b/indra/llappearance/lltexlayer.cpp
@@ -728,8 +728,8 @@ BOOL LLTexLayerInfo::parseXml(LLXmlTreeNode* node)
/* if ("upper_shirt" == local_texture_name)
mLocalTexture = TEX_UPPER_SHIRT; */
mLocalTexture = TEX_NUM_INDICES;
- for (LLAvatarAppearanceDictionary::Textures::const_iterator iter = LLAvatarAppearanceDictionary::getInstance()->getTextures().begin();
- iter != LLAvatarAppearanceDictionary::getInstance()->getTextures().end();
+ for (LLAvatarAppearanceDictionary::Textures::const_iterator iter = LLAvatarAppearance::getDictionary()->getTextures().begin();
+ iter != LLAvatarAppearance::getDictionary()->getTextures().end();
iter++)
{
const LLAvatarAppearanceDictionary::TextureEntry *texture_dict = iter->second;
@@ -979,7 +979,7 @@ LLWearableType::EType LLTexLayerInterface::getWearableType() const
return type;
}
- return LLAvatarAppearanceDictionary::getTEWearableType(te);
+ return LLAvatarAppearance::getDictionary()->getTEWearableType(te);
}
LLTexLayerInterface::ERenderPass LLTexLayerInterface::getRenderPass() const
diff --git a/indra/llappearance/llwearable.cpp b/indra/llappearance/llwearable.cpp
index 6079913a8e..28a36e6e41 100644
--- a/indra/llappearance/llwearable.cpp
+++ b/indra/llappearance/llwearable.cpp
@@ -183,7 +183,7 @@ void LLWearable::createVisualParams(LLAvatarAppearance *avatarp)
void LLWearable::createLayers(S32 te, LLAvatarAppearance *avatarp)
{
LLTexLayerSet *layer_set = NULL;
- const LLAvatarAppearanceDictionary::TextureEntry *texture_dict = LLAvatarAppearanceDictionary::getInstance()->getTexture((ETextureIndex)te);
+ const LLAvatarAppearanceDictionary::TextureEntry *texture_dict = LLAvatarAppearance::getDictionary()->getTexture((ETextureIndex)te);
if (texture_dict && texture_dict->mIsUsedByBakedTexture)
{
const EBakedTextureIndex baked_index = texture_dict->mBakedTextureIndex;
@@ -606,7 +606,7 @@ void LLWearable::syncImages(te_map_t &src, te_map_t &dst)
// Deep copy of src (copies only those tes that are current, filling in defaults where needed)
for( S32 te = 0; te < TEX_NUM_INDICES; te++ )
{
- if (LLAvatarAppearanceDictionary::getTEWearableType((ETextureIndex) te) == mType)
+ if (LLAvatarAppearance::getDictionary()->getTEWearableType((ETextureIndex) te) == mType)
{
te_map_t::const_iterator iter = src.find(te);
LLUUID image_id;
diff --git a/indra/llappearance/llwearabledata.cpp b/indra/llappearance/llwearabledata.cpp
index 2bf3b9085b..66cc4f3766 100644
--- a/indra/llappearance/llwearabledata.cpp
+++ b/indra/llappearance/llwearabledata.cpp
@@ -339,7 +339,7 @@ U32 LLWearableData::getWearableCount(const LLWearableType::EType type) const
U32 LLWearableData::getWearableCount(const U32 tex_index) const
{
- const LLWearableType::EType wearable_type = LLAvatarAppearanceDictionary::getTEWearableType((LLAvatarAppearanceDefines::ETextureIndex)tex_index);
+ const LLWearableType::EType wearable_type = LLAvatarAppearance::getDictionary()->getTEWearableType((LLAvatarAppearanceDefines::ETextureIndex)tex_index);
return getWearableCount(wearable_type);
}
@@ -349,7 +349,7 @@ LLUUID LLWearableData::computeBakedTextureHash(LLAvatarAppearanceDefines::EBaked
LLUUID hash_id;
bool hash_computed = false;
LLMD5 hash;
- const LLAvatarAppearanceDictionary::BakedEntry *baked_dict = LLAvatarAppearanceDictionary::getInstance()->getBakedTexture(baked_index);
+ const LLAvatarAppearanceDictionary::BakedEntry *baked_dict = LLAvatarAppearance::getDictionary()->getBakedTexture(baked_index);
for (U8 i=0; i < baked_dict->mWearables.size(); i++)
{
diff --git a/indra/llcorehttp/_httpoprequest.cpp b/indra/llcorehttp/_httpoprequest.cpp
index 7bea8e9f9c..ba31290c24 100644
--- a/indra/llcorehttp/_httpoprequest.cpp
+++ b/indra/llcorehttp/_httpoprequest.cpp
@@ -567,16 +567,9 @@ HttpStatus HttpOpRequest::prepareRequest(HttpService * service)
// Use the viewer-based thread-safe API which has a
// fast/safe check for proxy enable. Would like to
// encapsulate this someway...
- if (LLProxy::instanceExists())
- {
- // Make sure proxy won't be initialized from here,
- // it might conflict with LLStartUp::startLLProxy()
- LLProxy::getInstance()->applyProxySettings(mCurlHandle);
- }
- else
- {
- LL_WARNS() << "Proxy is not initialized!" << LL_ENDL;
- }
+ // Make sure proxy won't be getInstance() from here,
+ // it is not thread safe
+ LLProxy::applyProxySettings(mCurlHandle);
}
else if (gpolicy.mHttpProxy.size())
@@ -817,6 +810,7 @@ size_t HttpOpRequest::readCallback(void * data, size_t size, size_t nmemb, void
const size_t do_size((std::min)(req_size, body_size - op->mCurlBodyPos));
const size_t read_size(op->mReqBody->read(op->mCurlBodyPos, static_cast<char *>(data), do_size));
+ // FIXME: singleton's instance() is Thread unsafe! Even if stats accumulators inside are.
HTTPStats::instance().recordDataUp(read_size);
op->mCurlBodyPos += read_size;
return read_size;
diff --git a/indra/llimage/llimage.cpp b/indra/llimage/llimage.cpp
index 7a0c8cd8f5..aed8943439 100644
--- a/indra/llimage/llimage.cpp
+++ b/indra/llimage/llimage.cpp
@@ -583,29 +583,39 @@ static void bilinear_scale(const U8 *src, U32 srcW, U32 srcH, U32 srcCh, U32 src
// LLImage
//---------------------------------------------------------------------------
-LLImage::LLImage(bool use_new_byte_range, S32 minimal_reverse_byte_range_percent)
+//static
+std::string LLImage::sLastErrorMessage;
+LLMutex* LLImage::sMutex = NULL;
+bool LLImage::sUseNewByteRange = false;
+S32 LLImage::sMinimalReverseByteRangePercent = 75;
+
+//static
+void LLImage::initClass(bool use_new_byte_range, S32 minimal_reverse_byte_range_percent)
{
- mMutex = new LLMutex();
- mUseNewByteRange = use_new_byte_range;
- mMinimalReverseByteRangePercent = minimal_reverse_byte_range_percent;
+ sUseNewByteRange = use_new_byte_range;
+ sMinimalReverseByteRangePercent = minimal_reverse_byte_range_percent;
+ sMutex = new LLMutex();
}
-LLImage::~LLImage()
+//static
+void LLImage::cleanupClass()
{
- delete mMutex;
- mMutex = NULL;
+ delete sMutex;
+ sMutex = NULL;
}
-const std::string& LLImage::getLastErrorMessage()
+//static
+const std::string& LLImage::getLastError()
{
static const std::string noerr("No Error");
- return mLastErrorMessage.empty() ? noerr : mLastErrorMessage;
+ return sLastErrorMessage.empty() ? noerr : sLastErrorMessage;
}
-void LLImage::setLastErrorMessage(const std::string& message)
+//static
+void LLImage::setLastError(const std::string& message)
{
- LLMutexLock m(mMutex);
- mLastErrorMessage = message;
+ LLMutexLock m(sMutex);
+ sLastErrorMessage = message;
}
//---------------------------------------------------------------------------
diff --git a/indra/llimage/llimage.h b/indra/llimage/llimage.h
index 9f8d061293..f66b1666d7 100644
--- a/indra/llimage/llimage.h
+++ b/indra/llimage/llimage.h
@@ -30,7 +30,6 @@
#include "lluuid.h"
#include "llstring.h"
#include "llpointer.h"
-#include "llsingleton.h"
#include "lltrace.h"
const S32 MIN_IMAGE_MIP = 2; // 4x4, only used for expand/contract power of 2
@@ -88,26 +87,25 @@ typedef enum e_image_codec
//============================================================================
// library initialization class
+// LLImage is frequently used in threads so do not convert it to LLSingleton
-class LLImage : public LLParamSingleton<LLImage>
+class LLImage
{
- LLSINGLETON(LLImage, bool use_new_byte_range = false, S32 minimal_reverse_byte_range_percent = 75);
- ~LLImage();
public:
+ static void initClass(bool use_new_byte_range = false, S32 minimal_reverse_byte_range_percent = 75);
+ static void cleanupClass();
- const std::string& getLastErrorMessage();
- static const std::string& getLastError() { return getInstance()->getLastErrorMessage(); };
- void setLastErrorMessage(const std::string& message);
- static void setLastError(const std::string& message) { getInstance()->setLastErrorMessage(message); }
-
- bool useNewByteRange() { return mUseNewByteRange; }
- S32 getReverseByteRangePercent() { return mMinimalReverseByteRangePercent; }
-
-private:
- LLMutex* mMutex;
- std::string mLastErrorMessage;
- bool mUseNewByteRange;
- S32 mMinimalReverseByteRangePercent;
+ static const std::string& getLastError();
+ static void setLastError(const std::string& message);
+
+ static bool useNewByteRange() { return sUseNewByteRange; }
+ static S32 getReverseByteRangePercent() { return sMinimalReverseByteRangePercent; }
+
+protected:
+ static LLMutex* sMutex;
+ static std::string sLastErrorMessage;
+ static bool sUseNewByteRange;
+ static S32 sMinimalReverseByteRangePercent;
};
//============================================================================
diff --git a/indra/llimage/llimagej2c.cpp b/indra/llimage/llimagej2c.cpp
index 71cab0554d..4bff21610f 100644
--- a/indra/llimage/llimagej2c.cpp
+++ b/indra/llimage/llimagej2c.cpp
@@ -281,7 +281,7 @@ S32 LLImageJ2C::calcDataSizeJ2C(S32 w, S32 h, S32 comp, S32 discard_level, F32 r
S32 bytes;
S32 new_bytes = (S32) (sqrt((F32)(w*h))*(F32)(comp)*rate*1000.f/layer_factor);
S32 old_bytes = (S32)((F32)(w*h*comp)*rate);
- bytes = (LLImage::getInstance()->useNewByteRange() && (new_bytes < old_bytes) ? new_bytes : old_bytes);
+ bytes = (LLImage::useNewByteRange() && (new_bytes < old_bytes) ? new_bytes : old_bytes);
bytes = llmax(bytes, calcHeaderSizeJ2C());
return bytes;
}
@@ -322,7 +322,7 @@ S32 LLImageJ2C::calcDiscardLevelBytes(S32 bytes)
{
S32 bytes_needed = calcDataSize(discard_level);
// Use TextureReverseByteRange percent (see settings.xml) of the optimal size to qualify as correct rendering for the given discard level
- if (bytes >= (bytes_needed*LLImage::getInstance()->getReverseByteRangePercent()/100))
+ if (bytes >= (bytes_needed*LLImage::getReverseByteRangePercent()/100))
{
break;
}
diff --git a/indra/llinventory/llinventory.h b/indra/llinventory/llinventory.h
index 024afc109c..0f336a072f 100644
--- a/indra/llinventory/llinventory.h
+++ b/indra/llinventory/llinventory.h
@@ -244,7 +244,7 @@ public:
LLInventoryCategory(const LLInventoryCategory* other);
void copyCategory(const LLInventoryCategory* other); // LLRefCount requires custom copy
protected:
- ~LLInventoryCategory();
+ virtual ~LLInventoryCategory();
//--------------------------------------------------------------------
// Accessors And Mutators
diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp
index 7da53bf8c8..e085fa6ada 100644
--- a/indra/llmath/llvolume.cpp
+++ b/indra/llmath/llvolume.cpp
@@ -5241,9 +5241,9 @@ public:
LLVCacheTriangleData* tri = *iter;
if (tri->mActive)
{
- tri->mScore = tri->mVertex[0]->mScore;
- tri->mScore += tri->mVertex[1]->mScore;
- tri->mScore += tri->mVertex[2]->mScore;
+ tri->mScore = tri->mVertex[0] ? tri->mVertex[0]->mScore : 0;
+ tri->mScore += tri->mVertex[1] ? tri->mVertex[1]->mScore : 0;
+ tri->mScore += tri->mVertex[2] ? tri->mVertex[2]->mScore : 0;
if (!mBestTriangle || mBestTriangle->mScore < tri->mScore)
{
diff --git a/indra/llmessage/llavatarnamecache.cpp b/indra/llmessage/llavatarnamecache.cpp
index fbd65cc67b..7380df041d 100644
--- a/indra/llmessage/llavatarnamecache.cpp
+++ b/indra/llmessage/llavatarnamecache.cpp
@@ -285,12 +285,27 @@ void LLAvatarNameCache::processName(const LLUUID& agent_id, const LLAvatarName&
return;
}
+ bool updated_account = true; // assume obsolete value for new arrivals by default
+
+ std::map<LLUUID, LLAvatarName>::iterator it = mCache.find(agent_id);
+ if (it != mCache.end()
+ && (*it).second.getAccountName() == av_name.getAccountName())
+ {
+ updated_account = false;
+ }
+
// Add to the cache
mCache[agent_id] = av_name;
// Suppress request from the queue
mPendingQueue.erase(agent_id);
+ // notify mute list about changes
+ if (updated_account && mAccountNameChangedCallback)
+ {
+ mAccountNameChangedCallback(agent_id, av_name);
+ }
+
// Signal everyone waiting on this name
signal_map_t::iterator sig_it = mSignalMap.find(agent_id);
if (sig_it != mSignalMap.end())
@@ -303,6 +318,8 @@ void LLAvatarNameCache::processName(const LLUUID& agent_id, const LLAvatarName&
delete signal;
signal = NULL;
}
+
+
}
void LLAvatarNameCache::requestNamesViaCapability()
diff --git a/indra/llmessage/llavatarnamecache.h b/indra/llmessage/llavatarnamecache.h
index ba89d569f3..549d1703fa 100644
--- a/indra/llmessage/llavatarnamecache.h
+++ b/indra/llmessage/llavatarnamecache.h
@@ -42,6 +42,7 @@ class LLAvatarNameCache : public LLSingleton<LLAvatarNameCache>
~LLAvatarNameCache();
public:
typedef boost::signals2::signal<void (void)> use_display_name_signal_t;
+ typedef boost::function<void (const LLUUID id, const LLAvatarName& av_name)> account_name_changed_callback_t;
// Import/export the name cache to file.
bool importFile(std::istream& istr);
@@ -103,6 +104,8 @@ public:
void addUseDisplayNamesCallback(const use_display_name_signal_t::slot_type& cb);
+ void setAccountNameChangedCallback(const account_name_changed_callback_t& cb) { mAccountNameChangedCallback = cb; }
+
private:
// Handle name response off network.
void processName(const LLUUID& agent_id,
@@ -141,6 +144,7 @@ private:
private:
use_display_name_signal_t mUseDisplayNamesSignal;
+ account_name_changed_callback_t mAccountNameChangedCallback;
// Cache starts in a paused state until we can determine if the
// current region supports display names.
diff --git a/indra/llmessage/llproxy.cpp b/indra/llmessage/llproxy.cpp
index 86bcfe6881..749e599c66 100644
--- a/indra/llmessage/llproxy.cpp
+++ b/indra/llmessage/llproxy.cpp
@@ -40,6 +40,7 @@
// incoming packet just to do a simple bool test. The getter for this
// member is also static
bool LLProxy::sUDPProxyEnabled = false;
+LLProxy* LLProxy::sProxyInstance = NULL;
// Some helpful TCP static functions.
static apr_status_t tcp_blocking_handshake(LLSocket::ptr_t handle, char * dataout, apr_size_t outlen, char * datain, apr_size_t maxinlen); // Do a TCP data handshake
@@ -60,11 +61,21 @@ LLProxy::LLProxy():
LLProxy::~LLProxy()
{
- if (ll_apr_is_initialized())
- {
- stopSOCKSProxy();
- disableHTTPProxy();
- }
+ if (ll_apr_is_initialized())
+ {
+ // locks mutex
+ stopSOCKSProxy();
+ disableHTTPProxy();
+ }
+ // The primary safety of sProxyInstance is the fact that by the
+ // point SUBSYSTEM_CLEANUP(LLProxy) gets called, nothing should
+ // be capable of using proxy
+ sProxyInstance = NULL;
+}
+
+void LLProxy::initSingleton()
+{
+ sProxyInstance = this;
}
/**
@@ -424,28 +435,28 @@ void LLProxy::cleanupClass()
void LLProxy::applyProxySettings(CURL* handle)
{
// Do a faster unlocked check to see if we are supposed to proxy.
- if (mHTTPProxyEnabled)
+ if (sProxyInstance && sProxyInstance->mHTTPProxyEnabled)
{
- // We think we should proxy, lock the proxy mutex.
- LLMutexLock lock(&mProxyMutex);
+ // We think we should proxy, lock the proxy mutex. sProxyInstance is not protected by mutex
+ LLMutexLock lock(&sProxyInstance->mProxyMutex);
// Now test again to verify that the proxy wasn't disabled between the first check and the lock.
- if (mHTTPProxyEnabled)
+ if (sProxyInstance->mHTTPProxyEnabled)
{
- LLCore::LLHttp::check_curl_code(curl_easy_setopt(handle, CURLOPT_PROXY, mHTTPProxy.getIPString().c_str()), CURLOPT_PROXY);
- LLCore::LLHttp::check_curl_code(curl_easy_setopt(handle, CURLOPT_PROXYPORT, mHTTPProxy.getPort()), CURLOPT_PROXYPORT);
+ LLCore::LLHttp::check_curl_code(curl_easy_setopt(handle, CURLOPT_PROXY, sProxyInstance->mHTTPProxy.getIPString().c_str()), CURLOPT_PROXY);
+ LLCore::LLHttp::check_curl_code(curl_easy_setopt(handle, CURLOPT_PROXYPORT, sProxyInstance->mHTTPProxy.getPort()), CURLOPT_PROXYPORT);
- if (mProxyType == LLPROXY_SOCKS)
+ if (sProxyInstance->mProxyType == LLPROXY_SOCKS)
{
- LLCore::LLHttp::check_curl_code(curl_easy_setopt(handle, CURLOPT_PROXYTYPE, CURLPROXY_SOCKS5), CURLOPT_PROXYTYPE);
- if (mAuthMethodSelected == METHOD_PASSWORD)
+ LLCore::LLHttp::check_curl_code(curl_easy_setopt(handle, CURLOPT_PROXYTYPE, CURLPROXY_SOCKS5), CURLOPT_PROXYTYPE);
+ if (sProxyInstance->mAuthMethodSelected == METHOD_PASSWORD)
{
- std::string auth_string = mSocksUsername + ":" + mSocksPassword;
- LLCore::LLHttp::check_curl_code(curl_easy_setopt(handle, CURLOPT_PROXYUSERPWD, auth_string.c_str()), CURLOPT_PROXYUSERPWD);
+ std::string auth_string = sProxyInstance->mSocksUsername + ":" + sProxyInstance->mSocksPassword;
+ LLCore::LLHttp::check_curl_code(curl_easy_setopt(handle, CURLOPT_PROXYUSERPWD, auth_string.c_str()), CURLOPT_PROXYUSERPWD);
}
}
else
{
- LLCore::LLHttp::check_curl_code(curl_easy_setopt(handle, CURLOPT_PROXYTYPE, CURLPROXY_HTTP), CURLOPT_PROXYTYPE);
+ LLCore::LLHttp::check_curl_code(curl_easy_setopt(handle, CURLOPT_PROXYTYPE, CURLPROXY_HTTP), CURLOPT_PROXYTYPE);
}
}
}
diff --git a/indra/llmessage/llproxy.h b/indra/llmessage/llproxy.h
index a1ffa9e5d5..25f6977e14 100644
--- a/indra/llmessage/llproxy.h
+++ b/indra/llmessage/llproxy.h
@@ -226,6 +226,8 @@ class LLProxy: public LLSingleton<LLProxy>
LLSINGLETON(LLProxy);
LOG_CLASS(LLProxy);
+ /*virtual*/ void initSingleton();
+
public:
// Static check for enabled status for UDP packets. Call from main thread only.
static bool isSOCKSProxyEnabled() { return sUDPProxyEnabled; }
@@ -251,7 +253,7 @@ public:
// Apply the current proxy settings to a curl request. Doesn't do anything if mHTTPProxyEnabled is false.
// Safe to call from any thread.
- void applyProxySettings(CURL* handle);
+ static void applyProxySettings(CURL* handle);
// Start a connection to the SOCKS 5 proxy. Call from main thread only.
S32 startSOCKSProxy(LLHost host);
@@ -344,6 +346,10 @@ private:
/*###########################################################################################
END OF SHARED MEMBERS
###########################################################################################*/
+
+ // A hack to get arround getInstance() and capture_dependency() which are unsafe to use inside threads
+ // set/reset on init/cleanup, strictly for use in applyProxySettings
+ static LLProxy* sProxyInstance;
};
#endif
diff --git a/indra/llplugin/llpluginprocessparent.cpp b/indra/llplugin/llpluginprocessparent.cpp
index eb6cb1b503..7d18bae947 100644
--- a/indra/llplugin/llpluginprocessparent.cpp
+++ b/indra/llplugin/llpluginprocessparent.cpp
@@ -152,8 +152,18 @@ void LLPluginProcessParent::shutdown()
mapInstances_t::iterator it;
for (it = sInstances.begin(); it != sInstances.end(); ++it)
{
- (*it).second->setState(STATE_GOODBYE);
- (*it).second->idle();
+ EState state = (*it).second->mState;
+ if (state != STATE_CLEANUP
+ || state != STATE_EXITING
+ || state != STATE_DONE
+ || state != STATE_ERROR)
+ {
+ (*it).second->setState(STATE_GOODBYE);
+ }
+ if (state != STATE_DONE)
+ {
+ (*it).second->idle();
+ }
}
sInstances.clear();
}
diff --git a/indra/llprimitive/lldaeloader.cpp b/indra/llprimitive/lldaeloader.cpp
index d2aa3d8dc6..dfa29fb539 100644
--- a/indra/llprimitive/lldaeloader.cpp
+++ b/indra/llprimitive/lldaeloader.cpp
@@ -1472,7 +1472,8 @@ void LLDAELoader::processDomModel(LLModel* model, DAE* dae, daeElement* root, do
std::string lookingForJoint = (*jointIt).c_str();
//Look for the joint xform that we extracted from the skeleton, using the jointIt as the key
//and store it in the alternate bind matrix
- if ( mJointMap.find( lookingForJoint ) != mJointMap.end() )
+ if (mJointMap.find(lookingForJoint) != mJointMap.end()
+ && model->mSkinInfo.mInvBindMatrix.size() > i)
{
LLMatrix4 newInverse = model->mSkinInfo.mInvBindMatrix[i];
newInverse.setTranslation( mJointList[lookingForJoint].getTranslation() );
diff --git a/indra/llrender/llfontregistry.cpp b/indra/llrender/llfontregistry.cpp
index dbe71e2882..33a33af160 100644
--- a/indra/llrender/llfontregistry.cpp
+++ b/indra/llrender/llfontregistry.cpp
@@ -45,6 +45,7 @@ bool font_desc_init_from_xml(LLXMLNodePtr node, LLFontDescriptor& desc);
bool init_from_xml(LLFontRegistry* registry, LLXMLNodePtr node);
const std::string MACOSX_FONT_PATH_LIBRARY = "/Library/Fonts/";
+const std::string MACOSX_FONT_SUPPLEMENTAL = "Supplemental/";
LLFontDescriptor::LLFontDescriptor():
mStyle(0)
@@ -473,6 +474,8 @@ LLFontGL *LLFontRegistry::createFont(const LLFontDescriptor& desc)
font_paths.push_back(sys_path + *file_name_it);
#if LL_DARWIN
font_paths.push_back(MACOSX_FONT_PATH_LIBRARY + *file_name_it);
+ font_paths.push_back(MACOSX_FONT_PATH_LIBRARY + MACOSX_FONT_SUPPLEMENTAL + *file_name_it);
+ font_paths.push_back(sys_path + MACOSX_FONT_SUPPLEMENTAL + *file_name_it);
#endif
bool is_ft_collection = (std::find(ft_collection_list.begin(), ft_collection_list.end(), *file_name_it) != ft_collection_list.end());
diff --git a/indra/llrender/llgl.cpp b/indra/llrender/llgl.cpp
index 8d22f7b68b..43fedeca64 100644
--- a/indra/llrender/llgl.cpp
+++ b/indra/llrender/llgl.cpp
@@ -948,6 +948,79 @@ std::string LLGLManager::getRawGLString()
return gl_string;
}
+void LLGLManager::asLLSD(LLSD& info)
+{
+ // Currently these are duplicates of fields in "system".
+ info["gpu_vendor"] = mGLVendorShort;
+ info["gpu_version"] = mDriverVersionVendorString;
+ info["opengl_version"] = mGLVersionString;
+
+ info["vram"] = mVRAM;
+
+ // Extensions used by everyone
+ info["has_multitexture"] = mHasMultitexture;
+ info["has_ati_mem_info"] = mHasATIMemInfo;
+ info["has_nvx_mem_info"] = mHasNVXMemInfo;
+ info["num_texture_units"] = mNumTextureUnits;
+ info["has_mip_map_generation"] = mHasMipMapGeneration;
+ info["has_compressed_textures"] = mHasCompressedTextures;
+ info["has_framebuffer_object"] = mHasFramebufferObject;
+ info["max_samples"] = mMaxSamples;
+ info["has_blend_func_separate"] = mHasBlendFuncSeparate;
+
+ // ARB Extensions
+ info["has_vertex_buffer_object"] = mHasVertexBufferObject;
+ info["has_vertex_array_object"] = mHasVertexArrayObject;
+ info["has_sync"] = mHasSync;
+ info["has_map_buffer_range"] = mHasMapBufferRange;
+ info["has_flush_buffer_range"] = mHasFlushBufferRange;
+ info["has_pbuffer"] = mHasPBuffer;
+ info["has_shader_objects"] = mHasShaderObjects;
+ info["has_vertex_shader"] = mHasVertexShader;
+ info["has_fragment_shader"] = mHasFragmentShader;
+ info["num_texture_image_units"] = mNumTextureImageUnits;
+ info["has_occlusion_query"] = mHasOcclusionQuery;
+ info["has_timer_query"] = mHasTimerQuery;
+ info["has_occlusion_query2"] = mHasOcclusionQuery2;
+ info["has_point_parameters"] = mHasPointParameters;
+ info["has_draw_buffers"] = mHasDrawBuffers;
+ info["has_depth_clamp"] = mHasDepthClamp;
+ info["has_texture_rectangle"] = mHasTextureRectangle;
+ info["has_texture_multisample"] = mHasTextureMultisample;
+ info["has_transform_feedback"] = mHasTransformFeedback;
+ info["max_sample_mask_words"] = mMaxSampleMaskWords;
+ info["max_color_texture_samples"] = mMaxColorTextureSamples;
+ info["max_depth_texture_samples"] = mMaxDepthTextureSamples;
+ info["max_integer_samples"] = mMaxIntegerSamples;
+
+ // Other extensions.
+ info["has_anisotropic"] = mHasAnisotropic;
+ info["has_arb_env_combine"] = mHasARBEnvCombine;
+ info["has_cube_map"] = mHasCubeMap;
+ info["has_debug_output"] = mHasDebugOutput;
+ info["has_srgb_texture"] = mHassRGBTexture;
+ info["has_srgb_framebuffer"] = mHassRGBFramebuffer;
+ info["has_texture_srgb_decode"] = mHasTexturesRGBDecode;
+
+ // Vendor-specific extensions
+ info["is_ati"] = mIsATI;
+ info["is_nvidia"] = mIsNVIDIA;
+ info["is_intel"] = mIsIntel;
+ info["is_gf2or4mx"] = mIsGF2or4MX;
+ info["is_gf3"] = mIsGF3;
+ info["is_gf_gfx"] = mIsGFFX;
+ info["ati_offset_vertical_lines"] = mATIOffsetVerticalLines;
+ info["ati_old_driver"] = mATIOldDriver;
+
+ // Other fields
+ info["has_requirements"] = mHasRequirements;
+ info["has_separate_specular_color"] = mHasSeparateSpecularColor;
+ info["max_vertex_range"] = mGLMaxVertexRange;
+ info["max_index_range"] = mGLMaxIndexRange;
+ info["max_texture_size"] = mGLMaxTextureSize;
+ info["gl_renderer"] = mGLRenderer;
+}
+
void LLGLManager::shutdownGL()
{
if (mInited)
diff --git a/indra/llrender/llgl.h b/indra/llrender/llgl.h
index 3d597a23fe..a07e2d9bb0 100644
--- a/indra/llrender/llgl.h
+++ b/indra/llrender/llgl.h
@@ -162,6 +162,8 @@ public:
void printGLInfoString();
void getGLInfo(LLSD& info);
+ void asLLSD(LLSD& info);
+
// In ALL CAPS
std::string mGLVendor;
std::string mGLVendorShort;
diff --git a/indra/llrender/llimagegl.cpp b/indra/llrender/llimagegl.cpp
index 3b6a49735e..0151d20128 100644
--- a/indra/llrender/llimagegl.cpp
+++ b/indra/llrender/llimagegl.cpp
@@ -1386,6 +1386,15 @@ BOOL LLImageGL::createGLTexture(S32 discard_level, const LLImageRaw* imageraw, S
return FALSE;
}
+ if (mHasExplicitFormat &&
+ ((mFormatPrimary == GL_RGBA && mComponents < 4) ||
+ (mFormatPrimary == GL_RGB && mComponents < 3)))
+
+ {
+ LL_WARNS() << "Incorrect format: " << std::hex << mFormatPrimary << " components: " << (U32)mComponents << LL_ENDL;
+ mHasExplicitFormat = FALSE;
+ }
+
if( !mHasExplicitFormat )
{
switch (mComponents)
diff --git a/indra/llrender/llimagegl.h b/indra/llrender/llimagegl.h
index 4f3d7eed0a..61ddc8d59b 100644
--- a/indra/llrender/llimagegl.h
+++ b/indra/llrender/llimagegl.h
@@ -133,6 +133,7 @@ public:
S32 getMipBytes(S32 discard_level = -1) const;
BOOL getBoundRecently() const;
BOOL isJustBound() const;
+ BOOL getHasExplicitFormat() const { return mHasExplicitFormat; }
LLGLenum getPrimaryFormat() const { return mFormatPrimary; }
LLGLenum getFormatType() const { return mFormatType; }
@@ -197,7 +198,7 @@ private:
U16 mPickMaskWidth;
U16 mPickMaskHeight;
S8 mUseMipMaps;
- S8 mHasExplicitFormat; // If false (default), GL format is f(mComponents)
+ BOOL mHasExplicitFormat; // If false (default), GL format is f(mComponents)
S8 mAutoGenMips;
BOOL mIsMask;
diff --git a/indra/llrender/llrender2dutils.h b/indra/llrender/llrender2dutils.h
index 70ab006fd6..8c01784071 100644
--- a/indra/llrender/llrender2dutils.h
+++ b/indra/llrender/llrender2dutils.h
@@ -32,6 +32,7 @@
#include "llpointer.h" // LLPointer<>
#include "llrect.h"
+#include "llsingleton.h"
#include "llglslshader.h"
class LLColor4;
diff --git a/indra/llui/llfloater.cpp b/indra/llui/llfloater.cpp
index abb043f428..e9c980ad9a 100644
--- a/indra/llui/llfloater.cpp
+++ b/indra/llui/llfloater.cpp
@@ -303,12 +303,10 @@ void LLFloater::initFloater(const Params& p)
mButtonsEnabled[BUTTON_CLOSE] = TRUE;
}
- // Help button: '?'
- if ( !mHelpTopic.empty() )
- {
- mButtonsEnabled[BUTTON_HELP] = TRUE;
- }
-
+ // Help button: '?'
+ //SL-14050 Disable all Help question marks
+ mButtonsEnabled[BUTTON_HELP] = FALSE;
+
// Minimize button only for top draggers
if ( !mDragOnLeft && mCanMinimize )
{
diff --git a/indra/llui/llfolderviewmodel.h b/indra/llui/llfolderviewmodel.h
index 84a1539094..f4ddfa8f18 100644
--- a/indra/llui/llfolderviewmodel.h
+++ b/indra/llui/llfolderviewmodel.h
@@ -285,7 +285,7 @@ public:
typedef std::list<LLFolderViewModelItem*> child_list_t;
virtual void addChild(LLFolderViewModelItem* child)
- {
+ {
mChildren.push_back(child);
child->setParent(this);
dirtyFilter();
diff --git a/indra/llui/llscrolllistctrl.cpp b/indra/llui/llscrolllistctrl.cpp
index 367c6c3c5b..a6e4f3a2af 100644
--- a/indra/llui/llscrolllistctrl.cpp
+++ b/indra/llui/llscrolllistctrl.cpp
@@ -763,14 +763,20 @@ void LLScrollListCtrl::updateColumns(bool force_update)
}
}
+ bool header_changed_width = false;
// expand last column header we encountered to full list width
if (last_header)
{
+ S32 old_width = last_header->getColumn()->getWidth();
S32 new_width = llmax(0, mItemListRect.mRight - last_header->getRect().mLeft);
last_header->reshape(new_width, last_header->getRect().getHeight());
last_header->setVisible(mDisplayColumnHeaders && new_width > 0);
- last_header->getColumn()->setWidth(new_width);
- }
+ if (old_width != new_width)
+ {
+ last_header->getColumn()->setWidth(new_width);
+ header_changed_width = true;
+ }
+ }
// propagate column widths to individual cells
if (columns_changed_width || force_update)
@@ -789,6 +795,20 @@ void LLScrollListCtrl::updateColumns(bool force_update)
}
}
}
+ else if (header_changed_width)
+ {
+ item_list::iterator iter;
+ S32 index = last_header->getColumn()->mIndex; // Not always identical to last column!
+ for (iter = mItemList.begin(); iter != mItemList.end(); iter++)
+ {
+ LLScrollListItem *itemp = *iter;
+ LLScrollListCell* cell = itemp->getColumn(index);
+ if (cell)
+ {
+ cell->setWidth(last_header->getColumn()->getWidth());
+ }
+ }
+ }
}
void LLScrollListCtrl::setHeadingHeight(S32 heading_height)
@@ -1381,18 +1401,34 @@ BOOL LLScrollListCtrl::setSelectedByValue(const LLSD& value, BOOL selected)
for (iter = mItemList.begin(); iter != mItemList.end(); iter++)
{
LLScrollListItem* item = *iter;
- if (item->getEnabled() && (item->getValue().asString() == value.asString()))
- {
- if (selected)
- {
- selectItem(item);
- }
- else
- {
- deselectItem(item);
- }
- found = TRUE;
- break;
+ if (item->getEnabled())
+ {
+ if (value.isBinary())
+ {
+ if (item->getValue().isBinary())
+ {
+ LLSD::Binary data1 = value.asBinary();
+ LLSD::Binary data2 = item->getValue().asBinary();
+ found = std::equal(data1.begin(), data1.end(), data2.begin()) ? TRUE : FALSE;
+ }
+ }
+ else
+ {
+ found = item->getValue().asString() == value.asString() ? TRUE : FALSE;
+ }
+
+ if (found)
+ {
+ if (selected)
+ {
+ selectItem(item);
+ }
+ else
+ {
+ deselectItem(item);
+ }
+ break;
+ }
}
}
diff --git a/indra/llui/llurlentry.cpp b/indra/llui/llurlentry.cpp
index e6835f73fb..a69c0eb008 100644
--- a/indra/llui/llurlentry.cpp
+++ b/indra/llui/llurlentry.cpp
@@ -1481,4 +1481,43 @@ void LLUrlEntryExperienceProfile::onExperienceDetails( const LLSD& experience_de
callObservers(experience_details[LLExperienceCache::EXPERIENCE_ID].asString(), name, LLStringUtil::null);
}
+//
+// LLUrlEntryEmail Describes an IPv6 address
+//
+LLUrlEntryIPv6::LLUrlEntryIPv6()
+ : LLUrlEntryBase()
+{
+ mHostPath = "https?://\\[([a-f0-9:]+:+)+[a-f0-9]+]";
+ mPattern = boost::regex(mHostPath + "(:\\d{1,5})?(/\\S*)?",
+ boost::regex::perl | boost::regex::icase);
+ mMenuName = "menu_url_http.xml";
+ mTooltip = LLTrans::getString("TooltipHttpUrl");
+}
+std::string LLUrlEntryIPv6::getLabel(const std::string &url, const LLUrlLabelCallback &cb)
+{
+ boost::regex regex = boost::regex(mHostPath, boost::regex::perl | boost::regex::icase);
+ boost::match_results<std::string::const_iterator> matches;
+
+ if (boost::regex_search(url, matches, regex))
+ {
+ return url.substr(0, matches[0].length());
+ }
+ else
+ {
+ return url;
+ }
+}
+
+std::string LLUrlEntryIPv6::getQuery(const std::string &url) const
+{
+ boost::regex regex = boost::regex(mHostPath, boost::regex::perl | boost::regex::icase);
+ boost::match_results<std::string::const_iterator> matches;
+
+ return boost::regex_replace(url, regex, "");
+}
+
+std::string LLUrlEntryIPv6::getUrl(const std::string &string) const
+{
+ return string;
+}
diff --git a/indra/llui/llurlentry.h b/indra/llui/llurlentry.h
index 78c149d9fd..0a0c247a6a 100644
--- a/indra/llui/llurlentry.h
+++ b/indra/llui/llurlentry.h
@@ -513,5 +513,18 @@ public:
/*virtual*/ std::string getUrl(const std::string &string) const;
};
+///
+/// LLUrlEntryEmail Describes an IPv6 address
+///
+class LLUrlEntryIPv6 : public LLUrlEntryBase
+{
+public:
+ LLUrlEntryIPv6();
+ /*virtual*/ std::string getLabel(const std::string &url, const LLUrlLabelCallback &cb);
+ /*virtual*/ std::string getUrl(const std::string &string) const;
+ /*virtual*/ std::string getQuery(const std::string &url) const;
+
+ std::string mHostPath;
+};
#endif
diff --git a/indra/llui/llurlregistry.cpp b/indra/llui/llurlregistry.cpp
index ba6fa1e2e9..321a0ec5b9 100644
--- a/indra/llui/llurlregistry.cpp
+++ b/indra/llui/llurlregistry.cpp
@@ -79,6 +79,7 @@ LLUrlRegistry::LLUrlRegistry()
mUrlEntrySLLabel = new LLUrlEntrySLLabel();
registerUrl(mUrlEntrySLLabel);
registerUrl(new LLUrlEntryEmail());
+ registerUrl(new LLUrlEntryIPv6());
}
LLUrlRegistry::~LLUrlRegistry()
diff --git a/indra/llui/tests/llurlentry_test.cpp b/indra/llui/tests/llurlentry_test.cpp
index 3c34fd269e..4a4fdb72e3 100644
--- a/indra/llui/tests/llurlentry_test.cpp
+++ b/indra/llui/tests/llurlentry_test.cpp
@@ -903,4 +903,38 @@ namespace tut
"and even no www something lindenlab.com",
"");
}
+
+ template<> template<>
+ void object::test<16>()
+ {
+ //
+ // test LLUrlEntryIPv6
+ //
+ LLUrlEntryIPv6 url;
+
+ // Regex tests.
+ testRegex("match urls with a protocol", url,
+ "this url should match http://[::1]",
+ "http://[::1]");
+
+ testRegex("match urls with a protocol and query", url,
+ "this url should match http://[::1]/file.mp3",
+ "http://[::1]/file.mp3");
+
+ testRegex("match urls with a protocol", url,
+ "this url should match http://[2001:0db8:11a3:09d7:1f34:8a2e:07a0:765d]",
+ "http://[2001:0db8:11a3:09d7:1f34:8a2e:07a0:765d]");
+
+ testRegex("match urls with port", url,
+ "let's specify some port http://[2001:0db8:11a3:09d7:1f34:8a2e:07a0:765d]:8080",
+ "http://[2001:0db8:11a3:09d7:1f34:8a2e:07a0:765d]:8080");
+
+ testRegex("don't match urls w/o protocol", url,
+ "looks like an url something [2001:0db8:11a3:09d7:1f34:8a2e:07a0:765d] but no https prefix",
+ "");
+
+ testRegex("don't match incorrect urls", url,
+ "http://[ 2001:0db8:11a3:09d7:1f34:8a2e:07a0:765d ]",
+ "");
+ }
}
diff --git a/indra/llwindow/llwindow.h b/indra/llwindow/llwindow.h
index a05ba8cbba..f1113acd5f 100644
--- a/indra/llwindow/llwindow.h
+++ b/indra/llwindow/llwindow.h
@@ -168,6 +168,10 @@ public:
// Get system UI size based on DPI (for 96 DPI UI size should be 1.0)
virtual F32 getSystemUISize() { return 1.0; }
+
+ // windows only DirectInput8 for joysticks
+ virtual void* getDirectInput8() { return NULL; };
+ virtual bool getInputDevices(U32 device_type_filter, void * devices_callback, void* userdata) { return false; };
protected:
LLWindow(LLWindowCallbacks* callbacks, BOOL fullscreen, U32 flags);
virtual ~LLWindow();
diff --git a/indra/llwindow/llwindowwin32.cpp b/indra/llwindow/llwindowwin32.cpp
index afe0c2cc6a..702b592139 100644
--- a/indra/llwindow/llwindowwin32.cpp
+++ b/indra/llwindow/llwindowwin32.cpp
@@ -59,6 +59,9 @@
#include <dinput.h>
#include <Dbt.h.>
+#include <InitGuid.h> // needed for llurlentry test to build on some systems
+#pragma comment(lib, "dxguid.lib") // needed for llurlentry test to build on some systems
+#pragma comment(lib, "dinput8")
const S32 MAX_MESSAGE_PER_UPDATE = 20;
const S32 BITS_PER_PIXEL = 32;
@@ -76,6 +79,7 @@ const F32 ICON_FLASH_TIME = 0.5f;
extern BOOL gDebugWindowProc;
LPWSTR gIconResource = IDI_APPLICATION;
+LPDIRECTINPUT8 gDirectInput8;
LLW32MsgCallback gAsyncMsgCallback = NULL;
@@ -483,6 +487,21 @@ LLWindowWin32::LLWindowWin32(LLWindowCallbacks* callbacks,
mhInstance = GetModuleHandle(NULL);
mWndProc = NULL;
+ // Init Direct Input - needed for joystick / Spacemouse
+
+ LPDIRECTINPUT8 di8_interface;
+ HRESULT status = DirectInput8Create(
+ mhInstance, // HINSTANCE hinst,
+ DIRECTINPUT_VERSION, // DWORD dwVersion,
+ IID_IDirectInput8, // REFIID riidltf,
+ (LPVOID*)&di8_interface, // LPVOID * ppvOut,
+ NULL // LPUNKNOWN punkOuter
+ );
+ if (status == DI_OK)
+ {
+ gDirectInput8 = di8_interface;
+ }
+
mSwapMethod = SWAP_METHOD_UNDEFINED;
// No WPARAM yet.
@@ -4236,6 +4255,28 @@ void LLWindowWin32::setDPIAwareness()
}
}
+void* LLWindowWin32::getDirectInput8()
+{
+ return &gDirectInput8;
+}
+
+bool LLWindowWin32::getInputDevices(U32 device_type_filter, void * di8_devices_callback, void* userdata)
+{
+ if (gDirectInput8 != NULL)
+ {
+ // Enumerate devices
+ HRESULT status = gDirectInput8->EnumDevices(
+ (DWORD) device_type_filter, // DWORD dwDevType,
+ (LPDIENUMDEVICESCALLBACK)di8_devices_callback, // LPDIENUMDEVICESCALLBACK lpCallback, // BOOL DIEnumDevicesCallback( LPCDIDEVICEINSTANCE lpddi, LPVOID pvRef ) // BOOL CALLBACK DinputDevice::DevicesCallback
+ (LPVOID*)userdata, // LPVOID pvRef
+ DIEDFL_ATTACHEDONLY // DWORD dwFlags
+ );
+
+ return status == DI_OK;
+ }
+ return false;
+}
+
F32 LLWindowWin32::getSystemUISize()
{
F32 scale_value = 1.f;
diff --git a/indra/llwindow/llwindowwin32.h b/indra/llwindow/llwindowwin32.h
index 9cd16eb993..ee0df570e9 100644
--- a/indra/llwindow/llwindowwin32.h
+++ b/indra/llwindow/llwindowwin32.h
@@ -116,6 +116,9 @@ public:
static std::vector<std::string> getDynamicFallbackFontList();
static void setDPIAwareness();
+
+ /*virtual*/ void* getDirectInput8();
+ /*virtual*/ bool getInputDevices(U32 device_type_filter, void * di8_devices_callback, void* userdata);
protected:
LLWindowWin32(LLWindowCallbacks* callbacks,
const std::string& title, const std::string& name, int x, int y, int width, int height, U32 flags,
diff --git a/indra/llxml/llcontrol.cpp b/indra/llxml/llcontrol.cpp
index 80a414d00f..ead8634df4 100644
--- a/indra/llxml/llcontrol.cpp
+++ b/indra/llxml/llcontrol.cpp
@@ -641,6 +641,24 @@ LLSD LLControlGroup::getLLSD(const std::string& name)
return get<LLSD>(name);
}
+LLSD LLControlGroup::asLLSD(bool diffs_only)
+{
+ // Dump all stored values as LLSD
+ LLSD result = LLSD::emptyArray();
+ for (ctrl_name_table_t::iterator iter = mNameTable.begin();
+ iter != mNameTable.end(); iter++)
+ {
+ LLControlVariable *control = iter->second;
+ if (!control || control->isType(TYPE_STRING) || (diffs_only && control->isDefault()))
+ {
+ continue;
+ }
+ const std::string& name = iter->first;
+ result[name] = getLLSD(name);
+ }
+ return result;
+}
+
BOOL LLControlGroup::controlExists(const std::string& name)
{
ctrl_name_table_t::iterator iter = mNameTable.find(name);
diff --git a/indra/llxml/llcontrol.h b/indra/llxml/llcontrol.h
index 99946607f4..19508becc3 100644
--- a/indra/llxml/llcontrol.h
+++ b/indra/llxml/llcontrol.h
@@ -242,6 +242,8 @@ public:
LLColor4 getColor4(const std::string& name);
LLColor3 getColor3(const std::string& name);
+ LLSD asLLSD(bool diffs_only);
+
// generic getter
template<typename T> T get(const std::string& name)
{
diff --git a/indra/newview/VIEWER_VERSION.txt b/indra/newview/VIEWER_VERSION.txt
index d613169e88..0438a6cd91 100644
--- a/indra/newview/VIEWER_VERSION.txt
+++ b/indra/newview/VIEWER_VERSION.txt
@@ -1 +1 @@
-6.4.12
+6.4.13
diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index 0b9cc78132..e7ec4f1f9a 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -812,6 +812,17 @@
<key>Value</key>
<integer>0</integer>
</map>
+ <key>FramePerSecondLimit</key>
+ <map>
+ <key>Comment</key>
+ <string>Controls upper limit of frames per second</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>U32</string>
+ <key>Value</key>
+ <integer>120</integer>
+ </map>
<key>BackgroundYieldTime</key>
<map>
<key>Comment</key>
@@ -5231,6 +5242,17 @@
<key>Value</key>
<string />
</map>
+ <key>JoystickDeviceUUID</key>
+ <map>
+ <key>Comment</key>
+ <string>Preffered device ID.</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>String</string>
+ <key>Value</key>
+ <string />
+ </map>
<key>JoystickMouselookYaw</key>
<map>
<key>Comment</key>
@@ -9091,7 +9113,7 @@
<key>Type</key>
<string>F32</string>
<key>Value</key>
- <real>0.03</real>
+ <real>0.1</real>
</map>
<key>RenderDebugPipeline</key>
<map>
diff --git a/indra/newview/app_settings/shaders/class1/deferred/sunDiscF.glsl b/indra/newview/app_settings/shaders/class1/deferred/sunDiscF.glsl
index 454af2a9bc..b2fa5d8a25 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/sunDiscF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/sunDiscF.glsl
@@ -49,10 +49,6 @@ void main()
vec4 sunDiscB = texture2D(altDiffuseMap, vary_texcoord0.xy);
vec4 c = mix(sunDiscA, sunDiscB, blend_factor);
- c.rgb = srgb_to_linear(c.rgb);
- c.rgb = clamp(c.rgb, vec3(0), vec3(1));
- c.rgb = pow(c.rgb, vec3(0.7f));
-
//c.rgb = fullbrightAtmosTransport(c.rgb);
c.rgb = fullbrightScaleSoftClip(c.rgb);
diff --git a/indra/newview/app_settings/shaders/class1/windlight/sunDiscF.glsl b/indra/newview/app_settings/shaders/class1/windlight/sunDiscF.glsl
index b9ae7a0226..5a41dc644a 100644
--- a/indra/newview/app_settings/shaders/class1/windlight/sunDiscF.glsl
+++ b/indra/newview/app_settings/shaders/class1/windlight/sunDiscF.glsl
@@ -51,7 +51,6 @@ void main()
// SL-9806 stars poke through
// c.a *= sun_fade;
- c.rgb = pow(c.rgb, vec3(0.7f));
c.rgb = fullbrightAtmosTransport(c.rgb);
c.rgb = fullbrightScaleSoftClip(c.rgb);
frag_color = c;
diff --git a/indra/newview/app_settings/shaders/class2/windlight/cloudsF.glsl b/indra/newview/app_settings/shaders/class2/windlight/cloudsF.glsl
index 75bf8730df..fa928d993e 100644
--- a/indra/newview/app_settings/shaders/class2/windlight/cloudsF.glsl
+++ b/indra/newview/app_settings/shaders/class2/windlight/cloudsF.glsl
@@ -26,9 +26,9 @@
/*[EXTRA_CODE_HERE]*/
#ifdef DEFINE_GL_FRAGCOLOR
-out vec4 frag_data[3];
+out vec4 frag_color;
#else
-#define frag_data gl_FragData
+#define frag_color gl_FragColor
#endif
/////////////////////////////////////////////////////////////////////////
@@ -126,8 +126,6 @@ void main()
color.rgb = scaleSoftClip(color.rgb);
/// Gamma correct for WL (soft clip effect).
- frag_data[0] = vec4(color.rgb, alpha1);
- frag_data[1] = vec4(0.0,0.0,0.0,0.0);
- frag_data[2] = vec4(0,0,0,1);
+ frag_color = vec4(color.rgb, alpha1);
}
diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp
index e7e9404ded..c65bc0fa50 100644
--- a/indra/newview/llagent.cpp
+++ b/indra/newview/llagent.cpp
@@ -877,6 +877,18 @@ boost::signals2::connection LLAgent::addParcelChangedCallback(parcel_changed_cal
return mParcelChangedSignal.connect(cb);
}
+// static
+void LLAgent::capabilityReceivedCallback(const LLUUID &region_id)
+{
+ LLViewerRegion* region = gAgent.getRegion();
+ if (region && region->getRegionID() == region_id)
+ {
+ region->requestSimulatorFeatures();
+ LLAppViewer::instance()->updateNameLookupUrl();
+ }
+}
+
+
//-----------------------------------------------------------------------------
// setRegion()
//-----------------------------------------------------------------------------
@@ -923,10 +935,11 @@ void LLAgent::setRegion(LLViewerRegion *regionp)
if (regionp->capabilitiesReceived())
{
regionp->requestSimulatorFeatures();
+ LLAppViewer::instance()->updateNameLookupUrl();
}
else
{
- regionp->setCapabilitiesReceivedCallback(boost::bind(&LLViewerRegion::requestSimulatorFeatures, regionp));
+ regionp->setCapabilitiesReceivedCallback(LLAgent::capabilityReceivedCallback);
}
}
@@ -945,6 +958,15 @@ void LLAgent::setRegion(LLViewerRegion *regionp)
// Update all of the regions.
LLWorld::getInstance()->updateAgentOffset(mAgentOriginGlobal);
+
+ if (regionp->capabilitiesReceived())
+ {
+ LLAppViewer::instance()->updateNameLookupUrl();
+ }
+ else
+ {
+ regionp->setCapabilitiesReceivedCallback([](const LLUUID &region_id) {LLAppViewer::instance()->updateNameLookupUrl(); });
+ }
}
// Pass new region along to metrics components that care about this level of detail.
diff --git a/indra/newview/llagent.h b/indra/newview/llagent.h
index f72378f654..d46c99db8c 100644
--- a/indra/newview/llagent.h
+++ b/indra/newview/llagent.h
@@ -254,6 +254,8 @@ public:
boost::signals2::connection addParcelChangedCallback(parcel_changed_callback_t);
private:
+ static void capabilityReceivedCallback(const LLUUID &region_id);
+
typedef boost::signals2::signal<void()> parcel_changed_signal_t;
parcel_changed_signal_t mParcelChangedSignal;
diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp
index e5c505501e..e8a3305645 100644
--- a/indra/newview/llappearancemgr.cpp
+++ b/indra/newview/llappearancemgr.cpp
@@ -1957,7 +1957,7 @@ bool LLAppearanceMgr::getCanReplaceCOF(const LLUUID& outfit_cat_id)
}
// Moved from LLWearableList::ContextMenu for wider utility.
-bool LLAppearanceMgr::canAddWearables(const uuid_vec_t& item_ids)
+bool LLAppearanceMgr::canAddWearables(const uuid_vec_t& item_ids) const
{
// TODO: investigate wearables may not be loaded at this point EXT-8231
@@ -1967,7 +1967,7 @@ bool LLAppearanceMgr::canAddWearables(const uuid_vec_t& item_ids)
// Count given clothes (by wearable type) and objects.
for (uuid_vec_t::const_iterator it = item_ids.begin(); it != item_ids.end(); ++it)
{
- LLViewerInventoryItem* item = gInventory.getItem(*it);
+ const LLViewerInventoryItem* item = gInventory.getItem(*it);
if (!item)
{
return false;
diff --git a/indra/newview/llappearancemgr.h b/indra/newview/llappearancemgr.h
index c274a8b049..8a55a848db 100644
--- a/indra/newview/llappearancemgr.h
+++ b/indra/newview/llappearancemgr.h
@@ -101,7 +101,7 @@ public:
bool getCanReplaceCOF(const LLUUID& outfit_cat_id);
// Can we add all referenced items to the avatar?
- bool canAddWearables(const uuid_vec_t& item_ids);
+ bool canAddWearables(const uuid_vec_t& item_ids) const;
// Copy all items in a category.
void shallowCopyCategoryContents(const LLUUID& src_id, const LLUUID& dst_id,
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index 4e6200e8af..297925d0f0 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -287,7 +287,7 @@ extern BOOL gHiDPISupport;
////////////////////////////////////////////////////////////
// All from the last globals push...
-F32 gSimLastTime; // Used in LLAppViewer::init and send_stats()
+F32 gSimLastTime; // Used in LLAppViewer::init and send_viewer_stats()
F32 gSimFrames;
BOOL gShowObjectUpdates = FALSE;
@@ -680,6 +680,7 @@ LLAppViewer::LLAppViewer()
mPurgeCacheOnExit(false),
mPurgeUserDataOnExit(false),
mSecondInstance(false),
+ mUpdaterNotFound(false),
mSavedFinalSnapshot(false),
mSavePerAccountSettings(false), // don't save settings on logout unless login succeeded.
mQuitRequested(false),
@@ -692,7 +693,8 @@ LLAppViewer::LLAppViewer()
mPeriodicSlowFrame(LLCachedControl<bool>(gSavedSettings,"Periodic Slow Frame", FALSE)),
mFastTimerLogThread(NULL),
mSettingsLocationList(NULL),
- mIsFirstRun(false)
+ mIsFirstRun(false),
+ mMinMicroSecPerFrame(0.f)
{
if(NULL != sInstance)
{
@@ -1163,7 +1165,7 @@ bool LLAppViewer::init()
gGLActive = FALSE;
-#if LL_RELEASE_FOR_DOWNLOAD
+#if LL_RELEASE_FOR_DOWNLOAD
if (!gSavedSettings.getBOOL("CmdLineSkipUpdater"))
{
LLProcess::Params updater;
@@ -1171,14 +1173,18 @@ bool LLAppViewer::init()
// Because it's the updater, it MUST persist beyond the lifespan of the
// viewer itself.
updater.autokill = false;
+ std::string updater_file;
#if LL_WINDOWS
- updater.executable = gDirUtilp->getExpandedFilename(LL_PATH_EXECUTABLE, "SLVersionChecker.exe");
+ updater_file = "SLVersionChecker.exe";
+ updater.executable = gDirUtilp->getExpandedFilename(LL_PATH_EXECUTABLE, updater_file);
#elif LL_DARWIN
// explicitly run the system Python interpreter on SLVersionChecker.py
updater.executable = "python";
- updater.args.add(gDirUtilp->add(gDirUtilp->getAppRODataDir(), "updater", "SLVersionChecker.py"));
+ updater_file = "SLVersionChecker.py";
+ updater.args.add(gDirUtilp->add(gDirUtilp->getAppRODataDir(), "updater", updater_file));
#else
- updater.executable = gDirUtilp->getExpandedFilename(LL_PATH_EXECUTABLE, "SLVersionChecker");
+ updater_file = "SLVersionChecker";
+ updater.executable = gDirUtilp->getExpandedFilename(LL_PATH_EXECUTABLE, updater_file);
#endif
// add LEAP mode command-line argument to whichever of these we selected
updater.args.add("leap");
@@ -1191,37 +1197,58 @@ bool LLAppViewer::init()
// ForceAddressSize
updater.args.add(stringize(gSavedSettings.getU32("ForceAddressSize")));
- // Run the updater. An exception from launching the updater should bother us.
- LLLeap::create(updater, true);
+ try
+ {
+ // Run the updater. An exception from launching the updater should bother us.
+ LLLeap::create(updater, true);
+ mUpdaterNotFound = false;
+ }
+ catch (...)
+ {
+ LLUIString details = LLNotifications::instance().getGlobalString("LLLeapUpdaterFailure");
+ details.setArg("[UPDATER_APP]", updater_file);
+ OSMessageBox(
+ details.getString(),
+ LLStringUtil::null,
+ OSMB_OK);
+ mUpdaterNotFound = true;
+ }
}
else
{
LL_WARNS("InitInfo") << "Skipping updater check." << LL_ENDL;
}
- // Iterate over --leap command-line options. But this is a bit tricky: if
- // there's only one, it won't be an array at all.
- LLSD LeapCommand(gSavedSettings.getLLSD("LeapCommand"));
- LL_DEBUGS("InitInfo") << "LeapCommand: " << LeapCommand << LL_ENDL;
- if (LeapCommand.isDefined() && ! LeapCommand.isArray())
- {
- // If LeapCommand is actually a scalar value, make an array of it.
- // Have to do it in two steps because LeapCommand.append(LeapCommand)
- // trashes content! :-P
- LLSD item(LeapCommand);
- LeapCommand.append(item);
- }
- BOOST_FOREACH(const std::string& leap, llsd::inArray(LeapCommand))
- {
- LL_INFOS("InitInfo") << "processing --leap \"" << leap << '"' << LL_ENDL;
- // We don't have any better description of this plugin than the
- // user-specified command line. Passing "" causes LLLeap to derive a
- // description from the command line itself.
- // Suppress LLLeap::Error exception: trust LLLeap's own logging. We
- // don't consider any one --leap command mission-critical, so if one
- // fails, log it, shrug and carry on.
- LLLeap::create("", leap, false); // exception=false
- }
+ if (mUpdaterNotFound)
+ {
+ LL_WARNS("InitInfo") << "Failed to launch updater. Skipping Leap commands." << LL_ENDL;
+ }
+ else
+ {
+ // Iterate over --leap command-line options. But this is a bit tricky: if
+ // there's only one, it won't be an array at all.
+ LLSD LeapCommand(gSavedSettings.getLLSD("LeapCommand"));
+ LL_DEBUGS("InitInfo") << "LeapCommand: " << LeapCommand << LL_ENDL;
+ if (LeapCommand.isDefined() && !LeapCommand.isArray())
+ {
+ // If LeapCommand is actually a scalar value, make an array of it.
+ // Have to do it in two steps because LeapCommand.append(LeapCommand)
+ // trashes content! :-P
+ LLSD item(LeapCommand);
+ LeapCommand.append(item);
+ }
+ BOOST_FOREACH(const std::string& leap, llsd::inArray(LeapCommand))
+ {
+ LL_INFOS("InitInfo") << "processing --leap \"" << leap << '"' << LL_ENDL;
+ // We don't have any better description of this plugin than the
+ // user-specified command line. Passing "" causes LLLeap to derive a
+ // description from the command line itself.
+ // Suppress LLLeap::Error exception: trust LLLeap's own logging. We
+ // don't consider any one --leap command mission-critical, so if one
+ // fails, log it, shrug and carry on.
+ LLLeap::create("", leap, false); // exception=false
+ }
+ }
if (gSavedSettings.getBOOL("QAMode") && gSavedSettings.getS32("QAModeEventHostPort") > 0)
{
@@ -1229,7 +1256,7 @@ bool LLAppViewer::init()
<< "lleventhost no longer supported as a dynamic library"
<< LL_ENDL;
}
-#endif
+#endif //LL_RELEASE_FOR_DOWNLOAD
LLTextUtil::TextHelpers::iconCallbackCreationFunction = create_text_segment_icon_from_url_match;
@@ -1275,6 +1302,10 @@ bool LLAppViewer::init()
joystick = LLViewerJoystick::getInstance();
joystick->setNeedsReset(true);
+ /*----------------------------------------------------------------------*/
+
+ gSavedSettings.getControl("FramePerSecondLimit")->getSignal()->connect(boost::bind(&LLAppViewer::onChangeFrameLimit, this, _2));
+ onChangeFrameLimit(gSavedSettings.getLLSD("FramePerSecondLimit"));
return true;
}
@@ -1460,6 +1491,21 @@ bool LLAppViewer::doFrame()
display();
+ static U64 last_call = 0;
+ if (!gTeleportDisplay)
+ {
+ // Frame/draw throttling, controlled by FramePerSecondLimit
+ U64 elapsed_time = LLTimer::getTotalTime() - last_call;
+ if (elapsed_time < mMinMicroSecPerFrame)
+ {
+ LL_RECORD_BLOCK_TIME(FTM_SLEEP);
+ // llclamp for when time function gets funky
+ U64 sleep_time = llclamp(mMinMicroSecPerFrame - elapsed_time, (U64)1, (U64)1e6);
+ micro_sleep(sleep_time, 0);
+ }
+ }
+ last_call = LLTimer::getTotalTime();
+
pingMainloopTimeout("Main:Snapshot");
LLFloaterSnapshot::update(); // take snapshots
LLFloaterOutfitSnapshot::update();
@@ -1831,8 +1877,6 @@ bool LLAppViewer::cleanup()
SUBSYSTEM_CLEANUP(LLAvatarAppearance);
- SUBSYSTEM_CLEANUP(LLAvatarAppearance);
-
SUBSYSTEM_CLEANUP(LLPostProcess);
LLTracker::cleanupInstance();
@@ -2034,6 +2078,7 @@ bool LLAppViewer::cleanup()
LLUIImageList::getInstance()->cleanUp();
// This should eventually be done in LLAppViewer
+ SUBSYSTEM_CLEANUP(LLImage);
SUBSYSTEM_CLEANUP(LLVFSThread);
SUBSYSTEM_CLEANUP(LLLFSThread);
@@ -2077,6 +2122,7 @@ bool LLAppViewer::cleanup()
LLWeb::loadURLExternal( gLaunchFileOnQuit, false );
LL_INFOS() << "File launched." << LL_ENDL;
}
+ // make sure nothing uses applyProxySettings by this point.
LL_INFOS() << "Cleaning up LLProxy." << LL_ENDL;
SUBSYSTEM_CLEANUP(LLProxy);
LLCore::LLHttp::cleanup();
@@ -2132,7 +2178,7 @@ bool LLAppViewer::initThreads()
{
static const bool enable_threads = true;
- LLImage::initParamSingleton(gSavedSettings.getBOOL("TextureNewByteRange"),gSavedSettings.getS32("TextureReverseByteRange"));
+ LLImage::initClass(gSavedSettings.getBOOL("TextureNewByteRange"),gSavedSettings.getS32("TextureReverseByteRange"));
LLVFSThread::initClass(enable_threads && false);
LLLFSThread::initClass(enable_threads && false);
@@ -3088,7 +3134,7 @@ LLSD LLAppViewer::getViewerInfo() const
info["REGION"] = gAgent.getRegion()->getName();
boost::regex regex("\\.(secondlife|lindenlab)\\..*");
- info["HOSTNAME"] = boost::regex_replace(gAgent.getRegion()->getHost().getHostName(), regex, "");
+ info["HOSTNAME"] = boost::regex_replace(gAgent.getRegion()->getSimHostName(), regex, "");
info["SERVER_VERSION"] = gLastVersionChannel;
LLSLURL slurl;
LLAgentUI::buildSLURL(slurl);
@@ -3544,7 +3590,7 @@ void LLAppViewer::handleViewerCrash()
if(gAgent.getRegion())
{
- gDebugInfo["Dynamic"]["CurrentSimHost"] = gAgent.getRegionHost().getHostName();
+ gDebugInfo["Dynamic"]["CurrentSimHost"] = gAgent.getRegion()->getSimHostName();
gDebugInfo["Dynamic"]["CurrentRegion"] = gAgent.getRegion()->getName();
const LLVector3& loc = gAgent.getPositionAgent();
@@ -3936,7 +3982,9 @@ void LLAppViewer::requestQuit()
gFloaterView->closeAllChildren(true);
}
- send_stats();
+ // Send preferences once, when exiting
+ bool include_preferences = true;
+ send_viewer_stats(include_preferences);
gLogoutTimer.reset();
mQuitRequested = true;
@@ -4735,7 +4783,8 @@ void LLAppViewer::idle()
if (viewer_stats_timer.getElapsedTimeF32() >= SEND_STATS_PERIOD && !gDisconnected)
{
LL_INFOS() << "Transmitting sessions stats" << LL_ENDL;
- send_stats();
+ bool include_preferences = false;
+ send_viewer_stats(include_preferences);
viewer_stats_timer.reset();
}
@@ -5146,11 +5195,56 @@ void LLAppViewer::sendLogoutRequest()
}
}
+void LLAppViewer::updateNameLookupUrl()
+{
+ LLViewerRegion* region = gAgent.getRegion();
+ if (!region || !region->capabilitiesReceived())
+ {
+ return;
+ }
+
+ LLAvatarNameCache *name_cache = LLAvatarNameCache::getInstance();
+ bool had_capability = LLAvatarNameCache::getInstance()->hasNameLookupURL();
+ std::string name_lookup_url;
+ name_lookup_url.reserve(128); // avoid a memory allocation below
+ name_lookup_url = region->getCapability("GetDisplayNames");
+ bool have_capability = !name_lookup_url.empty();
+ if (have_capability)
+ {
+ // we have support for display names, use it
+ U32 url_size = name_lookup_url.size();
+ // capabilities require URLs with slashes before query params:
+ // https://<host>:<port>/cap/<uuid>/?ids=<blah>
+ // but the caps are granted like:
+ // https://<host>:<port>/cap/<uuid>
+ if (url_size > 0 && name_lookup_url[url_size - 1] != '/')
+ {
+ name_lookup_url += '/';
+ }
+ name_cache->setNameLookupURL(name_lookup_url);
+ }
+ else
+ {
+ // Display names not available on this region
+ name_cache->setNameLookupURL(std::string());
+ }
+
+ // Error recovery - did we change state?
+ if (had_capability != have_capability)
+ {
+ // name tags are persistant on screen, so make sure they refresh
+ LLVOAvatar::invalidateNameTags();
+ }
+}
+
void LLAppViewer::idleNameCache()
{
// Neither old nor new name cache can function before agent has a region
LLViewerRegion* region = gAgent.getRegion();
- if (!region) return;
+ if (!region)
+ {
+ return;
+ }
// deal with any queued name requests and replies.
gCacheName->processPending();
@@ -5158,47 +5252,12 @@ void LLAppViewer::idleNameCache()
// Can't run the new cache until we have the list of capabilities
// for the agent region, and can therefore decide whether to use
// display names or fall back to the old name system.
- if (!region->capabilitiesReceived()) return;
-
- // Agent may have moved to a different region, so need to update cap URL
- // for name lookups. Can't do this in the cap grant code, as caps are
- // granted to neighbor regions before the main agent gets there. Can't
- // do it in the move-into-region code because cap not guaranteed to be
- // granted yet, for example on teleport.
- LLAvatarNameCache *name_cache = LLAvatarNameCache::getInstance();
- bool had_capability = LLAvatarNameCache::getInstance()->hasNameLookupURL();
- std::string name_lookup_url;
- name_lookup_url.reserve(128); // avoid a memory allocation below
- name_lookup_url = region->getCapability("GetDisplayNames");
- bool have_capability = !name_lookup_url.empty();
- if (have_capability)
- {
- // we have support for display names, use it
- U32 url_size = name_lookup_url.size();
- // capabilities require URLs with slashes before query params:
- // https://<host>:<port>/cap/<uuid>/?ids=<blah>
- // but the caps are granted like:
- // https://<host>:<port>/cap/<uuid>
- if (url_size > 0 && name_lookup_url[url_size-1] != '/')
- {
- name_lookup_url += '/';
- }
- name_cache->setNameLookupURL(name_lookup_url);
- }
- else
- {
- // Display names not available on this region
- name_cache->setNameLookupURL( std::string() );
- }
-
- // Error recovery - did we change state?
- if (had_capability != have_capability)
- {
- // name tags are persistant on screen, so make sure they refresh
- LLVOAvatar::invalidateNameTags();
- }
+ if (!region->capabilitiesReceived())
+ {
+ return;
+ }
- name_cache->idle();
+ LLAvatarNameCache::getInstance()->idle();
}
//
@@ -5400,6 +5459,19 @@ void LLAppViewer::disconnectViewer()
LLUrlEntryParcel::setDisconnected(gDisconnected);
}
+bool LLAppViewer::onChangeFrameLimit(LLSD const & evt)
+{
+ if (evt.asInteger() > 0)
+ {
+ mMinMicroSecPerFrame = (U64)(1000000.0f / F32(evt.asInteger()));
+ }
+ else
+ {
+ mMinMicroSecPerFrame = 0;
+ }
+ return false;
+}
+
void LLAppViewer::forceErrorLLError()
{
LL_ERRS() << "This is a deliberate llerror" << LL_ENDL;
@@ -5537,7 +5609,7 @@ void LLAppViewer::handleLoginComplete()
if(gAgent.getRegion())
{
- gDebugInfo["CurrentSimHost"] = gAgent.getRegionHost().getHostName();
+ gDebugInfo["CurrentSimHost"] = gAgent.getRegion()->getSimHostName();
gDebugInfo["CurrentRegion"] = gAgent.getRegion()->getName();
}
diff --git a/indra/newview/llappviewer.h b/indra/newview/llappviewer.h
index f3c5f5b500..11432346b1 100644
--- a/indra/newview/llappviewer.h
+++ b/indra/newview/llappviewer.h
@@ -95,6 +95,7 @@ public:
bool quitRequested() { return mQuitRequested; }
bool logoutRequestSent() { return mLogoutRequestSent; }
bool isSecondInstance() { return mSecondInstance; }
+ bool isUpdaterMissing() { return mUpdaterNotFound; }
void writeDebugInfo(bool isStatic=true);
@@ -205,7 +206,9 @@ public:
// llcorehttp init/shutdown/config information.
LLAppCoreHttp & getAppCoreHttp() { return mAppCoreHttp; }
-
+
+ void updateNameLookupUrl();
+
protected:
virtual bool initWindow(); // Initialize the viewer's window.
virtual void initLoggingAndGetLastDuration(); // Initialize log files, logging system
@@ -254,11 +257,14 @@ private:
void sendLogoutRequest();
void disconnectViewer();
+ bool onChangeFrameLimit(LLSD const & evt);
+
// *FIX: the app viewer class should be some sort of singleton, no?
// Perhaps its child class is the singleton and this should be an abstract base.
static LLAppViewer* sInstance;
bool mSecondInstance; // Is this a second instance of the app?
+ bool mUpdaterNotFound; // True when attempt to start updater failed
std::string mMarkerFileName;
LLAPRFile mMarkerFile; // A file created to indicate the app is running.
@@ -308,7 +314,10 @@ private:
// llcorehttp library init/shutdown helper
LLAppCoreHttp mAppCoreHttp;
- bool mIsFirstRun;
+ bool mIsFirstRun;
+ U64 mMinMicroSecPerFrame; // frame throttling
+
+
};
// consts from viewer.h
diff --git a/indra/newview/llcurrencyuimanager.cpp b/indra/newview/llcurrencyuimanager.cpp
index df94e337da..d4fc1fe64d 100644
--- a/indra/newview/llcurrencyuimanager.cpp
+++ b/indra/newview/llcurrencyuimanager.cpp
@@ -603,6 +603,11 @@ bool LLCurrencyUIManager::bought()
return impl.mBought;
}
+void LLCurrencyUIManager::clearError()
+{
+ impl.clearError();
+}
+
bool LLCurrencyUIManager::hasError()
{
return impl.mError;
diff --git a/indra/newview/llcurrencyuimanager.h b/indra/newview/llcurrencyuimanager.h
index 3f37db8db1..7c05acbb05 100644
--- a/indra/newview/llcurrencyuimanager.h
+++ b/indra/newview/llcurrencyuimanager.h
@@ -80,6 +80,8 @@ public:
bool buying(); // are we in the process of buying?
bool bought(); // did the buy() transaction complete successfully
+ void clearError();
+
bool hasError();
std::string errorMessage();
std::string errorURI();
diff --git a/indra/newview/lldrawpoolwlsky.cpp b/indra/newview/lldrawpoolwlsky.cpp
index d4e7f1600e..0c3d8f3098 100644
--- a/indra/newview/lldrawpoolwlsky.cpp
+++ b/indra/newview/lldrawpoolwlsky.cpp
@@ -226,7 +226,7 @@ void LLDrawPoolWLSky::renderSkyHaze(const LLVector3& camPosLocal, F32 camHeightL
}
}
-void LLDrawPoolWLSky::renderStars(void) const
+void LLDrawPoolWLSky::renderStars(const LLVector3& camPosLocal) const
{
LLGLSPipelineBlendSkyBox gls_skybox(true, false);
@@ -266,6 +266,7 @@ void LLDrawPoolWLSky::renderStars(void) const
}
gGL.pushMatrix();
+ gGL.translatef(camPosLocal.mV[0], camPosLocal.mV[1], camPosLocal.mV[2]);
gGL.rotatef(gFrameTimeSeconds*0.01f, 0.f, 0.f, 1.f);
if (LLGLSLShader::sNoFixedFunction)
{
@@ -296,7 +297,7 @@ void LLDrawPoolWLSky::renderStars(void) const
}
}
-void LLDrawPoolWLSky::renderStarsDeferred(void) const
+void LLDrawPoolWLSky::renderStarsDeferred(const LLVector3& camPosLocal) const
{
LLGLSPipelineBlendSkyBox gls_sky(true, false);
@@ -337,6 +338,8 @@ void LLDrawPoolWLSky::renderStarsDeferred(void) const
gGL.getTexUnit(1)->bind(tex_b);
}
+ gGL.pushMatrix();
+ gGL.translatef(camPosLocal.mV[0], camPosLocal.mV[1], camPosLocal.mV[2]);
gDeferredStarProgram.uniform1f(LLShaderMgr::BLEND_FACTOR, blend_factor);
if (LLPipeline::sReflectionRender)
@@ -355,6 +358,8 @@ void LLDrawPoolWLSky::renderStarsDeferred(void) const
gGL.getTexUnit(1)->unbind(LLTexUnit::TT_TEXTURE);
gDeferredStarProgram.unbind();
+
+ gGL.popMatrix();
}
void LLDrawPoolWLSky::renderSkyCloudsDeferred(const LLVector3& camPosLocal, F32 camHeightLocal, LLGLSLShader* cloudshader) const
@@ -601,7 +606,7 @@ void LLDrawPoolWLSky::renderDeferred(S32 pass)
if (gPipeline.canUseWindLightShaders())
{
renderSkyHazeDeferred(origin, camHeightLocal);
- renderStarsDeferred();
+ renderStarsDeferred(origin);
renderHeavenlyBodies();
renderSkyCloudsDeferred(origin, camHeightLocal, cloud_shader);
}
@@ -620,7 +625,7 @@ void LLDrawPoolWLSky::render(S32 pass)
LLVector3 const & origin = LLViewerCamera::getInstance()->getOrigin();
renderSkyHaze(origin, camHeightLocal);
- renderStars();
+ renderStars(origin);
renderHeavenlyBodies();
renderSkyClouds(origin, camHeightLocal, cloud_shader);
diff --git a/indra/newview/lldrawpoolwlsky.h b/indra/newview/lldrawpoolwlsky.h
index a4f176d6db..324886ed42 100644
--- a/indra/newview/lldrawpoolwlsky.h
+++ b/indra/newview/lldrawpoolwlsky.h
@@ -78,8 +78,8 @@ private:
void renderSkyHazeDeferred(const LLVector3& camPosLocal, F32 camHeightLocal) const;
void renderSkyCloudsDeferred(const LLVector3& camPosLocal, F32 camHeightLocal, LLGLSLShader* cloudshader) const;
- void renderStarsDeferred(void) const;
- void renderStars(void) const;
+ void renderStarsDeferred(const LLVector3& camPosLocal) const;
+ void renderStars(const LLVector3& camPosLocal) const;
void renderHeavenlyBodies();
};
diff --git a/indra/newview/llenvironment.cpp b/indra/newview/llenvironment.cpp
index e56ed92d9e..74c1b99e4d 100644
--- a/indra/newview/llenvironment.cpp
+++ b/indra/newview/llenvironment.cpp
@@ -1029,7 +1029,7 @@ void LLEnvironment::onRegionChange()
}
if (!cur_region->capabilitiesReceived())
{
- cur_region->setCapabilitiesReceivedCallback([](LLUUID region_id) { LLEnvironment::instance().requestRegion(); });
+ cur_region->setCapabilitiesReceivedCallback([](const LLUUID &region_id) { LLEnvironment::instance().requestRegion(); });
return;
}
requestRegion();
@@ -1668,6 +1668,17 @@ void LLEnvironment::updateShaderUniforms(LLGLSLShader *shader)
void LLEnvironment::recordEnvironment(S32 parcel_id, LLEnvironment::EnvironmentInfo::ptr_t envinfo, LLSettingsBase::Seconds transition)
{
+ if (!gAgent.getRegion())
+ {
+ return;
+ }
+ // mRegionId id can be null, no specification as to why and if it's valid so check valid ids only
+ if (gAgent.getRegion()->getRegionID() != envinfo->mRegionId && envinfo->mRegionId.notNull())
+ {
+ LL_INFOS("ENVIRONMENT") << "Requested environmend region id: " << envinfo->mRegionId << " agent is on: " << gAgent.getRegion()->getRegionID() << LL_ENDL;
+ return;
+ }
+
if (envinfo->mParcelId == INVALID_PARCEL_ID)
{
// the returned info applies to an entire region.
diff --git a/indra/newview/lleventpoll.cpp b/indra/newview/lleventpoll.cpp
index 299fffd9ab..4b5fd8a758 100644
--- a/indra/newview/lleventpoll.cpp
+++ b/indra/newview/lleventpoll.cpp
@@ -166,6 +166,14 @@ namespace Details
// LL_DEBUGS("LLEventPollImpl::eventPollCoro") << "<" << counter << "> result = "
// << LLSDXMLStreamer(result) << LL_ENDL;
+ if (gDisconnected)
+ {
+ // Lost connection or disconnected during quit, don't process sim/region update
+ // messages, they might populate some cleaned up classes (LLWorld, region and object list)
+ LL_INFOS("LLEventPollImpl") << "Dropping event messages" << LL_ENDL;
+ break;
+ }
+
LLSD httpResults = result["http_result"];
LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
@@ -210,7 +218,7 @@ namespace Details
llcoro::suspendUntilTimeout(waitToRetry);
- if (mDone)
+ if (mDone || gDisconnected)
break;
LL_INFOS("LLEventPollImpl") << "<" << counter << "> About to retry request." << LL_ENDL;
continue;
diff --git a/indra/newview/llfloateravatartextures.cpp b/indra/newview/llfloateravatartextures.cpp
index 8e654a53c4..ebb73fc1f7 100644
--- a/indra/newview/llfloateravatartextures.cpp
+++ b/indra/newview/llfloateravatartextures.cpp
@@ -55,7 +55,7 @@ BOOL LLFloaterAvatarTextures::postBuild()
{
for (U32 i=0; i < TEX_NUM_INDICES; i++)
{
- const std::string tex_name = LLAvatarAppearanceDictionary::getInstance()->getTexture(ETextureIndex(i))->mName;
+ const std::string tex_name = LLAvatarAppearance::getDictionary()->getTexture(ETextureIndex(i))->mName;
mTextures[i] = getChild<LLTextureCtrl>(tex_name);
}
mTitle = getTitle();
@@ -77,7 +77,7 @@ static void update_texture_ctrl(LLVOAvatar* avatarp,
ETextureIndex te)
{
LLUUID id = IMG_DEFAULT_AVATAR;
- const LLAvatarAppearanceDictionary::TextureEntry* tex_entry = LLAvatarAppearanceDictionary::getInstance()->getTexture(te);
+ const LLAvatarAppearanceDictionary::TextureEntry* tex_entry = LLAvatarAppearance::getDictionary()->getTexture(te);
if (tex_entry && tex_entry->mIsLocalTexture)
{
if (avatarp->isSelf())
@@ -165,14 +165,14 @@ void LLFloaterAvatarTextures::onClickDump(void* data)
const LLTextureEntry* te = avatarp->getTE(i);
if (!te) continue;
- const LLAvatarAppearanceDictionary::TextureEntry* tex_entry = LLAvatarAppearanceDictionary::getInstance()->getTexture((ETextureIndex)(i));
+ const LLAvatarAppearanceDictionary::TextureEntry* tex_entry = LLAvatarAppearance::getDictionary()->getTexture((ETextureIndex)(i));
if (!tex_entry)
continue;
if (LLVOAvatar::isIndexLocalTexture((ETextureIndex)i))
{
LLUUID id = IMG_DEFAULT_AVATAR;
- LLWearableType::EType wearable_type = LLAvatarAppearanceDictionary::getInstance()->getTEWearableType((ETextureIndex)i);
+ LLWearableType::EType wearable_type = LLAvatarAppearance::getDictionary()->getTEWearableType((ETextureIndex)i);
if (avatarp->isSelf())
{
LLViewerWearable *wearable = gAgentWearables.getViewerWearable(wearable_type, 0);
diff --git a/indra/newview/llfloaterbuycurrency.cpp b/indra/newview/llfloaterbuycurrency.cpp
index 25348474a1..1751d54b5a 100644
--- a/indra/newview/llfloaterbuycurrency.cpp
+++ b/indra/newview/llfloaterbuycurrency.cpp
@@ -184,6 +184,7 @@ void LLFloaterBuyCurrencyUI::updateUI()
args["TITLE"] = getString("info_cannot_buy");
args["MESSAGE"] = mManager.errorMessage();
LLNotificationsUtil::add("CouldNotBuyCurrency", args);
+ mManager.clearError();
closeFloater();
}
else
diff --git a/indra/newview/llfloaterdeleteprefpreset.cpp b/indra/newview/llfloaterdeleteprefpreset.cpp
index 0765756b43..819b2bcee2 100644
--- a/indra/newview/llfloaterdeleteprefpreset.cpp
+++ b/indra/newview/llfloaterdeleteprefpreset.cpp
@@ -59,8 +59,17 @@ BOOL LLFloaterDeletePrefPreset::postBuild()
void LLFloaterDeletePrefPreset::onOpen(const LLSD& key)
{
mSubdirectory = key.asString();
- std::string floater_title = getString(std::string("title_") + mSubdirectory);
- setTitle(floater_title);
+ std::string title_type = std::string("title_") + mSubdirectory;
+ if (hasString(title_type))
+ {
+ std::string floater_title = getString(title_type);
+ setTitle(floater_title);
+ }
+ else
+ {
+ LL_WARNS() << title_type << " not found" << LL_ENDL;
+ setTitle(title_type);
+ }
LLComboBox* combo = getChild<LLComboBox>("preset_combo");
EDefaultOptions option = DEFAULT_HIDE;
diff --git a/indra/newview/llfloaterimcontainer.cpp b/indra/newview/llfloaterimcontainer.cpp
index 2a05f82f94..c6e9069d09 100644
--- a/indra/newview/llfloaterimcontainer.cpp
+++ b/indra/newview/llfloaterimcontainer.cpp
@@ -454,19 +454,23 @@ void LLFloaterIMContainer::idleUpdate()
const LLConversationItem *current_session = getCurSelectedViewModelItem();
if (current_session)
{
- // Update moderator options visibility
- LLFolderViewModelItemCommon::child_list_t::const_iterator current_participant_model = current_session->getChildrenBegin();
- LLFolderViewModelItemCommon::child_list_t::const_iterator end_participant_model = current_session->getChildrenEnd();
- bool is_moderator = isGroupModerator();
- bool can_ban = haveAbilityToBan();
- while (current_participant_model != end_participant_model)
+ if (current_session->getType() == LLConversationItem::CONV_SESSION_GROUP)
{
- LLConversationItemParticipant* participant_model = dynamic_cast<LLConversationItemParticipant*>(*current_participant_model);
- participant_model->setModeratorOptionsVisible(is_moderator);
- participant_model->setGroupBanVisible(can_ban && participant_model->getUUID() != gAgentID);
-
- current_participant_model++;
+ // Update moderator options visibility
+ LLFolderViewModelItemCommon::child_list_t::const_iterator current_participant_model = current_session->getChildrenBegin();
+ LLFolderViewModelItemCommon::child_list_t::const_iterator end_participant_model = current_session->getChildrenEnd();
+ bool is_moderator = isGroupModerator();
+ bool can_ban = haveAbilityToBan();
+ while (current_participant_model != end_participant_model)
+ {
+ LLConversationItemParticipant* participant_model = dynamic_cast<LLConversationItemParticipant*>(*current_participant_model);
+ participant_model->setModeratorOptionsVisible(is_moderator);
+ participant_model->setGroupBanVisible(can_ban && participant_model->getUUID() != gAgentID);
+
+ current_participant_model++;
+ }
}
+
// Update floater's title as required by the currently selected session or use the default title
LLFloaterIMSession * conversation_floaterp = LLFloaterIMSession::findInstance(current_session->getUUID());
setTitle(conversation_floaterp && conversation_floaterp->needsTitleOverwrite() ? conversation_floaterp->getTitle() : mGeneralTitle);
diff --git a/indra/newview/llfloaterimsession.cpp b/indra/newview/llfloaterimsession.cpp
index a4ab1af9a8..48e2b8dc14 100644
--- a/indra/newview/llfloaterimsession.cpp
+++ b/indra/newview/llfloaterimsession.cpp
@@ -160,7 +160,6 @@ void LLFloaterIMSession::onClickCloseBtn(bool)
else
{
LL_WARNS() << "Empty session with id: " << (mSessionID.asString()) << LL_ENDL;
- return;
}
LLFloaterIMSessionTab::onClickCloseBtn();
diff --git a/indra/newview/llfloaterjoystick.cpp b/indra/newview/llfloaterjoystick.cpp
index 2b672bc890..93a26f31cc 100644
--- a/indra/newview/llfloaterjoystick.cpp
+++ b/indra/newview/llfloaterjoystick.cpp
@@ -40,7 +40,17 @@
#include "llviewercontrol.h"
#include "llappviewer.h"
#include "llviewerjoystick.h"
+#include "llviewerwindow.h"
+#include "llwindow.h"
#include "llcheckboxctrl.h"
+#include "llcombobox.h"
+
+#if LL_WINDOWS && !LL_MESA_HEADLESS
+// Require DirectInput version 8
+#define DIRECTINPUT_VERSION 0x0800
+
+#include <dinput.h>
+#endif
static LLTrace::SampleStatHandle<> sJoystickAxis0("Joystick axis 0"),
sJoystickAxis1("Joystick axis 1"),
@@ -58,8 +68,33 @@ static LLTrace::SampleStatHandle<>* sJoystickAxes[6] =
&sJoystickAxis5
};
+
+#if LL_WINDOWS && !LL_MESA_HEADLESS
+
+BOOL CALLBACK di8_list_devices_callback(LPCDIDEVICEINSTANCE device_instance_ptr, LPVOID pvRef)
+{
+ // Note: If a single device can function as more than one DirectInput
+ // device type, it is enumerated as each device type that it supports.
+ // Capable of detecting devices like Oculus Rift
+ if (device_instance_ptr && pvRef)
+ {
+ std::string product_name = utf16str_to_utf8str(llutf16string(device_instance_ptr->tszProductName));
+ S32 size = sizeof(GUID);
+ LLSD::Binary data; //just an std::vector
+ data.resize(size);
+ memcpy(&data[0], &device_instance_ptr->guidInstance /*POD _GUID*/, size);
+
+ LLFloaterJoystick * floater = (LLFloaterJoystick*)pvRef;
+ LLSD value = data;
+ floater->addDevice(product_name, value);
+ }
+ return DIENUM_CONTINUE;
+}
+#endif
+
LLFloaterJoystick::LLFloaterJoystick(const LLSD& data)
- : LLFloater(data)
+ : LLFloater(data),
+ mHasDeviceList(false)
{
if (!LLViewerJoystick::getInstance()->isJoystickInitialized())
{
@@ -71,14 +106,13 @@ LLFloaterJoystick::LLFloaterJoystick(const LLSD& data)
void LLFloaterJoystick::draw()
{
- bool joystick_inited = LLViewerJoystick::getInstance()->isJoystickInitialized();
- getChildView("enable_joystick")->setEnabled(joystick_inited);
- getChildView("joystick_type")->setEnabled(joystick_inited);
- std::string desc = LLViewerJoystick::getInstance()->getDescription();
- if (desc.empty()) desc = getString("NoDevice");
- getChild<LLUICtrl>("joystick_type")->setValue(desc);
-
- LLViewerJoystick* joystick(LLViewerJoystick::getInstance());
+ LLViewerJoystick* joystick(LLViewerJoystick::getInstance());
+ bool joystick_inited = joystick->isJoystickInitialized();
+ if (joystick_inited != mHasDeviceList)
+ {
+ refreshListOfDevices();
+ }
+
for (U32 i = 0; i < 6; i++)
{
F32 value = joystick->getJoystickAxis(i);
@@ -115,8 +149,8 @@ BOOL LLFloaterJoystick::postBuild()
}
}
- mCheckJoystickEnabled = getChild<LLCheckBoxCtrl>("enable_joystick");
- childSetCommitCallback("enable_joystick",onCommitJoystickEnabled,this);
+ mJoysticksCombo = getChild<LLComboBox>("joystick_combo");
+ childSetCommitCallback("joystick_combo",onCommitJoystickEnabled,this);
mCheckFlycamEnabled = getChild<LLCheckBoxCtrl>("JoystickFlycamEnabled");
childSetCommitCallback("JoystickFlycamEnabled",onCommitJoystickEnabled,this);
@@ -125,6 +159,7 @@ BOOL LLFloaterJoystick::postBuild()
childSetAction("ok_btn", onClickOK, this);
refresh();
+ refreshListOfDevices();
return TRUE;
}
@@ -141,6 +176,7 @@ void LLFloaterJoystick::apply()
void LLFloaterJoystick::initFromSettings()
{
mJoystickEnabled = gSavedSettings.getBOOL("JoystickEnabled");
+ mJoystickId = gSavedSettings.getLLSD("JoystickDeviceUUID");
mJoystickAxis[0] = gSavedSettings.getS32("JoystickAxis0");
mJoystickAxis[1] = gSavedSettings.getS32("JoystickAxis1");
@@ -210,12 +246,80 @@ void LLFloaterJoystick::initFromSettings()
void LLFloaterJoystick::refresh()
{
LLFloater::refresh();
+
initFromSettings();
}
+void LLFloaterJoystick::addDevice(std::string &name, LLSD& value)
+{
+ mJoysticksCombo->add(name, value, ADD_BOTTOM, 1);
+}
+
+void LLFloaterJoystick::refreshListOfDevices()
+{
+ mJoysticksCombo->removeall();
+ std::string no_device = getString("JoystickDisabled");
+ LLSD value = LLSD::Integer(0);
+ addDevice(no_device, value);
+
+ mHasDeviceList = false;
+
+ // di8_devices_callback callback is immediate and happens in scope of getInputDevices()
+#if LL_WINDOWS && !LL_MESA_HEADLESS
+ // space navigator is marked as DI8DEVCLASS_GAMECTRL in ndof lib
+ U32 device_type = DI8DEVCLASS_GAMECTRL;
+ void* callback = &di8_list_devices_callback;
+#else
+ // MAC doesn't support device search yet
+ // On MAC there is an ndof_idsearch and it is possible to specify product
+ // and manufacturer in NDOF_Device for ndof_init_first to pick specific one
+ U32 device_type = 0;
+ void* callback = NULL;
+#endif
+ if (gViewerWindow->getWindow()->getInputDevices(device_type, callback, this))
+ {
+ mHasDeviceList = true;
+ }
+
+ bool is_device_id_set = LLViewerJoystick::getInstance()->isDeviceUUIDSet();
+
+ if (LLViewerJoystick::getInstance()->isJoystickInitialized() &&
+ (!mHasDeviceList || !is_device_id_set))
+ {
+#if LL_WINDOWS && !LL_MESA_HEADLESS
+ LL_WARNS() << "NDOF connected to device without using SL provided handle" << LL_ENDL;
+#endif
+ std::string desc = LLViewerJoystick::getInstance()->getDescription();
+ if (!desc.empty())
+ {
+ LLSD value = LLSD::Integer(0);
+ addDevice(desc, value);
+ mHasDeviceList = true;
+ }
+ }
+
+ if (gSavedSettings.getBOOL("JoystickEnabled") && mHasDeviceList)
+ {
+ if (is_device_id_set)
+ {
+ LLSD guid = LLViewerJoystick::getInstance()->getDeviceUUID();
+ mJoysticksCombo->selectByValue(guid);
+ }
+ else
+ {
+ mJoysticksCombo->selectByValue(LLSD::Integer(1));
+ }
+ }
+ else
+ {
+ mJoysticksCombo->selectByValue(LLSD::Integer(0));
+ }
+}
+
void LLFloaterJoystick::cancel()
{
gSavedSettings.setBOOL("JoystickEnabled", mJoystickEnabled);
+ gSavedSettings.setLLSD("JoystickDeviceUUID", mJoystickId);
gSavedSettings.setS32("JoystickAxis0", mJoystickAxis[0]);
gSavedSettings.setS32("JoystickAxis1", mJoystickAxis[1]);
@@ -285,7 +389,21 @@ void LLFloaterJoystick::cancel()
void LLFloaterJoystick::onCommitJoystickEnabled(LLUICtrl*, void *joy_panel)
{
LLFloaterJoystick* self = (LLFloaterJoystick*)joy_panel;
- BOOL joystick_enabled = self->mCheckJoystickEnabled->get();
+
+ LLSD value = self->mJoysticksCombo->getValue();
+ bool joystick_enabled = true;
+ if (value.isInteger())
+ {
+ // ndof already has a device selected, we are just setting it enabled or disabled
+ joystick_enabled = value.asInteger();
+ }
+ else
+ {
+ LLViewerJoystick::getInstance()->initDevice(value);
+ // else joystick is enabled, because combobox holds id of device
+ joystick_enabled = true;
+ }
+ gSavedSettings.setBOOL("JoystickEnabled", joystick_enabled);
BOOL flycam_enabled = self->mCheckFlycamEnabled->get();
if (!joystick_enabled || !flycam_enabled)
@@ -297,6 +415,12 @@ void LLFloaterJoystick::onCommitJoystickEnabled(LLUICtrl*, void *joy_panel)
joystick->toggleFlycam();
}
}
+
+ std::string device_id = LLViewerJoystick::getInstance()->getDeviceUUIDString();
+ gSavedSettings.setString("JoystickDeviceUUID", device_id);
+ LL_DEBUGS("Joystick") << "Selected " << device_id << " as joystick." << LL_ENDL;
+
+ self->refreshListOfDevices();
}
void LLFloaterJoystick::onClickRestoreSNDefaults(void *joy_panel)
diff --git a/indra/newview/llfloaterjoystick.h b/indra/newview/llfloaterjoystick.h
index a1b5951389..1d46efd3f6 100644
--- a/indra/newview/llfloaterjoystick.h
+++ b/indra/newview/llfloaterjoystick.h
@@ -31,6 +31,7 @@
#include "llstatview.h"
class LLCheckBoxCtrl;
+class LLComboBox;
class LLFloaterJoystick : public LLFloater
{
@@ -45,8 +46,11 @@ public:
virtual void draw();
static void setSNDefaults();
+ void addDevice(std::string &name, LLSD& value);
+
protected:
+ void refreshListOfDevices();
void onClose(bool app_quitting);
void onClickCloseBtn(bool app_quitting);
@@ -65,6 +69,7 @@ private:
private:
// Device prefs
bool mJoystickEnabled;
+ LLSD mJoystickId;
S32 mJoystickAxis[7];
bool m3DCursor;
bool mAutoLeveling;
@@ -85,8 +90,10 @@ private:
F32 mFlycamFeathering;
// Controls that can disable the flycam
- LLCheckBoxCtrl *mCheckJoystickEnabled;
LLCheckBoxCtrl *mCheckFlycamEnabled;
+ LLComboBox *mJoysticksCombo;
+
+ bool mHasDeviceList;
// stats view
LLStatBar* mAxisStatsBar[6];
diff --git a/indra/newview/llfloaterloadprefpreset.cpp b/indra/newview/llfloaterloadprefpreset.cpp
index f89daf3e04..8ed76b1df4 100644
--- a/indra/newview/llfloaterloadprefpreset.cpp
+++ b/indra/newview/llfloaterloadprefpreset.cpp
@@ -58,9 +58,17 @@ BOOL LLFloaterLoadPrefPreset::postBuild()
void LLFloaterLoadPrefPreset::onOpen(const LLSD& key)
{
mSubdirectory = key.asString();
- std::string floater_title = getString(std::string("title_") + mSubdirectory);
-
- setTitle(floater_title);
+ std::string title_type = std::string("title_") + mSubdirectory;
+ if (hasString(title_type))
+ {
+ std::string floater_title = getString(title_type);
+ setTitle(floater_title);
+ }
+ else
+ {
+ LL_WARNS() << title_type << " not found" << LL_ENDL;
+ setTitle(title_type);
+ }
LLComboBox* combo = getChild<LLComboBox>("preset_combo");
diff --git a/indra/newview/llfloatersidepanelcontainer.cpp b/indra/newview/llfloatersidepanelcontainer.cpp
index 64ddeff1b0..dd7ce40e97 100644
--- a/indra/newview/llfloatersidepanelcontainer.cpp
+++ b/indra/newview/llfloatersidepanelcontainer.cpp
@@ -60,7 +60,7 @@ void LLFloaterSidePanelContainer::onOpen(const LLSD& key)
void LLFloaterSidePanelContainer::closeFloater(bool app_quitting)
{
LLPanelOutfitEdit* panel_outfit_edit =
- dynamic_cast<LLPanelOutfitEdit*>(LLFloaterSidePanelContainer::getPanel("appearance", "panel_outfit_edit"));
+ dynamic_cast<LLPanelOutfitEdit*>(LLFloaterSidePanelContainer::findPanel("appearance", "panel_outfit_edit"));
if (panel_outfit_edit)
{
LLFloater *parent = gFloaterView->getParentFloater(panel_outfit_edit);
@@ -145,3 +145,15 @@ LLPanel* LLFloaterSidePanelContainer::getPanel(const std::string& floater_name,
return NULL;
}
+
+LLPanel* LLFloaterSidePanelContainer::findPanel(const std::string& floater_name, const std::string& panel_name)
+{
+ LLFloaterSidePanelContainer* floaterp = LLFloaterReg::findTypedInstance<LLFloaterSidePanelContainer>(floater_name);
+
+ if (floaterp)
+ {
+ return floaterp->findChild<LLPanel>(panel_name, true);
+ }
+
+ return NULL;
+}
diff --git a/indra/newview/llfloatersidepanelcontainer.h b/indra/newview/llfloatersidepanelcontainer.h
index 635514e26c..20baf28184 100644
--- a/indra/newview/llfloatersidepanelcontainer.h
+++ b/indra/newview/llfloatersidepanelcontainer.h
@@ -62,6 +62,8 @@ public:
static void showPanel(const std::string& floater_name, const std::string& panel_name, const LLSD& key);
static LLPanel* getPanel(const std::string& floater_name, const std::string& panel_name = sMainPanelName);
+
+ static LLPanel* findPanel(const std::string& floater_name, const std::string& panel_name = sMainPanelName);
/**
* Gets the panel of given type T (doesn't show it or do anything else with it).
diff --git a/indra/newview/llgiveinventory.cpp b/indra/newview/llgiveinventory.cpp
index 3ab8fed2c6..127055459d 100644
--- a/indra/newview/llgiveinventory.cpp
+++ b/indra/newview/llgiveinventory.cpp
@@ -129,23 +129,14 @@ bool LLGiveInventory::isInventoryGiveAcceptable(const LLInventoryItem* item)
switch(item->getType())
{
case LLAssetType::AT_OBJECT:
- if (get_is_item_worn(item->getUUID()))
- {
- acceptable = false;
- }
- break;
case LLAssetType::AT_BODYPART:
case LLAssetType::AT_CLOTHING:
{
- BOOL copyable = false;
- if (item->getPermissions().allowCopyBy(gAgentID)) copyable = true;
-
- if (!copyable && get_is_item_worn(item->getUUID()))
+ if (get_is_item_worn(item->getUUID()))
{
- // worn no-copy items can't be transfered,
- // but it is valid to transfer a copy of a worn item
acceptable = false;
}
+ break;
}
break;
default:
diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp
index d17bb982e1..9afb6ca58b 100644
--- a/indra/newview/llimview.cpp
+++ b/indra/newview/llimview.cpp
@@ -2254,6 +2254,19 @@ BOOL LLOutgoingCallDialog::postBuild()
// Class LLIncomingCallDialog
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+const std::array<std::string, 4> voice_call_types =
+{
+ "VoiceInviteP2P",
+ "VoiceInviteGroup",
+ "VoiceInviteAdHoc",
+ "InviteAdHoc"
+};
+
+bool is_voice_call_type(const std::string &value)
+{
+ return std::find(voice_call_types.begin(), voice_call_types.end(), value) != voice_call_types.end();
+}
+
LLIncomingCallDialog::LLIncomingCallDialog(const LLSD& payload) :
LLCallDialog(payload),
mAvatarNameCacheConnection()
@@ -2283,9 +2296,28 @@ BOOL LLIncomingCallDialog::postBuild()
{
LLCallDialog::postBuild();
+ if (!mPayload.isMap() || mPayload.size() == 0)
+ {
+ LL_INFOS("IMVIEW") << "IncomingCall: invalid argument" << LL_ENDL;
+ return TRUE;
+ }
+
LLUUID session_id = mPayload["session_id"].asUUID();
LLSD caller_id = mPayload["caller_id"];
std::string caller_name = mPayload["caller_name"].asString();
+
+ if (session_id.isNull() && caller_id.asUUID().isNull())
+ {
+ LL_INFOS("IMVIEW") << "IncomingCall: invalid ids" << LL_ENDL;
+ return TRUE;
+ }
+
+ std::string notify_box_type = mPayload["notify_box_type"].asString();
+ if (!is_voice_call_type(notify_box_type))
+ {
+ LL_INFOS("IMVIEW") << "IncomingCall: notify_box_type was not provided" << LL_ENDL;
+ return TRUE;
+ }
// init notification's lifetime
std::istringstream ss( getString("lifetime") );
@@ -2302,15 +2334,14 @@ BOOL LLIncomingCallDialog::postBuild()
if (gAgent.getGroupData(session_id, data))
{
args["[GROUP]"] = data.mName;
- call_type = getString(mPayload["notify_box_type"], args);
+ call_type = getString(notify_box_type, args);
}
}
else
{
- call_type = getString(mPayload["notify_box_type"]);
+ call_type = getString(notify_box_type);
}
-
-
+
// check to see if this is an Avaline call
bool is_avatar = LLVoiceClient::getInstance()->isParticipantAvatar(session_id);
if (caller_name == "anonymous")
@@ -2340,7 +2371,6 @@ BOOL LLIncomingCallDialog::postBuild()
childSetAction("Start IM", onStartIM, this);
setDefaultBtn("Accept");
- std::string notify_box_type = mPayload["notify_box_type"].asString();
if(notify_box_type != "VoiceInviteGroup" && notify_box_type != "VoiceInviteAdHoc")
{
// starting notification's timer for P2P and AVALINE invitations
@@ -2491,10 +2521,10 @@ void LLIncomingCallDialog::processCallResponse(S32 response, const LLSD &payload
correct_session_name.append(ADHOC_NAME_SUFFIX);
}
}
- LL_INFOS() << "Corrected session name is " << correct_session_name << LL_ENDL;
+ LL_INFOS("IMVIEW") << "Corrected session name is " << correct_session_name << LL_ENDL;
break;
default:
- LL_WARNS() << "Received an empty session name from a server and failed to generate a new proper session name" << LL_ENDL;
+ LL_WARNS("IMVIEW") << "Received an empty session name from a server and failed to generate a new proper session name" << LL_ENDL;
break;
}
}
@@ -2694,6 +2724,14 @@ void LLIMMgr::addMessage(
bool new_session = !hasSession(new_session_id);
if (new_session)
{
+ // Group chat session was initiated by muted resident, do not start this session viewerside
+ // do not send leave msg either, so we are able to get group messages from other participants
+ if ((IM_SESSION_INVITE == dialog) && gAgent.isInGroup(new_session_id) &&
+ LLMuteList::getInstance()->isMuted(other_participant_id, LLMute::flagTextChat) && !from_linden)
+ {
+ return;
+ }
+
LLAvatarName av_name;
if (LLAvatarNameCache::get(other_participant_id, &av_name) && !name_is_setted)
{
@@ -2737,7 +2775,7 @@ void LLIMMgr::addMessage(
LL_WARNS() << "Leaving IM session from initiating muted resident " << from << LL_ENDL;
if (!gIMMgr->leaveSession(new_session_id))
{
- LL_INFOS() << "Session " << new_session_id << " does not exist." << LL_ENDL;
+ LL_INFOS("IMVIEW") << "Session " << new_session_id << " does not exist." << LL_ENDL;
}
return;
}
@@ -2948,7 +2986,7 @@ LLUUID LLIMMgr::addSession(
//we don't need to show notes about online/offline, mute/unmute users' statuses for existing sessions
if (!new_session) return session_id;
- LL_INFOS() << "LLIMMgr::addSession, new session added, name = " << name << ", session id = " << session_id << LL_ENDL;
+ LL_INFOS("IMVIEW") << "LLIMMgr::addSession, new session added, name = " << name << ", session id = " << session_id << LL_ENDL;
//Per Plan's suggestion commented "explicit offline status warning" out to make Dessie happier (see EXT-3609)
//*TODO After February 2010 remove this commented out line if no one will be missing that warning
@@ -2985,7 +3023,7 @@ void LLIMMgr::removeSession(const LLUUID& session_id)
LLIMModel::getInstance()->clearSession(session_id);
- LL_INFOS() << "LLIMMgr::removeSession, session removed, session id = " << session_id << LL_ENDL;
+ LL_INFOS("IMVIEW") << "LLIMMgr::removeSession, session removed, session id = " << session_id << LL_ENDL;
notifyObserverSessionRemoved(session_id);
}
@@ -3051,13 +3089,13 @@ void LLIMMgr::inviteToSession(
if (LLMuteList::getInstance()->isMuted(caller_id, LLMute::flagVoiceChat)
&& voice_invite && "VoiceInviteQuestionDefault" == question_type)
{
- LL_INFOS() << "Rejecting voice call from initiating muted resident " << caller_name << LL_ENDL;
+ LL_INFOS("IMVIEW") << "Rejecting voice call from initiating muted resident " << caller_name << LL_ENDL;
LLIncomingCallDialog::processCallResponse(1, payload);
return;
}
else if (LLMuteList::getInstance()->isMuted(caller_id, LLMute::flagAll & ~LLMute::flagVoiceChat) && !voice_invite)
{
- LL_INFOS() << "Rejecting session invite from initiating muted resident " << caller_name << LL_ENDL;
+ LL_INFOS("IMVIEW") << "Rejecting session invite from initiating muted resident " << caller_name << LL_ENDL;
return;
}
}
diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp
index e9aaca13eb..d35d8456be 100644
--- a/indra/newview/llinventorybridge.cpp
+++ b/indra/newview/llinventorybridge.cpp
@@ -7665,13 +7665,12 @@ void LLFolderViewGroupedItemBridge::groupFilterContextMenu(folder_view_item_dequ
disable_context_entries_if_present(menu, disabled_items);
}
-bool LLFolderViewGroupedItemBridge::canWearSelected(uuid_vec_t item_ids)
+bool LLFolderViewGroupedItemBridge::canWearSelected(const uuid_vec_t& item_ids) const
{
for (uuid_vec_t::const_iterator it = item_ids.begin(); it != item_ids.end(); ++it)
{
- LLViewerInventoryItem* item = gInventory.getItem(*it);
- LLAssetType::EType asset_type = item->getType();
- if (!item || (asset_type >= LLAssetType::AT_COUNT) || (asset_type <= LLAssetType::AT_NONE))
+ const LLViewerInventoryItem* item = gInventory.getItem(*it);
+ if (!item || (item->getType() >= LLAssetType::AT_COUNT) || (item->getType() <= LLAssetType::AT_NONE))
{
return false;
}
diff --git a/indra/newview/llinventorybridge.h b/indra/newview/llinventorybridge.h
index fce7ade661..9af8664388 100644
--- a/indra/newview/llinventorybridge.h
+++ b/indra/newview/llinventorybridge.h
@@ -760,7 +760,7 @@ class LLFolderViewGroupedItemBridge: public LLFolderViewGroupedItemModel
public:
LLFolderViewGroupedItemBridge();
virtual void groupFilterContextMenu(folder_view_item_deque& selected_items, LLMenuGL& menu);
- bool canWearSelected(uuid_vec_t item_ids);
+ bool canWearSelected(const uuid_vec_t& item_ids) const;
};
#endif // LL_LLINVENTORYBRIDGE_H
diff --git a/indra/newview/llinventoryfunctions.cpp b/indra/newview/llinventoryfunctions.cpp
index d069aa3223..7a0ea8b668 100644
--- a/indra/newview/llinventoryfunctions.cpp
+++ b/indra/newview/llinventoryfunctions.cpp
@@ -2442,16 +2442,19 @@ void LLInventoryAction::doToSelected(LLInventoryModel* model, LLFolderView* root
{
bool open_multi_preview = true;
- for (std::set<LLFolderViewItem*>::iterator set_iter = selected_items.begin(); set_iter != selected_items.end(); ++set_iter)
+ if ("open" == action)
{
- LLFolderViewItem* folder_item = *set_iter;
- if (folder_item)
+ for (std::set<LLFolderViewItem*>::iterator set_iter = selected_items.begin(); set_iter != selected_items.end(); ++set_iter)
{
- LLInvFVBridge* bridge = dynamic_cast<LLInvFVBridge*>(folder_item->getViewModelItem());
- if (!bridge || !bridge->isMultiPreviewAllowed())
+ LLFolderViewItem* folder_item = *set_iter;
+ if (folder_item)
{
- open_multi_preview = false;
- break;
+ LLInvFVBridge* bridge = dynamic_cast<LLInvFVBridge*>(folder_item->getViewModelItem());
+ if (!bridge || !bridge->isMultiPreviewAllowed())
+ {
+ open_multi_preview = false;
+ break;
+ }
}
}
}
diff --git a/indra/newview/llinventorypanel.cpp b/indra/newview/llinventorypanel.cpp
index f96750fb0b..74d9e895c2 100644
--- a/indra/newview/llinventorypanel.cpp
+++ b/indra/newview/llinventorypanel.cpp
@@ -154,7 +154,8 @@ LLInventoryPanel::LLInventoryPanel(const LLInventoryPanel::Params& p) :
mShowEmptyMessage(p.show_empty_message),
mSuppressFolderMenu(p.suppress_folder_menu),
mSuppressOpenItemAction(false),
- mViewsInitialized(false),
+ mBuildViewsOnInit(p.preinitialize_views),
+ mViewsInitialized(VIEWS_UNINITIALIZED),
mInvFVBridgeBuilder(NULL),
mInventoryViewModel(p.name),
mGroupedItemBridge(new LLFolderViewGroupedItemBridge)
@@ -281,14 +282,22 @@ void LLInventoryPanel::initFromParams(const LLInventoryPanel::Params& params)
mCompletionObserver = new LLInvPanelComplObserver(boost::bind(&LLInventoryPanel::onItemsCompletion, this));
mInventory->addObserver(mCompletionObserver);
- // Build view of inventory if we need default full hierarchy and inventory ready, otherwise do in onIdle.
- // Initializing views takes a while so always do it onIdle if viewer already loaded.
- if (mInventory->isInventoryUsable() && !mViewsInitialized && LLStartUp::getStartupState() <= STATE_WEARABLES_WAIT)
- {
- initializeViews();
- }
-
- gIdleCallbacks.addFunction(onIdle, (void*)this);
+ if (mBuildViewsOnInit)
+ {
+ // Build view of inventory if we need default full hierarchy and inventory is ready, otherwise do in onIdle.
+ // Initializing views takes a while so always do it onIdle if viewer already loaded.
+ if (mInventory->isInventoryUsable()
+ && mViewsInitialized == VIEWS_UNINITIALIZED
+ && LLStartUp::getStartupState() <= STATE_WEARABLES_WAIT)
+ {
+ initializeViews();
+ }
+ else if (mViewsInitialized != VIEWS_INITIALIZING)
+ {
+ mViewsInitialized = VIEWS_INITIALIZING;
+ gIdleCallbacks.addFunction(onIdle, (void*)this);
+ }
+ }
if (mSortOrderSetting != INHERIT_SORT_ORDER)
{
@@ -334,6 +343,17 @@ LLInventoryPanel::~LLInventoryPanel()
clearFolderRoot();
}
+/*virtual*/
+void LLInventoryPanel::onVisibilityChange(BOOL new_visibility)
+{
+ if (new_visibility && mViewsInitialized == VIEWS_UNINITIALIZED)
+ {
+ mViewsInitialized = VIEWS_INITIALIZING;
+ gIdleCallbacks.addFunction(onIdle, (void*)this);
+ }
+ LLPanel::onVisibilityChange(new_visibility);
+}
+
void LLInventoryPanel::draw()
{
// Select the desired item (in case it wasn't loaded when the selection was requested)
@@ -657,7 +677,7 @@ void LLInventoryPanel::modelChanged(U32 mask)
{
LL_RECORD_BLOCK_TIME(FTM_REFRESH);
- if (!mViewsInitialized) return;
+ if (mViewsInitialized != VIEWS_INITIALIZED) return;
const LLInventoryModel* model = getModel();
if (!model) return;
@@ -723,11 +743,11 @@ void LLInventoryPanel::onIdle(void *userdata)
LLInventoryPanel *self = (LLInventoryPanel*)userdata;
// Inventory just initialized, do complete build
- if (!self->mViewsInitialized)
+ if (self->mViewsInitialized != VIEWS_INITIALIZED)
{
self->initializeViews();
}
- if (self->mViewsInitialized)
+ if (self->mViewsInitialized == VIEWS_INITIALIZED)
{
gIdleCallbacks.deleteFunction(onIdle, (void*)self);
}
@@ -810,7 +830,7 @@ void LLInventoryPanel::initializeViews()
gIdleCallbacks.addFunction(idle, this);
- mViewsInitialized = true;
+ mViewsInitialized = VIEWS_INITIALIZED;
openStartFolderOrMyInventory();
diff --git a/indra/newview/llinventorypanel.h b/indra/newview/llinventorypanel.h
index c202333f45..ad6010f09c 100644
--- a/indra/newview/llinventorypanel.h
+++ b/indra/newview/llinventorypanel.h
@@ -108,6 +108,10 @@ public:
Optional<LLFolderViewFolder::Params> folder;
Optional<LLFolderViewItem::Params> item;
+ // All item and folder views will be initialized on init if true (default)
+ // Will initialize on visibility change otherwise.
+ Optional<bool> preinitialize_views;
+
Params()
: sort_order_setting("sort_order_setting"),
inventory("", &gInventory),
@@ -126,7 +130,8 @@ public:
accepts_drag_and_drop("accepts_drag_and_drop"),
folder_view("folder_view"),
folder("folder"),
- item("item")
+ item("item"),
+ preinitialize_views("preinitialize_views", true)
{}
};
@@ -154,6 +159,7 @@ public:
LLFolderViewModelInventory& getRootViewModel() { return mInventoryViewModel; }
// LLView methods
+ /*virtual*/ void onVisibilityChange(BOOL new_visibility);
void draw();
/*virtual*/ BOOL handleKeyHere( KEY key, MASK mask );
BOOL handleHover(S32 x, S32 y, MASK mask);
@@ -313,7 +319,7 @@ public:
void addHideFolderType(LLFolderType::EType folder_type);
public:
- BOOL getIsViewsInitialized() const { return mViewsInitialized; }
+ bool getViewsInitialized() const { return mViewsInitialized == VIEWS_INITIALIZED; }
protected:
// Builds the UI. Call this once the inventory is usable.
void initializeViews();
@@ -349,8 +355,15 @@ private:
LLFolderViewItem *target_view,
LLFolderViewFolder *parent_folder_view);
- bool mBuildDefaultHierarchy; // default inventory hierarchy should be created in postBuild()
- bool mViewsInitialized; // Views have been generated
+ typedef enum e_views_initialization_state
+ {
+ VIEWS_UNINITIALIZED = 0,
+ VIEWS_INITIALIZING,
+ VIEWS_INITIALIZED,
+ } EViewsInitializationState;
+
+ bool mBuildViewsOnInit;
+ EViewsInitializationState mViewsInitialized; // Whether views have been generated
};
diff --git a/indra/newview/lllocationinputctrl.cpp b/indra/newview/lllocationinputctrl.cpp
index fd418afd2c..83195e9e3f 100644
--- a/indra/newview/lllocationinputctrl.cpp
+++ b/indra/newview/lllocationinputctrl.cpp
@@ -296,7 +296,6 @@ LLLocationInputCtrl::LLLocationInputCtrl(const LLLocationInputCtrl::Params& p)
LLButton::Params maturity_button = p.maturity_button;
mMaturityButton = LLUICtrlFactory::create<LLButton>(maturity_button);
addChild(mMaturityButton);
- mMaturityButton->setClickedCallback(boost::bind(&LLLocationInputCtrl::onMaturityButtonClicked, this));
LLButton::Params for_sale_button = p.for_sale_button;
for_sale_button.tool_tip = LLTrans::getString("LocationCtrlForSaleTooltip");
@@ -663,11 +662,6 @@ void LLLocationInputCtrl::onAgentParcelChange()
refresh();
}
-void LLLocationInputCtrl::onMaturityButtonClicked()
-{
- LLUI::getInstance()->mHelpImpl->showTopic(mMaturityHelpTopic);
-}
-
void LLLocationInputCtrl::onRegionBoundaryCrossed()
{
createNavMeshStatusListenerForCurrentRegion();
diff --git a/indra/newview/lllocationinputctrl.h b/indra/newview/lllocationinputctrl.h
index da71bab6c1..79dbe17982 100644
--- a/indra/newview/lllocationinputctrl.h
+++ b/indra/newview/lllocationinputctrl.h
@@ -160,7 +160,6 @@ private:
void onForSaleButtonClicked();
void onAddLandmarkButtonClicked();
void onAgentParcelChange();
- void onMaturityButtonClicked();
void onRegionBoundaryCrossed();
void onNavMeshStatusChange(const LLPathfindingNavMeshStatus &pNavMeshStatus);
// callbacks
diff --git a/indra/newview/lllogininstance.cpp b/indra/newview/lllogininstance.cpp
index 0f846c152a..fa53a21940 100644
--- a/indra/newview/lllogininstance.cpp
+++ b/indra/newview/lllogininstance.cpp
@@ -427,6 +427,7 @@ void LLLoginInstance::handleLoginSuccess(const LLSD& event)
LL_INFOS("LLLogin") << "LLLoginInstance::handleLoginSuccess" << LL_ENDL;
attemptComplete();
+ mRequestData.clear();
}
void LLLoginInstance::handleDisconnect(const LLSD& event)
diff --git a/indra/newview/llmutelist.cpp b/indra/newview/llmutelist.cpp
index 64df449c26..663a6071f7 100644
--- a/indra/newview/llmutelist.cpp
+++ b/indra/newview/llmutelist.cpp
@@ -169,6 +169,14 @@ LLMuteList::LLMuteList() :
gMessageSystem.callWhenReady(boost::bind(&LLMessageSystem::setHandlerFuncFast, _1,
_PREHASH_UseCachedMuteList, processUseCachedMuteList,
static_cast<void**>(NULL)));
+
+ // make sure mute list's instance gets initialized before we start any name requests
+ LLAvatarNameCache::getInstance()->setAccountNameChangedCallback([this](const LLUUID& id, const LLAvatarName& av_name)
+ {
+ // it would be better to just pass LLAvatarName instead of doing unnesssesary copies
+ // but this way is just more convinient
+ onAccountNameChanged(id, av_name.getUserName());
+ });
}
//-----------------------------------------------------------------------------
@@ -179,6 +187,11 @@ LLMuteList::~LLMuteList()
}
+void LLMuteList::cleanupSingleton()
+{
+ LLAvatarNameCache::getInstance()->setAccountNameChangedCallback(NULL);
+}
+
BOOL LLMuteList::isLinden(const std::string& name) const
{
std::string username = boost::replace_all_copy(name, ".", " ");
@@ -232,8 +245,8 @@ BOOL LLMuteList::add(const LLMute& mute, U32 flags)
LL_WARNS() << "Trying to self; ignored" << LL_ENDL;
return FALSE;
}
-
- S32 mute_list_limit = gSavedSettings.getS32("MuteListLimit");
+
+ static LLCachedControl<S32> mute_list_limit(gSavedSettings, "MuteListLimit", 1000);
if (getMutes().size() >= mute_list_limit)
{
LL_WARNS() << "Mute limit is reached; ignored" << LL_ENDL;
@@ -358,6 +371,10 @@ void LLMuteList::updateAdd(const LLMute& mute)
msg->addU32("MuteFlags", mute.mFlags);
gAgent.sendReliableMessage();
+ if (!mIsLoaded)
+ {
+ LL_WARNS() << "Added elements to non-initialized block list" << LL_ENDL;
+ }
mIsLoaded = TRUE; // why is this here? -MG
}
@@ -391,6 +408,8 @@ BOOL LLMuteList::remove(const LLMute& mute, U32 flags)
else
{
// The caller didn't pass any flags -- just remove the mute entry entirely.
+ // set flags to notify observers with (flag being present means that something is allowed)
+ localmute.mFlags = LLMute::flagAll;
}
// Always remove the entry from the set -- it will be re-added with new flags if necessary.
@@ -411,8 +430,8 @@ BOOL LLMuteList::remove(const LLMute& mute, U32 flags)
}
// Must be after erase.
+ notifyObservers();
notifyObserversDetailed(localmute);
- setLoaded(); // why is this here? -MG
}
else
{
@@ -425,8 +444,8 @@ BOOL LLMuteList::remove(const LLMute& mute, U32 flags)
updateRemove(mute);
mLegacyMutes.erase(legacy_it);
// Must be after erase.
+ notifyObservers();
notifyObserversDetailed(mute);
- setLoaded(); // why is this here? -MG
}
}
@@ -584,6 +603,19 @@ BOOL LLMuteList::loadFromFile(const std::string& filename)
}
fclose(fp);
setLoaded();
+
+ // server does not maintain up-to date account names (not display names!)
+ // in this list, so it falls to viewer.
+ pending_names_t::iterator iter = mPendingAgentNameUpdates.begin();
+ pending_names_t::iterator end = mPendingAgentNameUpdates.end();
+ while (iter != end)
+ {
+ // this will send updates to server, make sure mIsLoaded is set
+ onAccountNameChanged(iter->first, iter->second);
+ iter++;
+ }
+ mPendingAgentNameUpdates.clear();
+
return TRUE;
}
@@ -767,6 +799,48 @@ void LLMuteList::onFileMuteList(void** user_data, S32 error_code, LLExtStat ext_
delete local_filename_and_path;
}
+void LLMuteList::onAccountNameChanged(const LLUUID& id, const std::string& username)
+{
+ if (mIsLoaded)
+ {
+ LLMute mute(id, username, LLMute::AGENT);
+ mute_set_t::iterator mute_it = mMutes.find(mute);
+ if (mute_it != mMutes.end()
+ && mute_it->mName != mute.mName
+ && mute_it->mType == LLMute::AGENT) // just in case, it is std::set, not map
+ {
+ // existing mute, but name changed, copy data
+ mute.mFlags = mute_it->mFlags;
+
+ // erase old variant
+ mMutes.erase(mute_it);
+
+ // (re)add the mute entry.
+ {
+ std::pair<mute_set_t::iterator, bool> result = mMutes.insert(mute);
+ if (result.second)
+ {
+ LL_INFOS() << "Muting " << mute.mName << " id " << mute.mID << " flags " << mute.mFlags << LL_ENDL;
+ updateAdd(mute);
+ // Do not notify observers here, observers do not know or need to handle name changes
+ // Example: block list considers notifyObserversDetailed as a selection update;
+ // Various chat/voice statuses care only about id and flags
+ // Since apropriate update time for account names is considered to be in 'hours' it is
+ // fine not to update UI (will be fine after restart or couple other changes)
+
+ }
+ }
+ }
+ }
+ else
+ {
+ // Delay update until we load file
+ // Ex: Buddies list can arrive too early since we prerequest
+ // names from Buddies list before we load blocklist
+ mPendingAgentNameUpdates[id] = username;
+ }
+}
+
void LLMuteList::addObserver(LLMuteListObserver* observer)
{
mObservers.insert(observer);
diff --git a/indra/newview/llmutelist.h b/indra/newview/llmutelist.h
index f2fcf3dbb3..0d426fbd48 100644
--- a/indra/newview/llmutelist.h
+++ b/indra/newview/llmutelist.h
@@ -73,6 +73,7 @@ class LLMuteList : public LLSingleton<LLMuteList>
{
LLSINGLETON(LLMuteList);
~LLMuteList();
+ /*virtual*/ void cleanupSingleton();
public:
// reasons for auto-unmuting a resident
enum EAutoReason
@@ -131,6 +132,7 @@ private:
static void processUseCachedMuteList(LLMessageSystem* msg, void**);
static void onFileMuteList(void** user_data, S32 code, LLExtStat ext_status);
+ void onAccountNameChanged(const LLUUID& id, const std::string& username);
private:
struct compare_by_name
@@ -155,7 +157,9 @@ private:
};
typedef std::set<LLMute, compare_by_id> mute_set_t;
mute_set_t mMutes;
-
+ typedef std::map<LLUUID, std::string> pending_names_t;
+ pending_names_t mPendingAgentNameUpdates;
+
typedef std::set<std::string> string_set_t;
string_set_t mLegacyMutes;
diff --git a/indra/newview/lloutputmonitorctrl.cpp b/indra/newview/lloutputmonitorctrl.cpp
index e9fe493d7e..7129641c20 100644
--- a/indra/newview/lloutputmonitorctrl.cpp
+++ b/indra/newview/lloutputmonitorctrl.cpp
@@ -312,10 +312,14 @@ void LLOutputMonitorCtrl::setSpeakerId(const LLUUID& speaker_id, const LLUUID& s
}
}
-void LLOutputMonitorCtrl::onChange()
+void LLOutputMonitorCtrl::onChangeDetailed(const LLMute& mute)
{
- // check only blocking on voice. EXT-3542
- mIsMuted = LLMuteList::getInstance()->isMuted(mSpeakerId, LLMute::flagVoiceChat);
+ if (mute.mID == mSpeakerId)
+ {
+ // Check only blocking on voice.
+ // Logic goes in reverse, if flag is set, action is allowed
+ mIsMuted = !(LLMute::flagVoiceChat & mute.mFlags);
+ }
}
// virtual
diff --git a/indra/newview/lloutputmonitorctrl.h b/indra/newview/lloutputmonitorctrl.h
index 98966d39ee..e80745e1df 100644
--- a/indra/newview/lloutputmonitorctrl.h
+++ b/indra/newview/lloutputmonitorctrl.h
@@ -105,7 +105,8 @@ public:
void setSpeakerId(const LLUUID& speaker_id, const LLUUID& session_id = LLUUID::null, bool show_other_participants_speaking = false);
//called by mute list
- virtual void onChange();
+ virtual void onChange() {};
+ virtual void onChangeDetailed(const LLMute& mute);
/**
* Implementation of LLSpeakingIndicator interface.
diff --git a/indra/newview/llpanelgroupnotices.cpp b/indra/newview/llpanelgroupnotices.cpp
index 7373c7412c..c63d04cd55 100644
--- a/indra/newview/llpanelgroupnotices.cpp
+++ b/indra/newview/llpanelgroupnotices.cpp
@@ -201,9 +201,12 @@ std::string build_notice_date(const U32& the_time)
time(&t);
}
- std::string dateStr = "["+LLTrans::getString("LTimeMthNum")+"]/["
- +LLTrans::getString("LTimeDay")+"]/["
- +LLTrans::getString("LTimeYear")+"]";
+ std::string dateStr = "["+ LLTrans::getString("LTimeYear") + "]/["
+ + LLTrans::getString("LTimeMthNum") + "]/["
+ + LLTrans::getString("LTimeDay") + "] ["
+ + LLTrans::getString("LTimeHour") + "]:["
+ + LLTrans::getString("LTimeMin") + "]:["
+ + LLTrans::getString("LTimeSec") + "]";
LLSD substitution;
substitution["datetime"] = (S32) t;
LLStringUtil::format (dateStr, substitution);
diff --git a/indra/newview/llpanellogin.cpp b/indra/newview/llpanellogin.cpp
index a19182b01e..4f60703488 100644
--- a/indra/newview/llpanellogin.cpp
+++ b/indra/newview/llpanellogin.cpp
@@ -1337,8 +1337,10 @@ void LLPanelLogin::onSelectServer()
switch (index)
{
case 0: // last location
+ LLStartUp::setStartSLURL(LLSLURL(LLSLURL::SIM_LOCATION_LAST));
+ break;
case 1: // home location
- // do nothing - these are grid-agnostic locations
+ LLStartUp::setStartSLURL(LLSLURL(LLSLURL::SIM_LOCATION_HOME));
break;
default:
diff --git a/indra/newview/llpanelmaininventory.cpp b/indra/newview/llpanelmaininventory.cpp
index 02cd22c307..fbc1b80857 100644
--- a/indra/newview/llpanelmaininventory.cpp
+++ b/indra/newview/llpanelmaininventory.cpp
@@ -165,6 +165,7 @@ BOOL LLPanelMainInventory::postBuild()
recent_items_panel->setSinceLogoff(TRUE);
recent_items_panel->setSortOrder(LLInventoryFilter::SO_DATE);
recent_items_panel->setShowFolderState(LLInventoryFilter::SHOW_NON_EMPTY_FOLDERS);
+ recent_items_panel->setFilterLinks(LLInventoryFilter::FILTERLINK_EXCLUDE_LINKS);
LLInventoryFilter& recent_filter = recent_items_panel->getFilter();
recent_filter.setFilterObjectTypes(recent_filter.getFilterObjectTypes() & ~(0x1 << LLInventoryType::IT_CATEGORY));
recent_filter.setEmptyLookupMessage("InventoryNoMatchingRecentItems");
diff --git a/indra/newview/llpaneloutfitedit.cpp b/indra/newview/llpaneloutfitedit.cpp
index 1d87aa6f5d..28a020870f 100644
--- a/indra/newview/llpaneloutfitedit.cpp
+++ b/indra/newview/llpaneloutfitedit.cpp
@@ -563,6 +563,8 @@ BOOL LLPanelOutfitEdit::postBuild()
mGearMenuBtn->setMenu(mGearMenu);
mSaveComboBtn.reset(new LLSaveOutfitComboBtn(this));
+
+ onOutfitChanging(gAgentWearables.isCOFChangeInProgress());
return TRUE;
}
@@ -703,6 +705,10 @@ void LLPanelOutfitEdit::onListViewFilterCommitted(LLUICtrl* ctrl)
S32 curr_filter_type = mListViewFilterCmbBox->getCurrentIndex();
if (curr_filter_type < 0) return;
+ if (curr_filter_type >= LVIT_SHAPE)
+ {
+ mWearableItemsList->setMenuWearableType(LLWearableType::EType(curr_filter_type - LVIT_SHAPE));
+ }
mWearableListManager->setFilterCollector(mListViewItemTypes[curr_filter_type]->collector);
}
@@ -1282,6 +1288,7 @@ void LLPanelOutfitEdit::showFilteredWearablesListView(LLWearableType::EType type
//e_list_view_item_type implicitly contains LLWearableType::EType starting from LVIT_SHAPE
applyListViewFilter(static_cast<EListViewItemType>(LVIT_SHAPE + type));
+ mWearableItemsList->setMenuWearableType(type);
}
static void update_status_widget_rect(LLView * widget, S32 right_border)
diff --git a/indra/newview/llpanelpermissions.cpp b/indra/newview/llpanelpermissions.cpp
index ef16427713..3e770958da 100644
--- a/indra/newview/llpanelpermissions.cpp
+++ b/indra/newview/llpanelpermissions.cpp
@@ -972,13 +972,45 @@ void LLPanelPermissions::refresh()
getChildView("clickaction")->setEnabled(is_perm_modify && is_nonpermanent_enforced && all_volume);
}
+// Shorten name if it doesn't fit into max_pixels of two lines
+void shorten_name(std::string &name, const LLStyle::Params& style_params, S32 max_pixels)
+{
+ const LLFontGL* font = style_params.font();
+
+ LLWString wline = utf8str_to_wstring(name);
+ // panel supports two lines long names
+ S32 segment_length = font->maxDrawableChars(wline.c_str(), max_pixels, wline.length(), LLFontGL::WORD_BOUNDARY_IF_POSSIBLE);
+ if (segment_length == wline.length())
+ {
+ // no work needed
+ return;
+ }
+
+ S32 first_line_length = segment_length;
+ segment_length = font->maxDrawableChars(wline.substr(first_line_length).c_str(), max_pixels, wline.length(), LLFontGL::ANYWHERE);
+ if (segment_length + first_line_length == wline.length())
+ {
+ // no work needed
+ return;
+ }
+
+ // name does not fit, cut it, add ...
+ const LLWString dots_pad(utf8str_to_wstring(std::string("....")));
+ S32 elipses_width = font->getWidthF32(dots_pad.c_str());
+ segment_length = font->maxDrawableChars(wline.substr(first_line_length).c_str(), max_pixels - elipses_width, wline.length(), LLFontGL::ANYWHERE);
+
+ name = name.substr(0, segment_length + first_line_length) + std::string("...");
+}
+
void LLPanelPermissions::updateOwnerName(const LLUUID& owner_id, const LLAvatarName& owner_name, const LLStyle::Params& style_params)
{
if (mOwnerCacheConnection.connected())
{
mOwnerCacheConnection.disconnect();
}
- mLabelOwnerName->setText(owner_name.getCompleteName(), style_params);
+ std::string name = owner_name.getCompleteName();
+ shorten_name(name, style_params, mLabelOwnerName->getLocalRect().getWidth());
+ mLabelOwnerName->setText(name, style_params);
}
void LLPanelPermissions::updateCreatorName(const LLUUID& creator_id, const LLAvatarName& creator_name, const LLStyle::Params& style_params)
@@ -987,7 +1019,9 @@ void LLPanelPermissions::updateCreatorName(const LLUUID& creator_id, const LLAva
{
mCreatorCacheConnection.disconnect();
}
- mLabelCreatorName->setText(creator_name.getCompleteName(), style_params);
+ std::string name = creator_name.getCompleteName();
+ shorten_name(name, style_params, mLabelCreatorName->getLocalRect().getWidth());
+ mLabelCreatorName->setText(name, style_params);
}
// static
diff --git a/indra/newview/llpreviewscript.cpp b/indra/newview/llpreviewscript.cpp
index 7a68d1e270..5e81fa6402 100644
--- a/indra/newview/llpreviewscript.cpp
+++ b/indra/newview/llpreviewscript.cpp
@@ -544,9 +544,6 @@ void LLScriptEdCore::initMenu()
menuItem = getChild<LLMenuItemCallGL>("Go to line...");
menuItem->setClickCallback(boost::bind(&LLFloaterGotoLine::show, this));
- menuItem = getChild<LLMenuItemCallGL>("Help...");
- menuItem->setClickCallback(boost::bind(&LLScriptEdCore::onBtnHelp, this));
-
menuItem = getChild<LLMenuItemCallGL>("Keyword Help...");
menuItem->setClickCallback(boost::bind(&LLScriptEdCore::onBtnDynamicHelp, this));
@@ -882,11 +879,6 @@ bool LLScriptEdCore::handleSaveChangesDialog(const LLSD& notification, const LLS
return false;
}
-void LLScriptEdCore::onBtnHelp()
-{
- LLUI::getInstance()->mHelpImpl->showTopic(HELP_LSL_PORTAL_TOPIC);
-}
-
void LLScriptEdCore::onBtnDynamicHelp()
{
LLFloater* live_help_floater = mLiveHelpHandle.get();
diff --git a/indra/newview/llpreviewscript.h b/indra/newview/llpreviewscript.h
index 74e4c00d43..3cf22a0e6e 100644
--- a/indra/newview/llpreviewscript.h
+++ b/indra/newview/llpreviewscript.h
@@ -144,7 +144,6 @@ public:
void setItemRemoved(bool script_removed){mScriptRemoved = script_removed;};
private:
- void onBtnHelp();
void onBtnDynamicHelp();
void onBtnUndoChanges();
diff --git a/indra/newview/llpreviewtexture.cpp b/indra/newview/llpreviewtexture.cpp
index 9d8be4b2fe..1e91da529c 100644
--- a/indra/newview/llpreviewtexture.cpp
+++ b/indra/newview/llpreviewtexture.cpp
@@ -401,7 +401,7 @@ void LLPreviewTexture::onFileLoadedForSave(BOOL success,
{
const U32 ext_length = 3;
std::string extension = self->mSaveFileName.substr( self->mSaveFileName.length() - ext_length);
-
+ LLStringUtil::toLower(extension);
// We only support saving in PNG or TGA format
LLPointer<LLImageFormatted> image;
if(extension == "png")
diff --git a/indra/newview/llprogressview.cpp b/indra/newview/llprogressview.cpp
index 3e3ab3a676..416848f9af 100644
--- a/indra/newview/llprogressview.cpp
+++ b/indra/newview/llprogressview.cpp
@@ -431,9 +431,10 @@ void LLProgressView::initLogos()
// 108x41
icon_width = 74;
+ icon_height = default_height;
loadLogo(temp_str + "vivox_logo.png",
image_codec,
- LLRect(texture_start_x, texture_start_y + default_height, texture_start_x + icon_width, texture_start_y),
+ LLRect(texture_start_x, texture_start_y + icon_height, texture_start_x + icon_width, texture_start_y),
default_clip,
default_clip);
}
diff --git a/indra/newview/llscenemonitor.cpp b/indra/newview/llscenemonitor.cpp
index 2c0c38dc75..3c9ce6b752 100644
--- a/indra/newview/llscenemonitor.cpp
+++ b/indra/newview/llscenemonitor.cpp
@@ -526,8 +526,7 @@ void LLSceneMonitor::fetchQueryResult()
//dump results to a file _scene_xmonitor_results.csv
void LLSceneMonitor::dumpToFile(std::string file_name)
-{ using namespace LLTrace;
-
+{
if (!hasResults()) return;
LL_INFOS("SceneMonitor") << "Saving scene load stats to " << file_name << LL_ENDL;
@@ -536,7 +535,7 @@ void LLSceneMonitor::dumpToFile(std::string file_name)
os << std::setprecision(10);
- PeriodicRecording& scene_load_recording = mSceneLoadRecording.getResults();
+ LLTrace::PeriodicRecording& scene_load_recording = mSceneLoadRecording.getResults();
const U32 frame_count = scene_load_recording.getNumRecordedPeriods();
F64Seconds frame_time;
@@ -558,7 +557,7 @@ void LLSceneMonitor::dumpToFile(std::string file_name)
os << '\n';
- typedef StatType<CountAccumulator> trace_count;
+ typedef LLTrace::StatType<LLTrace::CountAccumulator> trace_count;
for (auto& it : trace_count::instance_snapshot())
{
std::ostringstream row;
@@ -576,7 +575,7 @@ void LLSceneMonitor::dumpToFile(std::string file_name)
for (S32 frame = 1; frame <= frame_count; frame++)
{
- Recording& recording = scene_load_recording.getPrevRecording(frame_count - frame);
+ LLTrace::Recording& recording = scene_load_recording.getPrevRecording(frame_count - frame);
samples += recording.getSampleCount(it);
row << ", " << recording.getSum(it);
}
@@ -589,7 +588,7 @@ void LLSceneMonitor::dumpToFile(std::string file_name)
}
}
- typedef StatType<EventAccumulator> trace_event;
+ typedef LLTrace::StatType<LLTrace::EventAccumulator> trace_event;
for (auto& it : trace_event::instance_snapshot())
{
@@ -607,7 +606,7 @@ void LLSceneMonitor::dumpToFile(std::string file_name)
for (S32 frame = 1; frame <= frame_count; frame++)
{
- Recording& recording = scene_load_recording.getPrevRecording(frame_count - frame);
+ LLTrace::Recording& recording = scene_load_recording.getPrevRecording(frame_count - frame);
samples += recording.getSampleCount(it);
F64 mean = recording.getMean(it);
if (llisnan(mean))
@@ -628,7 +627,7 @@ void LLSceneMonitor::dumpToFile(std::string file_name)
}
}
- typedef StatType<SampleAccumulator> trace_sample;
+ typedef LLTrace::StatType<LLTrace::SampleAccumulator> trace_sample;
for (auto& it : trace_sample::instance_snapshot())
{
@@ -646,7 +645,7 @@ void LLSceneMonitor::dumpToFile(std::string file_name)
for (S32 frame = 1; frame <= frame_count; frame++)
{
- Recording& recording = scene_load_recording.getPrevRecording(frame_count - frame);
+ LLTrace::Recording& recording = scene_load_recording.getPrevRecording(frame_count - frame);
samples += recording.getSampleCount(it);
F64 mean = recording.getMean(it);
if (llisnan(mean))
@@ -667,7 +666,7 @@ void LLSceneMonitor::dumpToFile(std::string file_name)
}
}
- typedef StatType<MemAccumulator> trace_mem;
+ typedef LLTrace::StatType<LLTrace::MemAccumulator> trace_mem;
for (auto& it : trace_mem::instance_snapshot())
{
os << it.getName() << "(KiB)";
diff --git a/indra/newview/llsidepanelappearance.cpp b/indra/newview/llsidepanelappearance.cpp
index 6e2b4a00fc..48151c17ea 100644
--- a/indra/newview/llsidepanelappearance.cpp
+++ b/indra/newview/llsidepanelappearance.cpp
@@ -140,6 +140,8 @@ BOOL LLSidepanelAppearance::postBuild()
setVisibleCallback(boost::bind(&LLSidepanelAppearance::onVisibilityChanged,this,_2));
+ setWearablesLoading(gAgentWearables.isCOFChangeInProgress());
+
return TRUE;
}
diff --git a/indra/newview/llspatialpartition.cpp b/indra/newview/llspatialpartition.cpp
index 8fc2405f0a..0186c1943f 100644
--- a/indra/newview/llspatialpartition.cpp
+++ b/indra/newview/llspatialpartition.cpp
@@ -2253,52 +2253,91 @@ void renderBoundingBox(LLDrawable* drawable, BOOL set_color = TRUE)
}
}
-void renderNormals(LLDrawable* drawablep)
+void renderNormals(LLDrawable *drawablep)
{
- LLVertexBuffer::unbind();
+ if (!drawablep->isVisible())
+ return;
- LLVOVolume* vol = drawablep->getVOVolume();
- if (vol)
- {
- LLVolume* volume = vol->getVolume();
- gGL.pushMatrix();
- gGL.multMatrix((F32*) vol->getRelativeXform().mMatrix);
-
- gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+ LLVertexBuffer::unbind();
- LLVector4a scale(gSavedSettings.getF32("RenderDebugNormalScale"));
+ LLVOVolume *vol = drawablep->getVOVolume();
- for (S32 i = 0; i < volume->getNumVolumeFaces(); ++i)
- {
- const LLVolumeFace& face = volume->getVolumeFace(i);
+ if (vol)
+ {
+ LLVolume *volume = vol->getVolume();
- for (S32 j = 0; j < face.mNumVertices; ++j)
- {
- gGL.begin(LLRender::LINES);
- LLVector4a n,p;
-
- n.setMul(face.mNormals[j], scale);
- p.setAdd(face.mPositions[j], n);
-
- gGL.diffuseColor4f(1,1,1,1);
- gGL.vertex3fv(face.mPositions[j].getF32ptr());
- gGL.vertex3fv(p.getF32ptr());
-
- if (face.mTangents)
- {
- n.setMul(face.mTangents[j], scale);
- p.setAdd(face.mPositions[j], n);
-
- gGL.diffuseColor4f(0,1,1,1);
- gGL.vertex3fv(face.mPositions[j].getF32ptr());
- gGL.vertex3fv(p.getF32ptr());
- }
- gGL.end();
- }
- }
+ // Drawable's normals & tangents are stored in model space, i.e. before any scaling is applied.
+ //
+ // SL-13490, using pos + normal to compute the 2nd vertex of a normal line segment doesn't
+ // work when there's a non-uniform scale in the mix. Normals require MVP-inverse-transpose
+ // transform. We get that effect here by pre-applying the inverse scale (twice, because
+ // one forward scale will be re-applied via the MVP in the vertex shader)
- gGL.popMatrix();
- }
+ LLVector3 scale_v3 = vol->getScale();
+ float scale_len = scale_v3.length();
+ LLVector4a obj_scale(scale_v3.mV[VX], scale_v3.mV[VY], scale_v3.mV[VZ]);
+ obj_scale.normalize3();
+
+ // Normals &tangent line segments get scaled along with the object. Divide by scale length
+ // to keep the as-viewed lengths (relatively) constant with the debug setting length
+ float draw_length = gSavedSettings.getF32("RenderDebugNormalScale") / scale_len;
+
+ // Create inverse-scale vector for normals
+ LLVector4a inv_scale(1.0 / scale_v3.mV[VX], 1.0 / scale_v3.mV[VY], 1.0 / scale_v3.mV[VZ]);
+ inv_scale.mul(inv_scale); // Squared, to apply inverse scale twice
+ inv_scale.normalize3fast();
+
+ gGL.pushMatrix();
+ gGL.multMatrix((F32 *) vol->getRelativeXform().mMatrix);
+
+ gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+
+ for (S32 i = 0; i < volume->getNumVolumeFaces(); ++i)
+ {
+ const LLVolumeFace &face = volume->getVolumeFace(i);
+
+ gGL.flush();
+ gGL.diffuseColor4f(1, 1, 0, 1);
+ gGL.begin(LLRender::LINES);
+ for (S32 j = 0; j < face.mNumVertices; ++j)
+ {
+ LLVector4a n, p;
+
+ n.setMul(face.mNormals[j], 1.0);
+ n.mul(inv_scale); // Pre-scale normal, so it's left with an inverse-transpose xform after MVP
+ n.normalize3fast();
+ n.mul(draw_length);
+ p.setAdd(face.mPositions[j], n);
+
+ gGL.vertex3fv(face.mPositions[j].getF32ptr());
+ gGL.vertex3fv(p.getF32ptr());
+ }
+ gGL.end();
+
+ // Tangents are simple vectors and do not require reorientation via pre-scaling
+ if (face.mTangents)
+ {
+ gGL.flush();
+ gGL.diffuseColor4f(0, 1, 1, 1);
+ gGL.begin(LLRender::LINES);
+ for (S32 j = 0; j < face.mNumVertices; ++j)
+ {
+ LLVector4a t, p;
+
+ t.setMul(face.mTangents[j], 1.0f);
+ t.normalize3fast();
+ t.mul(draw_length);
+ p.setAdd(face.mPositions[j], t);
+
+ gGL.vertex3fv(face.mPositions[j].getF32ptr());
+ gGL.vertex3fv(p.getF32ptr());
+ }
+ gGL.end();
+ }
+ }
+
+ gGL.popMatrix();
+ }
}
S32 get_physics_detail(const LLVolumeParams& volume_params, const LLVector3& scale)
diff --git a/indra/newview/lltexturecache.cpp b/indra/newview/lltexturecache.cpp
index 6211d0ce3b..a9f19dc32d 100644
--- a/indra/newview/lltexturecache.cpp
+++ b/indra/newview/lltexturecache.cpp
@@ -52,7 +52,8 @@ const S32 TEXTURE_CACHE_ENTRY_SIZE = FIRST_PACKET_SIZE;//1024;
const F32 TEXTURE_CACHE_PURGE_AMOUNT = .20f; // % amount to reduce the cache by when it exceeds its limit
const F32 TEXTURE_CACHE_LRU_SIZE = .10f; // % amount for LRU list (low overhead to regenerate)
const S32 TEXTURE_FAST_CACHE_ENTRY_OVERHEAD = sizeof(S32) * 4; //w, h, c, level
-const S32 TEXTURE_FAST_CACHE_ENTRY_SIZE = 16 * 16 * 4 + TEXTURE_FAST_CACHE_ENTRY_OVERHEAD;
+const S32 TEXTURE_FAST_CACHE_DATA_SIZE = 16 * 16 * 4;
+const S32 TEXTURE_FAST_CACHE_ENTRY_SIZE = TEXTURE_FAST_CACHE_DATA_SIZE + TEXTURE_FAST_CACHE_ENTRY_OVERHEAD;
const F32 TEXTURE_LAZY_PURGE_TIME_LIMIT = .004f; // 4ms. Would be better to autoadjust, but there is a major cache rework in progress.
class LLTextureCacheWorker : public LLWorkerClass
@@ -2068,7 +2069,9 @@ LLPointer<LLImageRaw> LLTextureCache::readFromFastCache(const LLUUID& id, S32& d
}
S32 image_size = head[0] * head[1] * head[2];
- if(!image_size) //invalid
+ if(image_size <= 0
+ || image_size > TEXTURE_FAST_CACHE_DATA_SIZE
+ || head[3] < 0) //invalid
{
closeFastCache();
return NULL;
@@ -2090,46 +2093,6 @@ LLPointer<LLImageRaw> LLTextureCache::readFromFastCache(const LLUUID& id, S32& d
return raw;
}
-#if LL_WINDOWS
-
-static const U32 STATUS_MSC_EXCEPTION = 0xE06D7363; // compiler specific
-
-U32 exception_dupe_filter(U32 code, struct _EXCEPTION_POINTERS *exception_infop)
-{
- if (code == STATUS_MSC_EXCEPTION)
- {
- // C++ exception, go on
- return EXCEPTION_CONTINUE_SEARCH;
- }
- else
- {
- // handle it
- return EXCEPTION_EXECUTE_HANDLER;
- }
-}
-
-//due to unwinding
-void dupe(LLPointer<LLImageRaw> &raw)
-{
- raw = raw->duplicate();
-}
-
-void logExceptionDupplicate(LLPointer<LLImageRaw> &raw)
-{
- __try
- {
- dupe(raw);
- }
- __except (exception_dupe_filter(GetExceptionCode(), GetExceptionInformation()))
- {
- // convert to C++ styled exception
- char integer_string[32];
- sprintf(integer_string, "SEH, code: %lu\n", GetExceptionCode());
- throw std::exception(integer_string);
- }
-}
-#endif
-
//return the fast cache location
bool LLTextureCache::writeToFastCache(LLUUID image_id, S32 id, LLPointer<LLImageRaw> raw, S32 discardlevel)
{
@@ -2146,8 +2109,9 @@ bool LLTextureCache::writeToFastCache(LLUUID image_id, S32 id, LLPointer<LLImage
c = raw->getComponents();
S32 i = 0 ;
-
- while(((w >> i) * (h >> i) * c) > TEXTURE_FAST_CACHE_ENTRY_SIZE - TEXTURE_FAST_CACHE_ENTRY_OVERHEAD)
+
+ // Search for a discard level that will fit into fast cache
+ while(((w >> i) * (h >> i) * c) > TEXTURE_FAST_CACHE_DATA_SIZE)
{
++i ;
}
@@ -2159,30 +2123,7 @@ bool LLTextureCache::writeToFastCache(LLUUID image_id, S32 id, LLPointer<LLImage
if(w * h *c > 0) //valid
{
// Make a duplicate to keep the original raw image untouched.
- // Might be good idea to do a copy during writeToCache() call instead of here
- try
- {
-#if LL_WINDOWS
- // Temporary diagnostics for scale/duplicate crash
- logExceptionDupplicate(raw);
-#else
- raw = raw->duplicate();
-#endif
- }
- catch (...)
- {
- removeFromCache(image_id);
- LL_ERRS() << "Failed to cache image: " << image_id
- << " local id: " << id
- << " Exception: " << boost::current_exception_diagnostic_information()
- << " Image new width: " << w
- << " Image new height: " << h
- << " Image new components: " << c
- << " Image discard difference: " << i
- << LL_ENDL;
-
- return false;
- }
+ raw = raw->duplicate();
if (raw->isBufferInvalid())
{
diff --git a/indra/newview/lltextureview.cpp b/indra/newview/lltextureview.cpp
index 1c4187d30f..7a0f69fed5 100644
--- a/indra/newview/lltextureview.cpp
+++ b/indra/newview/lltextureview.cpp
@@ -423,8 +423,8 @@ void LLAvatarTexBar::draw()
LLColor4 color;
U32 line_num = 1;
- for (LLAvatarAppearanceDefines::LLAvatarAppearanceDictionary::BakedTextures::const_iterator baked_iter = LLAvatarAppearanceDefines::LLAvatarAppearanceDictionary::getInstance()->getBakedTextures().begin();
- baked_iter != LLAvatarAppearanceDefines::LLAvatarAppearanceDictionary::getInstance()->getBakedTextures().end();
+ for (LLAvatarAppearanceDefines::LLAvatarAppearanceDictionary::BakedTextures::const_iterator baked_iter = LLAvatarAppearance::getDictionary()->getBakedTextures().begin();
+ baked_iter != LLAvatarAppearance::getDictionary()->getBakedTextures().end();
++baked_iter)
{
const LLAvatarAppearanceDefines::EBakedTextureIndex baked_index = baked_iter->first;
diff --git a/indra/newview/llviewerassetupload.cpp b/indra/newview/llviewerassetupload.cpp
index d53cc3f745..bc07821ccd 100644
--- a/indra/newview/llviewerassetupload.cpp
+++ b/indra/newview/llviewerassetupload.cpp
@@ -316,24 +316,25 @@ bool LLResourceUploadInfo::findAssetTypeOfExtension(const std::string& exten, LL
bool LLResourceUploadInfo::findAssetTypeAndCodecOfExtension(const std::string& exten, LLAssetType::EType& asset_type, U32& codec, bool bulk_upload)
{
bool succ = false;
-
- codec = LLImageBase::getCodecFromExtension(exten);
+ std::string exten_lc(exten);
+ LLStringUtil::toLower(exten_lc);
+ codec = LLImageBase::getCodecFromExtension(exten_lc);
if (codec != IMG_CODEC_INVALID)
{
asset_type = LLAssetType::AT_TEXTURE;
succ = true;
}
- else if (exten == "wav")
+ else if (exten_lc == "wav")
{
asset_type = LLAssetType::AT_SOUND;
succ = true;
}
- else if (exten == "anim")
+ else if (exten_lc == "anim")
{
asset_type = LLAssetType::AT_ANIMATION;
succ = true;
}
- else if (!bulk_upload && (exten == "bvh"))
+ else if (!bulk_upload && (exten_lc == "bvh"))
{
asset_type = LLAssetType::AT_ANIMATION;
succ = true;
diff --git a/indra/newview/llviewerjoystick.cpp b/indra/newview/llviewerjoystick.cpp
index 491ad7e3b2..e35cb26ce1 100644
--- a/indra/newview/llviewerjoystick.cpp
+++ b/indra/newview/llviewerjoystick.cpp
@@ -36,10 +36,19 @@
#include "lltoolmgr.h"
#include "llselectmgr.h"
#include "llviewermenu.h"
+#include "llviewerwindow.h"
+#include "llwindow.h"
#include "llagent.h"
#include "llagentcamera.h"
#include "llfocusmgr.h"
+#if LL_WINDOWS && !LL_MESA_HEADLESS
+// Require DirectInput version 8
+#define DIRECTINPUT_VERSION 0x0800
+
+#include <dinput.h>
+#endif
+
// ----------------------------------------------------------------------------
// Constants
@@ -62,6 +71,7 @@ F32 LLViewerJoystick::sDelta[] = {0,0,0,0,0,0,0};
#define MAX_SPACENAVIGATOR_INPUT 3000.0f
#define MAX_JOYSTICK_INPUT_VALUE MAX_SPACENAVIGATOR_INPUT
+
#if LIB_NDOF
std::ostream& operator<<(std::ostream& out, NDOF_Device* ptr)
{
@@ -99,6 +109,126 @@ std::ostream& operator<<(std::ostream& out, NDOF_Device* ptr)
}
#endif // LIB_NDOF
+
+#if LL_WINDOWS && !LL_MESA_HEADLESS
+// this should reflect ndof and set axises, see ndofdev_win.cpp from ndof package
+BOOL CALLBACK EnumObjectsCallback(const DIDEVICEOBJECTINSTANCE* inst, VOID* user_data)
+{
+ if (inst->dwType & DIDFT_AXIS)
+ {
+ LPDIRECTINPUTDEVICE8 device = *((LPDIRECTINPUTDEVICE8 *)user_data);
+ DIPROPRANGE diprg;
+ diprg.diph.dwSize = sizeof(DIPROPRANGE);
+ diprg.diph.dwHeaderSize = sizeof(DIPROPHEADER);
+ diprg.diph.dwHow = DIPH_BYID;
+ diprg.diph.dwObj = inst->dwType; // specify the enumerated axis
+
+ // Set the range for the axis
+ diprg.lMin = (long)-MAX_JOYSTICK_INPUT_VALUE;
+ diprg.lMax = (long)+MAX_JOYSTICK_INPUT_VALUE;
+ HRESULT hr = device->SetProperty(DIPROP_RANGE, &diprg.diph);
+
+ if (FAILED(hr))
+ {
+ return DIENUM_STOP;
+ }
+ }
+
+ return DIENUM_CONTINUE;
+}
+
+BOOL CALLBACK di8_devices_callback(LPCDIDEVICEINSTANCE device_instance_ptr, LPVOID pvRef)
+{
+ // Note: If a single device can function as more than one DirectInput
+ // device type, it is enumerated as each device type that it supports.
+ // Capable of detecting devices like Oculus Rift
+ if (device_instance_ptr)
+ {
+ std::string product_name = utf16str_to_utf8str(llutf16string(device_instance_ptr->tszProductName));
+
+ LLSD guid = LLViewerJoystick::getInstance()->getDeviceUUID();
+
+ bool init_device = false;
+ if (guid.isBinary())
+ {
+ std::vector<U8> bin_bucket = guid.asBinary();
+ init_device = memcmp(&bin_bucket[0], &device_instance_ptr->guidInstance, sizeof(GUID)) == 0;
+ }
+ else
+ {
+ // It might be better to init space navigator here, but if system doesn't has one,
+ // ndof will pick a random device, it is simpler to pick first device now to have an id
+ init_device = true;
+ }
+
+ if (init_device)
+ {
+ LL_DEBUGS("Joystick") << "Found and attempting to use device: " << product_name << LL_ENDL;
+ LPDIRECTINPUT8 di8_interface = *((LPDIRECTINPUT8 *)gViewerWindow->getWindow()->getDirectInput8());
+ LPDIRECTINPUTDEVICE8 device = NULL;
+
+ HRESULT status = di8_interface->CreateDevice(
+ device_instance_ptr->guidInstance, // REFGUID rguid,
+ &device, // LPDIRECTINPUTDEVICE * lplpDirectInputDevice,
+ NULL // LPUNKNOWN pUnkOuter
+ );
+
+ if (status == DI_OK)
+ {
+ // prerequisite for aquire()
+ LL_DEBUGS("Joystick") << "Device created" << LL_ENDL;
+ status = device->SetDataFormat(&c_dfDIJoystick); // c_dfDIJoystick2
+ }
+
+ if (status == DI_OK)
+ {
+ // set properties
+ LL_DEBUGS("Joystick") << "Format set" << LL_ENDL;
+ status = device->EnumObjects(EnumObjectsCallback, &device, DIDFT_ALL);
+ }
+
+ if (status == DI_OK)
+ {
+ LL_DEBUGS("Joystick") << "Properties updated" << LL_ENDL;
+
+ S32 size = sizeof(GUID);
+ LLSD::Binary data; //just an std::vector
+ data.resize(size);
+ memcpy(&data[0], &device_instance_ptr->guidInstance /*POD _GUID*/, size);
+ LLViewerJoystick::getInstance()->initDevice(&device, product_name, LLSD(data));
+ return DIENUM_STOP;
+ }
+ }
+ else
+ {
+ LL_DEBUGS("Joystick") << "Found device: " << product_name << LL_ENDL;
+ }
+ }
+ return DIENUM_CONTINUE;
+}
+
+// Windows guids
+// This is GUID2 so teoretically it can be memcpy copied into LLUUID
+void guid_from_string(GUID &guid, const std::string &input)
+{
+ CLSIDFromString(utf8str_to_utf16str(input).c_str(), &guid);
+}
+
+std::string string_from_guid(const GUID &guid)
+{
+ OLECHAR* guidString; //wchat
+ StringFromCLSID(guid, &guidString);
+
+ // use guidString...
+
+ std::string res = utf16str_to_utf8str(llutf16string(guidString));
+ // ensure memory is freed
+ ::CoTaskMemFree(guidString);
+
+ return res;
+}
+#endif
+
// -----------------------------------------------------------------------------
void LLViewerJoystick::updateEnabled(bool autoenable)
{
@@ -108,7 +238,8 @@ void LLViewerJoystick::updateEnabled(bool autoenable)
}
else
{
- if (isLikeSpaceNavigator() && autoenable)
+ // autoenable if user specifically chose this device
+ if (autoenable && (isLikeSpaceNavigator() || isDeviceUUIDSet()))
{
gSavedSettings.setBOOL("JoystickEnabled", TRUE );
}
@@ -144,7 +275,7 @@ NDOF_HotPlugResult LLViewerJoystick::HotPlugAddCallback(NDOF_Device *dev)
LLViewerJoystick* joystick(LLViewerJoystick::getInstance());
if (joystick->mDriverState == JDS_UNINITIALIZED)
{
- LL_INFOS("joystick") << "HotPlugAddCallback: will use device:" << LL_ENDL;
+ LL_INFOS("Joystick") << "HotPlugAddCallback: will use device:" << LL_ENDL;
ndof_dump(stderr, dev);
joystick->mNdofDev = dev;
joystick->mDriverState = JDS_INITIALIZED;
@@ -162,7 +293,7 @@ void LLViewerJoystick::HotPlugRemovalCallback(NDOF_Device *dev)
LLViewerJoystick* joystick(LLViewerJoystick::getInstance());
if (joystick->mNdofDev == dev)
{
- LL_INFOS("joystick") << "HotPlugRemovalCallback: joystick->mNdofDev="
+ LL_INFOS("Joystick") << "HotPlugRemovalCallback: joystick->mNdofDev="
<< joystick->mNdofDev << "; removed device:" << LL_ENDL;
ndof_dump(stderr, dev);
joystick->mDriverState = JDS_UNINITIALIZED;
@@ -189,6 +320,8 @@ LLViewerJoystick::LLViewerJoystick()
// factor in bandwidth? bandwidth = gViewerStats->mKBitStat
mPerfScale = 4000.f / gSysCPU.getMHz(); // hmm. why?
+
+ mLastDeviceUUID = LLSD::Integer(1);
}
// -----------------------------------------------------------------------------
@@ -207,12 +340,14 @@ void LLViewerJoystick::init(bool autoenable)
static bool libinit = false;
mDriverState = JDS_INITIALIZING;
+ loadDeviceIdFromSettings();
+
if (libinit == false)
{
// Note: The HotPlug callbacks are not actually getting called on Windows
if (ndof_libinit(HotPlugAddCallback,
HotPlugRemovalCallback,
- NULL))
+ gViewerWindow->getWindow()->getDirectInput8()))
{
mDriverState = JDS_UNINITIALIZED;
}
@@ -229,39 +364,33 @@ void LLViewerJoystick::init(bool autoenable)
if (libinit)
{
if (mNdofDev)
- {
- LL_DEBUGS("joystick") << "ndof_create() returned: " << mNdofDev << LL_ENDL;
- // Different joysticks will return different ranges of raw values.
- // Since we want to handle every device in the same uniform way,
- // we initialize the mNdofDev struct and we set the range
- // of values we would like to receive.
- //
- // HACK: On Windows, libndofdev passes our range to DI with a
- // SetProperty call. This works but with one notable exception, the
- // SpaceNavigator, who doesn't seem to care about the SetProperty
- // call. In theory, we should handle this case inside libndofdev.
- // However, the range we're setting here is arbitrary anyway,
- // so let's just use the SpaceNavigator range for our purposes.
- mNdofDev->axes_min = (long)-MAX_JOYSTICK_INPUT_VALUE;
- mNdofDev->axes_max = (long)+MAX_JOYSTICK_INPUT_VALUE;
-
- // libndofdev could be used to return deltas. Here we choose to
- // just have the absolute values instead.
- mNdofDev->absolute = 1;
-
- LL_DEBUGS("joystick") << "ndof_init_first() received: " << mNdofDev << LL_ENDL;
- // init & use the first suitable NDOF device found on the USB chain
- if (ndof_init_first(mNdofDev, NULL))
- {
- mDriverState = JDS_UNINITIALIZED;
- LL_WARNS("joystick") << "ndof_init_first FAILED" << LL_ENDL;
- ndof_dump_list(stderr);
- }
- else
- {
- mDriverState = JDS_INITIALIZED;
- }
- LL_DEBUGS("joystick") << "ndof_init_first() left: " << mNdofDev << LL_ENDL;
+ {
+ // di8_devices_callback callback is immediate and happens in scope of getInputDevices()
+#if LL_WINDOWS && !LL_MESA_HEADLESS
+ // space navigator is marked as DI8DEVCLASS_GAMECTRL in ndof lib
+ U32 device_type = DI8DEVCLASS_GAMECTRL;
+ void* callback = &di8_devices_callback;
+#else
+ // MAC doesn't support device search yet
+ // On MAC there is an ndof_idsearch and it is possible to specify product
+ // and manufacturer in NDOF_Device for ndof_init_first to pick specific one
+ U32 device_type = 0;
+ void* callback = NULL;
+#endif
+ if (!gViewerWindow->getWindow()->getInputDevices(device_type, callback, NULL))
+ {
+ LL_INFOS("Joystick") << "Failed to gather devices from window. Falling back to ndof's init" << LL_ENDL;
+ // Failed to gather devices from windows, init first suitable one
+ mLastDeviceUUID = LLSD();
+ void *preffered_device = NULL;
+ initDevice(preffered_device);
+ }
+
+ if (mDriverState == JDS_INITIALIZING)
+ {
+ LL_INFOS("Joystick") << "Found no matching joystick devices." << LL_ENDL;
+ mDriverState = JDS_UNINITIALIZED;
+ }
}
else
{
@@ -300,11 +429,92 @@ void LLViewerJoystick::init(bool autoenable)
// No device connected, don't change any settings
}
- LL_INFOS("joystick") << "ndof: mDriverState=" << mDriverState << "; mNdofDev="
+ LL_INFOS("Joystick") << "ndof: mDriverState=" << mDriverState << "; mNdofDev="
<< mNdofDev << "; libinit=" << libinit << LL_ENDL;
#endif
}
+void LLViewerJoystick::initDevice(LLSD &guid)
+{
+#if LIB_NDOF
+ mLastDeviceUUID = guid;
+
+#if LL_WINDOWS && !LL_MESA_HEADLESS
+ // space navigator is marked as DI8DEVCLASS_GAMECTRL in ndof lib
+ U32 device_type = DI8DEVCLASS_GAMECTRL;
+ void* callback = &di8_devices_callback;
+#else
+ // MAC doesn't support device search yet
+ // On MAC there is an ndof_idsearch and it is possible to specify product
+ // and manufacturer in NDOF_Device for ndof_init_first to pick specific one
+ U32 device_type = 0;
+ void* callback = NULL;
+#endif
+
+ mDriverState = JDS_INITIALIZING;
+ if (!gViewerWindow->getWindow()->getInputDevices(device_type, callback, NULL))
+ {
+ LL_INFOS("Joystick") << "Failed to gather devices from window. Falling back to ndof's init" << LL_ENDL;
+ // Failed to gather devices from windows, init first suitable one
+ void *preffered_device = NULL;
+ mLastDeviceUUID = LLSD();
+ initDevice(preffered_device);
+ }
+
+ if (mDriverState == JDS_INITIALIZING)
+ {
+ LL_INFOS("Joystick") << "Found no matching joystick devices." << LL_ENDL;
+ mDriverState = JDS_UNINITIALIZED;
+ }
+#endif
+}
+
+void LLViewerJoystick::initDevice(void * preffered_device /*LPDIRECTINPUTDEVICE8*/, std::string &name, LLSD &guid)
+{
+#if LIB_NDOF
+ mLastDeviceUUID = guid;
+
+ strncpy(mNdofDev->product, name.c_str(), sizeof(mNdofDev->product));
+ mNdofDev->manufacturer[0] = '\0';
+
+ initDevice(preffered_device);
+#endif
+}
+
+void LLViewerJoystick::initDevice(void * preffered_device /* LPDIRECTINPUTDEVICE8* */)
+{
+#if LIB_NDOF
+ // Different joysticks will return different ranges of raw values.
+ // Since we want to handle every device in the same uniform way,
+ // we initialize the mNdofDev struct and we set the range
+ // of values we would like to receive.
+ //
+ // HACK: On Windows, libndofdev passes our range to DI with a
+ // SetProperty call. This works but with one notable exception, the
+ // SpaceNavigator, who doesn't seem to care about the SetProperty
+ // call. In theory, we should handle this case inside libndofdev.
+ // However, the range we're setting here is arbitrary anyway,
+ // so let's just use the SpaceNavigator range for our purposes.
+ mNdofDev->axes_min = (long)-MAX_JOYSTICK_INPUT_VALUE;
+ mNdofDev->axes_max = (long)+MAX_JOYSTICK_INPUT_VALUE;
+
+ // libndofdev could be used to return deltas. Here we choose to
+ // just have the absolute values instead.
+ mNdofDev->absolute = 1;
+ // init & use the first suitable NDOF device found on the USB chain
+ // On windows preffered_device needs to be a pointer to LPDIRECTINPUTDEVICE8
+ if (ndof_init_first(mNdofDev, preffered_device))
+ {
+ mDriverState = JDS_UNINITIALIZED;
+ LL_WARNS() << "ndof_init_first FAILED" << LL_ENDL;
+ }
+ else
+ {
+ mDriverState = JDS_INITIALIZED;
+ }
+#endif
+}
+
// -----------------------------------------------------------------------------
void LLViewerJoystick::terminate()
{
@@ -314,7 +524,7 @@ void LLViewerJoystick::terminate()
ndof_libcleanup(); // frees alocated memory in mNdofDev
mDriverState = JDS_UNINITIALIZED;
mNdofDev = NULL;
- LL_INFOS("joystick") << "Terminated connection with NDOF device." << LL_ENDL;
+ LL_INFOS("Joystick") << "Terminated connection with NDOF device." << LL_ENDL;
}
#endif
}
@@ -1105,6 +1315,74 @@ void LLViewerJoystick::scanJoystick()
}
// -----------------------------------------------------------------------------
+bool LLViewerJoystick::isDeviceUUIDSet()
+{
+#if LL_WINDOWS && !LL_MESA_HEADLESS
+ // for ease of comparison and to dial less with platform specific variables, we store id as LLSD binary
+ return mLastDeviceUUID.isBinary();
+#else
+ return false;
+#endif
+}
+
+LLSD LLViewerJoystick::getDeviceUUID()
+{
+ return mLastDeviceUUID;
+}
+
+std::string LLViewerJoystick::getDeviceUUIDString()
+{
+#if LL_WINDOWS && !LL_MESA_HEADLESS
+ // Might be simpler to just convert _GUID into string everywhere, store and compare as string
+ if (mLastDeviceUUID.isBinary())
+ {
+ S32 size = sizeof(GUID);
+ LLSD::Binary data = mLastDeviceUUID.asBinary();
+ GUID guid;
+ memcpy(&guid, &data[0], size);
+ return string_from_guid(guid);
+ }
+ else
+ {
+ return std::string();
+ }
+#else
+ return std::string();
+ // return mLastDeviceUUID;
+#endif
+}
+
+void LLViewerJoystick::loadDeviceIdFromSettings()
+{
+#if LL_WINDOWS && !LL_MESA_HEADLESS
+ // We can't save binary data to gSavedSettings, somebody editing the file will corrupt it,
+ // so _GUID data gets converted to string (we probably can convert it to LLUUID with memcpy)
+ // and here we need to convert it back to binary from string
+ std::string device_string = gSavedSettings.getString("JoystickDeviceUUID");
+ if (device_string.empty())
+ {
+ mLastDeviceUUID = LLSD();
+ }
+ else
+ {
+ LL_DEBUGS("Joystick") << "Looking for device by id: " << device_string << LL_ENDL;
+ GUID guid;
+ guid_from_string(guid, device_string);
+ S32 size = sizeof(GUID);
+ LLSD::Binary data; //just an std::vector
+ data.resize(size);
+ memcpy(&data[0], &guid /*POD _GUID*/, size);
+ // We store this data in LLSD since LLSD is versatile and will be able to handle both GUID2
+ // and any data MAC will need for device selection
+ mLastDeviceUUID = LLSD(data);
+ }
+#else
+ mLastDeviceUUID = LLSD();
+ //mLastDeviceUUID = gSavedSettings.getLLSD("JoystickDeviceUUID");
+#endif
+}
+
+// -----------------------------------------------------------------------------
std::string LLViewerJoystick::getDescription()
{
std::string res;
@@ -1145,7 +1423,7 @@ void LLViewerJoystick::setSNDefaults()
#endif
//gViewerWindow->alertXml("CacheWillClear");
- LL_INFOS("joystick") << "restoring SpaceNavigator defaults..." << LL_ENDL;
+ LL_INFOS("Joystick") << "restoring SpaceNavigator defaults..." << LL_ENDL;
gSavedSettings.setS32("JoystickAxis0", 1); // z (at)
gSavedSettings.setS32("JoystickAxis1", 0); // x (slide)
diff --git a/indra/newview/llviewerjoystick.h b/indra/newview/llviewerjoystick.h
index 016b435ee8..782c523d4f 100644
--- a/indra/newview/llviewerjoystick.h
+++ b/indra/newview/llviewerjoystick.h
@@ -50,6 +50,9 @@ class LLViewerJoystick : public LLSingleton<LLViewerJoystick>
public:
void init(bool autoenable);
+ void initDevice(LLSD &guid);
+ void initDevice(void * preffered_device /*LPDIRECTINPUTDEVICE8*/);
+ void initDevice(void * preffered_device /*LPDIRECTINPUTDEVICE8*/, std::string &name, LLSD &guid);
void terminate();
void updateStatus();
@@ -68,8 +71,11 @@ public:
void setOverrideCamera(bool val);
bool toggleFlycam();
void setSNDefaults();
+ bool isDeviceUUIDSet();
+ LLSD getDeviceUUID(); //unconverted, OS dependent value wrapped into LLSD, for comparison/search
+ std::string getDeviceUUIDString(); // converted readable value for settings
std::string getDescription();
-
+
protected:
void updateEnabled(bool autoenable);
void handleRun(F32 inc);
@@ -80,6 +86,7 @@ protected:
void agentYaw(F32 yaw_inc);
void agentJump();
void resetDeltas(S32 axis[]);
+ void loadDeviceIdFromSettings();
#if LIB_NDOF
static NDOF_HotPlugResult HotPlugAddCallback(NDOF_Device *dev);
static void HotPlugRemovalCallback(NDOF_Device *dev);
@@ -95,6 +102,7 @@ private:
bool mCameraUpdated;
bool mOverrideCamera;
U32 mJoystickRun;
+ LLSD mLastDeviceUUID; // _GUID as U8 binary map, integer 1 for no device/ndof's device
static F32 sLastDelta[7];
static F32 sDelta[7];
diff --git a/indra/newview/llviewermedia.cpp b/indra/newview/llviewermedia.cpp
index 534a67195e..9ed2df2759 100644
--- a/indra/newview/llviewermedia.cpp
+++ b/indra/newview/llviewermedia.cpp
@@ -194,7 +194,6 @@ static F32 sGlobalVolume = 1.0f;
static bool sForceUpdate = false;
static LLUUID sOnlyAudibleTextureID = LLUUID::null;
static F64 sLowestLoadableImplInterest = 0.0f;
-static bool sAnyMediaShowing = false;
//////////////////////////////////////////////////////////////////////////////////////////
static void add_media_impl(LLViewerMediaImpl* media)
@@ -866,7 +865,7 @@ void LLViewerMedia::updateMedia(void *dummy_arg)
if (!pimpl->getUsedInUI() && pimpl->hasMedia())
{
- sAnyMediaShowing = true;
+ mAnyMediaShowing = true;
}
if (!pimpl->getUsedInUI() && pimpl->hasMedia() && (pimpl->isMediaPlaying() || !pimpl->isMediaTimeBased()))
diff --git a/indra/newview/llviewermediafocus.cpp b/indra/newview/llviewermediafocus.cpp
index 10099eda5b..ba80eeb6b6 100644
--- a/indra/newview/llviewermediafocus.cpp
+++ b/indra/newview/llviewermediafocus.cpp
@@ -340,15 +340,6 @@ BOOL LLViewerMediaFocus::handleKey(KEY key, MASK mask, BOOL called_from_parent)
clearFocus();
}
-
- if ( KEY_F1 == key && LLUI::getInstance()->mHelpImpl && mMediaControls.get())
- {
- std::string help_topic;
- if (mMediaControls.get()->findHelpTopic(help_topic))
- {
- LLUI::getInstance()->mHelpImpl->showTopic(help_topic);
- }
- }
}
return true;
diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp
index 4890867f29..dfe9a38d34 100644
--- a/indra/newview/llviewermenu.cpp
+++ b/indra/newview/llviewermenu.cpp
@@ -4144,7 +4144,7 @@ void handle_reset_view()
// switching to outfit selector should automagically save any currently edited wearable
LLFloaterSidePanelContainer::showPanel("appearance", LLSD().with("type", "my_outfits"));
}
-
+ gAgentCamera.setFocusOnAvatar(TRUE, FALSE, FALSE);
reset_view_final( TRUE );
LLFloaterCamera::resetCameraMode();
}
@@ -7898,7 +7898,7 @@ void handle_grab_baked_texture(void* data)
if(folder_id.notNull())
{
std::string name;
- name = "Baked " + LLAvatarAppearanceDictionary::getInstance()->getBakedTexture(baked_tex_index)->mNameCapitalized + " Texture";
+ name = "Baked " + LLAvatarAppearance::getDictionary()->getBakedTexture(baked_tex_index)->mNameCapitalized + " Texture";
LLUUID item_id;
item_id.generate();
diff --git a/indra/newview/llviewermenufile.cpp b/indra/newview/llviewermenufile.cpp
index d43442d69d..4b231c7067 100644
--- a/indra/newview/llviewermenufile.cpp
+++ b/indra/newview/llviewermenufile.cpp
@@ -391,7 +391,9 @@ const void upload_single_file(const std::vector<std::string>& filenames, LLFileP
}
if (type == LLFilePicker::FFLOAD_ANIM)
{
- if (filename.rfind(".anim") != std::string::npos)
+ std::string filename_lc(filename);
+ LLStringUtil::toLower(filename_lc);
+ if (filename_lc.rfind(".anim") != std::string::npos)
{
LLFloaterReg::showInstance("upload_anim_anim", LLSD(filename));
}
@@ -686,11 +688,12 @@ class LLFileTakeSnapshotToDisk : public view_listener_t
bool render_ui = gSavedSettings.getBOOL("RenderUIInSnapshot");
bool render_hud = gSavedSettings.getBOOL("RenderHUDInSnapshot");
- if (gSavedSettings.getBOOL("HighResSnapshot"))
+ BOOL high_res = gSavedSettings.getBOOL("HighResSnapshot");
+ if (high_res)
{
width *= 2;
height *= 2;
- // not compatible wirh UI/HUD
+ // not compatible with UI/HUD
render_ui = false;
render_hud = false;
}
@@ -702,7 +705,9 @@ class LLFileTakeSnapshotToDisk : public view_listener_t
FALSE,
render_ui,
render_hud,
- FALSE))
+ FALSE,
+ LLSnapshotModel::SNAPSHOT_TYPE_COLOR,
+ high_res ? S32_MAX : MAX_SNAPSHOT_IMAGE_SIZE)) //per side
{
LLPointer<LLImageFormatted> formatted;
LLSnapshotModel::ESnapshotFormat fmt = (LLSnapshotModel::ESnapshotFormat) gSavedSettings.getS32("SnapshotFormat");
diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp
index 34d5dd5663..458fc3b13d 100644
--- a/indra/newview/llviewermessage.cpp
+++ b/indra/newview/llviewermessage.cpp
@@ -5736,8 +5736,9 @@ void process_script_question(LLMessageSystem *msg, void **user_data)
// so we'll reuse the same namespace for both throttle types.
std::string throttle_name = owner_name;
std::string self_name;
- LLAgentUI::buildFullname( self_name );
- if( owner_name == self_name )
+ LLAgentUI::buildFullname( self_name ); // does not include ' Resident'
+ std::string clean_owner_name = LLCacheName::cleanFullName(owner_name); // removes ' Resident'
+ if( clean_owner_name == self_name )
{
throttle_name = taskid.getString();
}
@@ -5772,7 +5773,7 @@ void process_script_question(LLMessageSystem *msg, void **user_data)
S32 count = 0;
LLSD args;
args["OBJECTNAME"] = object_name;
- args["NAME"] = LLCacheName::cleanFullName(owner_name);
+ args["NAME"] = clean_owner_name;
S32 known_questions = 0;
bool has_not_only_debit = questions ^ SCRIPT_PERMISSIONS[SCRIPT_PERMISSION_DEBIT].permbit;
// check the received permission flags against each permission
diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp
index 5c99e693d2..2fde4fe49c 100644
--- a/indra/newview/llviewerregion.cpp
+++ b/indra/newview/llviewerregion.cpp
@@ -291,6 +291,7 @@ void LLViewerRegionImpl::requestBaseCapabilitiesCoro(U64 regionHandle)
LL_INFOS("AppInit", "Capabilities") << "Requesting seed from " << url
<< " region name " << regionp->getName()
+ << " region id " << regionp->getRegionID()
<< " handle " << regionp->getHandle()
<< " (attempt #" << mSeedCapAttempts + 1 << ")" << LL_ENDL;
LL_DEBUGS("AppInit", "Capabilities") << "Capabilities requested: " << capabilityNames << LL_ENDL;
@@ -406,7 +407,7 @@ void LLViewerRegionImpl::requestBaseCapabilitiesCompleteCoro(U64 regionHandle)
LLSD capabilityNames = LLSD::emptyArray();
buildCapabilityNames(capabilityNames);
- LL_INFOS("AppInit", "Capabilities") << "Requesting second Seed from " << url << LL_ENDL;
+ LL_INFOS("AppInit", "Capabilities") << "Requesting second Seed from " << url << " for region " << regionp->getRegionID() << LL_ENDL;
regionp = NULL;
result = httpAdapter->postAndSuspend(httpRequest, url, capabilityNames);
@@ -2222,7 +2223,7 @@ void LLViewerRegion::requestSimulatorFeatures()
LLCoros::instance().launch("LLViewerRegionImpl::requestSimulatorFeatureCoro",
boost::bind(&LLViewerRegionImpl::requestSimulatorFeatureCoro, mImpl, url, getHandle()));
- LL_INFOS("AppInit", "SimulatorFeatures") << "Launching " << coroname << " requesting simulator features from " << url << LL_ENDL;
+ LL_INFOS("AppInit", "SimulatorFeatures") << "Launching " << coroname << " requesting simulator features from " << url << " for region " << getRegionID() << LL_ENDL;
}
else
{
@@ -3029,7 +3030,7 @@ void LLViewerRegion::setSeedCapability(const std::string& url)
if (getCapability("Seed") == url)
{
setCapabilityDebug("Seed", url);
- LL_WARNS("CrossingCaps") << "Received duplicate seed capability, posting to seed " <<
+ LL_WARNS("CrossingCaps") << "Received duplicate seed capability for " << getRegionID() << ", posting to seed " <<
url << LL_ENDL;
//Instead of just returning we build up a second set of seed caps and compare them
@@ -3050,7 +3051,7 @@ void LLViewerRegion::setSeedCapability(const std::string& url)
LLCoros::instance().launch("LLViewerRegionImpl::requestBaseCapabilitiesCoro",
boost::bind(&LLViewerRegionImpl::requestBaseCapabilitiesCoro, mImpl, getHandle()));
- LL_INFOS("AppInit", "Capabilities") << "Launching " << coroname << " requesting seed capabilities from " << url << LL_ENDL;
+ LL_INFOS("AppInit", "Capabilities") << "Launching " << coroname << " requesting seed capabilities from " << url << " for region " << getRegionID() << LL_ENDL;
}
S32 LLViewerRegion::getNumSeedCapRetries()
@@ -3360,5 +3361,12 @@ U32 LLViewerRegion::getMaxMaterialsPerTransaction() const
return max_entries;
}
-
+std::string LLViewerRegion::getSimHostName()
+{
+ if (mSimulatorFeaturesReceived)
+ {
+ return mSimulatorFeatures.has("HostName") ? mSimulatorFeatures["HostName"].asString() : getHost().getHostName();
+ }
+ return std::string("...");
+}
diff --git a/indra/newview/llviewerregion.h b/indra/newview/llviewerregion.h
index 477aabb971..dfd8c64f76 100644
--- a/indra/newview/llviewerregion.h
+++ b/indra/newview/llviewerregion.h
@@ -393,6 +393,8 @@ public:
BOOL isPaused() const {return mPaused;}
S32 getLastUpdate() const {return mLastUpdate;}
+ std::string getSimHostName();
+
static BOOL isNewObjectCreationThrottleDisabled() {return sNewObjectCreationThrottle < 0;}
private:
diff --git a/indra/newview/llviewerstats.cpp b/indra/newview/llviewerstats.cpp
index f7ded00318..05f88b0a75 100644
--- a/indra/newview/llviewerstats.cpp
+++ b/indra/newview/llviewerstats.cpp
@@ -60,6 +60,7 @@
#include "llviewernetwork.h"
#include "llmeshrepository.h" //for LLMeshRepository::sBytesReceived
#include "llsdserialize.h"
+#include "llsdutil.h"
#include "llcorehttputil.h"
#include "llvoicevivox.h"
@@ -425,7 +426,7 @@ void update_statistics()
* If you move stats around here, make the corresponding changes in
* those locations, too.
*/
-void send_stats()
+void send_viewer_stats(bool include_preferences)
{
// IW 9/23/02 I elected not to move this into LLViewerStats
// because it depends on too many viewer.cpp globals.
@@ -513,6 +514,8 @@ void send_stats()
system["gpu_version"] = gGLManager.mDriverVersionVendorString;
system["opengl_version"] = gGLManager.mGLVersionString;
+ gGLManager.asLLSD(system["gl"]);
+
S32 shader_level = 0;
if (LLPipeline::sRenderDeferred)
{
@@ -572,6 +575,7 @@ void send_stats()
fail["failed_resends"] = (S32) gMessageSystem->mFailedResendPackets;
fail["off_circuit"] = (S32) gMessageSystem->mOffCircuitPackets;
fail["invalid"] = (S32) gMessageSystem->mInvalidOnCircuitPackets;
+ fail["missing_updater"] = (S32) LLAppViewer::instance()->isUpdaterMissing();
body["stats"]["voice"] = LLVoiceVivoxStats::getInstance()->read();
@@ -617,10 +621,25 @@ void send_stats()
body["DisplayNamesEnabled"] = gSavedSettings.getBOOL("UseDisplayNames");
body["DisplayNamesShowUsername"] = gSavedSettings.getBOOL("NameTagShowUsernames");
-
+
+ // Preferences
+ if (include_preferences)
+ {
+ bool diffs_only = true; // only log preferences that differ from default
+ body["preferences"]["settings"] = gSavedSettings.asLLSD(diffs_only);
+ body["preferences"]["settings_per_account"] = gSavedPerAccountSettings.asLLSD(diffs_only);
+ }
+
body["MinimalSkin"] = false;
+
LL_INFOS("LogViewerStatsPacket") << "Sending viewer statistics: " << body << LL_ENDL;
+ if (debugLoggingEnabled("LogViewerStatsPacket"))
+ {
+ std::string filename("viewer_stats_packet.xml");
+ llofstream of(filename.c_str());
+ LLSDSerialize::toPrettyXML(body,of);
+ }
// The session ID token must never appear in logs
body["session_id"] = gAgentSessionID;
diff --git a/indra/newview/llviewerstats.h b/indra/newview/llviewerstats.h
index d8d92d61d3..04870e0c26 100644
--- a/indra/newview/llviewerstats.h
+++ b/indra/newview/llviewerstats.h
@@ -294,7 +294,7 @@ static const F32 SEND_STATS_PERIOD = 300.0f;
// The following are from (older?) statistics code found in appviewer.
void update_statistics();
-void send_stats();
+void send_viewer_stats(bool include_preferences);
extern LLFrameTimer gTextureTimer;
extern U32Bytes gTotalTextureData;
diff --git a/indra/newview/llviewertexture.cpp b/indra/newview/llviewertexture.cpp
index e811638358..ca01bb46aa 100644
--- a/indra/newview/llviewertexture.cpp
+++ b/indra/newview/llviewertexture.cpp
@@ -1544,6 +1544,26 @@ BOOL LLViewerFetchedTexture::createTexture(S32 usename/*= 0*/)
return FALSE;
}
+ if (mGLTexturep->getHasExplicitFormat())
+ {
+ LLGLenum format = mGLTexturep->getPrimaryFormat();
+ S8 components = mRawImage->getComponents();
+ if ((format == GL_RGBA && components < 4)
+ || (format == GL_RGB && components < 3))
+ {
+ LL_WARNS() << "Can't create a texture " << mID << ": invalid image format " << std::hex << format << " vs components " << (U32)components << LL_ENDL;
+ // Was expecting specific format but raw texture has insufficient components for
+ // such format, using such texture will result in crash or will display wrongly
+ // if we change format. Texture might be corrupted server side, so just set as
+ // missing and clear cashed texture (do not cause reload loop, will retry&recover
+ // during new session)
+ setIsMissingAsset();
+ destroyRawImage();
+ LLAppViewer::getTextureCache()->removeFromCache(mID);
+ return FALSE;
+ }
+ }
+
res = mGLTexturep->createGLTexture(mRawDiscardLevel, mRawImage, usename, TRUE, mBoostLevel);
notifyAboutCreatingTexture();
diff --git a/indra/newview/llviewerwearable.cpp b/indra/newview/llviewerwearable.cpp
index 2d7a0f920f..9c4dfd1ca2 100644
--- a/indra/newview/llviewerwearable.cpp
+++ b/indra/newview/llviewerwearable.cpp
@@ -178,7 +178,7 @@ BOOL LLViewerWearable::isOldVersion() const
S32 te_count = 0;
for( S32 te = 0; te < TEX_NUM_INDICES; te++ )
{
- if (LLAvatarAppearanceDictionary::getTEWearableType((ETextureIndex) te) == mType)
+ if (LLAvatarAppearance::getDictionary()->getTEWearableType((ETextureIndex) te) == mType)
{
te_count++;
if( !is_in_map(mTEMap, te ) )
@@ -230,7 +230,7 @@ BOOL LLViewerWearable::isDirty() const
for( S32 te = 0; te < TEX_NUM_INDICES; te++ )
{
- if (LLAvatarAppearanceDictionary::getTEWearableType((ETextureIndex) te) == mType)
+ if (LLAvatarAppearance::getDictionary()->getTEWearableType((ETextureIndex) te) == mType)
{
te_map_t::const_iterator current_iter = mTEMap.find(te);
if(current_iter != mTEMap.end())
@@ -276,7 +276,7 @@ void LLViewerWearable::setTexturesToDefaults()
{
for( S32 te = 0; te < TEX_NUM_INDICES; te++ )
{
- if (LLAvatarAppearanceDictionary::getTEWearableType((ETextureIndex) te) == mType)
+ if (LLAvatarAppearance::getDictionary()->getTEWearableType((ETextureIndex) te) == mType)
{
LLUUID id = getDefaultTextureImageID((ETextureIndex) te);
LLViewerFetchedTexture * image = LLViewerTextureManager::getFetchedTexture( id );
@@ -300,7 +300,7 @@ void LLViewerWearable::setTexturesToDefaults()
// virtual
LLUUID LLViewerWearable::getDefaultTextureImageID(ETextureIndex index) const
{
- const LLAvatarAppearanceDictionary::TextureEntry *texture_dict = LLAvatarAppearanceDictionary::getInstance()->getTexture(index);
+ const LLAvatarAppearanceDictionary::TextureEntry *texture_dict = LLAvatarAppearance::getDictionary()->getTexture(index);
const std::string &default_image_name = texture_dict ? texture_dict->mDefaultImageName : "";
if (default_image_name == "")
{
@@ -331,7 +331,7 @@ void LLViewerWearable::writeToAvatar(LLAvatarAppearance *avatarp)
// Pull texture entries
for( S32 te = 0; te < TEX_NUM_INDICES; te++ )
{
- if (LLAvatarAppearanceDictionary::getTEWearableType((ETextureIndex) te) == mType)
+ if (LLAvatarAppearance::getDictionary()->getTEWearableType((ETextureIndex) te) == mType)
{
te_map_t::const_iterator iter = mTEMap.find(te);
LLUUID image_id;
@@ -424,7 +424,7 @@ void LLViewerWearable::copyDataFrom(const LLViewerWearable* src)
// Deep copy of mTEMap (copies only those tes that are current, filling in defaults where needed)
for (S32 te = 0; te < TEX_NUM_INDICES; te++)
{
- if (LLAvatarAppearanceDictionary::getTEWearableType((ETextureIndex) te) == mType)
+ if (LLAvatarAppearance::getDictionary()->getTEWearableType((ETextureIndex) te) == mType)
{
te_map_t::const_iterator iter = src->mTEMap.find(te);
LLUUID image_id;
@@ -463,8 +463,7 @@ void LLViewerWearable::revertValues()
{
LLWearable::revertValues();
-
- LLSidepanelAppearance *panel = dynamic_cast<LLSidepanelAppearance*>(LLFloaterSidePanelContainer::getPanel("appearance"));
+ LLSidepanelAppearance *panel = dynamic_cast<LLSidepanelAppearance*>(LLFloaterSidePanelContainer::findPanel("appearance"));
if( panel )
{
panel->updateScrollingPanelList();
@@ -480,7 +479,7 @@ void LLViewerWearable::saveValues()
{
LLWearable::saveValues();
- LLSidepanelAppearance *panel = dynamic_cast<LLSidepanelAppearance*>(LLFloaterSidePanelContainer::getPanel("appearance"));
+ LLSidepanelAppearance *panel = dynamic_cast<LLSidepanelAppearance*>(LLFloaterSidePanelContainer::findPanel("appearance"));
if( panel )
{
panel->updateScrollingPanelList();
diff --git a/indra/newview/llviewerwindow.h b/indra/newview/llviewerwindow.h
index e901245f92..e282905a1c 100644
--- a/indra/newview/llviewerwindow.h
+++ b/indra/newview/llviewerwindow.h
@@ -137,7 +137,7 @@ private:
};
-static const U32 MAX_SNAPSHOT_IMAGE_SIZE = 6 * 1024; // max snapshot image size 6144 * 6144
+static const U32 MAX_SNAPSHOT_IMAGE_SIZE = 7680; // max snapshot image size 7680 * 7680 UHDTV2
class LLViewerWindow : public LLWindowCallbacks
{
diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp
index 0aee4a3398..b205823820 100644
--- a/indra/newview/llvoavatar.cpp
+++ b/indra/newview/llvoavatar.cpp
@@ -573,7 +573,6 @@ private:
//-----------------------------------------------------------------------------
// Static Data
//-----------------------------------------------------------------------------
-LLAvatarAppearanceDictionary *LLVOAvatar::sAvatarDictionary = NULL;
S32 LLVOAvatar::sFreezeCounter = 0;
U32 LLVOAvatar::sMaxNonImpostors = 12; // overridden based on graphics setting
F32 LLVOAvatar::sRenderDistance = 256.f;
@@ -1025,15 +1024,15 @@ void LLVOAvatar::dumpBakedStatus()
{
LL_CONT << " Unbaked (";
- for (LLAvatarAppearanceDictionary::BakedTextures::const_iterator iter = LLAvatarAppearanceDictionary::getInstance()->getBakedTextures().begin();
- iter != LLAvatarAppearanceDictionary::getInstance()->getBakedTextures().end();
+ for (LLAvatarAppearanceDictionary::BakedTextures::const_iterator iter = LLAvatarAppearance::getDictionary()->getBakedTextures().begin();
+ iter != LLAvatarAppearance::getDictionary()->getBakedTextures().end();
++iter)
{
const LLAvatarAppearanceDictionary::BakedEntry *baked_dict = iter->second;
const ETextureIndex index = baked_dict->mTextureIndex;
if (!inst->isTextureDefined(index))
{
- LL_CONT << " " << (LLAvatarAppearanceDictionary::getInstance()->getTexture(index) ? LLAvatarAppearanceDictionary::getInstance()->getTexture(index)->mName : "");
+ LL_CONT << " " << (LLAvatarAppearance::getDictionary()->getTexture(index) ? LLAvatarAppearance::getDictionary()->getTexture(index)->mName : "");
}
}
LL_CONT << " ) " << inst->getUnbakedPixelAreaRank();
@@ -1119,6 +1118,7 @@ void LLVOAvatar::initClass()
LLJoint::setDebugJointNames(gSavedSettings.getString("DebugAvatarJoints"));
LLControlAvatar::sRegionChangedSlot = gAgent.addRegionChangedCallback(&LLControlAvatar::onRegionChanged);
+
}
@@ -5188,7 +5188,7 @@ void LLVOAvatar::collectLocalTextureUUIDs(std::set<LLUUID>& ids) const
{
for (U32 texture_index = 0; texture_index < getNumTEs(); texture_index++)
{
- LLWearableType::EType wearable_type = LLAvatarAppearanceDictionary::getTEWearableType((ETextureIndex)texture_index);
+ LLWearableType::EType wearable_type = LLAvatarAppearance::getDictionary()->getTEWearableType((ETextureIndex)texture_index);
U32 num_wearables = gAgentWearables.getWearableCount(wearable_type);
LLViewerFetchedTexture *imagep = NULL;
@@ -5197,7 +5197,7 @@ void LLVOAvatar::collectLocalTextureUUIDs(std::set<LLUUID>& ids) const
imagep = LLViewerTextureManager::staticCastToFetchedTexture(getImage(texture_index, wearable_index), TRUE);
if (imagep)
{
- const LLAvatarAppearanceDictionary::TextureEntry *texture_dict = LLAvatarAppearanceDictionary::getInstance()->getTexture((ETextureIndex)texture_index);
+ const LLAvatarAppearanceDictionary::TextureEntry *texture_dict = LLAvatarAppearance::getDictionary()->getTexture((ETextureIndex)texture_index);
if (texture_dict && texture_dict->mIsLocalTexture)
{
ids.insert(imagep->getID());
@@ -5331,7 +5331,7 @@ void LLVOAvatar::updateTextures()
mHasGrey = FALSE; // debug
for (U32 texture_index = 0; texture_index < getNumTEs(); texture_index++)
{
- LLWearableType::EType wearable_type = LLAvatarAppearanceDictionary::getTEWearableType((ETextureIndex)texture_index);
+ LLWearableType::EType wearable_type = LLAvatarAppearance::getDictionary()->getTEWearableType((ETextureIndex)texture_index);
U32 num_wearables = gAgentWearables.getWearableCount(wearable_type);
const LLTextureEntry *te = getTE(texture_index);
@@ -5354,7 +5354,7 @@ void LLVOAvatar::updateTextures()
imagep = LLViewerTextureManager::staticCastToFetchedTexture(getImage(texture_index, wearable_index), TRUE);
if (imagep)
{
- const LLAvatarAppearanceDictionary::TextureEntry *texture_dict = LLAvatarAppearanceDictionary::getInstance()->getTexture((ETextureIndex)texture_index);
+ const LLAvatarAppearanceDictionary::TextureEntry *texture_dict = LLAvatarAppearance::getDictionary()->getTexture((ETextureIndex)texture_index);
const EBakedTextureIndex baked_index = texture_dict ? texture_dict->mBakedTextureIndex : EBakedTextureIndex::BAKED_NUM_INDICES;
if (texture_dict && texture_dict->mIsLocalTexture)
{
@@ -5529,7 +5529,7 @@ const std::string LLVOAvatar::getImageURL(const U8 te, const LLUUID &uuid)
return url;
}
- const LLAvatarAppearanceDictionary::TextureEntry* texture_entry = LLAvatarAppearanceDictionary::getInstance()->getTexture((ETextureIndex)te);
+ const LLAvatarAppearanceDictionary::TextureEntry* texture_entry = LLAvatarAppearance::getDictionary()->getTexture((ETextureIndex)te);
if (texture_entry != NULL)
{
url = appearance_service_url + "texture/" + getID().asString() + "/" + texture_entry->mDefaultImageName + "/" + uuid.asString();
@@ -7564,8 +7564,8 @@ BOOL LLVOAvatar::isWearingWearableType(LLWearableType::EType type) const
break; // Do nothing
}
- for (LLAvatarAppearanceDictionary::Textures::const_iterator tex_iter = LLAvatarAppearanceDictionary::getInstance()->getTextures().begin();
- tex_iter != LLAvatarAppearanceDictionary::getInstance()->getTextures().end();
+ for (LLAvatarAppearanceDictionary::Textures::const_iterator tex_iter = LLAvatarAppearance::getDictionary()->getTextures().begin();
+ tex_iter != LLAvatarAppearance::getDictionary()->getTextures().end();
++tex_iter)
{
const LLAvatarAppearanceDictionary::TextureEntry *texture_dict = tex_iter->second;
@@ -7578,7 +7578,7 @@ BOOL LLVOAvatar::isWearingWearableType(LLWearableType::EType type) const
if (texture_dict->mIsUsedByBakedTexture)
{
const EBakedTextureIndex baked_index = texture_dict->mBakedTextureIndex;
- return isTextureDefined(LLAvatarAppearanceDictionary::getInstance()->getBakedTexture(baked_index)->mTextureIndex);
+ return isTextureDefined(LLAvatarAppearance::getDictionary()->getBakedTexture(baked_index)->mTextureIndex);
}
return FALSE;
}
@@ -8324,8 +8324,8 @@ void LLVOAvatar::updateMeshTextures()
for (LLAvatarAppearanceDictionary::BakedTextures::const_iterator baked_iter =
- LLAvatarAppearanceDictionary::getInstance()->getBakedTextures().begin();
- baked_iter != LLAvatarAppearanceDictionary::getInstance()->getBakedTextures().end();
+ LLAvatarAppearance::getDictionary()->getBakedTextures().begin();
+ baked_iter != LLAvatarAppearance::getDictionary()->getBakedTextures().end();
++baked_iter)
{
const EBakedTextureIndex baked_index = baked_iter->first;
@@ -8503,7 +8503,7 @@ void LLVOAvatar::releaseComponentTextures()
for (U8 baked_index = 0; baked_index < BAKED_NUM_INDICES; baked_index++)
{
- const LLAvatarAppearanceDictionary::BakedEntry * bakedDicEntry = LLAvatarAppearanceDictionary::getInstance()->getBakedTexture((EBakedTextureIndex)baked_index);
+ const LLAvatarAppearanceDictionary::BakedEntry * bakedDicEntry = LLAvatarAppearance::getDictionary()->getBakedTexture((EBakedTextureIndex)baked_index);
// skip if this is a skirt and av is not wearing one, or if we don't have a baked texture UUID
if (!isTextureDefined(bakedDicEntry->mTextureIndex)
&& ( (baked_index != BAKED_SKIRT) || isWearingWearableType(LLWearableType::WT_SKIRT) ))
@@ -8522,8 +8522,8 @@ void LLVOAvatar::releaseComponentTextures()
void LLVOAvatar::dumpAvatarTEs( const std::string& context ) const
{
LL_DEBUGS("Avatar") << avString() << (isSelf() ? "Self: " : "Other: ") << context << LL_ENDL;
- for (LLAvatarAppearanceDictionary::Textures::const_iterator iter = LLAvatarAppearanceDictionary::getInstance()->getTextures().begin();
- iter != LLAvatarAppearanceDictionary::getInstance()->getTextures().end();
+ for (LLAvatarAppearanceDictionary::Textures::const_iterator iter = LLAvatarAppearance::getDictionary()->getTextures().begin();
+ iter != LLAvatarAppearance::getDictionary()->getTextures().end();
++iter)
{
const LLAvatarAppearanceDictionary::TextureEntry *texture_dict = iter->second;
@@ -9272,8 +9272,8 @@ void LLVOAvatar::onBakedTextureMasksLoaded( BOOL success, LLViewerFetchedTexture
self->mBakedTextureDatas[BAKED_HEAD].mTexLayerSet->applyMorphMask(aux_src->getData(), aux_src->getWidth(), aux_src->getHeight(), 1);
maskData->mLastDiscardLevel = discard_level; */
BOOL found_texture_id = false;
- for (LLAvatarAppearanceDictionary::Textures::const_iterator iter = LLAvatarAppearanceDictionary::getInstance()->getTextures().begin();
- iter != LLAvatarAppearanceDictionary::getInstance()->getTextures().end();
+ for (LLAvatarAppearanceDictionary::Textures::const_iterator iter = LLAvatarAppearance::getDictionary()->getTextures().begin();
+ iter != LLAvatarAppearance::getDictionary()->getTextures().end();
++iter)
{
@@ -9404,7 +9404,7 @@ void LLVOAvatar::useBakedTexture( const LLUUID& id )
}
const LLAvatarAppearanceDictionary::BakedEntry *baked_dict =
- LLAvatarAppearanceDictionary::getInstance()->getBakedTexture((EBakedTextureIndex)i);
+ LLAvatarAppearance::getDictionary()->getBakedTexture((EBakedTextureIndex)i);
for (texture_vec_t::const_iterator local_tex_iter = baked_dict->mLocalTextures.begin();
local_tex_iter != baked_dict->mLocalTextures.end();
++local_tex_iter)
@@ -9539,7 +9539,7 @@ void LLVOAvatar::dumpArchetypeXML(const std::string& prefix, bool group_by_weara
for (U8 te = 0; te < TEX_NUM_INDICES; te++)
{
- if (LLAvatarAppearanceDictionary::getTEWearableType((ETextureIndex)te) == type)
+ if (LLAvatarAppearance::getDictionary()->getTEWearableType((ETextureIndex)te) == type)
{
// MULTIPLE_WEARABLES: extend to multiple wearables?
LLViewerTexture* te_image = getImage((ETextureIndex)te, 0);
@@ -10450,7 +10450,7 @@ void LLVOAvatar::calculateUpdateRenderComplexity()
for (U8 baked_index = 0; baked_index < BAKED_NUM_INDICES; baked_index++)
{
const LLAvatarAppearanceDictionary::BakedEntry *baked_dict
- = LLAvatarAppearanceDictionary::getInstance()->getBakedTexture((EBakedTextureIndex)baked_index);
+ = LLAvatarAppearance::getDictionary()->getBakedTexture((EBakedTextureIndex)baked_index);
ETextureIndex tex_index = baked_dict->mTextureIndex;
if ((tex_index != TEX_SKIRT_BAKED) || (isWearingWearableType(LLWearableType::WT_SKIRT)))
{
@@ -10515,8 +10515,8 @@ void LLVOAvatar::calculateUpdateRenderComplexity()
}
// print any avatar textures we didn't already know about
- for (LLAvatarAppearanceDictionary::Textures::const_iterator iter = LLAvatarAppearanceDictionary::getInstance()->getTextures().begin();
- iter != LLAvatarAppearanceDictionary::getInstance()->getTextures().end();
+ for (LLAvatarAppearanceDictionary::Textures::const_iterator iter = LLAvatarAppearance::getDictionary()->getTextures().begin();
+ iter != LLAvatarAppearance::getDictionary()->getTextures().end();
++iter)
{
const LLAvatarAppearanceDictionary::TextureEntry *texture_dict = iter->second;
@@ -10631,7 +10631,7 @@ BOOL LLVOAvatar::isIndexLocalTexture(ETextureIndex index)
{
return (index < 0 || index >= TEX_NUM_INDICES)
? false
- : LLAvatarAppearanceDictionary::getInstance()->getTexture(index)->mIsLocalTexture;
+ : LLAvatarAppearance::getDictionary()->getTexture(index)->mIsLocalTexture;
}
// static
@@ -10639,15 +10639,15 @@ BOOL LLVOAvatar::isIndexBakedTexture(ETextureIndex index)
{
return (index < 0 || index >= TEX_NUM_INDICES)
? false
- : LLAvatarAppearanceDictionary::getInstance()->getTexture(index)->mIsBakedTexture;
+ : LLAvatarAppearance::getDictionary()->getTexture(index)->mIsBakedTexture;
}
const std::string LLVOAvatar::getBakedStatusForPrintout() const
{
std::string line;
- for (LLAvatarAppearanceDictionary::Textures::const_iterator iter = LLAvatarAppearanceDictionary::getInstance()->getTextures().begin();
- iter != LLAvatarAppearanceDictionary::getInstance()->getTextures().end();
+ for (LLAvatarAppearanceDictionary::Textures::const_iterator iter = LLAvatarAppearance::getDictionary()->getTextures().begin();
+ iter != LLAvatarAppearance::getDictionary()->getTextures().end();
++iter)
{
const ETextureIndex index = iter->first;
diff --git a/indra/newview/llvoavatar.h b/indra/newview/llvoavatar.h
index cfb007cbc9..79f31ba5b5 100644
--- a/indra/newview/llvoavatar.h
+++ b/indra/newview/llvoavatar.h
@@ -677,9 +677,6 @@ public:
public:
static BOOL isIndexLocalTexture(LLAvatarAppearanceDefines::ETextureIndex i);
static BOOL isIndexBakedTexture(LLAvatarAppearanceDefines::ETextureIndex i);
-private:
- static const LLAvatarAppearanceDefines::LLAvatarAppearanceDictionary *getDictionary() { return sAvatarDictionary; }
- static LLAvatarAppearanceDefines::LLAvatarAppearanceDictionary* sAvatarDictionary;
//--------------------------------------------------------------------
// Messaging
diff --git a/indra/newview/llvoavatarself.cpp b/indra/newview/llvoavatarself.cpp
index aea12380e8..58109b838e 100644
--- a/indra/newview/llvoavatarself.cpp
+++ b/indra/newview/llvoavatarself.cpp
@@ -1079,8 +1079,8 @@ void LLVOAvatarSelf::updateAttachmentVisibility(U32 camera_mode)
//-----------------------------------------------------------------------------
void LLVOAvatarSelf::wearableUpdated(LLWearableType::EType type)
{
- for (LLAvatarAppearanceDictionary::BakedTextures::const_iterator baked_iter = LLAvatarAppearanceDictionary::getInstance()->getBakedTextures().begin();
- baked_iter != LLAvatarAppearanceDictionary::getInstance()->getBakedTextures().end();
+ for (LLAvatarAppearanceDictionary::BakedTextures::const_iterator baked_iter = sAvatarDictionary->getBakedTextures().begin();
+ baked_iter != sAvatarDictionary->getBakedTextures().end();
++baked_iter)
{
const LLAvatarAppearanceDictionary::BakedEntry *baked_dict = baked_iter->second;
@@ -1277,7 +1277,7 @@ BOOL LLVOAvatarSelf::detachAttachmentIntoInventory(const LLUUID &item_id)
U32 LLVOAvatarSelf::getNumWearables(LLAvatarAppearanceDefines::ETextureIndex i) const
{
- LLWearableType::EType type = LLAvatarAppearanceDictionary::getInstance()->getTEWearableType(i);
+ LLWearableType::EType type = sAvatarDictionary->getTEWearableType(i);
return gAgentWearables.getWearableCount(type);
}
@@ -1388,8 +1388,8 @@ BOOL LLVOAvatarSelf::isLocalTextureDataAvailable(const LLViewerTexLayerSet* laye
{
/* if (layerset == mBakedTextureDatas[BAKED_HEAD].mTexLayerSet)
return getLocalDiscardLevel(TEX_HEAD_BODYPAINT) >= 0; */
- for (LLAvatarAppearanceDictionary::BakedTextures::const_iterator baked_iter = LLAvatarAppearanceDictionary::getInstance()->getBakedTextures().begin();
- baked_iter != LLAvatarAppearanceDictionary::getInstance()->getBakedTextures().end();
+ for (LLAvatarAppearanceDictionary::BakedTextures::const_iterator baked_iter = sAvatarDictionary->getBakedTextures().begin();
+ baked_iter != sAvatarDictionary->getBakedTextures().end();
++baked_iter)
{
const EBakedTextureIndex baked_index = baked_iter->first;
@@ -1402,7 +1402,7 @@ BOOL LLVOAvatarSelf::isLocalTextureDataAvailable(const LLViewerTexLayerSet* laye
++local_tex_iter)
{
const ETextureIndex tex_index = *local_tex_iter;
- const LLWearableType::EType wearable_type = LLAvatarAppearanceDictionary::getTEWearableType(tex_index);
+ const LLWearableType::EType wearable_type = sAvatarDictionary->getTEWearableType(tex_index);
const U32 wearable_count = gAgentWearables.getWearableCount(wearable_type);
for (U32 wearable_index = 0; wearable_index < wearable_count; wearable_index++)
{
@@ -1432,13 +1432,13 @@ BOOL LLVOAvatarSelf::isLocalTextureDataFinal(const LLViewerTexLayerSet* layerset
{
if (layerset == mBakedTextureDatas[i].mTexLayerSet)
{
- const LLAvatarAppearanceDictionary::BakedEntry *baked_dict = LLAvatarAppearanceDictionary::getInstance()->getBakedTexture((EBakedTextureIndex)i);
+ const LLAvatarAppearanceDictionary::BakedEntry *baked_dict = sAvatarDictionary->getBakedTexture((EBakedTextureIndex)i);
for (texture_vec_t::const_iterator local_tex_iter = baked_dict->mLocalTextures.begin();
local_tex_iter != baked_dict->mLocalTextures.end();
++local_tex_iter)
{
const ETextureIndex tex_index = *local_tex_iter;
- const LLWearableType::EType wearable_type = LLAvatarAppearanceDictionary::getTEWearableType(tex_index);
+ const LLWearableType::EType wearable_type = sAvatarDictionary->getTEWearableType(tex_index);
const U32 wearable_count = gAgentWearables.getWearableCount(wearable_type);
for (U32 wearable_index = 0; wearable_index < wearable_count; wearable_index++)
{
@@ -1465,13 +1465,13 @@ BOOL LLVOAvatarSelf::isAllLocalTextureDataFinal() const
for (U32 i = 0; i < mBakedTextureDatas.size(); i++)
{
- const LLAvatarAppearanceDictionary::BakedEntry *baked_dict = LLAvatarAppearanceDictionary::getInstance()->getBakedTexture((EBakedTextureIndex)i);
+ const LLAvatarAppearanceDictionary::BakedEntry *baked_dict = sAvatarDictionary->getBakedTexture((EBakedTextureIndex)i);
for (texture_vec_t::const_iterator local_tex_iter = baked_dict->mLocalTextures.begin();
local_tex_iter != baked_dict->mLocalTextures.end();
++local_tex_iter)
{
const ETextureIndex tex_index = *local_tex_iter;
- const LLWearableType::EType wearable_type = LLAvatarAppearanceDictionary::getTEWearableType(tex_index);
+ const LLWearableType::EType wearable_type = sAvatarDictionary->getTEWearableType(tex_index);
const U32 wearable_count = gAgentWearables.getWearableCount(wearable_type);
for (U32 wearable_index = 0; wearable_index < wearable_count; wearable_index++)
{
@@ -1493,7 +1493,7 @@ BOOL LLVOAvatarSelf::isTextureDefined(LLAvatarAppearanceDefines::ETextureIndex t
BOOL isDefined = TRUE;
if (isIndexLocalTexture(type))
{
- const LLWearableType::EType wearable_type = LLAvatarAppearanceDictionary::getTEWearableType(type);
+ const LLWearableType::EType wearable_type = sAvatarDictionary->getTEWearableType(type);
const U32 wearable_count = gAgentWearables.getWearableCount(wearable_type);
if (index >= wearable_count)
{
@@ -1710,7 +1710,7 @@ void LLVOAvatarSelf::setLocalTexture(ETextureIndex type, LLViewerTexture* src_te
LL_ERRS() << "Tried to set local texture with invalid type: (" << (U32) type << ", " << index << ")" << LL_ENDL;
return;
}
- LLWearableType::EType wearable_type = LLAvatarAppearanceDictionary::getInstance()->getTEWearableType(type);
+ LLWearableType::EType wearable_type = sAvatarDictionary->getTEWearableType(type);
if (!gAgentWearables.getViewerWearable(wearable_type,index))
{
// no wearable is loaded, cannot set the texture.
@@ -1787,8 +1787,8 @@ void LLVOAvatarSelf::dumpLocalTextures() const
/* ETextureIndex baked_equiv[] = {
TEX_UPPER_BAKED,
if (isTextureDefined(baked_equiv[i])) */
- for (LLAvatarAppearanceDictionary::Textures::const_iterator iter = LLAvatarAppearanceDictionary::getInstance()->getTextures().begin();
- iter != LLAvatarAppearanceDictionary::getInstance()->getTextures().end();
+ for (LLAvatarAppearanceDictionary::Textures::const_iterator iter = sAvatarDictionary->getTextures().begin();
+ iter != sAvatarDictionary->getTextures().end();
++iter)
{
const LLAvatarAppearanceDictionary::TextureEntry *texture_dict = iter->second;
@@ -1796,7 +1796,7 @@ void LLVOAvatarSelf::dumpLocalTextures() const
continue;
const EBakedTextureIndex baked_index = texture_dict->mBakedTextureIndex;
- const ETextureIndex baked_equiv = LLAvatarAppearanceDictionary::getInstance()->getBakedTexture(baked_index)->mTextureIndex;
+ const ETextureIndex baked_equiv = sAvatarDictionary->getBakedTexture(baked_index)->mTextureIndex;
const std::string &name = texture_dict->mName;
const LLLocalTextureObject *local_tex_obj = getLocalTextureObject(iter->first, 0);
@@ -2031,8 +2031,8 @@ const std::string LLVOAvatarSelf::verboseDebugDumpLocalTextureDataInfo(const LLV
{
std::ostringstream outbuf;
for (LLAvatarAppearanceDictionary::BakedTextures::const_iterator baked_iter =
- LLAvatarAppearanceDictionary::getInstance()->getBakedTextures().begin();
- baked_iter != LLAvatarAppearanceDictionary::getInstance()->getBakedTextures().end();
+ sAvatarDictionary->getBakedTextures().begin();
+ baked_iter != sAvatarDictionary->getBakedTextures().end();
++baked_iter)
{
const EBakedTextureIndex baked_index = baked_iter->first;
@@ -2045,9 +2045,9 @@ const std::string LLVOAvatarSelf::verboseDebugDumpLocalTextureDataInfo(const LLV
++local_tex_iter)
{
const ETextureIndex tex_index = *local_tex_iter;
- const std::string tex_name = LLAvatarAppearanceDictionary::getInstance()->getTexture(tex_index)->mName;
+ const std::string tex_name = sAvatarDictionary->getTexture(tex_index)->mName;
outbuf << " tex_index " << (S32) tex_index << " name " << tex_name << "\n";
- const LLWearableType::EType wearable_type = LLAvatarAppearanceDictionary::getTEWearableType(tex_index);
+ const LLWearableType::EType wearable_type = sAvatarDictionary->getTEWearableType(tex_index);
const U32 wearable_count = gAgentWearables.getWearableCount(wearable_type);
if (wearable_count > 0)
{
@@ -2091,8 +2091,8 @@ const std::string LLVOAvatarSelf::verboseDebugDumpLocalTextureDataInfo(const LLV
void LLVOAvatarSelf::dumpAllTextures() const
{
std::string vd_text = "Local textures per baked index and wearable:\n";
- for (LLAvatarAppearanceDefines::LLAvatarAppearanceDictionary::BakedTextures::const_iterator baked_iter = LLAvatarAppearanceDefines::LLAvatarAppearanceDictionary::getInstance()->getBakedTextures().begin();
- baked_iter != LLAvatarAppearanceDefines::LLAvatarAppearanceDictionary::getInstance()->getBakedTextures().end();
+ for (LLAvatarAppearanceDefines::LLAvatarAppearanceDictionary::BakedTextures::const_iterator baked_iter = sAvatarDictionary->getBakedTextures().begin();
+ baked_iter != sAvatarDictionary->getBakedTextures().end();
++baked_iter)
{
const LLAvatarAppearanceDefines::EBakedTextureIndex baked_index = baked_iter->first;
@@ -2113,8 +2113,8 @@ const std::string LLVOAvatarSelf::debugDumpLocalTextureDataInfo(const LLViewerTe
/* if (layerset == mBakedTextureDatas[BAKED_HEAD].mTexLayerSet)
return getLocalDiscardLevel(TEX_HEAD_BODYPAINT) >= 0; */
- for (LLAvatarAppearanceDictionary::BakedTextures::const_iterator baked_iter = LLAvatarAppearanceDictionary::getInstance()->getBakedTextures().begin();
- baked_iter != LLAvatarAppearanceDictionary::getInstance()->getBakedTextures().end();
+ for (LLAvatarAppearanceDictionary::BakedTextures::const_iterator baked_iter = sAvatarDictionary->getBakedTextures().begin();
+ baked_iter != sAvatarDictionary->getBakedTextures().end();
++baked_iter)
{
const EBakedTextureIndex baked_index = baked_iter->first;
@@ -2127,7 +2127,7 @@ const std::string LLVOAvatarSelf::debugDumpLocalTextureDataInfo(const LLViewerTe
++local_tex_iter)
{
const ETextureIndex tex_index = *local_tex_iter;
- const LLWearableType::EType wearable_type = LLAvatarAppearanceDictionary::getTEWearableType(tex_index);
+ const LLWearableType::EType wearable_type = sAvatarDictionary->getTEWearableType(tex_index);
const U32 wearable_count = gAgentWearables.getWearableCount(wearable_type);
if (wearable_count > 0)
{
@@ -2154,14 +2154,14 @@ const std::string LLVOAvatarSelf::debugDumpAllLocalTextureDataInfo() const
for (U32 i = 0; i < mBakedTextureDatas.size(); i++)
{
- const LLAvatarAppearanceDictionary::BakedEntry *baked_dict = LLAvatarAppearanceDictionary::getInstance()->getBakedTexture((EBakedTextureIndex)i);
+ const LLAvatarAppearanceDictionary::BakedEntry *baked_dict = sAvatarDictionary->getBakedTexture((EBakedTextureIndex)i);
BOOL is_texture_final = TRUE;
for (texture_vec_t::const_iterator local_tex_iter = baked_dict->mLocalTextures.begin();
local_tex_iter != baked_dict->mLocalTextures.end();
++local_tex_iter)
{
const ETextureIndex tex_index = *local_tex_iter;
- const LLWearableType::EType wearable_type = LLAvatarAppearanceDictionary::getTEWearableType(tex_index);
+ const LLWearableType::EType wearable_type = sAvatarDictionary->getTEWearableType(tex_index);
const U32 wearable_count = gAgentWearables.getWearableCount(wearable_type);
for (U32 wearable_index = 0; wearable_index < wearable_count; wearable_index++)
{
@@ -2341,7 +2341,7 @@ const LLUUID& LLVOAvatarSelf::grabBakedTexture(EBakedTextureIndex baked_index) c
{
if (canGrabBakedTexture(baked_index))
{
- ETextureIndex tex_index = LLAvatarAppearanceDictionary::bakedToLocalTextureIndex(baked_index);
+ ETextureIndex tex_index = sAvatarDictionary->bakedToLocalTextureIndex(baked_index);
if (tex_index == TEX_NUM_INDICES)
{
return LLUUID::null;
@@ -2353,7 +2353,7 @@ const LLUUID& LLVOAvatarSelf::grabBakedTexture(EBakedTextureIndex baked_index) c
BOOL LLVOAvatarSelf::canGrabBakedTexture(EBakedTextureIndex baked_index) const
{
- ETextureIndex tex_index = LLAvatarAppearanceDictionary::bakedToLocalTextureIndex(baked_index);
+ ETextureIndex tex_index = sAvatarDictionary->bakedToLocalTextureIndex(baked_index);
if (tex_index == TEX_NUM_INDICES)
{
return FALSE;
@@ -2372,13 +2372,13 @@ BOOL LLVOAvatarSelf::canGrabBakedTexture(EBakedTextureIndex baked_index) const
// baked texture. We don't want people copying people's
// work via baked textures.
- const LLAvatarAppearanceDictionary::BakedEntry *baked_dict = LLAvatarAppearanceDictionary::getInstance()->getBakedTexture(baked_index);
+ const LLAvatarAppearanceDictionary::BakedEntry *baked_dict = sAvatarDictionary->getBakedTexture(baked_index);
for (texture_vec_t::const_iterator iter = baked_dict->mLocalTextures.begin();
iter != baked_dict->mLocalTextures.end();
++iter)
{
const ETextureIndex t_index = (*iter);
- LLWearableType::EType wearable_type = LLAvatarAppearanceDictionary::getTEWearableType(t_index);
+ LLWearableType::EType wearable_type = sAvatarDictionary->getTEWearableType(t_index);
U32 count = gAgentWearables.getWearableCount(wearable_type);
LL_DEBUGS() << "Checking index " << (U32) t_index << " count: " << count << LL_ENDL;
@@ -2466,7 +2466,7 @@ void LLVOAvatarSelf::addLocalTextureStats( ETextureIndex type, LLViewerFetchedTe
LLLocalTextureObject* LLVOAvatarSelf::getLocalTextureObject(LLAvatarAppearanceDefines::ETextureIndex i, U32 wearable_index) const
{
- LLWearableType::EType type = LLAvatarAppearanceDictionary::getInstance()->getTEWearableType(i);
+ LLWearableType::EType type = sAvatarDictionary->getTEWearableType(i);
LLViewerWearable* wearable = gAgentWearables.getViewerWearable(type, wearable_index);
if (wearable)
{
@@ -2540,8 +2540,8 @@ void LLVOAvatarSelf::outputRezDiagnostics() const
LL_DEBUGS("Avatar") << "\t\t (" << i << ") \t" << (S32)mDebugBakedTextureTimes[i][0] << " / " << (S32)mDebugBakedTextureTimes[i][1] << LL_ENDL;
}
- for (LLAvatarAppearanceDefines::LLAvatarAppearanceDictionary::BakedTextures::const_iterator baked_iter = LLAvatarAppearanceDefines::LLAvatarAppearanceDictionary::getInstance()->getBakedTextures().begin();
- baked_iter != LLAvatarAppearanceDefines::LLAvatarAppearanceDictionary::getInstance()->getBakedTextures().end();
+ for (LLAvatarAppearanceDefines::LLAvatarAppearanceDictionary::BakedTextures::const_iterator baked_iter = sAvatarDictionary->getBakedTextures().begin();
+ baked_iter != sAvatarDictionary->getBakedTextures().end();
++baked_iter)
{
const LLAvatarAppearanceDefines::EBakedTextureIndex baked_index = baked_iter->first;
@@ -2607,7 +2607,7 @@ void LLVOAvatarSelf::requestLayerSetUpdate(ETextureIndex index )
case LOCTEX_UPPER_SHIRT:
if( mUpperBodyLayerSet )
mUpperBodyLayerSet->requestUpdate(); */
- const LLAvatarAppearanceDictionary::TextureEntry *texture_dict = LLAvatarAppearanceDictionary::getInstance()->getTexture(index);
+ const LLAvatarAppearanceDictionary::TextureEntry *texture_dict = sAvatarDictionary->getTexture(index);
if (!texture_dict)
return;
if (!texture_dict->mIsLocalTexture || !texture_dict->mIsUsedByBakedTexture)
@@ -2625,7 +2625,7 @@ LLViewerTexLayerSet* LLVOAvatarSelf::getLayerSet(ETextureIndex index) const
case TEX_HEAD_BAKED:
case TEX_HEAD_BODYPAINT:
return mHeadLayerSet; */
- const LLAvatarAppearanceDictionary::TextureEntry *texture_dict = LLAvatarAppearanceDictionary::getInstance()->getTexture(index);
+ const LLAvatarAppearanceDictionary::TextureEntry *texture_dict = sAvatarDictionary->getTexture(index);
if (texture_dict && texture_dict->mIsUsedByBakedTexture)
{
const EBakedTextureIndex baked_index = texture_dict->mBakedTextureIndex;
@@ -2711,8 +2711,8 @@ bool LLVOAvatarSelf::sendAppearanceMessage(LLMessageSystem *mesgsys) const
{
LLUUID texture_id[TEX_NUM_INDICES];
// pack away current TEs to make sure we don't send them out
- for (LLAvatarAppearanceDictionary::Textures::const_iterator iter = LLAvatarAppearanceDictionary::getInstance()->getTextures().begin();
- iter != LLAvatarAppearanceDictionary::getInstance()->getTextures().end();
+ for (LLAvatarAppearanceDictionary::Textures::const_iterator iter = sAvatarDictionary->getTextures().begin();
+ iter != sAvatarDictionary->getTextures().end();
++iter)
{
const ETextureIndex index = iter->first;
@@ -2728,8 +2728,8 @@ bool LLVOAvatarSelf::sendAppearanceMessage(LLMessageSystem *mesgsys) const
bool success = packTEMessage(mesgsys);
// unpack TEs to make sure we don't re-trigger a bake
- for (LLAvatarAppearanceDictionary::Textures::const_iterator iter = LLAvatarAppearanceDictionary::getInstance()->getTextures().begin();
- iter != LLAvatarAppearanceDictionary::getInstance()->getTextures().end();
+ for (LLAvatarAppearanceDictionary::Textures::const_iterator iter = sAvatarDictionary->getTextures().begin();
+ iter != sAvatarDictionary->getTextures().end();
++iter)
{
const ETextureIndex index = iter->first;
diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp
index 492d37edba..95cfe29a80 100644
--- a/indra/newview/llvovolume.cpp
+++ b/indra/newview/llvovolume.cpp
@@ -695,6 +695,11 @@ void LLVOVolume::updateTextureVirtualSize(bool forced)
LL_RECORD_BLOCK_TIME(FTM_VOLUME_TEXTURES);
// Update the pixel area of all faces
+ if (mDrawable.isNull())
+ {
+ return;
+ }
+
if(!forced)
{
if(!isVisible())
@@ -2332,7 +2337,8 @@ bool LLVOVolume::notifyAboutCreatingTexture(LLViewerTexture *texture)
//setup new materials
for(map_te_material::const_iterator it = new_material.begin(), end = new_material.end(); it != end; ++it)
{
- LLMaterialMgr::getInstance()->put(getID(), it->first, *it->second);
+ // These are placeholder materials, they shouldn't be sent to server
+ LLMaterialMgr::getInstance()->setLocalMaterial(getRegion()->getRegionID(), it->second);
LLViewerObject::setTEMaterialParams(it->first, it->second);
}
diff --git a/indra/newview/llwearableitemslist.cpp b/indra/newview/llwearableitemslist.cpp
index e7f62e77b4..9acc0f8d2f 100644
--- a/indra/newview/llwearableitemslist.cpp
+++ b/indra/newview/llwearableitemslist.cpp
@@ -640,6 +640,7 @@ LLWearableItemsList::LLWearableItemsList(const LLWearableItemsList::Params& p)
: LLInventoryItemsList(p)
{
setSortOrder(E_SORT_BY_TYPE_LAYER, false);
+ mMenuWearableType = LLWearableType::WT_NONE;
mIsStandalone = p.standalone;
if (mIsStandalone)
{
@@ -731,10 +732,15 @@ void LLWearableItemsList::onRightClick(S32 x, S32 y)
getSelectedUUIDs(selected_uuids);
if (selected_uuids.empty())
{
- return;
+ if ((mMenuWearableType != LLWearableType::WT_NONE) && (size() == 0))
+ {
+ ContextMenu::instance().show(this, mMenuWearableType, x, y);
+ }
+ }
+ else
+ {
+ ContextMenu::instance().show(this, selected_uuids, x, y);
}
-
- ContextMenu::instance().show(this, selected_uuids, x, y);
}
void LLWearableItemsList::setSortOrder(ESortOrder sort_order, bool sort_now)
@@ -785,6 +791,46 @@ void LLWearableItemsList::ContextMenu::show(LLView* spawning_view, const uuid_ve
mParent = NULL; // to avoid dereferencing an invalid pointer
}
+void LLWearableItemsList::ContextMenu::show(LLView* spawning_view, LLWearableType::EType w_type, S32 x, S32 y)
+{
+ mParent = dynamic_cast<LLWearableItemsList*>(spawning_view);
+ LLContextMenu* menup = mMenuHandle.get();
+ if (menup)
+ {
+ //preventing parent (menu holder) from deleting already "dead" context menus on exit
+ LLView* parent = menup->getParent();
+ if (parent)
+ {
+ parent->removeChild(menup);
+ }
+ delete menup;
+ mUUIDs.clear();
+ }
+
+ LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar;
+ registrar.add("Wearable.CreateNew", boost::bind(createNewWearableByType, w_type));
+ menup = createFromFile("menu_wearable_list_item.xml");
+ if (!menup)
+ {
+ LL_WARNS() << "Context menu creation failed" << LL_ENDL;
+ return;
+ }
+ setMenuItemVisible(menup, "create_new", true);
+ setMenuItemEnabled(menup, "create_new", true);
+ setMenuItemVisible(menup, "wearable_attach_to", false);
+ setMenuItemVisible(menup, "wearable_attach_to_hud", false);
+
+ std::string new_label = LLTrans::getString("create_new_" + LLWearableType::getTypeName(w_type));
+ LLMenuItemGL* menu_item = menup->getChild<LLMenuItemGL>("create_new");
+ menu_item->setLabel(new_label);
+
+ mMenuHandle = menup->getHandle();
+ menup->show(x, y);
+ LLMenuGL::showPopup(spawning_view, menup, x, y);
+
+ mParent = NULL; // to avoid dereferencing an invalid pointer
+}
+
// virtual
LLContextMenu* LLWearableItemsList::ContextMenu::createMenu()
{
@@ -1014,4 +1060,10 @@ void LLWearableItemsList::ContextMenu::createNewWearable(const LLUUID& item_id)
LLAgentWearables::createWearable(item->getWearableType(), true);
}
+// static
+void LLWearableItemsList::ContextMenu::createNewWearableByType(LLWearableType::EType type)
+{
+ LLAgentWearables::createWearable(type, true);
+}
+
// EOF
diff --git a/indra/newview/llwearableitemslist.h b/indra/newview/llwearableitemslist.h
index f3182ed163..ba8488b237 100644
--- a/indra/newview/llwearableitemslist.h
+++ b/indra/newview/llwearableitemslist.h
@@ -415,6 +415,8 @@ public:
public:
/*virtual*/ void show(LLView* spawning_view, const uuid_vec_t& uuids, S32 x, S32 y);
+ void show(LLView* spawning_view, LLWearableType::EType w_type, S32 x, S32 y);
+
protected:
enum {
MASK_CLOTHING = 0x01,
@@ -431,6 +433,7 @@ public:
static void setMenuItemEnabled(LLContextMenu* menu, const std::string& name, bool val);
static void updateMask(U32& mask, LLAssetType::EType at);
static void createNewWearable(const LLUUID& item_id);
+ static void createNewWearableByType(LLWearableType::EType type);
LLWearableItemsList* mParent;
};
@@ -469,6 +472,8 @@ public:
void setSortOrder(ESortOrder sort_order, bool sort_now = true);
+ void setMenuWearableType(LLWearableType::EType type) { mMenuWearableType = type; }
+
protected:
friend class LLUICtrlFactory;
LLWearableItemsList(const LLWearableItemsList::Params& p);
@@ -479,6 +484,8 @@ protected:
bool mWornIndicationEnabled;
ESortOrder mSortOrder;
+
+ LLWearableType::EType mMenuWearableType;
};
#endif //LL_LLWEARABLEITEMSLIST_H
diff --git a/indra/newview/llwlhandlers.cpp b/indra/newview/llwlhandlers.cpp
index 6b8374fd48..730aa3774f 100644
--- a/indra/newview/llwlhandlers.cpp
+++ b/indra/newview/llwlhandlers.cpp
@@ -51,7 +51,7 @@ bool LLEnvironmentRequest::initiate(LLEnvironment::environment_apply_fn cb)
if (!cur_region->capabilitiesReceived())
{
LL_INFOS("WindlightCaps") << "Deferring windlight settings request until we've got region caps" << LL_ENDL;
- cur_region->setCapabilitiesReceivedCallback([cb](LLUUID region_id) { LLEnvironmentRequest::onRegionCapsReceived(region_id, cb); });
+ cur_region->setCapabilitiesReceivedCallback([cb](const LLUUID &region_id) { LLEnvironmentRequest::onRegionCapsReceived(region_id, cb); });
return false;
}
diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index d7c7288293..46c8c5b11a 100644
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -6553,7 +6553,7 @@ void LLPipeline::enableLightsDynamic()
{
gPipeline.enableLightsAvatar();
}
- else if (gAgentAvatarp->mSpecialRenderMode >= 1) // anim preview
+ else if (gAgentAvatarp->mSpecialRenderMode == 2) // anim preview
{
gPipeline.enableLightsAvatarEdit(LLColor4(0.7f, 0.6f, 0.3f, 1.f));
}
diff --git a/indra/newview/skins/default/xui/en/floater_joystick.xml b/indra/newview/skins/default/xui/en/floater_joystick.xml
index 3dfdf8e1a5..7d2cea1fe5 100644
--- a/indra/newview/skins/default/xui/en/floater_joystick.xml
+++ b/indra/newview/skins/default/xui/en/floater_joystick.xml
@@ -8,27 +8,32 @@
title="JOYSTICK CONFIGURATION"
width="569">
<floater.string
- name="NoDevice">
- no device detected
+ name="JoystickDisabled">
+ None
</floater.string>
- <check_box
- bottom="38"
- height="10"
- control_name="JoystickEnabled"
- halign="left"
- label="Enable Joystick:"
+ <text
+ type="string"
layout="topleft"
+ follows="left|top"
+ halign="left"
+ height="12"
+ top="22"
left="14"
- name="enable_joystick"
- width="60" />
- <text
- bottom="32"
+ width="50"
+ mouse_opaque="false"
+ name="joystick_lbl">
+ Joystick:
+ </text>
+ <combo_box
+ allow_text_entry="false"
+ follows="left|top"
layout="topleft"
- left="120"
- name="joystick_type"
- width="380" />
+ name="joystick_combo"
+ top="19"
+ left_pad="4"
+ width="300"/>
<spinner
- bottom="48"
+ bottom="56"
height="10"
control_name="JoystickAxis1"
decimal_digits="0"
@@ -42,7 +47,7 @@
name="JoystickAxis1"
width="140" />
<spinner
- bottom="48"
+ bottom_delta="0"
height="10"
control_name="JoystickAxis2"
decimal_digits="0"
@@ -56,7 +61,7 @@
name="JoystickAxis2"
width="140" />
<spinner
- bottom="48"
+ bottom_delta="0"
height="10"
control_name="JoystickAxis0"
decimal_digits="0"
@@ -70,7 +75,7 @@
name="JoystickAxis0"
width="140" />
<spinner
- bottom="68"
+ bottom="76"
height="10"
control_name="JoystickAxis4"
decimal_digits="0"
@@ -84,7 +89,7 @@
name="JoystickAxis4"
width="140" />
<spinner
- bottom="68"
+ bottom_delta="0"
height="10"
control_name="JoystickAxis5"
decimal_digits="0"
@@ -98,7 +103,7 @@
name="JoystickAxis5"
width="140" />
<spinner
- bottom="68"
+ bottom_delta="0"
height="10"
control_name="JoystickAxis3"
decimal_digits="0"
@@ -112,7 +117,7 @@
name="JoystickAxis3"
width="140" />
<spinner
- bottom="88"
+ bottom="96"
height="10"
control_name="JoystickAxis6"
decimal_digits="0"
@@ -162,12 +167,12 @@
left="37"
mouse_opaque="false"
name="Control Modes:"
- top="110"
+ top="118"
width="102">
Control Modes:
</text>
<check_box
- bottom="127"
+ bottom="134"
height="10"
control_name="JoystickAvatarEnabled"
halign="center"
@@ -177,7 +182,7 @@
name="JoystickAvatarEnabled"
width="60" />
<check_box
- bottom="127"
+ bottom_delta="0"
height="10"
control_name="JoystickBuildEnabled"
halign="center"
@@ -187,7 +192,7 @@
name="JoystickBuildEnabled"
width="60" />
<check_box
- bottom="127"
+ bottom_delta="0"
height="10"
control_name="JoystickFlycamEnabled"
halign="center"
@@ -203,7 +208,7 @@
left="359"
name="axis_view"
show_label="true"
- top="135"
+ top="143"
width="200">
<stat_bar
bar_max="2"
@@ -266,7 +271,7 @@
<text
type="string"
length="1"
- bottom="144"
+ bottom="152"
halign="right"
layout="topleft"
left="3"
@@ -275,7 +280,7 @@
X Scale
</text>
<spinner
- bottom="144"
+ bottom_delta="0"
height="10"
control_name="AvatarAxisScale1"
decimal_digits="2"
@@ -287,7 +292,7 @@
name="AvatarAxisScale1"
width="56" />
<spinner
- bottom="144"
+ bottom_delta="0"
height="10"
control_name="BuildAxisScale1"
decimal_digits="2"
@@ -299,7 +304,7 @@
name="BuildAxisScale1"
width="56" />
<spinner
- bottom="144"
+ bottom_delta="0"
height="10"
control_name="FlycamAxisScale1"
decimal_digits="2"
@@ -313,7 +318,7 @@
<text
type="string"
length="1"
- bottom="164"
+ bottom="172"
halign="right"
layout="topleft"
left="3"
@@ -322,7 +327,7 @@
Y Scale
</text>
<spinner
- bottom="164"
+ bottom_delta="0"
height="10"
control_name="AvatarAxisScale2"
decimal_digits="2"
@@ -334,7 +339,7 @@
name="AvatarAxisScale2"
width="56" />
<spinner
- bottom="164"
+ bottom_delta="0"
height="10"
control_name="BuildAxisScale2"
decimal_digits="2"
@@ -346,7 +351,7 @@
name="BuildAxisScale2"
width="56" />
<spinner
- bottom="164"
+ bottom_delta="0"
height="10"
control_name="FlycamAxisScale2"
decimal_digits="2"
@@ -360,7 +365,7 @@
<text
type="string"
length="1"
- bottom="184"
+ bottom="192"
halign="right"
layout="topleft"
left="3"
@@ -369,7 +374,7 @@
Z Scale
</text>
<spinner
- bottom="184"
+ bottom_delta="0"
height="10"
control_name="AvatarAxisScale0"
decimal_digits="2"
@@ -381,7 +386,7 @@
name="AvatarAxisScale0"
width="56" />
<spinner
- bottom="184"
+ bottom_delta="0"
height="10"
control_name="BuildAxisScale0"
decimal_digits="2"
@@ -393,7 +398,7 @@
name="BuildAxisScale0"
width="56" />
<spinner
- bottom="184"
+ bottom_delta="0"
height="10"
control_name="FlycamAxisScale0"
decimal_digits="2"
@@ -407,7 +412,7 @@
<text
type="string"
length="1"
- bottom="204"
+ bottom="212"
halign="right"
layout="topleft"
left="3"
@@ -416,7 +421,7 @@
Pitch Scale
</text>
<spinner
- bottom="204"
+ bottom_delta="0"
height="10"
control_name="AvatarAxisScale4"
decimal_digits="2"
@@ -428,7 +433,7 @@
name="AvatarAxisScale4"
width="56" />
<spinner
- bottom="204"
+ bottom_delta="0"
height="10"
control_name="BuildAxisScale4"
decimal_digits="2"
@@ -440,7 +445,7 @@
name="BuildAxisScale4"
width="56" />
<spinner
- bottom="204"
+ bottom_delta="0"
height="10"
control_name="FlycamAxisScale4"
decimal_digits="2"
@@ -454,7 +459,7 @@
<text
type="string"
length="1"
- bottom="224"
+ bottom="232"
halign="right"
layout="topleft"
left="3"
@@ -463,7 +468,7 @@
Yaw Scale
</text>
<spinner
- bottom="224"
+ bottom_delta="0"
height="10"
control_name="AvatarAxisScale5"
decimal_digits="2"
@@ -475,7 +480,7 @@
name="AvatarAxisScale5"
width="56" />
<spinner
- bottom="224"
+ bottom_delta="0"
height="10"
control_name="BuildAxisScale5"
decimal_digits="2"
@@ -487,7 +492,7 @@
name="BuildAxisScale5"
width="56" />
<spinner
- bottom="224"
+ bottom_delta="0"
height="10"
control_name="FlycamAxisScale5"
decimal_digits="2"
@@ -501,7 +506,7 @@
<text
type="string"
length="1"
- bottom="244"
+ bottom="252"
halign="right"
layout="topleft"
left="3"
@@ -510,7 +515,7 @@
Roll Scale
</text>
<spinner
- bottom="244"
+ bottom_delta="0"
height="10"
control_name="BuildAxisScale3"
decimal_digits="2"
@@ -522,7 +527,7 @@
name="BuildAxisScale3"
width="56" />
<spinner
- bottom="244"
+ bottom_delta="0"
height="10"
control_name="FlycamAxisScale3"
decimal_digits="2"
@@ -536,7 +541,7 @@
<text
type="string"
length="1"
- bottom="274"
+ bottom="282"
halign="right"
layout="topleft"
left="3"
@@ -545,7 +550,7 @@
X Dead Zone
</text>
<spinner
- bottom="274"
+ bottom_delta="0"
height="10"
control_name="AvatarAxisDeadZone1"
decimal_digits="2"
@@ -556,7 +561,7 @@
name="AvatarAxisDeadZone1"
width="56" />
<spinner
- bottom="274"
+ bottom_delta="0"
height="10"
control_name="BuildAxisDeadZone1"
decimal_digits="2"
@@ -567,7 +572,7 @@
name="BuildAxisDeadZone1"
width="56" />
<spinner
- bottom="274"
+ bottom_delta="0"
height="10"
control_name="FlycamAxisDeadZone1"
decimal_digits="2"
@@ -580,7 +585,7 @@
<text
type="string"
length="1"
- bottom="294"
+ bottom="302"
halign="right"
layout="topleft"
left="3"
@@ -589,7 +594,7 @@
Y Dead Zone
</text>
<spinner
- bottom="294"
+ bottom_delta="0"
height="10"
control_name="AvatarAxisDeadZone2"
decimal_digits="2"
@@ -600,7 +605,7 @@
name="AvatarAxisDeadZone2"
width="56" />
<spinner
- bottom="294"
+ bottom_delta="0"
height="10"
control_name="BuildAxisDeadZone2"
decimal_digits="2"
@@ -611,7 +616,7 @@
name="BuildAxisDeadZone2"
width="56" />
<spinner
- bottom="294"
+ bottom_delta="0"
height="10"
control_name="FlycamAxisDeadZone2"
decimal_digits="2"
@@ -624,7 +629,7 @@
<text
type="string"
length="1"
- bottom="314"
+ bottom="322"
halign="right"
layout="topleft"
left="3"
@@ -633,7 +638,7 @@
Z Dead Zone
</text>
<spinner
- bottom="314"
+ bottom_delta="0"
height="10"
control_name="AvatarAxisDeadZone0"
decimal_digits="2"
@@ -644,7 +649,7 @@
name="AvatarAxisDeadZone0"
width="56" />
<spinner
- bottom="314"
+ bottom_delta="0"
height="10"
control_name="BuildAxisDeadZone0"
decimal_digits="2"
@@ -655,7 +660,7 @@
name="BuildAxisDeadZone0"
width="56" />
<spinner
- bottom="314"
+ bottom_delta="0"
height="10"
control_name="FlycamAxisDeadZone0"
decimal_digits="2"
@@ -668,7 +673,7 @@
<text
type="string"
length="1"
- bottom="334"
+ bottom="342"
halign="right"
layout="topleft"
left="2"
@@ -677,7 +682,7 @@
Pitch Dead Zone
</text>
<spinner
- bottom="334"
+ bottom_delta="0"
height="10"
control_name="AvatarAxisDeadZone4"
decimal_digits="2"
@@ -688,7 +693,7 @@
name="AvatarAxisDeadZone4"
width="56" />
<spinner
- bottom="334"
+ bottom_delta="0"
height="10"
control_name="BuildAxisDeadZone4"
decimal_digits="2"
@@ -699,7 +704,7 @@
name="BuildAxisDeadZone4"
width="56" />
<spinner
- bottom="334"
+ bottom_delta="0"
height="10"
control_name="FlycamAxisDeadZone4"
decimal_digits="2"
@@ -712,7 +717,7 @@
<text
type="string"
length="1"
- bottom="354"
+ bottom="362"
halign="right"
layout="topleft"
left="3"
@@ -721,7 +726,7 @@
Yaw Dead Zone
</text>
<spinner
- bottom="354"
+ bottom_delta="0"
height="10"
control_name="AvatarAxisDeadZone5"
decimal_digits="2"
@@ -732,7 +737,7 @@
name="AvatarAxisDeadZone5"
width="56" />
<spinner
- bottom="354"
+ bottom_delta="0"
height="10"
control_name="BuildAxisDeadZone5"
decimal_digits="2"
@@ -743,7 +748,7 @@
name="BuildAxisDeadZone5"
width="56" />
<spinner
- bottom="354"
+ bottom_delta="0"
height="10"
control_name="FlycamAxisDeadZone5"
decimal_digits="2"
@@ -756,7 +761,7 @@
<text
type="string"
length="1"
- bottom="374"
+ bottom="382"
halign="right"
layout="topleft"
left="3"
@@ -765,7 +770,7 @@
Roll Dead Zone
</text>
<spinner
- bottom="374"
+ bottom_delta="0"
height="10"
control_name="BuildAxisDeadZone3"
decimal_digits="2"
@@ -776,7 +781,7 @@
name="BuildAxisDeadZone3"
width="56" />
<spinner
- bottom="374"
+ bottom_delta="0"
height="10"
control_name="FlycamAxisDeadZone3"
decimal_digits="2"
@@ -789,7 +794,7 @@
<text
type="string"
length="1"
- bottom="402"
+ bottom="410"
halign="right"
layout="topleft"
left="3"
@@ -810,7 +815,7 @@
min_val="1"
name="AvatarFeathering"
show_text="false"
- top="402"
+ top="410"
width="73" />
<slider
control_name="BuildFeathering"
@@ -845,7 +850,7 @@
<text
type="string"
length="1"
- bottom="430"
+ bottom="438"
halign="right"
layout="topleft"
left="3"
@@ -854,7 +859,7 @@
Zoom Scale
</text>
<spinner
- bottom="430"
+ bottom_delta="0"
height="10"
control_name="FlycamAxisScale6"
decimal_digits="2"
@@ -868,7 +873,7 @@
<text
type="string"
length="1"
- bottom="450"
+ bottom="458"
halign="right"
layout="topleft"
left="3"
@@ -877,7 +882,7 @@
Zoom Dead Zone
</text>
<spinner
- bottom="450"
+ bottom_delta="0"
height="10"
control_name="FlycamAxisDeadZone6"
decimal_digits="2"
@@ -894,7 +899,7 @@
layout="topleft"
left="359"
name="SpaceNavigatorDefaults"
- top="429"
+ top="437"
width="200" />
<button
follows="right|bottom"
diff --git a/indra/newview/skins/default/xui/en/menu_wearable_list_item.xml b/indra/newview/skins/default/xui/en/menu_wearable_list_item.xml
index cb429812e2..20c81c983b 100644
--- a/indra/newview/skins/default/xui/en/menu_wearable_list_item.xml
+++ b/indra/newview/skins/default/xui/en/menu_wearable_list_item.xml
@@ -4,6 +4,7 @@
<menu_item_call
label="Replace"
layout="topleft"
+ visible="false"
name="wear_replace">
<on_click
function="Wearable.Wear" />
@@ -11,6 +12,7 @@
<menu_item_call
label="Wear"
layout="topleft"
+ visible="false"
name="wear_wear">
<on_click
function="Wearable.Wear" />
@@ -18,6 +20,7 @@
<menu_item_call
label="Add"
layout="topleft"
+ visible="false"
name="wear_add">
<on_click
function="Wearable.Add" />
@@ -26,17 +29,20 @@
label="Touch"
layout="topleft"
name="touch"
+ visible="false"
on_click.function="Attachment.Touch"
/>
<menu_item_call
label="Edit"
layout="topleft"
name="edit"
+ visible="false"
on_click.function="Wearable.Edit"
/>
<menu_item_call
label="Take Off / Detach"
layout="topleft"
+ visible="false"
name="take_off_or_detach">
<on_click
function="Wearable.TakeOffDetach" />
@@ -44,6 +50,7 @@
<menu_item_call
label="Detach"
layout="topleft"
+ visible="false"
name="detach">
<on_click
function="Attachment.Detach" />
@@ -59,6 +66,7 @@
<menu_item_call
label="Take Off"
layout="topleft"
+ visible="false"
name="take_off">
<on_click
function="Clothing.TakeOff" />
@@ -66,6 +74,7 @@
<menu_item_call
label="Item Profile"
layout="topleft"
+ visible="false"
name="object_profile">
<on_click
function="Attachment.Profile" />
@@ -73,6 +82,7 @@
<menu_item_call
label="Show Original"
layout="topleft"
+ visible="false"
name="show_original">
<on_click
function="Wearable.ShowOriginal" />
@@ -80,6 +90,7 @@
<menu_item_call
label="Create New"
layout="topleft"
+ visible="false"
name="create_new"
translate="false">
<on_click
@@ -88,6 +99,7 @@
<menu_item_call
label="--no options--"
layout="topleft"
+ visible="false"
name="--no options--"
translate="false">
</menu_item_call>
diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml
index 29d570de64..2f4da4f9b7 100644
--- a/indra/newview/skins/default/xui/en/notifications.xml
+++ b/indra/newview/skins/default/xui/en/notifications.xml
@@ -9595,6 +9595,10 @@ If you continue to have problems, please visit the [SUPPORT_SITE].
<global name="UnsupportedRAM">
- Your system memory does not meet the minimum requirements.
</global>
+
+ <global name="LLLeapUpdaterFailure">
+Failed to launch updater service [UPDATER_APP]. Please verify the viewer is installed correctly and has the necessary permissions to run. If you continue to experience issues, please visit the [SUPPORT_SITE].
+ </global>
<!-- these are alert strings from server. the name needs to match entire the server string, and needs to be changed
whenever the server string changes -->
diff --git a/indra/newview/skins/default/xui/en/panel_group_notices.xml b/indra/newview/skins/default/xui/en/panel_group_notices.xml
index 47aceb2c2e..a5aca5c72b 100644
--- a/indra/newview/skins/default/xui/en/panel_group_notices.xml
+++ b/indra/newview/skins/default/xui/en/panel_group_notices.xml
@@ -59,7 +59,8 @@ Maximum 200 per group daily
<scroll_list.columns
label="Date"
name="date"
- width="60" />
+ sort_column="sort"
+ width="100" />
<scroll_list.columns
name="sort"
width="-1" />
diff --git a/indra/newview/skins/default/xui/en/panel_outfit_edit.xml b/indra/newview/skins/default/xui/en/panel_outfit_edit.xml
index afce9f6eb5..3f7444dec3 100644
--- a/indra/newview/skins/default/xui/en/panel_outfit_edit.xml
+++ b/indra/newview/skins/default/xui/en/panel_outfit_edit.xml
@@ -321,6 +321,7 @@ It is calculated as border_size + 2*UIResizeBarOverlap
name="folder_view"
top_pad="0"
width="313"
+ preinitialize_views="false"
visible="false"/>
<panel name="filtered_wearables_panel"
background_opaque="true"
diff --git a/indra/newview/skins/default/xui/en/panel_script_ed.xml b/indra/newview/skins/default/xui/en/panel_script_ed.xml
index ed37e9e2cc..545c01935b 100644
--- a/indra/newview/skins/default/xui/en/panel_script_ed.xml
+++ b/indra/newview/skins/default/xui/en/panel_script_ed.xml
@@ -145,10 +145,6 @@
name="Help"
width="112">
<menu_item_call
- label="Help..."
- layout="topleft"
- name="Help..." />
- <menu_item_call
label="Keyword Help..."
layout="topleft"
name="Keyword Help..." />
diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py
index 90a2af98f7..6d231040f7 100755
--- a/indra/newview/viewer_manifest.py
+++ b/indra/newview/viewer_manifest.py
@@ -260,6 +260,9 @@ class ViewerManifest(LLManifest):
app_suffix=self.channel_variant()
return CHANNEL_VENDOR_BASE + ' ' + app_suffix
+ def exec_name(self):
+ return "SecondLifeViewer"
+
def app_name_oneword(self):
return ''.join(self.app_name().split())
@@ -419,10 +422,9 @@ class WindowsManifest(ViewerManifest):
build_data_json_platform = 'win'
def final_exe(self):
- return self.app_name_oneword()+".exe"
+ return self.exec_name()+".exe"
def finish_build_data_dict(self, build_data_dict):
- #MAINT-7294: Windows exe names depend on channel name, so write that in also
build_data_dict['Executable'] = self.final_exe()
build_data_dict['AppName'] = self.app_name()
return build_data_dict