summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--BuildParams19
-rw-r--r--indra/fix-incredibuild.py38
-rw-r--r--indra/llimage/llimage.cpp2
-rw-r--r--indra/llrender/llimagegl.cpp3
-rw-r--r--indra/newview/CMakeLists.txt4
-rw-r--r--indra/newview/app_settings/settings.xml22
-rw-r--r--indra/newview/featuretable.txt4
-rw-r--r--indra/newview/featuretable_linux.txt4
-rw-r--r--indra/newview/featuretable_mac.txt4
-rw-r--r--indra/newview/featuretable_xp.txt554
-rw-r--r--indra/newview/llagentwearables.cpp2
-rw-r--r--indra/newview/llappearancemgr.cpp3
-rw-r--r--indra/newview/llappviewer.cpp48
-rw-r--r--indra/newview/llappviewer.h3
-rw-r--r--indra/newview/llattachmentsmgr.cpp131
-rw-r--r--indra/newview/llattachmentsmgr.h73
-rw-r--r--indra/newview/llavatarlist.cpp17
-rw-r--r--indra/newview/llavatarlist.h5
-rw-r--r--indra/newview/llavatarlistitem.cpp99
-rw-r--r--indra/newview/llavatarlistitem.h28
-rw-r--r--indra/newview/llcallingcard.h2
-rw-r--r--indra/newview/lldynamictexture.cpp7
-rw-r--r--indra/newview/llfeaturemanager.cpp62
-rw-r--r--indra/newview/llfloatersidetraytab.cpp45
-rw-r--r--indra/newview/llfloatersidetraytab.h47
-rw-r--r--indra/newview/llinventorybridge.cpp77
-rw-r--r--indra/newview/llinventoryicon.cpp2
-rw-r--r--indra/newview/llinventoryicon.h2
-rw-r--r--indra/newview/llpanelgroup.cpp14
-rw-r--r--indra/newview/llpanelgroup.h2
-rw-r--r--indra/newview/llpanelpeople.cpp10
-rw-r--r--indra/newview/llsidetray.cpp49
-rw-r--r--indra/newview/llsidetray.h13
-rw-r--r--indra/newview/lltexturecache.cpp23
-rw-r--r--indra/newview/lltexturecache.h2
-rw-r--r--indra/newview/lltextureview.cpp8
-rw-r--r--indra/newview/llviewerfloaterreg.cpp3
-rw-r--r--indra/newview/llviewerregion.cpp164
-rw-r--r--indra/newview/llviewerregion.h10
-rw-r--r--indra/newview/llviewerstats.h2
-rw-r--r--indra/newview/llviewerwindow.cpp9
-rw-r--r--indra/newview/llvoavatar.cpp4
-rw-r--r--indra/newview/llvoavatarself.cpp14
-rw-r--r--indra/newview/llvoavatarself.h1
-rw-r--r--indra/newview/llvocache.cpp538
-rw-r--r--indra/newview/llvocache.h86
-rw-r--r--indra/newview/llwearabletype.cpp11
-rw-r--r--indra/newview/llworld.cpp3
-rw-r--r--indra/newview/noise.cpp1
-rw-r--r--indra/newview/skins/default/textures/icons/Generic_Group_Large.pngbin7061 -> 7507 bytes
-rw-r--r--indra/newview/skins/default/textures/icons/Generic_Person_Large.pngbin1630 -> 51508 bytes
-rw-r--r--indra/newview/skins/default/textures/icons/Inv_Invalid.pngbin0 -> 329 bytes
-rw-r--r--indra/newview/skins/default/textures/textures.xml10
-rw-r--r--indra/newview/skins/default/xui/en/floater_side_bar_tab.xml3
-rw-r--r--indra/newview/skins/default/xui/en/menu_people_friends_view_sort.xml8
-rw-r--r--indra/newview/skins/default/xui/en/panel_avatar_list_item.xml48
-rw-r--r--indra/newview/skins/default/xui/en/panel_landmark_info.xml2
-rw-r--r--indra/newview/skins/default/xui/en/panel_outfit_edit.xml2
-rw-r--r--indra/newview/skins/default/xui/en/panel_people.xml2
-rw-r--r--indra/newview/skins/default/xui/en/strings.xml2
60 files changed, 2002 insertions, 349 deletions
diff --git a/BuildParams b/BuildParams
index 6b7d15f6cc..f70488d942 100644
--- a/BuildParams
+++ b/BuildParams
@@ -56,6 +56,7 @@ viewer-release.build_viewer_update_version_manager = true
viewer-development-import.build_debug_release_separately = true
viewer-development-fixes.build_debug_release_separately = true
+viewer-development-tweaks.build_debug_release_separately = true
# =======================================
# brad
@@ -78,18 +79,6 @@ brad-parabuild.build_server = false
brad-parabuild.build_server_tests = false
# ========================================
-# moss
-# ========================================
-
-mossbuild1.email = moss@lindenlab.com
-mossbuild1.build_server = false
-mossbuild1.build_server_tests = false
-
-mossbuild2.email = moss@lindenlab.com
-mossbuild2.build_server = false
-mossbuild2.build_server_tests = false
-
-# ========================================
# gooey
# ========================================
@@ -173,6 +162,12 @@ oz_viewer-review2_coverity.build_CYGWIN_RelWithDebInfo = false
oz_viewer-review2_coverity.build_CYGWIN_Release = false
# ========================================
+# tofu
+# ========================================
+
+tofu_viewer-development-staging.email = tofu.linden@lindenlab.com
+
+# ========================================
# enus
# ========================================
diff --git a/indra/fix-incredibuild.py b/indra/fix-incredibuild.py
new file mode 100644
index 0000000000..b96b00dc85
--- /dev/null
+++ b/indra/fix-incredibuild.py
@@ -0,0 +1,38 @@
+import sys
+import os
+import glob
+
+def delete_file_types(path, filetypes):
+ if os.path.exists(path):
+ print 'Cleaning: ' + path
+ orig_dir = os.getcwd();
+ os.chdir(path)
+ filelist = []
+ for type in filetypes:
+ filelist.extend(glob.glob(type))
+ for file in filelist:
+ os.remove(file)
+ os.chdir(orig_dir)
+
+def main():
+ build_types = ['*.exp','*.exe','*.pdb','*.idb',
+ '*.ilk','*.lib','*.obj','*.ib_pdb_index']
+ pch_types = ['*.pch']
+ delete_file_types("build-vc80/newview/Release", build_types)
+ delete_file_types("build-vc80/newview/secondlife-bin.dir/Release/",
+ pch_types)
+ delete_file_types("build-vc80/newview/RelWithDebInfo", build_types)
+ delete_file_types("build-vc80/newview/secondlife-bin.dir/RelWithDebInfo/",
+ pch_types)
+ delete_file_types("build-vc80/newview/Debug", build_types)
+ delete_file_types("build-vc80/newview/secondlife-bin.dir/Debug/",
+ pch_types)
+
+
+ delete_file_types("build-vc80/test/RelWithDebInfo", build_types)
+ delete_file_types("build-vc80/test/test.dir/RelWithDebInfo/",
+ pch_types)
+
+
+if __name__ == "__main__":
+ main()
diff --git a/indra/llimage/llimage.cpp b/indra/llimage/llimage.cpp
index be0ab9fcb7..5c33b675ca 100644
--- a/indra/llimage/llimage.cpp
+++ b/indra/llimage/llimage.cpp
@@ -147,7 +147,7 @@ U8* LLImageBase::allocateData(S32 size)
size = mWidth * mHeight * mComponents;
if (size <= 0)
{
- llerrs << llformat("LLImageBase::allocateData called with bad dimensions: %dx%dx%d",mWidth,mHeight,mComponents) << llendl;
+ llerrs << llformat("LLImageBase::allocateData called with bad dimensions: %dx%dx%d",mWidth,mHeight,(S32)mComponents) << llendl;
}
}
diff --git a/indra/llrender/llimagegl.cpp b/indra/llrender/llimagegl.cpp
index 90fcf6ab3f..9d037f2565 100644
--- a/indra/llrender/llimagegl.cpp
+++ b/indra/llrender/llimagegl.cpp
@@ -1055,7 +1055,8 @@ BOOL LLImageGL::setSubImageFromFrameBuffer(S32 fb_x, S32 fb_y, S32 x_pos, S32 y_
{
llinfos << "Calling glCopyTexSubImage2D(...)" << llendl ;
checkTexSize(true) ;
- llcallstacks << fb_x << " : " << fb_y << " : " << x_pos << " : " << y_pos << " : " << width << " : " << height << llcallstacksendl ;
+ llcallstacks << fb_x << " : " << fb_y << " : " << x_pos << " : " << y_pos << " : " << width << " : " << height <<
+ " : " << (S32)mComponents << llcallstacksendl ;
}
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, fb_x, fb_y, x_pos, y_pos, width, height);
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index 630902c48f..592f772549 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -82,6 +82,7 @@ set(viewer_SOURCE_FILES
llappviewerlistener.cpp
llassetuploadqueue.cpp
llassetuploadresponders.cpp
+ llattachmentsmgr.cpp
llaudiosourcevo.cpp
llavataractions.cpp
llavatariconctrl.cpp
@@ -203,6 +204,7 @@ set(viewer_SOURCE_FILES
llfloatersearch.cpp
llfloatersellland.cpp
llfloatersettingsdebug.cpp
+ llfloatersidetraytab.cpp
llfloatersnapshot.cpp
llfloatertelehub.cpp
llfloatertestinspectors.cpp
@@ -604,6 +606,7 @@ set(viewer_HEADER_FILES
llappviewerlistener.h
llassetuploadqueue.h
llassetuploadresponders.h
+ llattachmentsmgr.h
llaudiosourcevo.h
llavataractions.h
llavatariconctrl.h
@@ -727,6 +730,7 @@ set(viewer_HEADER_FILES
llfloatersearch.h
llfloatersellland.h
llfloatersettingsdebug.h
+ llfloatersidetraytab.h
llfloatersnapshot.h
llfloatertelehub.h
llfloatertestinspectors.h
diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index 6285df31c0..8fe33d4fa3 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -1147,6 +1147,17 @@
<key>Value</key>
<string />
</map>
+ <key>CacheNumberOfRegionsForObjects</key>
+ <map>
+ <key>Comment</key>
+ <string>Controls number of regions to be cached for objects, ranges from 16 to 128.</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>U32</string>
+ <key>Value</key>
+ <integer>128</integer>
+ </map>
<key>CacheSize</key>
<map>
<key>Comment</key>
@@ -8890,6 +8901,17 @@
<key>Value</key>
<integer>1</integer>
</map>
+ <key>FriendsListShowPermissions</key>
+ <map>
+ <key>Comment</key>
+ <string>Show/hide permission icons in the friend list</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>1</integer>
+ </map>
<key>NearbyListShowIcons</key>
<map>
<key>Comment</key>
diff --git a/indra/newview/featuretable.txt b/indra/newview/featuretable.txt
index 9440e877df..e3fc9d4949 100644
--- a/indra/newview/featuretable.txt
+++ b/indra/newview/featuretable.txt
@@ -1,4 +1,4 @@
-version 22
+version 23
// NOTE: This is mostly identical to featuretable_mac.txt with a few differences
// Should be combined into one table
@@ -81,7 +81,7 @@ RenderTerrainDetail 1 0
RenderTerrainLODFactor 1 1
RenderTreeLODFactor 1 0
RenderUseImpostors 1 1
-RenderVolumeLODFactor 1 0
+RenderVolumeLODFactor 1 0.5
VertexShaderEnable 1 0
WindLightUseAtmosShaders 1 0
WLSkyDetail 1 48
diff --git a/indra/newview/featuretable_linux.txt b/indra/newview/featuretable_linux.txt
index 85b8564138..1bad7e5260 100644
--- a/indra/newview/featuretable_linux.txt
+++ b/indra/newview/featuretable_linux.txt
@@ -1,4 +1,4 @@
-version 21
+version 22
// NOTE: This is mostly identical to featuretable_mac.txt with a few differences
// Should be combined into one table
@@ -80,7 +80,7 @@ RenderTerrainDetail 1 0
RenderTerrainLODFactor 1 1
RenderTreeLODFactor 1 0
RenderUseImpostors 1 1
-RenderVolumeLODFactor 1 0
+RenderVolumeLODFactor 1 0.5
VertexShaderEnable 1 0
WindLightUseAtmosShaders 1 0
WLSkyDetail 1 48
diff --git a/indra/newview/featuretable_mac.txt b/indra/newview/featuretable_mac.txt
index 2095f3a81d..4fba47e3df 100644
--- a/indra/newview/featuretable_mac.txt
+++ b/indra/newview/featuretable_mac.txt
@@ -1,4 +1,4 @@
-version 21
+version 22
// NOTE: This is mostly identical to featuretable_mac.txt with a few differences
// Should be combined into one table
@@ -81,7 +81,7 @@ RenderTerrainDetail 1 0
RenderTerrainLODFactor 1 1
RenderTreeLODFactor 1 0
RenderUseImpostors 1 1
-RenderVolumeLODFactor 1 0
+RenderVolumeLODFactor 1 0.5
RenderWaterReflections 1 0
VertexShaderEnable 1 0
WindLightUseAtmosShaders 1 0
diff --git a/indra/newview/featuretable_xp.txt b/indra/newview/featuretable_xp.txt
new file mode 100644
index 0000000000..9b901022c4
--- /dev/null
+++ b/indra/newview/featuretable_xp.txt
@@ -0,0 +1,554 @@
+version 23
+
+// NOTE: This is mostly identical to featuretable_mac.txt with a few differences
+// Should be combined into one table
+
+//
+// Generates lists of feature mask that can be applied on top of each other.
+//
+// // Begin comments
+// list <name>
+// Starts a feature list named <name>
+// <name> <available> <recommended>
+// <name> is the name of a feature
+// <available> is 0 or 1, whether the feature is available
+// <recommended> is an F32 which is the recommended value
+//
+// For now, the first list read sets up all of the default values
+//
+
+
+//
+// All contains everything at their default settings for high end machines
+// NOTE: All settings are set to the MIN of applied values, including 'all'!
+//
+list all
+RenderAnisotropic 1 1
+RenderAvatarCloth 1 1
+RenderAvatarLODFactor 1 1.0
+RenderAvatarMaxVisible 1 12
+RenderAvatarVP 1 1
+RenderCubeMap 1 1
+RenderDelayVBUpdate 1 0
+RenderFarClip 1 256
+RenderFlexTimeFactor 1 1.0
+RenderFogRatio 1 4.0
+RenderGamma 1 0
+RenderGlowResolutionPow 1 9
+RenderGround 1 1
+RenderMaxPartCount 1 8192
+RenderNightBrightness 1 1.0
+RenderObjectBump 1 1
+RenderReflectionDetail 1 4
+RenderTerrainDetail 1 1
+RenderTerrainLODFactor 1 2.0
+RenderTreeLODFactor 1 1.0
+RenderUseImpostors 1 1
+RenderVBOEnable 1 1
+RenderVolumeLODFactor 1 2.0
+UseStartScreen 1 1
+UseOcclusion 1 1
+VertexShaderEnable 1 1
+WindLightUseAtmosShaders 1 1
+WLSkyDetail 1 128
+Disregard128DefaultDrawDistance 1 1
+Disregard96DefaultDrawDistance 1 1
+RenderTextureMemoryMultiple 1 1.0
+RenderShaderLightingMaxLevel 1 3
+SkyUseClassicClouds 1 1
+RenderDeferred 1 0
+RenderDeferredSSAO 1 0
+RenderShadowDetail 1 0
+WatchdogDisabled 1 1
+RenderUseStreamVBO 1 1
+
+//
+// Low Graphics Settings
+//
+list Low
+RenderAnisotropic 1 0
+RenderAvatarCloth 1 0
+RenderAvatarLODFactor 1 0
+RenderAvatarMaxVisible 1 3
+RenderAvatarVP 1 0
+RenderFarClip 1 64
+RenderFlexTimeFactor 1 0
+RenderGlowResolutionPow 1 8
+RenderMaxPartCount 1 0
+RenderObjectBump 1 0
+RenderReflectionDetail 1 0
+RenderTerrainDetail 1 0
+RenderTerrainLODFactor 1 1
+RenderTreeLODFactor 1 0
+RenderUseImpostors 1 1
+RenderVolumeLODFactor 1 0.5
+VertexShaderEnable 1 0
+WindLightUseAtmosShaders 1 0
+WLSkyDetail 1 48
+SkyUseClassicClouds 1 0
+RenderDeferred 1 0
+RenderDeferredSSAO 1 0
+RenderShadowDetail 1 0
+
+
+//
+// Mid Graphics Settings
+//
+list Mid
+RenderAnisotropic 1 0
+RenderAvatarCloth 1 0
+RenderAvatarLODFactor 1 0.5
+RenderAvatarVP 1 1
+RenderFarClip 1 96
+RenderFlexTimeFactor 1 1.0
+RenderGlowResolutionPow 1 8
+RenderMaxPartCount 1 2048
+RenderObjectBump 1 1
+RenderReflectionDetail 1 0
+RenderTerrainDetail 1 1
+RenderTerrainLODFactor 1 1.0
+RenderTreeLODFactor 1 0.5
+RenderUseImpostors 1 1
+RenderVolumeLODFactor 1 1.125
+VertexShaderEnable 1 1
+WindLightUseAtmosShaders 1 0
+WLSkyDetail 1 48
+RenderDeferred 1 0
+RenderDeferredSSAO 1 0
+RenderShadowDetail 1 0
+
+
+//
+// High Graphics Settings (purty)
+//
+list High
+RenderAnisotropic 1 1
+RenderAvatarCloth 1 0
+RenderAvatarLODFactor 1 1.0
+RenderAvatarVP 1 1
+RenderFarClip 1 128
+RenderFlexTimeFactor 1 1.0
+RenderGlowResolutionPow 1 9
+RenderMaxPartCount 1 4096
+RenderObjectBump 1 1
+RenderReflectionDetail 1 2
+RenderTerrainDetail 1 1
+RenderTerrainLODFactor 1 2.0
+RenderTreeLODFactor 1 0.5
+RenderUseImpostors 1 1
+RenderVolumeLODFactor 1 1.125
+VertexShaderEnable 1 1
+WindLightUseAtmosShaders 1 1
+WLSkyDetail 1 48
+RenderDeferred 1 0
+RenderDeferredSSAO 1 0
+RenderShadowDetail 1 0
+
+
+//
+// Ultra graphics (REALLY PURTY!)
+//
+list Ultra
+RenderAnisotropic 1 1
+RenderAvatarCloth 1 1
+RenderAvatarLODFactor 1 1.0
+RenderAvatarVP 1 1
+RenderFarClip 1 256
+RenderFlexTimeFactor 1 1.0
+RenderGlowResolutionPow 1 9
+RenderMaxPartCount 1 8192
+RenderObjectBump 1 1
+RenderReflectionDetail 1 4
+RenderTerrainDetail 1 1
+RenderTerrainLODFactor 1 2.0
+RenderTreeLODFactor 1 1.0
+RenderUseImpostors 1 1
+RenderVolumeLODFactor 1 2.0
+VertexShaderEnable 1 1
+WindLightUseAtmosShaders 1 1
+WLSkyDetail 1 128
+RenderDeferred 1 0
+RenderDeferredSSAO 1 0
+RenderShadowDetail 1 0
+
+//
+// Class Unknown Hardware (unknown)
+//
+list Unknown
+RenderVBOEnable 1 0
+
+//
+// Class 0 Hardware (just old)
+//
+list Class0
+RenderVBOEnable 1 1
+
+//
+// Class 1 Hardware
+//
+list Class1
+RenderVBOEnable 1 1
+
+//
+// Class 2 Hardware (make it purty)
+//
+list Class2
+RenderVBOEnable 1 1
+
+//
+// Class 3 Hardware (make it purty)
+//
+list Class3
+RenderVBOEnable 1 1
+
+//
+// No Pixel Shaders available
+//
+list NoPixelShaders
+RenderAvatarVP 0 0
+RenderAvatarCloth 0 0
+RenderReflectionDetail 0 0
+VertexShaderEnable 0 0
+WindLightUseAtmosShaders 0 0
+RenderDeferred 0 0
+RenderDeferredSSAO 0 0
+RenderShadowDetail 0 0
+
+//
+// No Vertex Shaders available
+//
+list NoVertexShaders
+RenderAvatarVP 0 0
+RenderAvatarCloth 0 0
+RenderReflectionDetail 0 0
+VertexShaderEnable 0 0
+WindLightUseAtmosShaders 0 0
+RenderDeferred 0 0
+RenderDeferredSSAO 0 0
+RenderShadowDetail 0 0
+
+//
+// "Default" setups for safe, low, medium, high
+//
+list safe
+RenderAnisotropic 1 0
+RenderAvatarCloth 0 0
+RenderAvatarVP 0 0
+RenderObjectBump 0 0
+RenderMaxPartCount 1 1024
+RenderTerrainDetail 1 0
+RenderUseImpostors 0 0
+RenderVBOEnable 1 0
+RenderReflectionDetail 0 0
+WindLightUseAtmosShaders 0 0
+RenderDeferred 0 0
+RenderDeferredSSAO 0 0
+RenderShadowDetail 0 0
+
+//
+// CPU based feature masks
+//
+
+// 1Ghz or less (equiv)
+list CPUSlow
+RenderMaxPartCount 1 1024
+
+//
+// RAM based feature masks
+//
+list RAM256MB
+RenderObjectBump 0 0
+
+//
+// Graphics card based feature masks
+//
+list OpenGLPre15
+RenderVBOEnable 1 0
+
+list Intel
+RenderAnisotropic 1 0
+
+list GeForce2
+RenderAnisotropic 1 0
+RenderMaxPartCount 1 2048
+RenderTerrainDetail 1 0
+RenderVBOEnable 1 1
+
+list SiS
+UseOcclusion 0 0
+
+
+list Intel_830M
+RenderTerrainDetail 1 0
+RenderVBOEnable 1 0
+RenderUseImpostors 0 0
+
+list Intel_845G
+RenderTerrainDetail 1 0
+RenderVBOEnable 1 0
+RenderUseImpostors 0 0
+
+list Intel_855GM
+RenderTerrainDetail 1 0
+RenderVBOEnable 1 0
+RenderUseImpostors 0 0
+
+list Intel_865G
+RenderTerrainDetail 1 0
+RenderVBOEnable 1 0
+RenderUseImpostors 0 0
+
+list Intel_900
+RenderTerrainDetail 1 0
+RenderVBOEnable 1 0
+RenderUseImpostors 0 0
+
+list Intel_915GM
+RenderTerrainDetail 1 0
+RenderVBOEnable 1 0
+RenderUseImpostors 0 0
+
+list Intel_915G
+RenderTerrainDetail 1 0
+RenderVBOEnable 1 0
+RenderUseImpostors 0 0
+
+list Intel_945GM
+RenderTerrainDetail 1 0
+RenderVBOEnable 1 0
+
+list Intel_945G
+RenderTerrainDetail 1 0
+RenderVBOEnable 1 0
+
+list Intel_950
+RenderTerrainDetail 1 0
+RenderVBOEnable 1 0
+
+list Intel_965
+RenderTerrainDetail 1 0
+RenderVBOEnable 1 0
+RenderUseImpostors 1 0
+UseOcclusion 0 0
+
+list Intel_G33
+RenderTerrainDetail 1 0
+RenderVBOEnable 1 0
+
+list Intel_G45
+WindLightUseAtmosShaders 0 0
+
+list Intel_Bear_Lake
+RenderTerrainDetail 1 0
+RenderVBOEnable 1 0
+
+list Intel_Broadwater
+RenderTerrainDetail 1 0
+RenderVBOEnable 1 0
+
+list Intel_Brookdale
+RenderTerrainDetail 1 0
+RenderVBOEnable 1 0
+
+list Intel_Eaglelake
+WindLightUseAtmosShaders 0 0
+
+list Intel_Montara
+RenderTerrainDetail 1 0
+RenderVBOEnable 1 0
+
+list Intel_Springdale
+RenderTerrainDetail 1 0
+RenderVBOEnable 1 0
+
+
+list ATI_FireGL_5200
+RenderVBOEnable 1 0
+WindLightUseAtmosShaders 0 0
+
+
+list ATI_Mobility_Radeon_7xxx
+RenderVBOEnable 0 0
+
+list ATI_Radeon_7xxx
+RenderVBOEnable 0 0
+
+list ATI_All-in-Wonder_Radeon
+RenderVBOEnable 0 0
+
+list ATI_All-in-Wonder_7500
+RenderVBOEnable 0 0
+
+list ATI_Mobility_Radeon_9600
+Disregard96DefaultDrawDistance 1 0
+
+
+/// tweaked ATI to 96 Draw distance
+
+list ATI_Radeon_9000
+Disregard96DefaultDrawDistance 1 0
+list ATI_Radeon_9200
+Disregard96DefaultDrawDistance 1 0
+list ATI_Radeon_9500
+Disregard96DefaultDrawDistance 1 0
+list ATI_Radeon_9600
+Disregard96DefaultDrawDistance 1 0
+
+/// tweaked ATI to 128 draw distance
+
+list ATI_Radeon_X300
+Disregard128DefaultDrawDistance 1 0
+RenderVBOEnable 1 0
+list ATI_Radeon_X400
+Disregard128DefaultDrawDistance 1 0
+RenderVBOEnable 1 0
+list ATI_Radeon_X500
+Disregard128DefaultDrawDistance 1 0
+RenderVBOEnable 1 0
+list ATI_Radeon_X600
+Disregard128DefaultDrawDistance 1 0
+RenderVBOEnable 1 0
+list ATI_Radeon_X700
+Disregard128DefaultDrawDistance 1 0
+RenderVBOEnable 1 0
+list ATI_Radeon_X1300
+Disregard128DefaultDrawDistance 1 0
+RenderVBOEnable 1 0
+UseStartScreen 0 0
+list ATI_Radeon_X1400
+Disregard128DefaultDrawDistance 1 0
+RenderVBOEnable 1 0
+list ATI_Radeon_X1500
+Disregard128DefaultDrawDistance 1 0
+RenderVBOEnable 1 0
+UseStartScreen 0 0
+list ATI_Radeon_X1600
+Disregard128DefaultDrawDistance 1 0
+RenderVBOEnable 1 0
+list ATI_Radeon_X1700
+Disregard128DefaultDrawDistance 1 0
+RenderVBOEnable 1 0
+list ATI_Mobility_Radeon_X1xxx
+Disregard128DefaultDrawDistance 1 0
+RenderVBOEnable 1 0
+
+list ATI_Radeon_HD_2300
+Disregard128DefaultDrawDistance 1 0
+list ATI_Radeon_HD_2400
+Disregard128DefaultDrawDistance 1 0
+list ATI_ASUS_AH24xx
+Disregard128DefaultDrawDistance 1 0
+
+
+// Avatar hardware skinning causes invisible avatars
+// on various ATI chipsets on drivers before 8.2
+
+list ATIOldDriver
+RenderAvatarVP 0 0
+RenderAvatarCloth 0 0
+
+// ATI cards generally perform better when not using VBOs for streaming data
+
+list ATI
+RenderUseStreamVBO 1 0
+
+/// Tweaked NVIDIA
+
+list NVIDIA_GeForce_FX_5100
+Disregard96DefaultDrawDistance 1 0
+list NVIDIA_GeForce_FX_5200
+Disregard96DefaultDrawDistance 1 0
+list NVIDIA_GeForce_FX_5500
+Disregard96DefaultDrawDistance 1 0
+list NVIDIA_GeForce_FX_5600
+Disregard96DefaultDrawDistance 1 0
+
+list NVIDIA_GeForce_FX_Go5100
+Disregard96DefaultDrawDistance 1 0
+list NVIDIA_GeForce_FX_Go5200
+Disregard96DefaultDrawDistance 1 0
+list NVIDIA_GeForce_FX_Go5300
+Disregard96DefaultDrawDistance 1 0
+list NVIDIA_GeForce_FX_Go5500
+Disregard96DefaultDrawDistance 1 0
+list NVIDIA_GeForce_FX_Go5600
+Disregard96DefaultDrawDistance 1 0
+
+list NVIDIA_GeForce_6100
+Disregard128DefaultDrawDistance 1 0
+list NVIDIA_GeForce_6200
+Disregard128DefaultDrawDistance 1 0
+list NVIDIA_GeForce_6500
+Disregard128DefaultDrawDistance 1 0
+list NVIDIA_GeForce_6600
+Disregard128DefaultDrawDistance 1 0
+
+list NVIDIA_G73
+Disregard128DefaultDrawDistance 1 0
+
+list NVIDIA_GeForce_Go_6100
+RenderVBOEnable 1 0
+Disregard128DefaultDrawDistance 1 0
+list NVIDIA_GeForce_Go_6200
+RenderVBOEnable 1 0
+Disregard128DefaultDrawDistance 1 0
+list NVIDIA_GeForce_Go_6500
+RenderVBOEnable 1 0
+Disregard128DefaultDrawDistance 1 0
+list NVIDIA_GeForce_Go_6600
+RenderVBOEnable 1 0
+Disregard128DefaultDrawDistance 1 0
+list NVIDIA_GeForce_Go_6700
+RenderVBOEnable 1 0
+Disregard128DefaultDrawDistance 1 0
+list NVIDIA_GeForce_Go_6800
+RenderVBOEnable 1 0
+Disregard128DefaultDrawDistance 1 0
+list NVIDIA_GeForce_Go_6
+RenderVBOEnable 1 0
+Disregard128DefaultDrawDistance 1 0
+
+list NVIDIA_GeForce_7000
+RenderShaderLightingMaxLevel 1 2
+list NVIDIA_GeForce_7100
+RenderShaderLightingMaxLevel 1 2
+list NVIDIA_GeForce_7200
+Disregard128DefaultDrawDistance 1 0
+RenderShaderLightingMaxLevel 1 2
+list NVIDIA_GeForce_7300
+Disregard128DefaultDrawDistance 1 0
+RenderShaderLightingMaxLevel 1 2
+list NVIDIA_GeForce_7400
+Disregard128DefaultDrawDistance 1 0
+RenderShaderLightingMaxLevel 1 2
+list NVIDIA_GeForce_7500
+RenderShaderLightingMaxLevel 1 2
+list NVIDIA_GeForce_7600
+RenderShaderLightingMaxLevel 1 2
+list NVIDIA_GeForce_7700
+RenderShaderLightingMaxLevel 1 2
+list NVIDIA_GeForce_7800
+RenderShaderLightingMaxLevel 1 2
+list NVIDIA_GeForce_7900
+RenderShaderLightingMaxLevel 1 2
+
+list NVIDIA_GeForce_Go_7200
+Disregard128DefaultDrawDistance 1 0
+RenderShaderLightingMaxLevel 1 2
+list NVIDIA_GeForce_Go_7300
+Disregard128DefaultDrawDistance 1 0
+RenderShaderLightingMaxLevel 1 2
+list NVIDIA_GeForce_Go_7300_LE
+RenderShaderLightingMaxLevel 1 2
+list NVIDIA_GeForce_Go_7400
+Disregard128DefaultDrawDistance 1 0
+RenderShaderLightingMaxLevel 1 2
+list NVIDIA_GeForce_Go_7600
+RenderShaderLightingMaxLevel 1 2
+list NVIDIA_GeForce_Go_7700
+RenderShaderLightingMaxLevel 1 2
+list NVIDIA_GeForce_Go_7800
+RenderShaderLightingMaxLevel 1 2
+list NVIDIA_GeForce_Go_7900
+RenderShaderLightingMaxLevel 1 2
+
diff --git a/indra/newview/llagentwearables.cpp b/indra/newview/llagentwearables.cpp
index dd08e6c49a..055be4cae2 100644
--- a/indra/newview/llagentwearables.cpp
+++ b/indra/newview/llagentwearables.cpp
@@ -1882,7 +1882,7 @@ void LLAgentWearables::userAttachMultipleAttachments(LLInventoryModel::item_arra
msg->nextBlockFast(_PREHASH_ObjectData );
msg->addUUIDFast(_PREHASH_ItemID, item->getLinkedUUID());
msg->addUUIDFast(_PREHASH_OwnerID, item->getPermissions().getOwner());
- msg->addU8Fast(_PREHASH_AttachmentPt, 0 ); // Wear at the previous or default attachment point
+ msg->addU8Fast(_PREHASH_AttachmentPt, 0 | ATTACHMENT_ADD); // Wear at the previous or default attachment point
pack_permissions_slam(msg, item->getFlags(), item->getPermissions());
msg->addStringFast(_PREHASH_Name, item->getName());
msg->addStringFast(_PREHASH_Description, item->getDescription());
diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp
index 7159d89d21..ed5e8ceee3 100644
--- a/indra/newview/llappearancemgr.cpp
+++ b/indra/newview/llappearancemgr.cpp
@@ -31,6 +31,7 @@
#include "llagentcamera.h"
#include "llagentwearables.h"
#include "llappearancemgr.h"
+#include "llattachmentsmgr.h"
#include "llcommandhandler.h"
#include "lleventtimer.h"
#include "llgesturemgr.h"
@@ -2644,6 +2645,8 @@ LLAppearanceMgr::LLAppearanceMgr():
mUnlockOutfitTimer.reset(new LLOutfitUnLockTimer(gSavedSettings.getS32(
"OutfitOperationsTimeout")));
+
+ gIdleCallbacks.addFunction(&LLAttachmentsMgr::onIdle,NULL);
}
LLAppearanceMgr::~LLAppearanceMgr()
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index bfe3e52657..fd6b8b739d 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -3025,14 +3025,6 @@ void LLAppViewer::migrateCacheDirectory()
#endif // LL_WINDOWS || LL_DARWIN
}
-//static
-S32 LLAppViewer::getCacheVersion()
-{
- static const S32 cache_version = 7;
-
- return cache_version ;
-}
-
void dumpVFSCaches()
{
llinfos << "======= Static VFS ========" << llendl;
@@ -3071,23 +3063,40 @@ void dumpVFSCaches()
SetCurrentDirectory(w_str);
#endif
}
+
+//static
+U32 LLAppViewer::getTextureCacheVersion()
+{
+ //viewer texture cache version, change if the texture cache format changes.
+ const U32 TEXTURE_CACHE_VERSION = 7;
+
+ return TEXTURE_CACHE_VERSION ;
+}
+
+//static
+U32 LLAppViewer::getObjectCacheVersion()
+{
+ // Viewer object cache version, change if object update
+ // format changes. JC
+ const U32 INDRA_OBJECT_CACHE_VERSION = 14;
+
+ return INDRA_OBJECT_CACHE_VERSION;
+}
+
bool LLAppViewer::initCache()
{
mPurgeCache = false;
- BOOL disable_texture_cache = FALSE ;
BOOL read_only = mSecondInstance ? TRUE : FALSE;
LLAppViewer::getTextureCache()->setReadOnly(read_only) ;
+ LLVOCache::getInstance()->setReadOnly(read_only);
- if (gSavedSettings.getS32("LocalCacheVersion") != LLAppViewer::getCacheVersion())
+ BOOL texture_cache_mismatch = FALSE ;
+ if (gSavedSettings.getS32("LocalCacheVersion") != LLAppViewer::getTextureCacheVersion())
{
- if(read_only)
+ texture_cache_mismatch = TRUE ;
+ if(!read_only)
{
- disable_texture_cache = TRUE ; //if the cache version of this viewer is different from the running one, this viewer can not use the texture cache.
- }
- else
- {
- mPurgeCache = true; // Purge cache if the version number is different.
- gSavedSettings.setS32("LocalCacheVersion", LLAppViewer::getCacheVersion());
+ gSavedSettings.setS32("LocalCacheVersion", LLAppViewer::getTextureCacheVersion());
}
}
@@ -3138,9 +3147,11 @@ bool LLAppViewer::initCache()
const S64 MAX_CACHE_SIZE = 1024*MB;
cache_size = llmin(cache_size, MAX_CACHE_SIZE);
S64 texture_cache_size = ((cache_size * 8)/10);
- S64 extra = LLAppViewer::getTextureCache()->initCache(LL_PATH_CACHE, texture_cache_size, disable_texture_cache);
+ S64 extra = LLAppViewer::getTextureCache()->initCache(LL_PATH_CACHE, texture_cache_size, texture_cache_mismatch);
texture_cache_size -= extra;
+ LLVOCache::getInstance()->initCache(LL_PATH_CACHE, gSavedSettings.getU32("CacheNumberOfRegionsForObjects"), getObjectCacheVersion()) ;
+
LLSplashScreen::update(LLTrans::getString("StartupInitializingVFS"));
// Init the VFS
@@ -3303,6 +3314,7 @@ void LLAppViewer::purgeCache()
{
LL_INFOS("AppCache") << "Purging Cache and Texture Cache..." << llendl;
LLAppViewer::getTextureCache()->purgeCache(LL_PATH_CACHE);
+ LLVOCache::getInstance()->removeCache(LL_PATH_CACHE);
std::string mask = gDirUtilp->getDirDelimiter() + "*.*";
gDirUtilp->deleteFilesInDir(gDirUtilp->getExpandedFilename(LL_PATH_CACHE,""),mask);
}
diff --git a/indra/newview/llappviewer.h b/indra/newview/llappviewer.h
index 1fcf38d18a..c5cac6827c 100644
--- a/indra/newview/llappviewer.h
+++ b/indra/newview/llappviewer.h
@@ -94,7 +94,8 @@ public:
static LLImageDecodeThread* getImageDecodeThread() { return sImageDecodeThread; }
static LLTextureFetch* getTextureFetch() { return sTextureFetch; }
- static S32 getCacheVersion() ;
+ static U32 getTextureCacheVersion() ;
+ static U32 getObjectCacheVersion() ;
const std::string& getSerialNumber() { return mSerialNumber; }
diff --git a/indra/newview/llattachmentsmgr.cpp b/indra/newview/llattachmentsmgr.cpp
new file mode 100644
index 0000000000..c9543988a6
--- /dev/null
+++ b/indra/newview/llattachmentsmgr.cpp
@@ -0,0 +1,131 @@
+/**
+ * @file llattachmentsmgr.cpp
+ * @brief Manager for initiating attachments changes on the viewer
+ *
+ * $LicenseInfo:firstyear=2004&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+#include "llattachmentsmgr.h"
+
+#include "llagent.h"
+#include "llinventorymodel.h"
+#include "lltooldraganddrop.h" // pack_permissions_slam
+#include "llviewerinventory.h"
+#include "llviewerregion.h"
+#include "message.h"
+
+
+LLAttachmentsMgr::LLAttachmentsMgr()
+{
+}
+
+LLAttachmentsMgr::~LLAttachmentsMgr()
+{
+}
+
+void LLAttachmentsMgr::addAttachment(const LLUUID& item_id,
+ const U8 attachment_pt,
+ const BOOL add)
+{
+ AttachmentsInfo attachment;
+ attachment.mItemID = item_id;
+ attachment.mAttachmentPt = attachment_pt;
+ attachment.mAdd = add;
+ mPendingAttachments.push_back(attachment);
+}
+
+// static
+void LLAttachmentsMgr::onIdle(void *)
+{
+ LLAttachmentsMgr::instance().onIdle();
+}
+
+void LLAttachmentsMgr::onIdle()
+{
+ S32 obj_count = mPendingAttachments.size();
+ if (obj_count == 0)
+ {
+ return;
+ }
+
+ // Limit number of packets to send
+ const S32 MAX_PACKETS_TO_SEND = 10;
+ const S32 OBJECTS_PER_PACKET = 4;
+ const S32 MAX_OBJECTS_TO_SEND = MAX_PACKETS_TO_SEND * OBJECTS_PER_PACKET;
+ if( obj_count > MAX_OBJECTS_TO_SEND )
+ {
+ obj_count = MAX_OBJECTS_TO_SEND;
+ }
+
+ LLUUID compound_msg_id;
+ compound_msg_id.generate();
+ LLMessageSystem* msg = gMessageSystem;
+
+
+ S32 i = 0;
+ for (attachments_vec_t::const_iterator iter = mPendingAttachments.begin();
+ iter != mPendingAttachments.end();
+ ++iter)
+ {
+ if( 0 == (i % OBJECTS_PER_PACKET) )
+ {
+ // Start a new message chunk
+ msg->newMessageFast(_PREHASH_RezMultipleAttachmentsFromInv);
+ msg->nextBlockFast(_PREHASH_AgentData);
+ msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
+ msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
+ msg->nextBlockFast(_PREHASH_HeaderData);
+ msg->addUUIDFast(_PREHASH_CompoundMsgID, compound_msg_id );
+ msg->addU8Fast(_PREHASH_TotalObjects, obj_count );
+ msg->addBOOLFast(_PREHASH_FirstDetachAll, false );
+ }
+
+ const AttachmentsInfo &attachment = (*iter);
+ LLViewerInventoryItem* item = gInventory.getItem(attachment.mItemID);
+ if (!item)
+ {
+ llinfos << "Attempted to add non-existant item ID:" << attachment.mItemID << llendl;
+ continue;
+ }
+ S32 attachment_pt = attachment.mAttachmentPt;
+ if (attachment.mAdd)
+ attachment_pt |= ATTACHMENT_ADD;
+
+ msg->nextBlockFast(_PREHASH_ObjectData );
+ msg->addUUIDFast(_PREHASH_ItemID, item->getLinkedUUID());
+ msg->addUUIDFast(_PREHASH_OwnerID, item->getPermissions().getOwner());
+ msg->addU8Fast(_PREHASH_AttachmentPt, attachment_pt);
+ pack_permissions_slam(msg, item->getFlags(), item->getPermissions());
+ msg->addStringFast(_PREHASH_Name, item->getName());
+ msg->addStringFast(_PREHASH_Description, item->getDescription());
+
+ if( (i+1 == obj_count) || ((OBJECTS_PER_PACKET-1) == (i % OBJECTS_PER_PACKET)) )
+ {
+ // End of message chunk
+ msg->sendReliable( gAgent.getRegion()->getHost() );
+ }
+ i++;
+ }
+
+ mPendingAttachments.clear();
+}
diff --git a/indra/newview/llattachmentsmgr.h b/indra/newview/llattachmentsmgr.h
new file mode 100644
index 0000000000..1d8ab74dfd
--- /dev/null
+++ b/indra/newview/llattachmentsmgr.h
@@ -0,0 +1,73 @@
+/**
+ * @file llattachmentsmgr.h
+ * @brief Batches up attachment requests and sends them all
+ * in one message.
+ *
+ * $LicenseInfo:firstyear=2004&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLATTACHMENTSMGR_H
+#define LL_LLATTACHMENTSMGR_H
+
+#include "llsingleton.h"
+
+class LLViewerInventoryItem;
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// LLAttachmentsMgr
+//
+// The sole purpose of this class is to take attachment
+// requests, queue them up, and send them all at once.
+// This handles situations where the viewer may request
+// a bunch of attachments at once in a short period of
+// time, where each of the requests would normally be
+// sent as a separate message versus being batched into
+// one single message.
+//
+// The intent of this batching is to reduce viewer->server
+// traffic.
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+class LLAttachmentsMgr: public LLSingleton<LLAttachmentsMgr>
+{
+public:
+ LLAttachmentsMgr();
+ virtual ~LLAttachmentsMgr();
+
+ void addAttachment(const LLUUID& item_id,
+ const U8 attachment_pt,
+ const BOOL add);
+ static void onIdle(void *);
+protected:
+ void onIdle();
+private:
+ struct AttachmentsInfo
+ {
+ LLUUID mItemID;
+ U8 mAttachmentPt;
+ BOOL mAdd;
+ };
+
+ typedef std::vector<AttachmentsInfo> attachments_vec_t;
+ attachments_vec_t mPendingAttachments;
+};
+
+#endif
diff --git a/indra/newview/llavatarlist.cpp b/indra/newview/llavatarlist.cpp
index 1cd705c2f9..5241f20c0e 100644
--- a/indra/newview/llavatarlist.cpp
+++ b/indra/newview/llavatarlist.cpp
@@ -90,6 +90,20 @@ void LLAvatarList::setSpeakingIndicatorsVisible(bool visible)
}
}
+void LLAvatarList::showPermissions(bool visible)
+{
+ // Save the value for new items to use.
+ mShowPermissions = visible;
+
+ // Enable or disable showing permissions icons for all existing items.
+ std::vector<LLPanel*> items;
+ getItems(items);
+ for(std::vector<LLPanel*>::const_iterator it = items.begin(), end_it = items.end(); it != end_it; ++it)
+ {
+ static_cast<LLAvatarListItem*>(*it)->setShowPermissions(mShowPermissions);
+ }
+}
+
static bool findInsensitive(std::string haystack, const std::string& needle_upper)
{
LLStringUtil::toUpper(haystack);
@@ -107,6 +121,7 @@ LLAvatarList::Params::Params()
, show_info_btn("show_info_btn", true)
, show_profile_btn("show_profile_btn", true)
, show_speaking_indicator("show_speaking_indicator", true)
+, show_permissions_granted("show_permissions_granted", false)
{
}
@@ -121,6 +136,7 @@ LLAvatarList::LLAvatarList(const Params& p)
, mShowInfoBtn(p.show_info_btn)
, mShowProfileBtn(p.show_profile_btn)
, mShowSpeakingIndicator(p.show_speaking_indicator)
+, mShowPermissions(p.show_permissions_granted)
{
setCommitOnSelectionChange(true);
@@ -377,6 +393,7 @@ void LLAvatarList::addNewItem(const LLUUID& id, const std::string& name, BOOL is
item->setShowInfoBtn(mShowInfoBtn);
item->setShowProfileBtn(mShowProfileBtn);
item->showSpeakingIndicator(mShowSpeakingIndicator);
+ item->setShowPermissions(mShowPermissions);
item->setDoubleClickCallback(boost::bind(&LLAvatarList::onItemDoubleClicked, this, _1, _2, _3, _4));
diff --git a/indra/newview/llavatarlist.h b/indra/newview/llavatarlist.h
index 83faa53c28..9d3dcb75f3 100644
--- a/indra/newview/llavatarlist.h
+++ b/indra/newview/llavatarlist.h
@@ -54,7 +54,8 @@ public:
show_last_interaction_time, // show most recent interaction time. *HACK: move this to a derived class
show_info_btn,
show_profile_btn,
- show_speaking_indicator;
+ show_speaking_indicator,
+ show_permissions_granted;
Params();
};
@@ -78,6 +79,7 @@ public:
void toggleIcons();
void setSpeakingIndicatorsVisible(bool visible);
+ void showPermissions(bool visible);
void sortByName();
void setShowIcons(std::string param_name);
bool getIconsVisible() const { return mShowIcons; }
@@ -115,6 +117,7 @@ private:
bool mShowInfoBtn;
bool mShowProfileBtn;
bool mShowSpeakingIndicator;
+ bool mShowPermissions;
LLTimer* mLITUpdateTimer; // last interaction time update timer
std::string mIconParamName;
diff --git a/indra/newview/llavatarlistitem.cpp b/indra/newview/llavatarlistitem.cpp
index 341913edf7..8fc4ad6763 100644
--- a/indra/newview/llavatarlistitem.cpp
+++ b/indra/newview/llavatarlistitem.cpp
@@ -60,12 +60,17 @@ LLAvatarListItem::LLAvatarListItem(bool not_from_ui_factory/* = true*/)
mAvatarIcon(NULL),
mAvatarName(NULL),
mLastInteractionTime(NULL),
+ mIconPermissionOnline(NULL),
+ mIconPermissionMap(NULL),
+ mIconPermissionEditMine(NULL),
+ mIconPermissionEditTheirs(NULL),
mSpeakingIndicator(NULL),
mInfoBtn(NULL),
mProfileBtn(NULL),
mOnlineStatus(E_UNKNOWN),
mShowInfoBtn(true),
- mShowProfileBtn(true)
+ mShowProfileBtn(true),
+ mShowPermissions(false)
{
if (not_from_ui_factory)
{
@@ -86,7 +91,16 @@ BOOL LLAvatarListItem::postBuild()
mAvatarIcon = getChild<LLAvatarIconCtrl>("avatar_icon");
mAvatarName = getChild<LLTextBox>("avatar_name");
mLastInteractionTime = getChild<LLTextBox>("last_interaction");
-
+
+ mIconPermissionOnline = getChild<LLIconCtrl>("permission_online_icon");
+ mIconPermissionMap = getChild<LLIconCtrl>("permission_map_icon");
+ mIconPermissionEditMine = getChild<LLIconCtrl>("permission_edit_mine_icon");
+ mIconPermissionEditTheirs = getChild<LLIconCtrl>("permission_edit_theirs_icon");
+ mIconPermissionOnline->setVisible(false);
+ mIconPermissionMap->setVisible(false);
+ mIconPermissionEditMine->setVisible(false);
+ mIconPermissionEditTheirs->setVisible(false);
+
mSpeakingIndicator = getChild<LLOutputMonitorCtrl>("speaking_indicator");
mInfoBtn = getChild<LLButton>("info_btn");
mProfileBtn = getChild<LLButton>("profile_btn");
@@ -125,8 +139,10 @@ void LLAvatarListItem::onMouseEnter(S32 x, S32 y, MASK mask)
mInfoBtn->setVisible(mShowInfoBtn);
mProfileBtn->setVisible(mShowProfileBtn);
+ mHovered = true;
LLPanel::onMouseEnter(x, y, mask);
+ showPermissions(mShowPermissions);
updateChildren();
}
@@ -136,8 +152,10 @@ void LLAvatarListItem::onMouseLeave(S32 x, S32 y, MASK mask)
mInfoBtn->setVisible(false);
mProfileBtn->setVisible(false);
+ mHovered = false;
LLPanel::onMouseLeave(x, y, mask);
+ showPermissions(false);
updateChildren();
}
@@ -146,6 +164,12 @@ void LLAvatarListItem::changed(U32 mask)
{
// no need to check mAvatarId for null in this case
setOnline(LLAvatarTracker::instance().isBuddyOnline(mAvatarId));
+
+ if (mask & LLFriendObserver::POWERS)
+ {
+ showPermissions(mShowPermissions && mHovered);
+ updateChildren();
+ }
}
void LLAvatarListItem::setOnline(bool online)
@@ -230,10 +254,7 @@ void LLAvatarListItem::setAvatarId(const LLUUID& id, const LLUUID& session_id, b
void LLAvatarListItem::showLastInteractionTime(bool show)
{
- if (show)
- return;
-
- mLastInteractionTime->setVisible(false);
+ mLastInteractionTime->setVisible(show);
updateChildren();
}
@@ -244,17 +265,11 @@ void LLAvatarListItem::setLastInteractionTime(U32 secs_since)
void LLAvatarListItem::setShowInfoBtn(bool show)
{
- // Already done? Then do nothing.
- if(mShowInfoBtn == show)
- return;
mShowInfoBtn = show;
}
void LLAvatarListItem::setShowProfileBtn(bool show)
{
- // Already done? Then do nothing.
- if(mShowProfileBtn == show)
- return;
mShowProfileBtn = show;
}
@@ -273,7 +288,9 @@ void LLAvatarListItem::setAvatarIconVisible(bool visible)
{
// Already done? Then do nothing.
if (mAvatarIcon->getVisible() == (BOOL)visible)
+ {
return;
+ }
// Show/hide avatar icon.
mAvatarIcon->setVisible(visible);
@@ -322,7 +339,7 @@ const std::string LLAvatarListItem::getAvatarName() const
return mAvatarName->getValue();
}
-//== PRIVATE SECITON ==========================================================
+//== PRIVATE SECTION ==========================================================
void LLAvatarListItem::setNameInternal(const std::string& name, const std::string& highlight)
{
@@ -432,10 +449,22 @@ void LLAvatarListItem::initChildrenWidths(LLAvatarListItem* avatar_item)
//info btn width + padding
S32 info_btn_width = avatar_item->mProfileBtn->getRect().mLeft - avatar_item->mInfoBtn->getRect().mLeft;
+ // edit their objects permission icon width + padding
+ S32 permission_edit_theirs_width = avatar_item->mInfoBtn->getRect().mLeft - avatar_item->mIconPermissionEditTheirs->getRect().mLeft;
+
+ // edit my objects permission icon width + padding
+ S32 permission_edit_mine_width = avatar_item->mIconPermissionEditTheirs->getRect().mLeft - avatar_item->mIconPermissionEditMine->getRect().mLeft;
+
+ // map permission icon width + padding
+ S32 permission_map_width = avatar_item->mIconPermissionEditMine->getRect().mLeft - avatar_item->mIconPermissionMap->getRect().mLeft;
+
+ // online permission icon width + padding
+ S32 permission_online_width = avatar_item->mIconPermissionMap->getRect().mLeft - avatar_item->mIconPermissionOnline->getRect().mLeft;
+
// last interaction time textbox width + padding
- S32 last_interaction_time_width = avatar_item->mInfoBtn->getRect().mLeft - avatar_item->mLastInteractionTime->getRect().mLeft;
+ S32 last_interaction_time_width = avatar_item->mIconPermissionOnline->getRect().mLeft - avatar_item->mLastInteractionTime->getRect().mLeft;
- // icon width + padding
+ // avatar icon width + padding
S32 icon_width = avatar_item->mAvatarName->getRect().mLeft - avatar_item->mAvatarIcon->getRect().mLeft;
sLeftPadding = avatar_item->mAvatarIcon->getRect().mLeft;
@@ -445,9 +474,14 @@ void LLAvatarListItem::initChildrenWidths(LLAvatarListItem* avatar_item)
sChildrenWidths[--index] = icon_width;
sChildrenWidths[--index] = 0; // for avatar name we don't need its width, it will be calculated as "left available space"
sChildrenWidths[--index] = last_interaction_time_width;
+ sChildrenWidths[--index] = permission_online_width;
+ sChildrenWidths[--index] = permission_map_width;
+ sChildrenWidths[--index] = permission_edit_mine_width;
+ sChildrenWidths[--index] = permission_edit_theirs_width;
sChildrenWidths[--index] = info_btn_width;
sChildrenWidths[--index] = profile_btn_width;
sChildrenWidths[--index] = speaking_indicator_width;
+ llassert(index == 0);
}
void LLAvatarListItem::updateChildren()
@@ -526,6 +560,27 @@ void LLAvatarListItem::updateChildren()
LL_DEBUGS("AvatarItemReshape") << "name rect after: " << name_view_rect << LL_ENDL;
}
+bool LLAvatarListItem::showPermissions(bool visible)
+{
+ const LLRelationship* relation = LLAvatarTracker::instance().getBuddyInfo(getAvatarId());
+ if(relation && visible)
+ {
+ mIconPermissionOnline->setVisible(relation->isRightGrantedTo(LLRelationship::GRANT_ONLINE_STATUS));
+ mIconPermissionMap->setVisible(relation->isRightGrantedTo(LLRelationship::GRANT_MAP_LOCATION));
+ mIconPermissionEditMine->setVisible(relation->isRightGrantedTo(LLRelationship::GRANT_MODIFY_OBJECTS));
+ mIconPermissionEditTheirs->setVisible(relation->isRightGrantedFrom(LLRelationship::GRANT_MODIFY_OBJECTS));
+ }
+ else
+ {
+ mIconPermissionOnline->setVisible(false);
+ mIconPermissionMap->setVisible(false);
+ mIconPermissionEditMine->setVisible(false);
+ mIconPermissionEditTheirs->setVisible(false);
+ }
+
+ return NULL != relation;
+}
+
LLView* LLAvatarListItem::getItemChildView(EAvatarListItemChildIndex child_view_index)
{
LLView* child_view = mAvatarName;
@@ -542,7 +597,19 @@ LLView* LLAvatarListItem::getItemChildView(EAvatarListItemChildIndex child_view_
child_view = mLastInteractionTime;
break;
case ALIC_SPEAKER_INDICATOR:
- child_view = mSpeakingIndicator;
+ child_view = mSpeakingIndicator;
+ break;
+ case ALIC_PERMISSION_ONLINE:
+ child_view = mIconPermissionOnline;
+ break;
+ case ALIC_PERMISSION_MAP:
+ child_view = mIconPermissionMap;
+ break;
+ case ALIC_PERMISSION_EDIT_MINE:
+ child_view = mIconPermissionEditMine;
+ break;
+ case ALIC_PERMISSION_EDIT_THEIRS:
+ child_view = mIconPermissionEditTheirs;
break;
case ALIC_INFO_BUTTON:
child_view = mInfoBtn;
diff --git a/indra/newview/llavatarlistitem.h b/indra/newview/llavatarlistitem.h
index e252e69ea9..ffb988b2ab 100644
--- a/indra/newview/llavatarlistitem.h
+++ b/indra/newview/llavatarlistitem.h
@@ -36,6 +36,7 @@
#include "llcallingcard.h" // for LLFriendObserver
class LLAvatarIconCtrl;
+class LLIconCtrl;
class LLAvatarListItem : public LLPanel, public LLFriendObserver
{
@@ -94,6 +95,7 @@ public:
void setShowProfileBtn(bool show);
void setShowInfoBtn(bool show);
void showSpeakingIndicator(bool show);
+ void setShowPermissions(bool show) { mShowPermissions = show; };
void showLastInteractionTime(bool show);
void setAvatarIconVisible(bool visible);
@@ -113,6 +115,15 @@ protected:
LLAvatarIconCtrl* mAvatarIcon;
+ /// Indicator for permission to see me online.
+ LLIconCtrl* mIconPermissionOnline;
+ /// Indicator for permission to see my position on the map.
+ LLIconCtrl* mIconPermissionMap;
+ /// Indicator for permission to edit my objects.
+ LLIconCtrl* mIconPermissionEditMine;
+ /// Indicator for permission to edit their objects.
+ LLIconCtrl* mIconPermissionEditTheirs;
+
private:
typedef enum e_online_status {
@@ -132,6 +143,10 @@ private:
ALIC_SPEAKER_INDICATOR,
ALIC_PROFILE_BUTTON,
ALIC_INFO_BUTTON,
+ ALIC_PERMISSION_EDIT_THEIRS,
+ ALIC_PERMISSION_EDIT_MINE,
+ ALIC_PERMISSION_MAP,
+ ALIC_PERMISSION_ONLINE,
ALIC_INTERACTION_TIME,
ALIC_NAME,
ALIC_ICON,
@@ -159,6 +174,13 @@ private:
void updateChildren();
/**
+ * Update visibility of active permissions icons.
+ *
+ * Need to call updateChildren() afterwards to sort out their layout.
+ */
+ bool showPermissions(bool visible);
+
+ /**
* Gets child view specified by index.
*
* This method implemented via switch by all EAvatarListItemChildIndex values.
@@ -181,6 +203,12 @@ private:
bool mShowInfoBtn;
bool mShowProfileBtn;
+ /// indicates whether to show icons representing permissions granted
+ bool mShowPermissions;
+
+ /// true when the mouse pointer is hovering over this item
+ bool mHovered;
+
static bool sStaticInitialized; // this variable is introduced to improve code readability
static S32 sLeftPadding; // padding to first left visible child (icon or name)
static S32 sRightNamePadding; // right padding from name to next visible child
diff --git a/indra/newview/llcallingcard.h b/indra/newview/llcallingcard.h
index 617f8fe27b..15ca51743a 100644
--- a/indra/newview/llcallingcard.h
+++ b/indra/newview/llcallingcard.h
@@ -45,7 +45,7 @@ class LLFriendObserver
public:
// This enumeration is a way to refer to what changed in a more
// human readable format. You can mask the value provided by
- // chaged() to see if the observer is interested in the change.
+ // changed() to see if the observer is interested in the change.
enum
{
NONE = 0,
diff --git a/indra/newview/lldynamictexture.cpp b/indra/newview/lldynamictexture.cpp
index ed35546ca3..a3d2941114 100644
--- a/indra/newview/lldynamictexture.cpp
+++ b/indra/newview/lldynamictexture.cpp
@@ -54,6 +54,13 @@ LLViewerDynamicTexture::LLViewerDynamicTexture(S32 width, S32 height, S32 compon
{
llassert((1 <= components) && (components <= 4));
+ if(gGLManager.mDebugGPU)
+ {
+ if(components == 3)
+ {
+ mComponents = 4 ; //convert to 32bits.
+ }
+ }
generateGLTexture();
llassert( 0 <= order && order < ORDER_COUNT );
diff --git a/indra/newview/llfeaturemanager.cpp b/indra/newview/llfeaturemanager.cpp
index 03cfc6764a..ca2ef5f5b8 100644
--- a/indra/newview/llfeaturemanager.cpp
+++ b/indra/newview/llfeaturemanager.cpp
@@ -67,8 +67,8 @@ const char FEATURE_TABLE_VER_FILENAME[] = "featuretable_linux.%s.txt";
const char FEATURE_TABLE_FILENAME[] = "featuretable_solaris.txt";
const char FEATURE_TABLE_VER_FILENAME[] = "featuretable_solaris.%s.txt";
#else
-const char FEATURE_TABLE_FILENAME[] = "featuretable.txt";
-const char FEATURE_TABLE_VER_FILENAME[] = "featuretable.%s.txt";
+const char FEATURE_TABLE_FILENAME[] = "featuretable%s.txt";
+const char FEATURE_TABLE_VER_FILENAME[] = "featuretable%s.%s.txt";
#endif
const char GPU_TABLE_FILENAME[] = "gpu_table.txt";
@@ -220,10 +220,30 @@ BOOL LLFeatureManager::loadFeatureTables()
// first table is install with app
std::string app_path = gDirUtilp->getAppRODataDir();
app_path += gDirUtilp->getDirDelimiter();
- app_path += FEATURE_TABLE_FILENAME;
+ std::string filename;
+ std::string http_filename;
+#if LL_WINDOWS
+ std::string os_string = LLAppViewer::instance()->getOSInfo().getOSStringSimple();
+ if (os_string.find("Microsoft Windows XP") == 0)
+ {
+ filename = llformat(FEATURE_TABLE_FILENAME, "_xp");
+ http_filename = llformat(FEATURE_TABLE_VER_FILENAME, "_xp", LLVersionInfo::getVersion().c_str());
+ }
+ else
+ {
+ filename = llformat(FEATURE_TABLE_FILENAME, "");
+ http_filename = llformat(FEATURE_TABLE_VER_FILENAME, "", LLVersionInfo::getVersion().c_str());
+ }
+#else
+ filename = FEATURE_TABLE_FILENAME;
+ http_filename = llformat(FEATURE_TABLE_VER_FILENAME, LLVersionInfo::getVersion().c_str());
+#endif
+
+ app_path += filename;
+
+
// second table is downloaded with HTTP
- std::string http_filename = llformat(FEATURE_TABLE_VER_FILENAME, LLVersionInfo::getVersion().c_str());
std::string http_path = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, http_filename);
// use HTTP table if it exists
@@ -488,7 +508,35 @@ private:
std::string mFilename;
};
-void fetch_table(std::string table)
+void fetch_feature_table(std::string table)
+{
+ const std::string base = gSavedSettings.getString("FeatureManagerHTTPTable");
+
+#if LL_WINDOWS
+ std::string os_string = LLAppViewer::instance()->getOSInfo().getOSStringSimple();
+ std::string filename;
+ if (os_string.find("Microsoft Windows XP") == 0)
+ {
+ filename = llformat(table.c_str(), "_xp", LLVersionInfo::getVersion().c_str());
+ }
+ else
+ {
+ filename = llformat(table.c_str(), "", LLVersionInfo::getVersion().c_str());
+ }
+#else
+ const std::string filename = llformat(table.c_str(), LLVersionInfo::getVersion().c_str());
+#endif
+
+ const std::string url = base + "/" + filename;
+
+ const std::string path = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, filename);
+
+ llinfos << "LLFeatureManager fetching " << url << " into " << path << llendl;
+
+ LLHTTPClient::get(url, new LLHTTPFeatureTableResponder(path));
+}
+
+void fetch_gpu_table(std::string table)
{
const std::string base = gSavedSettings.getString("FeatureManagerHTTPTable");
@@ -506,8 +554,8 @@ void fetch_table(std::string table)
// fetch table(s) from a website (S3)
void LLFeatureManager::fetchHTTPTables()
{
- fetch_table(FEATURE_TABLE_VER_FILENAME);
- fetch_table(GPU_TABLE_VER_FILENAME);
+ fetch_feature_table(FEATURE_TABLE_VER_FILENAME);
+ fetch_gpu_table(GPU_TABLE_VER_FILENAME);
}
diff --git a/indra/newview/llfloatersidetraytab.cpp b/indra/newview/llfloatersidetraytab.cpp
new file mode 100644
index 0000000000..f13b4db3a0
--- /dev/null
+++ b/indra/newview/llfloatersidetraytab.cpp
@@ -0,0 +1,45 @@
+/**
+ * @file llfloatersidetraytab.cpp
+ * @brief LLFloaterSideTrayTab class definition
+ *
+ * $LicenseInfo:firstyear=2010&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+#include "llfloatersidetraytab.h"
+
+// newview includes
+#include "lltransientfloatermgr.h"
+
+LLFloaterSideTrayTab::LLFloaterSideTrayTab(const LLSD& key, const Params& params)
+: LLFloater(key, params)
+{
+ // Prevent transient floaters (e.g. IM windows) from hiding
+ // when this floater is clicked.
+ LLTransientFloaterMgr::getInstance()->addControlView(LLTransientFloaterMgr::GLOBAL, this);
+}
+
+LLFloaterSideTrayTab::~LLFloaterSideTrayTab()
+{
+ LLTransientFloaterMgr::getInstance()->removeControlView(LLTransientFloaterMgr::GLOBAL, this);
+}
diff --git a/indra/newview/llfloatersidetraytab.h b/indra/newview/llfloatersidetraytab.h
new file mode 100644
index 0000000000..e47f82e8ba
--- /dev/null
+++ b/indra/newview/llfloatersidetraytab.h
@@ -0,0 +1,47 @@
+/**
+ * @file llfloatersidetraytab.h
+ * @brief LLFloaterSideTrayTab class definition
+ *
+ * $LicenseInfo:firstyear=2010&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLFLOATERSIDETRAYTAB_H
+#define LL_LLFLOATERSIDETRAYTAB_H
+
+#include "llfloater.h"
+
+/**
+ * When a side tray tab gets detached, it's wrapped in an instance of this class.
+ *
+ * This class helps to make sure that clicking a detached side tray tab doesn't
+ * make transient floaters (e.g. IM windows) hide, so that it's possible to
+ * drag an inventory item from detached My Inventory window to a docked IM window,
+ * i.e. share the item (see VWR-22891).
+ */
+class LLFloaterSideTrayTab : public LLFloater
+{
+public:
+ LLFloaterSideTrayTab(const LLSD& key, const Params& params = getDefaultParams());
+ ~LLFloaterSideTrayTab();
+};
+
+#endif // LL_LLFLOATERSIDETRAYTAB_H
diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp
index aff0bc4099..02e7f0b9e2 100644
--- a/indra/newview/llinventorybridge.cpp
+++ b/indra/newview/llinventorybridge.cpp
@@ -28,19 +28,20 @@
#include "llinventorybridge.h"
// external projects
-#include "lltransfersourceasset.h"
+#include "lltransfersourceasset.h"
#include "llagent.h"
#include "llagentcamera.h"
#include "llagentwearables.h"
#include "llappearancemgr.h"
-#include "llavataractions.h"
+#include "llattachmentsmgr.h"
+#include "llavataractions.h"
#include "llfloateropenobject.h"
#include "llfloaterreg.h"
#include "llfloaterworldmap.h"
#include "llfriendcard.h"
#include "llgesturemgr.h"
-#include "llgiveinventory.h"
+#include "llgiveinventory.h"
#include "llimfloater.h"
#include "llimview.h"
#include "llinventoryclipboard.h"
@@ -100,7 +101,7 @@ void dec_busy_count()
void remove_inventory_category_from_avatar(LLInventoryCategory* category);
void remove_inventory_category_from_avatar_step2( BOOL proceed, LLUUID category_id);
bool move_task_inventory_callback(const LLSD& notification, const LLSD& response, LLMoveInv*);
-bool confirm_replace_attachment_rez(const LLSD& notification, const LLSD& response);
+bool confirm_attachment_rez(const LLSD& notification, const LLSD& response);
void teleport_via_landmark(const LLUUID& asset_id);
// +=================================================+
@@ -3978,22 +3979,22 @@ std::string LLObjectBridge::getLabelSuffix() const
{
if (get_is_item_worn(mUUID))
{
- if (!isAgentAvatarValid())
+ if (!isAgentAvatarValid()) // Error condition, can't figure out attach point
{
return LLItemBridge::getLabelSuffix() + LLTrans::getString("worn");
}
-
std::string attachment_point_name = gAgentAvatarp->getAttachedPointName(mUUID);
-
+ if (attachment_point_name == LLStringUtil::null) // Error condition, invalid attach point
+ {
+ attachment_point_name = "Invalid Attachment";
+ }
// e.g. "(worn on ...)" / "(attached to ...)"
LLStringUtil::format_map_t args;
args["[ATTACHMENT_POINT]"] = LLTrans::getString(attachment_point_name);
+
return LLItemBridge::getLabelSuffix() + LLTrans::getString("WornOnAttachmentPoint", args);
}
- else
- {
- return LLItemBridge::getLabelSuffix();
- }
+ return LLItemBridge::getLabelSuffix();
}
void rez_attachment(LLViewerInventoryItem* item, LLViewerJointAttachment* attachment, bool replace)
@@ -4024,19 +4025,15 @@ void rez_attachment(LLViewerInventoryItem* item, LLViewerJointAttachment* attach
}
}
- if (!replace)
- {
- attach_pt |= ATTACHMENT_ADD;
- }
-
LLSD payload;
payload["item_id"] = item_id; // Wear the base object in case this is a link.
payload["attachment_point"] = attach_pt;
+ payload["is_add"] = !replace;
if (replace &&
(attachment && attachment->getNumObjects() > 0))
{
- LLNotificationsUtil::add("ReplaceAttachment", LLSD(), payload, confirm_replace_attachment_rez);
+ LLNotificationsUtil::add("ReplaceAttachment", LLSD(), payload, confirm_attachment_rez);
}
else
{
@@ -4044,7 +4041,7 @@ void rez_attachment(LLViewerInventoryItem* item, LLViewerJointAttachment* attach
}
}
-bool confirm_replace_attachment_rez(const LLSD& notification, const LLSD& response)
+bool confirm_attachment_rez(const LLSD& notification, const LLSD& response)
{
if (!gAgentAvatarp->canAttachMoreObjects())
{
@@ -4062,27 +4059,41 @@ bool confirm_replace_attachment_rez(const LLSD& notification, const LLSD& respon
if (itemp)
{
+ /*
+ {
+ U8 attachment_pt = notification["payload"]["attachment_point"].asInteger();
+
+ LLMessageSystem* msg = gMessageSystem;
+ msg->newMessageFast(_PREHASH_RezSingleAttachmentFromInv);
+ msg->nextBlockFast(_PREHASH_AgentData);
+ msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
+ msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
+ msg->nextBlockFast(_PREHASH_ObjectData);
+ msg->addUUIDFast(_PREHASH_ItemID, itemp->getUUID());
+ msg->addUUIDFast(_PREHASH_OwnerID, itemp->getPermissions().getOwner());
+ msg->addU8Fast(_PREHASH_AttachmentPt, attachment_pt);
+ pack_permissions_slam(msg, itemp->getFlags(), itemp->getPermissions());
+ msg->addStringFast(_PREHASH_Name, itemp->getName());
+ msg->addStringFast(_PREHASH_Description, itemp->getDescription());
+ msg->sendReliable(gAgent.getRegion()->getHost());
+ return false;
+ }
+ */
+
+ // Queue up attachments to be sent in next idle tick, this way the
+ // attachments are batched up all into one message versus each attachment
+ // being sent in its own separate attachments message.
U8 attachment_pt = notification["payload"]["attachment_point"].asInteger();
-
+ BOOL is_add = notification["payload"]["is_add"].asBoolean();
- LLMessageSystem* msg = gMessageSystem;
- msg->newMessageFast(_PREHASH_RezSingleAttachmentFromInv);
- msg->nextBlockFast(_PREHASH_AgentData);
- msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
- msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
- msg->nextBlockFast(_PREHASH_ObjectData);
- msg->addUUIDFast(_PREHASH_ItemID, itemp->getUUID());
- msg->addUUIDFast(_PREHASH_OwnerID, itemp->getPermissions().getOwner());
- msg->addU8Fast(_PREHASH_AttachmentPt, attachment_pt);
- pack_permissions_slam(msg, itemp->getFlags(), itemp->getPermissions());
- msg->addStringFast(_PREHASH_Name, itemp->getName());
- msg->addStringFast(_PREHASH_Description, itemp->getDescription());
- msg->sendReliable(gAgent.getRegion()->getHost());
+ LLAttachmentsMgr::instance().addAttachment(item_id,
+ attachment_pt,
+ is_add);
}
}
return false;
}
-static LLNotificationFunctorRegistration confirm_replace_attachment_rez_reg("ReplaceAttachment", confirm_replace_attachment_rez);
+static LLNotificationFunctorRegistration confirm_replace_attachment_rez_reg("ReplaceAttachment", confirm_attachment_rez);
void LLObjectBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
{
diff --git a/indra/newview/llinventoryicon.cpp b/indra/newview/llinventoryicon.cpp
index 021790648d..7216d61e7f 100644
--- a/indra/newview/llinventoryicon.cpp
+++ b/indra/newview/llinventoryicon.cpp
@@ -85,6 +85,8 @@ LLIconDictionary::LLIconDictionary()
addEntry(LLInventoryIcon::ICONNAME_LINKITEM, new IconEntry("Inv_LinkItem"));
addEntry(LLInventoryIcon::ICONNAME_LINKFOLDER, new IconEntry("Inv_LinkItem"));
+ addEntry(LLInventoryIcon::ICONNAME_INVALID, new IconEntry("Inv_Invalid"));
+
addEntry(LLInventoryIcon::ICONNAME_NONE, new IconEntry("NONE"));
}
diff --git a/indra/newview/llinventoryicon.h b/indra/newview/llinventoryicon.h
index 3c7ac7f609..9a2cc08095 100644
--- a/indra/newview/llinventoryicon.h
+++ b/indra/newview/llinventoryicon.h
@@ -73,8 +73,8 @@ public:
ICONNAME_LINKITEM,
ICONNAME_LINKFOLDER,
+ ICONNAME_INVALID,
ICONNAME_COUNT,
-
ICONNAME_NONE = -1
};
diff --git a/indra/newview/llpanelgroup.cpp b/indra/newview/llpanelgroup.cpp
index e42057e93a..62ed7acb15 100644
--- a/indra/newview/llpanelgroup.cpp
+++ b/indra/newview/llpanelgroup.cpp
@@ -112,6 +112,7 @@ void LLPanelGroup::onOpen(const LLSD& key)
if(!key.has("action"))
{
setGroupID(group_id);
+ getChild<LLAccordionCtrl>("groups_accordion")->expandDefaultTab();
return;
}
@@ -176,11 +177,6 @@ BOOL LLPanelGroup::postBuild()
LLPanelGroupTab* panel_notices = findChild<LLPanelGroupTab>("group_notices_tab_panel");
LLPanelGroupTab* panel_land = findChild<LLPanelGroupTab>("group_land_tab_panel");
- if (LLAccordionCtrl* accordion_ctrl = getChild<LLAccordionCtrl>("groups_accordion"))
- {
- setVisibleCallback(boost::bind(&LLPanelGroup::onVisibilityChange, this, _2, accordion_ctrl));
- }
-
if(panel_general) mTabs.push_back(panel_general);
if(panel_roles) mTabs.push_back(panel_roles);
if(panel_notices) mTabs.push_back(panel_notices);
@@ -304,14 +300,6 @@ void LLPanelGroup::onBtnCancel()
onBackBtnClick();
}
-void LLPanelGroup::onVisibilityChange(const LLSD &in_visible_chain, LLAccordionCtrl* accordion_ctrl)
-{
- if (in_visible_chain.asBoolean() && accordion_ctrl != NULL)
- {
- accordion_ctrl->expandDefaultTab();
- }
-}
-
void LLPanelGroup::changed(LLGroupChange gc)
{
for(std::vector<LLPanelGroupTab* >::iterator it = mTabs.begin();it!=mTabs.end();++it)
diff --git a/indra/newview/llpanelgroup.h b/indra/newview/llpanelgroup.h
index 86875d2da3..b494c7d403 100644
--- a/indra/newview/llpanelgroup.h
+++ b/indra/newview/llpanelgroup.h
@@ -36,7 +36,6 @@ class LLOfferInfo;
const S32 UPDATE_MEMBERS_PER_FRAME = 500;
// Forward declares
-class LLAccordionCtrl;
class LLPanelGroupTab;
class LLTabContainer;
class LLAgent;
@@ -97,7 +96,6 @@ protected:
void onBackBtnClick();
void onBtnJoin();
void onBtnCancel();
- void onVisibilityChange(const LLSD &in_visible_chain, LLAccordionCtrl* accordion_ctrl);
static void onBtnApply(void*);
static void onBtnRefresh(void*);
diff --git a/indra/newview/llpanelpeople.cpp b/indra/newview/llpanelpeople.cpp
index 06ba08b51c..d096b17145 100644
--- a/indra/newview/llpanelpeople.cpp
+++ b/indra/newview/llpanelpeople.cpp
@@ -522,8 +522,10 @@ BOOL LLPanelPeople::postBuild()
mAllFriendList = friends_tab->getChild<LLAvatarList>("avatars_all");
mOnlineFriendList->setNoItemsCommentText(getString("no_friends_online"));
mOnlineFriendList->setShowIcons("FriendsListShowIcons");
+ mOnlineFriendList->showPermissions("FriendsListShowPermissions");
mAllFriendList->setNoItemsCommentText(getString("no_friends"));
mAllFriendList->setShowIcons("FriendsListShowIcons");
+ mAllFriendList->showPermissions("FriendsListShowPermissions");
LLPanel* nearby_tab = getChild<LLPanel>(NEARBY_TAB_NAME);
nearby_tab->setVisibleCallback(boost::bind(&Updater::setActive, mNearbyListUpdater, _2));
@@ -1205,6 +1207,14 @@ void LLPanelPeople::onFriendsViewSortMenuItemClicked(const LLSD& userdata)
mAllFriendList->toggleIcons();
mOnlineFriendList->toggleIcons();
}
+ else if (chosen_item == "view_permissions")
+ {
+ bool show_permissions = !gSavedSettings.getBOOL("FriendsListShowPermissions");
+ gSavedSettings.setBOOL("FriendsListShowPermissions", show_permissions);
+
+ mAllFriendList->showPermissions(show_permissions);
+ mOnlineFriendList->showPermissions(show_permissions);
+ }
}
void LLPanelPeople::onGroupsViewSortMenuItemClicked(const LLSD& userdata)
diff --git a/indra/newview/llsidetray.cpp b/indra/newview/llsidetray.cpp
index 7af3ad9896..1d32b58948 100644
--- a/indra/newview/llsidetray.cpp
+++ b/indra/newview/llsidetray.cpp
@@ -244,9 +244,7 @@ void LLSideTrayTab::toggleTabDocked()
LLFloater* floater_tab = LLFloaterReg::getInstance("side_bar_tab", tab_name);
if (!floater_tab) return;
- LLFloaterReg::toggleInstance("side_bar_tab", tab_name);
-
- bool docking = !LLFloater::isShown(floater_tab);
+ bool docking = LLFloater::isShown(floater_tab);
// Hide the "Tear Off" button when a tab gets undocked
// and show "Dock" button instead.
@@ -261,6 +259,10 @@ void LLSideTrayTab::toggleTabDocked()
{
undock(floater_tab);
}
+
+ // Open/close the floater *after* we reparent the tab panel,
+ // so that it doesn't receive redundant visibility change notifications.
+ LLFloaterReg::toggleInstance("side_bar_tab", tab_name);
}
void LLSideTrayTab::dock()
@@ -282,7 +284,7 @@ void LLSideTrayTab::dock()
if (side_tray->getCollapsed())
{
- side_tray->expandSideBar();
+ side_tray->expandSideBar(false);
}
}
@@ -291,6 +293,10 @@ void LLSideTrayTab::undock(LLFloater* floater_tab)
LLSideTray* side_tray = getSideTray();
if (!side_tray) return;
+ // Remember whether the tab have been active before detaching
+ // because removeTab() will change active tab.
+ bool was_active = side_tray->getActiveTab() == this;
+
// Remove the tab from Side Tray's tabs list.
// We have to do it despite removing the tab from Side Tray's child view tree
// by addChild(). Otherwise the tab could be accessed by the pointer in LLSideTray::mTabs.
@@ -300,7 +306,12 @@ void LLSideTrayTab::undock(LLFloater* floater_tab)
return;
}
- setVisible(true); // *HACK: restore visibility after being hidden by LLSideTray::selectTabByName().
+ // If we're undocking while side tray is collapsed we need to explicitly show the panel.
+ if (!getVisible())
+ {
+ setVisible(true);
+ }
+
floater_tab->addChild(this);
floater_tab->setTitle(mTabTitle);
@@ -334,7 +345,7 @@ void LLSideTrayTab::undock(LLFloater* floater_tab)
side_tray->collapseSideBar();
}
- if (side_tray->getActiveTab() != this)
+ if (!was_active)
{
// When a tab other then current active tab is detached from Side Tray
// onOpen() should be called as tab visibility is changed.
@@ -618,8 +629,9 @@ bool LLSideTray::selectTabByIndex(size_t index)
return selectTabByName(sidebar_tab->getName());
}
-bool LLSideTray::selectTabByName (const std::string& name)
+bool LLSideTray::selectTabByName(const std::string& name, bool keep_prev_visible)
{
+ LLSideTrayTab* tab_to_keep_visible = NULL;
LLSideTrayTab* new_tab = getTab(name);
if (!new_tab) return false;
@@ -630,6 +642,8 @@ bool LLSideTray::selectTabByName (const std::string& name)
//deselect old tab
if (mActiveTab)
{
+ // Keep previously active tab visible if requested.
+ if (keep_prev_visible) tab_to_keep_visible = mActiveTab;
toggleTabButton(mActiveTab);
}
@@ -650,9 +664,17 @@ bool LLSideTray::selectTabByName (const std::string& name)
for ( child_it = mTabs.begin(); child_it != mTabs.end(); ++child_it)
{
LLSideTrayTab* sidebar_tab = *child_it;
+
+ bool vis = sidebar_tab == mActiveTab;
+
+ // Force keeping the tab visible if requested.
+ vis |= sidebar_tab == tab_to_keep_visible;
+
// When the last tab gets detached, for a short moment the "Toggle Sidebar" pseudo-tab
// is shown. So, to avoid the flicker we make sure it never gets visible.
- sidebar_tab->setVisible(sidebar_tab == mActiveTab && (*child_it)->getName() != "sidebar_openclose");
+ vis &= (*child_it)->getName() != "sidebar_openclose";
+
+ sidebar_tab->setVisible(vis);
}
return true;
}
@@ -741,7 +763,7 @@ bool LLSideTray::removeTab(LLSideTrayTab* tab)
{
child_vector_iter_t next_tab_it =
(tab_it < (mTabs.end() - 1)) ? tab_it + 1 : mTabs.begin();
- selectTabByName((*next_tab_it)->getName());
+ selectTabByName((*next_tab_it)->getName(), true); // Don't hide the tab being removed.
}
// Remove the tab.
@@ -1016,7 +1038,7 @@ void LLSideTray::collapseSideBar()
setFocus( FALSE );
}
-void LLSideTray::expandSideBar()
+void LLSideTray::expandSideBar(bool open_active)
{
mCollapsed = false;
LLSideTrayTab* openclose_tab = getTab("sidebar_openclose");
@@ -1024,8 +1046,11 @@ void LLSideTray::expandSideBar()
{
mCollapseButton->setImageOverlay( openclose_tab->mImageSelected );
}
- LLSD key;//empty
- mActiveTab->onOpen(key);
+
+ if (open_active)
+ {
+ mActiveTab->onOpen(LLSD());
+ }
reflectCollapseChange();
diff --git a/indra/newview/llsidetray.h b/indra/newview/llsidetray.h
index 248def8e3d..4e79007c13 100644
--- a/indra/newview/llsidetray.h
+++ b/indra/newview/llsidetray.h
@@ -76,9 +76,12 @@ public:
// interface functions
/**
- * Select tab with specific name and set it active
- */
- bool selectTabByName (const std::string& name);
+ * Select tab with specific name and set it active
+ *
+ * @param name Tab to switch to.
+ * @param keep_prev_visible Whether to keep the previously selected tab visible.
+ */
+ bool selectTabByName (const std::string& name, bool keep_prev_visible = false);
/**
* Select tab with specific index and set it active
@@ -119,8 +122,10 @@ public:
/*
* expand SideBar
+ *
+ * @param open_active Whether to call onOpen() for the active tab.
*/
- void expandSideBar ();
+ void expandSideBar(bool open_active = true);
/**
diff --git a/indra/newview/lltexturecache.cpp b/indra/newview/lltexturecache.cpp
index 2fd0a22f80..6a213309a0 100644
--- a/indra/newview/lltexturecache.cpp
+++ b/indra/newview/lltexturecache.cpp
@@ -927,7 +927,7 @@ void LLTextureCache::setReadOnly(BOOL read_only)
}
//called in the main thread.
-S64 LLTextureCache::initCache(ELLPath location, S64 max_size, BOOL disable_texture_cache)
+S64 LLTextureCache::initCache(ELLPath location, S64 max_size, BOOL texture_cache_mismatch)
{
llassert_always(getPending() == 0) ; //should not start accessing the texture cache before initialized.
@@ -942,20 +942,23 @@ S64 LLTextureCache::initCache(ELLPath location, S64 max_size, BOOL disable_textu
sCacheMaxTexturesSize = max_size;
max_size -= sCacheMaxTexturesSize;
- if(disable_texture_cache) //the texture cache is disabled
- {
- llinfos << "The texture cache is disabled!" << llendl ;
- setReadOnly(TRUE) ;
- purgeAllTextures(true);
-
- return max_size ;
- }
-
LL_INFOS("TextureCache") << "Headers: " << sCacheMaxEntries
<< " Textures size: " << sCacheMaxTexturesSize/(1024*1024) << " MB" << LL_ENDL;
setDirNames(location);
+ if(texture_cache_mismatch)
+ {
+ //if readonly, disable the texture cache,
+ //otherwise wipe out the texture cache.
+ purgeAllTextures(true);
+
+ if(mReadOnly)
+ {
+ return max_size ;
+ }
+ }
+
if (!mReadOnly)
{
LLFile::mkdir(mTexturesDirName);
diff --git a/indra/newview/lltexturecache.h b/indra/newview/lltexturecache.h
index 7f1bba56fb..64e3a2658c 100644
--- a/indra/newview/lltexturecache.h
+++ b/indra/newview/lltexturecache.h
@@ -105,7 +105,7 @@ public:
void purgeCache(ELLPath location);
void setReadOnly(BOOL read_only) ;
- S64 initCache(ELLPath location, S64 maxsize, BOOL disable_texture_cache);
+ S64 initCache(ELLPath location, S64 maxsize, BOOL texture_cache_mismatch);
handle_t readFromCache(const std::string& local_filename, const LLUUID& id, U32 priority, S32 offset, S32 size,
ReadResponder* responder);
diff --git a/indra/newview/lltextureview.cpp b/indra/newview/lltextureview.cpp
index 6a75e4b009..c87aff022f 100644
--- a/indra/newview/lltextureview.cpp
+++ b/indra/newview/lltextureview.cpp
@@ -48,6 +48,7 @@
#include "llviewertexture.h"
#include "llviewertexturelist.h"
#include "llvovolume.h"
+#include "llviewerstats.h"
// For avatar texture view
#include "llvoavatarself.h"
@@ -513,6 +514,7 @@ void LLGLTexMemBar::draw()
F32 cache_max_usage = (F32)BYTES_TO_MEGA_BYTES(LLAppViewer::getTextureCache()->getMaxUsage()) ;
S32 line_height = (S32)(LLFontGL::getFontMonospace()->getLineHeight() + .5f);
S32 v_offset = (S32)((texture_bar_height + 2.2f) * mTextureView->mNumTextureBars + 2.0f);
+ S32 total_downloaded = BYTES_TO_MEGA_BYTES(gTotalTextureBytes);
//----------------------------------------------------------------------------
LLGLSUIDefault gls_ui;
LLColor4 text_color(1.f, 1.f, 1.f, 0.75f);
@@ -523,13 +525,13 @@ void LLGLTexMemBar::draw()
LLFontGL::getFontMonospace()->renderUTF8(text, 0, 0, v_offset + line_height*6,
text_color, LLFontGL::LEFT, LLFontGL::TOP);
- text = llformat("GL Tot: %d/%d MB Bound: %d/%d MB Raw Tot: %d MB Bias: %.2f Cache: %.1f/%.1f MB",
+ text = llformat("GL Tot: %d/%d MB Bound: %d/%d MB Raw Tot: %d MB Bias: %.2f Cache: %.1f/%.1f MB Net Tot: %d MB",
total_mem,
max_total_mem,
bound_mem,
max_bound_mem,
- LLImageRaw::sGlobalRawMemory >> 20, discard_bias,
- cache_usage, cache_max_usage);
+ LLImageRaw::sGlobalRawMemory >> 20, discard_bias,
+ cache_usage, cache_max_usage, total_downloaded);
//, cache_entries, cache_max_entries
LLFontGL::getFontMonospace()->renderUTF8(text, 0, 0, v_offset + line_height*3,
diff --git a/indra/newview/llviewerfloaterreg.cpp b/indra/newview/llviewerfloaterreg.cpp
index 8728298575..b6f2d34663 100644
--- a/indra/newview/llviewerfloaterreg.cpp
+++ b/indra/newview/llviewerfloaterreg.cpp
@@ -86,6 +86,7 @@
#include "llfloaterscriptlimits.h"
#include "llfloatersellland.h"
#include "llfloatersettingsdebug.h"
+#include "llfloatersidetraytab.h"
#include "llfloatersnapshot.h"
#include "llfloatertelehub.h"
#include "llfloatertestinspectors.h"
@@ -234,7 +235,7 @@ void LLViewerFloaterReg::registerFloaters()
LLFloaterReg::add("script_limits", "floater_script_limits.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterScriptLimits>);
LLFloaterReg::add("sell_land", "floater_sell_land.xml", &LLFloaterSellLand::buildFloater);
LLFloaterReg::add("settings_debug", "floater_settings_debug.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSettingsDebug>);
- LLFloaterReg::add("side_bar_tab", "floater_side_bar_tab.xml",&LLFloaterReg::build<LLFloater>);
+ LLFloaterReg::add("side_bar_tab", "floater_side_bar_tab.xml", &LLFloaterReg::build<LLFloaterSideTrayTab>);
LLFloaterReg::add("stats", "floater_stats.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloater>);
LLFloaterReg::add("start_queue", "floater_script_queue.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterRunQueue>);
LLFloaterReg::add("stop_queue", "floater_script_queue.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterNotRunQueue>);
diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp
index a86efa215b..98f16757b2 100644
--- a/indra/newview/llviewerregion.cpp
+++ b/indra/newview/llviewerregion.cpp
@@ -69,13 +69,6 @@
#pragma warning(disable:4355)
#endif
-// Viewer object cache version, change if object update
-// format changes. JC
-const U32 INDRA_OBJECT_CACHE_VERSION = 14;
-
-// Format string used to construct filename for the object cache
-static const char OBJECT_CACHE_FILENAME[] = "objects_%d_%d.slc";
-
extern BOOL gNoRender;
const F32 WATER_TEXTURE_SCALE = 8.f; // Number of times to repeat the water texture across a region
@@ -214,7 +207,7 @@ LLViewerRegion::LLViewerRegion(const U64 &handle,
mProductName("unknown"),
mHttpUrl(""),
mCacheLoaded(FALSE),
- mCacheEntriesCount(0),
+ mCacheDirty(FALSE),
mCacheID(),
mEventPoll(NULL),
mReleaseNotesRequested(FALSE),
@@ -264,8 +257,6 @@ LLViewerRegion::LLViewerRegion(const U64 &handle,
// Create the object lists
initStats();
- mCacheStart.append(mCacheEnd);
-
//create object partitions
//MUST MATCH declaration of eObjectPartitions
mObjectPartition.push_back(new LLHUDPartition()); //PARTITION_HUD
@@ -324,19 +315,6 @@ LLViewerRegion::~LLViewerRegion()
std::for_each(mObjectPartition.begin(), mObjectPartition.end(), DeletePointer());
}
-
-const std::string LLViewerRegion::getObjectCacheFilename(U64 mHandle) const
-{
- std::string filename;
- U32 region_x, region_y;
-
- grid_from_region_handle(mHandle, &region_x, &region_y);
- filename = gDirUtilp->getExpandedFilename(LL_PATH_CACHE,
- llformat(OBJECT_CACHE_FILENAME, region_x, region_y));
-
- return filename;
-}
-
void LLViewerRegion::loadObjectCache()
{
if (mCacheLoaded)
@@ -347,77 +325,10 @@ void LLViewerRegion::loadObjectCache()
// Presume success. If it fails, we don't want to try again.
mCacheLoaded = TRUE;
- LLVOCacheEntry *entry;
-
- std::string filename = getObjectCacheFilename(mHandle);
- LL_DEBUGS("ObjectCache") << filename << LL_ENDL;
-
- LLFILE* fp = LLFile::fopen(filename, "rb"); /* Flawfinder: ignore */
- if (!fp)
- {
- // might not have a file, which is normal
- return;
- }
-
- U32 zero;
- size_t nread;
- nread = fread(&zero, sizeof(U32), 1, fp);
- if (nread != 1 || zero)
- {
- // a non-zero value here means bad things!
- // skip reading the cached values
- llinfos << "Cache file invalid" << llendl;
- fclose(fp);
- return;
- }
-
- U32 version;
- nread = fread(&version, sizeof(U32), 1, fp);
- if (nread != 1 || version != INDRA_OBJECT_CACHE_VERSION)
+ if(LLVOCache::hasInstance())
{
- // a version mismatch here means we've changed the binary format!
- // skip reading the cached values
- llinfos << "Cache version changed, discarding" << llendl;
- fclose(fp);
- return;
- }
-
- LLUUID cache_id;
- nread = fread(&cache_id.mData, 1, UUID_BYTES, fp);
- if (nread != (size_t)UUID_BYTES || mCacheID != cache_id)
- {
- llinfos << "Cache ID doesn't match for this region, discarding"
- << llendl;
- fclose(fp);
- return;
- }
-
- S32 num_entries;
- nread = fread(&num_entries, sizeof(S32), 1, fp);
- if (nread != 1)
- {
- llinfos << "Short read, discarding" << llendl;
- fclose(fp);
- return;
+ LLVOCache::getInstance()->readFromCache(mHandle, mCacheID, mCacheMap) ;
}
-
- S32 i;
- for (i = 0; i < num_entries; i++)
- {
- entry = new LLVOCacheEntry(fp);
- if (!entry->getLocalID())
- {
- llwarns << "Aborting cache file load for " << filename << ", cache file corruption!" << llendl;
- delete entry;
- entry = NULL;
- break;
- }
- mCacheEnd.insert(*entry);
- mCacheMap[entry->getLocalID()] = entry;
- mCacheEntriesCount++;
- }
-
- fclose(fp);
}
@@ -428,61 +339,22 @@ void LLViewerRegion::saveObjectCache()
return;
}
- S32 num_entries = mCacheEntriesCount;
- if (0 == num_entries)
+ if (mCacheMap.empty())
{
return;
}
- std::string filename = getObjectCacheFilename(mHandle);
- LL_DEBUGS("ObjectCache") << filename << LL_ENDL;
-
- LLFILE* fp = LLFile::fopen(filename, "wb"); /* Flawfinder: ignore */
- if (!fp)
+ if(LLVOCache::hasInstance())
{
- llwarns << "Unable to write cache file " << filename << llendl;
- return;
+ LLVOCache::getInstance()->writeToCache(mHandle, mCacheID, mCacheMap, mCacheDirty) ;
+ mCacheDirty = FALSE;
}
- // write out zero to indicate a version cache file
- U32 zero = 0;
- if (fwrite(&zero, sizeof(U32), 1, fp) != 1)
+ for(LLVOCacheEntry::vocache_entry_map_t::iterator iter = mCacheMap.begin(); iter != mCacheMap.end(); ++iter)
{
- llwarns << "Short write" << llendl;
+ delete iter->second;
}
-
- // write out version number
- U32 version = INDRA_OBJECT_CACHE_VERSION;
- if (fwrite(&version, sizeof(U32), 1, fp) != 1)
- {
- llwarns << "Short write" << llendl;
- }
-
- // write the cache id for this sim
- if (fwrite(&mCacheID.mData, 1, UUID_BYTES, fp) != (size_t)UUID_BYTES)
- {
- llwarns << "Short write" << llendl;
- }
-
- if (fwrite(&num_entries, sizeof(S32), 1, fp) != 1)
- {
- llwarns << "Short write" << llendl;
- }
-
- LLVOCacheEntry *entry;
-
- for (entry = mCacheStart.getNext(); entry && (entry != &mCacheEnd); entry = entry->getNext())
- {
- entry->writeToFile(fp);
- }
-
mCacheMap.clear();
- mCacheEnd.unlink();
- mCacheEnd.init();
- mCacheStart.deleteAll();
- mCacheStart.init();
-
- fclose(fp);
}
void LLViewerRegion::sendMessage()
@@ -1175,7 +1047,6 @@ void LLViewerRegion::cacheFullUpdate(LLViewerObject* objectp, LLDataPackerBinary
mCacheMap.erase(local_id);
delete entry;
entry = new LLVOCacheEntry(local_id, crc, dp);
- mCacheEnd.insert(*entry);
mCacheMap[local_id] = entry;
}
}
@@ -1184,18 +1055,13 @@ void LLViewerRegion::cacheFullUpdate(LLViewerObject* objectp, LLDataPackerBinary
// we haven't seen this object before
// Create new entry and add to map
- if (mCacheEntriesCount > MAX_OBJECT_CACHE_ENTRIES)
+ if (mCacheMap.size() > MAX_OBJECT_CACHE_ENTRIES)
{
- entry = mCacheStart.getNext();
- mCacheMap.erase(entry->getLocalID());
- delete entry;
- mCacheEntriesCount--;
+ mCacheMap.erase(mCacheMap.begin());
}
entry = new LLVOCacheEntry(local_id, crc, dp);
- mCacheEnd.insert(*entry);
mCacheMap[local_id] = entry;
- mCacheEntriesCount++;
}
return ;
}
@@ -1310,6 +1176,7 @@ void LLViewerRegion::requestCacheMisses()
mCacheMissFull.reset();
mCacheMissCRC.reset();
+ mCacheDirty = TRUE ;
// llinfos << "KILLDEBUG Sent cache miss full " << full_count << " crc " << crc_count << llendl;
}
@@ -1327,9 +1194,10 @@ void LLViewerRegion::dumpCache()
}
LLVOCacheEntry *entry;
-
- for (entry = mCacheStart.getNext(); entry && (entry != &mCacheEnd); entry = entry->getNext())
+ for(LLVOCacheEntry::vocache_entry_map_t::iterator iter = mCacheMap.begin(); iter != mCacheMap.end(); ++iter)
{
+ entry = iter->second ;
+
S32 hits = entry->getHitCount();
S32 changes = entry->getCRCChangeCount();
@@ -1340,7 +1208,7 @@ void LLViewerRegion::dumpCache()
change_bin[changes]++;
}
- llinfos << "Count " << mCacheEntriesCount << llendl;
+ llinfos << "Count " << mCacheMap.size() << llendl;
for (i = 0; i < BINS; i++)
{
llinfos << "Hits " << i << " " << hit_bin[i] << llendl;
diff --git a/indra/newview/llviewerregion.h b/indra/newview/llviewerregion.h
index 361ae87e1b..038c831e59 100644
--- a/indra/newview/llviewerregion.h
+++ b/indra/newview/llviewerregion.h
@@ -323,9 +323,6 @@ public:
LLDynamicArray<LLUUID> mMapAvatarIDs;
private:
- // determine the cache filename for the region from the region handle
- const std::string getObjectCacheFilename(U64 mHandle) const;
-
// The surfaces and other layers
LLSurface* mLandp;
@@ -387,11 +384,8 @@ private:
// Regions can have order 10,000 objects, so assume
// a structure of size 2^14 = 16,000
BOOL mCacheLoaded;
- typedef std::map<U32, LLVOCacheEntry *> cache_map_t;
- cache_map_t mCacheMap;
- LLVOCacheEntry mCacheStart;
- LLVOCacheEntry mCacheEnd;
- U32 mCacheEntriesCount;
+ BOOL mCacheDirty;
+ LLVOCacheEntry::vocache_entry_map_t mCacheMap;
LLDynamicArray<U32> mCacheMissFull;
LLDynamicArray<U32> mCacheMissCRC;
// time?
diff --git a/indra/newview/llviewerstats.h b/indra/newview/llviewerstats.h
index 5d8f58d5e9..ca977d4599 100644
--- a/indra/newview/llviewerstats.h
+++ b/indra/newview/llviewerstats.h
@@ -263,5 +263,5 @@ void send_stats();
extern std::map<S32,LLFrameTimer> gDebugTimers;
extern std::map<S32,std::string> gDebugTimerLabel;
-
+extern U32 gTotalTextureBytes;
#endif // LL_LLVIEWERSTATS_H
diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp
index 556451e390..43d18c6d83 100644
--- a/indra/newview/llviewerwindow.cpp
+++ b/indra/newview/llviewerwindow.cpp
@@ -3911,7 +3911,14 @@ BOOL LLViewerWindow::rawSnapshot(LLImageRaw *raw, S32 image_width, S32 image_hei
image_buffer_x = llfloor(snapshot_width*scale_factor) ;
image_buffer_y = llfloor(snapshot_height *scale_factor) ;
}
- raw->resize(image_buffer_x, image_buffer_y, 3);
+ if(image_buffer_x > 0 && image_buffer_y > 0)
+ {
+ raw->resize(image_buffer_x, image_buffer_y, 3);
+ }
+ else
+ {
+ return FALSE ;
+ }
if(raw->isBufferInvalid())
{
return FALSE ;
diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp
index f985ee0c15..cab6fbdc93 100644
--- a/indra/newview/llvoavatar.cpp
+++ b/indra/newview/llvoavatar.cpp
@@ -6835,12 +6835,14 @@ void LLVOAvatar::processAvatarAppearance( LLMessageSystem* mesgsys )
llinfos << "AvatarAppearance msg received without any parameters, object: " << getID() << llendl;
}
+ const F32 LOADING_TIMEOUT_SECONDS = 60.f;
// this isn't really a problem if we already have a non-default shape
- if (visualParamWeightsAreDefault())
+ if (visualParamWeightsAreDefault() && mRuthTimer.getElapsedTimeF32() > LOADING_TIMEOUT_SECONDS)
{
// re-request appearance, hoping that it comes back with a shape next time
llinfos << "Re-requesting AvatarAppearance for object: " << getID() << llendl;
LLAvatarPropertiesProcessor::getInstance()->sendAvatarTexturesRequest(getID());
+ mRuthTimer.reset();
}
else
{
diff --git a/indra/newview/llvoavatarself.cpp b/indra/newview/llvoavatarself.cpp
index a231afad3f..ec5c95469e 100644
--- a/indra/newview/llvoavatarself.cpp
+++ b/indra/newview/llvoavatarself.cpp
@@ -1163,12 +1163,24 @@ BOOL LLVOAvatarSelf::detachAttachmentIntoInventory(const LLUUID &item_id)
gMessageSystem->addUUIDFast(_PREHASH_ItemID, item_id);
gMessageSystem->sendReliable(gAgent.getRegion()->getHost());
- // this object might have been selected, so let the selection manager know it's gone now
+ // This object might have been selected, so let the selection manager know it's gone now
LLViewerObject *found_obj = gObjectList.findObject(item_id);
if (found_obj)
{
LLSelectMgr::getInstance()->remove(found_obj);
}
+
+ // Error checking in case this object was attached to an invalid point
+ // In that case, just remove the item from COF preemptively since detach
+ // will fail.
+ if (isAgentAvatarValid())
+ {
+ const LLViewerObject *attached_obj = gAgentAvatarp->getWornAttachment(item_id);
+ if (!attached_obj)
+ {
+ LLAppearanceMgr::instance().removeCOFItemLinks(item_id, false);
+ }
+ }
return TRUE;
}
return FALSE;
diff --git a/indra/newview/llvoavatarself.h b/indra/newview/llvoavatarself.h
index eb2475f666..23a799ea3a 100644
--- a/indra/newview/llvoavatarself.h
+++ b/indra/newview/llvoavatarself.h
@@ -33,6 +33,7 @@
struct LocalTextureData;
+
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// LLVOAvatarSelf
//
diff --git a/indra/newview/llvocache.cpp b/indra/newview/llvocache.cpp
index 4e6d630ed8..0b903e62b1 100644
--- a/indra/newview/llvocache.cpp
+++ b/indra/newview/llvocache.cpp
@@ -25,10 +25,19 @@
*/
#include "llviewerprecompiledheaders.h"
-
#include "llvocache.h"
-
#include "llerror.h"
+#include "llregionhandle.h"
+
+BOOL check_read(LLAPRFile* apr_file, void* src, S32 n_bytes)
+{
+ return apr_file->read(src, n_bytes) == n_bytes ;
+}
+
+BOOL check_write(LLAPRFile* apr_file, void* src, S32 n_bytes)
+{
+ return apr_file->write(src, n_bytes) == n_bytes ;
+}
//---------------------------------------------------------------------------
// LLVOCacheEntry
@@ -57,26 +66,31 @@ LLVOCacheEntry::LLVOCacheEntry()
mDP.assignBuffer(mBuffer, 0);
}
+LLVOCacheEntry::LLVOCacheEntry(LLAPRFile* apr_file)
+{
+ S32 size = -1;
+ BOOL success;
-static inline void checkedRead(LLFILE *fp, void *data, size_t nbytes)
+ success = check_read(apr_file, &mLocalID, sizeof(U32));
+ if(success)
{
- if (fread(data, 1, nbytes, fp) != nbytes)
+ success = check_read(apr_file, &mCRC, sizeof(U32));
+ }
+ if(success)
{
- llwarns << "Short read" << llendl;
- memset(data, 0, nbytes);
+ success = check_read(apr_file, &mHitCount, sizeof(S32));
}
+ if(success)
+ {
+ success = check_read(apr_file, &mDupeCount, sizeof(S32));
}
-
-LLVOCacheEntry::LLVOCacheEntry(LLFILE *fp)
+ if(success)
{
- S32 size;
- checkedRead(fp, &mLocalID, sizeof(U32));
- checkedRead(fp, &mCRC, sizeof(U32));
- checkedRead(fp, &mHitCount, sizeof(S32));
- checkedRead(fp, &mDupeCount, sizeof(S32));
- checkedRead(fp, &mCRCChangeCount, sizeof(S32));
-
- checkedRead(fp, &size, sizeof(S32));
+ success = check_read(apr_file, &mCRCChangeCount, sizeof(S32));
+ }
+ if(success)
+ {
+ success = check_read(apr_file, &size, sizeof(S32));
// Corruption in the cache entries
if ((size > 10000) || (size < 1))
@@ -90,11 +104,30 @@ LLVOCacheEntry::LLVOCacheEntry(LLFILE *fp)
mBuffer = NULL;
return;
}
+ }
+ if(success && size > 0)
+ {
+ mBuffer = new U8[size];
+ success = check_read(apr_file, mBuffer, size);
- mBuffer = new U8[size];
- checkedRead(fp, mBuffer, size);
+ if(success)
+ {
mDP.assignBuffer(mBuffer, size);
}
+ else
+ {
+ delete[] mBuffer ;
+ mBuffer = NULL ;
+ }
+ }
+
+ if(!success)
+ {
+ mLocalID = 0;
+ mCRC = 0;
+ mBuffer = NULL;
+ }
+}
LLVOCacheEntry::~LLVOCacheEntry()
{
@@ -148,22 +181,467 @@ void LLVOCacheEntry::dump() const
<< llendl;
}
-static inline void checkedWrite(LLFILE *fp, const void *data, size_t nbytes)
+BOOL LLVOCacheEntry::writeToFile(LLAPRFile* apr_file) const
+{
+ BOOL success;
+ success = check_write(apr_file, (void*)&mLocalID, sizeof(U32));
+ if(success)
+ {
+ success = check_write(apr_file, (void*)&mCRC, sizeof(U32));
+ }
+ if(success)
+ {
+ success = check_write(apr_file, (void*)&mHitCount, sizeof(S32));
+ }
+ if(success)
+ {
+ success = check_write(apr_file, (void*)&mDupeCount, sizeof(S32));
+ }
+ if(success)
+ {
+ success = check_write(apr_file, (void*)&mCRCChangeCount, sizeof(S32));
+ }
+ if(success)
+ {
+ S32 size = mDP.getBufferSize();
+ success = check_write(apr_file, (void*)&size, sizeof(S32));
+
+ if(success)
+ {
+ success = check_write(apr_file, (void*)mBuffer, size);
+ }
+}
+
+ return success ;
+}
+
+//-------------------------------------------------------------------
+//LLVOCache
+//-------------------------------------------------------------------
+// Format string used to construct filename for the object cache
+static const char OBJECT_CACHE_FILENAME[] = "objects_%d_%d.slc";
+
+const U32 MAX_NUM_OBJECT_ENTRIES = 128 ;
+const U32 NUM_ENTRIES_TO_PURGE = 16 ;
+const char* object_cache_dirname = "objectcache";
+const char* header_filename = "object.cache";
+
+LLVOCache* LLVOCache::sInstance = NULL;
+
+//static
+LLVOCache* LLVOCache::getInstance()
+{
+ if(!sInstance)
+ {
+ sInstance = new LLVOCache() ;
+}
+ return sInstance ;
+}
+
+//static
+BOOL LLVOCache::hasInstance()
+{
+ return sInstance != NULL ;
+}
+
+//static
+void LLVOCache::destroyClass()
+{
+ if(sInstance)
+ {
+ delete sInstance ;
+ sInstance = NULL ;
+ }
+}
+
+LLVOCache::LLVOCache():
+ mInitialized(FALSE),
+ mReadOnly(TRUE),
+ mNumEntries(0)
+{
+ mLocalAPRFilePoolp = new LLVolatileAPRPool() ;
+}
+
+LLVOCache::~LLVOCache()
+{
+ writeCacheHeader();
+ clearCacheInMemory();
+ delete mLocalAPRFilePoolp;
+}
+
+void LLVOCache::setDirNames(ELLPath location)
+{
+ std::string delem = gDirUtilp->getDirDelimiter();
+
+ mHeaderFileName = gDirUtilp->getExpandedFilename(location, object_cache_dirname, header_filename);
+ mObjectCacheDirName = gDirUtilp->getExpandedFilename(location, object_cache_dirname);
+}
+
+void LLVOCache::initCache(ELLPath location, U32 size, U32 cache_version)
+{
+ if(mInitialized)
+ {
+ return ;
+ }
+
+ setDirNames(location);
+ if (!mReadOnly)
+ {
+ LLFile::mkdir(mObjectCacheDirName);
+ }
+ mCacheSize = llmin(size, MAX_NUM_OBJECT_ENTRIES) ;
+ mCacheSize = llmax(mCacheSize, NUM_ENTRIES_TO_PURGE);
+
+ mMetaInfo.mVersion = cache_version;
+ readCacheHeader();
+ mInitialized = TRUE ;
+
+ if(mMetaInfo.mVersion != cache_version)
+ {
+ mMetaInfo.mVersion = cache_version ;
+ if(mReadOnly) //disable cache
+ {
+ clearCacheInMemory();
+ }
+ else //delete the current cache if the format does not match.
+ {
+ removeCache();
+ }
+ }
+}
+
+void LLVOCache::removeCache(ELLPath location)
+{
+ if(mReadOnly)
+ {
+ return ;
+ }
+
+ std::string delem = gDirUtilp->getDirDelimiter();
+ std::string mask = delem + "*";
+ std::string cache_dir = gDirUtilp->getExpandedFilename(location, object_cache_dirname);
+ gDirUtilp->deleteFilesInDir(cache_dir, mask); //delete all files
+ LLFile::rmdir(cache_dir);
+
+ clearCacheInMemory();
+ mInitialized = FALSE ;
+}
+
+void LLVOCache::removeCache()
+{
+ llassert_always(mInitialized) ;
+ if(mReadOnly)
+ {
+ return ;
+ }
+
+ std::string delem = gDirUtilp->getDirDelimiter();
+ std::string mask = delem + "*";
+ gDirUtilp->deleteFilesInDir(mObjectCacheDirName, mask);
+
+ clearCacheInMemory() ;
+ writeCacheHeader();
+}
+
+void LLVOCache::clearCacheInMemory()
+{
+ if(!mHeaderEntryQueue.empty())
+ {
+ for(header_entry_queue_t::iterator iter = mHeaderEntryQueue.begin(); iter != mHeaderEntryQueue.end(); ++iter)
+ {
+ delete *iter ;
+ }
+ mHeaderEntryQueue.clear();
+ mHandleEntryMap.clear();
+ mNumEntries = 0 ;
+ }
+}
+
+void LLVOCache::getObjectCacheFilename(U64 handle, std::string& filename)
+{
+ U32 region_x, region_y;
+
+ grid_from_region_handle(handle, &region_x, &region_y);
+ filename = gDirUtilp->getExpandedFilename(LL_PATH_CACHE, object_cache_dirname,
+ llformat(OBJECT_CACHE_FILENAME, region_x, region_y));
+
+ return ;
+}
+
+void LLVOCache::removeFromCache(U64 handle)
+{
+ if(mReadOnly)
+ {
+ return ;
+ }
+
+ std::string filename;
+ getObjectCacheFilename(handle, filename);
+ LLAPRFile::remove(filename, mLocalAPRFilePoolp);
+}
+
+BOOL LLVOCache::checkRead(LLAPRFile* apr_file, void* src, S32 n_bytes)
+{
+ if(!check_read(apr_file, src, n_bytes))
+ {
+ delete apr_file ;
+ removeCache() ;
+ return FALSE ;
+ }
+
+ return TRUE ;
+}
+
+BOOL LLVOCache::checkWrite(LLAPRFile* apr_file, void* src, S32 n_bytes)
+{
+ if(!check_write(apr_file, src, n_bytes))
+ {
+ delete apr_file ;
+ removeCache() ;
+ return FALSE ;
+ }
+
+ return TRUE ;
+}
+
+void LLVOCache::readCacheHeader()
+{
+ //clear stale info.
+ clearCacheInMemory();
+
+ if (LLAPRFile::isExist(mHeaderFileName, mLocalAPRFilePoolp))
+ {
+ LLAPRFile* apr_file = new LLAPRFile(mHeaderFileName, APR_READ|APR_BINARY, mLocalAPRFilePoolp);
+
+ //read the meta element
+ if(!checkRead(apr_file, &mMetaInfo, sizeof(HeaderMetaInfo)))
+ {
+ return ;
+ }
+
+ HeaderEntryInfo* entry ;
+ mNumEntries = 0 ;
+ while(mNumEntries < MAX_NUM_OBJECT_ENTRIES)
+ {
+ entry = new HeaderEntryInfo() ;
+ if(!checkRead(apr_file, entry, sizeof(HeaderEntryInfo)))
+ {
+ delete entry ;
+ return ;
+ }
+ else if(!entry->mTime) //end of the cache.
+ {
+ delete entry ;
+ return ;
+ }
+
+ entry->mIndex = mNumEntries++ ;
+ mHeaderEntryQueue.insert(entry) ;
+ mHandleEntryMap[entry->mHandle] = entry ;
+ }
+
+ delete apr_file ;
+ }
+ else
+ {
+ writeCacheHeader() ;
+ }
+}
+
+void LLVOCache::writeCacheHeader()
{
- if (fwrite(data, 1, nbytes, fp) != nbytes)
+ if(mReadOnly)
+ {
+ return ;
+ }
+
+ LLAPRFile* apr_file = new LLAPRFile(mHeaderFileName, APR_CREATE|APR_WRITE|APR_BINARY, mLocalAPRFilePoolp);
+
+ //write the meta element
+ if(!checkWrite(apr_file, &mMetaInfo, sizeof(HeaderMetaInfo)))
{
- llwarns << "Short write" << llendl;
+ return ;
}
+
+ mNumEntries = 0 ;
+ for(header_entry_queue_t::iterator iter = mHeaderEntryQueue.begin() ; iter != mHeaderEntryQueue.end(); ++iter)
+ {
+ (*iter)->mIndex = mNumEntries++ ;
+ if(!checkWrite(apr_file, (void*)*iter, sizeof(HeaderEntryInfo)))
+ {
+ return ;
+ }
+ }
+
+ mNumEntries = mHeaderEntryQueue.size() ;
+ if(mNumEntries < MAX_NUM_OBJECT_ENTRIES)
+ {
+ HeaderEntryInfo* entry = new HeaderEntryInfo() ;
+ for(S32 i = mNumEntries ; i < MAX_NUM_OBJECT_ENTRIES ; i++)
+ {
+ //fill the cache with the default entry.
+ if(!checkWrite(apr_file, entry, sizeof(HeaderEntryInfo)))
+ {
+ mReadOnly = TRUE ; //disable the cache.
+ return ;
+ }
+ }
+ delete entry ;
+ }
+ delete apr_file ;
}
-void LLVOCacheEntry::writeToFile(LLFILE *fp) const
+BOOL LLVOCache::updateEntry(const HeaderEntryInfo* entry)
{
- checkedWrite(fp, &mLocalID, sizeof(U32));
- checkedWrite(fp, &mCRC, sizeof(U32));
- checkedWrite(fp, &mHitCount, sizeof(S32));
- checkedWrite(fp, &mDupeCount, sizeof(S32));
- checkedWrite(fp, &mCRCChangeCount, sizeof(S32));
- S32 size = mDP.getBufferSize();
- checkedWrite(fp, &size, sizeof(S32));
- checkedWrite(fp, mBuffer, size);
+ LLAPRFile* apr_file = new LLAPRFile(mHeaderFileName, APR_WRITE|APR_BINARY, mLocalAPRFilePoolp);
+ apr_file->seek(APR_SET, entry->mIndex * sizeof(HeaderEntryInfo) + sizeof(HeaderMetaInfo)) ;
+
+ return checkWrite(apr_file, (void*)entry, sizeof(HeaderEntryInfo)) ;
}
+
+void LLVOCache::readFromCache(U64 handle, const LLUUID& id, LLVOCacheEntry::vocache_entry_map_t& cache_entry_map)
+{
+ llassert_always(mInitialized);
+
+ handle_entry_map_t::iterator iter = mHandleEntryMap.find(handle) ;
+ if(iter == mHandleEntryMap.end()) //no cache
+ {
+ return ;
+ }
+
+ std::string filename;
+ getObjectCacheFilename(handle, filename);
+ LLAPRFile* apr_file = new LLAPRFile(filename, APR_READ|APR_BINARY, mLocalAPRFilePoolp);
+
+ LLUUID cache_id ;
+ if(!checkRead(apr_file, cache_id.mData, UUID_BYTES))
+ {
+ return ;
+ }
+ if(cache_id != id)
+ {
+ llinfos << "Cache ID doesn't match for this region, discarding"<< llendl;
+
+ delete apr_file ;
+ return ;
+ }
+
+ S32 num_entries;
+ if(!checkRead(apr_file, &num_entries, sizeof(S32)))
+ {
+ return ;
+ }
+
+ for (S32 i = 0; i < num_entries; i++)
+ {
+ LLVOCacheEntry* entry = new LLVOCacheEntry(apr_file);
+ if (!entry->getLocalID())
+ {
+ llwarns << "Aborting cache file load for " << filename << ", cache file corruption!" << llendl;
+ delete entry ;
+ break;
+ }
+ cache_entry_map[entry->getLocalID()] = entry;
+ }
+ num_entries = cache_entry_map.size() ;
+
+ delete apr_file ;
+ return ;
+}
+
+void LLVOCache::purgeEntries()
+{
+ U32 limit = mCacheSize - NUM_ENTRIES_TO_PURGE ;
+ while(mHeaderEntryQueue.size() > limit)
+ {
+ header_entry_queue_t::iterator iter = mHeaderEntryQueue.begin() ;
+ HeaderEntryInfo* entry = *iter ;
+
+ removeFromCache(entry->mHandle) ;
+ mHandleEntryMap.erase(entry->mHandle) ;
+ mHeaderEntryQueue.erase(iter) ;
+ delete entry ;
+ }
+
+ writeCacheHeader() ;
+ readCacheHeader() ;
+ mNumEntries = mHandleEntryMap.size() ;
+}
+
+void LLVOCache::writeToCache(U64 handle, const LLUUID& id, const LLVOCacheEntry::vocache_entry_map_t& cache_entry_map, BOOL dirty_cache)
+{
+ llassert_always(mInitialized);
+
+ if(mReadOnly)
+ {
+ return ;
+ }
+
+ HeaderEntryInfo* entry;
+ handle_entry_map_t::iterator iter = mHandleEntryMap.find(handle) ;
+ if(iter == mHandleEntryMap.end()) //new entry
+ {
+ if(mNumEntries >= mCacheSize)
+ {
+ purgeEntries() ;
+ }
+
+ entry = new HeaderEntryInfo();
+ entry->mHandle = handle ;
+ entry->mTime = time(NULL) ;
+ entry->mIndex = mNumEntries++ ;
+ mHeaderEntryQueue.insert(entry) ;
+ mHandleEntryMap[handle] = entry ;
+ }
+ else
+ {
+ entry = iter->second ;
+ entry->mTime = time(NULL) ;
+
+ //resort
+ mHeaderEntryQueue.erase(entry) ;
+ mHeaderEntryQueue.insert(entry) ;
+ }
+
+ //update cache header
+ if(!updateEntry(entry))
+ {
+ return ; //update failed.
+ }
+
+ if(!dirty_cache)
+ {
+ return ; //nothing changed, no need to update.
+ }
+
+ //write to cache file
+ std::string filename;
+ getObjectCacheFilename(handle, filename);
+ LLAPRFile* apr_file = new LLAPRFile(filename, APR_CREATE|APR_WRITE|APR_BINARY, mLocalAPRFilePoolp);
+
+ if(!checkWrite(apr_file, (void*)id.mData, UUID_BYTES))
+ {
+ return ;
+ }
+
+ S32 num_entries = cache_entry_map.size() ;
+ if(!checkWrite(apr_file, &num_entries, sizeof(S32)))
+ {
+ return ;
+ }
+
+ for (LLVOCacheEntry::vocache_entry_map_t::const_iterator iter = cache_entry_map.begin(); iter != cache_entry_map.end(); ++iter)
+ {
+ if(!iter->second->writeToFile(apr_file))
+ {
+ //failed
+ delete apr_file ;
+ removeCache() ;
+ return ;
+ }
+ }
+
+ delete apr_file ;
+ return ;
+}
+
diff --git a/indra/newview/llvocache.h b/indra/newview/llvocache.h
index 7a4572b399..56b48ef705 100644
--- a/indra/newview/llvocache.h
+++ b/indra/newview/llvocache.h
@@ -36,11 +36,11 @@
// Cache entries
class LLVOCacheEntry;
-class LLVOCacheEntry : public LLDLinked<LLVOCacheEntry>
+class LLVOCacheEntry
{
public:
LLVOCacheEntry(U32 local_id, U32 crc, LLDataPackerBinaryBuffer &dp);
- LLVOCacheEntry(LLFILE *fp);
+ LLVOCacheEntry(LLAPRFile* apr_file);
LLVOCacheEntry();
~LLVOCacheEntry();
@@ -50,12 +50,15 @@ public:
S32 getCRCChangeCount() const { return mCRCChangeCount; }
void dump() const;
- void writeToFile(LLFILE *fp) const;
+ BOOL writeToFile(LLAPRFile* apr_file) const;
void assignCRC(U32 crc, LLDataPackerBinaryBuffer &dp);
LLDataPackerBinaryBuffer *getDP(U32 crc);
void recordHit();
void recordDupe() { mDupeCount++; }
+public:
+ typedef std::map<U32, LLVOCacheEntry*> vocache_entry_map_t;
+
protected:
U32 mLocalID;
U32 mCRC;
@@ -66,4 +69,81 @@ protected:
U8 *mBuffer;
};
+//
+//Note: LLVOCache is not thread-safe
+//
+class LLVOCache
+{
+private:
+ struct HeaderEntryInfo
+ {
+ HeaderEntryInfo() : mIndex(0), mHandle(0), mTime(0) {}
+ S32 mIndex;
+ U64 mHandle ;
+ U32 mTime ;
+ };
+
+ struct HeaderMetaInfo
+ {
+ HeaderMetaInfo() : mVersion(0){}
+
+ U32 mVersion;
+ };
+
+ struct header_entry_less
+ {
+ bool operator()(const HeaderEntryInfo* lhs, const HeaderEntryInfo* rhs) const
+ {
+ return lhs->mTime < rhs->mTime; // older entry in front of queue (set)
+ }
+ };
+ typedef std::set<HeaderEntryInfo*, header_entry_less> header_entry_queue_t;
+ typedef std::map<U64, HeaderEntryInfo*> handle_entry_map_t;
+private:
+ LLVOCache() ;
+
+public:
+ ~LLVOCache() ;
+
+ void initCache(ELLPath location, U32 size, U32 cache_version) ;
+ void removeCache(ELLPath location) ;
+
+ void readFromCache(U64 handle, const LLUUID& id, LLVOCacheEntry::vocache_entry_map_t& cache_entry_map) ;
+ void writeToCache(U64 handle, const LLUUID& id, const LLVOCacheEntry::vocache_entry_map_t& cache_entry_map, BOOL dirty_cache) ;
+
+ void setReadOnly(BOOL read_only) {mReadOnly = read_only;}
+
+private:
+ void setDirNames(ELLPath location);
+ // determine the cache filename for the region from the region handle
+ void getObjectCacheFilename(U64 handle, std::string& filename);
+ void removeFromCache(U64 handle);
+ void readCacheHeader();
+ void writeCacheHeader();
+ void clearCacheInMemory();
+ void removeCache() ;
+ void purgeEntries();
+ BOOL updateEntry(const HeaderEntryInfo* entry);
+ BOOL checkRead(LLAPRFile* apr_file, void* src, S32 n_bytes) ;
+ BOOL checkWrite(LLAPRFile* apr_file, void* src, S32 n_bytes) ;
+
+private:
+ BOOL mInitialized ;
+ BOOL mReadOnly ;
+ HeaderMetaInfo mMetaInfo;
+ U32 mCacheSize;
+ U32 mNumEntries;
+ std::string mHeaderFileName ;
+ std::string mObjectCacheDirName;
+ LLVolatileAPRPool* mLocalAPRFilePoolp ;
+ header_entry_queue_t mHeaderEntryQueue;
+ handle_entry_map_t mHandleEntryMap;
+
+ static LLVOCache* sInstance ;
+public:
+ static LLVOCache* getInstance() ;
+ static BOOL hasInstance() ;
+ static void destroyClass() ;
+};
+
#endif
diff --git a/indra/newview/llwearabletype.cpp b/indra/newview/llwearabletype.cpp
index d2e62c86ab..0d707d65bf 100644
--- a/indra/newview/llwearabletype.cpp
+++ b/indra/newview/llwearabletype.cpp
@@ -77,8 +77,8 @@ LLWearableDictionary::LLWearableDictionary()
addEntry(LLWearableType::WT_SKIRT, new WearableEntry("skirt", "New Skirt", LLAssetType::AT_CLOTHING, LLInventoryIcon::ICONNAME_CLOTHING_SKIRT));
addEntry(LLWearableType::WT_ALPHA, new WearableEntry("alpha", "New Alpha", LLAssetType::AT_CLOTHING, LLInventoryIcon::ICONNAME_CLOTHING_ALPHA));
addEntry(LLWearableType::WT_TATTOO, new WearableEntry("tattoo", "New Tattoo", LLAssetType::AT_CLOTHING, LLInventoryIcon::ICONNAME_CLOTHING_TATTOO));
- addEntry(LLWearableType::WT_INVALID, new WearableEntry("invalid", "Invalid Wearable", LLAssetType::AT_NONE, LLInventoryIcon::ICONNAME_NONE));
- addEntry(LLWearableType::WT_NONE, new WearableEntry("none", "Invalid Wearable", LLAssetType::AT_NONE, LLInventoryIcon::ICONNAME_NONE));
+ addEntry(LLWearableType::WT_INVALID, new WearableEntry("invalid", "Invalid Wearable", LLAssetType::AT_NONE, LLInventoryIcon::ICONNAME_INVALID));
+ addEntry(LLWearableType::WT_NONE, new WearableEntry("none", "Invalid Wearable", LLAssetType::AT_NONE, LLInventoryIcon::ICONNAME_INVALID));
}
// static
@@ -94,6 +94,7 @@ const std::string& LLWearableType::getTypeName(LLWearableType::EType type)
{
const LLWearableDictionary *dict = LLWearableDictionary::getInstance();
const WearableEntry *entry = dict->lookup(type);
+ if (!entry) return getTypeName(WT_INVALID);
return entry->mName;
}
@@ -102,6 +103,7 @@ const std::string& LLWearableType::getTypeDefaultNewName(LLWearableType::EType t
{
const LLWearableDictionary *dict = LLWearableDictionary::getInstance();
const WearableEntry *entry = dict->lookup(type);
+ if (!entry) return getTypeDefaultNewName(WT_INVALID);
return entry->mDefaultNewName;
}
@@ -110,6 +112,7 @@ const std::string& LLWearableType::getTypeLabel(LLWearableType::EType type)
{
const LLWearableDictionary *dict = LLWearableDictionary::getInstance();
const WearableEntry *entry = dict->lookup(type);
+ if (!entry) return getTypeLabel(WT_INVALID);
return entry->mLabel;
}
@@ -118,6 +121,7 @@ LLAssetType::EType LLWearableType::getAssetType(LLWearableType::EType type)
{
const LLWearableDictionary *dict = LLWearableDictionary::getInstance();
const WearableEntry *entry = dict->lookup(type);
+ if (!entry) return getAssetType(WT_INVALID);
return entry->mAssetType;
}
@@ -126,6 +130,7 @@ LLInventoryIcon::EIconName LLWearableType::getIconName(LLWearableType::EType typ
{
const LLWearableDictionary *dict = LLWearableDictionary::getInstance();
const WearableEntry *entry = dict->lookup(type);
+ if (!entry) return getIconName(WT_INVALID);
return entry->mIconName;
-}
+}
diff --git a/indra/newview/llworld.cpp b/indra/newview/llworld.cpp
index 2ad43ff394..5760d04a08 100644
--- a/indra/newview/llworld.cpp
+++ b/indra/newview/llworld.cpp
@@ -121,6 +121,7 @@ void LLWorld::destroyClass()
LLViewerRegion* region_to_delete = *region_it++;
removeRegion(region_to_delete->getHost());
}
+ LLVOCache::getInstance()->destroyClass() ;
LLViewerPartSim::getInstance()->destroyClass();
}
@@ -256,6 +257,8 @@ void LLWorld::removeRegion(const LLHost &host)
llwarns << "Disabling region " << regionp->getName() << " that agent is in!" << llendl;
LLAppViewer::instance()->forceDisconnect(LLTrans::getString("YouHaveBeenDisconnected"));
+
+ regionp->saveObjectCache() ; //force to save objects here in case that the object cache is about to be destroyed.
return;
}
diff --git a/indra/newview/noise.cpp b/indra/newview/noise.cpp
index 00d04f7be4..5f2c718b49 100644
--- a/indra/newview/noise.cpp
+++ b/indra/newview/noise.cpp
@@ -30,6 +30,7 @@
#include "llrand.h"
+
// static
#define B 0x100
S32 p[B + B + 2];
diff --git a/indra/newview/skins/default/textures/icons/Generic_Group_Large.png b/indra/newview/skins/default/textures/icons/Generic_Group_Large.png
index de8a39fc8a..75833eccf3 100644
--- a/indra/newview/skins/default/textures/icons/Generic_Group_Large.png
+++ b/indra/newview/skins/default/textures/icons/Generic_Group_Large.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/Generic_Person_Large.png b/indra/newview/skins/default/textures/icons/Generic_Person_Large.png
index 65b0ce8b67..532288b430 100644
--- a/indra/newview/skins/default/textures/icons/Generic_Person_Large.png
+++ b/indra/newview/skins/default/textures/icons/Generic_Person_Large.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/Inv_Invalid.png b/indra/newview/skins/default/textures/icons/Inv_Invalid.png
new file mode 100644
index 0000000000..328be104ee
--- /dev/null
+++ b/indra/newview/skins/default/textures/icons/Inv_Invalid.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/textures.xml b/indra/newview/skins/default/textures/textures.xml
index ce67cf0083..273531f9b2 100644
--- a/indra/newview/skins/default/textures/textures.xml
+++ b/indra/newview/skins/default/textures/textures.xml
@@ -229,7 +229,8 @@ with the same filename but different name
<texture name="Inv_Underpants" file_name="icons/Inv_Underpants.png" preload="false" />
<texture name="Inv_Undershirt" file_name="icons/Inv_Undershirt.png" preload="false" />
<texture name="Inv_Link" file_name="icons/Inv_Link.png" preload="false" />
-
+ <texture name="Inv_Invalid" file_name="icons/Inv_Invalid.png" preload="false" />
+
<texture name="Linden_Dollar_Alert" file_name="widgets/Linden_Dollar_Alert.png"/>
<texture name="Linden_Dollar_Background" file_name="widgets/Linden_Dollar_Background.png"/>
@@ -358,11 +359,16 @@ with the same filename but different name
<texture name="Pause_Off" file_name="icons/Pause_Off.png" preload="false" />
<texture name="Pause_Over" file_name="icons/Pause_Over.png" preload="false" />
<texture name="Pause_Press" file_name="icons/Pause_Press.png" preload="false" />
+
+ <texture name="Permission_Visible_Online" file_name="ff_visible_online_button.tga" preload="false" />
+ <texture name="Permission_Visible_Map" file_name="ff_visible_map_button.tga" preload="false" />
+ <texture name="Permission_Edit_Objects_Mine" file_name="ff_edit_mine_button.tga" preload="false" />
+ <texture name="Permission_Edit_Objects_Theirs" file_name="ff_edit_theirs_button.tga" preload="false" />
+
<texture name="Play_Off" file_name="icons/Play_Off.png" preload="false" />
<texture name="Play_Over" file_name="icons/Play_Over.png" preload="false" />
<texture name="Play_Press" file_name="icons/Play_Press.png" preload="false" />
-
<texture name="ProgressBar" file_name="widgets/ProgressBar.png" preload="true" scale.left="4" scale.top="10" scale.right="48" scale.bottom="2" />
<texture name="ProgressTrack" file_name="widgets/ProgressTrack.png" preload="true" scale.left="4" scale.top="13" scale.right="148" scale.bottom="2" />
diff --git a/indra/newview/skins/default/xui/en/floater_side_bar_tab.xml b/indra/newview/skins/default/xui/en/floater_side_bar_tab.xml
index bf0913fde7..9f14e9ae0a 100644
--- a/indra/newview/skins/default/xui/en/floater_side_bar_tab.xml
+++ b/indra/newview/skins/default/xui/en/floater_side_bar_tab.xml
@@ -2,7 +2,8 @@
<floater
can_close="false"
can_resize="true"
- min_width="150"
+ min_width="333"
+ min_height="440"
save_rect="true"
save_visibility="true"
>
diff --git a/indra/newview/skins/default/xui/en/menu_people_friends_view_sort.xml b/indra/newview/skins/default/xui/en/menu_people_friends_view_sort.xml
index 92752a0fee..22796f7b68 100644
--- a/indra/newview/skins/default/xui/en/menu_people_friends_view_sort.xml
+++ b/indra/newview/skins/default/xui/en/menu_people_friends_view_sort.xml
@@ -31,6 +31,14 @@
function="CheckControl"
parameter="FriendsListShowIcons" />
</menu_item_check>
+ <menu_item_check name="view_permissions" label="View Permissions Granted">
+ <menu_item_check.on_click
+ function="People.Friends.ViewSort.Action"
+ parameter="view_permissions" />
+ <menu_item_check.on_check
+ function="CheckControl"
+ parameter="FriendsListShowPermissions" />
+ </menu_item_check>
<menu_item_separator layout="topleft" />
<menu_item_call name="show_blocked_list" label="Show Blocked Residents &amp; Objects">
<menu_item_call.on_click function="SideTray.ShowPanel" parameter="panel_block_list_sidetray" />
diff --git a/indra/newview/skins/default/xui/en/panel_avatar_list_item.xml b/indra/newview/skins/default/xui/en/panel_avatar_list_item.xml
index f58715be56..b385654010 100644
--- a/indra/newview/skins/default/xui/en/panel_avatar_list_item.xml
+++ b/indra/newview/skins/default/xui/en/panel_avatar_list_item.xml
@@ -65,11 +65,55 @@
height="15"
layout="topleft"
left_pad="5"
- right="-72"
+ right="-164"
name="last_interaction"
text_color="LtGray_50"
value="0s"
width="35" />
+ <icon
+ height="20"
+ follows="right"
+ image_name="Permission_Visible_Online"
+ layout="topleft"
+ left_pad="3"
+ right="-141"
+ name="permission_online_icon"
+ tool_tip="This friend can see when you&apos;re online"
+ top="2"
+ width="20" />
+ <icon
+ height="20"
+ follows="right"
+ image_name="Permission_Visible_Map"
+ layout="topleft"
+ left_pad="3"
+ tool_tip="This friend can locate you on the map"
+ right="-118"
+ name="permission_map_icon"
+ top_delta="0"
+ width="20" />
+ <icon
+ height="20"
+ follows="right"
+ image_name="Permission_Edit_Objects_Mine"
+ layout="topleft"
+ left_pad="3"
+ right="-95"
+ name="permission_edit_mine_icon"
+ tool_tip="This friend can edit, delete or take your objects"
+ top_delta="0"
+ width="20" />
+ <icon
+ height="20"
+ follows="right"
+ image_name="Permission_Edit_Objects_Theirs"
+ layout="topleft"
+ left_pad="3"
+ right="-72"
+ name="permission_edit_theirs_icon"
+ tool_tip="You can edit this friend&apos;s objects"
+ top_delta="0"
+ width="20" />
<button
follows="right"
height="16"
@@ -80,7 +124,7 @@
right="-53"
name="info_btn"
tab_stop="false"
- top_delta="-2"
+ top_delta="2"
width="16" />
<button
follows="right"
diff --git a/indra/newview/skins/default/xui/en/panel_landmark_info.xml b/indra/newview/skins/default/xui/en/panel_landmark_info.xml
index c5d6aced7a..f8ae238148 100644
--- a/indra/newview/skins/default/xui/en/panel_landmark_info.xml
+++ b/indra/newview/skins/default/xui/en/panel_landmark_info.xml
@@ -57,7 +57,7 @@
translate="false"
value="Parcel_R_Dark" />
<button
- follows="top|right"
+ follows="top|left"
height="24"
image_hover_unselected="BackButton_Over"
image_pressed="BackButton_Press"
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 1cbdecab9d..883cbb30c6 100644
--- a/indra/newview/skins/default/xui/en/panel_outfit_edit.xml
+++ b/indra/newview/skins/default/xui/en/panel_outfit_edit.xml
@@ -295,7 +295,7 @@ It is calculated as border_size + 2*UIResizeBarOverlap
auto_resize="true"
default_tab_group="3"
height="450"
- min_height="73"
+ min_height="80"
name="add_wearables_panel"
width="313"
tab_group="2"
diff --git a/indra/newview/skins/default/xui/en/panel_people.xml b/indra/newview/skins/default/xui/en/panel_people.xml
index 059283ce09..ab8930c967 100644
--- a/indra/newview/skins/default/xui/en/panel_people.xml
+++ b/indra/newview/skins/default/xui/en/panel_people.xml
@@ -192,6 +192,7 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M
left="0"
multi_select="true"
name="avatars_online"
+ show_permissions_granted="true"
top="0"
width="307" />
</accordion_tab>
@@ -208,6 +209,7 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M
left="0"
multi_select="true"
name="avatars_all"
+ show_permissions_granted="true"
top="0"
width="307" />
</accordion_tab>
diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml
index cf040b10c7..72639f08ee 100644
--- a/indra/newview/skins/default/xui/en/strings.xml
+++ b/indra/newview/skins/default/xui/en/strings.xml
@@ -2019,6 +2019,7 @@ Clears (deletes) the media and all params from the given face.
<string name="Stomach">Stomach</string>
<string name="Left Pec">Left Pec</string>
<string name="Right Pec">Right Pec</string>
+ <string name="Invalid Attachment">Invalid Attachment Point</string>
<!-- Avatar age computation, see LLDateUtil::ageFromDate -->
<string name="YearsMonthsOld">[AGEYEARS] [AGEMONTHS] old</string>
@@ -2182,7 +2183,6 @@ Clears (deletes) the media and all params from the given face.
<string name="ATTACH_HUD_BOTTOM_LEFT">HUD Bottom Left</string>
<string name="ATTACH_HUD_BOTTOM">HUD Bottom</string>
<string name="ATTACH_HUD_BOTTOM_RIGHT">HUD Bottom Right</string>
- <string name="Bad attachment point">Invalid Attachment Point</string>
<!-- script editor -->
<string name="CursorPos">Line [LINE], Column [COLUMN]</string>