summaryrefslogtreecommitdiff
path: root/indra
diff options
context:
space:
mode:
authorCallum Prentice <callum@gmail.com>2021-02-03 09:31:32 -0800
committerCallum Prentice <callum@gmail.com>2021-02-03 09:31:32 -0800
commitd26567915cd80999260edffc41df467a7cbbd80c (patch)
tree84072d2a7a5e6afa7b57850ed4b325439cb2be16 /indra
parent7528855442a100cee379b9e409280a69caa78bba (diff)
parent21565a1f3fe1ae737e2f91c58be2c3cb0b5a2fec (diff)
Merge with Master after Viewer release
Diffstat (limited to 'indra')
-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.cpp74
-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.xml22
-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.cpp235
-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/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/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
116 files changed, 1865 insertions, 677 deletions
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 1348fb0763..a4600069ce 100644
--- a/indra/llappearance/lltexlayer.cpp
+++ b/indra/llappearance/lltexlayer.cpp
@@ -726,8 +726,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;
@@ -977,7 +977,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 3e7be26e59..350a8eb120 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 604fb4e946..ee02a90b54 100644
--- a/indra/llrender/llgl.cpp
+++ b/indra/llrender/llgl.cpp
@@ -965,6 +965,80 @@ 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["debug_gpu"] = mDebugGPU;
+ 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 91ef4e9102..966c4b3c77 100644
--- a/indra/llrender/llgl.h
+++ b/indra/llrender/llgl.h
@@ -165,6 +165,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