summaryrefslogtreecommitdiff
path: root/indra/newview
diff options
context:
space:
mode:
Diffstat (limited to 'indra/newview')
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/cofF.glsl7
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/dofCombineF.glsl2
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/postDeferredF.glsl40
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl13
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/terrainF.glsl2
-rw-r--r--indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl11
-rw-r--r--indra/newview/character/avatar_lad.xml4
-rw-r--r--indra/newview/llappviewer.cpp8
-rwxr-xr-x[-rw-r--r--]indra/newview/llavatariconctrl.cpp3
-rw-r--r--indra/newview/llfasttimerview.cpp2
-rw-r--r--indra/newview/llfloaterinspect.cpp39
-rw-r--r--indra/newview/llfloaterinspect.h4
-rw-r--r--indra/newview/lloverlaybar.cpp378
-rw-r--r--indra/newview/lloverlaybar.h95
-rw-r--r--indra/newview/llpanelnearbymedia.cpp42
-rw-r--r--indra/newview/llpanelnearbymedia.h1
-rw-r--r--indra/newview/llparticipantlist.cpp9
-rw-r--r--indra/newview/llparticipantlist.h2
-rw-r--r--indra/newview/llspatialpartition.cpp26
-rw-r--r--indra/newview/llspatialpartition.h2
-rw-r--r--indra/newview/lltexturecache.cpp2
-rw-r--r--indra/newview/lltexturecache.h2
-rw-r--r--indra/newview/lltexturefetch.cpp2
-rw-r--r--indra/newview/lltexturefetch.h2
-rw-r--r--indra/newview/llvieweraudio.cpp238
-rw-r--r--indra/newview/llvieweraudio.h47
-rw-r--r--indra/newview/llviewermedia.cpp19
-rwxr-xr-xindra/newview/llviewermessage.cpp3
-rw-r--r--indra/newview/llviewerparcelmgr.cpp56
-rw-r--r--indra/newview/llviewertexture.cpp54
-rw-r--r--indra/newview/pipeline.cpp25
-rw-r--r--indra/newview/skins/default/xui/en/menu_viewer.xml6
-rw-r--r--indra/newview/skins/default/xui/en/notifications.xml4
-rw-r--r--indra/newview/skins/default/xui/en/panel_region_covenant.xml4
-rw-r--r--indra/newview/skins/default/xui/es/panel_navigation_bar.xml2
-rw-r--r--indra/newview/skins/default/xui/fr/menu_viewer.xml4
36 files changed, 551 insertions, 609 deletions
diff --git a/indra/newview/app_settings/shaders/class1/deferred/cofF.glsl b/indra/newview/app_settings/shaders/class1/deferred/cofF.glsl
index 88fe3c3dee..e612efba61 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/cofF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/cofF.glsl
@@ -57,7 +57,7 @@ float getDepth(vec2 pos_screen)
float calc_cof(float depth)
{
- float sc = abs(depth-focal_distance)/-depth*blur_constant;
+ float sc = (depth-focal_distance)/-depth*blur_constant;
sc /= magnification;
@@ -79,9 +79,10 @@ void main()
vec4 diff = texture2DRect(diffuseRect, vary_fragcoord.xy);
float sc = calc_cof(depth);
- sc = min(abs(sc), max_cof);
+ sc = min(sc, max_cof);
+ sc = max(sc, -max_cof);
vec4 bloom = texture2D(bloomMap, vary_fragcoord.xy/screen_res);
gl_FragColor.rgb = diff.rgb + bloom.rgb;
- gl_FragColor.a = sc/max_cof;
+ gl_FragColor.a = sc/max_cof*0.5+0.5;
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/dofCombineF.glsl b/indra/newview/app_settings/shaders/class1/deferred/dofCombineF.glsl
index 21453aefaa..01e3505359 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/dofCombineF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/dofCombineF.glsl
@@ -48,7 +48,7 @@ void main()
vec4 diff = texture2DRect(lightMap, vary_fragcoord.xy);
- float a = min(diff.a * max_cof*res_scale*res_scale, 1.0);
+ float a = min(abs(diff.a*2.0-1.0) * max_cof*res_scale*res_scale, 1.0);
if (a > 0.25 && a < 0.75)
{ //help out the transition a bit
diff --git a/indra/newview/app_settings/shaders/class1/deferred/postDeferredF.glsl b/indra/newview/app_settings/shaders/class1/deferred/postDeferredF.glsl
index 4603d99c5e..18d451bf87 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/postDeferredF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/postDeferredF.glsl
@@ -42,7 +42,7 @@ void dofSample(inout vec4 diff, inout float w, float min_sc, vec2 tc)
{
vec4 s = texture2DRect(diffuseRect, tc);
- float sc = s.a*max_cof;
+ float sc = abs(s.a*2.0-1.0)*max_cof;
if (sc > min_sc) //sampled pixel is more "out of focus" than current sample radius
{
@@ -57,6 +57,20 @@ void dofSample(inout vec4 diff, inout float w, float min_sc, vec2 tc)
}
}
+void dofSampleNear(inout vec4 diff, inout float w, float min_sc, vec2 tc)
+{
+ vec4 s = texture2DRect(diffuseRect, tc);
+
+ float wg = 0.25;
+
+ // de-weight dull areas to make highlights 'pop'
+ wg += s.r+s.g+s.b;
+
+ diff += wg*s;
+
+ w += wg;
+}
+
void main()
{
vec2 tc = vary_fragcoord.xy;
@@ -66,12 +80,30 @@ void main()
{
float w = 1.0;
- float sc = diff.a*max_cof;
-
+ float sc = (diff.a*2.0-1.0)*max_cof;
+
float PI = 3.14159265358979323846264;
// sample quite uniformly spaced points within a circle, for a circular 'bokeh'
+ if (sc > 0.5)
+ {
+ while (sc > 0.5)
+ {
+ int its = int(max(1.0,(sc*3.7)));
+ for (int i=0; i<its; ++i)
+ {
+ float ang = sc+i*2*PI/its; // sc is added for rotary perturbance
+ float samp_x = sc*sin(ang);
+ float samp_y = sc*cos(ang);
+ // you could test sample coords against an interesting non-circular aperture shape here, if desired.
+ dofSampleNear(diff, w, sc, vary_fragcoord.xy + vec2(samp_x,samp_y));
+ }
+ sc -= 1.0;
+ }
+ }
+ else if (sc < -0.5)
{
+ sc = abs(sc);
while (sc > 0.5)
{
int its = int(max(1.0,(sc*3.7)));
@@ -86,7 +118,7 @@ void main()
sc -= 1.0;
}
}
-
+
diff /= w;
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl
index 60952ea38e..51110ae4df 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl
@@ -35,7 +35,6 @@ uniform sampler2DRect positionMap;
uniform sampler2DRect normalMap;
uniform sampler2DRect lightMap;
uniform sampler2DRect depthMap;
-uniform sampler2D noiseMap;
uniform samplerCube environmentMap;
uniform sampler2D lightFunc;
@@ -60,9 +59,7 @@ uniform vec4 distance_multiplier;
uniform vec4 max_y;
uniform vec4 glow;
uniform float scene_light_strength;
-uniform vec3 env_mat[3];
-//uniform mat4 shadow_matrix[3];
-//uniform vec4 shadow_clip;
+uniform mat3 env_mat;
uniform mat3 ssao_effect_mat;
uniform vec3 sun_dir;
@@ -279,8 +276,7 @@ void main()
vec3 pos = getPosition_d(tc, depth).xyz;
vec3 norm = texture2DRect(normalMap, tc).xyz;
norm = vec3((norm.xy-0.5)*2.0,norm.z); // unpack norm
- //vec3 nz = texture2D(noiseMap, vary_fragcoord.xy/128.0).xyz;
-
+
float da = max(dot(norm.xyz, sun_dir.xyz), 0.0);
vec4 diffuse = texture2DRect(diffuseRect, tc);
@@ -309,6 +305,11 @@ void main()
vec3 spec_contrib = dumbshiny * spec.rgb;
bloom = dot(spec_contrib, spec_contrib);
col += spec_contrib;
+
+ //add environmentmap
+ vec3 env_vec = env_mat * refnormpersp;
+ col = mix(col.rgb, textureCube(environmentMap, env_vec).rgb,
+ max(spec.a-diffuse.a*2.0, 0.0));
}
col = atmosLighting(col);
diff --git a/indra/newview/app_settings/shaders/class1/deferred/terrainF.glsl b/indra/newview/app_settings/shaders/class1/deferred/terrainF.glsl
index e014e53d25..5522e6c41d 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/terrainF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/terrainF.glsl
@@ -52,7 +52,7 @@ void main()
vec4 outColor = mix( mix(color3, color2, alpha2), mix(color1, color0, alpha1), alphaFinal );
gl_FragData[0] = vec4(outColor.rgb, 0.0);
- gl_FragData[1] = vec4(outColor.rgb*0.2, 0.2);
+ gl_FragData[1] = vec4(0,0,0,0);
vec3 nvn = normalize(vary_normal);
gl_FragData[2] = vec4(nvn.xy * 0.5 + 0.5, nvn.z, 0.0);
}
diff --git a/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl b/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl
index eb367d4ad6..97f3063a9e 100644
--- a/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl
+++ b/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl
@@ -34,7 +34,6 @@ uniform sampler2DRect specularRect;
uniform sampler2DRect normalMap;
uniform sampler2DRect lightMap;
uniform sampler2DRect depthMap;
-uniform sampler2D noiseMap;
uniform samplerCube environmentMap;
uniform sampler2D lightFunc;
uniform vec3 gi_quad;
@@ -60,7 +59,7 @@ uniform vec4 distance_multiplier;
uniform vec4 max_y;
uniform vec4 glow;
uniform float scene_light_strength;
-uniform vec3 env_mat[3];
+uniform mat3 env_mat;
uniform vec4 shadow_clip;
uniform mat3 ssao_effect_mat;
@@ -279,8 +278,7 @@ void main()
vec3 pos = getPosition_d(tc, depth).xyz;
vec3 norm = texture2DRect(normalMap, tc).xyz;
norm = vec3((norm.xy-0.5)*2.0,norm.z); // unpack norm
- //vec3 nz = texture2D(noiseMap, vary_fragcoord.xy/128.0).xyz;
-
+
float da = max(dot(norm.xyz, sun_dir.xyz), 0.0);
vec4 diffuse = texture2DRect(diffuseRect, tc);
@@ -315,6 +313,11 @@ void main()
vec3 spec_contrib = dumbshiny * spec.rgb;
bloom = dot(spec_contrib, spec_contrib);
col += spec_contrib;
+
+ //add environmentmap
+ vec3 env_vec = env_mat * refnormpersp;
+ col = mix(col.rgb, textureCube(environmentMap, env_vec).rgb,
+ max(spec.a-diffuse.a*2.0, 0.0));
}
col = atmosLighting(col);
diff --git a/indra/newview/character/avatar_lad.xml b/indra/newview/character/avatar_lad.xml
index 6641c80b94..99dbfcae51 100644
--- a/indra/newview/character/avatar_lad.xml
+++ b/indra/newview/character/avatar_lad.xml
@@ -395,7 +395,7 @@
<attachment_point
id="39"
- group="9"
+ group="6"
pie_slice="1"
name="Neck"
joint="mNeck"
@@ -405,7 +405,7 @@
<attachment_point
id="40"
- group="9"
+ group="6"
pie_slice="2"
name="Avatar Center"
joint="mRoot"
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index e80475f096..9455bf9875 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -1345,17 +1345,19 @@ bool LLAppViewer::mainLoop()
{
S32 work_pending = 0;
S32 io_pending = 0;
+ F32 max_time = llmin(gFrameIntervalSeconds*10.f, 1.f);
+
{
LLFastTimer ftm(FTM_TEXTURE_CACHE);
- work_pending += LLAppViewer::getTextureCache()->update(1); // unpauses the texture cache thread
+ work_pending += LLAppViewer::getTextureCache()->update(max_time); // unpauses the texture cache thread
}
{
LLFastTimer ftm(FTM_DECODE);
- work_pending += LLAppViewer::getImageDecodeThread()->update(1); // unpauses the image thread
+ work_pending += LLAppViewer::getImageDecodeThread()->update(max_time); // unpauses the image thread
}
{
LLFastTimer ftm(FTM_DECODE);
- work_pending += LLAppViewer::getTextureFetch()->update(1); // unpauses the texture fetch thread
+ work_pending += LLAppViewer::getTextureFetch()->update(max_time); // unpauses the texture fetch thread
}
{
diff --git a/indra/newview/llavatariconctrl.cpp b/indra/newview/llavatariconctrl.cpp
index 42e7decec1..b539ac38ed 100644..100755
--- a/indra/newview/llavatariconctrl.cpp
+++ b/indra/newview/llavatariconctrl.cpp
@@ -75,6 +75,9 @@ void LLAvatarIconIDCache::load ()
LLUUID icon_id;
LLDate date;
+ if (line.length()<=uuid_len*2)
+ continue; // short line, bail out to prevent substr calls throwing exception.
+
std::string avatar_id_str = line.substr(0,uuid_len);
std::string icon_id_str = line.substr(uuid_len,uuid_len);
diff --git a/indra/newview/llfasttimerview.cpp b/indra/newview/llfasttimerview.cpp
index 065dc5f4be..233038daba 100644
--- a/indra/newview/llfasttimerview.cpp
+++ b/indra/newview/llfasttimerview.cpp
@@ -105,6 +105,7 @@ void LLFastTimerView::onPause()
if (!LLFastTimer::sPauseHistory)
{
mScrollIndex = 0;
+ LLFastTimer::sResetHistory = true;
getChild<LLButton>("pause_btn")->setLabel(getString("pause"));
}
else
@@ -591,6 +592,7 @@ void LLFastTimerView::draw()
{
mAvgCountTotal = ticks;
mMaxCountTotal = ticks;
+ LLFastTimer::sResetHistory = false;
}
}
diff --git a/indra/newview/llfloaterinspect.cpp b/indra/newview/llfloaterinspect.cpp
index a09b9ea235..cece8d299c 100644
--- a/indra/newview/llfloaterinspect.cpp
+++ b/indra/newview/llfloaterinspect.cpp
@@ -37,6 +37,7 @@
#include "llselectmgr.h"
#include "lltoolcomp.h"
#include "lltoolmgr.h"
+#include "lltrans.h"
#include "llviewercontrol.h"
#include "llviewerobject.h"
#include "lluictrlfactory.h"
@@ -166,6 +167,15 @@ LLUUID LLFloaterInspect::getSelectedUUID()
return LLUUID::null;
}
+void LLFloaterInspect::onGetAvNameCallback(const LLUUID& idCreator, const LLAvatarName& av_name, void* FloaterPtr)
+{
+ if (FloaterPtr)
+ {
+ LLFloaterInspect* floater = (LLFloaterInspect*)FloaterPtr;
+ floater->dirty();
+ }
+}
+
void LLFloaterInspect::refresh()
{
LLUUID creator_id;
@@ -205,11 +215,32 @@ void LLFloaterInspect::refresh()
substitution["datetime"] = (S32) timestamp;
LLStringUtil::format (timeStr, substitution);
+ const LLUUID& idOwner = obj->mPermissions->getOwner();
+ const LLUUID& idCreator = obj->mPermissions->getCreator();
LLAvatarName av_name;
- LLAvatarNameCache::get(obj->mPermissions->getOwner(), &av_name);
- owner_name = av_name.getCompleteName();
- LLAvatarNameCache::get(obj->mPermissions->getCreator(), &av_name);
- creator_name = av_name.getCompleteName();
+
+ // Only work with the names if we actually get a result
+ // from the name cache. If not, defer setting the
+ // actual name and set a placeholder.
+ if (LLAvatarNameCache::get(idOwner, &av_name))
+ {
+ owner_name = av_name.getCompleteName();
+ }
+ else
+ {
+ owner_name = LLTrans::getString("RetrievingData");
+ LLAvatarNameCache::get(idOwner, boost::bind(&LLFloaterInspect::onGetAvNameCallback, _1, _2, this));
+ }
+
+ if (LLAvatarNameCache::get(idCreator, &av_name))
+ {
+ creator_name = av_name.getCompleteName();
+ }
+ else
+ {
+ creator_name = LLTrans::getString("RetrievingData");
+ LLAvatarNameCache::get(idCreator, boost::bind(&LLFloaterInspect::onGetAvNameCallback, _1, _2, this));
+ }
row["id"] = obj->getObject()->getID();
row["columns"][0]["column"] = "object_name";
diff --git a/indra/newview/llfloaterinspect.h b/indra/newview/llfloaterinspect.h
index d9ffdf114b..7ee83ccdb4 100644
--- a/indra/newview/llfloaterinspect.h
+++ b/indra/newview/llfloaterinspect.h
@@ -29,6 +29,7 @@
#ifndef LL_LLFLOATERINSPECT_H
#define LL_LLFLOATERINSPECT_H
+#include "llavatarname.h"
#include "llfloater.h"
//class LLTool;
@@ -53,6 +54,9 @@ public:
void onClickCreatorProfile();
void onClickOwnerProfile();
void onSelectObject();
+
+ static void onGetAvNameCallback(const LLUUID& idCreator, const LLAvatarName& av_name, void* FloaterPtr);
+
LLScrollListCtrl* mObjectList;
protected:
// protected members
diff --git a/indra/newview/lloverlaybar.cpp b/indra/newview/lloverlaybar.cpp
deleted file mode 100644
index c2bbec0470..0000000000
--- a/indra/newview/lloverlaybar.cpp
+++ /dev/null
@@ -1,378 +0,0 @@
-/**
- * @file lloverlaybar.cpp
- * @brief LLOverlayBar class implementation
- *
- * $LicenseInfo:firstyear=2002&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$
- */
-
-// Temporary buttons that appear at the bottom of the screen when you
-// are in a mode.
-
-#include "llviewerprecompiledheaders.h"
-
-#include "lloverlaybar.h"
-
-#include "llaudioengine.h"
-#include "llrender.h"
-#include "llagent.h"
-#include "llbutton.h"
-#include "llfocusmgr.h"
-#include "llimview.h"
-#include "llmediaremotectrl.h"
-#include "llparcel.h"
-#include "lltextbox.h"
-#include "llui.h"
-#include "llviewercontrol.h"
-#include "llviewertexturelist.h"
-#include "llviewerjoystick.h"
-#include "llviewermedia.h"
-#include "llviewermenu.h" // handle_reset_view()
-#include "llviewermedia.h"
-#include "llviewerparcelmedia.h"
-#include "llviewerparcelmgr.h"
-#include "lluictrlfactory.h"
-#include "llviewerwindow.h"
-#include "llvoiceclient.h"
-#include "llvoavatarself.h"
-#include "llvoiceremotectrl.h"
-#include "llmediactrl.h"
-#include "llselectmgr.h"
-
-//
-// Globals
-//
-
-LLOverlayBar *gOverlayBar = NULL;
-
-extern S32 MENU_BAR_HEIGHT;
-
-//
-// Functions
-//
-
-
-
-void* LLOverlayBar::createMediaRemote(void* userdata)
-{
- LLOverlayBar *self = (LLOverlayBar*)userdata;
- self->mMediaRemote = new LLMediaRemoteCtrl ();
- return self->mMediaRemote;
-}
-
-void* LLOverlayBar::createVoiceRemote(void* userdata)
-{
- LLOverlayBar *self = (LLOverlayBar*)userdata;
- self->mVoiceRemote = new LLVoiceRemoteCtrl();
- return self->mVoiceRemote;
-}
-
-LLOverlayBar::LLOverlayBar()
- : LLPanel(),
- mMediaRemote(NULL),
- mVoiceRemote(NULL),
- mMusicState(STOPPED)
-{
- setMouseOpaque(FALSE);
- setIsChrome(TRUE);
-
- mBuilt = false;
-
- mFactoryMap["media_remote"] = LLCallbackMap(LLOverlayBar::createMediaRemote, this);
- mFactoryMap["voice_remote"] = LLCallbackMap(LLOverlayBar::createVoiceRemote, this);
-
- LLUICtrlFactory::getInstance()->buildPanel(this, "panel_overlaybar.xml");
-}
-
-BOOL LLOverlayBar::postBuild()
-{
- childSetAction("Set Not Busy",onClickSetNotBusy,this);
- childSetAction("Mouselook",onClickMouselook,this);
- childSetAction("Stand Up",onClickStandUp,this);
- childSetAction("Flycam",onClickFlycam,this);
- childSetVisible("chat_bar", gSavedSettings.getBOOL("ChatVisible"));
-
- mVoiceRemote->expandOrCollapse();
- mMediaRemote->expandOrCollapse();
-
- setFocusRoot(TRUE);
- mBuilt = true;
-
- layoutButtons();
- return TRUE;
-}
-
-LLOverlayBar::~LLOverlayBar()
-{
- // LLView destructor cleans up children
-}
-
-// virtual
-void LLOverlayBar::reshape(S32 width, S32 height, BOOL called_from_parent)
-{
- LLView::reshape(width, height, called_from_parent);
-
- if (mBuilt)
- {
- layoutButtons();
- }
-}
-
-void LLOverlayBar::layoutButtons()
-{
- LLView* state_buttons_panel = getChildView("state_buttons");
-
- if (state_buttons_panel->getVisible())
- {
- LLViewQuery query;
- LLWidgetTypeFilter<LLButton> widget_filter;
- query.addPreFilter(LLEnabledFilter::getInstance());
- query.addPreFilter(&widget_filter);
-
- child_list_t button_list = query(state_buttons_panel);
-
- const S32 MAX_BAR_WIDTH = 600;
- S32 bar_width = llclamp(state_buttons_panel->getRect().getWidth(), 0, MAX_BAR_WIDTH);
-
- // calculate button widths
- const S32 MAX_BUTTON_WIDTH = 150;
- const S32 STATUS_BAR_PAD = 10;
- S32 segment_width = llclamp(lltrunc((F32)(bar_width) / (F32)button_list.size()), 0, MAX_BUTTON_WIDTH);
- S32 btn_width = segment_width - STATUS_BAR_PAD;
-
- // Evenly space all buttons, starting from left
- S32 left = 0;
- S32 bottom = 1;
-
- for (child_list_reverse_iter_t child_iter = button_list.rbegin();
- child_iter != button_list.rend(); ++child_iter)
- {
- LLView *view = *child_iter;
- LLRect r = view->getRect();
- r.setOriginAndSize(left, bottom, btn_width, r.getHeight());
- view->setRect(r);
- left += segment_width;
- }
- }
-}
-
-// Per-frame updates of visibility
-void LLOverlayBar::refresh()
-{
- BOOL buttons_changed = FALSE;
-
- BOOL im_received = gIMMgr->getIMReceived();
- LLButton* button = getChild<LLButton>("IM Received");
- if (button && button->getVisible() != im_received)
- {
- button->setVisible(im_received);
- sendChildToFront(button);
- moveChildToBackOfTabGroup(button);
- buttons_changed = TRUE;
- }
-
- BOOL busy = gAgent.getBusy();
- button = getChild<LLButton>("Set Not Busy");
- if (button && button->getVisible() != busy)
- {
- button->setVisible(busy);
- sendChildToFront(button);
- moveChildToBackOfTabGroup(button);
- buttons_changed = TRUE;
- }
-
- BOOL flycam = LLViewerJoystick::getInstance()->getOverrideCamera();
- button = getChild<LLButton>("Flycam");
- if (button && button->getVisible() != flycam)
- {
- button->setVisible(flycam);
- sendChildToFront(button);
- moveChildToBackOfTabGroup(button);
- buttons_changed = TRUE;
- }
-
- BOOL mouselook_grabbed;
- mouselook_grabbed = gAgent.isControlGrabbed(CONTROL_ML_LBUTTON_DOWN_INDEX)
- || gAgent.isControlGrabbed(CONTROL_ML_LBUTTON_UP_INDEX);
- button = getChild<LLButton>("Mouselook");
-
- if (button && button->getVisible() != mouselook_grabbed)
- {
- button->setVisible(mouselook_grabbed);
- sendChildToFront(button);
- moveChildToBackOfTabGroup(button);
- buttons_changed = TRUE;
- }
-
- BOOL sitting = FALSE;
- if (gAgent.getAvatarObject())
- {
- sitting = gAgent.getAvatarObject()->isSitting();
- }
- button = getChild<LLButton>("Stand Up");
-
- if (button && button->getVisible() != sitting)
- {
- button->setVisible(sitting);
- sendChildToFront(button);
- moveChildToBackOfTabGroup(button);
- buttons_changed = TRUE;
- }
-
-
- moveChildToBackOfTabGroup(mMediaRemote);
- moveChildToBackOfTabGroup(mVoiceRemote);
-
- // turn off the whole bar in mouselook
- if (gAgent.cameraMouselook())
- {
- childSetVisible("media_remote_container", FALSE);
- childSetVisible("voice_remote_container", FALSE);
- childSetVisible("state_buttons", FALSE);
- }
- else
- {
- // update "remotes"
- childSetVisible("media_remote_container", TRUE);
- childSetVisible("voice_remote_container", LLVoiceClient::getInstance()->voiceEnabled());
- childSetVisible("state_buttons", TRUE);
- }
-
- // always let user toggle into and out of chatbar
- childSetVisible("chat_bar", gSavedSettings.getBOOL("ChatVisible"));
-
- if (buttons_changed)
- {
- layoutButtons();
- }
-}
-
-//-----------------------------------------------------------------------
-// Static functions
-//-----------------------------------------------------------------------
-
-// static
-void LLOverlayBar::onClickSetNotBusy(void*)
-{
- gAgent.clearBusy();
-}
-
-
-// static
-void LLOverlayBar::onClickFlycam(void*)
-{
- LLViewerJoystick::getInstance()->toggleFlycam();
-}
-
-// static
-void LLOverlayBar::onClickResetView(void* data)
-{
- handle_reset_view();
-}
-
-//static
-void LLOverlayBar::onClickMouselook(void*)
-{
- gAgent.changeCameraToMouselook();
-}
-
-//static
-void LLOverlayBar::onClickStandUp(void*)
-{
- LLSelectMgr::getInstance()->deselectAllForStandingUp();
- gAgent.setControlFlags(AGENT_CONTROL_STAND_UP);
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// static media helpers
-// *TODO: Move this into an audio manager abstraction
-//static
-void LLOverlayBar::mediaStop(void*)
-{
- if (!gOverlayBar)
- {
- // return;
- }
- LLViewerParcelMedia::stop();
-}
-//static
-void LLOverlayBar::toggleMediaPlay(void*)
-{
- if (!gOverlayBar)
- {
- // return;
- }
-
-
- if (LLViewerParcelMedia::getStatus() == LLViewerMediaImpl::MEDIA_PAUSED)
- {
- LLViewerParcelMedia::start();
- }
- else if(LLViewerParcelMedia::getStatus() == LLViewerMediaImpl::MEDIA_PLAYING)
- {
- LLViewerParcelMedia::pause();
- }
- else
- {
- LLParcel* parcel = LLViewerParcelMgr::getInstance()->getAgentParcel();
- if (parcel)
- {
- LLViewerParcelMedia::play(parcel);
- }
- }
-}
-
-//static
-void LLOverlayBar::toggleMusicPlay(void*)
-{
- if (gAudiop->isInternetStreamPlaying() != 1)
- {
- if (gAudiop)
- {
- LLParcel* parcel = LLViewerParcelMgr::getInstance()->getAgentParcel();
- if ( parcel )
- {
- // this doesn't work properly when crossing parcel boundaries - even when the
- // stream is stopped, it doesn't return the right thing - commenting out for now.
- // if ( gAudiop->isInternetStreamPlaying() == 0 )
- {
- gAudiop->startInternetStream(parcel->getMusicURL());
- }
- }
- }
- }
- //else
- //{
- // gOverlayBar->mMusicState = PAUSED; // desired state
- // if (gAudiop)
- // {
- // gAudiop->pauseInternetStream(1);
- // }
- //}
- else
- {
- if (gAudiop)
- {
- gAudiop->stopInternetStream();
- }
- }
-}
-
diff --git a/indra/newview/lloverlaybar.h b/indra/newview/lloverlaybar.h
deleted file mode 100644
index b36f5ebb73..0000000000
--- a/indra/newview/lloverlaybar.h
+++ /dev/null
@@ -1,95 +0,0 @@
-/**
- * @file lloverlaybar.h
- * @brief LLOverlayBar class definition
- *
- * $LicenseInfo:firstyear=2002&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_LLOVERLAYBAR_H
-#define LL_LLOVERLAYBAR_H
-
-#include "llpanel.h"
-
-// "Constants" loaded from settings.xml at start time
-extern S32 STATUS_BAR_HEIGHT;
-
-class LLButton;
-class LLLineEditor;
-class LLMediaRemoteCtrl;
-class LLMessageSystem;
-class LLTextBox;
-class LLTextEditor;
-class LLUICtrl;
-class LLUUID;
-class LLFrameTimer;
-class LLStatGraph;
-class LLSlider;
-class LLVoiceRemoteCtrl;
-
-class LLOverlayBar
-: public LLPanel
-{
-public:
- LLOverlayBar();
- ~LLOverlayBar();
-
- /*virtual*/ void refresh();
- /*virtual*/ void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE);
- /*virtual*/ BOOL postBuild();
-
- void layoutButtons();
-
- // helpers for returning desired state
- BOOL musicPlaying() { return mMusicState == PLAYING; }
-
- static void onClickSetNotBusy(void* data);
- static void onClickMouselook(void* data);
- static void onClickStandUp(void* data);
- static void onClickResetView(void* data);
- static void onClickFlycam(void* data);
-
- //static media helper functions
- static void toggleMediaPlay(void*);
- static void toggleMusicPlay(void*);
- static void musicPause(void*);
- static void musicStop(void*);
- static void mediaStop(void*);
-
- static void toggleAudioVolumeFloater(void*);
-
-protected:
- static void* createMediaRemote(void* userdata);
- static void* createVoiceRemote(void* userdata);
-
- void enableMediaButtons();
-
-protected:
- LLMediaRemoteCtrl* mMediaRemote;
- LLVoiceRemoteCtrl* mVoiceRemote;
- bool mBuilt; // dialog constructed yet?
- enum { STOPPED=0, PLAYING=1, PAUSED=2 };
- S32 mMusicState;
-};
-
-extern LLOverlayBar* gOverlayBar;
-
-#endif
diff --git a/indra/newview/llpanelnearbymedia.cpp b/indra/newview/llpanelnearbymedia.cpp
index 2bbd15ae11..c01adc3c35 100644
--- a/indra/newview/llpanelnearbymedia.cpp
+++ b/indra/newview/llpanelnearbymedia.cpp
@@ -52,6 +52,7 @@
#include "llvovolume.h"
#include "llstatusbar.h"
#include "llsdutil.h"
+#include "llvieweraudio.h"
#include "llfloaterreg.h"
#include "llfloaterpreference.h" // for the gear icon
@@ -807,14 +808,26 @@ bool LLPanelNearByMedia::setDisabled(const LLUUID &row_id, bool disabled)
{
if (row_id == PARCEL_AUDIO_LIST_ITEM_UUID)
{
- if (disabled) onClickParcelAudioStop();
- else onClickParcelAudioStart();
+ if (disabled)
+ {
+ onClickParcelAudioStop();
+ }
+ else
+ {
+ onClickParcelAudioPlay();
+ }
return true;
}
else if (row_id == PARCEL_MEDIA_LIST_ITEM_UUID)
{
- if (disabled) onClickDisableParcelMedia();
- else onClickEnableParcelMedia();
+ if (disabled)
+ {
+ onClickDisableParcelMedia();
+ }
+ else
+ {
+ onClickEnableParcelMedia();
+ }
return true;
}
else {
@@ -857,24 +870,11 @@ void LLPanelNearByMedia::onClickParcelMediaPause()
LLViewerParcelMedia::pause();
}
-void LLPanelNearByMedia::onClickParcelAudioStart()
-{
- // User *explicitly* started the internet stream, so keep the stream
- // playing and updated as they cross to other parcels etc.
- mParcelAudioAutoStart = true;
-
- if (!gAudiop)
- return;
-
- gAudiop->startInternetStream(LLViewerMedia::getParcelAudioURL());
-}
-
void LLPanelNearByMedia::onClickParcelAudioPlay()
{
// User *explicitly* started the internet stream, so keep the stream
// playing and updated as they cross to other parcels etc.
mParcelAudioAutoStart = true;
-
if (!gAudiop)
return;
@@ -883,8 +883,9 @@ void LLPanelNearByMedia::onClickParcelAudioPlay()
// 'false' means unpause
gAudiop->pauseInternetStream(false);
}
- else {
- gAudiop->startInternetStream(LLViewerMedia::getParcelAudioURL());
+ else
+ {
+ LLViewerAudio::getInstance()->startInternetStreamWithAutoFade(LLViewerMedia::getParcelAudioURL());
}
}
@@ -894,11 +895,10 @@ void LLPanelNearByMedia::onClickParcelAudioStop()
// re-start audio when i.e. they move to another parcel, until
// they explicitly start it again.
mParcelAudioAutoStart = false;
-
if (!gAudiop)
return;
- gAudiop->stopInternetStream();
+ LLViewerAudio::getInstance()->stopInternetStreamWithAutoFade();
}
void LLPanelNearByMedia::onClickParcelAudioPause()
diff --git a/indra/newview/llpanelnearbymedia.h b/indra/newview/llpanelnearbymedia.h
index be4d313743..c3634de9b4 100644
--- a/indra/newview/llpanelnearbymedia.h
+++ b/indra/newview/llpanelnearbymedia.h
@@ -115,7 +115,6 @@ private:
void onClickParcelMediaPause();
void onClickParcelAudioPlay();
void onClickParcelAudioStop();
- void onClickParcelAudioStart();
void onClickParcelAudioPause();
void onCheckAutoPlay();
void onAdvancedButtonClick();
diff --git a/indra/newview/llparticipantlist.cpp b/indra/newview/llparticipantlist.cpp
index fb1153980a..5c95e805ce 100644
--- a/indra/newview/llparticipantlist.cpp
+++ b/indra/newview/llparticipantlist.cpp
@@ -468,7 +468,7 @@ void LLParticipantList::setValidateSpeakerCallback(validate_speaker_callback_t c
void LLParticipantList::updateRecentSpeakersOrder()
{
- if (E_SORT_BY_RECENT_SPEAKERS == getSortOrder())
+ if (E_SORT_BY_RECENT_SPEAKERS == getSortOrder() && !isHovered())
{
// Need to update speakers to sort list correctly
mSpeakerMgr->update(true);
@@ -477,6 +477,13 @@ void LLParticipantList::updateRecentSpeakersOrder()
}
}
+bool LLParticipantList::isHovered()
+{
+ S32 x, y;
+ LLUI::getMousePositionScreen(&x, &y);
+ return mAvatarList->calcScreenRect().pointInRect(x, y);
+}
+
bool LLParticipantList::onAddItemEvent(LLPointer<LLOldEvents::LLEvent> event, const LLSD& userdata)
{
LLUUID uu_id = event->getValue().asUUID();
diff --git a/indra/newview/llparticipantlist.h b/indra/newview/llparticipantlist.h
index e0b3d42c25..a001d29b67 100644
--- a/indra/newview/llparticipantlist.h
+++ b/indra/newview/llparticipantlist.h
@@ -251,6 +251,8 @@ private:
*/
void adjustParticipant(const LLUUID& speaker_id);
+ bool isHovered();
+
LLSpeakerMgr* mSpeakerMgr;
LLAvatarList* mAvatarList;
diff --git a/indra/newview/llspatialpartition.cpp b/indra/newview/llspatialpartition.cpp
index 3e16ccf3da..fb107a302a 100644
--- a/indra/newview/llspatialpartition.cpp
+++ b/indra/newview/llspatialpartition.cpp
@@ -28,6 +28,10 @@
#include "llspatialpartition.h"
+#include "llappviewer.h"
+#include "lltexturecache.h"
+#include "lltexturefetch.h"
+#include "llimageworker.h"
#include "llviewerwindow.h"
#include "llviewerobjectlist.h"
#include "llvovolume.h"
@@ -1221,6 +1225,7 @@ LLSpatialGroup::LLSpatialGroup(OctreeNode* node, LLSpatialPartition* part) :
for (U32 i = 0; i < LLViewerCamera::NUM_CAMERAS; i++)
{
mOcclusionQuery[i] = 0;
+ mOcclusionIssued[i] = 0;
mOcclusionState[i] = parent ? SG_STATE_INHERIT_MASK & parent->mOcclusionState[i] : 0;
mVisible[i] = 0;
}
@@ -1543,6 +1548,8 @@ BOOL LLSpatialGroup::rebound()
}
static LLFastTimer::DeclareTimer FTM_OCCLUSION_READBACK("Readback Occlusion");
+static LLFastTimer::DeclareTimer FTM_OCCLUSION_WAIT("Wait");
+
void LLSpatialGroup::checkOcclusion()
{
if (LLPipeline::sUseOcclusion > 1)
@@ -1560,6 +1567,22 @@ void LLSpatialGroup::checkOcclusion()
if (mOcclusionQuery[LLViewerCamera::sCurCameraID])
{
glGetQueryObjectuivARB(mOcclusionQuery[LLViewerCamera::sCurCameraID], GL_QUERY_RESULT_AVAILABLE_ARB, &available);
+
+ if (mOcclusionIssued[LLViewerCamera::sCurCameraID] < gFrameCount)
+ { //query was issued last frame, wait until it's available
+ S32 max_loop = 1024;
+ LLFastTimer t(FTM_OCCLUSION_WAIT);
+ while (!available && max_loop-- > 0)
+ {
+ F32 max_time = llmin(gFrameIntervalSeconds*10.f, 1.f);
+ //do some usefu work while we wait
+ LLAppViewer::getTextureCache()->update(max_time); // unpauses the texture cache thread
+ LLAppViewer::getImageDecodeThread()->update(max_time); // unpauses the image thread
+ LLAppViewer::getTextureFetch()->update(max_time); // unpauses the texture fetch thread
+
+ glGetQueryObjectuivARB(mOcclusionQuery[LLViewerCamera::sCurCameraID], GL_QUERY_RESULT_AVAILABLE_ARB, &available);
+ }
+ }
}
else
{
@@ -1679,6 +1702,9 @@ void LLSpatialGroup::doOcclusion(LLCamera* camera)
{
LLFastTimer t(FTM_PUSH_OCCLUSION_VERTS);
+ //store which frame this query was issued on
+ mOcclusionIssued[LLViewerCamera::sCurCameraID] = gFrameCount;
+
{
LLFastTimer t(FTM_OCCLUSION_BEGIN_QUERY);
glBeginQueryARB(mode, mOcclusionQuery[LLViewerCamera::sCurCameraID]);
diff --git a/indra/newview/llspatialpartition.h b/indra/newview/llspatialpartition.h
index f0c8a372ee..899547ae4d 100644
--- a/indra/newview/llspatialpartition.h
+++ b/indra/newview/llspatialpartition.h
@@ -396,6 +396,8 @@ protected:
U32 mState;
U32 mOcclusionState[LLViewerCamera::NUM_CAMERAS];
+ U32 mOcclusionIssued[LLViewerCamera::NUM_CAMERAS];
+
S32 mLODHash;
static S32 sLODSeed;
diff --git a/indra/newview/lltexturecache.cpp b/indra/newview/lltexturecache.cpp
index e7a176f4f9..8632890bbb 100644
--- a/indra/newview/lltexturecache.cpp
+++ b/indra/newview/lltexturecache.cpp
@@ -760,7 +760,7 @@ LLTextureCache::~LLTextureCache()
//////////////////////////////////////////////////////////////////////////////
//virtual
-S32 LLTextureCache::update(U32 max_time_ms)
+S32 LLTextureCache::update(F32 max_time_ms)
{
static LLFrameTimer timer ;
static const F32 MAX_TIME_INTERVAL = 300.f ; //seconds.
diff --git a/indra/newview/lltexturecache.h b/indra/newview/lltexturecache.h
index 64e3a2658c..dd0cc9b4bd 100644
--- a/indra/newview/lltexturecache.h
+++ b/indra/newview/lltexturecache.h
@@ -101,7 +101,7 @@ public:
LLTextureCache(bool threaded);
~LLTextureCache();
- /*virtual*/ S32 update(U32 max_time_ms);
+ /*virtual*/ S32 update(F32 max_time_ms);
void purgeCache(ELLPath location);
void setReadOnly(BOOL read_only) ;
diff --git a/indra/newview/lltexturefetch.cpp b/indra/newview/lltexturefetch.cpp
index 56dfb61c4f..f18aa8b4e6 100644
--- a/indra/newview/lltexturefetch.cpp
+++ b/indra/newview/lltexturefetch.cpp
@@ -2204,7 +2204,7 @@ void LLTextureFetch::commonUpdate()
// MAIN THREAD
//virtual
-S32 LLTextureFetch::update(U32 max_time_ms)
+S32 LLTextureFetch::update(F32 max_time_ms)
{
static LLCachedControl<F32> band_width(gSavedSettings,"ThrottleBandwidthKBPS");
diff --git a/indra/newview/lltexturefetch.h b/indra/newview/lltexturefetch.h
index d101da1f4b..35df7d816f 100644
--- a/indra/newview/lltexturefetch.h
+++ b/indra/newview/lltexturefetch.h
@@ -55,7 +55,7 @@ public:
class TFRequest;
- /*virtual*/ S32 update(U32 max_time_ms);
+ /*virtual*/ S32 update(F32 max_time_ms);
void shutDownTextureCacheThread() ; //called in the main thread after the TextureCacheThread shuts down.
void shutDownImageDecodeThread() ; //called in the main thread after the ImageDecodeThread shuts down.
diff --git a/indra/newview/llvieweraudio.cpp b/indra/newview/llvieweraudio.cpp
index f7fa5690d6..2447f5dea8 100644
--- a/indra/newview/llvieweraudio.cpp
+++ b/indra/newview/llvieweraudio.cpp
@@ -37,9 +37,226 @@
#include "llvoiceclient.h"
#include "llviewermedia.h"
#include "llprogressview.h"
+#include "llcallbacklist.h"
+#include "llstartup.h"
+#include "llviewerparcelmgr.h"
+#include "llparcel.h"
/////////////////////////////////////////////////////////
+LLViewerAudio::LLViewerAudio() :
+ mDone(true),
+ mFadeState(FADE_IDLE),
+ mFadeTime(),
+ mIdleListnerActive(false),
+ mForcedTeleportFade(false)
+{
+ mTeleportFailedConnection = LLViewerParcelMgr::getInstance()->
+ setTeleportFailedCallback(boost::bind(&LLViewerAudio::onTeleportFailed, this));
+}
+
+LLViewerAudio::~LLViewerAudio()
+{
+ mTeleportFailedConnection.disconnect();
+}
+
+void LLViewerAudio::registerIdleListener()
+{
+ if(mIdleListnerActive==false)
+ {
+ mIdleListnerActive = true;
+ doOnIdleRepeating(boost::bind(boost::bind(&LLViewerAudio::onIdleUpdate, this)));
+ }
+
+}
+
+void LLViewerAudio::startInternetStreamWithAutoFade(std::string streamURI)
+{
+ // Old and new stream are identical
+ if (mNextStreamURI == streamURI)
+ {
+ return;
+ }
+
+ // Record the URI we are going to be switching to
+ mNextStreamURI = streamURI;
+
+ switch (mFadeState)
+ {
+ case FADE_IDLE:
+ // If a stream is playing fade it out first
+ if (!gAudiop->getInternetStreamURL().empty())
+ {
+ // The order of these tests is important, state FADE_OUT will be processed below
+ mFadeState = FADE_OUT;
+ }
+ // Otherwise the new stream can be faded in
+ else
+ {
+ mFadeState = FADE_IN;
+ gAudiop->startInternetStream(mNextStreamURI);
+ startFading();
+ registerIdleListener();
+ break;
+ }
+
+ case FADE_OUT:
+ startFading();
+ registerIdleListener();
+ break;
+
+ case FADE_IN:
+ registerIdleListener();
+ break;
+
+ default:
+ llwarns << "Unknown fading state: " << mFadeState << llendl;
+ break;
+ }
+}
+
+// A return of false from onIdleUpdate means it will be called again next idle update.
+// A return of true means we have finished with it and the callback will be deleted.
+bool LLViewerAudio::onIdleUpdate()
+{
+ bool fadeIsFinished = false;
+
+ // There is a delay in the login sequence between when the parcel information has
+ // arrived and the music stream is started and when the audio system is called to set
+ // initial volume levels. This code extends the fade time so you hear a full fade in.
+ if ((LLStartUp::getStartupState() < STATE_STARTED))
+ {
+ stream_fade_timer.reset();
+ stream_fade_timer.setTimerExpirySec(mFadeTime);
+ }
+
+ if (mDone)
+ {
+ // This should be a rare or never occurring state.
+ if (mFadeState == FADE_IDLE)
+ {
+ deregisterIdleListener();
+ fadeIsFinished = true; // Stop calling onIdleUpdate
+ }
+
+ // we have finished the current fade operation
+ if (mFadeState == FADE_OUT)
+ {
+ // Clear URI
+ gAudiop->startInternetStream(LLStringUtil::null);
+ gAudiop->stopInternetStream();
+
+ if (!mNextStreamURI.empty())
+ {
+ mFadeState = FADE_IN;
+ gAudiop->startInternetStream(mNextStreamURI);
+ startFading();
+ }
+ else
+ {
+ mFadeState = FADE_IDLE;
+ deregisterIdleListener();
+ fadeIsFinished = true; // Stop calling onIdleUpdate
+ }
+ }
+ else if (mFadeState == FADE_IN)
+ {
+ if (mNextStreamURI != gAudiop->getInternetStreamURL())
+ {
+ mFadeState = FADE_OUT;
+ startFading();
+ }
+ else
+ {
+ mFadeState = FADE_IDLE;
+ deregisterIdleListener();
+ fadeIsFinished = true; // Stop calling onIdleUpdate
+ }
+ }
+ }
+
+ return fadeIsFinished;
+}
+
+void LLViewerAudio::stopInternetStreamWithAutoFade()
+{
+ mFadeState = FADE_IDLE;
+ mNextStreamURI = LLStringUtil::null;
+ mDone = true;
+
+ gAudiop->startInternetStream(LLStringUtil::null);
+ gAudiop->stopInternetStream();
+}
+
+void LLViewerAudio::startFading()
+{
+ const F32 AUDIO_MUSIC_FADE_IN_TIME = 3.0f;
+ const F32 AUDIO_MUSIC_FADE_OUT_TIME = 2.0f;
+ // This minimum fade time prevents divide by zero and negative times
+ const F32 AUDIO_MUSIC_MINIMUM_FADE_TIME = 0.01f;
+
+ if(mDone)
+ {
+ // The fade state here should only be one of FADE_IN or FADE_OUT, but, in case it is not,
+ // rather than check for both states assume a fade in and check for the fade out case.
+ mFadeTime = AUDIO_MUSIC_FADE_IN_TIME;
+ if (LLViewerAudio::getInstance()->getFadeState() == LLViewerAudio::FADE_OUT)
+ {
+ mFadeTime = AUDIO_MUSIC_FADE_OUT_TIME;
+ }
+
+ // Prevent invalid fade time
+ mFadeTime = llmax(mFadeTime, AUDIO_MUSIC_MINIMUM_FADE_TIME);
+
+ stream_fade_timer.reset();
+ stream_fade_timer.setTimerExpirySec(mFadeTime);
+ mDone = false;
+ }
+}
+
+F32 LLViewerAudio::getFadeVolume()
+{
+ F32 fade_volume = 1.0f;
+
+ if (stream_fade_timer.hasExpired())
+ {
+ mDone = true;
+ // If we have been fading out set volume to 0 until the next fade state occurs to prevent
+ // an audio transient.
+ if (LLViewerAudio::getInstance()->getFadeState() == LLViewerAudio::FADE_OUT)
+ {
+ fade_volume = 0.0f;
+ }
+ }
+
+ if (!mDone)
+ {
+ // Calculate how far we are into the fade time
+ fade_volume = stream_fade_timer.getElapsedTimeF32() / mFadeTime;
+
+ if (LLViewerAudio::getInstance()->getFadeState() == LLViewerAudio::FADE_OUT)
+ {
+ // If we are not fading in then we are fading out, so invert the fade
+ // direction; start loud and move towards zero volume.
+ fade_volume = 1.0f - fade_volume;
+ }
+ }
+
+ return fade_volume;
+}
+
+void LLViewerAudio::onTeleportFailed()
+{
+ if (gAudiop)
+ {
+ LLParcel* parcel = LLViewerParcelMgr::getInstance()->getAgentParcel();
+ if (parcel)
+ {
+ mNextStreamURI = parcel->getMusicURL();
+ }
+ }
+}
+
void init_audio()
{
if (!gAudiop)
@@ -142,12 +359,25 @@ void audio_update_volume(bool force_update)
// Streaming Music
if (gAudiop)
- {
+ {
+ if (progress_view_visible && !LLViewerAudio::getInstance()->getForcedTeleportFade())
+ {
+ LLViewerAudio::getInstance()->setForcedTeleportFade(true);
+ LLViewerAudio::getInstance()->startInternetStreamWithAutoFade(LLStringUtil::null);
+ LLViewerAudio::getInstance()->setNextStreamURI(LLStringUtil::null);
+ }
+
+ if (!progress_view_visible && LLViewerAudio::getInstance()->getForcedTeleportFade() == true)
+ {
+ LLViewerAudio::getInstance()->setForcedTeleportFade(false);
+ }
+
F32 music_volume = gSavedSettings.getF32("AudioLevelMusic");
BOOL music_muted = gSavedSettings.getBOOL("MuteMusic");
- music_volume = mute_volume * master_volume * music_volume;
- gAudiop->setInternetStreamGain ( music_muted || progress_view_visible ? 0.f : music_volume );
-
+ F32 fade_volume = LLViewerAudio::getInstance()->getFadeVolume();
+
+ music_volume = mute_volume * master_volume * music_volume * fade_volume;
+ gAudiop->setInternetStreamGain (music_muted ? 0.f : music_volume);
}
// Streaming Media
diff --git a/indra/newview/llvieweraudio.h b/indra/newview/llvieweraudio.h
index e5916285fb..a3da9fc6b8 100644
--- a/indra/newview/llvieweraudio.h
+++ b/indra/newview/llvieweraudio.h
@@ -27,6 +27,9 @@
#ifndef LL_VIEWERAUDIO_H
#define LL_VIEWERAUDIO_H
+#include "llframetimer.h"
+#include "llsingleton.h"
+
// comment out to turn off wind
#define kAUDIO_ENABLE_WIND
//#define kAUDIO_ENABLE_WATER 1 // comment out to turn off water
@@ -38,4 +41,48 @@ void audio_update_volume(bool force_update = true);
void audio_update_listener();
void audio_update_wind(bool force_update = true);
+class LLViewerAudio : public LLSingleton<LLViewerAudio>
+{
+public:
+
+ enum EFadeState
+ {
+ FADE_IDLE,
+ FADE_IN,
+ FADE_OUT,
+ };
+
+ LLViewerAudio();
+ virtual ~LLViewerAudio();
+
+ void startInternetStreamWithAutoFade(std::string streamURI);
+ void stopInternetStreamWithAutoFade();
+
+ bool onIdleUpdate();
+
+ EFadeState getFadeState() { return mFadeState; }
+ bool isDone() { return mDone; };
+ F32 getFadeVolume();
+ bool getForcedTeleportFade() { return mForcedTeleportFade; };
+ void setForcedTeleportFade(bool fade) { mForcedTeleportFade = fade;} ;
+ void setNextStreamURI(std::string stream) { mNextStreamURI = stream; } ;
+
+private:
+
+ bool mDone;
+ F32 mFadeTime;
+ std::string mNextStreamURI;
+ EFadeState mFadeState;
+ LLFrameTimer stream_fade_timer;
+ bool mIdleListnerActive;
+ bool mForcedTeleportFade;
+ boost::signals2::connection mTeleportFailedConnection;
+
+ void registerIdleListener();
+ void deregisterIdleListener() { mIdleListnerActive = false; };
+ void startFading();
+ void onTeleportFailed();
+
+};
+
#endif //LL_VIEWER_H
diff --git a/indra/newview/llviewermedia.cpp b/indra/newview/llviewermedia.cpp
index 98f4ce58fe..4ac1b7fa6e 100644
--- a/indra/newview/llviewermedia.cpp
+++ b/indra/newview/llviewermedia.cpp
@@ -67,7 +67,7 @@
//#include "llfirstuse.h"
#include "llviewernetwork.h"
#include "llwindow.h"
-
+#include "llvieweraudio.h"
#include "llfloaterwebcontent.h" // for handling window close requests and geometry change requests in media browser windows.
@@ -986,7 +986,7 @@ void LLViewerMedia::updateMedia(void *dummy_arg)
{
if(LLViewerMedia::isParcelAudioPlaying() && gAudiop && LLViewerMedia::hasParcelAudio())
{
- gAudiop->stopInternetStream();
+ LLViewerAudio::getInstance()->stopInternetStreamWithAutoFade();
}
}
pimpl->setPriority(new_priority);
@@ -1090,13 +1090,24 @@ void LLViewerMedia::setAllMediaEnabled(bool val)
gAudiop &&
LLViewerMedia::hasParcelAudio())
{
- gAudiop->startInternetStream(LLViewerMedia::getParcelAudioURL());
+ if (LLAudioEngine::AUDIO_PAUSED == gAudiop->isInternetStreamPlaying())
+ {
+ // 'false' means unpause
+ gAudiop->pauseInternetStream(false);
+ }
+ else
+ {
+ LLViewerAudio::getInstance()->startInternetStreamWithAutoFade(LLViewerMedia::getParcelAudioURL());
+ }
}
}
else {
// This actually unloads the impl, as opposed to "stop"ping the media
LLViewerParcelMedia::stop();
- if (gAudiop) gAudiop->stopInternetStream();
+ if (gAudiop)
+ {
+ LLViewerAudio::getInstance()->stopInternetStreamWithAutoFade();
+ }
}
}
diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp
index dca5cdd06d..ad333a71ff 100755
--- a/indra/newview/llviewermessage.cpp
+++ b/indra/newview/llviewermessage.cpp
@@ -3638,6 +3638,9 @@ void process_teleport_finish(LLMessageSystem* msg, void**)
gCacheName->setUpstream(sim);
*/
+ // Make sure we're standing
+ gAgent.standUp();
+
// now, use the circuit info to tell simulator about us!
LL_INFOS("Messaging") << "process_teleport_finish() Enabling "
<< sim_host << " with code " << msg->mOurCircuitCode << LL_ENDL;
diff --git a/indra/newview/llviewerparcelmgr.cpp b/indra/newview/llviewerparcelmgr.cpp
index d6002e7320..c64e8dd6af 100644
--- a/indra/newview/llviewerparcelmgr.cpp
+++ b/indra/newview/llviewerparcelmgr.cpp
@@ -67,6 +67,7 @@
#include "llworld.h"
#include "roles_constants.h"
#include "llweb.h"
+#include "llvieweraudio.h"
const F32 PARCEL_COLLISION_DRAW_SECS = 1.f;
@@ -1725,7 +1726,10 @@ void LLViewerParcelMgr::processParcelProperties(LLMessageSystem *msg, void **use
}
else
{
- // look for music.
+ // Check for video
+ LLViewerParcelMedia::update(parcel);
+
+ // Then check for music
if (gAudiop)
{
if (parcel)
@@ -1736,46 +1740,34 @@ void LLViewerParcelMgr::processParcelProperties(LLMessageSystem *msg, void **use
std::string music_url = music_url_raw;
LLStringUtil::trim(music_url);
- // On entering a new parcel, stop the last stream if the
- // new parcel has a different music url. (Empty URL counts
- // as different.)
- const std::string& stream_url = gAudiop->getInternetStreamURL();
-
- if (music_url.empty() || music_url != stream_url)
+ // If there is a new music URL and it's valid, play it.
+ if (music_url.size() > 12)
{
- // URL is different from one currently playing.
- gAudiop->stopInternetStream();
-
- // If there is a new music URL and it's valid, play it.
- if (music_url.size() > 12)
+ if (music_url.substr(0,7) == "http://")
{
- if (music_url.substr(0,7) == "http://")
- {
- optionally_start_music(music_url);
- }
- else
- {
- llinfos << "Stopping parcel music (invalid audio stream URL)" << llendl;
- // clears the URL
- gAudiop->startInternetStream(LLStringUtil::null);
- }
+ optionally_start_music(music_url);
}
- else if (!gAudiop->getInternetStreamURL().empty())
+ else
{
- llinfos << "Stopping parcel music (parcel stream URL is empty)" << llendl;
- gAudiop->startInternetStream(LLStringUtil::null);
+ llinfos << "Stopping parcel music (invalid audio stream URL)" << llendl;
+ // clears the URL
+ // null value causes fade out
+ LLViewerAudio::getInstance()->startInternetStreamWithAutoFade(LLStringUtil::null);
}
}
+ else if (!gAudiop->getInternetStreamURL().empty())
+ {
+ llinfos << "Stopping parcel music (parcel stream URL is empty)" << llendl;
+ // null value causes fade out
+ LLViewerAudio::getInstance()->startInternetStreamWithAutoFade(LLStringUtil::null);
+ }
}
else
{
// Public land has no music
- gAudiop->stopInternetStream();
+ LLViewerAudio::getInstance()->stopInternetStreamWithAutoFade();
}
}//if gAudiop
-
- // now check for video
- LLViewerParcelMedia::update( parcel );
};
}
@@ -1794,7 +1786,11 @@ void optionally_start_music(const std::string& music_url)
gSavedSettings.getBOOL("MediaTentativeAutoPlay")))
{
llinfos << "Starting parcel music " << music_url << llendl;
- gAudiop->startInternetStream(music_url);
+ LLViewerAudio::getInstance()->startInternetStreamWithAutoFade(music_url);
+ }
+ else
+ {
+ LLViewerAudio::getInstance()->startInternetStreamWithAutoFade(LLStringUtil::null);
}
}
}
diff --git a/indra/newview/llviewertexture.cpp b/indra/newview/llviewertexture.cpp
index f4bbc2b067..61236edc86 100644
--- a/indra/newview/llviewertexture.cpp
+++ b/indra/newview/llviewertexture.cpp
@@ -417,11 +417,24 @@ const S32 min_non_tex_system_mem = (128<<20); // 128 MB
F32 texmem_lower_bound_scale = 0.85f;
F32 texmem_middle_bound_scale = 0.925f;
+static LLFastTimer::DeclareTimer FTM_TEXTURE_MEMORY_CHECK("Memory Check");
+
//static
bool LLViewerTexture::isMemoryForTextureLow()
{
- const static S32 MIN_FREE_TEXTURE_MEMORY = 5 ; //MB
- const static S32 MIN_FREE_MAIN_MEMORy = 100 ; //MB
+ const F32 WAIT_TIME = 1.0f ; //second
+ static LLFrameTimer timer ;
+
+ if(timer.getElapsedTimeF32() < WAIT_TIME) //call this once per second.
+ {
+ return false;
+ }
+ timer.reset() ;
+
+ LLFastTimer t(FTM_TEXTURE_MEMORY_CHECK);
+
+ const S32 MIN_FREE_TEXTURE_MEMORY = 5 ; //MB
+ const S32 MIN_FREE_MAIN_MEMORy = 100 ; //MB
bool low_mem = false ;
if (gGLManager.mHasATIMemInfo)
@@ -433,6 +446,15 @@ bool LLViewerTexture::isMemoryForTextureLow()
{
low_mem = true ;
}
+
+ if(!low_mem) //check main memory, only works for windows.
+ {
+ LLMemory::updateMemoryInfo() ;
+ if(LLMemory::getAvailableMemKB() / 1024 < MIN_FREE_MAIN_MEMORy)
+ {
+ low_mem = true ;
+ }
+ }
}
#if 0 //ignore nVidia cards
else if (gGLManager.mHasNVXMemInfo)
@@ -445,20 +467,14 @@ bool LLViewerTexture::isMemoryForTextureLow()
low_mem = true ;
}
}
-#endif
-
- if(!low_mem) //check main memory, only works for windows.
- {
- LLMemory::updateMemoryInfo() ;
- if(LLMemory::getAvailableMemKB() / 1024 < MIN_FREE_MAIN_MEMORy)
- {
- low_mem = true ;
- }
- }
+#endif
return low_mem ;
}
+static LLFastTimer::DeclareTimer FTM_TEXTURE_UPDATE_MEDIA("Media");
+static LLFastTimer::DeclareTimer FTM_TEXTURE_UPDATE_TEST("Test");
+
//static
void LLViewerTexture::updateClass(const F32 velocity, const F32 angular_velocity)
{
@@ -467,9 +483,14 @@ void LLViewerTexture::updateClass(const F32 velocity, const F32 angular_velocity
LLTexturePipelineTester* tester = (LLTexturePipelineTester*)LLMetricPerformanceTesterBasic::getTester(sTesterName);
if (tester)
{
+ LLFastTimer t(FTM_TEXTURE_UPDATE_TEST);
tester->update() ;
}
- LLViewerMediaTexture::updateClass() ;
+
+ {
+ LLFastTimer t(FTM_TEXTURE_UPDATE_MEDIA);
+ LLViewerMediaTexture::updateClass() ;
+ }
sBoundTextureMemoryInBytes = LLImageGL::sBoundTextureMemoryInBytes;//in bytes
sTotalTextureMemoryInBytes = LLImageGL::sGlobalTextureMemoryInBytes;//in bytes
@@ -3142,8 +3163,13 @@ void LLViewerLODTexture::processTextureStats()
S32 current_discard = getDiscardLevel();
if (sDesiredDiscardBias > 0.0f && mBoostLevel < LLViewerTexture::BOOST_SCULPTED && current_discard >= 0)
{
+ if(desired_discard_bias_max <= sDesiredDiscardBias && !mForceToSaveRawImage)
+ {
+ //needs to release texture memory urgently
+ scaleDown() ;
+ }
// Limit the amount of GL memory bound each frame
- if ( BYTES_TO_MEGA_BYTES(sBoundTextureMemoryInBytes) > sMaxBoundTextureMemInMegaBytes * texmem_middle_bound_scale &&
+ else if ( BYTES_TO_MEGA_BYTES(sBoundTextureMemoryInBytes) > sMaxBoundTextureMemInMegaBytes * texmem_middle_bound_scale &&
(!getBoundRecently() || mDesiredDiscardLevel >= mCachedRawDiscardLevel))
{
scaleDown() ;
diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index 12bec90881..00acc3e511 100644
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -6333,17 +6333,10 @@ void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield)
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
}
- U32 res_mod = RenderResolutionDivisor;
-
LLVector2 tc1(0,0);
LLVector2 tc2((F32) mScreen.getWidth()*2,
(F32) mScreen.getHeight()*2);
- if (res_mod > 1)
- {
- tc2 /= (F32) res_mod;
- }
-
LLFastTimer ftm(FTM_RENDER_BLOOM);
gGL.color4f(1,1,1,1);
LLGLDepthTest depth(GL_FALSE);
@@ -6807,7 +6800,13 @@ void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield)
mFXAABuffer.bindTexture(0, channel);
gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_BILINEAR);
}
-
+
+ gGLViewport[0] = gViewerWindow->getWorldViewRectRaw().mLeft;
+ gGLViewport[1] = gViewerWindow->getWorldViewRectRaw().mBottom;
+ gGLViewport[2] = gViewerWindow->getWorldViewRectRaw().getWidth();
+ gGLViewport[3] = gViewerWindow->getWorldViewRectRaw().getHeight();
+ glViewport(gGLViewport[0], gGLViewport[1], gGLViewport[2], gGLViewport[3]);
+
F32 scale_x = (F32) width/mFXAABuffer.getWidth();
F32 scale_y = (F32) height/mFXAABuffer.getHeight();
shader->uniform2f(LLShaderMgr::FXAA_TC_SCALE, scale_x, scale_y);
@@ -6827,11 +6826,6 @@ void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield)
}
else
{
- if (res_mod > 1)
- {
- tc2 /= (F32) res_mod;
- }
-
U32 mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_TEXCOORD1;
LLPointer<LLVertexBuffer> buff = new LLVertexBuffer(mask, 0);
buff->allocateBuffer(3,0,TRUE);
@@ -7108,13 +7102,12 @@ void LLPipeline::bindDeferredShader(LLGLSLShader& shader, U32 light_index, U32 n
cube_map->enable(channel);
cube_map->bind();
F32* m = gGLModelView;
-
-
+
F32 mat[] = { m[0], m[1], m[2],
m[4], m[5], m[6],
m[8], m[9], m[10] };
- shader.uniform3fv(LLShaderMgr::DEFERRED_ENV_MAT, 3, mat);
+ shader.uniformMatrix3fv(LLShaderMgr::DEFERRED_ENV_MAT, 1, TRUE, mat);
}
}
diff --git a/indra/newview/skins/default/xui/en/menu_viewer.xml b/indra/newview/skins/default/xui/en/menu_viewer.xml
index c8c1922bf6..3a581e7e6e 100644
--- a/indra/newview/skins/default/xui/en/menu_viewer.xml
+++ b/indra/newview/skins/default/xui/en/menu_viewer.xml
@@ -1723,12 +1723,6 @@
function="Tools.EnableReleaseKeys"
parameter="" />
</menu_item_call>
- <menu_item_call
- label="Set UI Size to Default"
- name="Set UI Size to Default">
- <menu_item_call.on_click
- function="View.DefaultUISize" />
- </menu_item_call>
<!-- This second, alternative shortcut for Show Advanced Menu is for backward compatibility. The main shortcut has been changed so it's Linux-friendly, where the old shortcut is typically eaten by the window manager. -->
<menu_item_check
label="Show Advanced Menu - legacy shortcut"
diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml
index e4458f33b1..4e4eea0354 100644
--- a/indra/newview/skins/default/xui/en/notifications.xml
+++ b/indra/newview/skins/default/xui/en/notifications.xml
@@ -6939,7 +6939,7 @@ With the following Residents:
<usetemplate
name="okcancelbuttons"
notext="Cancel"
- yestext="Ok"/>
+ yestext="OK"/>
</notification>
<notification
@@ -7135,7 +7135,7 @@ Mute everyone?
<usetemplate
ignoretext="Confirm before I mute all participants in a group call"
name="okcancelignore"
- yestext="Ok"
+ yestext="OK"
notext="Cancel">
<unique/>
</usetemplate>
diff --git a/indra/newview/skins/default/xui/en/panel_region_covenant.xml b/indra/newview/skins/default/xui/en/panel_region_covenant.xml
index df16f6fd37..112f12500d 100644
--- a/indra/newview/skins/default/xui/en/panel_region_covenant.xml
+++ b/indra/newview/skins/default/xui/en/panel_region_covenant.xml
@@ -57,7 +57,7 @@
mouse_opaque="false"
name="estate_name_text"
top_delta="0"
- width="150">
+ width="350">
mainland
</text>
<text
@@ -79,7 +79,7 @@
mouse_opaque="false"
name="estate_owner_text"
top_delta="0"
- width="150">
+ width="350">
(none)
</text>
<text
diff --git a/indra/newview/skins/default/xui/es/panel_navigation_bar.xml b/indra/newview/skins/default/xui/es/panel_navigation_bar.xml
index 1b7f5d5a9f..d36c6283bc 100644
--- a/indra/newview/skins/default/xui/es/panel_navigation_bar.xml
+++ b/indra/newview/skins/default/xui/es/panel_navigation_bar.xml
@@ -3,7 +3,7 @@
<layout_stack name="nvp_stack">
<layout_panel name="navigation_layout_panel">
<panel name="navigation_panel">
- <pull_button name="back_btn" tool_tip="Volver a lo localización anterior"/>
+ <pull_button name="back_btn" tool_tip="Volver a la localización anterior"/>
<pull_button name="forward_btn" tool_tip="Ir una localización adelante"/>
<button name="home_btn" tool_tip="Teleportar a mi Base"/>
<location_input label="Lugar" name="location_combo"/>
diff --git a/indra/newview/skins/default/xui/fr/menu_viewer.xml b/indra/newview/skins/default/xui/fr/menu_viewer.xml
index 64cd463070..78f973a61f 100644
--- a/indra/newview/skins/default/xui/fr/menu_viewer.xml
+++ b/indra/newview/skins/default/xui/fr/menu_viewer.xml
@@ -319,7 +319,7 @@
<menu_item_check label="Pauser l&apos;avatar" name="AgentPause"/>
<menu_item_call label="Activer le journal des messages" name="Enable Message Log"/>
<menu_item_call label="Désactiver le journal des messages" name="Disable Message Log"/>
- <menu_item_check label="Velocity Interpolate Objects" name="Velocity Interpolate Objects"/>
+ <menu_item_check label="Objets d&apos;interpolation de vitesse" name="Velocity Interpolate Objects"/>
<menu_item_check label="Interpolation ping des positions des objets" name="Ping Interpolate Object Positions"/>
<menu_item_call label="Abandonner un paquet" name="Drop a Packet"/>
</menu>
@@ -336,7 +336,7 @@
<menu_item_check label="Ignorer les paramètres du soleil de la sim" name="Sim Sun Override"/>
<menu_item_check label="Balise animée" name="Cheesy Beacon"/>
<menu_item_check label="Météo fixe" name="Fixed Weather"/>
- <menu_item_call label="Dump Region Object Cache" name="Dump Region Object Cache"/>
+ <menu_item_call label="Vidage de cache d&apos;objet de la région" name="Dump Region Object Cache"/>
</menu>
<menu label="Interface" name="UI">
<menu_item_call label="Test du navigateur de médias" name="Web Browser Test"/>