summaryrefslogtreecommitdiff
path: root/indra/newview
diff options
context:
space:
mode:
authorBrad Linden <brad@lindenlab.com>2023-02-02 12:11:40 -0800
committerBrad Linden <brad@lindenlab.com>2023-02-02 12:11:40 -0800
commit5fabfa50d7135d29c0cb8a553006cf9038f9baae (patch)
tree1d0f21551bd443d4e1ba187480c082d612dfaac5 /indra/newview
parent627e3d51c61778e07e350689ce68ede24afe61ab (diff)
parent8d21d29bd7fa038db632ff90fb0e1207d0713ca2 (diff)
Merge remote-tracking branch 'origin/main' into DRTVWR-559
Diffstat (limited to 'indra/newview')
-rw-r--r--indra/newview/CMakeLists.txt6
-rw-r--r--indra/newview/app_settings/settings.xml11
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/skyF.glsl50
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/skyV.glsl35
-rw-r--r--indra/newview/app_settings/shaders/class2/deferred/skyF.glsl199
-rw-r--r--indra/newview/app_settings/shaders/class2/deferred/skyV.glsl42
-rw-r--r--indra/newview/llaccountingcostmanager.cpp6
-rw-r--r--indra/newview/llappdelegate-objc.mm15
-rw-r--r--indra/newview/llappearancemgr.cpp2
-rw-r--r--indra/newview/llappviewer.cpp8
-rw-r--r--indra/newview/llavatarrenderinfoaccountant.cpp3
-rw-r--r--indra/newview/llbuycurrencyhtml.cpp2
-rw-r--r--indra/newview/llcallingcard.cpp14
-rw-r--r--indra/newview/llchathistory.cpp89
-rw-r--r--indra/newview/llchiclet.cpp66
-rw-r--r--indra/newview/llchiclet.h6
-rw-r--r--indra/newview/llcommandhandler.cpp82
-rw-r--r--indra/newview/llcommandhandler.h10
-rw-r--r--indra/newview/llenvironment.cpp3
-rw-r--r--indra/newview/llfilepicker.cpp10
-rw-r--r--indra/newview/llfilepicker.h2
-rw-r--r--indra/newview/llfilepicker_mac.h4
-rw-r--r--indra/newview/llfilepicker_mac.mm157
-rw-r--r--indra/newview/llfloater360capture.cpp12
-rw-r--r--indra/newview/llfloateravatar.cpp14
-rw-r--r--indra/newview/llfloateravatar.h3
-rw-r--r--indra/newview/llfloaterbump.cpp35
-rw-r--r--indra/newview/llfloaterbump.h2
-rw-r--r--indra/newview/llfloatercreatelandmark.cpp1
-rw-r--r--indra/newview/llfloaterimcontainer.cpp1
-rw-r--r--indra/newview/llfloaterimsessiontab.cpp1
-rw-r--r--indra/newview/llfloatermodelpreview.cpp2
-rw-r--r--indra/newview/llfloateropenobject.cpp14
-rw-r--r--indra/newview/llfloateropenobject.h2
-rw-r--r--indra/newview/llfloateroutfitphotopreview.cpp1
-rw-r--r--indra/newview/llfloaterpathfindinglinksets.cpp19
-rw-r--r--indra/newview/llfloaterpathfindinglinksets.h5
-rw-r--r--indra/newview/llfloaterscriptlimits.cpp1
-rw-r--r--indra/newview/llfloatersearch.cpp2
-rw-r--r--indra/newview/llfloatersettingsdebug.cpp283
-rw-r--r--indra/newview/llfloatersettingsdebug.h21
-rwxr-xr-xindra/newview/llfloaterworldmap.cpp4
-rw-r--r--indra/newview/llgroupactions.cpp27
-rw-r--r--indra/newview/llimprocessing.cpp2
-rw-r--r--indra/newview/llimview.cpp6
-rw-r--r--indra/newview/llinventorybridge.cpp13
-rw-r--r--indra/newview/llinventoryfilter.cpp1
-rw-r--r--indra/newview/llinventoryfunctions.cpp3
-rw-r--r--indra/newview/llinventorylistitem.h2
-rw-r--r--indra/newview/llinventorymodel.cpp3
-rw-r--r--indra/newview/llinventorypanel.cpp7
-rw-r--r--indra/newview/llkeyconflict.cpp8
-rw-r--r--indra/newview/lllistcontextmenu.cpp10
-rw-r--r--indra/newview/llmaterialmgr.cpp20
-rw-r--r--indra/newview/llmediactrl.cpp50
-rw-r--r--indra/newview/llmediactrl.h4
-rw-r--r--indra/newview/llmeshrepository.cpp520
-rw-r--r--indra/newview/llmeshrepository.h33
-rw-r--r--indra/newview/llmodelpreview.cpp22
-rw-r--r--[-rwxr-xr-x]indra/newview/llnetmap.cpp58
-rw-r--r--indra/newview/llnetmap.h2
-rw-r--r--indra/newview/llnotificationlistitem.cpp4
-rw-r--r--indra/newview/lloutfitgallery.cpp2
-rw-r--r--indra/newview/lloutfitslist.cpp3
-rw-r--r--indra/newview/llpaneleditwearable.cpp2
-rw-r--r--indra/newview/llpanelexperiencelog.cpp2
-rw-r--r--indra/newview/llpanellandmedia.cpp1
-rw-r--r--indra/newview/llpanelmaininventory.cpp12
-rw-r--r--indra/newview/llpanelobject.cpp2
-rw-r--r--indra/newview/llpanelobjectinventory.cpp22
-rw-r--r--indra/newview/llpanelobjectinventory.h11
-rw-r--r--indra/newview/llpanelplaces.cpp1
-rw-r--r--indra/newview/llpanelprofile.cpp27
-rw-r--r--indra/newview/llpanelprofileclassifieds.cpp24
-rw-r--r--indra/newview/llpanelprofilepicks.cpp24
-rw-r--r--indra/newview/llpreviewnotecard.cpp3
-rw-r--r--indra/newview/llscenemonitor.cpp2
-rw-r--r--indra/newview/llscenemonitor.h2
-rw-r--r--indra/newview/llscriptfloater.cpp7
-rw-r--r--indra/newview/llspeakers.cpp1
-rw-r--r--indra/newview/llspeakingindicatormanager.cpp20
-rw-r--r--indra/newview/llstartup.cpp2
-rw-r--r--indra/newview/lltoastnotifypanel.cpp1
-rw-r--r--indra/newview/lltoolbarview.cpp17
-rw-r--r--indra/newview/llurldispatcher.cpp2
-rw-r--r--indra/newview/llviewerfloaterreg.cpp98
-rw-r--r--indra/newview/llviewerinput.cpp10
-rw-r--r--indra/newview/llviewerinventory.cpp2
-rw-r--r--indra/newview/llviewermenu.cpp22
-rw-r--r--indra/newview/llviewerobject.cpp27
-rw-r--r--indra/newview/llviewerpartsource.cpp2
-rw-r--r--indra/newview/llviewertexteditor.cpp1
-rw-r--r--indra/newview/llviewerwindow.cpp54
-rw-r--r--indra/newview/llvoiceclient.cpp15
-rw-r--r--indra/newview/llvoiceclient.h2
-rw-r--r--indra/newview/llvoicevivox.cpp5
-rw-r--r--indra/newview/llvoicevivox.h2
-rw-r--r--indra/newview/llvosky.cpp4
-rw-r--r--indra/newview/llvovolume.cpp44
-rw-r--r--indra/newview/llvovolume.h4
-rw-r--r--indra/newview/llwearableitemslist.cpp101
-rw-r--r--indra/newview/llwearableitemslist.h23
-rw-r--r--indra/newview/llworld.cpp4
-rw-r--r--indra/newview/skins/default/textures/icons/add_icon.pngbin0 -> 3386 bytes
-rw-r--r--indra/newview/skins/default/textures/icons/remove_icon.pngbin0 -> 3446 bytes
-rw-r--r--indra/newview/skins/default/textures/textures.xml3
-rw-r--r--indra/newview/skins/default/xui/en/floater_object_weights.xml21
-rw-r--r--indra/newview/skins/default/xui/en/floater_openobject.xml52
-rw-r--r--indra/newview/skins/default/xui/en/floater_pathfinding_linksets.xml49
-rw-r--r--indra/newview/skins/default/xui/en/floater_settings_debug.xml134
-rw-r--r--indra/newview/skins/default/xui/en/outfit_accordion_tab.xml1
-rw-r--r--indra/newview/skins/default/xui/en/panel_outfits_wearing.xml1
-rw-r--r--indra/newview/skins/default/xui/en/panel_preferences_privacy.xml2
-rw-r--r--indra/newview/skins/default/xui/en/panel_profile_secondlife.xml6
-rw-r--r--indra/newview/skins/default/xui/en/strings.xml2
-rw-r--r--indra/newview/skins/default/xui/en/widgets/filter_editor.xml2
-rw-r--r--indra/newview/skins/default/xui/en/widgets/search_editor.xml2
-rw-r--r--indra/newview/skins/default/xui/en/widgets/wearable_outfit_list_item.xml64
-rwxr-xr-xindra/newview/viewer_manifest.py4
119 files changed, 1825 insertions, 1168 deletions
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index 4dc8eaedaf..085bac0042 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -1844,9 +1844,9 @@ if (WINDOWS)
${SHARED_LIB_STAGING_DIR}/Release/libcollada14dom22.dll
${SHARED_LIB_STAGING_DIR}/RelWithDebInfo/libcollada14dom22.dll
${SHARED_LIB_STAGING_DIR}/Debug/libcollada14dom22-d.dll
- ${SHARED_LIB_STAGING_DIR}/Release/openjpeg.dll
- ${SHARED_LIB_STAGING_DIR}/RelWithDebInfo/openjpeg.dll
- ${SHARED_LIB_STAGING_DIR}/Debug/openjpegd.dll
+ ${SHARED_LIB_STAGING_DIR}/Release/openjp2.dll
+ ${SHARED_LIB_STAGING_DIR}/RelWithDebInfo/openjp2.dll
+ ${SHARED_LIB_STAGING_DIR}/Debug/openjp2.dll
${SHARED_LIB_STAGING_DIR}/Release/libhunspell.dll
${SHARED_LIB_STAGING_DIR}/RelWithDebInfo/libhunspell.dll
${SHARED_LIB_STAGING_DIR}/Debug/libhunspell.dll
diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index 333d764866..4a12d239ed 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -16978,5 +16978,16 @@
<key>Value</key>
<integer>0</integer>
</map>
+ <key>DebugSettingsHideDefault</key>
+ <map>
+ <key>Comment</key>
+ <string>Show non-default settings only in Debug Settings list</string>
+ <key>Persist</key>
+ <integer>0</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>0</integer>
+ </map>
</map>
</llsd>
diff --git a/indra/newview/app_settings/shaders/class1/deferred/skyF.glsl b/indra/newview/app_settings/shaders/class1/deferred/skyF.glsl
index adc2db60b6..849e1c4893 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/skyF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/skyF.glsl
@@ -25,6 +25,17 @@
/*[EXTRA_CODE_HERE]*/
+// Inputs
+VARYING vec4 vary_HazeColor;
+VARYING float vary_LightNormPosDot;
+
+uniform sampler2D rainbow_map;
+uniform sampler2D halo_map;
+
+uniform float moisture_level;
+uniform float droplet_radius;
+uniform float ice_level;
+
#ifdef DEFINE_GL_FRAGCOLOR
out vec4 frag_data[3];
#else
@@ -37,9 +48,34 @@ out vec4 frag_data[3];
VARYING vec3 vary_HazeColor;
+vec3 rainbow(float d)
+{
+ // 'Interesting' values of d are -0.75 .. -0.825, i.e. when view vec nearly opposite of sun vec
+ // Rainbox tex is mapped with REPEAT, so -.75 as tex coord is same as 0.25. -0.825 -> 0.175. etc.
+ // SL-13629
+ // Unfortunately the texture is inverted, so we need to invert the y coord, but keep the 'interesting'
+ // part within the same 0.175..0.250 range, i.e. d = (1 - d) - 1.575
+ d = clamp(-0.575 - d, 0.0, 1.0);
+
+ // With the colors in the lower 1/4 of the texture, inverting the coords leaves most of it inaccessible.
+ // So, we can stretch the texcoord above the colors (ie > 0.25) to fill the entire remaining coordinate
+ // space. This improves gradation, reduces banding within the rainbow interior. (1-0.25) / (0.425/0.25) = 4.2857
+ float interior_coord = max(0.0, d - 0.25) * 4.2857;
+ d = clamp(d, 0.0, 0.25) + interior_coord;
+
+ float rad = (droplet_radius - 5.0f) / 1024.0f;
+ return pow(texture2D(rainbow_map, vec2(rad+0.5, d)).rgb, vec3(1.8)) * moisture_level;
+}
+
+vec3 halo22(float d)
+{
+ d = clamp(d, 0.1, 1.0);
+ float v = sqrt(clamp(1 - (d * d), 0, 1));
+ return texture2D(halo_map, vec2(0, v)).rgb * ice_level;
+}
+
/// Soft clips the light with a gamma correction
vec3 scaleSoftClip(vec3 light);
-vec3 srgb_to_linear(vec3 c);
void main()
{
@@ -48,14 +84,18 @@ void main()
// the fragment) if the sky wouldn't show up because the clouds
// are fully opaque.
- vec3 color;
- color = vary_HazeColor;
+ vec3 color = vary_HazeColor;
+ float rel_pos_lightnorm = vary_LightNormPosDot;
+ float optic_d = rel_pos_lightnorm;
+ vec3 halo_22 = halo22(optic_d);
+ color.rgb += rainbow(optic_d);
+ color.rgb += halo_22;
color.rgb *= 2.;
color.rgb = scaleSoftClip(color.rgb);
- /// Gamma correct for WL (soft clip effect).
- frag_data[0] = vec4(color.rgb, 0.0);
+ // Gamma correct for WL (soft clip effect).
+ frag_data[0] = vec4(color.rgb, 1.0);
frag_data[1] = vec4(0.0,0.0,0.0,0.0);
frag_data[2] = vec4(0.0,0.0,0.0,GBUFFER_FLAG_SKIP_ATMOS); //1.0 in norm.w masks off fog
diff --git a/indra/newview/app_settings/shaders/class1/deferred/skyV.glsl b/indra/newview/app_settings/shaders/class1/deferred/skyV.glsl
index ff53646fd4..3b24311f2b 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/skyV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/skyV.glsl
@@ -33,6 +33,7 @@ ATTRIBUTE vec3 position;
// Output parameters
VARYING vec3 vary_HazeColor;
+VARYING float vary_LightNormPosDot;
// Inputs
uniform vec3 camPosLocal;
@@ -70,27 +71,29 @@ void main()
vec3 rel_pos = position.xyz - camPosLocal.xyz + vec3(0, 50, 0);
// Adj position vector to clamp altitude
- if (rel_pos.y > 0)
+ if (rel_pos.y > 0.)
{
rel_pos *= (max_y / rel_pos.y);
}
- if (rel_pos.y < 0)
+ if (rel_pos.y < 0.)
{
rel_pos *= (-32000. / rel_pos.y);
}
- // Can normalize then
- vec3 rel_pos_norm = normalize(rel_pos);
+ // Normalized
+ vec3 rel_pos_norm = normalize(rel_pos);
+ float rel_pos_len = length(rel_pos);
- float rel_pos_len = length(rel_pos);
+ // Grab this value and pass to frag shader for rainbows
+ float rel_pos_lightnorm_dot = dot(rel_pos_norm, lightnorm.xyz);
+ vary_LightNormPosDot = rel_pos_lightnorm_dot;
// Initialize temp variables
vec3 sunlight = (sun_up_factor == 1) ? sunlight_color : moonlight_color;
- vec3 light_atten;
// Sunlight attenuation effect (hue and brightness) due to atmosphere
// this is used later for sunlight modulation at various altitudes
- light_atten = (blue_density + vec3(haze_density * 0.25)) * (density_multiplier * max_y);
+ vec3 light_atten = (blue_density + vec3(haze_density * 0.25)) * (density_multiplier * max_y);
// Calculate relative weights
vec3 combined_haze = abs(blue_density) + vec4(abs(haze_density));
@@ -110,7 +113,7 @@ void main()
combined_haze = exp(-combined_haze * density_dist);
// Compute haze glow
- float haze_glow = 1.0 - dot(rel_pos_norm, lightnorm.xyz);
+ float haze_glow = 1.0 - rel_pos_lightnorm_dot;
// haze_glow is 0 at the sun and increases away from sun
haze_glow = max(haze_glow, .001);
// Set a minimum "angle" (smaller glow.y allows tighter, brighter hotspot)
@@ -121,30 +124,30 @@ void main()
// Add "minimum anti-solar illumination"
// For sun, add to glow. For moon, remove glow entirely. SL-13768
- haze_glow = (sun_moon_glow_factor < 1.0) ? 0.0 : (haze_glow + 0.25);
+ haze_glow = (sun_moon_glow_factor < 1.0) ? 0.0 : (sun_moon_glow_factor * (haze_glow + 0.25));
- vec3 color =
- (blue_horizon * blue_weight * (sunlight + ambient_color) + (haze_horizon * haze_weight) * (sunlight * haze_glow + ambient_color));
+ // Haze color above cloud
+ vec3 color = (blue_horizon * blue_weight * (sunlight + ambient_color)
+ + (haze_horizon * haze_weight) * (sunlight * haze_glow + ambient_color));
// Final atmosphere additive
color *= (1. - combined_haze);
// Increase ambient when there are more clouds
- vec3 tmpAmbient = ambient_color;
- tmpAmbient += max(vec3(0), (1. - ambient_color)) * cloud_shadow * 0.5;
+ vec3 ambient = ambient_color + max(vec3(0), (1. - ambient_color)) * cloud_shadow * 0.5;
// Dim sunlight by cloud shadow percentage
sunlight *= max(0.0, (1. - cloud_shadow));
// Haze color below cloud
- vec3 additiveColorBelowCloud =
- (blue_horizon * blue_weight * (sunlight + tmpAmbient) + (haze_horizon * haze_weight) * (sunlight * haze_glow + tmpAmbient));
+ vec3 add_below_cloud = (blue_horizon * blue_weight * (sunlight + ambient)
+ + (haze_horizon * haze_weight) * (sunlight * haze_glow + ambient));
// Attenuate cloud color by atmosphere
combined_haze = sqrt(combined_haze); // less atmos opacity (more transparency) below clouds
// At horizon, blend high altitude sky color towards the darker color below the clouds
- color += (additiveColorBelowCloud - color) * (1. - sqrt(combined_haze));
+ color += (add_below_cloud - color) * (1. - sqrt(combined_haze));
// Haze color above cloud
vary_HazeColor = color;
diff --git a/indra/newview/app_settings/shaders/class2/deferred/skyF.glsl b/indra/newview/app_settings/shaders/class2/deferred/skyF.glsl
deleted file mode 100644
index 668f70c3ab..0000000000
--- a/indra/newview/app_settings/shaders/class2/deferred/skyF.glsl
+++ /dev/null
@@ -1,199 +0,0 @@
-/**
- * @file class2/deferred/skyF.glsl
- *
- * $LicenseInfo:firstyear=2005&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2005, 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$
- */
-
-uniform mat4 modelview_projection_matrix;
-
-// SKY ////////////////////////////////////////////////////////////////////////
-// The vertex shader for creating the atmospheric sky
-///////////////////////////////////////////////////////////////////////////////
-
-// Inputs
-uniform vec3 camPosLocal;
-
-uniform vec3 lightnorm;
-uniform vec3 sunlight_color;
-uniform vec3 moonlight_color;
-uniform int sun_up_factor;
-uniform vec3 ambient_color;
-uniform vec3 blue_horizon;
-uniform vec3 blue_density;
-uniform float haze_horizon;
-uniform float haze_density;
-
-uniform float cloud_shadow;
-uniform float density_multiplier;
-uniform float distance_multiplier;
-uniform float max_y;
-
-uniform vec3 glow;
-uniform float sun_moon_glow_factor;
-
-uniform vec3 cloud_color;
-
-#ifdef DEFINE_GL_FRAGCOLOR
-out vec4 frag_data[3];
-#else
-#define frag_data gl_FragData
-#endif
-
-VARYING vec3 pos;
-
-/////////////////////////////////////////////////////////////////////////
-// The fragment shader for the sky
-/////////////////////////////////////////////////////////////////////////
-
-uniform sampler2D rainbow_map;
-uniform sampler2D halo_map;
-
-uniform float moisture_level;
-uniform float droplet_radius;
-uniform float ice_level;
-
-vec3 rainbow(float d)
-{
- // d is the dot product of view and sun directions, so ranging -1.0..1.0
- // 'interesting' values of d are the range -0.75..-0.825, when view is nearly opposite of sun vec
- // Rainbox texture mode is GL_REPEAT, so tc of -.75 is equiv to 0.25, -0.825 equiv to 0.175.
-
- // SL-13629 Rainbow texture has colors within the correct .175...250 range, but order is inverted.
- // Rather than replace the texture, we mirror and translate the y tc to keep the colors within the
- // interesting range, but in reversed order: i.e. d = (1 - d) - 1.575
- d = clamp(-0.575 - d, 0.0, 1.0);
-
- // With the colors in the lower 1/4 of the texture, inverting the coords leaves most of it inaccessible.
- // So, we can stretch the texcoord above the colors (ie > 0.25) to fill the entire remaining coordinate
- // space. This improves gradation, reduces banding within the rainbow interior. (1-0.25) / (0.425/0.25) = 4.2857
- float interior_coord = max(0.0, d - 0.25) * 4.2857;
- d = clamp(d, 0.0, 0.25) + interior_coord;
-
- float rad = (droplet_radius - 5.0f) / 1024.0f;
- return pow(texture2D(rainbow_map, vec2(rad, d)).rgb, vec3(1.8)) * moisture_level;
-}
-
-vec3 halo22(float d)
-{
- d = clamp(d, 0.1, 1.0);
- float v = sqrt(clamp(1 - (d * d), 0, 1));
- return texture2D(halo_map, vec2(0, v)).rgb * ice_level;
-}
-
-/// Soft clips the light with a gamma correction
-vec3 scaleSoftClip(vec3 light);
-
-void main()
-{
- // World / view / projection
- // Get relative position (offset why?)
- vec3 rel_pos = pos.xyz - camPosLocal.xyz + vec3(0, 50, 0);
-
- // Adj position vector to clamp altitude
- if (rel_pos.y > 0.)
- {
- rel_pos *= (max_y / rel_pos.y);
- }
- if (rel_pos.y < 0.)
- {
- rel_pos *= (-32000. / rel_pos.y);
- }
-
- // Normalized
- vec3 rel_pos_norm = normalize(rel_pos);
- float rel_pos_len = length(rel_pos);
-
- // Initialize temp variables
- vec3 sunlight = (sun_up_factor == 1) ? sunlight_color : moonlight_color;
-
- // Sunlight attenuation effect (hue and brightness) due to atmosphere
- // this is used later for sunlight modulation at various altitudes
- vec3 light_atten = (blue_density + vec3(haze_density * 0.25)) * (density_multiplier * max_y);
-
- // Calculate relative weights
- vec3 combined_haze = abs(blue_density) + vec3(abs(haze_density));
- vec3 blue_weight = blue_density / combined_haze;
- vec3 haze_weight = haze_density / combined_haze;
-
- // Compute sunlight from rel_pos & lightnorm (for long rays like sky)
- float off_axis = 1.0 / max(1e-6, max(0, rel_pos_norm.y) + lightnorm.y);
- sunlight *= exp(-light_atten * off_axis);
-
- // Distance
- float density_dist = rel_pos_len * density_multiplier;
-
- // Transparency (-> combined_haze)
- // ATI Bugfix -- can't store combined_haze*density_dist in a variable because the ati
- // compiler gets confused.
- combined_haze = exp(-combined_haze * density_dist);
-
- // Compute haze glow
- float haze_glow = dot(rel_pos_norm, lightnorm.xyz);
- haze_glow = 1. - haze_glow;
- // haze_glow is 0 at the sun and increases away from sun
- haze_glow = max(haze_glow, .001);
- // Set a minimum "angle" (smaller glow.y allows tighter, brighter hotspot)
- haze_glow *= glow.x;
- // Higher glow.x gives dimmer glow (because next step is 1 / "angle")
- haze_glow = pow(haze_glow, glow.z);
- // glow.z should be negative, so we're doing a sort of (1 / "angle") function
-
- // Add "minimum anti-solar illumination"
- // For sun, add to glow. For moon, remove glow entirely. SL-13768
- haze_glow = (sun_moon_glow_factor < 1.0) ? 0.0 : (sun_moon_glow_factor * (haze_glow + 0.25));
-
- // Haze color above cloud
- vec3 color = blue_horizon * blue_weight * (sunlight + ambient_color)
- + haze_horizon * haze_weight * (sunlight * haze_glow + ambient_color);
-
- // Final atmosphere additive
- color *= (1. - combined_haze);
-
- // Increase ambient when there are more clouds
- // TODO 9/20: DJH what does this do? max(0,(1-ambient)) will change the color
- vec3 ambient = ambient_color + max(vec3(0), (1. - ambient_color)) * cloud_shadow * 0.5;
-
- // Dim sunlight by cloud shadow percentage
- sunlight *= max(0.0, (1. - cloud_shadow));
-
- // Haze color below cloud
- vec3 add_below_cloud = blue_horizon * blue_weight * (sunlight + ambient)
- + haze_horizon * haze_weight * (sunlight * haze_glow + ambient);
-
- // Attenuate cloud color by atmosphere
- combined_haze = sqrt(combined_haze); // less atmos opacity (more transparency) below clouds
-
- // At horizon, blend high altitude sky color towards the darker color below the clouds
- color += (add_below_cloud - color) * (1. - sqrt(combined_haze));
-
- float optic_d = dot(rel_pos_norm, lightnorm.xyz);
- vec3 halo_22 = halo22(optic_d);
- color.rgb += rainbow(optic_d);
- color.rgb += halo_22;
- color.rgb *= 2.;
- color.rgb = scaleSoftClip(color.rgb);
-
- // Gamma correct for WL (soft clip effect).
- frag_data[0] = vec4(color.rgb, 1.0);
- frag_data[1] = vec4(0.0, 0.0, 0.0, 0.0);
- frag_data[2] = vec4(0.0, 0.0, 0.0, GBUFFER_FLAG_SKIP_ATMOS); // 1.0 in norm.w masks off fog
-}
diff --git a/indra/newview/app_settings/shaders/class2/deferred/skyV.glsl b/indra/newview/app_settings/shaders/class2/deferred/skyV.glsl
deleted file mode 100644
index bcf775577a..0000000000
--- a/indra/newview/app_settings/shaders/class2/deferred/skyV.glsl
+++ /dev/null
@@ -1,42 +0,0 @@
-/**
- * @file WLSkyV.glsl
- *
- * $LicenseInfo:firstyear=2005&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2005, 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$
- */
-
-uniform mat4 modelview_projection_matrix;
-
-ATTRIBUTE vec3 position;
-
-// SKY ////////////////////////////////////////////////////////////////////////
-// The vertex shader for creating the atmospheric sky
-///////////////////////////////////////////////////////////////////////////////
-
-VARYING vec3 pos;
-
-void main()
-{
-
- // World / view / projection
- pos = position.xyz;
- gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0);
-}
diff --git a/indra/newview/llaccountingcostmanager.cpp b/indra/newview/llaccountingcostmanager.cpp
index e09527a34b..d3f988d715 100644
--- a/indra/newview/llaccountingcostmanager.cpp
+++ b/indra/newview/llaccountingcostmanager.cpp
@@ -96,11 +96,7 @@ void LLAccountingCostManager::accountingCostCoro(std::string url,
LLSD dataToPost = LLSD::emptyMap();
dataToPost[keystr.c_str()] = objectList;
- LLAccountingCostObserver* observer = observerHandle.get();
- LLUUID transactionId = observer->getTransactionID();
- observer = NULL;
-
-
+ LLAccountingCostObserver* observer = NULL;
LLSD results = httpAdapter->postAndSuspend(httpRequest, url, dataToPost);
diff --git a/indra/newview/llappdelegate-objc.mm b/indra/newview/llappdelegate-objc.mm
index 5214f4b838..1090888c1c 100644
--- a/indra/newview/llappdelegate-objc.mm
+++ b/indra/newview/llappdelegate-objc.mm
@@ -46,6 +46,7 @@
- (void)dealloc
{
+ [currentInputLanguage release];
[super dealloc];
}
@@ -199,12 +200,14 @@
- (bool) romanScript
{
- // How to add support for new languages with the input window:
- // Simply append this array with the language code (ja for japanese, ko for korean, zh for chinese, etc.)
- NSArray *nonRomanScript = [[NSArray alloc] initWithObjects:@"ja", @"ko", @"zh-Hant", @"zh-Hans", nil];
- if ([nonRomanScript containsObject:currentInputLanguage])
- {
- return false;
+ @autoreleasepool {
+ // How to add support for new languages with the input window:
+ // Simply append this array with the language code (ja for japanese, ko for korean, zh for chinese, etc.)
+ NSArray* nonRomanScript = @[@"ja", @"ko", @"zh-Hant", @"zh-Hans"];
+ if ([nonRomanScript containsObject:currentInputLanguage])
+ {
+ return false;
+ }
}
return true;
diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp
index 909f32cd21..3c93a9df7e 100644
--- a/indra/newview/llappearancemgr.cpp
+++ b/indra/newview/llappearancemgr.cpp
@@ -3987,7 +3987,7 @@ void LLAppearanceMgr::makeNewOutfitLinks(const std::string& new_folder_name, boo
// existence of AIS as an indicator the fix is present. Does
// not actually use AIS to create the category.
inventory_func_type func = boost::bind(&LLAppearanceMgr::onOutfitFolderCreated,this,_1,show_panel);
- LLUUID folder_id = gInventory.createNewCategory(
+ gInventory.createNewCategory(
parent_id,
LLFolderType::FT_OUTFIT,
new_folder_name,
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index dd4363d2a4..061feba0a4 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -135,6 +135,10 @@
#include "vlc/libvlc_version.h"
#endif // LL_LINUX
+#if LL_DARWIN
+#include "llwindowmacosx.h"
+#endif
+
// Third party library includes
#include <boost/bind.hpp>
#include <boost/foreach.hpp>
@@ -560,6 +564,7 @@ static void settings_to_globals()
LLWorldMapView::setScaleSetting(gSavedSettings.getF32("MapScale"));
#if LL_DARWIN
+ LLWindowMacOSX::sUseMultGL = gSavedSettings.getBOOL("RenderAppleUseMultGL");
gHiDPISupport = gSavedSettings.getBOOL("RenderHiDPI");
#endif
}
@@ -1697,7 +1702,8 @@ bool LLAppViewer::cleanup()
{
if (!isSecondInstance())
{
- LLSceneMonitor::instance().dumpToFile(gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "scene_monitor_results.csv"));
+ std::string dump_path = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "scene_monitor_results.csv");
+ LLSceneMonitor::instance().dumpToFile(dump_path);
}
LLSceneMonitor::deleteSingleton();
}
diff --git a/indra/newview/llavatarrenderinfoaccountant.cpp b/indra/newview/llavatarrenderinfoaccountant.cpp
index 275f17b02a..293c9d60a1 100644
--- a/indra/newview/llavatarrenderinfoaccountant.cpp
+++ b/indra/newview/llavatarrenderinfoaccountant.cpp
@@ -364,11 +364,10 @@ void LLAvatarRenderInfoAccountant::getRenderInfoFromRegion(LLViewerRegion * regi
}
}
-// static
// Called every frame - send render weight requests to every region
void LLAvatarRenderInfoAccountant::idle()
{
- if (mRenderInfoScanTimer.hasExpired())
+ if (mRenderInfoScanTimer.hasExpired() && !LLApp::isExiting())
{
LL_DEBUGS("AvatarRenderInfo") << "Scanning regions for render info updates"
<< LL_ENDL;
diff --git a/indra/newview/llbuycurrencyhtml.cpp b/indra/newview/llbuycurrencyhtml.cpp
index 1c69dadb12..7ad06f8eaa 100644
--- a/indra/newview/llbuycurrencyhtml.cpp
+++ b/indra/newview/llbuycurrencyhtml.cpp
@@ -41,7 +41,7 @@ class LLBuyCurrencyHTMLHandler :
{
public:
// requests will be throttled from a non-trusted browser
- LLBuyCurrencyHTMLHandler() : LLCommandHandler( "buycurrencyhtml", UNTRUSTED_ALLOW ) {}
+ LLBuyCurrencyHTMLHandler() : LLCommandHandler( "buycurrencyhtml", UNTRUSTED_THROTTLE) {}
bool handle(const LLSD& params, const LLSD& query_map, LLMediaCtrl* web)
{
diff --git a/indra/newview/llcallingcard.cpp b/indra/newview/llcallingcard.cpp
index 1ad2157df0..df79043b00 100644
--- a/indra/newview/llcallingcard.cpp
+++ b/indra/newview/llcallingcard.cpp
@@ -650,8 +650,7 @@ void LLAvatarTracker::processChange(LLMessageSystem* msg)
{
if(mBuddyInfo.find(agent_id) != mBuddyInfo.end())
{
- if (((mBuddyInfo[agent_id]->getRightsGrantedFrom() ^ new_rights) & LLRelationship::GRANT_MODIFY_OBJECTS)
- && !gAgent.isDoNotDisturb())
+ if (((mBuddyInfo[agent_id]->getRightsGrantedFrom() ^ new_rights) & LLRelationship::GRANT_MODIFY_OBJECTS))
{
LLSD args;
args["NAME"] = LLSLURL("agent", agent_id, "displayname").getSLURLString();
@@ -719,11 +718,12 @@ void LLAvatarTracker::processNotify(LLMessageSystem* msg, bool online)
// we were tracking someone who went offline
deleteTrackingData();
}
- }
- if(chat_notify)
- {
- // Look up the name of this agent for the notification
- LLAvatarNameCache::get(agent_id,boost::bind(&on_avatar_name_cache_notify,_1, _2, online, payload));
+
+ if(chat_notify)
+ {
+ // Look up the name of this agent for the notification
+ LLAvatarNameCache::get(agent_id,boost::bind(&on_avatar_name_cache_notify,_1, _2, online, payload));
+ }
}
mModifyMask |= LLFriendObserver::ONLINE;
diff --git a/indra/newview/llchathistory.cpp b/indra/newview/llchathistory.cpp
index 7188b9136c..9a608fba8e 100644
--- a/indra/newview/llchathistory.cpp
+++ b/indra/newview/llchathistory.cpp
@@ -141,6 +141,18 @@ public:
{
mAvatarNameCacheConnection.disconnect();
}
+ auto menu = mPopupMenuHandleAvatar.get();
+ if (menu)
+ {
+ menu->die();
+ mPopupMenuHandleAvatar.markDead();
+ }
+ menu = mPopupMenuHandleObject.get();
+ if (menu)
+ {
+ menu->die();
+ mPopupMenuHandleObject.markDead();
+ }
}
BOOL handleMouseUp(S32 x, S32 y, MASK mask)
@@ -567,36 +579,6 @@ public:
BOOL postBuild()
{
- LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar;
- LLUICtrl::EnableCallbackRegistry::ScopedRegistrar registrar_enable;
-
- registrar.add("AvatarIcon.Action", boost::bind(&LLChatHistoryHeader::onAvatarIconContextMenuItemClicked, this, _2));
- registrar_enable.add("AvatarIcon.Check", boost::bind(&LLChatHistoryHeader::onAvatarIconContextMenuItemChecked, this, _2));
- registrar_enable.add("AvatarIcon.Enable", boost::bind(&LLChatHistoryHeader::onAvatarIconContextMenuItemEnabled, this, _2));
- registrar_enable.add("AvatarIcon.Visible", boost::bind(&LLChatHistoryHeader::onAvatarIconContextMenuItemVisible, this, _2));
- registrar.add("ObjectIcon.Action", boost::bind(&LLChatHistoryHeader::onObjectIconContextMenuItemClicked, this, _2));
- registrar_enable.add("ObjectIcon.Visible", boost::bind(&LLChatHistoryHeader::onObjectIconContextMenuItemVisible, this, _2));
-
- LLMenuGL* menu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>("menu_avatar_icon.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
- if (menu)
- {
- mPopupMenuHandleAvatar = menu->getHandle();
- }
- else
- {
- LL_WARNS() << " Failed to create menu_avatar_icon.xml" << LL_ENDL;
- }
-
- menu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>("menu_object_icon.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
- if (menu)
- {
- mPopupMenuHandleObject = menu->getHandle();
- }
- else
- {
- LL_WARNS() << " Failed to create menu_object_icon.xml" << LL_ENDL;
- }
-
setDoubleClickCallback(boost::bind(&LLChatHistoryHeader::showInspector, this));
setMouseEnterCallback(boost::bind(&LLChatHistoryHeader::showInfoCtrl, this));
@@ -884,13 +866,53 @@ protected:
void showObjectContextMenu(S32 x,S32 y)
{
LLMenuGL* menu = (LLMenuGL*)mPopupMenuHandleObject.get();
- if(menu)
+ if (!menu)
+ {
+ LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar;
+ LLUICtrl::EnableCallbackRegistry::ScopedRegistrar registrar_enable;
+ registrar.add("ObjectIcon.Action", boost::bind(&LLChatHistoryHeader::onObjectIconContextMenuItemClicked, this, _2));
+ registrar_enable.add("ObjectIcon.Visible", boost::bind(&LLChatHistoryHeader::onObjectIconContextMenuItemVisible, this, _2));
+
+ menu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>("menu_object_icon.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
+ if (menu)
+ {
+ mPopupMenuHandleObject = menu->getHandle();
+ menu->updateParent(LLMenuGL::sMenuContainer);
+ LLMenuGL::showPopup(this, menu, x, y);
+ }
+ else
+ {
+ LL_WARNS() << " Failed to create menu_object_icon.xml" << LL_ENDL;
+ }
+ }
+ else
+ {
LLMenuGL::showPopup(this, menu, x, y);
+ }
}
void showAvatarContextMenu(S32 x,S32 y)
{
LLMenuGL* menu = (LLMenuGL*)mPopupMenuHandleAvatar.get();
+ if (!menu)
+ {
+ LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar;
+ LLUICtrl::EnableCallbackRegistry::ScopedRegistrar registrar_enable;
+ registrar.add("AvatarIcon.Action", boost::bind(&LLChatHistoryHeader::onAvatarIconContextMenuItemClicked, this, _2));
+ registrar_enable.add("AvatarIcon.Check", boost::bind(&LLChatHistoryHeader::onAvatarIconContextMenuItemChecked, this, _2));
+ registrar_enable.add("AvatarIcon.Enable", boost::bind(&LLChatHistoryHeader::onAvatarIconContextMenuItemEnabled, this, _2));
+ registrar_enable.add("AvatarIcon.Visible", boost::bind(&LLChatHistoryHeader::onAvatarIconContextMenuItemVisible, this, _2));
+
+ menu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>("menu_avatar_icon.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
+ if (menu)
+ {
+ mPopupMenuHandleAvatar = menu->getHandle();
+ }
+ else
+ {
+ LL_WARNS() << " Failed to create menu_avatar_icon.xml" << LL_ENDL;
+ }
+ }
if(menu)
{
@@ -1082,10 +1104,7 @@ LLChatHistory::LLChatHistory(const LLChatHistory::Params& p)
LLSD LLChatHistory::getValue() const
{
- LLSD* text=new LLSD();
- text->assign(mEditor->getText());
- return *text;
-
+ return LLSD(mEditor->getText());
}
LLChatHistory::~LLChatHistory()
diff --git a/indra/newview/llchiclet.cpp b/indra/newview/llchiclet.cpp
index 0f187b0ecf..cc4f4536a4 100644
--- a/indra/newview/llchiclet.cpp
+++ b/indra/newview/llchiclet.cpp
@@ -67,7 +67,6 @@ LLSysWellChiclet::LLSysWellChiclet(const Params& p)
, mMaxDisplayedCount(p.max_displayed_count)
, mIsNewMessagesState(false)
, mFlashToLitTimer(NULL)
- , mContextMenu(NULL)
{
LLButton::Params button_params = p.button;
mButton = LLUICtrlFactory::create<LLButton>(button_params);
@@ -79,6 +78,12 @@ LLSysWellChiclet::LLSysWellChiclet(const Params& p)
LLSysWellChiclet::~LLSysWellChiclet()
{
mFlashToLitTimer->unset();
+ LLContextMenu* menu = static_cast<LLContextMenu*>(mContextMenuHandle.get());
+ if (menu)
+ {
+ menu->die();
+ mContextMenuHandle.markDead();
+ }
}
void LLSysWellChiclet::setCounter(S32 counter)
@@ -145,14 +150,16 @@ void LLSysWellChiclet::updateWidget(bool is_window_empty)
// virtual
BOOL LLSysWellChiclet::handleRightMouseDown(S32 x, S32 y, MASK mask)
{
- if(!mContextMenu)
+ LLContextMenu* menu_avatar = mContextMenuHandle.get();
+ if(!menu_avatar)
{
createMenu();
+ menu_avatar = mContextMenuHandle.get();
}
- if (mContextMenu)
+ if (menu_avatar)
{
- mContextMenu->show(x, y);
- LLMenuGL::showPopup(this, mContextMenu, x, y);
+ menu_avatar->show(x, y);
+ LLMenuGL::showPopup(this, menu_avatar, x, y);
}
return TRUE;
}
@@ -192,7 +199,7 @@ bool LLNotificationChiclet::enableMenuItem(const LLSD& user_data)
void LLNotificationChiclet::createMenu()
{
- if(mContextMenu)
+ if(mContextMenuHandle.get())
{
LL_WARNS() << "Menu already exists" << LL_ENDL;
return;
@@ -207,10 +214,14 @@ void LLNotificationChiclet::createMenu()
boost::bind(&LLNotificationChiclet::enableMenuItem, this, _2));
llassert(LLMenuGL::sMenuContainer != NULL);
- mContextMenu = LLUICtrlFactory::getInstance()->createFromFile<LLContextMenu>
+ LLContextMenu* menu = LLUICtrlFactory::getInstance()->createFromFile<LLContextMenu>
("menu_notification_well_button.xml",
LLMenuGL::sMenuContainer,
LLViewerMenuHolderGL::child_registry_t::instance());
+ if (menu)
+ {
+ mContextMenuHandle = menu->getHandle();
+ }
}
/*virtual*/
@@ -309,10 +320,19 @@ LLIMChiclet::LLIMChiclet(const LLIMChiclet::Params& p)
, mDefaultWidth(p.rect().getWidth())
, mNewMessagesIcon(NULL)
, mChicletButton(NULL)
-, mPopupMenu(NULL)
{
}
+LLIMChiclet::~LLIMChiclet()
+{
+ auto menu = mPopupMenuHandle.get();
+ if (menu)
+ {
+ menu->die();
+ mPopupMenuHandle.markDead();
+ }
+}
+
/* virtual*/
BOOL LLIMChiclet::postBuild()
{
@@ -364,16 +384,18 @@ void LLIMChiclet::setToggleState(bool toggle)
BOOL LLIMChiclet::handleRightMouseDown(S32 x, S32 y, MASK mask)
{
- if(!mPopupMenu)
+ auto menu = static_cast<LLMenuGL*>(mPopupMenuHandle.get());
+ if(!menu)
{
createPopupMenu();
+ menu = static_cast<LLMenuGL*>(mPopupMenuHandle.get());
}
- if (mPopupMenu)
+ if (menu)
{
updateMenuItems();
- mPopupMenu->arrangeAndClear();
- LLMenuGL::showPopup(this, mPopupMenu, x, y);
+ menu->arrangeAndClear();
+ LLMenuGL::showPopup(this, menu, x, y);
}
return TRUE;
@@ -381,15 +403,16 @@ BOOL LLIMChiclet::handleRightMouseDown(S32 x, S32 y, MASK mask)
void LLIMChiclet::hidePopupMenu()
{
- if (mPopupMenu)
+ auto menu = mPopupMenuHandle.get();
+ if (menu)
{
- mPopupMenu->setVisible(FALSE);
+ menu->setVisible(FALSE);
}
}
bool LLIMChiclet::canCreateMenu()
{
- if(mPopupMenu)
+ if(mPopupMenuHandle.get())
{
LL_WARNS() << "Menu already exists" << LL_ENDL;
return false;
@@ -1107,8 +1130,13 @@ void LLScriptChiclet::createPopupMenu()
LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar;
registrar.add("ScriptChiclet.Action", boost::bind(&LLScriptChiclet::onMenuItemClicked, this, _2));
- mPopupMenu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>
+ LLMenuGL* menu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>
("menu_script_chiclet.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
+ if (menu)
+ {
+ mPopupMenuHandle = menu->getHandle();
+ }
+
}
//////////////////////////////////////////////////////////////////////////
@@ -1185,8 +1213,12 @@ void LLInvOfferChiclet::createPopupMenu()
LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar;
registrar.add("InvOfferChiclet.Action", boost::bind(&LLInvOfferChiclet::onMenuItemClicked, this, _2));
- mPopupMenu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>
+ LLMenuGL* menu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>
("menu_inv_offer_chiclet.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
+ if (menu)
+ {
+ mPopupMenuHandle = menu->getHandle();
+ }
}
// EOF
diff --git a/indra/newview/llchiclet.h b/indra/newview/llchiclet.h
index aceedda07e..58a797218f 100644
--- a/indra/newview/llchiclet.h
+++ b/indra/newview/llchiclet.h
@@ -252,7 +252,7 @@ public:
{};
- virtual ~LLIMChiclet() {};
+ virtual ~LLIMChiclet();
/**
* It is used for default setting up of chicklet:click handler, etc.
@@ -325,7 +325,7 @@ protected:
bool canCreateMenu();
- LLMenuGL* mPopupMenu;
+ LLHandle<LLUICtrl> mPopupMenuHandle;
bool mShowSpeaker;
bool mCounterEnabled;
@@ -519,7 +519,7 @@ protected:
bool mIsNewMessagesState;
LLFlashTimer* mFlashToLitTimer;
- LLContextMenu* mContextMenu;
+ LLHandle<LLContextMenu> mContextMenuHandle;
};
class LLNotificationChiclet : public LLSysWellChiclet
diff --git a/indra/newview/llcommandhandler.cpp b/indra/newview/llcommandhandler.cpp
index 23e2271eae..74f37961c7 100644
--- a/indra/newview/llcommandhandler.cpp
+++ b/indra/newview/llcommandhandler.cpp
@@ -39,6 +39,7 @@
#define THROTTLE_PERIOD 5 // required seconds between throttled commands
static LLCommandDispatcherListener sCommandDispatcherListener;
+const std::string LLCommandHandler::NAV_TYPE_CLICKED = "clicked";
//---------------------------------------------------------------------------
// Underlying registry for command handlers, not directly accessible.
@@ -64,6 +65,9 @@ public:
bool trusted_browser);
private:
+ void notifySlurlBlocked();
+ void notifySlurlThrottled();
+
friend LLSD LLCommandDispatcher::enumerate();
std::map<std::string, LLCommandHandlerInfo> mMap;
};
@@ -96,8 +100,6 @@ bool LLCommandHandlerRegistry::dispatch(const std::string& cmd,
const std::string& nav_type,
bool trusted_browser)
{
- static bool slurl_blocked = false;
- static bool slurl_throttled = false;
static F64 last_throttle_time = 0.0;
F64 cur_time = 0.0;
std::map<std::string, LLCommandHandlerInfo>::iterator it = mMap.find(cmd);
@@ -115,44 +117,45 @@ bool LLCommandHandlerRegistry::dispatch(const std::string& cmd,
// block request from external browser, but report as
// "handled" because it was well formatted.
LL_WARNS_ONCE("SLURL") << "Blocked SLURL command from untrusted browser" << LL_ENDL;
- if (! slurl_blocked)
- {
- if (LLStartUp::getStartupState() >= STATE_BROWSER_INIT)
- {
- // Note: commands can arrive before we initialize everything we need for Notification.
- LLNotificationsUtil::add("BlockedSLURL");
- }
- slurl_blocked = true;
- }
+ notifySlurlBlocked();
return true;
+ case LLCommandHandler::UNTRUSTED_CLICK_ONLY:
+ if (nav_type == LLCommandHandler::NAV_TYPE_CLICKED
+ && info.mHandler->canHandleUntrusted(params, query_map, web, nav_type))
+ {
+ break;
+ }
+ LL_WARNS_ONCE("SLURL") << "Blocked SLURL click-only command " << cmd << " from untrusted browser" << LL_ENDL;
+ notifySlurlBlocked();
+ return true;
+
case LLCommandHandler::UNTRUSTED_THROTTLE:
+ //skip initial request from external browser before STATE_BROWSER_INIT
+ if (LLStartUp::getStartupState() == STATE_FIRST)
+ {
+ return true;
+ }
+ if (!info.mHandler->canHandleUntrusted(params, query_map, web, nav_type))
+ {
+ LL_WARNS_ONCE("SLURL") << "Blocked SLURL command from untrusted browser" << LL_ENDL;
+ notifySlurlBlocked();
+ return true;
+ }
// if users actually click on a link, we don't need to throttle it
// (throttling mechanism is used to prevent an avalanche of clicks via
// javascript
- if ( nav_type == "clicked" )
+ if (nav_type == LLCommandHandler::NAV_TYPE_CLICKED)
{
break;
}
- //skip initial request from external browser before STATE_BROWSER_INIT
- if (LLStartUp::getStartupState() == STATE_FIRST)
- {
- return true;
- }
cur_time = LLTimer::getElapsedSeconds();
if (cur_time < last_throttle_time + THROTTLE_PERIOD)
{
// block request from external browser if it happened
// within THROTTLE_PERIOD seconds of the last command
LL_WARNS_ONCE("SLURL") << "Throttled SLURL command from untrusted browser" << LL_ENDL;
- if (! slurl_throttled)
- {
- if (LLStartUp::getStartupState() >= STATE_BROWSER_INIT)
- {
- LLNotificationsUtil::add("ThrottledSLURL");
- }
- slurl_throttled = true;
- }
+ notifySlurlThrottled();
return true;
}
last_throttle_time = cur_time;
@@ -163,6 +166,34 @@ bool LLCommandHandlerRegistry::dispatch(const std::string& cmd,
return info.mHandler->handle(params, query_map, web);
}
+void LLCommandHandlerRegistry::notifySlurlBlocked()
+{
+ static bool slurl_blocked = false;
+ if (!slurl_blocked)
+ {
+ if (LLStartUp::getStartupState() >= STATE_BROWSER_INIT)
+ {
+ // Note: commands can arrive before we initialize everything we need for Notification.
+ LLNotificationsUtil::add("BlockedSLURL");
+ }
+ slurl_blocked = true;
+ }
+}
+
+void LLCommandHandlerRegistry::notifySlurlThrottled()
+{
+ static bool slurl_throttled = false;
+ if (!slurl_throttled)
+ {
+ if (LLStartUp::getStartupState() >= STATE_BROWSER_INIT)
+ {
+ // Note: commands can arrive before we initialize everything we need for Notification.
+ LLNotificationsUtil::add("ThrottledSLURL");
+ }
+ slurl_throttled = true;
+ }
+}
+
//---------------------------------------------------------------------------
// Automatic registration of commands, runs before main()
//---------------------------------------------------------------------------
@@ -230,6 +261,7 @@ symbol_info symbols[] =
{
ent(LLCommandHandler::UNTRUSTED_ALLOW), // allow commands from untrusted browsers
ent(LLCommandHandler::UNTRUSTED_BLOCK), // ignore commands from untrusted browsers
+ ent(LLCommandHandler::UNTRUSTED_CLICK_ONLY), // allow untrusted, but only if clicked
ent(LLCommandHandler::UNTRUSTED_THROTTLE) // allow untrusted, but only a few per min.
};
diff --git a/indra/newview/llcommandhandler.h b/indra/newview/llcommandhandler.h
index 1e0895565a..763e3ee51f 100644
--- a/indra/newview/llcommandhandler.h
+++ b/indra/newview/llcommandhandler.h
@@ -65,9 +65,12 @@ public:
{
UNTRUSTED_ALLOW, // allow commands from untrusted browsers
UNTRUSTED_BLOCK, // ignore commands from untrusted browsers
+ UNTRUSTED_CLICK_ONLY, // allow untrusted, but only if clicked
UNTRUSTED_THROTTLE // allow untrusted, but only a few per min.
};
+ static const std::string NAV_TYPE_CLICKED;
+
LLCommandHandler(const char* command, EUntrustedAccess untrusted_access);
// Automatically registers object to get called when
// command is executed. All commands can be processed
@@ -76,6 +79,13 @@ public:
virtual ~LLCommandHandler();
+ virtual bool canHandleUntrusted(
+ const LLSD& params,
+ const LLSD& query_map,
+ LLMediaCtrl* web,
+ const std::string& nav_type)
+ { return true; }
+
virtual bool handle(const LLSD& params,
const LLSD& query_map,
LLMediaCtrl* web) = 0;
diff --git a/indra/newview/llenvironment.cpp b/indra/newview/llenvironment.cpp
index 6d600efe37..d88f0f9847 100644
--- a/indra/newview/llenvironment.cpp
+++ b/indra/newview/llenvironment.cpp
@@ -684,7 +684,6 @@ namespace
if (!injection->mBlendIn)
mix = 1.0 - mix;
stringset_t dummy;
- LLUUID cloud_noise_id = getCloudNoiseTextureId();
F64 value = this->mSettings[injection->mKeyName].asReal();
if (this->getCloudNoiseTextureId().isNull())
{
@@ -3129,7 +3128,7 @@ bool LLEnvironment::loadFromSettings()
LL_INFOS("ENVIRONMENT") << "Unable to open previous session environment file " << user_filepath << LL_ENDL;
}
- if (!env_data.isMap() || env_data.emptyMap())
+ if (!env_data.isMap() || (env_data.size() == 0))
{
LL_DEBUGS("ENVIRONMENT") << "Empty map loaded from: " << user_filepath << LL_ENDL;
return false;
diff --git a/indra/newview/llfilepicker.cpp b/indra/newview/llfilepicker.cpp
index 39bac89864..29e8210d8e 100644
--- a/indra/newview/llfilepicker.cpp
+++ b/indra/newview/llfilepicker.cpp
@@ -593,9 +593,9 @@ BOOL LLFilePicker::getSaveFile(ESaveFilter filter, const std::string& filename,
#elif LL_DARWIN
-std::vector<std::string>* LLFilePicker::navOpenFilterProc(ELoadFilter filter) //(AEDesc *theItem, void *info, void *callBackUD, NavFilterModes filterMode)
+std::unique_ptr<std::vector<std::string>> LLFilePicker::navOpenFilterProc(ELoadFilter filter) //(AEDesc *theItem, void *info, void *callBackUD, NavFilterModes filterMode)
{
- std::vector<std::string> *allowedv = new std::vector< std::string >;
+ std::unique_ptr<std::vector<std::string>> allowedv(new std::vector< std::string >);
switch(filter)
{
case FFLOAD_ALL:
@@ -669,9 +669,9 @@ bool LLFilePicker::doNavChooseDialog(ELoadFilter filter)
gViewerWindow->getWindow()->beforeDialog();
- std::vector<std::string> *allowed_types=navOpenFilterProc(filter);
+ std::unique_ptr<std::vector<std::string>> allowed_types = navOpenFilterProc(filter);
- std::vector<std::string> *filev = doLoadDialog(allowed_types,
+ std::unique_ptr<std::vector<std::string>> filev = doLoadDialog(allowed_types.get(),
mPickOptions);
gViewerWindow->getWindow()->afterDialog();
@@ -786,7 +786,7 @@ bool LLFilePicker::doNavSaveDialog(ESaveFilter filter, const std::string& filena
gViewerWindow->getWindow()->beforeDialog();
// Run the dialog
- std::string* filev = doSaveDialog(&namestring,
+ std::unique_ptr<std::string> filev = doSaveDialog(&namestring,
&type,
&creator,
&extension,
diff --git a/indra/newview/llfilepicker.h b/indra/newview/llfilepicker.h
index a03f3f6711..f510d93dff 100644
--- a/indra/newview/llfilepicker.h
+++ b/indra/newview/llfilepicker.h
@@ -165,7 +165,7 @@ private:
bool doNavChooseDialog(ELoadFilter filter);
bool doNavSaveDialog(ESaveFilter filter, const std::string& filename);
- std::vector<std::string>* navOpenFilterProc(ELoadFilter filter);
+ std::unique_ptr<std::vector<std::string>> navOpenFilterProc(ELoadFilter filter);
#endif
#if LL_GTK
diff --git a/indra/newview/llfilepicker_mac.h b/indra/newview/llfilepicker_mac.h
index e0b7e2e8ce..b2fb371afe 100644
--- a/indra/newview/llfilepicker_mac.h
+++ b/indra/newview/llfilepicker_mac.h
@@ -39,9 +39,9 @@
#include <vector>
//void modelessPicker();
-std::vector<std::string>* doLoadDialog(const std::vector<std::string>* allowed_types,
+std::unique_ptr<std::vector<std::string>> doLoadDialog(const std::vector<std::string>* allowed_types,
unsigned int flags);
-std::string* doSaveDialog(const std::string* file,
+std::unique_ptr<std::string> doSaveDialog(const std::string* file,
const std::string* type,
const std::string* creator,
const std::string* extension,
diff --git a/indra/newview/llfilepicker_mac.mm b/indra/newview/llfilepicker_mac.mm
index 1438e4dc0a..0ae5fc3f77 100644
--- a/indra/newview/llfilepicker_mac.mm
+++ b/indra/newview/llfilepicker_mac.mm
@@ -29,104 +29,107 @@
#include <iostream>
#include "llfilepicker_mac.h"
-std::vector<std::string>* doLoadDialog(const std::vector<std::string>* allowed_types,
+std::unique_ptr<std::vector<std::string>> doLoadDialog(const std::vector<std::string>* allowed_types,
unsigned int flags)
{
- int i, result;
-
- //Aura TODO: We could init a small window and release it at the end of this routine
- //for a modeless interface.
-
- NSOpenPanel *panel = [NSOpenPanel openPanel];
- //NSString *fileName = nil;
- NSMutableArray *fileTypes = nil;
-
-
- if ( allowed_types && !allowed_types->empty())
- {
- fileTypes = [[NSMutableArray alloc] init];
+ std::unique_ptr<std::vector<std::string>> outfiles;
+
+ @autoreleasepool {
+ int i, result;
+ //Aura TODO: We could init a small window and release it at the end of this routine
+ //for a modeless interface.
+
+ NSOpenPanel *panel = [NSOpenPanel openPanel];
+ //NSString *fileName = nil;
+ NSMutableArray *fileTypes = nil;
- for (i=0;i<allowed_types->size();++i)
+ if ( allowed_types && !allowed_types->empty())
{
- [fileTypes addObject:
- [NSString stringWithCString:(*allowed_types)[i].c_str()
- encoding:[NSString defaultCStringEncoding]]];
+ fileTypes = [[[NSMutableArray alloc] init] autorelease];
+
+ for (i=0;i<allowed_types->size();++i)
+ {
+ [fileTypes addObject:
+ [NSString stringWithCString:(*allowed_types)[i].c_str()
+ encoding:[NSString defaultCStringEncoding]]];
+ }
}
- }
- //[panel setMessage:@"Import one or more files or directories."];
- [panel setAllowsMultipleSelection: ( (flags & F_MULTIPLE)?true:false ) ];
- [panel setCanChooseDirectories: ( (flags & F_DIRECTORY)?true:false ) ];
- [panel setCanCreateDirectories: true];
- [panel setResolvesAliases: true];
- [panel setCanChooseFiles: ( (flags & F_FILE)?true:false )];
- [panel setTreatsFilePackagesAsDirectories: ( flags & F_NAV_SUPPORT ) ];
-
- std::vector<std::string>* outfiles = NULL;
-
- if (fileTypes)
- {
- [panel setAllowedFileTypes:fileTypes];
- result = [panel runModal];
- }
- else
- {
- // I suggest it's better to open the last path and let this default to home dir as necessary
- // for consistency with other OS X apps
- //
- //[panel setDirectoryURL: fileURLWithPath(NSHomeDirectory()) ];
- result = [panel runModal];
- }
-
- if (result == NSOKButton)
- {
- NSArray *filesToOpen = [panel URLs];
- int i, count = [filesToOpen count];
+ //[panel setMessage:@"Import one or more files or directories."];
+ [panel setAllowsMultipleSelection: ( (flags & F_MULTIPLE)?true:false ) ];
+ [panel setCanChooseDirectories: ( (flags & F_DIRECTORY)?true:false ) ];
+ [panel setCanCreateDirectories: true];
+ [panel setResolvesAliases: true];
+ [panel setCanChooseFiles: ( (flags & F_FILE)?true:false )];
+ [panel setTreatsFilePackagesAsDirectories: ( flags & F_NAV_SUPPORT ) ];
- if (count > 0)
+ if (fileTypes)
+ {
+ [panel setAllowedFileTypes:fileTypes];
+ result = [panel runModal];
+ }
+ else
{
- outfiles = new std::vector<std::string>;
+ // I suggest it's better to open the last path and let this default to home dir as necessary
+ // for consistency with other OS X apps
+ //
+ //[panel setDirectoryURL: fileURLWithPath(NSHomeDirectory()) ];
+ result = [panel runModal];
}
- for (i=0; i<count; i++) {
- NSString *aFile = [[filesToOpen objectAtIndex:i] path];
- std::string *afilestr = new std::string([aFile UTF8String]);
- outfiles->push_back(*afilestr);
+ if (result == NSOKButton)
+ {
+ NSArray *filesToOpen = [panel URLs];
+ int i, count = [filesToOpen count];
+
+ if (count > 0)
+ {
+ outfiles.reset(new std::vector<std::string>);
+ }
+
+ for (i=0; i<count; i++) {
+ NSString *aFile = [[filesToOpen objectAtIndex:i] path];
+ std::string afilestr = std::string([aFile UTF8String]);
+ outfiles->push_back(afilestr);
+ }
}
}
+
return outfiles;
}
-std::string* doSaveDialog(const std::string* file,
+std::unique_ptr<std::string> doSaveDialog(const std::string* file,
const std::string* type,
const std::string* creator,
const std::string* extension,
unsigned int flags)
{
- NSSavePanel *panel = [NSSavePanel savePanel];
-
- NSString *extensionns = [NSString stringWithCString:extension->c_str() encoding:[NSString defaultCStringEncoding]];
- NSArray *fileType = [extensionns componentsSeparatedByString:@","];
-
- //[panel setMessage:@"Save Image File"];
- [panel setTreatsFilePackagesAsDirectories: ( flags & F_NAV_SUPPORT ) ];
- [panel setCanSelectHiddenExtension:true];
- [panel setAllowedFileTypes:fileType];
- NSString *fileName = [NSString stringWithCString:file->c_str() encoding:[NSString defaultCStringEncoding]];
-
- std::string *outfile = NULL;
- NSURL* url = [NSURL fileURLWithPath:fileName];
- [panel setNameFieldStringValue: fileName];
- [panel setDirectoryURL: url];
- if([panel runModal] ==
- NSFileHandlingPanelOKButton)
- {
- NSURL* url = [panel URL];
- NSString* p = [url path];
- outfile = new std::string( [p UTF8String] );
- // write the file
- }
+ std::unique_ptr<std::string> outfile;
+ @autoreleasepool {
+ NSSavePanel *panel = [NSSavePanel savePanel];
+
+ NSString *extensionns = [NSString stringWithCString:extension->c_str() encoding:[NSString defaultCStringEncoding]];
+ NSArray *fileType = [extensionns componentsSeparatedByString:@","];
+
+ //[panel setMessage:@"Save Image File"];
+ [panel setTreatsFilePackagesAsDirectories: ( flags & F_NAV_SUPPORT ) ];
+ [panel setCanSelectHiddenExtension:true];
+ [panel setAllowedFileTypes:fileType];
+ NSString *fileName = [NSString stringWithCString:file->c_str() encoding:[NSString defaultCStringEncoding]];
+
+ NSURL* url = [NSURL fileURLWithPath:fileName];
+ [panel setNameFieldStringValue: fileName];
+ [panel setDirectoryURL: url];
+ if([panel runModal] ==
+ NSFileHandlingPanelOKButton)
+ {
+ NSURL* url = [panel URL];
+ NSString* p = [url path];
+ outfile.reset(new std::string([p UTF8String]));
+ // write the file
+ }
+ }
return outfile;
}
diff --git a/indra/newview/llfloater360capture.cpp b/indra/newview/llfloater360capture.cpp
index 62a1e0af94..eff94bd195 100644
--- a/indra/newview/llfloater360capture.cpp
+++ b/indra/newview/llfloater360capture.cpp
@@ -537,7 +537,8 @@ void LLFloater360Capture::capture360Images()
// We need to convert from the angle getYaw() gives us into something
// the XMP data field wants (N=0, E=90, S=180, W= 270 etc.)
mInitialHeadingDeg = (360 + 90 - (int)(camera->getYaw() * RAD_TO_DEG)) % 360;
- LL_INFOS("360Capture") << "Recording a heading of " << (int)(mInitialHeadingDeg) << LL_ENDL;
+ LL_INFOS("360Capture") << "Recording a heading of " << (int)(mInitialHeadingDeg)
+ << " Image size: " << (S32)mSourceImageSize << LL_ENDL;
// camera constants for the square, cube map capture image
camera->setAspect(1.0); // must set aspect ratio first to avoid undesirable clamping of vertical FoV
@@ -587,6 +588,9 @@ void LLFloater360Capture::capture360Images()
// for each of the 6 directions we shoot...
for (int i = 0; i < 6; i++)
{
+ LLAppViewer::instance()->pauseMainloopTimeout();
+ LLViewerStats::instance().getRecording().stop();
+
// these buffers are where the raw, captured pixels are stored and
// the first time we use them, we have to make a new one
if (mRawImages[i] == nullptr)
@@ -624,8 +628,10 @@ void LLFloater360Capture::capture360Images()
auto duration = std::chrono::duration_cast<std::chrono::duration<double>>(t_end - t_start);
encode_time_total += duration.count();
- // ping the main loop in case the snapshot process takes a really long
- // time and we get disconnected
+ LLViewerStats::instance().getRecording().resume();
+ LLAppViewer::instance()->resumeMainloopTimeout();
+
+ // update main loop timeout state
LLAppViewer::instance()->pingMainloopTimeout("LLFloater360Capture::capture360Images");
}
diff --git a/indra/newview/llfloateravatar.cpp b/indra/newview/llfloateravatar.cpp
index 31adf5b61e..f888d032ae 100644
--- a/indra/newview/llfloateravatar.cpp
+++ b/indra/newview/llfloateravatar.cpp
@@ -44,17 +44,21 @@ LLFloaterAvatar::LLFloaterAvatar(const LLSD& key)
LLFloaterAvatar::~LLFloaterAvatar()
{
- LLMediaCtrl* avatar_picker = findChild<LLMediaCtrl>("avatar_picker_contents");
- if (avatar_picker)
+ if (mAvatarPicker)
{
- avatar_picker->navigateStop();
- avatar_picker->clearCache(); //images are reloading each time already
- avatar_picker->unloadMediaSource();
+ mAvatarPicker->navigateStop();
+ mAvatarPicker->clearCache(); //images are reloading each time already
+ mAvatarPicker->unloadMediaSource();
}
}
BOOL LLFloaterAvatar::postBuild()
{
+ mAvatarPicker = findChild<LLMediaCtrl>("avatar_picker_contents");
+ if (mAvatarPicker)
+ {
+ mAvatarPicker->clearCache();
+ }
enableResizeCtrls(true, true, false);
return TRUE;
}
diff --git a/indra/newview/llfloateravatar.h b/indra/newview/llfloateravatar.h
index cadc5e4028..76e9372709 100644
--- a/indra/newview/llfloateravatar.h
+++ b/indra/newview/llfloateravatar.h
@@ -29,6 +29,7 @@
#define LL_FLOATER_AVATAR_H
#include "llfloater.h"
+class LLMediaCtrl;
class LLFloaterAvatar:
public LLFloater
@@ -38,6 +39,8 @@ private:
LLFloaterAvatar(const LLSD& key);
/*virtual*/ ~LLFloaterAvatar();
/*virtual*/ BOOL postBuild();
+
+ LLMediaCtrl* mAvatarPicker;
};
#endif
diff --git a/indra/newview/llfloaterbump.cpp b/indra/newview/llfloaterbump.cpp
index 33e4c7cd5f..307ab8c4d1 100644
--- a/indra/newview/llfloaterbump.cpp
+++ b/indra/newview/llfloaterbump.cpp
@@ -69,6 +69,12 @@ LLFloaterBump::LLFloaterBump(const LLSD& key)
// Destroys the object
LLFloaterBump::~LLFloaterBump()
{
+ auto menu = mPopupMenuHandle.get();
+ if (menu)
+ {
+ menu->die();
+ mPopupMenuHandle.markDead();
+ }
}
BOOL LLFloaterBump::postBuild()
@@ -77,11 +83,15 @@ BOOL LLFloaterBump::postBuild()
mList->setAllowMultipleSelection(false);
mList->setRightMouseDownCallback(boost::bind(&LLFloaterBump::onScrollListRightClicked, this, _1, _2, _3));
- mPopupMenu = LLUICtrlFactory::getInstance()->createFromFile<LLContextMenu>("menu_avatar_other.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
- mPopupMenu->setItemVisible(std::string("Normal"), false);
- mPopupMenu->setItemVisible(std::string("Always use impostor"), false);
- mPopupMenu->setItemVisible(std::string("Never use impostor"), false);
- mPopupMenu->setItemVisible(std::string("Impostor seperator"), false);
+ LLContextMenu* menu = LLUICtrlFactory::getInstance()->createFromFile<LLContextMenu>("menu_avatar_other.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
+ if (menu)
+ {
+ mPopupMenuHandle = menu->getHandle();
+ menu->setItemVisible(std::string("Normal"), false);
+ menu->setItemVisible(std::string("Always use impostor"), false);
+ menu->setItemVisible(std::string("Never use impostor"), false);
+ menu->setItemVisible(std::string("Impostor seperator"), false);
+ }
return TRUE;
}
@@ -176,18 +186,19 @@ void LLFloaterBump::onScrollListRightClicked(LLUICtrl* ctrl, S32 x, S32 y)
if (!gMeanCollisionList.empty())
{
LLScrollListItem* item = mList->hitItem(x, y);
- if (item && mPopupMenu)
+ auto menu = mPopupMenuHandle.get();
+ if (item && menu)
{
mItemUUID = item->getUUID();
- mPopupMenu->buildDrawLabels();
- mPopupMenu->updateParent(LLMenuGL::sMenuContainer);
+ menu->buildDrawLabels();
+ menu->updateParent(LLMenuGL::sMenuContainer);
std::string mute_msg = (LLMuteList::getInstance()->isMuted(mItemUUID, mNames[mItemUUID])) ? "UnmuteAvatar" : "MuteAvatar";
- mPopupMenu->getChild<LLUICtrl>("Avatar Mute")->setValue(LLTrans::getString(mute_msg));
- mPopupMenu->setItemEnabled(std::string("Zoom In"), bool(gObjectList.findObject(mItemUUID)));
+ menu->getChild<LLUICtrl>("Avatar Mute")->setValue(LLTrans::getString(mute_msg));
+ menu->setItemEnabled(std::string("Zoom In"), bool(gObjectList.findObject(mItemUUID)));
- ((LLContextMenu*)mPopupMenu)->show(x, y);
- LLMenuGL::showPopup(ctrl, mPopupMenu, x, y);
+ menu->show(x, y);
+ LLMenuGL::showPopup(ctrl, menu, x, y);
}
}
}
diff --git a/indra/newview/llfloaterbump.h b/indra/newview/llfloaterbump.h
index ce52c75255..d2f9fabdd3 100644
--- a/indra/newview/llfloaterbump.h
+++ b/indra/newview/llfloaterbump.h
@@ -68,7 +68,7 @@ private:
virtual ~LLFloaterBump();
LLScrollListCtrl* mList;
- LLMenuGL* mPopupMenu;
+ LLHandle<LLContextMenu> mPopupMenuHandle;
LLUUID mItemUUID;
typedef std::map<LLUUID, std::string> uuid_map_t;
diff --git a/indra/newview/llfloatercreatelandmark.cpp b/indra/newview/llfloatercreatelandmark.cpp
index 7def855d83..b82d8a29ba 100644
--- a/indra/newview/llfloatercreatelandmark.cpp
+++ b/indra/newview/llfloatercreatelandmark.cpp
@@ -316,7 +316,6 @@ void LLFloaterCreateLandmark::onSaveClicked()
LLStringUtil::trim(current_title_value);
LLStringUtil::trim(current_notes_value);
- LLUUID item_id = mItem->getUUID();
LLUUID folder_id = mFolderCombo->getValue().asUUID();
bool change_parent = folder_id != mItem->getParentUUID();
diff --git a/indra/newview/llfloaterimcontainer.cpp b/indra/newview/llfloaterimcontainer.cpp
index 703b5d0011..2720b7fcf7 100644
--- a/indra/newview/llfloaterimcontainer.cpp
+++ b/indra/newview/llfloaterimcontainer.cpp
@@ -211,6 +211,7 @@ BOOL LLFloaterIMContainer::postBuild()
p.options_menu = "menu_conversation.xml";
mConversationsRoot = LLUICtrlFactory::create<LLFolderView>(p);
mConversationsRoot->setCallbackRegistrar(&mCommitCallbackRegistrar);
+ mConversationsRoot->setEnableRegistrar(&mEnableCallbackRegistrar);
// Add listener to conversation model events
mConversationsEventStream.listen("ConversationsRefresh", boost::bind(&LLFloaterIMContainer::onConversationModelEvent, this, _1));
diff --git a/indra/newview/llfloaterimsessiontab.cpp b/indra/newview/llfloaterimsessiontab.cpp
index 204cd03b09..78271369d2 100644
--- a/indra/newview/llfloaterimsessiontab.cpp
+++ b/indra/newview/llfloaterimsessiontab.cpp
@@ -316,6 +316,7 @@ BOOL LLFloaterIMSessionTab::postBuild()
p.name = "root";
mConversationsRoot = LLUICtrlFactory::create<LLFolderView>(p);
mConversationsRoot->setCallbackRegistrar(&mCommitCallbackRegistrar);
+ mConversationsRoot->setEnableRegistrar(&mEnableCallbackRegistrar);
// Attach that root to the scroller
mScroller->addChild(mConversationsRoot);
mConversationsRoot->setScrollContainer(mScroller);
diff --git a/indra/newview/llfloatermodelpreview.cpp b/indra/newview/llfloatermodelpreview.cpp
index cba074b380..c37d8fae53 100644
--- a/indra/newview/llfloatermodelpreview.cpp
+++ b/indra/newview/llfloatermodelpreview.cpp
@@ -1740,7 +1740,7 @@ void LLFloaterModelPreview::toggleCalculateButton(bool visible)
childSetTextArg("download_weight", "[ST]", tbd);
childSetTextArg("server_weight", "[SIM]", tbd);
childSetTextArg("physics_weight", "[PH]", tbd);
- if (!mModelPhysicsFee.isMap() || mModelPhysicsFee.emptyMap())
+ if (!mModelPhysicsFee.isMap() || (mModelPhysicsFee.size() == 0))
{
childSetTextArg("upload_fee", "[FEE]", tbd);
}
diff --git a/indra/newview/llfloateropenobject.cpp b/indra/newview/llfloateropenobject.cpp
index 2a1749bd42..a682064dad 100644
--- a/indra/newview/llfloateropenobject.cpp
+++ b/indra/newview/llfloateropenobject.cpp
@@ -56,8 +56,6 @@ LLFloaterOpenObject::LLFloaterOpenObject(const LLSD& key)
mDirty(TRUE)
{
mCommitCallbackRegistrar.add("OpenObject.MoveToInventory", boost::bind(&LLFloaterOpenObject::onClickMoveToInventory, this));
- mCommitCallbackRegistrar.add("OpenObject.MoveAndWear", boost::bind(&LLFloaterOpenObject::onClickMoveAndWear, this));
- mCommitCallbackRegistrar.add("OpenObject.ReplaceOutfit", boost::bind(&LLFloaterOpenObject::onClickReplace, this));
mCommitCallbackRegistrar.add("OpenObject.Cancel", boost::bind(&LLFloaterOpenObject::onClickCancel, this));
}
@@ -243,18 +241,6 @@ void LLFloaterOpenObject::onClickMoveToInventory()
closeFloater();
}
-void LLFloaterOpenObject::onClickMoveAndWear()
-{
- moveToInventory(true, false);
- closeFloater();
-}
-
-void LLFloaterOpenObject::onClickReplace()
-{
- moveToInventory(true, true);
- closeFloater();
-}
-
void LLFloaterOpenObject::onClickCancel()
{
closeFloater();
diff --git a/indra/newview/llfloateropenobject.h b/indra/newview/llfloateropenobject.h
index 2e761f99bf..745753316b 100644
--- a/indra/newview/llfloateropenobject.h
+++ b/indra/newview/llfloateropenobject.h
@@ -63,8 +63,6 @@ protected:
void moveToInventory(bool wear, bool replace = false);
void onClickMoveToInventory();
- void onClickMoveAndWear();
- void onClickReplace();
void onClickCancel();
static void callbackCreateInventoryCategory(const LLUUID& category_id, LLUUID object_id, bool wear, bool replace = false);
static void callbackMoveInventory(S32 result, void* data);
diff --git a/indra/newview/llfloateroutfitphotopreview.cpp b/indra/newview/llfloateroutfitphotopreview.cpp
index 6c39db730c..ade258aef7 100644
--- a/indra/newview/llfloateroutfitphotopreview.cpp
+++ b/indra/newview/llfloateroutfitphotopreview.cpp
@@ -234,7 +234,6 @@ void LLFloaterOutfitPhotoPreview::updateImageID()
if(item)
{
mImageID = item->getAssetUUID();
- LLPermissions perm(item->getPermissions());
}
else
{
diff --git a/indra/newview/llfloaterpathfindinglinksets.cpp b/indra/newview/llfloaterpathfindinglinksets.cpp
index 1e46d7a402..03aede94c6 100644
--- a/indra/newview/llfloaterpathfindinglinksets.cpp
+++ b/indra/newview/llfloaterpathfindinglinksets.cpp
@@ -44,6 +44,7 @@
#include "llpathfindinglinkset.h"
#include "llpathfindinglinksetlist.h"
#include "llpathfindingmanager.h"
+#include "llsearcheditor.h"
#include "llscrolllistitem.h"
#include "llsd.h"
#include "lltextbase.h"
@@ -114,17 +115,13 @@ BOOL LLFloaterPathfindingLinksets::postBuild()
{
mBeaconColor = LLUIColorTable::getInstance()->getColor("PathfindingLinksetBeaconColor");
- mFilterByName = findChild<LLLineEditor>("filter_by_name");
- llassert(mFilterByName != NULL);
- mFilterByName->setCommitCallback(boost::bind(&LLFloaterPathfindingLinksets::onApplyAllFilters, this));
- mFilterByName->setSelectAllonFocusReceived(true);
- mFilterByName->setCommitOnFocusLost(true);
-
- mFilterByDescription = findChild<LLLineEditor>("filter_by_description");
- llassert(mFilterByDescription != NULL);
- mFilterByDescription->setCommitCallback(boost::bind(&LLFloaterPathfindingLinksets::onApplyAllFilters, this));
- mFilterByDescription->setSelectAllonFocusReceived(true);
- mFilterByDescription->setCommitOnFocusLost(true);
+ mFilterByName = getChild<LLSearchEditor>("filter_by_name");
+ mFilterByName->setCommitCallback(boost::bind(&LLFloaterPathfindingLinksets::onApplyAllFilters, this));
+ mFilterByName->setCommitOnFocusLost(true);
+
+ mFilterByDescription = getChild<LLSearchEditor>("filter_by_description");
+ mFilterByDescription->setCommitCallback(boost::bind(&LLFloaterPathfindingLinksets::onApplyAllFilters, this));
+ mFilterByDescription->setCommitOnFocusLost(true);
mFilterByLinksetUse = findChild<LLComboBox>("filter_by_linkset_use");
llassert(mFilterByLinksetUse != NULL);
diff --git a/indra/newview/llfloaterpathfindinglinksets.h b/indra/newview/llfloaterpathfindinglinksets.h
index 7149da9215..a954d8a8ec 100644
--- a/indra/newview/llfloaterpathfindinglinksets.h
+++ b/indra/newview/llfloaterpathfindinglinksets.h
@@ -42,6 +42,7 @@ class LLSD;
class LLTextBase;
class LLUICtrl;
class LLVector3;
+class LLSearchEditor;
class LLFloaterPathfindingLinksets : public LLFloaterPathfindingObjects
{
@@ -105,8 +106,8 @@ private:
LLPathfindingLinkset::ELinksetUse convertToLinksetUse(LLSD pXuiValue) const;
LLSD convertToXuiValue(LLPathfindingLinkset::ELinksetUse pLinksetUse) const;
- LLLineEditor *mFilterByName;
- LLLineEditor *mFilterByDescription;
+ LLSearchEditor *mFilterByName;
+ LLSearchEditor *mFilterByDescription;
LLComboBox *mFilterByLinksetUse;
LLComboBox *mEditLinksetUse;
LLScrollListItem *mEditLinksetUseUnset;
diff --git a/indra/newview/llfloaterscriptlimits.cpp b/indra/newview/llfloaterscriptlimits.cpp
index 3746b9b6c2..40fe11b309 100644
--- a/indra/newview/llfloaterscriptlimits.cpp
+++ b/indra/newview/llfloaterscriptlimits.cpp
@@ -421,7 +421,6 @@ void LLPanelScriptLimitsRegionMemory::setRegionDetails(LLSD content)
for(S32 i = 0; i < number_parcels; i++)
{
std::string parcel_name = content["parcels"][i]["name"].asString();
- LLUUID parcel_id = content["parcels"][i]["id"].asUUID();
S32 number_objects = content["parcels"][i]["objects"].size();
S32 local_id = 0;
diff --git a/indra/newview/llfloatersearch.cpp b/indra/newview/llfloatersearch.cpp
index bb3ed77772..7e6af45515 100644
--- a/indra/newview/llfloatersearch.cpp
+++ b/indra/newview/llfloatersearch.cpp
@@ -45,7 +45,7 @@ class LLSearchHandler : public LLCommandHandler
{
public:
// requires trusted browser to trigger
- LLSearchHandler() : LLCommandHandler("search", UNTRUSTED_THROTTLE) { }
+ LLSearchHandler() : LLCommandHandler("search", UNTRUSTED_CLICK_ONLY) { }
bool handle(const LLSD& tokens, const LLSD& query_map, LLMediaCtrl* web)
{
if (!LLUI::getInstance()->mSettingGroups["config"]->getBOOL("EnableSearch"))
diff --git a/indra/newview/llfloatersettingsdebug.cpp b/indra/newview/llfloatersettingsdebug.cpp
index 186994c857..3c7f341613 100644
--- a/indra/newview/llfloatersettingsdebug.cpp
+++ b/indra/newview/llfloatersettingsdebug.cpp
@@ -2,9 +2,9 @@
* @file llfloatersettingsdebug.cpp
* @brief floater for debugging internal viewer settings
*
- * $LicenseInfo:firstyear=2001&license=viewerlgpl$
+ * $LicenseInfo:firstyear=2022&license=viewerlgpl$
* Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
+ * Copyright (C) 2022, 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
@@ -27,8 +27,8 @@
#include "llviewerprecompiledheaders.h"
#include "llfloatersettingsdebug.h"
#include "llfloater.h"
+#include "llfiltereditor.h"
#include "lluictrlfactory.h"
-//#include "llfirstuse.h"
#include "llcombobox.h"
#include "llspinctrl.h"
#include "llcolorswatch.h"
@@ -37,12 +37,11 @@
LLFloaterSettingsDebug::LLFloaterSettingsDebug(const LLSD& key)
-: LLFloater(key)
+: LLFloater(key),
+ mSettingList(NULL)
{
- mCommitCallbackRegistrar.add("SettingSelect", boost::bind(&LLFloaterSettingsDebug::onSettingSelect, this,_1));
mCommitCallbackRegistrar.add("CommitSettings", boost::bind(&LLFloaterSettingsDebug::onCommitSettings, this));
mCommitCallbackRegistrar.add("ClickDefault", boost::bind(&LLFloaterSettingsDebug::onClickDefault, this));
-
}
LLFloaterSettingsDebug::~LLFloaterSettingsDebug()
@@ -50,59 +49,43 @@ LLFloaterSettingsDebug::~LLFloaterSettingsDebug()
BOOL LLFloaterSettingsDebug::postBuild()
{
- LLComboBox* settings_combo = getChild<LLComboBox>("settings_combo");
+ enableResizeCtrls(true, false, true);
- struct f : public LLControlGroup::ApplyFunctor
- {
- LLComboBox* combo;
- f(LLComboBox* c) : combo(c) {}
- virtual void apply(const std::string& name, LLControlVariable* control)
- {
- if (!control->isHiddenFromSettingsEditor())
- {
- combo->add(name, (void*)control);
- }
- }
- } func(settings_combo);
+ mComment = getChild<LLTextEditor>("comment_text");
- std::string key = getKey().asString();
- if (key == "all" || key == "base")
- {
- gSavedSettings.applyToAll(&func);
- }
- if (key == "all" || key == "account")
- {
- gSavedPerAccountSettings.applyToAll(&func);
- }
+ getChild<LLFilterEditor>("filter_input")->setCommitCallback(boost::bind(&LLFloaterSettingsDebug::setSearchFilter, this, _2));
+
+ mSettingList = getChild<LLScrollListCtrl>("setting_list");
+ mSettingList->setCommitOnSelectionChange(TRUE);
+ mSettingList->setCommitCallback(boost::bind(&LLFloaterSettingsDebug::onSettingSelect, this));
+
+ updateList();
+
+ gSavedSettings.getControl("DebugSettingsHideDefault")->getCommitSignal()->connect(boost::bind(&LLFloaterSettingsDebug::updateList, this, false));
- settings_combo->sortByName();
- settings_combo->updateSelection();
- mComment = getChild<LLTextEditor>("comment_text");
return TRUE;
}
void LLFloaterSettingsDebug::draw()
{
- LLComboBox* settings_combo = getChild<LLComboBox>("settings_combo");
- LLControlVariable* controlp = (LLControlVariable*)settings_combo->getCurrentUserdata();
- updateControl(controlp);
+ LLScrollListItem* first_selected = mSettingList->getFirstSelected();
+ if (first_selected)
+ {
+ LLControlVariable* controlp = (LLControlVariable*)first_selected->getUserdata();
+ updateControl(controlp);
+ }
LLFloater::draw();
}
-//static
-void LLFloaterSettingsDebug::onSettingSelect(LLUICtrl* ctrl)
-{
- LLComboBox* combo_box = (LLComboBox*)ctrl;
- LLControlVariable* controlp = (LLControlVariable*)combo_box->getCurrentUserdata();
-
- updateControl(controlp);
-}
-
void LLFloaterSettingsDebug::onCommitSettings()
{
- LLComboBox* settings_combo = getChild<LLComboBox>("settings_combo");
- LLControlVariable* controlp = (LLControlVariable*)settings_combo->getCurrentUserdata();
+ LLScrollListItem* first_selected = mSettingList->getFirstSelected();
+ if (!first_selected)
+ {
+ return;
+ }
+ LLControlVariable* controlp = (LLControlVariable*)first_selected->getUserdata();
if (!controlp)
{
@@ -176,19 +159,23 @@ void LLFloaterSettingsDebug::onCommitSettings()
default:
break;
}
+ updateDefaultColumn(controlp);
}
// static
void LLFloaterSettingsDebug::onClickDefault()
{
- LLComboBox* settings_combo = getChild<LLComboBox>("settings_combo");
- LLControlVariable* controlp = (LLControlVariable*)settings_combo->getCurrentUserdata();
-
- if (controlp)
- {
- controlp->resetToDefault(true);
- updateControl(controlp);
- }
+ LLScrollListItem* first_selected = mSettingList->getFirstSelected();
+ if (first_selected)
+ {
+ LLControlVariable* controlp = (LLControlVariable*)first_selected->getUserdata();
+ if (controlp)
+ {
+ controlp->resetToDefault(true);
+ updateDefaultColumn(controlp);
+ updateControl(controlp);
+ }
+ }
}
// we've switched controls, or doing per-frame update, so update spinners, etc.
@@ -207,23 +194,30 @@ void LLFloaterSettingsDebug::updateControl(LLControlVariable* controlp)
return;
}
- spinner1->setVisible(FALSE);
- spinner2->setVisible(FALSE);
- spinner3->setVisible(FALSE);
- spinner4->setVisible(FALSE);
- color_swatch->setVisible(FALSE);
- getChildView("val_text")->setVisible( FALSE);
- mComment->setText(LLStringUtil::null);
+ hideUIControls();
- if (controlp)
+ if (controlp && !isSettingHidden(controlp))
{
eControlType type = controlp->type();
//hide combo box only for non booleans, otherwise this will result in the combo box closing every frame
getChildView("boolean_combo")->setVisible( type == TYPE_BOOLEAN);
-
+ getChildView("default_btn")->setVisible(true);
+ getChildView("setting_name_txt")->setVisible(true);
+ getChild<LLTextBox>("setting_name_txt")->setText(controlp->getName());
+ getChild<LLTextBox>("setting_name_txt")->setToolTip(controlp->getName());
+ mComment->setVisible(true);
+
+ std::string old_text = mComment->getText();
+ std::string new_text = controlp->getComment();
+ // Don't setText if not nessesary, it will reset scroll
+ // This is a debug UI that reads from xml, there might
+ // be use cases where comment changes, but not the name
+ if (old_text != new_text)
+ {
+ mComment->setText(controlp->getComment());
+ }
- mComment->setText(controlp->getComment());
spinner1->setMaxValue(F32_MAX);
spinner2->setMaxValue(F32_MAX);
spinner3->setMaxValue(F32_MAX);
@@ -479,3 +473,166 @@ void LLFloaterSettingsDebug::updateControl(LLControlVariable* controlp)
}
}
+
+void LLFloaterSettingsDebug::updateList(bool skip_selection)
+{
+ std::string last_selected;
+ LLScrollListItem* item = mSettingList->getFirstSelected();
+ if (item)
+ {
+ LLScrollListCell* cell = item->getColumn(1);
+ if (cell)
+ {
+ last_selected = cell->getValue().asString();
+ }
+ }
+
+ mSettingList->deleteAllItems();
+ struct f : public LLControlGroup::ApplyFunctor
+ {
+ LLScrollListCtrl* setting_list;
+ LLFloaterSettingsDebug* floater;
+ std::string selected_setting;
+ bool skip_selection;
+ f(LLScrollListCtrl* list, LLFloaterSettingsDebug* floater, std::string setting, bool skip_selection)
+ : setting_list(list), floater(floater), selected_setting(setting), skip_selection(skip_selection) {}
+ virtual void apply(const std::string& name, LLControlVariable* control)
+ {
+ if (!control->isHiddenFromSettingsEditor() && floater->matchesSearchFilter(name) && !floater->isSettingHidden(control))
+ {
+ LLSD row;
+
+ row["columns"][0]["column"] = "changed_setting";
+ row["columns"][0]["value"] = control->isDefault() ? "" : "*";
+
+ row["columns"][1]["column"] = "setting";
+ row["columns"][1]["value"] = name;
+
+ LLScrollListItem* item = setting_list->addElement(row, ADD_BOTTOM, (void*)control);
+ if (!floater->mSearchFilter.empty() && (selected_setting == name) && !skip_selection)
+ {
+ std::string lower_name(name);
+ LLStringUtil::toLower(lower_name);
+ if (LLStringUtil::startsWith(lower_name, floater->mSearchFilter))
+ {
+ item->setSelected(true);
+ }
+ }
+ }
+ }
+ } func(mSettingList, this, last_selected, skip_selection);
+
+ std::string key = getKey().asString();
+ if (key == "all" || key == "base")
+ {
+ gSavedSettings.applyToAll(&func);
+ }
+ if (key == "all" || key == "account")
+ {
+ gSavedPerAccountSettings.applyToAll(&func);
+ }
+
+
+ if (!mSettingList->isEmpty())
+ {
+ if (mSettingList->hasSelectedItem())
+ {
+ mSettingList->scrollToShowSelected();
+ }
+ else if (!mSettingList->hasSelectedItem() && !mSearchFilter.empty() && !skip_selection)
+ {
+ if (!mSettingList->selectItemByPrefix(mSearchFilter, false, 1))
+ {
+ mSettingList->selectFirstItem();
+ }
+ mSettingList->scrollToShowSelected();
+ }
+ }
+ else
+ {
+ LLSD row;
+
+ row["columns"][0]["column"] = "changed_setting";
+ row["columns"][0]["value"] = "";
+ row["columns"][1]["column"] = "setting";
+ row["columns"][1]["value"] = "No matching settings.";
+
+ mSettingList->addElement(row);
+ hideUIControls();
+ }
+}
+
+void LLFloaterSettingsDebug::onSettingSelect()
+{
+ LLScrollListItem* first_selected = mSettingList->getFirstSelected();
+ if (first_selected)
+ {
+ LLControlVariable* controlp = (LLControlVariable*)first_selected->getUserdata();
+ if (controlp)
+ {
+ updateControl(controlp);
+ }
+ }
+}
+
+void LLFloaterSettingsDebug::setSearchFilter(const std::string& filter)
+{
+ if(mSearchFilter == filter)
+ return;
+ mSearchFilter = filter;
+ LLStringUtil::toLower(mSearchFilter);
+ updateList();
+}
+
+bool LLFloaterSettingsDebug::matchesSearchFilter(std::string setting_name)
+{
+ // If the search filter is empty, everything passes.
+ if (mSearchFilter.empty()) return true;
+
+ LLStringUtil::toLower(setting_name);
+ std::string::size_type match_name = setting_name.find(mSearchFilter);
+
+ return (std::string::npos != match_name);
+}
+
+bool LLFloaterSettingsDebug::isSettingHidden(LLControlVariable* control)
+{
+ static LLCachedControl<bool> hide_default(gSavedSettings, "DebugSettingsHideDefault", false);
+ return hide_default && control->isDefault();
+}
+
+void LLFloaterSettingsDebug::updateDefaultColumn(LLControlVariable* control)
+{
+ if (isSettingHidden(control))
+ {
+ hideUIControls();
+ updateList(true);
+ return;
+ }
+
+ LLScrollListItem* item = mSettingList->getFirstSelected();
+ if (item)
+ {
+ LLScrollListCell* cell = item->getColumn(0);
+ if (cell)
+ {
+ std::string is_default = control->isDefault() ? "" : "*";
+ cell->setValue(is_default);
+ }
+ }
+}
+
+void LLFloaterSettingsDebug::hideUIControls()
+{
+ getChildView("val_spinner_1")->setVisible(false);
+ getChildView("val_spinner_2")->setVisible(false);
+ getChildView("val_spinner_3")->setVisible(false);
+ getChildView("val_spinner_4")->setVisible(false);
+ getChildView("val_color_swatch")->setVisible(false);
+ getChildView("val_text")->setVisible(false);
+ getChildView("default_btn")->setVisible(false);
+ getChildView("boolean_combo")->setVisible(false);
+ getChildView("setting_name_txt")->setVisible(false);
+ mComment->setVisible(false);
+}
+
diff --git a/indra/newview/llfloatersettingsdebug.h b/indra/newview/llfloatersettingsdebug.h
index f07e0557e3..888eaadcbd 100644
--- a/indra/newview/llfloatersettingsdebug.h
+++ b/indra/newview/llfloatersettingsdebug.h
@@ -2,9 +2,9 @@
* @file llfloatersettingsdebug.h
* @brief floater for debugging internal viewer settings
*
- * $LicenseInfo:firstyear=2001&license=viewerlgpl$
+ * $LicenseInfo:firstyear=2022&license=viewerlgpl$
* Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
+ * Copyright (C) 2022, 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
@@ -30,6 +30,8 @@
#include "llcontrol.h"
#include "llfloater.h"
+class LLScrollListCtrl;
+
class LLFloaterSettingsDebug
: public LLFloater
{
@@ -42,18 +44,31 @@ public:
void updateControl(LLControlVariable* control);
- void onSettingSelect(LLUICtrl* ctrl);
void onCommitSettings();
void onClickDefault();
+ bool matchesSearchFilter(std::string setting_name);
+ bool isSettingHidden(LLControlVariable* control);
+
private:
// key - selects which settings to show, one of:
// "all", "base", "account", "skin"
LLFloaterSettingsDebug(const LLSD& key);
virtual ~LLFloaterSettingsDebug();
+
+ void updateList(bool skip_selection = false);
+ void onSettingSelect();
+ void setSearchFilter(const std::string& filter);
+
+ void updateDefaultColumn(LLControlVariable* control);
+ void hideUIControls();
+
+ LLScrollListCtrl* mSettingList;
protected:
class LLTextEditor* mComment;
+
+ std::string mSearchFilter;
};
#endif //LLFLOATERDEBUGSETTINGS_H
diff --git a/indra/newview/llfloaterworldmap.cpp b/indra/newview/llfloaterworldmap.cpp
index 01bfae8934..704abd269f 100755
--- a/indra/newview/llfloaterworldmap.cpp
+++ b/indra/newview/llfloaterworldmap.cpp
@@ -122,7 +122,7 @@ class LLWorldMapHandler : public LLCommandHandler
{
public:
// requires trusted browser to trigger
- LLWorldMapHandler() : LLCommandHandler("worldmap", UNTRUSTED_THROTTLE ) { }
+ LLWorldMapHandler() : LLCommandHandler("worldmap", UNTRUSTED_CLICK_ONLY ) { }
bool handle(const LLSD& params, const LLSD& query_map,
LLMediaCtrl* web)
@@ -159,7 +159,7 @@ class LLMapTrackAvatarHandler : public LLCommandHandler
{
public:
// requires trusted browser to trigger
- LLMapTrackAvatarHandler() : LLCommandHandler("maptrackavatar", UNTRUSTED_THROTTLE)
+ LLMapTrackAvatarHandler() : LLCommandHandler("maptrackavatar", UNTRUSTED_CLICK_ONLY)
{
}
diff --git a/indra/newview/llgroupactions.cpp b/indra/newview/llgroupactions.cpp
index dbeb157323..be52e280e1 100644
--- a/indra/newview/llgroupactions.cpp
+++ b/indra/newview/llgroupactions.cpp
@@ -52,7 +52,32 @@ class LLGroupHandler : public LLCommandHandler
{
public:
// requires trusted browser to trigger
- LLGroupHandler() : LLCommandHandler("group", UNTRUSTED_THROTTLE) { }
+ LLGroupHandler() : LLCommandHandler("group", UNTRUSTED_CLICK_ONLY) { }
+
+ virtual bool canHandleUntrusted(
+ const LLSD& params,
+ const LLSD& query_map,
+ LLMediaCtrl* web,
+ const std::string& nav_type)
+ {
+ if (params.size() < 1)
+ {
+ return true; // don't block, will fail later
+ }
+
+ if (nav_type == NAV_TYPE_CLICKED)
+ {
+ return true;
+ }
+
+ const std::string verb = params[0].asString();
+ if (verb == "create")
+ {
+ return false;
+ }
+ return true;
+ }
+
bool handle(const LLSD& tokens, const LLSD& query_map,
LLMediaCtrl* web)
{
diff --git a/indra/newview/llimprocessing.cpp b/indra/newview/llimprocessing.cpp
index e6845127e3..af2d168aef 100644
--- a/indra/newview/llimprocessing.cpp
+++ b/indra/newview/llimprocessing.cpp
@@ -1568,7 +1568,7 @@ void LLIMProcessing::requestOfflineMessagesCoro(std::string url)
return;
}
- if (messages.emptyArray())
+ if (messages.size() == 0)
{
// Nothing to process
return;
diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp
index bf9e226244..3607e49b4a 100644
--- a/indra/newview/llimview.cpp
+++ b/indra/newview/llimview.cpp
@@ -2115,8 +2115,6 @@ void LLOutgoingCallDialog::show(const LLSD& key)
std::string callee_name = mPayload["session_name"].asString();
- LLUUID session_id = mPayload["session_id"].asUUID();
-
if (callee_name == "anonymous") // obsolete? Likely was part of avaline support
{
callee_name = getString("anonymous");
@@ -2500,7 +2498,7 @@ void LLIncomingCallDialog::processCallResponse(S32 response, const LLSD &payload
}
}
- LLUUID new_session_id = gIMMgr->addSession(correct_session_name, type, session_id, true);
+ gIMMgr->addSession(correct_session_name, type, session_id, true);
std::string url = gAgent.getRegion()->getCapability(
"ChatSessionRequest");
@@ -2586,7 +2584,7 @@ bool inviteUserResponse(const LLSD& notification, const LLSD& response)
}
else
{
- LLUUID new_session_id = gIMMgr->addSession(
+ gIMMgr->addSession(
payload["session_name"].asString(),
type,
session_id, true);
diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp
index 141dc20d92..2665cb1b92 100644
--- a/indra/newview/llinventorybridge.cpp
+++ b/indra/newview/llinventorybridge.cpp
@@ -834,6 +834,12 @@ void LLInvFVBridge::getClipboardEntries(bool show_asset_id,
{
disabled_items.push_back(std::string("Find Original"));
}
+
+ items.push_back(std::string("Cut"));
+ if (!isItemMovable() || !isItemRemovable())
+ {
+ disabled_items.push_back(std::string("Cut"));
+ }
}
else
{
@@ -2154,6 +2160,7 @@ bool LLItemBridge::isItemCopyable(bool can_copy_as_link) const
static LLCachedControl<bool> inventory_linking(gSavedSettings, "InventoryLinking", true);
return (can_copy_as_link && inventory_linking)
+ || (mIsLink && inventory_linking)
|| item->getPermissions().allowCopyBy(gAgent.getID());
}
@@ -2360,6 +2367,12 @@ BOOL LLFolderBridge::isUpToDate() const
bool LLFolderBridge::isItemCopyable(bool can_copy_as_link) const
{
+ if (can_copy_as_link && !LLFolderType::lookupIsProtectedType(getPreferredType()))
+ {
+ // Can copy and paste unprotected folders as links
+ return true;
+ }
+
// Folders are copyable if items in them are, recursively, copyable.
// Get the content of the folder
diff --git a/indra/newview/llinventoryfilter.cpp b/indra/newview/llinventoryfilter.cpp
index f7dc493109..374790b917 100644
--- a/indra/newview/llinventoryfilter.cpp
+++ b/indra/newview/llinventoryfilter.cpp
@@ -437,7 +437,6 @@ bool LLInventoryFilter::checkAgainstFilterType(const LLFolderViewModelItemInvent
bool LLInventoryFilter::checkAgainstFilterType(const LLInventoryItem* item) const
{
LLInventoryType::EType object_type = item->getInventoryType();
- const LLUUID object_id = item->getUUID();
const U32 filterTypes = mFilterOps.mFilterTypes;
diff --git a/indra/newview/llinventoryfunctions.cpp b/indra/newview/llinventoryfunctions.cpp
index 5755bc692e..af1c93f383 100644
--- a/indra/newview/llinventoryfunctions.cpp
+++ b/indra/newview/llinventoryfunctions.cpp
@@ -1406,9 +1406,6 @@ bool move_item_to_marketplacelistings(LLInventoryItem* inv_item, LLUUID dest_fol
LLNotificationsUtil::add("MerchantPasteFailed", subs);
return false;
}
-
- // Get the parent folder of the moved item : we may have to update it
- LLUUID src_folder = viewer_inv_item->getParentUUID();
if (copy)
{
diff --git a/indra/newview/llinventorylistitem.h b/indra/newview/llinventorylistitem.h
index d4dd212cc3..cf713a6930 100644
--- a/indra/newview/llinventorylistitem.h
+++ b/indra/newview/llinventorylistitem.h
@@ -197,6 +197,7 @@ protected:
virtual BOOL handleToolTip( S32 x, S32 y, MASK mask);
const LLUUID mInventoryItemUUID;
+ bool mHovered;
private:
@@ -221,7 +222,6 @@ private:
LLUIImagePtr mSelectedImage;
LLUIImagePtr mSeparatorImage;
- bool mHovered;
bool mSelected;
bool mSeparatorVisible;
diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp
index e5c9ec927a..75dda5557d 100644
--- a/indra/newview/llinventorymodel.cpp
+++ b/indra/newview/llinventorymodel.cpp
@@ -1694,11 +1694,11 @@ void LLInventoryModel::deleteObject(const LLUUID& id, bool fix_broken_links, boo
// Can't have links to links, so there's no need for this update
// if the item removed is a link. Can also skip if source of the
// update is getting broken link info separately.
- obj = NULL; // delete obj
if (fix_broken_links && !is_link_type)
{
updateLinkedObjectsFromPurge(id);
}
+ obj = nullptr; // delete obj
if (do_notify_observers)
{
notifyObservers();
@@ -2718,7 +2718,6 @@ void LLInventoryModel::buildParentChildMap()
// some accounts has pbroken inventory root folders
std::string name = "My Inventory";
- LLUUID prev_root_id = mRootFolderID;
for (parent_cat_map_t::const_iterator it = mParentChildCategoryTree.begin(),
it_end = mParentChildCategoryTree.end(); it != it_end; ++it)
{
diff --git a/indra/newview/llinventorypanel.cpp b/indra/newview/llinventorypanel.cpp
index bc035fc2f6..7e5a2b3950 100644
--- a/indra/newview/llinventorypanel.cpp
+++ b/indra/newview/llinventorypanel.cpp
@@ -211,7 +211,11 @@ LLFolderView * LLInventoryPanel::createFolderRoot(LLUUID root_id )
p.allow_drop = mParams.allow_drop_on_root;
p.options_menu = "menu_inventory.xml";
- return LLUICtrlFactory::create<LLFolderView>(p);
+ LLFolderView* fv = LLUICtrlFactory::create<LLFolderView>(p);
+ fv->setCallbackRegistrar(&mCommitCallbackRegistrar);
+ fv->setEnableRegistrar(&mEnableCallbackRegistrar);
+
+ return fv;
}
void LLInventoryPanel::clearFolderRoot()
@@ -264,6 +268,7 @@ void LLInventoryPanel::initFromParams(const LLInventoryPanel::Params& params)
}
mCommitCallbackRegistrar.popScope();
mFolderRoot.get()->setCallbackRegistrar(&mCommitCallbackRegistrar);
+ mFolderRoot.get()->setEnableRegistrar(&mEnableCallbackRegistrar);
// Scroller
LLRect scroller_view_rect = getRect();
diff --git a/indra/newview/llkeyconflict.cpp b/indra/newview/llkeyconflict.cpp
index d3ba18525b..60f8aca94c 100644
--- a/indra/newview/llkeyconflict.cpp
+++ b/indra/newview/llkeyconflict.cpp
@@ -171,8 +171,9 @@ bool LLKeyConflictHandler::isReservedByMenu(const KEY &key, const MASK &mask)
{
return false;
}
- return (gMenuBarView && gMenuBarView->hasAccelerator(key, mask))
- || (gLoginMenuBarView && gLoginMenuBarView->hasAccelerator(key, mask));
+ // At the moment controls are only applicable inworld,
+ // ignore gLoginMenuBarView
+ return gMenuBarView && gMenuBarView->hasAccelerator(key, mask);
}
// static
@@ -182,8 +183,7 @@ bool LLKeyConflictHandler::isReservedByMenu(const LLKeyData &data)
{
return false;
}
- return (gMenuBarView && gMenuBarView->hasAccelerator(data.mKey, data.mMask))
- || (gLoginMenuBarView && gLoginMenuBarView->hasAccelerator(data.mKey, data.mMask));
+ return gMenuBarView && gMenuBarView->hasAccelerator(data.mKey, data.mMask);
}
bool LLKeyConflictHandler::registerControl(const std::string &control_name, U32 index, EMouseClickType mouse, KEY key, MASK mask, bool ignore_mask)
diff --git a/indra/newview/lllistcontextmenu.cpp b/indra/newview/lllistcontextmenu.cpp
index 6bda8b1d0d..77185411c5 100644
--- a/indra/newview/lllistcontextmenu.cpp
+++ b/indra/newview/lllistcontextmenu.cpp
@@ -51,6 +51,7 @@ LLListContextMenu::~LLListContextMenu()
if (!mMenuHandle.isDead())
{
mMenuHandle.get()->die();
+ mMenuHandle.markDead();
}
}
@@ -59,13 +60,8 @@ void LLListContextMenu::show(LLView* spawning_view, const uuid_vec_t& uuids, S32
LLContextMenu* menup = mMenuHandle.get();
if (menup)
{
- //preventing parent (menu holder) from deleting already "dead" context menus on exit
- LLView* parent = menup->getParent();
- if (parent)
- {
- parent->removeChild(menup);
- }
- delete menup;
+ menup->die();
+ mMenuHandle.markDead();
mUUIDs.clear();
}
diff --git a/indra/newview/llmaterialmgr.cpp b/indra/newview/llmaterialmgr.cpp
index 27a9758ec3..3b59b2f05e 100644
--- a/indra/newview/llmaterialmgr.cpp
+++ b/indra/newview/llmaterialmgr.cpp
@@ -428,12 +428,10 @@ void LLMaterialMgr::onGetResponse(bool success, const LLSD& content, const LLUUI
llassert(content.has(MATERIALS_CAP_ZIP_FIELD));
llassert(content[MATERIALS_CAP_ZIP_FIELD].isBinary());
- LLSD::Binary content_binary = content[MATERIALS_CAP_ZIP_FIELD].asBinary();
- std::string content_string(reinterpret_cast<const char*>(content_binary.data()), content_binary.size());
- std::istringstream content_stream(content_string);
+ const LLSD::Binary& content_binary = content[MATERIALS_CAP_ZIP_FIELD].asBinary();
LLSD response_data;
- U32 uzip_result = LLUZipHelper::unzip_llsd(response_data, content_stream, content_binary.size());
+ U32 uzip_result = LLUZipHelper::unzip_llsd(response_data, content_binary.data(), content_binary.size());
if (uzip_result != LLUZipHelper::ZR_OK)
{
LL_WARNS("Materials") << "Cannot unzip LLSD binary content: " << uzip_result << LL_ENDL;
@@ -471,12 +469,10 @@ void LLMaterialMgr::onGetAllResponse(bool success, const LLSD& content, const LL
llassert(content.has(MATERIALS_CAP_ZIP_FIELD));
llassert(content[MATERIALS_CAP_ZIP_FIELD].isBinary());
- LLSD::Binary content_binary = content[MATERIALS_CAP_ZIP_FIELD].asBinary();
- std::string content_string(reinterpret_cast<const char*>(content_binary.data()), content_binary.size());
- std::istringstream content_stream(content_string);
+ const LLSD::Binary& content_binary = content[MATERIALS_CAP_ZIP_FIELD].asBinary();
LLSD response_data;
- U32 uzip_result = LLUZipHelper::unzip_llsd(response_data, content_stream, content_binary.size());
+ U32 uzip_result = LLUZipHelper::unzip_llsd(response_data, content_binary.data(), content_binary.size());
if (uzip_result != LLUZipHelper::ZR_OK)
{
LL_WARNS("Materials") << "Cannot unzip LLSD binary content: " << uzip_result << LL_ENDL;
@@ -540,12 +536,10 @@ void LLMaterialMgr::onPutResponse(bool success, const LLSD& content)
llassert(content.has(MATERIALS_CAP_ZIP_FIELD));
llassert(content[MATERIALS_CAP_ZIP_FIELD].isBinary());
- LLSD::Binary content_binary = content[MATERIALS_CAP_ZIP_FIELD].asBinary();
- std::string content_string(reinterpret_cast<const char*>(content_binary.data()), content_binary.size());
- std::istringstream content_stream(content_string);
+ const LLSD::Binary& content_binary = content[MATERIALS_CAP_ZIP_FIELD].asBinary();
LLSD response_data;
- U32 uzip_result = LLUZipHelper::unzip_llsd(response_data, content_stream, content_binary.size());
+ U32 uzip_result = LLUZipHelper::unzip_llsd(response_data, content_binary.data(), content_binary.size());
if (uzip_result != LLUZipHelper::ZR_OK)
{
LL_WARNS("Materials") << "Cannot unzip LLSD binary content: " << uzip_result << LL_ENDL;
@@ -665,8 +659,8 @@ void LLMaterialMgr::processGetQueue()
{
material_queue_t::iterator itMaterial = loopMaterial++;
materialsData.append((*itMaterial).asLLSD());
- materials.erase(itMaterial);
markGetPending(region_id, *itMaterial);
+ materials.erase(itMaterial);
}
if (materials.empty())
{
diff --git a/indra/newview/llmediactrl.cpp b/indra/newview/llmediactrl.cpp
index 9142aadab9..36ac1bdf97 100644
--- a/indra/newview/llmediactrl.cpp
+++ b/indra/newview/llmediactrl.cpp
@@ -106,7 +106,6 @@ LLMediaCtrl::LLMediaCtrl( const Params& p) :
mTrusted(p.trusted_content),
mWindowShade(NULL),
mHoverTextChanged(false),
- mContextMenu(NULL),
mAllowFileDownload(false)
{
{
@@ -151,6 +150,13 @@ LLMediaCtrl::LLMediaCtrl( const Params& p) :
LLMediaCtrl::~LLMediaCtrl()
{
+ auto menu = mContextMenuHandle.get();
+ if (menu)
+ {
+ menu->die();
+ mContextMenuHandle.markDead();
+ }
+
if (mMediaSource)
{
mMediaSource->remObserver( this );
@@ -336,15 +342,33 @@ BOOL LLMediaCtrl::handleRightMouseDown( S32 x, S32 y, MASK mask )
setFocus( TRUE );
}
- if (mContextMenu)
+ auto menu = mContextMenuHandle.get();
+ if (!menu)
+ {
+ LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registar;
+ registar.add("Open.WebInspector", boost::bind(&LLMediaCtrl::onOpenWebInspector, this));
+
+ // stinson 05/05/2014 : use this as the parent of the context menu if the static menu
+ // container has yet to be created
+ LLPanel* menuParent = (LLMenuGL::sMenuContainer != NULL) ? dynamic_cast<LLPanel*>(LLMenuGL::sMenuContainer) : dynamic_cast<LLPanel*>(this);
+ llassert(menuParent != NULL);
+ menu = LLUICtrlFactory::getInstance()->createFromFile<LLContextMenu>(
+ "menu_media_ctrl.xml", menuParent, LLViewerMenuHolderGL::child_registry_t::instance());
+ if (menu)
+ {
+ mContextMenuHandle = menu->getHandle();
+ }
+ }
+
+ if (menu)
{
// hide/show debugging options
bool media_plugin_debugging_enabled = gSavedSettings.getBOOL("MediaPluginDebugging");
- mContextMenu->setItemVisible("open_webinspector", media_plugin_debugging_enabled );
- mContextMenu->setItemVisible("debug_separator", media_plugin_debugging_enabled );
+ menu->setItemVisible("open_webinspector", media_plugin_debugging_enabled );
+ menu->setItemVisible("debug_separator", media_plugin_debugging_enabled );
- mContextMenu->show(x, y);
- LLMenuGL::showPopup(this, mContextMenu, x, y);
+ menu->show(x, y);
+ LLMenuGL::showPopup(this, menu, x, y);
}
return TRUE;
@@ -409,15 +433,6 @@ void LLMediaCtrl::onFocusLost()
//
BOOL LLMediaCtrl::postBuild ()
{
- LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registar;
- registar.add("Open.WebInspector", boost::bind(&LLMediaCtrl::onOpenWebInspector, this));
-
- // stinson 05/05/2014 : use this as the parent of the context menu if the static menu
- // container has yet to be created
- LLPanel* menuParent = (LLMenuGL::sMenuContainer != NULL) ? dynamic_cast<LLPanel*>(LLMenuGL::sMenuContainer) : dynamic_cast<LLPanel*>(this);
- llassert(menuParent != NULL);
- mContextMenu = LLUICtrlFactory::getInstance()->createFromFile<LLContextMenu>(
- "menu_media_ctrl.xml", menuParent, LLViewerMenuHolderGL::child_registry_t::instance());
setVisibleCallback(boost::bind(&LLMediaCtrl::onVisibilityChanged, this, _2));
return TRUE;
@@ -1230,11 +1245,6 @@ void LLMediaCtrl::setTrustedContent(bool trusted)
}
}
-void LLMediaCtrl::updateContextMenuParent(LLView* pNewParent)
-{
- mContextMenu->updateParent(pNewParent);
-}
-
bool LLMediaCtrl::wantsKeyUpKeyDown() const
{
return true;
diff --git a/indra/newview/llmediactrl.h b/indra/newview/llmediactrl.h
index bc4cbaae68..487c654adc 100644
--- a/indra/newview/llmediactrl.h
+++ b/indra/newview/llmediactrl.h
@@ -174,8 +174,6 @@ public:
LLUUID getTextureID() {return mMediaTextureID;}
- void updateContextMenuParent(LLView* pNewParent);
-
// The Browser windows want keyup and keydown events. Overridden from LLFocusableElement to return true.
virtual bool wantsKeyUpKeyDown() const;
virtual bool wantsReturnKey() const;
@@ -220,7 +218,7 @@ public:
mTextureHeight;
class LLWindowShade* mWindowShade;
- LLContextMenu* mContextMenu;
+ LLHandle<LLContextMenu> mContextMenuHandle;
};
#endif // LL_LLMediaCtrl_H
diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp
index 5a6010d5e4..e8411dd573 100644
--- a/indra/newview/llmeshrepository.cpp
+++ b/indra/newview/llmeshrepository.cpp
@@ -77,6 +77,8 @@
#include "lluploaddialog.h"
#include "llfloaterreg.h"
+#include "boost/iostreams/device/array.hpp"
+#include "boost/iostreams/stream.hpp"
#include "boost/lexical_cast.hpp"
#ifndef LL_WINDOWS
@@ -138,7 +140,7 @@
// data copied
// headerReceived() invoked
// LLSD parsed
-// mMeshHeader, mMeshHeaderSize updated
+// mMeshHeader updated
// scan mPendingLOD for LOD request
// push LODRequest to mLODReqQ
// ...
@@ -246,7 +248,6 @@
// sActiveLODRequests mMutex rw.any.mMutex, ro.repo.none [1]
// sMaxConcurrentRequests mMutex wo.main.none, ro.repo.none, ro.main.mMutex
// mMeshHeader mHeaderMutex rw.repo.mHeaderMutex, ro.main.mHeaderMutex, ro.main.none [0]
-// mMeshHeaderSize mHeaderMutex rw.repo.mHeaderMutex
// mSkinRequests mMutex rw.repo.mMutex, ro.repo.none [5]
// mSkinInfoQ mMutex rw.repo.mMutex, rw.main.mMutex [5] (was: [0])
// mDecompositionRequests mMutex rw.repo.mMutex, ro.repo.none [5]
@@ -857,6 +858,12 @@ LLMeshRepoThread::~LLMeshRepoThread()
mHttpRequestSet.clear();
mHttpHeaders.reset();
+ while (!mSkinInfoQ.empty())
+ {
+ delete mSkinInfoQ.front();
+ mSkinInfoQ.pop_front();
+ }
+
while (!mDecompositionQ.empty())
{
delete mDecompositionQ.front();
@@ -946,7 +953,8 @@ void LLMeshRepoThread::run()
else
{
// too many fails
- mUnavailableQ.push(req);
+ LLMutexLock lock(mMutex);
+ mUnavailableQ.push_back(req);
LL_WARNS() << "Failed to load " << req.mMeshParams << " , skip" << LL_ENDL;
}
}
@@ -1022,37 +1030,42 @@ void LLMeshRepoThread::run()
if (!mSkinRequests.empty())
{
- std::set<UUIDBasedRequest> incomplete;
- while (!mSkinRequests.empty() && mHttpRequestSet.size() < sRequestHighWater)
- {
- mMutex->lock();
- std::set<UUIDBasedRequest>::iterator iter = mSkinRequests.begin();
- UUIDBasedRequest req = *iter;
- mSkinRequests.erase(iter);
- mMutex->unlock();
- if (req.isDelayed())
- {
- incomplete.insert(req);
- }
- else if (!fetchMeshSkinInfo(req.mId))
- {
- if (req.canRetry())
- {
- req.updateTime();
- incomplete.insert(req);
- }
- else
- {
- LL_DEBUGS() << "mSkinRequests failed: " << req.mId << LL_ENDL;
- }
- }
- }
+ std::list<UUIDBasedRequest> incomplete;
+ while (!mSkinRequests.empty() && mHttpRequestSet.size() < sRequestHighWater)
+ {
- if (!incomplete.empty())
- {
- LLMutexLock locker(mMutex);
- mSkinRequests.insert(incomplete.begin(), incomplete.end());
- }
+ mMutex->lock();
+ auto req = mSkinRequests.front();
+ mSkinRequests.pop_front();
+ mMutex->unlock();
+ if (req.isDelayed())
+ {
+ incomplete.emplace_back(req);
+ }
+ else if (!fetchMeshSkinInfo(req.mId, req.canRetry()))
+ {
+ if (req.canRetry())
+ {
+ req.updateTime();
+ incomplete.emplace_back(req);
+ }
+ else
+ {
+ LLMutexLock locker(mMutex);
+ mSkinUnavailableQ.push_back(req);
+ LL_DEBUGS() << "mSkinReqQ failed: " << req.mId << LL_ENDL;
+ }
+ }
+ }
+
+ if (!incomplete.empty())
+ {
+ LLMutexLock locker(mMutex);
+ for (const auto& req : incomplete)
+ {
+ mSkinRequests.push_back(req);
+ }
+ }
}
// holding lock, try next list
@@ -1151,7 +1164,7 @@ void LLMeshRepoThread::run()
// Mutex: LLMeshRepoThread::mMutex must be held on entry
void LLMeshRepoThread::loadMeshSkinInfo(const LLUUID& mesh_id)
{
- mSkinRequests.insert(UUIDBasedRequest(mesh_id));
+ mSkinRequests.push_back(UUIDBasedRequest(mesh_id));
}
// Mutex: LLMeshRepoThread::mMutex must be held on entry
@@ -1177,10 +1190,13 @@ void LLMeshRepoThread::lockAndLoadMeshLOD(const LLVolumeParams& mesh_params, S32
void LLMeshRepoThread::loadMeshLOD(const LLVolumeParams& mesh_params, S32 lod)
{ //could be called from any thread
+ const LLUUID& mesh_id = mesh_params.getSculptID();
LLMutexLock lock(mMutex);
- mesh_header_map::iterator iter = mMeshHeader.find(mesh_params.getSculptID());
+ LLMutexLock header_lock(mHeaderMutex);
+ mesh_header_map::iterator iter = mMeshHeader.find(mesh_id);
if (iter != mMeshHeader.end())
{ //if we have the header, request LOD byte range
+
LODRequest req(mesh_params, lod);
{
mLODReqQ.push(req);
@@ -1190,8 +1206,7 @@ void LLMeshRepoThread::loadMeshLOD(const LLVolumeParams& mesh_params, S32 lod)
else
{
HeaderRequest req(mesh_params);
-
- pending_lod_map::iterator pending = mPendingLOD.find(mesh_params);
+ pending_lod_map::iterator pending = mPendingLOD.find(mesh_id);
if (pending != mPendingLOD.end())
{ //append this lod request to existing header request
@@ -1201,7 +1216,7 @@ void LLMeshRepoThread::loadMeshLOD(const LLVolumeParams& mesh_params, S32 lod)
else
{ //if no header request is pending, fetch header
mHeaderReqQ.push(req);
- mPendingLOD[mesh_params].push_back(lod);
+ mPendingLOD[mesh_id].push_back(lod);
}
}
}
@@ -1304,7 +1319,7 @@ LLCore::HttpHandle LLMeshRepoThread::getByteRange(const std::string & url,
}
-bool LLMeshRepoThread::fetchMeshSkinInfo(const LLUUID& mesh_id)
+bool LLMeshRepoThread::fetchMeshSkinInfo(const LLUUID& mesh_id, bool can_retry)
{
if (!mHeaderMutex)
@@ -1314,7 +1329,8 @@ bool LLMeshRepoThread::fetchMeshSkinInfo(const LLUUID& mesh_id)
mHeaderMutex->lock();
- if (mMeshHeader.find(mesh_id) == mMeshHeader.end())
+ auto header_it = mMeshHeader.find(mesh_id);
+ if (header_it == mMeshHeader.end())
{ //we have no header info for this mesh, do nothing
mHeaderMutex->unlock();
return false;
@@ -1322,13 +1338,14 @@ bool LLMeshRepoThread::fetchMeshSkinInfo(const LLUUID& mesh_id)
++LLMeshRepository::sMeshRequestCount;
bool ret = true;
- U32 header_size = mMeshHeaderSize[mesh_id];
+ U32 header_size = header_it->second.first;
if (header_size > 0)
{
- S32 version = mMeshHeader[mesh_id]["version"].asInteger();
- S32 offset = header_size + mMeshHeader[mesh_id]["skin"]["offset"].asInteger();
- S32 size = mMeshHeader[mesh_id]["skin"]["size"].asInteger();
+ const LLSD& header = header_it->second.second;
+ S32 version = header["version"].asInteger();
+ S32 offset = header_size + header["skin"]["offset"].asInteger();
+ S32 size = header["skin"]["size"].asInteger();
mHeaderMutex->unlock();
@@ -1384,12 +1401,27 @@ bool LLMeshRepoThread::fetchMeshSkinInfo(const LLUUID& mesh_id)
<< LL_ENDL;
ret = false;
}
- else
+ else if(can_retry)
{
handler->mHttpHandle = handle;
mHttpRequestSet.insert(handler);
}
+ else
+ {
+ LLMutexLock locker(mMutex);
+ mSkinUnavailableQ.emplace_back(mesh_id);
+ }
}
+ else
+ {
+ LLMutexLock locker(mMutex);
+ mSkinUnavailableQ.emplace_back(mesh_id);
+ }
+ }
+ else
+ {
+ LLMutexLock locker(mMutex);
+ mSkinUnavailableQ.emplace_back(mesh_id);
}
}
else
@@ -1410,21 +1442,23 @@ bool LLMeshRepoThread::fetchMeshDecomposition(const LLUUID& mesh_id)
mHeaderMutex->lock();
- if (mMeshHeader.find(mesh_id) == mMeshHeader.end())
+ auto header_it = mMeshHeader.find(mesh_id);
+ if (header_it == mMeshHeader.end())
{ //we have no header info for this mesh, do nothing
mHeaderMutex->unlock();
return false;
}
++LLMeshRepository::sMeshRequestCount;
- U32 header_size = mMeshHeaderSize[mesh_id];
+ U32 header_size = header_it->second.first;
bool ret = true;
if (header_size > 0)
{
- S32 version = mMeshHeader[mesh_id]["version"].asInteger();
- S32 offset = header_size + mMeshHeader[mesh_id]["physics_convex"]["offset"].asInteger();
- S32 size = mMeshHeader[mesh_id]["physics_convex"]["size"].asInteger();
+ const auto& header = header_it->second.second;
+ S32 version = header["version"].asInteger();
+ S32 offset = header_size + header["physics_convex"]["offset"].asInteger();
+ S32 size = header["physics_convex"]["size"].asInteger();
mHeaderMutex->unlock();
@@ -1507,21 +1541,23 @@ bool LLMeshRepoThread::fetchMeshPhysicsShape(const LLUUID& mesh_id)
mHeaderMutex->lock();
- if (mMeshHeader.find(mesh_id) == mMeshHeader.end())
+ auto header_it = mMeshHeader.find(mesh_id);
+ if (header_it == mMeshHeader.end())
{ //we have no header info for this mesh, do nothing
mHeaderMutex->unlock();
return false;
}
++LLMeshRepository::sMeshRequestCount;
- U32 header_size = mMeshHeaderSize[mesh_id];
+ U32 header_size = header_it->second.first;
bool ret = true;
if (header_size > 0)
{
- S32 version = mMeshHeader[mesh_id]["version"].asInteger();
- S32 offset = header_size + mMeshHeader[mesh_id]["physics_mesh"]["offset"].asInteger();
- S32 size = mMeshHeader[mesh_id]["physics_mesh"]["size"].asInteger();
+ const auto& header = header_it->second.second;
+ S32 version = header["version"].asInteger();
+ S32 offset = header_size + header["physics_mesh"]["offset"].asInteger();
+ S32 size = header["physics_mesh"]["size"].asInteger();
mHeaderMutex->unlock();
@@ -1701,20 +1737,25 @@ bool LLMeshRepoThread::fetchMeshLOD(const LLVolumeParams& mesh_params, S32 lod,
return false;
}
- mHeaderMutex->lock();
+ const LLUUID& mesh_id = mesh_params.getSculptID();
+ mHeaderMutex->lock();
+ auto header_it = mMeshHeader.find(mesh_id);
+ if (header_it == mMeshHeader.end())
+ { //we have no header info for this mesh, do nothing
+ mHeaderMutex->unlock();
+ return false;
+ }
++LLMeshRepository::sMeshRequestCount;
bool retval = true;
-
- LLUUID mesh_id = mesh_params.getSculptID();
- U32 header_size = mMeshHeaderSize[mesh_id];
-
+ U32 header_size = header_it->second.first;
if (header_size > 0)
{
- S32 version = mMeshHeader[mesh_id]["version"].asInteger();
- S32 offset = header_size + mMeshHeader[mesh_id][header_lod[lod]]["offset"].asInteger();
- S32 size = mMeshHeader[mesh_id][header_lod[lod]]["size"].asInteger();
+ const auto& header = header_it->second.second;
+ S32 version = header["version"].asInteger();
+ S32 offset = header_size + header[header_lod[lod]]["offset"].asInteger();
+ S32 size = header[header_lod[lod]]["size"].asInteger();
mHeaderMutex->unlock();
if (version <= MAX_MESH_VERSION && offset >= 0 && size > 0)
@@ -1789,17 +1830,20 @@ bool LLMeshRepoThread::fetchMeshLOD(const LLVolumeParams& mesh_params, S32 lod,
}
else
{
- mUnavailableQ.push(LODRequest(mesh_params, lod));
+ LLMutexLock lock(mMutex);
+ mUnavailableQ.push_back(LODRequest(mesh_params, lod));
}
}
else
{
- mUnavailableQ.push(LODRequest(mesh_params, lod));
+ LLMutexLock lock(mMutex);
+ mUnavailableQ.push_back(LODRequest(mesh_params, lod));
}
}
else
{
- mUnavailableQ.push(LODRequest(mesh_params, lod));
+ LLMutexLock lock(mMutex);
+ mUnavailableQ.push_back(LODRequest(mesh_params, lod));
}
}
else
@@ -1818,27 +1862,12 @@ EMeshProcessingResult LLMeshRepoThread::headerReceived(const LLVolumeParams& mes
U32 header_size = 0;
if (data_size > 0)
{
- std::istringstream stream;
- try
- {
- std::string res_str((char*)data, data_size);
+ U32 dsize = data_size;
+ char* result_ptr = strip_deprecated_header((char*)data, dsize, &header_size);
- std::string deprecated_header("<? LLSD/Binary ?>");
+ data_size = dsize;
- if (res_str.substr(0, deprecated_header.size()) == deprecated_header)
- {
- res_str = res_str.substr(deprecated_header.size() + 1, data_size);
- header_size = deprecated_header.size() + 1;
- }
- data_size = res_str.size();
-
- stream.str(res_str);
- }
- catch (std::bad_alloc&)
- {
- // out of memory, we won't be able to process this mesh
- return MESH_OUT_OF_MEMORY;
- }
+ boost::iostreams::stream<boost::iostreams::array_source> stream(result_ptr, data_size);
if (!LLSDSerialize::fromBinary(header, stream, data_size))
{
@@ -1875,8 +1904,7 @@ EMeshProcessingResult LLMeshRepoThread::headerReceived(const LLVolumeParams& mes
{
LLMutexLock lock(mHeaderMutex);
- mMeshHeaderSize[mesh_id] = header_size;
- mMeshHeader[mesh_id] = header;
+ mMeshHeader[mesh_id] = { header_size, header };
LLMeshRepository::sCacheBytesHeaders += header_size;
}
@@ -1884,7 +1912,7 @@ EMeshProcessingResult LLMeshRepoThread::headerReceived(const LLVolumeParams& mes
LLMutexLock lock(mMutex); // make sure only one thread access mPendingLOD at the same time.
//check for pending requests
- pending_lod_map::iterator iter = mPendingLOD.find(mesh_params);
+ pending_lod_map::iterator iter = mPendingLOD.find(mesh_id);
if (iter != mPendingLOD.end())
{
for (U32 i = 0; i < iter->second.size(); ++i)
@@ -1908,26 +1936,14 @@ EMeshProcessingResult LLMeshRepoThread::lodReceived(const LLVolumeParams& mesh_p
}
LLPointer<LLVolume> volume = new LLVolume(mesh_params, LLVolumeLODGroup::getVolumeScaleFromDetail(lod));
- std::istringstream stream;
- try
- {
- std::string mesh_string((char*)data, data_size);
- stream.str(mesh_string);
- }
- catch (std::bad_alloc&)
- {
- // out of memory, we won't be able to process this mesh
- return MESH_OUT_OF_MEMORY;
- }
-
- if (volume->unpackVolumeFaces(stream, data_size))
+ if (volume->unpackVolumeFaces(data, data_size))
{
if (volume->getNumFaces() > 0)
{
LoadedMesh mesh(volume, mesh_params, lod);
{
LLMutexLock lock(mMutex);
- mLoadedQ.push(mesh);
+ mLoadedQ.push_back(mesh);
// LLPointer is not thread safe, since we added this pointer into
// threaded list, make sure counter gets decreased inside mutex lock
// and won't affect mLoadedQ processing
@@ -1950,10 +1966,7 @@ bool LLMeshRepoThread::skinInfoReceived(const LLUUID& mesh_id, U8* data, S32 dat
{
try
{
- std::string res_str((char*)data, data_size);
- std::istringstream stream(res_str);
-
- U32 uzip_result = LLUZipHelper::unzip_llsd(skin, stream, data_size);
+ U32 uzip_result = LLUZipHelper::unzip_llsd(skin, data, data_size);
if (uzip_result != LLUZipHelper::ZR_OK)
{
LL_WARNS(LOG_MESH) << "Mesh skin info parse error. Not a valid mesh asset! ID: " << mesh_id
@@ -1970,8 +1983,16 @@ bool LLMeshRepoThread::skinInfoReceived(const LLUUID& mesh_id, U8* data, S32 dat
}
{
- LLMeshSkinInfo info(skin);
- info.mMeshID = mesh_id;
+ LLMeshSkinInfo* info = nullptr;
+ try
+ {
+ info = new LLMeshSkinInfo(mesh_id, skin);
+ }
+ catch (const std::bad_alloc& ex)
+ {
+ LL_WARNS() << "Failed to allocate skin info with exception: " << ex.what() << LL_ENDL;
+ return false;
+ }
// LL_DEBUGS(LOG_MESH) << "info pelvis offset" << info.mPelvisOffset << LL_ENDL;
{
@@ -1991,10 +2012,7 @@ bool LLMeshRepoThread::decompositionReceived(const LLUUID& mesh_id, U8* data, S3
{
try
{
- std::string res_str((char*)data, data_size);
- std::istringstream stream(res_str);
-
- U32 uzip_result = LLUZipHelper::unzip_llsd(decomp, stream, data_size);
+ U32 uzip_result = LLUZipHelper::unzip_llsd(decomp, data, data_size);
if (uzip_result != LLUZipHelper::ZR_OK)
{
LL_WARNS(LOG_MESH) << "Mesh decomposition parse error. Not a valid mesh asset! ID: " << mesh_id
@@ -2003,7 +2021,7 @@ bool LLMeshRepoThread::decompositionReceived(const LLUUID& mesh_id, U8* data, S3
return false;
}
}
- catch (std::bad_alloc&)
+ catch (const std::bad_alloc&)
{
LL_WARNS(LOG_MESH) << "Out of memory for mesh ID " << mesh_id << " of size: " << data_size << LL_ENDL;
return false;
@@ -2040,20 +2058,7 @@ EMeshProcessingResult LLMeshRepoThread::physicsShapeReceived(const LLUUID& mesh_
volume_params.setSculptID(mesh_id, LL_SCULPT_TYPE_MESH);
LLPointer<LLVolume> volume = new LLVolume(volume_params,0);
- std::istringstream stream;
- try
- {
- std::string mesh_string((char*)data, data_size);
- stream.str(mesh_string);
- }
- catch (std::bad_alloc&)
- {
- // out of memory, we won't be able to process this mesh
- delete d;
- return MESH_OUT_OF_MEMORY;
- }
-
- if (volume->unpackVolumeFaces(stream, data_size))
+ if (volume->unpackVolumeFaces(data, data_size))
{
d->mPhysicsShapeMesh.clear();
@@ -2864,58 +2869,72 @@ void LLMeshRepoThread::notifyLoadedMeshes()
return;
}
- while (!mLoadedQ.empty())
+ if (!mLoadedQ.empty())
{
+ std::deque<LoadedMesh> loaded_queue;
+
mMutex->lock();
- if (mLoadedQ.empty())
+ if (!mLoadedQ.empty())
{
+ loaded_queue.swap(mLoadedQ);
mMutex->unlock();
- break;
- }
- LoadedMesh mesh = mLoadedQ.front(); // make sure nothing else owns volume pointer by this point
- mLoadedQ.pop();
- mMutex->unlock();
-
- update_metrics = true;
- if (mesh.mVolume->getNumVolumeFaces() > 0)
- {
- gMeshRepo.notifyMeshLoaded(mesh.mMeshParams, mesh.mVolume);
- }
- else
- {
- gMeshRepo.notifyMeshUnavailable(mesh.mMeshParams,
- LLVolumeLODGroup::getVolumeDetailFromScale(mesh.mVolume->getDetail()));
+
+ update_metrics = true;
+
+ // Process the elements free of the lock
+ for (const auto& mesh : loaded_queue)
+ {
+ if (mesh.mVolume->getNumVolumeFaces() > 0)
+ {
+ gMeshRepo.notifyMeshLoaded(mesh.mMeshParams, mesh.mVolume);
+ }
+ else
+ {
+ gMeshRepo.notifyMeshUnavailable(mesh.mMeshParams,
+ LLVolumeLODGroup::getVolumeDetailFromScale(mesh.mVolume->getDetail()));
+ }
+ }
}
}
- while (!mUnavailableQ.empty())
+ if (!mUnavailableQ.empty())
{
+ std::deque<LODRequest> unavil_queue;
+
mMutex->lock();
- if (mUnavailableQ.empty())
+ if (!mUnavailableQ.empty())
{
+ unavil_queue.swap(mUnavailableQ);
mMutex->unlock();
- break;
- }
-
- LODRequest req = mUnavailableQ.front();
- mUnavailableQ.pop();
- mMutex->unlock();
- update_metrics = true;
- gMeshRepo.notifyMeshUnavailable(req.mMeshParams, req.mLOD);
+ update_metrics = true;
+
+ // Process the elements free of the lock
+ for (const auto& req : unavil_queue)
+ {
+ gMeshRepo.notifyMeshUnavailable(req.mMeshParams, req.mLOD);
+ }
+ }
}
- if (! mSkinInfoQ.empty() || ! mDecompositionQ.empty())
+ if (!mSkinInfoQ.empty() || !mSkinUnavailableQ.empty() || ! mDecompositionQ.empty())
{
if (mMutex->trylock())
{
- std::list<LLMeshSkinInfo> skin_info_q;
+ std::deque<LLMeshSkinInfo*> skin_info_q;
+ std::deque<UUIDBasedRequest> skin_info_unavail_q;
std::list<LLModel::Decomposition*> decomp_q;
if (! mSkinInfoQ.empty())
{
skin_info_q.swap(mSkinInfoQ);
}
+
+ if (! mSkinUnavailableQ.empty())
+ {
+ skin_info_unavail_q.swap(mSkinUnavailableQ);
+ }
+
if (! mDecompositionQ.empty())
{
decomp_q.swap(mDecompositionQ);
@@ -2929,6 +2948,11 @@ void LLMeshRepoThread::notifyLoadedMeshes()
gMeshRepo.notifySkinInfoReceived(skin_info_q.front());
skin_info_q.pop_front();
}
+ while (! skin_info_unavail_q.empty())
+ {
+ gMeshRepo.notifySkinInfoUnavailable(skin_info_unavail_q.front().mId);
+ skin_info_unavail_q.pop_front();
+ }
while (! decomp_q.empty())
{
@@ -2953,7 +2977,7 @@ S32 LLMeshRepoThread::getActualMeshLOD(const LLVolumeParams& mesh_params, S32 lo
if (iter != mMeshHeader.end())
{
- LLSD& header = iter->second;
+ LLSD& header = iter->second.second;
return LLMeshRepository::getActualMeshLOD(header, lod);
}
@@ -3156,7 +3180,7 @@ void LLMeshHeaderHandler::processFailure(LLCore::HttpStatus status)
LLMutexLock lock(gMeshRepo.mThread->mMutex);
for (int i(0); i < 4; ++i)
{
- gMeshRepo.mThread->mUnavailableQ.push(LLMeshRepoThread::LODRequest(mMeshParams, i));
+ gMeshRepo.mThread->mUnavailableQ.push_back(LLMeshRepoThread::LODRequest(mMeshParams, i));
}
}
@@ -3185,7 +3209,7 @@ void LLMeshHeaderHandler::processData(LLCore::BufferArray * /* body */, S32 /* b
LLMutexLock lock(gMeshRepo.mThread->mMutex);
for (int i(0); i < 4; ++i)
{
- gMeshRepo.mThread->mUnavailableQ.push(LLMeshRepoThread::LODRequest(mMeshParams, i));
+ gMeshRepo.mThread->mUnavailableQ.push_back(LLMeshRepoThread::LODRequest(mMeshParams, i));
}
}
else if (data && data_size > 0)
@@ -3198,8 +3222,8 @@ void LLMeshHeaderHandler::processData(LLCore::BufferArray * /* body */, S32 /* b
LLMeshRepoThread::mesh_header_map::iterator iter = gMeshRepo.mThread->mMeshHeader.find(mesh_id);
if (iter != gMeshRepo.mThread->mMeshHeader.end())
{
- header_bytes = (S32)gMeshRepo.mThread->mMeshHeaderSize[mesh_id];
- header = iter->second;
+ header_bytes = (S32)iter->second.first;
+ header = iter->second.second;
}
if (header_bytes > 0
@@ -3267,7 +3291,7 @@ void LLMeshHeaderHandler::processData(LLCore::BufferArray * /* body */, S32 /* b
LLMutexLock lock(gMeshRepo.mThread->mMutex);
for (int i(0); i < 4; ++i)
{
- gMeshRepo.mThread->mUnavailableQ.push(LLMeshRepoThread::LODRequest(mMeshParams, i));
+ gMeshRepo.mThread->mUnavailableQ.push_back(LLMeshRepoThread::LODRequest(mMeshParams, i));
}
}
}
@@ -3294,7 +3318,7 @@ void LLMeshLODHandler::processFailure(LLCore::HttpStatus status)
<< LL_ENDL;
LLMutexLock lock(gMeshRepo.mThread->mMutex);
- gMeshRepo.mThread->mUnavailableQ.push(LLMeshRepoThread::LODRequest(mMeshParams, mLOD));
+ gMeshRepo.mThread->mUnavailableQ.push_back(LLMeshRepoThread::LODRequest(mMeshParams, mLOD));
}
void LLMeshLODHandler::processData(LLCore::BufferArray * /* body */, S32 /* body_offset */,
@@ -3331,7 +3355,7 @@ void LLMeshLODHandler::processData(LLCore::BufferArray * /* body */, S32 /* body
<< " Not retrying."
<< LL_ENDL;
LLMutexLock lock(gMeshRepo.mThread->mMutex);
- gMeshRepo.mThread->mUnavailableQ.push(LLMeshRepoThread::LODRequest(mMeshParams, mLOD));
+ gMeshRepo.mThread->mUnavailableQ.push_back(LLMeshRepoThread::LODRequest(mMeshParams, mLOD));
}
}
else
@@ -3342,7 +3366,7 @@ void LLMeshLODHandler::processData(LLCore::BufferArray * /* body */, S32 /* body
<< " Data size: " << data_size
<< LL_ENDL;
LLMutexLock lock(gMeshRepo.mThread->mMutex);
- gMeshRepo.mThread->mUnavailableQ.push(LLMeshRepoThread::LODRequest(mMeshParams, mLOD));
+ gMeshRepo.mThread->mUnavailableQ.push_back(LLMeshRepoThread::LODRequest(mMeshParams, mLOD));
}
}
@@ -3360,9 +3384,8 @@ void LLMeshSkinInfoHandler::processFailure(LLCore::HttpStatus status)
<< ", Reason: " << status.toString()
<< " (" << status.toTerseString() << "). Not retrying."
<< LL_ENDL;
-
- // *TODO: Mark mesh unavailable on error. For now, simply leave
- // request unfulfilled rather than retry forever.
+ LLMutexLock lock(gMeshRepo.mThread->mMutex);
+ gMeshRepo.mThread->mSkinUnavailableQ.emplace_back(mMeshID);
}
void LLMeshSkinInfoHandler::processData(LLCore::BufferArray * /* body */, S32 /* body_offset */,
@@ -3393,7 +3416,8 @@ void LLMeshSkinInfoHandler::processData(LLCore::BufferArray * /* body */, S32 /*
LL_WARNS(LOG_MESH) << "Error during mesh skin info processing. ID: " << mMeshID
<< ", Unknown reason. Not retrying."
<< LL_ENDL;
- // *TODO: Mark mesh unavailable on error
+ LLMutexLock lock(gMeshRepo.mThread->mMutex);
+ gMeshRepo.mThread->mSkinUnavailableQ.emplace_back(mMeshID);
}
}
@@ -3502,7 +3526,7 @@ LLMeshRepository::LLMeshRepository()
mMeshThreadCount(0),
mThread(NULL)
{
-
+ mSkinInfoCullTimer.resetWithExpiry(10.f);
}
void LLMeshRepository::init()
@@ -3603,6 +3627,22 @@ S32 LLMeshRepository::update()
return size ;
}
+void LLMeshRepository::unregisterMesh(LLVOVolume* vobj)
+{
+ for (auto& lod : mLoadingMeshes)
+ {
+ for (auto& param : lod)
+ {
+ vector_replace_with_last(param.second, vobj);
+ }
+ }
+
+ for (auto& skin_pair : mLoadingSkins)
+ {
+ vector_replace_with_last(skin_pair.second, vobj);
+ }
+}
+
S32 LLMeshRepository::loadMesh(LLVOVolume* vobj, const LLVolumeParams& mesh_params, S32 detail, S32 last_lod)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK; //LL_LL_RECORD_BLOCK_TIME(FTM_MESH_FETCH);
@@ -3618,15 +3658,19 @@ S32 LLMeshRepository::loadMesh(LLVOVolume* vobj, const LLVolumeParams& mesh_para
{
LLMutexLock lock(mMeshMutex);
//add volume to list of loading meshes
- mesh_load_map::iterator iter = mLoadingMeshes[detail].find(mesh_params);
+ const auto& mesh_id = mesh_params.getSculptID();
+ mesh_load_map::iterator iter = mLoadingMeshes[detail].find(mesh_id);
if (iter != mLoadingMeshes[detail].end())
{ //request pending for this mesh, append volume id to list
- iter->second.insert(vobj->getID());
+ auto it = std::find(iter->second.begin(), iter->second.end(), vobj);
+ if (it == iter->second.end()) {
+ iter->second.push_back(vobj);
+ }
}
else
{
//first request for this mesh
- mLoadingMeshes[detail][mesh_params].insert(vobj->getID());
+ mLoadingMeshes[detail][mesh_id].push_back(vobj);
mPendingRequests.push_back(LLMeshRepoThread::LODRequest(mesh_params, detail));
LLMeshRepository::sLODPending++;
}
@@ -3783,6 +3827,28 @@ void LLMeshRepository::notifyLoadedMeshes()
//call completed callbacks on finished decompositions
mDecompThread->notifyCompleted();
+ if (mSkinInfoCullTimer.checkExpirationAndReset(10.f))
+ {
+ //// Clean up dead skin info
+ //U64Bytes skinbytes(0);
+ for (auto iter = mSkinMap.begin(), ender = mSkinMap.end(); iter != ender;)
+ {
+ auto copy_iter = iter++;
+
+ //skinbytes += U64Bytes(sizeof(LLMeshSkinInfo));
+ //skinbytes += U64Bytes(copy_iter->second->mJointNames.size() * sizeof(std::string));
+ //skinbytes += U64Bytes(copy_iter->second->mJointNums.size() * sizeof(S32));
+ //skinbytes += U64Bytes(copy_iter->second->mJointNames.size() * sizeof(LLMatrix4a));
+ //skinbytes += U64Bytes(copy_iter->second->mJointNames.size() * sizeof(LLMatrix4));
+
+ if (copy_iter->second->getNumRefs() == 1)
+ {
+ mSkinMap.erase(copy_iter);
+ }
+ }
+ //LL_INFOS() << "Skin info cache elements:" << mSkinMap.size() << " Memory: " << U64Kilobytes(skinbytes) << LL_ENDL;
+ }
+
// For major operations, attempt to get the required locks
// without blocking and punt if they're not available. The
// longest run of holdoffs is kept in sMaxLockHoldoffs just
@@ -3853,10 +3919,9 @@ void LLMeshRepository::notifyLoadedMeshes()
for (mesh_load_map::iterator iter = mLoadingMeshes[i].begin(); iter != mLoadingMeshes[i].end(); ++iter)
{
F32 max_score = 0.f;
- for (std::set<LLUUID>::iterator obj_iter = iter->second.begin(); obj_iter != iter->second.end(); ++obj_iter)
+ for (auto obj_iter = iter->second.begin(); obj_iter != iter->second.end(); ++obj_iter)
{
- LLViewerObject* object = gObjectList.findObject(*obj_iter);
-
+ LLVOVolume* object = *obj_iter;
if (object)
{
LLDrawable* drawable = object->mDrawable;
@@ -3868,7 +3933,7 @@ void LLMeshRepository::notifyLoadedMeshes()
}
}
- score_map[iter->first.getSculptID()] = max_score;
+ score_map[iter->first] = max_score;
}
}
@@ -3920,24 +3985,39 @@ void LLMeshRepository::notifyLoadedMeshes()
mThread->mSignal->signal();
}
-void LLMeshRepository::notifySkinInfoReceived(LLMeshSkinInfo& info)
+void LLMeshRepository::notifySkinInfoReceived(LLMeshSkinInfo* info)
{
- mSkinMap[info.mMeshID] = info;
+ mSkinMap[info->mMeshID] = info; // Cache into LLPointer
// Alternative: We can get skin size from header
- sCacheBytesSkins += info.sizeBytes();
+ sCacheBytesSkins += info->sizeBytes();
- skin_load_map::iterator iter = mLoadingSkins.find(info.mMeshID);
+ skin_load_map::iterator iter = mLoadingSkins.find(info->mMeshID);
if (iter != mLoadingSkins.end())
{
- for (std::set<LLUUID>::iterator obj_id = iter->second.begin(); obj_id != iter->second.end(); ++obj_id)
+ for (LLVOVolume* vobj : iter->second)
{
- LLVOVolume* vobj = (LLVOVolume*) gObjectList.findObject(*obj_id);
if (vobj)
{
- vobj->notifyMeshLoaded();
+ vobj->notifySkinInfoLoaded(info);
}
}
- mLoadingSkins.erase(info.mMeshID);
+ mLoadingSkins.erase(iter);
+ }
+}
+
+void LLMeshRepository::notifySkinInfoUnavailable(const LLUUID& mesh_id)
+{
+ skin_load_map::iterator iter = mLoadingSkins.find(mesh_id);
+ if (iter != mLoadingSkins.end())
+ {
+ for (LLVOVolume* vobj : iter->second)
+ {
+ if (vobj)
+ {
+ vobj->notifySkinInfoUnavailable();
+ }
+ }
+ mLoadingSkins.erase(iter);
}
}
@@ -3966,14 +4046,15 @@ void LLMeshRepository::notifyMeshLoaded(const LLVolumeParams& mesh_params, LLVol
S32 detail = LLVolumeLODGroup::getVolumeDetailFromScale(volume->getDetail());
//get list of objects waiting to be notified this mesh is loaded
- mesh_load_map::iterator obj_iter = mLoadingMeshes[detail].find(mesh_params);
+ const auto& mesh_id = mesh_params.getSculptID();
+ mesh_load_map::iterator obj_iter = mLoadingMeshes[detail].find(mesh_id);
if (volume && obj_iter != mLoadingMeshes[detail].end())
{
//make sure target volume is still valid
if (volume->getNumVolumeFaces() <= 0)
{
- LL_WARNS(LOG_MESH) << "Mesh loading returned empty volume. ID: " << mesh_params.getSculptID()
+ LL_WARNS(LOG_MESH) << "Mesh loading returned empty volume. ID: " << mesh_id
<< LL_ENDL;
}
@@ -3987,37 +4068,35 @@ void LLMeshRepository::notifyMeshLoaded(const LLVolumeParams& mesh_params, LLVol
}
else
{
- LL_WARNS(LOG_MESH) << "Couldn't find system volume for mesh " << mesh_params.getSculptID()
+ LL_WARNS(LOG_MESH) << "Couldn't find system volume for mesh " << mesh_id
<< LL_ENDL;
}
}
//notify waiting LLVOVolume instances that their requested mesh is available
- for (std::set<LLUUID>::iterator vobj_iter = obj_iter->second.begin(); vobj_iter != obj_iter->second.end(); ++vobj_iter)
+ for (LLVOVolume* vobj : obj_iter->second)
{
- LLVOVolume* vobj = (LLVOVolume*) gObjectList.findObject(*vobj_iter);
if (vobj)
{
vobj->notifyMeshLoaded();
}
}
- mLoadingMeshes[detail].erase(mesh_params);
+ mLoadingMeshes[detail].erase(obj_iter);
}
}
void LLMeshRepository::notifyMeshUnavailable(const LLVolumeParams& mesh_params, S32 lod)
{ //called from main thread
//get list of objects waiting to be notified this mesh is loaded
- mesh_load_map::iterator obj_iter = mLoadingMeshes[lod].find(mesh_params);
-
- F32 detail = LLVolumeLODGroup::getVolumeScaleFromDetail(lod);
-
+ const auto& mesh_id = mesh_params.getSculptID();
+ mesh_load_map::iterator obj_iter = mLoadingMeshes[lod].find(mesh_id);
if (obj_iter != mLoadingMeshes[lod].end())
{
- for (std::set<LLUUID>::iterator vobj_iter = obj_iter->second.begin(); vobj_iter != obj_iter->second.end(); ++vobj_iter)
+ F32 detail = LLVolumeLODGroup::getVolumeScaleFromDetail(lod);
+
+ for (LLVOVolume* vobj : obj_iter->second)
{
- LLVOVolume* vobj = (LLVOVolume*) gObjectList.findObject(*vobj_iter);
if (vobj)
{
LLVolume* obj_volume = vobj->getVolume();
@@ -4031,7 +4110,7 @@ void LLMeshRepository::notifyMeshUnavailable(const LLVolumeParams& mesh_params,
}
}
- mLoadingMeshes[lod].erase(mesh_params);
+ mLoadingMeshes[lod].erase(obj_iter);
}
}
@@ -4040,7 +4119,7 @@ S32 LLMeshRepository::getActualMeshLOD(const LLVolumeParams& mesh_params, S32 lo
return mThread->getActualMeshLOD(mesh_params, lod);
}
-const LLMeshSkinInfo* LLMeshRepository::getSkinInfo(const LLUUID& mesh_id, const LLVOVolume* requesting_obj)
+const LLMeshSkinInfo* LLMeshRepository::getSkinInfo(const LLUUID& mesh_id, LLVOVolume* requesting_obj)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_AVATAR;
if (mesh_id.notNull())
@@ -4048,7 +4127,7 @@ const LLMeshSkinInfo* LLMeshRepository::getSkinInfo(const LLUUID& mesh_id, const
skin_map::iterator iter = mSkinMap.find(mesh_id);
if (iter != mSkinMap.end())
{
- return &(iter->second);
+ return iter->second;
}
//no skin info known about given mesh, try to fetch it
@@ -4057,14 +4136,22 @@ const LLMeshSkinInfo* LLMeshRepository::getSkinInfo(const LLUUID& mesh_id, const
LLMutexLock lock(mMeshMutex);
//add volume to list of loading meshes
skin_load_map::iterator iter = mLoadingSkins.find(mesh_id);
- if (iter == mLoadingSkins.end())
- { //no request pending for this skin info
+ if (iter != mLoadingSkins.end())
+ { //request pending for this mesh, append volume id to list
+ auto it = std::find(iter->second.begin(), iter->second.end(), requesting_obj);
+ if (it == iter->second.end()) {
+ iter->second.push_back(requesting_obj);
+ }
+ }
+ else
+ {
+ //first request for this mesh
+ mLoadingSkins[mesh_id].push_back(requesting_obj);
mPendingSkinRequests.push(mesh_id);
}
- mLoadingSkins[mesh_id].insert(requesting_obj->getID());
}
}
- return NULL;
+ return nullptr;
}
void LLMeshRepository::fetchPhysicsShape(const LLUUID& mesh_id)
@@ -4167,16 +4254,13 @@ bool LLMeshRepository::hasPhysicsShape(const LLUUID& mesh_id)
bool LLMeshRepoThread::hasPhysicsShapeInHeader(const LLUUID& mesh_id)
{
LLMutexLock lock(mHeaderMutex);
- if (mMeshHeaderSize[mesh_id] > 0)
+ mesh_header_map::iterator iter = mMeshHeader.find(mesh_id);
+ if (iter != mMeshHeader.end() && iter->second.first > 0)
{
- mesh_header_map::iterator iter = mMeshHeader.find(mesh_id);
- if (iter != mMeshHeader.end())
+ LLSD &mesh = iter->second.second;
+ if (mesh.has("physics_mesh") && mesh["physics_mesh"].has("size") && (mesh["physics_mesh"]["size"].asInteger() > 0))
{
- LLSD &mesh = iter->second;
- if (mesh.has("physics_mesh") && mesh["physics_mesh"].has("size") && (mesh["physics_mesh"]["size"].asInteger() > 0))
- {
- return true;
- }
+ return true;
}
}
@@ -4201,9 +4285,9 @@ S32 LLMeshRepository::getMeshSize(const LLUUID& mesh_id, S32 lod)
{
LLMutexLock lock(mThread->mHeaderMutex);
LLMeshRepoThread::mesh_header_map::iterator iter = mThread->mMeshHeader.find(mesh_id);
- if (iter != mThread->mMeshHeader.end() && mThread->mMeshHeaderSize[mesh_id] > 0)
+ if (iter != mThread->mMeshHeader.end() && iter->second.first > 0)
{
- LLSD& header = iter->second;
+ const LLSD& header = iter->second.second;
if (header.has("404"))
{
@@ -4307,9 +4391,9 @@ F32 LLMeshRepository::getStreamingCostLegacy(LLUUID mesh_id, F32 radius, S32* by
{
LLMutexLock lock(mThread->mHeaderMutex);
LLMeshRepoThread::mesh_header_map::iterator iter = mThread->mMeshHeader.find(mesh_id);
- if (iter != mThread->mMeshHeader.end() && mThread->mMeshHeaderSize[mesh_id] > 0)
+ if (iter != mThread->mMeshHeader.end() && iter->second.first > 0)
{
- result = getStreamingCostLegacy(iter->second, radius, bytes, bytes_visible, lod, unscaled_value);
+ result = getStreamingCostLegacy(iter->second.second, radius, bytes, bytes_visible, lod, unscaled_value);
}
}
if (result > 0.f)
@@ -4622,9 +4706,9 @@ bool LLMeshRepository::getCostData(LLUUID mesh_id, LLMeshCostData& data)
{
LLMutexLock lock(mThread->mHeaderMutex);
LLMeshRepoThread::mesh_header_map::iterator iter = mThread->mMeshHeader.find(mesh_id);
- if (iter != mThread->mMeshHeader.end() && mThread->mMeshHeaderSize[mesh_id] > 0)
+ if (iter != mThread->mMeshHeader.end() && iter->second.first > 0)
{
- LLSD& header = iter->second;
+ LLSD& header = iter->second.second;
bool header_invalid = (header.has("404")
|| !header.has("lowest_lod")
diff --git a/indra/newview/llmeshrepository.h b/indra/newview/llmeshrepository.h
index 6fe4ea5514..6922367ff7 100644
--- a/indra/newview/llmeshrepository.h
+++ b/indra/newview/llmeshrepository.h
@@ -210,10 +210,8 @@ public:
LLCondition* mSignal;
//map of known mesh headers
- typedef std::map<LLUUID, LLSD> mesh_header_map;
+ typedef boost::unordered_map<LLUUID, std::pair<U32, LLSD>> mesh_header_map; // pair is header_size and data
mesh_header_map mMeshHeader;
-
- std::map<LLUUID, U32> mMeshHeaderSize;
class HeaderRequest : public RequestStats
{
@@ -283,10 +281,13 @@ public:
};
//set of requested skin info
- std::set<UUIDBasedRequest> mSkinRequests;
+ std::deque<UUIDBasedRequest> mSkinRequests;
// list of completed skin info requests
- std::list<LLMeshSkinInfo> mSkinInfoQ;
+ std::deque<LLMeshSkinInfo*> mSkinInfoQ;
+
+ // list of skin info requests that have failed or are unavailaibe
+ std::deque<UUIDBasedRequest> mSkinUnavailableQ;
//set of requested decompositions
std::set<UUIDBasedRequest> mDecompositionRequests;
@@ -304,13 +305,13 @@ public:
std::queue<LODRequest> mLODReqQ;
//queue of unavailable LODs (either asset doesn't exist or asset doesn't have desired LOD)
- std::queue<LODRequest> mUnavailableQ;
+ std::deque<LODRequest> mUnavailableQ;
//queue of successfully loaded meshes
- std::queue<LoadedMesh> mLoadedQ;
+ std::deque<LoadedMesh> mLoadedQ;
//map of pending header requests and currently desired LODs
- typedef std::map<LLVolumeParams, std::vector<S32> > pending_lod_map;
+ typedef boost::unordered_map<LLUUID, std::vector<S32> > pending_lod_map;
pending_lod_map mPendingLOD;
// llcorehttp library interface objects.
@@ -353,7 +354,7 @@ public:
//send request for skin info, returns true if header info exists
// (should hold onto mesh_id and try again later if header info does not exist)
- bool fetchMeshSkinInfo(const LLUUID& mesh_id);
+ bool fetchMeshSkinInfo(const LLUUID& mesh_id, bool can_retry = true);
//send request for decomposition, returns true if header info exists
// (should hold onto mesh_id and try again later if header info does not exist)
@@ -575,18 +576,20 @@ public:
void shutdown();
S32 update();
+ void unregisterMesh(LLVOVolume* volume);
//mesh management functions
S32 loadMesh(LLVOVolume* volume, const LLVolumeParams& mesh_params, S32 detail = 0, S32 last_lod = -1);
void notifyLoadedMeshes();
void notifyMeshLoaded(const LLVolumeParams& mesh_params, LLVolume* volume);
void notifyMeshUnavailable(const LLVolumeParams& mesh_params, S32 lod);
- void notifySkinInfoReceived(LLMeshSkinInfo& info);
+ void notifySkinInfoReceived(LLMeshSkinInfo* info);
+ void notifySkinInfoUnavailable(const LLUUID& info);
void notifyDecompositionReceived(LLModel::Decomposition* info);
S32 getActualMeshLOD(const LLVolumeParams& mesh_params, S32 lod);
static S32 getActualMeshLOD(LLSD& header, S32 lod);
- const LLMeshSkinInfo* getSkinInfo(const LLUUID& mesh_id, const LLVOVolume* requesting_obj = nullptr);
+ const LLMeshSkinInfo* getSkinInfo(const LLUUID& mesh_id, LLVOVolume* requesting_obj = nullptr);
LLModel::Decomposition* getDecomposition(const LLUUID& mesh_id);
void fetchPhysicsShape(const LLUUID& mesh_id);
bool hasPhysicsShape(const LLUUID& mesh_id);
@@ -611,10 +614,10 @@ public:
static void metricsProgress(unsigned int count);
static void metricsUpdate();
- typedef std::map<LLVolumeParams, std::set<LLUUID> > mesh_load_map;
+ typedef boost::unordered_map<LLUUID, std::vector<LLVOVolume*> > mesh_load_map;
mesh_load_map mLoadingMeshes[4];
- typedef std::unordered_map<LLUUID, LLMeshSkinInfo> skin_map;
+ typedef std::unordered_map<LLUUID, LLPointer<LLMeshSkinInfo>> skin_map;
skin_map mSkinMap;
typedef std::map<LLUUID, LLModel::Decomposition*> decomposition_map;
@@ -625,7 +628,7 @@ public:
std::vector<LLMeshRepoThread::LODRequest> mPendingRequests;
//list of mesh ids awaiting skin info
- typedef std::map<LLUUID, std::set<LLUUID> > skin_load_map;
+ typedef boost::unordered_map<LLUUID, std::vector<LLVOVolume*> > skin_load_map;
skin_load_map mLoadingSkins;
//list of mesh ids that need to send skin info fetch requests
@@ -650,6 +653,8 @@ public:
std::vector<LLMeshUploadThread*> mUploadWaitList;
LLPhysicsDecomp* mDecompThread;
+
+ LLFrameTimer mSkinInfoCullTimer;
class inventory_data
{
diff --git a/indra/newview/llmodelpreview.cpp b/indra/newview/llmodelpreview.cpp
index 66d14df1f4..56a48cb74d 100644
--- a/indra/newview/llmodelpreview.cpp
+++ b/indra/newview/llmodelpreview.cpp
@@ -1956,32 +1956,16 @@ void LLModelPreview::genMeshOptimizerLODs(S32 which_lod, S32 meshopt_mode, U32 d
if (sloppy_ratio < 0)
{
// Sloppy method didn't work, try with smaller decimation values
- S32 size_vertices = 0;
-
- for (U32 face_idx = 0; face_idx < base->getNumVolumeFaces(); ++face_idx)
- {
- const LLVolumeFace &face = base->getVolumeFace(face_idx);
- size_vertices += face.mNumVertices;
- }
-
- // Complex models aren't supposed to get here, they are supposed
- // to work on a first try of sloppy due to having more viggle room.
- // If they didn't, something is likely wrong, no point locking the
- // thread in a long calculation that will fail.
- const U32 too_many_vertices = 27000;
- if (size_vertices > too_many_vertices)
- {
- LL_WARNS() << "Sloppy optimization method failed for a complex model " << target_model->getName() << LL_ENDL;
- }
- else
{
// Find a decimator that does work
F32 sloppy_decimation_step = sqrt((F32)decimation); // example: 27->15->9->5->3
F32 sloppy_decimator = indices_decimator / sloppy_decimation_step;
+ U64Microseconds end_time = LLTimer::getTotalTime() + U64Seconds(5);
while (sloppy_ratio < 0
&& sloppy_decimator > precise_ratio
- && sloppy_decimator > 1)// precise_ratio isn't supposed to be below 1, but check just in case
+ && sloppy_decimator > 1 // precise_ratio isn't supposed to be below 1, but check just in case
+ && end_time > LLTimer::getTotalTime())
{
sloppy_ratio = genMeshOptimizerPerModel(base, target_model, sloppy_decimator, lod_error_threshold, MESH_OPTIMIZER_NO_TOPOLOGY);
sloppy_decimator = sloppy_decimator / sloppy_decimation_step;
diff --git a/indra/newview/llnetmap.cpp b/indra/newview/llnetmap.cpp
index b34be80b07..0ba3c3d691 100755..100644
--- a/indra/newview/llnetmap.cpp
+++ b/indra/newview/llnetmap.cpp
@@ -102,8 +102,7 @@ LLNetMap::LLNetMap (const Params & p)
mObjectImagep(),
mClosestAgentToCursor(),
mClosestAgentAtLastRightClick(),
- mToolTipMsg(),
- mPopupMenu(NULL)
+ mToolTipMsg()
{
mScale = gSavedSettings.getF32("MiniMapScale");
if (gAgent.isFirstLogin())
@@ -119,6 +118,12 @@ LLNetMap::LLNetMap (const Params & p)
LLNetMap::~LLNetMap()
{
+ auto menu = static_cast<LLMenuGL*>(mPopupMenuHandle.get());
+ if (menu)
+ {
+ menu->die();
+ mPopupMenuHandle.markDead();
+ }
}
BOOL LLNetMap::postBuild()
@@ -134,11 +139,10 @@ BOOL LLNetMap::postBuild()
commitRegistrar.add("Minimap.MapOrientation.Set", boost::bind(&LLNetMap::setMapOrientation, this, _2));
commitRegistrar.add("Minimap.AboutLand", boost::bind(&LLNetMap::popupShowAboutLand, this, _2));
- mPopupMenu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>("menu_mini_map.xml", gMenuHolder,
- LLViewerMenuHolderGL::child_registry_t::instance());
- mPopupMenu->setItemEnabled("Re-center map", false);
-
- return true;
+ LLMenuGL* menu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>("menu_mini_map.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
+ mPopupMenuHandle = menu->getHandle();
+ menu->setItemEnabled("Re-center map", false);
+ return TRUE;
}
void LLNetMap::setScale( F32 scale )
@@ -206,8 +210,12 @@ void LLNetMap::draw()
mCentering = false;
}
- bool can_recenter_map = !(centered || mCentering || auto_centering);
- mPopupMenu->setItemEnabled("Re-center map", can_recenter_map);
+ auto menu = static_cast<LLMenuGL*>(mPopupMenuHandle.get());
+ if (menu)
+ {
+ bool can_recenter_map = !(centered || mCentering || auto_centering);
+ menu->setItemEnabled("Re-center map", can_recenter_map);
+ }
updateAboutLandPopupButton();
// Prepare a scissor region
@@ -595,14 +603,15 @@ void LLNetMap::drawTracking(const LLVector3d& pos_global, const LLColor4& color,
bool LLNetMap::isMouseOnPopupMenu()
{
- if (!mPopupMenu->isOpen())
+ auto menu = static_cast<LLMenuGL*>(mPopupMenuHandle.get());
+ if (!menu || !menu->isOpen())
{
return false;
}
S32 popup_x;
S32 popup_y;
- LLUI::getInstance()->getMousePositionLocal(mPopupMenu, &popup_x, &popup_y);
+ LLUI::getInstance()->getMousePositionLocal(menu, &popup_x, &popup_y);
// *NOTE: Tolerance is larger than it needs to be because the context menu is offset from the mouse when the menu is opened from certain
// directions. This may be a quirk of LLMenuGL::showPopup. -Cosmic,2022-03-22
constexpr S32 tolerance = 10;
@@ -613,7 +622,7 @@ bool LLNetMap::isMouseOnPopupMenu()
{
for (S32 sign_y = -1; sign_y <= 1; sign_y += 2)
{
- if (mPopupMenu->pointInView(popup_x + (sign_x * tolerance), popup_y + (sign_y * tolerance)))
+ if (menu->pointInView(popup_x + (sign_x * tolerance), popup_y + (sign_y * tolerance)))
{
return true;
}
@@ -624,7 +633,8 @@ bool LLNetMap::isMouseOnPopupMenu()
void LLNetMap::updateAboutLandPopupButton()
{
- if (!mPopupMenu->isOpen())
+ auto menu = static_cast<LLMenuGL*>(mPopupMenuHandle.get());
+ if (!menu || !menu->isOpen())
{
return;
}
@@ -632,7 +642,7 @@ void LLNetMap::updateAboutLandPopupButton()
LLViewerRegion *region = LLWorld::getInstance()->getRegionFromPosGlobal(mPopupWorldPos);
if (!region)
{
- mPopupMenu->setItemEnabled("About Land", false);
+ menu->setItemEnabled("About Land", false);
}
else
{
@@ -647,7 +657,7 @@ void LLNetMap::updateAboutLandPopupButton()
{
valid_parcel = hover_parcel->getOwnerID().notNull();
}
- mPopupMenu->setItemEnabled("About Land", valid_parcel);
+ menu->setItemEnabled("About Land", valid_parcel);
}
}
}
@@ -1043,13 +1053,14 @@ BOOL LLNetMap::handleMouseUp(S32 x, S32 y, MASK mask)
BOOL LLNetMap::handleRightMouseDown(S32 x, S32 y, MASK mask)
{
- if (mPopupMenu)
+ auto menu = static_cast<LLMenuGL*>(mPopupMenuHandle.get());
+ if (menu)
{
- mPopupWorldPos = viewPosToGlobal(x, y);
- mPopupMenu->buildDrawLabels();
- mPopupMenu->updateParent(LLMenuGL::sMenuContainer);
- mPopupMenu->setItemEnabled("Stop tracking", LLTracker::isTracking(0));
- LLMenuGL::showPopup(this, mPopupMenu, x, y);
+ mPopupWorldPos = viewPosToGlobal(x, y);
+ menu->buildDrawLabels();
+ menu->updateParent(LLMenuGL::sMenuContainer);
+ menu->setItemEnabled("Stop Tracking", LLTracker::isTracking(0));
+ LLMenuGL::showPopup(this, menu, x, y);
}
return TRUE;
}
@@ -1182,9 +1193,10 @@ void LLNetMap::setZoom(const LLSD &userdata)
void LLNetMap::handleStopTracking (const LLSD& userdata)
{
- if (mPopupMenu)
+ auto menu = static_cast<LLMenuGL*>(mPopupMenuHandle.get());
+ if (menu)
{
- mPopupMenu->setItemEnabled ("Stop tracking", false);
+ menu->setItemEnabled ("Stop Tracking", false);
LLTracker::stopTracking (LLTracker::isTracking(NULL));
}
}
diff --git a/indra/newview/llnetmap.h b/indra/newview/llnetmap.h
index fe1aca65a9..75c1abc4ed 100644
--- a/indra/newview/llnetmap.h
+++ b/indra/newview/llnetmap.h
@@ -162,7 +162,7 @@ private:
void setMapOrientation(const LLSD& userdata);
void popupShowAboutLand(const LLSD& userdata);
- LLMenuGL* mPopupMenu;
+ LLHandle<LLView> mPopupMenuHandle;
uuid_vec_t gmSelected;
};
diff --git a/indra/newview/llnotificationlistitem.cpp b/indra/newview/llnotificationlistitem.cpp
index 6a79a0c68c..f86edfd0cf 100644
--- a/indra/newview/llnotificationlistitem.cpp
+++ b/indra/newview/llnotificationlistitem.cpp
@@ -521,8 +521,6 @@ void LLGroupNoticeNotificationListItem::close()
void LLGroupNoticeNotificationListItem::onClickAttachment()
{
if (mInventoryOffer != NULL) {
- mInventoryOffer->forceResponse(IOR_ACCEPT);
-
static const LLUIColor textColor = LLUIColorTable::instance().getColor(
"GroupNotifyDimmedTextColor");
mAttachmentTextBox->setColor(textColor);
@@ -532,7 +530,7 @@ void LLGroupNoticeNotificationListItem::onClickAttachment()
if (!isAttachmentOpenable(mInventoryOffer->mType)) {
LLNotifications::instance().add("AttachmentSaved", LLSD(), LLSD());
}
-
+ mInventoryOffer->forceResponse(IOR_ACCEPT);
mInventoryOffer = NULL;
}
}
diff --git a/indra/newview/lloutfitgallery.cpp b/indra/newview/lloutfitgallery.cpp
index 5aaa80a7ef..92a742466e 100644
--- a/indra/newview/lloutfitgallery.cpp
+++ b/indra/newview/lloutfitgallery.cpp
@@ -1226,7 +1226,7 @@ void LLOutfitGallery::uploadOutfitImage(const std::vector<std::string>& filename
checkRemovePhoto(outfit_id);
std::string upload_pending_name = outfit_id.asString();
std::string upload_pending_desc = "";
- LLUUID photo_id = upload_new_resource(filename, // file
+ upload_new_resource(filename, // file
upload_pending_name,
upload_pending_desc,
0, LLFolderType::FT_NONE, LLInventoryType::IT_NONE,
diff --git a/indra/newview/lloutfitslist.cpp b/indra/newview/lloutfitslist.cpp
index 7270580032..4171fd8822 100644
--- a/indra/newview/lloutfitslist.cpp
+++ b/indra/newview/lloutfitslist.cpp
@@ -823,8 +823,7 @@ void LLOutfitListBase::onOpen(const LLSD& info)
mCategoriesObserver->addCategory(outfits,
boost::bind(&LLOutfitListBase::refreshList, this, outfits));
- const LLUUID cof = gInventory.findCategoryUUIDForType(LLFolderType::FT_CURRENT_OUTFIT);
-
+ //const LLUUID cof = gInventory.findCategoryUUIDForType(LLFolderType::FT_CURRENT_OUTFIT);
// Start observing changes in Current Outfit category.
//mCategoriesObserver->addCategory(cof, boost::bind(&LLOutfitsList::onCOFChanged, this));
diff --git a/indra/newview/llpaneleditwearable.cpp b/indra/newview/llpaneleditwearable.cpp
index 69998e8be4..5c209bc4c6 100644
--- a/indra/newview/llpaneleditwearable.cpp
+++ b/indra/newview/llpaneleditwearable.cpp
@@ -1662,7 +1662,7 @@ void LLPanelEditWearable::initPreviousAlphaTextureEntry(LLAvatarAppearanceDefine
class LLMetricSystemHandler : public LLCommandHandler
{
public:
- LLMetricSystemHandler() : LLCommandHandler("metricsystem", UNTRUSTED_THROTTLE) { }
+ LLMetricSystemHandler() : LLCommandHandler("metricsystem", UNTRUSTED_CLICK_ONLY) { }
bool handle(const LLSD& params, const LLSD& query_map, LLMediaCtrl* web)
{
diff --git a/indra/newview/llpanelexperiencelog.cpp b/indra/newview/llpanelexperiencelog.cpp
index 44b4728df7..e5c637938f 100644
--- a/indra/newview/llpanelexperiencelog.cpp
+++ b/indra/newview/llpanelexperiencelog.cpp
@@ -112,7 +112,7 @@ void LLPanelExperienceLog::refresh()
int items = 0;
bool moreItems = false;
LLSD events_to_save = events;
- if (!events.emptyMap())
+ if (events.isMap() && events.size() != 0)
{
LLSD::map_const_iterator day = events.endMap();
do
diff --git a/indra/newview/llpanellandmedia.cpp b/indra/newview/llpanellandmedia.cpp
index 213a66f005..ca252d1455 100644
--- a/indra/newview/llpanellandmedia.cpp
+++ b/indra/newview/llpanellandmedia.cpp
@@ -178,7 +178,6 @@ void LLPanelLandMedia::refresh()
// enable/disable for text label for completeness
mMediaSizeCtrlLabel->setEnabled( can_change_media && allow_resize );
- LLUUID tmp = parcel->getMediaID();
mMediaTextureCtrl->setImageAssetID ( parcel->getMediaID() );
mMediaTextureCtrl->setEnabled( can_change_media );
diff --git a/indra/newview/llpanelmaininventory.cpp b/indra/newview/llpanelmaininventory.cpp
index 8b78ee843f..f38357c5da 100644
--- a/indra/newview/llpanelmaininventory.cpp
+++ b/indra/newview/llpanelmaininventory.cpp
@@ -308,6 +308,13 @@ LLPanelMainInventory::~LLPanelMainInventory( void )
gInventory.removeObserver(this);
delete mSavedFolderState;
+
+ auto menu = mMenuAddHandle.get();
+ if(menu)
+ {
+ menu->die();
+ mMenuAddHandle.markDead();
+ }
}
LLInventoryPanel* LLPanelMainInventory::getAllItemsPanel()
@@ -1187,13 +1194,12 @@ void LLPanelMainInventory::initListCommandsHandlers()
mEnableCallbackRegistrar.add("Inventory.GearDefault.Check", boost::bind(&LLPanelMainInventory::isActionChecked, this, _2));
mEnableCallbackRegistrar.add("Inventory.GearDefault.Enable", boost::bind(&LLPanelMainInventory::isActionEnabled, this, _2));
mMenuGearDefault = LLUICtrlFactory::getInstance()->createFromFile<LLToggleableMenu>("menu_inventory_gear_default.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
- mGearMenuButton->setMenu(mMenuGearDefault);
+ mGearMenuButton->setMenu(mMenuGearDefault, LLMenuButton::MP_TOP_LEFT, true);
LLMenuGL* menu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>("menu_inventory_add.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
mMenuAddHandle = menu->getHandle();
mMenuVisibility = LLUICtrlFactory::getInstance()->createFromFile<LLToggleableMenu>("menu_inventory_search_visibility.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
- mVisibilityMenuButton->setMenu(mMenuVisibility);
- mVisibilityMenuButton->setMenuPosition(LLMenuButton::MP_BOTTOM_LEFT);
+ mVisibilityMenuButton->setMenu(mMenuVisibility, LLMenuButton::MP_BOTTOM_LEFT, true);
// Update the trash button when selected item(s) get worn or taken off.
LLOutfitObserver::instance().addCOFChangedCallback(boost::bind(&LLPanelMainInventory::updateListCommands, this));
diff --git a/indra/newview/llpanelobject.cpp b/indra/newview/llpanelobject.cpp
index 0ec26e9efc..0704fc881d 100644
--- a/indra/newview/llpanelobject.cpp
+++ b/indra/newview/llpanelobject.cpp
@@ -2129,7 +2129,7 @@ bool LLPanelObject::menuEnableItem(const LLSD& userdata)
}
else if (command == "params_paste")
{
- return mClipboardParams.isMap() && !mClipboardParams.emptyMap();
+ return mClipboardParams.isMap() && (mClipboardParams.size() != 0);
}
// copy options
else if (command == "psr_copy")
diff --git a/indra/newview/llpanelobjectinventory.cpp b/indra/newview/llpanelobjectinventory.cpp
index 38f7883b82..2db8620d2d 100644
--- a/indra/newview/llpanelobjectinventory.cpp
+++ b/indra/newview/llpanelobjectinventory.cpp
@@ -1334,7 +1334,8 @@ LLPanelObjectInventory::LLPanelObjectInventory(const LLPanelObjectInventory::Par
mHaveInventory(FALSE),
mIsInventoryEmpty(TRUE),
mInventoryNeedsUpdate(FALSE),
- mInventoryViewModel(p.name)
+ mInventoryViewModel(p.name),
+ mShowRootFolder(p.show_root_folder)
{
// Setup context menu callbacks
mCommitCallbackRegistrar.add("Inventory.DoToSelected", boost::bind(&LLPanelObjectInventory::doToSelected, this, _2));
@@ -1419,6 +1420,7 @@ void LLPanelObjectInventory::reset()
mFolders = LLUICtrlFactory::create<LLFolderView>(p);
mFolders->setCallbackRegistrar(&mCommitCallbackRegistrar);
+ mFolders->setEnableRegistrar(&mEnableCallbackRegistrar);
if (hasFocus())
{
@@ -1585,15 +1587,23 @@ void LLPanelObjectInventory::createFolderViews(LLInventoryObject* inventory_root
p.font_highlight_color = item_color;
LLFolderViewFolder* new_folder = LLUICtrlFactory::create<LLFolderViewFolder>(p);
- new_folder->addToFolder(mFolders);
- new_folder->toggleOpen();
+
+ if (mShowRootFolder)
+ {
+ new_folder->addToFolder(mFolders);
+ new_folder->toggleOpen();
+ }
if (!contents.empty())
{
- createViewsForCategory(&contents, inventory_root, new_folder);
+ createViewsForCategory(&contents, inventory_root, mShowRootFolder ? new_folder : mFolders);
}
- // Refresh for label to add item count
- new_folder->refresh();
+
+ if (mShowRootFolder)
+ {
+ // Refresh for label to add item count
+ new_folder->refresh();
+ }
}
}
diff --git a/indra/newview/llpanelobjectinventory.h b/indra/newview/llpanelobjectinventory.h
index 7b9ecfb8f3..0e450d8ce9 100644
--- a/indra/newview/llpanelobjectinventory.h
+++ b/indra/newview/llpanelobjectinventory.h
@@ -48,8 +48,14 @@ class LLViewerObject;
class LLPanelObjectInventory : public LLPanel, public LLVOInventoryListener
{
public:
- // dummy param block for template registration purposes
- struct Params : public LLPanel::Params {};
+ struct Params : public LLInitParam::Block<Params, LLPanel::Params>
+ {
+ Optional<bool> show_root_folder;
+
+ Params()
+ : show_root_folder("show_root_folder", true)
+ {}
+ };
LLPanelObjectInventory(const Params&);
virtual ~LLPanelObjectInventory();
@@ -110,6 +116,7 @@ private:
BOOL mIsInventoryEmpty; // 'Empty' label
BOOL mInventoryNeedsUpdate; // for idle, set on changed callback
LLFolderViewModelInventory mInventoryViewModel;
+ bool mShowRootFolder;
};
#endif // LL_LLPANELOBJECTINVENTORY_H
diff --git a/indra/newview/llpanelplaces.cpp b/indra/newview/llpanelplaces.cpp
index 74ec576554..0f00231643 100644
--- a/indra/newview/llpanelplaces.cpp
+++ b/indra/newview/llpanelplaces.cpp
@@ -800,7 +800,6 @@ void LLPanelPlaces::onSaveButtonClicked()
LLStringUtil::trim(current_title_value);
LLStringUtil::trim(current_notes_value);
- LLUUID item_id = mItem->getUUID();
LLUUID folder_id = mLandmarkInfo->getLandmarkFolder();
bool change_parent = folder_id != mItem->getParentUUID();
diff --git a/indra/newview/llpanelprofile.cpp b/indra/newview/llpanelprofile.cpp
index d9a8d496d1..816633b545 100644
--- a/indra/newview/llpanelprofile.cpp
+++ b/indra/newview/llpanelprofile.cpp
@@ -484,6 +484,30 @@ public:
// requires trusted browser to trigger
LLAgentHandler() : LLCommandHandler("agent", UNTRUSTED_THROTTLE) { }
+ virtual bool canHandleUntrusted(
+ const LLSD& params,
+ const LLSD& query_map,
+ LLMediaCtrl* web,
+ const std::string& nav_type)
+ {
+ if (params.size() < 2)
+ {
+ return true; // don't block, will fail later
+ }
+
+ if (nav_type == NAV_TYPE_CLICKED)
+ {
+ return true;
+ }
+
+ const std::string verb = params[1].asString();
+ if (verb == "about" || verb == "inspect" || verb == "reportAbuse")
+ {
+ return true;
+ }
+ return false;
+ }
+
bool handle(const LLSD& params, const LLSD& query_map,
LLMediaCtrl* web)
{
@@ -1031,7 +1055,6 @@ void LLPanelProfileSecondLife::resetData()
void LLPanelProfileSecondLife::processProfileProperties(const LLAvatarData* avatar_data)
{
- LLUUID avatar_id = getAvatarId();
const LLRelationship* relationship = LLAvatarTracker::instance().getBuddyInfo(getAvatarId());
if ((relationship != NULL || gAgent.isGodlike()) && !getSelfProfile())
{
@@ -1280,6 +1303,8 @@ void LLPanelProfileSecondLife::fillRightsData()
void LLPanelProfileSecondLife::fillAgeData(const LLDate &born_on)
{
+ // Date from server comes already converted to stl timezone,
+ // so display it as an UTC + 0
std::string name_and_date = getString("date_format");
LLSD args_name;
args_name["datetime"] = (S32)born_on.secondsSinceEpoch();
diff --git a/indra/newview/llpanelprofileclassifieds.cpp b/indra/newview/llpanelprofileclassifieds.cpp
index a3913ddc49..1ff12b4f37 100644
--- a/indra/newview/llpanelprofileclassifieds.cpp
+++ b/indra/newview/llpanelprofileclassifieds.cpp
@@ -81,6 +81,30 @@ public:
std::set<LLUUID> mClassifiedIds;
std::string mRequestVerb;
+
+ virtual bool canHandleUntrusted(
+ const LLSD& params,
+ const LLSD& query_map,
+ LLMediaCtrl* web,
+ const std::string& nav_type)
+ {
+ if (params.size() < 1)
+ {
+ return true; // don't block, will fail later
+ }
+
+ if (nav_type == NAV_TYPE_CLICKED)
+ {
+ return true;
+ }
+
+ const std::string verb = params[0].asString();
+ if (verb == "create")
+ {
+ return false;
+ }
+ return true;
+ }
bool handle(const LLSD& params, const LLSD& query_map, LLMediaCtrl* web)
{
diff --git a/indra/newview/llpanelprofilepicks.cpp b/indra/newview/llpanelprofilepicks.cpp
index 774119f169..45d0252e4f 100644
--- a/indra/newview/llpanelprofilepicks.cpp
+++ b/indra/newview/llpanelprofilepicks.cpp
@@ -63,6 +63,30 @@ public:
// requires trusted browser to trigger
LLPickHandler() : LLCommandHandler("pick", UNTRUSTED_THROTTLE) { }
+ virtual bool canHandleUntrusted(
+ const LLSD& params,
+ const LLSD& query_map,
+ LLMediaCtrl* web,
+ const std::string& nav_type)
+ {
+ if (params.size() < 1)
+ {
+ return true; // don't block, will fail later
+ }
+
+ if (nav_type == NAV_TYPE_CLICKED)
+ {
+ return true;
+ }
+
+ const std::string verb = params[0].asString();
+ if (verb == "create")
+ {
+ return false;
+ }
+ return true;
+ }
+
bool handle(const LLSD& params, const LLSD& query_map,
LLMediaCtrl* web)
{
diff --git a/indra/newview/llpreviewnotecard.cpp b/indra/newview/llpreviewnotecard.cpp
index 2eccc0474f..20b821f895 100644
--- a/indra/newview/llpreviewnotecard.cpp
+++ b/indra/newview/llpreviewnotecard.cpp
@@ -255,7 +255,7 @@ void LLPreviewNotecard::loadAsset()
else
{
LLHost source_sim = LLHost();
- LLSD* user_data = new LLSD();
+ LLSD* user_data = nullptr;
if (mObjectUUID.notNull())
{
LLViewerObject *objectp = gObjectList.findObject(mObjectUUID);
@@ -274,6 +274,7 @@ void LLPreviewNotecard::loadAsset()
mAssetStatus = PREVIEW_ASSET_LOADED;
return;
}
+ user_data = new LLSD();
user_data->with("taskid", mObjectUUID).with("itemid", mItemUUID);
}
else
diff --git a/indra/newview/llscenemonitor.cpp b/indra/newview/llscenemonitor.cpp
index fb2577e00e..8d86e2de4c 100644
--- a/indra/newview/llscenemonitor.cpp
+++ b/indra/newview/llscenemonitor.cpp
@@ -515,7 +515,7 @@ void LLSceneMonitor::fetchQueryResult()
}
//dump results to a file _scene_xmonitor_results.csv
-void LLSceneMonitor::dumpToFile(std::string file_name)
+void LLSceneMonitor::dumpToFile(const std::string &file_name)
{
if (!hasResults()) return;
diff --git a/indra/newview/llscenemonitor.h b/indra/newview/llscenemonitor.h
index 7cd531bd34..f2e1ef69b9 100644
--- a/indra/newview/llscenemonitor.h
+++ b/indra/newview/llscenemonitor.h
@@ -61,7 +61,7 @@ public:
bool needsUpdate() const;
const LLTrace::ExtendablePeriodicRecording* getRecording() const {return &mSceneLoadRecording;}
- void dumpToFile(std::string file_name);
+ void dumpToFile(const std::string &file_name);
bool hasResults() const { return mSceneLoadRecording.getResults().getDuration() != S32Seconds(0);}
void reset();
diff --git a/indra/newview/llscriptfloater.cpp b/indra/newview/llscriptfloater.cpp
index da912ef3d4..6a27ff3047 100644
--- a/indra/newview/llscriptfloater.cpp
+++ b/indra/newview/llscriptfloater.cpp
@@ -460,10 +460,11 @@ void LLScriptFloaterManager::onAddNotification(const LLUUID& notification_id)
if(it != mNotifications.end())
{
+ LLUUID old_id = it->first; // copy LLUUID to prevent use after free when it is erased below
LLChicletPanel * chiclet_panelp = LLChicletBar::getInstance()->getChicletPanel();
if (NULL != chiclet_panelp)
{
- LLIMChiclet * chicletp = chiclet_panelp->findChiclet<LLIMChiclet>(it->first);
+ LLIMChiclet * chicletp = chiclet_panelp->findChiclet<LLIMChiclet>(old_id);
if (NULL != chicletp)
{
// Pass the new_message icon state further.
@@ -472,14 +473,14 @@ void LLScriptFloaterManager::onAddNotification(const LLUUID& notification_id)
}
}
- LLScriptFloater* floater = LLFloaterReg::findTypedInstance<LLScriptFloater>("script_floater", it->first);
+ LLScriptFloater* floater = LLFloaterReg::findTypedInstance<LLScriptFloater>("script_floater", old_id);
if (floater)
{
// Generate chiclet with a "new message" indicator if a docked window was opened but not in focus. See EXT-3142.
set_new_message |= !floater->hasFocus();
}
- removeNotification(it->first);
+ removeNotification(old_id);
}
}
diff --git a/indra/newview/llspeakers.cpp b/indra/newview/llspeakers.cpp
index ea671a130e..60bada8f58 100644
--- a/indra/newview/llspeakers.cpp
+++ b/indra/newview/llspeakers.cpp
@@ -982,7 +982,6 @@ void LLActiveSpeakerMgr::updateSpeakerList()
// clean up text only speakers
for (speaker_map_t::iterator speaker_it = mSpeakers.begin(); speaker_it != mSpeakers.end(); ++speaker_it)
{
- LLUUID speaker_id = speaker_it->first;
LLSpeaker* speakerp = speaker_it->second;
if (speakerp->mStatus == LLSpeaker::STATUS_TEXT_ONLY)
{
diff --git a/indra/newview/llspeakingindicatormanager.cpp b/indra/newview/llspeakingindicatormanager.cpp
index 5ca1d4b4a5..0111d8869c 100644
--- a/indra/newview/llspeakingindicatormanager.cpp
+++ b/indra/newview/llspeakingindicatormanager.cpp
@@ -51,6 +51,10 @@ class SpeakingIndicatorManager : public LLSingleton<SpeakingIndicatorManager>, L
LLSINGLETON(SpeakingIndicatorManager);
~SpeakingIndicatorManager();
LOG_CLASS(SpeakingIndicatorManager);
+
+protected:
+ void cleanupSingleton();
+
public:
/**
@@ -183,12 +187,16 @@ SpeakingIndicatorManager::SpeakingIndicatorManager()
SpeakingIndicatorManager::~SpeakingIndicatorManager()
{
- // Don't use LLVoiceClient::getInstance() here without check
- // singleton MAY have already been destroyed.
- if(LLVoiceClient::instanceExists())
- {
- LLVoiceClient::getInstance()->removeObserver(this);
- }
+}
+
+void SpeakingIndicatorManager::cleanupSingleton()
+{
+ // Don't use LLVoiceClient::getInstance() here without a check,
+ // singleton MAY have already been destroyed.
+ if (LLVoiceClient::instanceExists())
+ {
+ LLVoiceClient::getInstance()->removeObserver(this);
+ }
}
void SpeakingIndicatorManager::sOnCurrentChannelChanged(const LLUUID& /*session_id*/)
diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp
index 0019038c76..0dc4746123 100644
--- a/indra/newview/llstartup.cpp
+++ b/indra/newview/llstartup.cpp
@@ -273,12 +273,10 @@ void show_first_run_dialog();
bool first_run_dialog_callback(const LLSD& notification, const LLSD& response);
void set_startup_status(const F32 frac, const std::string& string, const std::string& msg);
bool login_alert_status(const LLSD& notification, const LLSD& response);
-void login_packet_failed(void**, S32 result);
void use_circuit_callback(void**, S32 result);
void register_viewer_callbacks(LLMessageSystem* msg);
void asset_callback_nothing(const LLUUID&, LLAssetType::EType, void*, S32);
bool callback_choose_gender(const LLSD& notification, const LLSD& response);
-void init_start_screen(S32 location_id);
void release_start_screen();
void reset_login();
LLSD transform_cert_args(LLPointer<LLCertificate> cert);
diff --git a/indra/newview/lltoastnotifypanel.cpp b/indra/newview/lltoastnotifypanel.cpp
index 024f25bc98..bf3f4c1e88 100644
--- a/indra/newview/lltoastnotifypanel.cpp
+++ b/indra/newview/lltoastnotifypanel.cpp
@@ -89,6 +89,7 @@ LLButton* LLToastNotifyPanel::createButton(const LLSD& form_element, BOOL is_opt
const LLFontGL* font = make_small_btn ? sFontSmall: sFont; // for block and ignore buttons in script dialog
p.name = form_element["name"].asString();
p.label = form_element["text"].asString();
+ p.tool_tip = form_element["text"].asString();
p.font = font;
p.rect.height = BTN_HEIGHT;
p.click_callback.function(boost::bind(&LLToastNotifyPanel::onClickButton, userdata));
diff --git a/indra/newview/lltoolbarview.cpp b/indra/newview/lltoolbarview.cpp
index 752fc6f3f3..01d799dcd5 100644
--- a/indra/newview/lltoolbarview.cpp
+++ b/indra/newview/lltoolbarview.cpp
@@ -44,7 +44,6 @@
#include "llagent.h" // HACK for destinations guide on startup
#include "llfloaterreg.h" // HACK for destinations guide on startup
#include "llviewercontrol.h" // HACK for destinations guide on startup
-#include "llinventorymodel.h" // HACK to disable starter avatars button for NUX
#include <boost/foreach.hpp>
@@ -320,22 +319,6 @@ bool LLToolBarView::loadToolbars(bool force_default)
}
}
}
-
- // SL-18581: Don't show the starter avatar toolbar button for NUX users
- LLViewerInventoryCategory* my_outfits_cat = gInventory.getCategory(gInventory.findCategoryUUIDForType(LLFolderType::FT_MY_OUTFITS));
- if (gAgent.isFirstLogin()
- && my_outfits_cat != NULL
- && my_outfits_cat->getDescendentCount() > 0)
- {
- for (S32 i = LLToolBarEnums::TOOLBAR_FIRST; i <= LLToolBarEnums::TOOLBAR_LAST; i++)
- {
- if (mToolbars[i])
- {
- mToolbars[i]->removeCommand(LLCommandId("avatar"));
- }
- }
- }
-
mToolbarsLoaded = true;
return true;
}
diff --git a/indra/newview/llurldispatcher.cpp b/indra/newview/llurldispatcher.cpp
index a1670351f4..7c92e7ef98 100644
--- a/indra/newview/llurldispatcher.cpp
+++ b/indra/newview/llurldispatcher.cpp
@@ -263,7 +263,7 @@ public:
// inside the app, otherwise a malicious web page could
// cause a constant teleport loop. JC
LLTeleportHandler() :
- LLCommandHandler("teleport", UNTRUSTED_THROTTLE),
+ LLCommandHandler("teleport", UNTRUSTED_CLICK_ONLY),
LLEventAPI("LLTeleportHandler", "Low-level teleport API")
{
LLEventAPI::add("teleport",
diff --git a/indra/newview/llviewerfloaterreg.cpp b/indra/newview/llviewerfloaterreg.cpp
index f30c2195d3..14d5a7c276 100644
--- a/indra/newview/llviewerfloaterreg.cpp
+++ b/indra/newview/llviewerfloaterreg.cpp
@@ -174,11 +174,103 @@ const std::string FLOATER_PROFILE("profile");
class LLFloaterOpenHandler : public LLCommandHandler
{
public:
- // requires trusted browser to trigger
+ // requires trusted browser to trigger or an explicit click
LLFloaterOpenHandler() : LLCommandHandler("openfloater", UNTRUSTED_THROTTLE) { }
- bool handle(const LLSD& params, const LLSD& query_map,
- LLMediaCtrl* web)
+ bool canHandleUntrusted(
+ const LLSD& params,
+ const LLSD& query_map,
+ LLMediaCtrl* web,
+ const std::string& nav_type) override
+ {
+ if (params.size() != 1)
+ {
+ return true; // will fail silently
+ }
+
+ std::string fl_name = params[0].asString();
+
+ if (nav_type == NAV_TYPE_CLICKED)
+ {
+ const std::list<std::string> blacklist_clicked = {
+ "camera_presets",
+ "delete_pref_preset",
+ "forget_username",
+ "god_tools",
+ "group_picker",
+ "hud",
+ "incoming_call",
+ "linkreplace",
+ "message_critical", // Modal!!! Login specific.
+ "message_tos", // Modal!!! Login specific.
+ "save_pref_preset",
+ "save_camera_preset",
+ "region_restarting",
+ "outfit_snapshot",
+ "upload_anim_bvh",
+ "upload_anim_anim",
+ "upload_image",
+ "upload_model",
+ "upload_script",
+ "upload_sound"
+ };
+ return std::find(blacklist_clicked.begin(), blacklist_clicked.end(), fl_name) == blacklist_clicked.end();
+ }
+ else
+ {
+ const std::list<std::string> blacklist_untrusted = {
+ "360capture",
+ "block_timers",
+ "add_payment_method",
+ "appearance",
+ "associate_listing",
+ "avatar_picker",
+ "camera",
+ "camera_presets",
+ "classified",
+ "add_landmark",
+ "delete_pref_preset",
+ "env_fixed_environmentent_water",
+ "env_fixed_environmentent_sky",
+ "env_edit_extdaycycle",
+ "font_test",
+ "forget_username",
+ "god_tools",
+ "group_picker",
+ "hud",
+ "incoming_call",
+ "linkreplace",
+ "mem_leaking",
+ "marketplace_validation",
+ "message_critical", // Modal!!! Login specific. If this is in use elsewhere, better to create a non modal variant
+ "message_tos", // Modal!!! Login specific.
+ "mute_object_by_name",
+ "publish_classified",
+ "save_pref_preset",
+ "save_camera_preset",
+ "region_restarting",
+ "script_debug",
+ "script_debug_output",
+ "sell_land",
+ "outfit_snapshot",
+ "upload_anim_bvh",
+ "upload_anim_anim",
+ "upload_image",
+ "upload_model",
+ "upload_script",
+ "upload_sound"
+ };
+ return std::find(blacklist_untrusted.begin(), blacklist_untrusted.end(), fl_name) == blacklist_untrusted.end();
+ }
+
+
+ return true;
+ }
+
+ bool handle(
+ const LLSD& params,
+ const LLSD& query_map,
+ LLMediaCtrl* web) override
{
if (params.size() != 1)
{
diff --git a/indra/newview/llviewerinput.cpp b/indra/newview/llviewerinput.cpp
index 43b9cd90bd..6bab2c2100 100644
--- a/indra/newview/llviewerinput.cpp
+++ b/indra/newview/llviewerinput.cpp
@@ -1614,12 +1614,22 @@ BOOL LLViewerInput::handleMouse(LLWindow *window_impl, LLCoordGL pos, MASK mask,
clicktype = CLICK_DOUBLELEFT;
}
+ // If the first LMB click is handled by the menu, skip the following double click
+ static bool skip_double_click = false;
+ if (clicktype == CLICK_LEFT && down )
+ {
+ skip_double_click = handled;
+ }
if (double_click_sp && down)
{
// Consume click.
// Due to handling, double click that is not handled will be immediately followed by LMB click
}
+ else if (clicktype == CLICK_DOUBLELEFT && skip_double_click)
+ {
+ handled = true;
+ }
// If UI handled 'down', it should handle 'up' as well
// If we handle 'down' not by UI, then we should handle 'up'/'level' regardless of UI
else if (handled)
diff --git a/indra/newview/llviewerinventory.cpp b/indra/newview/llviewerinventory.cpp
index b4feafb7ff..518967709d 100644
--- a/indra/newview/llviewerinventory.cpp
+++ b/indra/newview/llviewerinventory.cpp
@@ -233,7 +233,7 @@ class LLInventoryHandler : public LLCommandHandler
{
public:
// requires trusted browser to trigger
- LLInventoryHandler() : LLCommandHandler("inventory", UNTRUSTED_THROTTLE) { }
+ LLInventoryHandler() : LLCommandHandler("inventory", UNTRUSTED_CLICK_ONLY) { }
bool handle(const LLSD& params, const LLSD& query_map,
LLMediaCtrl* web)
diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp
index 4ba4c5f935..bc722f496f 100644
--- a/indra/newview/llviewermenu.cpp
+++ b/indra/newview/llviewermenu.cpp
@@ -2711,14 +2711,15 @@ void handle_object_show_original()
}
-static void init_default_item_label(const std::string& item_name)
+static void init_default_item_label(LLUICtrl* ctrl)
{
+ const std::string& item_name = ctrl->getName();
boost::unordered_map<std::string, LLStringExplicit>::iterator it = sDefaultItemLabels.find(item_name);
if (it == sDefaultItemLabels.end())
{
// *NOTE: This will not work for items of type LLMenuItemCheckGL because they return boolean value
// (doesn't seem to matter much ATM).
- LLStringExplicit default_label = gMenuHolder->childGetValue(item_name).asString();
+ LLStringExplicit default_label = ctrl->getValue().asString();
if (!default_label.empty())
{
sDefaultItemLabels.insert(std::pair<std::string, LLStringExplicit>(item_name, default_label));
@@ -2749,18 +2750,17 @@ bool enable_object_touch(LLUICtrl* ctrl)
new_value = obj->flagHandleTouch() || (parent && parent->flagHandleTouch());
}
- std::string item_name = ctrl->getName();
- init_default_item_label(item_name);
+ init_default_item_label(ctrl);
// Update label based on the node touch name if available.
LLSelectNode* node = LLSelectMgr::getInstance()->getSelection()->getFirstRootNode();
if (node && node->mValid && !node->mTouchName.empty())
{
- gMenuHolder->childSetValue(item_name, node->mTouchName);
+ ctrl->setValue(node->mTouchName);
}
else
{
- gMenuHolder->childSetValue(item_name, get_default_item_label(item_name));
+ ctrl->setValue(get_default_item_label(ctrl->getName()));
}
return new_value;
@@ -5612,6 +5612,7 @@ class LLToolsSelectNextPartFace : public view_listener_t
}
}
LLSelectMgr::getInstance()->selectObjectOnly(to_select, new_te);
+ LLSelectMgr::getInstance()->addAsIndividual(to_select, new_te, false);
}
else
{
@@ -6575,20 +6576,18 @@ bool enable_object_sit(LLUICtrl* ctrl)
bool sitting_on_sel = sitting_on_selection();
if (!sitting_on_sel)
{
- std::string item_name = ctrl->getName();
-
// init default labels
- init_default_item_label(item_name);
+ init_default_item_label(ctrl);
// Update label
LLSelectNode* node = LLSelectMgr::getInstance()->getSelection()->getFirstRootNode();
if (node && node->mValid && !node->mSitName.empty())
{
- gMenuHolder->childSetValue(item_name, node->mSitName);
+ ctrl->setValue(node->mSitName);
}
else
{
- gMenuHolder->childSetValue(item_name, get_default_item_label(item_name));
+ ctrl->setValue(get_default_item_label(ctrl->getName()));
}
}
return !sitting_on_sel && is_object_sittable();
@@ -7634,7 +7633,6 @@ void handle_selected_texture_info(void*)
map_t::iterator it;
for (it = faces_per_texture.begin(); it != faces_per_texture.end(); ++it)
{
- LLUUID image_id = it->first;
U8 te = it->second[0];
LLViewerTexture* img = node->getObject()->getTEImage(te);
S32 height = img->getHeight();
diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp
index 5a365c79ea..9492604d7d 100644
--- a/indra/newview/llviewerobject.cpp
+++ b/indra/newview/llviewerobject.cpp
@@ -3248,36 +3248,39 @@ void LLViewerObject::processTaskInv(LLMessageSystem* msg, void** user_data)
return;
}
- LLFilenameAndTask* ft = new LLFilenameAndTask;
- ft->mTaskID = task_id;
// we can receive multiple task updates simultaneously, make sure we will not rewrite newer with older update
- msg->getS16Fast(_PREHASH_InventoryData, _PREHASH_Serial, ft->mSerial);
+ S16 serial = 0;
+ msg->getS16Fast(_PREHASH_InventoryData, _PREHASH_Serial, serial);
- if (ft->mSerial == object->mInventorySerialNum
- && ft->mSerial < object->mExpectedInventorySerialNum)
+ if (serial == object->mInventorySerialNum
+ && serial < object->mExpectedInventorySerialNum)
{
// Loop Protection.
// We received same serial twice.
// Viewer did some changes to inventory that couldn't be saved server side
// or something went wrong to cause serial to be out of sync.
// Drop xfer and restart after some time, assign server's value as expected
- LL_WARNS() << "Task inventory serial might be out of sync, server serial: " << ft->mSerial << " client expected serial: " << object->mExpectedInventorySerialNum << LL_ENDL;
- object->mExpectedInventorySerialNum = ft->mSerial;
+ LL_WARNS() << "Task inventory serial might be out of sync, server serial: " << serial << " client expected serial: " << object->mExpectedInventorySerialNum << LL_ENDL;
+ object->mExpectedInventorySerialNum = serial;
object->fetchInventoryDelayed(INVENTORY_UPDATE_WAIT_TIME_DESYNC);
}
- else if (ft->mSerial < object->mExpectedInventorySerialNum)
+ else if (serial < object->mExpectedInventorySerialNum)
{
// Out of date message, record to current serial for loop protection, but do not load it
// Drop xfer and restart after some time
- if (ft->mSerial < object->mInventorySerialNum)
+ if (serial < object->mInventorySerialNum)
{
LL_WARNS() << "Task serial decreased. Potentially out of order packet or desync." << LL_ENDL;
}
- object->mInventorySerialNum = ft->mSerial;
+ object->mInventorySerialNum = serial;
object->fetchInventoryDelayed(INVENTORY_UPDATE_WAIT_TIME_OUTDATED);
}
- else if (ft->mSerial >= object->mExpectedInventorySerialNum)
+ else if (serial >= object->mExpectedInventorySerialNum)
{
+ LLFilenameAndTask* ft = new LLFilenameAndTask;
+ ft->mTaskID = task_id;
+ ft->mSerial = serial;
+
// We received version we expected or newer. Load it.
object->mInventorySerialNum = ft->mSerial;
object->mExpectedInventorySerialNum = ft->mSerial;
@@ -3312,7 +3315,7 @@ void LLViewerObject::processTaskInv(LLMessageSystem* msg, void** user_data)
object->mRegionp->getHost(),
TRUE,
&LLViewerObject::processTaskInvFile,
- (void**)ft,
+ (void**)ft, // This takes ownership of ft
LLXferManager::HIGH_PRIORITY);
if (object->mInvRequestState == INVENTORY_XFER)
{
diff --git a/indra/newview/llviewerpartsource.cpp b/indra/newview/llviewerpartsource.cpp
index f042040e98..1751ee1ebb 100644
--- a/indra/newview/llviewerpartsource.cpp
+++ b/indra/newview/llviewerpartsource.cpp
@@ -793,7 +793,7 @@ void LLViewerPartSourceBeam::update(const F32 dt)
}
LLViewerPart* part = new LLViewerPart();
- part->init(this, mImagep, NULL);
+ part->init(this, mImagep, updatePart);
part->mFlags = LLPartData::LL_PART_INTERP_COLOR_MASK |
LLPartData::LL_PART_INTERP_SCALE_MASK |
diff --git a/indra/newview/llviewertexteditor.cpp b/indra/newview/llviewertexteditor.cpp
index 3f302d4f45..1353eea2f2 100644
--- a/indra/newview/llviewertexteditor.cpp
+++ b/indra/newview/llviewertexteditor.cpp
@@ -1278,7 +1278,6 @@ bool LLViewerTextEditor::onCopyToInvDialog(const LLSD& notification, const LLSD&
S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
if( 0 == option )
{
- LLUUID item_id = notification["payload"]["item_id"].asUUID();
llwchar wc = llwchar(notification["payload"]["item_wc"].asInteger());
LLInventoryItem* itemp = LLEmbeddedItems::getEmbeddedItemPtr(wc);
if (itemp)
diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp
index 20b5f7f394..5c1467f28f 100644
--- a/indra/newview/llviewerwindow.cpp
+++ b/indra/newview/llviewerwindow.cpp
@@ -1255,7 +1255,6 @@ LLWindowCallbacks::DragNDropResult LLViewerWindow::handleDragNDrop( LLWindow *wi
TRUE /* pick_transparent */,
FALSE /* pick_rigged */);
- LLUUID object_id = pick_info.getObjectID();
S32 object_face = pick_info.mObjectFace;
std::string url = data;
@@ -3380,6 +3379,59 @@ void LLViewerWindow::updateUI()
root_view = mRootView;
}
+ static LLCachedControl<bool> dump_menu_holder(gSavedSettings, "DumpMenuHolderSize", false);
+ if (dump_menu_holder)
+ {
+ static bool init = false;
+ static LLFrameTimer child_count_timer;
+ static std::vector <std::string> child_vec;
+ if (!init)
+ {
+ child_count_timer.resetWithExpiry(5.f);
+ init = true;
+ }
+ if (child_count_timer.hasExpired())
+ {
+ LL_INFOS() << "gMenuHolder child count: " << gMenuHolder->getChildCount() << LL_ENDL;
+ std::vector<std::string> local_child_vec;
+ LLView::child_list_t child_list = *gMenuHolder->getChildList();
+ for (auto child : child_list)
+ {
+ local_child_vec.emplace_back(child->getName());
+ }
+ if (!local_child_vec.empty() && local_child_vec != child_vec)
+ {
+ std::vector<std::string> out_vec;
+ std::sort(local_child_vec.begin(), local_child_vec.end());
+ std::sort(child_vec.begin(), child_vec.end());
+ std::set_difference(child_vec.begin(), child_vec.end(), local_child_vec.begin(), local_child_vec.end(), std::inserter(out_vec, out_vec.begin()));
+ if (!out_vec.empty())
+ {
+ LL_INFOS() << "gMenuHolder removal diff size: '"<<out_vec.size() <<"' begin_child_diff";
+ for (auto str : out_vec)
+ {
+ LL_CONT << " : " << str;
+ }
+ LL_CONT << " : end_child_diff" << LL_ENDL;
+ }
+
+ out_vec.clear();
+ std::set_difference(local_child_vec.begin(), local_child_vec.end(), child_vec.begin(), child_vec.end(), std::inserter(out_vec, out_vec.begin()));
+ if (!out_vec.empty())
+ {
+ LL_INFOS() << "gMenuHolder addition diff size: '" << out_vec.size() << "' begin_child_diff";
+ for (auto str : out_vec)
+ {
+ LL_CONT << " : " << str;
+ }
+ LL_CONT << " : end_child_diff" << LL_ENDL;
+ }
+ child_vec.swap(local_child_vec);
+ }
+ child_count_timer.resetWithExpiry(5.f);
+ }
+ }
+
// only update mouse hover set when UI is visible (since we shouldn't send hover events to invisible UI
if (gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI))
{
diff --git a/indra/newview/llvoiceclient.cpp b/indra/newview/llvoiceclient.cpp
index 2ef2d66f18..6bb987ede4 100644
--- a/indra/newview/llvoiceclient.cpp
+++ b/indra/newview/llvoiceclient.cpp
@@ -797,7 +797,10 @@ void LLVoiceClient::addObserver(LLVoiceClientStatusObserver* observer)
void LLVoiceClient::removeObserver(LLVoiceClientStatusObserver* observer)
{
- if (mVoiceModule && mVoiceModule->singletoneInstanceExists()) mVoiceModule->removeObserver(observer);
+ if (mVoiceModule)
+ {
+ mVoiceModule->removeObserver(observer);
+ }
}
void LLVoiceClient::addObserver(LLFriendObserver* observer)
@@ -807,7 +810,10 @@ void LLVoiceClient::addObserver(LLFriendObserver* observer)
void LLVoiceClient::removeObserver(LLFriendObserver* observer)
{
- if (mVoiceModule && mVoiceModule->singletoneInstanceExists()) mVoiceModule->removeObserver(observer);
+ if (mVoiceModule)
+ {
+ mVoiceModule->removeObserver(observer);
+ }
}
void LLVoiceClient::addObserver(LLVoiceClientParticipantObserver* observer)
@@ -817,7 +823,10 @@ void LLVoiceClient::addObserver(LLVoiceClientParticipantObserver* observer)
void LLVoiceClient::removeObserver(LLVoiceClientParticipantObserver* observer)
{
- if (mVoiceModule && mVoiceModule->singletoneInstanceExists()) mVoiceModule->removeObserver(observer);
+ if (mVoiceModule)
+ {
+ mVoiceModule->removeObserver(observer);
+ }
}
std::string LLVoiceClient::sipURIFromID(const LLUUID &id)
diff --git a/indra/newview/llvoiceclient.h b/indra/newview/llvoiceclient.h
index 246883b611..aa67502908 100644
--- a/indra/newview/llvoiceclient.h
+++ b/indra/newview/llvoiceclient.h
@@ -122,8 +122,6 @@ public:
virtual const LLVoiceVersionInfo& getVersion()=0;
- virtual bool singletoneInstanceExists()=0;
-
/////////////////////
/// @name Tuning
//@{
diff --git a/indra/newview/llvoicevivox.cpp b/indra/newview/llvoicevivox.cpp
index ab90f2e482..8f0938d01e 100644
--- a/indra/newview/llvoicevivox.cpp
+++ b/indra/newview/llvoicevivox.cpp
@@ -5215,11 +5215,6 @@ void LLVivoxVoiceClient::declineInvite(std::string &sessionHandle)
}
}
-bool LLVivoxVoiceClient::singletoneInstanceExists()
-{
- return LLVivoxVoiceClient::instanceExists();
-}
-
void LLVivoxVoiceClient::leaveNonSpatialChannel()
{
LL_DEBUGS("Voice") << "Request to leave spacial channel." << LL_ENDL;
diff --git a/indra/newview/llvoicevivox.h b/indra/newview/llvoicevivox.h
index ebc3a62c35..0a785401c1 100644
--- a/indra/newview/llvoicevivox.h
+++ b/indra/newview/llvoicevivox.h
@@ -73,8 +73,6 @@ public:
// Returns true if vivox has successfully logged in and is not in error state
virtual bool isVoiceWorking() const;
-
- virtual bool singletoneInstanceExists();
/////////////////////
/// @name Tuning
diff --git a/indra/newview/llvosky.cpp b/indra/newview/llvosky.cpp
index 59fcacf914..4b3b348d50 100644
--- a/indra/newview/llvosky.cpp
+++ b/indra/newview/llvosky.cpp
@@ -100,8 +100,8 @@ LLSkyTex::LLSkyTex() :
void LLSkyTex::init(bool isShiny)
{
mIsShiny = isShiny;
- mSkyData = new LLColor4[SKYTEX_RESOLUTION * SKYTEX_RESOLUTION];
- mSkyDirs = new LLVector3[SKYTEX_RESOLUTION * SKYTEX_RESOLUTION];
+ mSkyData = new LLColor4[(U32)(SKYTEX_RESOLUTION * SKYTEX_RESOLUTION)];
+ mSkyDirs = new LLVector3[(U32)(SKYTEX_RESOLUTION * SKYTEX_RESOLUTION)];
for (S32 i = 0; i < 2; ++i)
{
diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp
index 02d1654878..fd1c137a56 100644
--- a/indra/newview/llvovolume.cpp
+++ b/indra/newview/llvovolume.cpp
@@ -230,6 +230,9 @@ LLVOVolume::LLVOVolume(const LLUUID &id, const LLPCode pcode, LLViewerRegion *re
mColorChanged = FALSE;
mSpotLightPriority = 0.f;
+ mSkinInfoFailed = false;
+ mSkinInfo = NULL;
+
mMediaImplList.resize(getNumTEs());
mLastFetchedMediaVersion = -1;
mServerDrawableUpdateCount = 0;
@@ -246,6 +249,8 @@ LLVOVolume::~LLVOVolume()
delete mVolumeImpl;
mVolumeImpl = NULL;
+ gMeshRepo.unregisterMesh(this);
+
if(!mMediaImplList.empty())
{
for(U32 i = 0 ; i < mMediaImplList.size() ; i++)
@@ -869,10 +874,7 @@ void LLVOVolume::updateTextureVirtualSize(bool forced)
if (isSculpted())
{
- LLSculptParams *sculpt_params = (LLSculptParams *)getParameterEntry(LLNetworkData::PARAMS_SCULPT);
- LLUUID id = sculpt_params->getSculptTexture();
-
- updateSculptTexture();
+ updateSculptTexture();
@@ -1116,10 +1118,15 @@ BOOL LLVOVolume::setVolume(const LLVolumeParams &params_in, const S32 detail, bo
// if it's a mesh
if ((volume_params.getSculptType() & LL_SCULPT_TYPE_MASK) == LL_SCULPT_TYPE_MESH)
{
+ if (mSkinInfo && mSkinInfo->mMeshID != volume_params.getSculptID())
+ {
+ mSkinInfo = NULL;
+ mSkinInfoFailed = false;
+ }
+
if (!getVolume()->isMeshAssetLoaded())
{
//load request not yet issued, request pipeline load this mesh
- LLUUID asset_id = volume_params.getSculptID();
S32 available_lod = gMeshRepo.loadMesh(this, volume_params, lod, last_lod);
if (available_lod != lod)
{
@@ -1127,6 +1134,14 @@ BOOL LLVOVolume::setVolume(const LLVolumeParams &params_in, const S32 detail, bo
}
}
+ if (!mSkinInfo && !mSkinInfoFailed)
+ {
+ const LLMeshSkinInfo* skin_info = gMeshRepo.getSkinInfo(volume_params.getSculptID(), this);
+ if (skin_info)
+ {
+ notifySkinInfoLoaded(skin_info);
+ }
+ }
}
else // otherwise is sculptie
{
@@ -1159,6 +1174,9 @@ void LLVOVolume::updateSculptTexture()
{
mSculptTexture = LLViewerTextureManager::getFetchedTexture(id, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE);
}
+
+ mSkinInfoFailed = false;
+ mSkinInfo = NULL;
}
else
{
@@ -1213,6 +1231,20 @@ void LLVOVolume::notifyMeshLoaded()
updateVisualComplexity();
}
+void LLVOVolume::notifySkinInfoLoaded(const LLMeshSkinInfo* skin)
+{
+ mSkinInfoFailed = false;
+ mSkinInfo = skin;
+
+ notifyMeshLoaded();
+}
+
+void LLVOVolume::notifySkinInfoUnavailable()
+{
+ mSkinInfoFailed = true;
+ mSkinInfo = nullptr;
+}
+
// sculpt replaces generate() for sculpted surfaces
void LLVOVolume::sculpt()
{
@@ -3586,7 +3618,7 @@ const LLMeshSkinInfo* LLVOVolume::getSkinInfo() const
{
if (getVolume())
{
- return gMeshRepo.getSkinInfo(getMeshID(), this);
+ return mSkinInfo;
}
else
{
diff --git a/indra/newview/llvovolume.h b/indra/newview/llvovolume.h
index 1c44ddfc5d..9cfd90a940 100644
--- a/indra/newview/llvovolume.h
+++ b/indra/newview/llvovolume.h
@@ -376,6 +376,8 @@ public:
void updateVisualComplexity();
void notifyMeshLoaded();
+ void notifySkinInfoLoaded(const LLMeshSkinInfo* skin);
+ void notifySkinInfoUnavailable();
// Returns 'true' iff the media data for this object is in flight
bool isMediaDataBeingFetched() const;
@@ -463,6 +465,8 @@ private:
LLPointer<LLRiggedVolume> mRiggedVolume;
+ bool mSkinInfoFailed;
+ LLConstPointer<LLMeshSkinInfo> mSkinInfo;
// statics
public:
static F32 sLODSlopDistanceFactor;// Changing this to zero, effectively disables the LOD transition slop
diff --git a/indra/newview/llwearableitemslist.cpp b/indra/newview/llwearableitemslist.cpp
index bf4db81475..89b74ae962 100644
--- a/indra/newview/llwearableitemslist.cpp
+++ b/indra/newview/llwearableitemslist.cpp
@@ -92,17 +92,77 @@ LLPanelWearableListItem::LLPanelWearableListItem(LLViewerInventoryItem* item, co
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
+static LLWidgetNameRegistry::StaticRegistrar sRegisterPanelWearableOutfitItem(&typeid(LLPanelWearableOutfitItem::Params), "wearable_outfit_list_item");
+
+LLPanelWearableOutfitItem::Params::Params()
+: add_btn("add_btn"),
+ remove_btn("remove_btn")
+{
+}
+
+BOOL LLPanelWearableOutfitItem::postBuild()
+{
+ LLPanelWearableListItem::postBuild();
+
+ LLViewerInventoryItem* inv_item = getItem();
+ mShowWidgets &= (inv_item->getType() != LLAssetType::AT_BODYPART);
+ if(mShowWidgets)
+ {
+ addWidgetToRightSide("add_wearable");
+ addWidgetToRightSide("remove_wearable");
+
+ childSetAction("add_wearable", boost::bind(&LLPanelWearableOutfitItem::onAddWearable, this));
+ childSetAction("remove_wearable", boost::bind(&LLPanelWearableOutfitItem::onRemoveWearable, this));
+
+ setWidgetsVisible(false);
+ reshapeWidgets();
+ }
+ return TRUE;
+}
+
+BOOL LLPanelWearableOutfitItem::handleDoubleClick(S32 x, S32 y, MASK mask)
+{
+ if(!mShowWidgets)
+ {
+ return LLPanelWearableListItem::handleDoubleClick(x, y, mask);
+ }
+
+ if(LLAppearanceMgr::instance().isLinkedInCOF(mInventoryItemUUID))
+ {
+ onRemoveWearable();
+ }
+ else
+ {
+ onAddWearable();
+ }
+ return TRUE;
+}
+
+void LLPanelWearableOutfitItem::onAddWearable()
+{
+ setWidgetsVisible(false);
+ reshapeWidgets();
+ LLAppearanceMgr::instance().wearItemOnAvatar(mInventoryItemUUID, true, false);
+}
+
+void LLPanelWearableOutfitItem::onRemoveWearable()
+{
+ setWidgetsVisible(false);
+ reshapeWidgets();
+ LLAppearanceMgr::instance().removeItemFromAvatar(mInventoryItemUUID);
+}
// static
LLPanelWearableOutfitItem* LLPanelWearableOutfitItem::create(LLViewerInventoryItem* item,
- bool worn_indication_enabled)
+ bool worn_indication_enabled,
+ bool show_widgets)
{
LLPanelWearableOutfitItem* list_item = NULL;
if (item)
{
- const LLPanelInventoryListItemBase::Params& params = LLUICtrlFactory::getDefaultParams<LLPanelInventoryListItemBase>();
+ const LLPanelWearableOutfitItem::Params& params = LLUICtrlFactory::getDefaultParams<LLPanelWearableOutfitItem>();
- list_item = new LLPanelWearableOutfitItem(item, worn_indication_enabled, params);
+ list_item = new LLPanelWearableOutfitItem(item, worn_indication_enabled, params, show_widgets);
list_item->initFromParams(params);
list_item->postBuild();
}
@@ -110,11 +170,23 @@ LLPanelWearableOutfitItem* LLPanelWearableOutfitItem::create(LLViewerInventoryIt
}
LLPanelWearableOutfitItem::LLPanelWearableOutfitItem(LLViewerInventoryItem* item,
- bool worn_indication_enabled,
- const LLPanelWearableOutfitItem::Params& params)
-: LLPanelInventoryListItemBase(item, params)
+ bool worn_indication_enabled,
+ const LLPanelWearableOutfitItem::Params& params,
+ bool show_widgets)
+: LLPanelWearableListItem(item, params)
, mWornIndicationEnabled(worn_indication_enabled)
+, mShowWidgets(show_widgets)
{
+ if(mShowWidgets)
+ {
+ LLButton::Params button_params = params.add_btn;
+ applyXUILayout(button_params, this);
+ addChild(LLUICtrlFactory::create<LLButton>(button_params));
+
+ button_params = params.remove_btn;
+ applyXUILayout(button_params, this);
+ addChild(LLUICtrlFactory::create<LLButton>(button_params));
+ }
}
// virtual
@@ -127,11 +199,22 @@ void LLPanelWearableOutfitItem::updateItem(const std::string& name,
// We don't use get_is_item_worn() here because this update is triggered by
// an inventory observer upon link in COF beind added or removed so actual
// worn status of a linked item may still remain unchanged.
- if (mWornIndicationEnabled && LLAppearanceMgr::instance().isLinkedInCOF(mInventoryItemUUID))
+ bool is_worn = LLAppearanceMgr::instance().isLinkedInCOF(mInventoryItemUUID);
+ if (mWornIndicationEnabled && is_worn)
{
search_label += LLTrans::getString("worn");
item_state = IS_WORN;
}
+ if(mShowWidgets)
+ {
+ setShowWidget("add_wearable", !is_worn);
+ setShowWidget("remove_wearable", is_worn);
+ if(mHovered)
+ {
+ setWidgetsVisible(true);
+ reshapeWidgets();
+ }
+ }
LLPanelInventoryListItemBase::updateItem(search_label, item_state);
}
@@ -634,6 +717,7 @@ static const LLDefaultChildRegistry::Register<LLWearableItemsList> r("wearable_i
LLWearableItemsList::Params::Params()
: standalone("standalone", true)
, worn_indication_enabled("worn_indication_enabled", true)
+, show_item_widgets("show_item_widgets", false)
{}
LLWearableItemsList::LLWearableItemsList(const LLWearableItemsList::Params& p)
@@ -649,6 +733,7 @@ LLWearableItemsList::LLWearableItemsList(const LLWearableItemsList::Params& p)
}
mWornIndicationEnabled = p.worn_indication_enabled;
setNoItemsCommentText(LLTrans::getString("LoadingData"));
+ mShowItemWidgets = p.show_item_widgets;
}
// virtual
@@ -665,7 +750,7 @@ LLPanel* LLWearableItemsList::createNewItem(LLViewerInventoryItem* item)
return NULL;
}
- return LLPanelWearableOutfitItem::create(item, mWornIndicationEnabled);
+ return LLPanelWearableOutfitItem::create(item, mWornIndicationEnabled, mShowItemWidgets);
}
void LLWearableItemsList::updateList(const LLUUID& category_id)
diff --git a/indra/newview/llwearableitemslist.h b/indra/newview/llwearableitemslist.h
index ba8488b237..f7774a7086 100644
--- a/indra/newview/llwearableitemslist.h
+++ b/indra/newview/llwearableitemslist.h
@@ -72,12 +72,23 @@ protected:
* Extends LLPanelInventoryListItemBase with handling
* double click to wear the item.
*/
-class LLPanelWearableOutfitItem : public LLPanelInventoryListItemBase
+class LLPanelWearableOutfitItem : public LLPanelWearableListItem
{
LOG_CLASS(LLPanelWearableOutfitItem);
public:
+ struct Params : public LLInitParam::Block<Params, LLPanelWearableListItem::Params>
+ {
+ Optional<LLButton::Params> add_btn, remove_btn;
+
+ Params();
+ };
+
+ BOOL postBuild();
+ BOOL handleDoubleClick(S32 x, S32 y, MASK mask);
+
static LLPanelWearableOutfitItem* create(LLViewerInventoryItem* item,
- bool worn_indication_enabled);
+ bool worn_indication_enabled,
+ bool show_widgets);
/**
* Updates item name and (worn) suffix.
@@ -85,12 +96,16 @@ public:
/*virtual*/ void updateItem(const std::string& name,
EItemState item_state = IS_DEFAULT);
+ void onAddWearable();
+ void onRemoveWearable();
+
protected:
LLPanelWearableOutfitItem(LLViewerInventoryItem* item,
- bool worn_indication_enabled, const Params& params);
+ bool worn_indication_enabled, const Params& params, bool show_widgets = false);
private:
bool mWornIndicationEnabled;
+ bool mShowWidgets;
};
class LLPanelDeletableWearableListItem : public LLPanelWearableListItem
@@ -442,6 +457,7 @@ public:
{
Optional<bool> standalone;
Optional<bool> worn_indication_enabled;
+ Optional<bool> show_item_widgets;
Params();
};
@@ -482,6 +498,7 @@ protected:
bool mIsStandalone;
bool mWornIndicationEnabled;
+ bool mShowItemWidgets;
ESortOrder mSortOrder;
diff --git a/indra/newview/llworld.cpp b/indra/newview/llworld.cpp
index 5b91e26785..bba5f6dca6 100644
--- a/indra/newview/llworld.cpp
+++ b/indra/newview/llworld.cpp
@@ -295,13 +295,13 @@ void LLWorld::removeRegion(const LLHost &host)
mRegionRemovedSignal(regionp);
- delete regionp;
-
updateWaterObjects();
//double check all objects of this region are removed.
gObjectList.clearAllMapObjectsInRegion(regionp) ;
//llassert_always(!gObjectList.hasMapObjectInRegion(regionp)) ;
+
+ delete regionp; // Delete last to prevent use after free
}
diff --git a/indra/newview/skins/default/textures/icons/add_icon.png b/indra/newview/skins/default/textures/icons/add_icon.png
new file mode 100644
index 0000000000..cb68ee8e16
--- /dev/null
+++ b/indra/newview/skins/default/textures/icons/add_icon.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/remove_icon.png b/indra/newview/skins/default/textures/icons/remove_icon.png
new file mode 100644
index 0000000000..6e62ee33f4
--- /dev/null
+++ b/indra/newview/skins/default/textures/icons/remove_icon.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/textures.xml b/indra/newview/skins/default/textures/textures.xml
index 5bf27bb64d..bdf12d73fc 100644
--- a/indra/newview/skins/default/textures/textures.xml
+++ b/indra/newview/skins/default/textures/textures.xml
@@ -744,6 +744,9 @@ with the same filename but different name
<texture name="Wearables_Divider" file_name="windows/Wearables_Divider.png" preload="false" />
+ <texture name="Add_Icon" file_name="icons/add_icon.png" preload="false" />
+ <texture name="Remove_Icon" file_name="icons/remove_icon.png" preload="false" />
+
<texture name="Web_Profile_Off" file_name="icons/Web_Profile_Off.png" preload="false" />
<texture name="WellButton_Lit" file_name="bottomtray/WellButton_Lit.png" preload="true" scale.left="4" scale.top="19" scale.right="28" scale.bottom="4" />
diff --git a/indra/newview/skins/default/xui/en/floater_object_weights.xml b/indra/newview/skins/default/xui/en/floater_object_weights.xml
index eb283a1043..889efa061c 100644
--- a/indra/newview/skins/default/xui/en/floater_object_weights.xml
+++ b/indra/newview/skins/default/xui/en/floater_object_weights.xml
@@ -2,7 +2,7 @@
<floater
can_close="true"
can_tear_off="false"
- height="315"
+ height="289"
help_topic="object_weights"
layout="topleft"
name="object_weights"
@@ -320,23 +320,4 @@
top_delta="0"
value="Total capacity"
width="130" />
- <view_border
- bevel_style="none"
- follows="top|left"
- height="0"
- layout="topleft"
- left="10"
- name="land_impacts_text_border"
- top_pad="5"
- width="180"/>
-
- <text
- follows="left|top"
- height="16"
- layout="topleft"
- left="10"
- name="help_SLURL"
- top_pad="10"
- value="[secondlife:///app/help/object_weights What is all this?...]"
- width="180" />
</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_openobject.xml b/indra/newview/skins/default/xui/en/floater_openobject.xml
index 912db80bcc..ec03d7d32c 100644
--- a/indra/newview/skins/default/xui/en/floater_openobject.xml
+++ b/indra/newview/skins/default/xui/en/floater_openobject.xml
@@ -3,7 +3,7 @@
legacy_header_height="18"
can_resize="true"
default_tab_group="1"
- height="370"
+ height="350"
layout="topleft"
min_height="190"
min_width="285"
@@ -31,62 +31,18 @@
background_visible="false"
draw_border="false"
follows="all"
- height="240"
+ height="265"
layout="topleft"
+ show_root_folder="false"
left="10"
name="object_contents"
top_pad="0"
width="284" />
- <view_border
- bevel_style="none"
- follows="bottom|left"
- height="50"
- highlight_light_color="0.6 0.6 0.6"
- layout="topleft"
- left="10"
- name="border"
- top_pad="5"
- width="270"/>
- <text
- follows="bottom|left"
- height="15"
- layout="topleft"
- left="15"
- name="border_note"
- text_color="White"
- top_delta="5">
- Copy to inventory and wear
- </text>
- <button
- follows="bottom|left"
- height="23"
- label="Add to outfit"
- label_selected="Add to outfit"
- layout="topleft"
- left="15"
- name="copy_and_wear_button"
- top_pad="3"
- width="135">
- <button.commit_callback
- function="OpenObject.MoveAndWear" />
- </button>
- <button
- follows="bottom|left"
- height="23"
- label="Replace outfit"
- label_selected="Replace outfit"
- layout="topleft"
- left_pad="5"
- name="copy_and_replace_button"
- width="120">
- <button.commit_callback
- function="OpenObject.ReplaceOutfit" />
- </button>
<button
follows="bottom|left"
height="23"
label="Only copy to inventory"
- label_selected="Only copy to inventory"
+ label_selected="Copy to inventory"
layout="topleft"
left="15"
name="copy_to_inventory_button"
diff --git a/indra/newview/skins/default/xui/en/floater_pathfinding_linksets.xml b/indra/newview/skins/default/xui/en/floater_pathfinding_linksets.xml
index 41384a77b8..59117c0178 100644
--- a/indra/newview/skins/default/xui/en/floater_pathfinding_linksets.xml
+++ b/indra/newview/skins/default/xui/en/floater_pathfinding_linksets.xml
@@ -82,17 +82,20 @@
width="62">
Name
</text>
- <line_editor
- border_style="line"
- border_thickness="1"
- follows="left|top"
- height="20"
- layout="topleft"
- left_pad="0"
- top_pad="-18"
- max_length_chars="255"
- name="filter_by_name"
- width="161" />
+
+ <search_editor
+ follows="left|top"
+ search_button_visible="false"
+ height="20"
+ text_readonly_color="DkGray"
+ label="Objects by Name"
+ layout="topleft"
+ left_pad="0"
+ top_pad="-18"
+ name="filter_by_name"
+ select_on_focus="true"
+ width="161">
+ </search_editor>
<text
name="linksets_desc_label"
height="13"
@@ -108,17 +111,19 @@
width="88">
Description
</text>
- <line_editor
- border_style="line"
- border_thickness="1"
- follows="left|top"
- height="20"
- layout="topleft"
- left_pad="0"
- top_pad="-17"
- max_length_chars="255"
- name="filter_by_description"
- width="162" />
+ <search_editor
+ follows="left|top"
+ search_button_visible="false"
+ height="20"
+ text_readonly_color="DkGray"
+ label="Objects by Description"
+ layout="topleft"
+ left_pad="0"
+ top_pad="-17"
+ name="filter_by_description"
+ select_on_focus="true"
+ width="162">
+ </search_editor>
<combo_box
height="20"
layout="topleft"
diff --git a/indra/newview/skins/default/xui/en/floater_settings_debug.xml b/indra/newview/skins/default/xui/en/floater_settings_debug.xml
index 3ed2bd7206..e4fda5cd10 100644
--- a/indra/newview/skins/default/xui/en/floater_settings_debug.xml
+++ b/indra/newview/skins/default/xui/en/floater_settings_debug.xml
@@ -2,41 +2,79 @@
<floater
legacy_header_height="18"
can_minimize="false"
- height="215"
+ height="360"
+ min_height="367"
layout="topleft"
name="settings_debug"
help_topic="settings_debug"
title="DEBUG SETTINGS"
- width="350">
- <combo_box
- allow_text_entry="true"
- follows="top|left"
- height="22"
- layout="topleft"
- left="15"
- max_chars="255"
- name="settings_combo"
- top="30"
- width="320">
- <combo_box.commit_callback
- function="SettingSelect" />
- </combo_box>
- <text_editor
- enabled="false"
- height="60"
- layout="topleft"
- left_delta="0"
- name="comment_text"
- top_pad="10"
- width="320"
- word_wrap="true" />
+ reuse_instance="true"
+ can_resize="true"
+ min_width="550"
+ width="570">
+ <filter_editor
+ follows="left|top|right"
+ height="23"
+ layout="topleft"
+ left="10"
+ right="-10"
+ label="Enter search text"
+ max_length_chars="300"
+ name="filter_input"
+ text_pad_left="10"
+ top="30" />
+ <scroll_list
+ column_padding="0"
+ draw_heading="true"
+ draw_stripes="false"
+ heading_height="23"
+ height="266"
+ layout="topleft"
+ search_column="1"
+ left="10"
+ follows="left|top|bottom"
+ name="setting_list"
+ top_pad="2"
+ width="300">
+ <scroll_list.columns
+ name="changed_setting"
+ relative_width="0.05" />
+ <scroll_list.columns
+ label="Setting"
+ name="setting" />
+ </scroll_list>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ name="setting_name_txt"
+ font="SansSerifSmallBold"
+ top_delta="8"
+ left_pad="10"
+ visible="false"
+ use_ellipses="true"
+ text_color="White"
+ width="240">
+ Debug setting name
+ </text>
+ <text_editor
+ enabled="false"
+ height="75"
+ layout="topleft"
+ visible="false"
+ name="comment_text"
+ follows="left|top"
+ width="240"
+ top_delta="20"
+ word_wrap="true" />
<radio_group
follows="top|left"
height="30"
layout="topleft"
- left_delta="0"
name="boolean_combo"
- top_pad="10"
+ top_pad="15"
visible="false"
tab_stop="true"
width="100">
@@ -55,21 +93,25 @@
</radio_group>
<line_editor
height="20"
+ follows="top|left"
layout="topleft"
left_delta="0"
name="val_text"
top_delta="0"
visible="false"
- width="300" >
+ width="220" >
<line_editor.commit_callback
function="CommitSettings" />
</line_editor>
<color_swatch
- bottom="185"
+ top_delta="0"
+ left_delta="0"
+ follows="top|left"
can_apply_immediately="true"
height="55"
name="val_color_swatch"
label="Color"
+ visible="false"
layout="topleft"
width="37" >
<color_swatch.commit_callback
@@ -79,10 +121,11 @@
height="20"
label="x"
layout="topleft"
+ follows="top|left"
left_delta="0"
max_val="1e+007"
name="val_spinner_1"
- top_delta="10"
+ top_delta="5"
visible="false"
width="120" >
<spinner.commit_callback
@@ -92,10 +135,11 @@
height="20"
label="x"
layout="topleft"
- left_pad="15"
+ follows="top|left"
+ left_delta="0"
max_val="1e+007"
name="val_spinner_2"
- top_delta="0"
+ top_pad="10"
visible="false"
width="120">
<spinner.commit_callback
@@ -105,10 +149,11 @@
height="20"
label="x"
layout="topleft"
- left="15"
+ follows="top|left"
+ left_delta="0"
max_val="1e+007"
name="val_spinner_3"
- top="160"
+ top_pad="10"
visible="false"
width="120">
<spinner.commit_callback
@@ -118,10 +163,11 @@
height="20"
label="x"
layout="topleft"
- left_pad="15"
+ follows="top|left"
+ left_delta="0"
max_val="1e+007"
name="val_spinner_4"
- top_delta="0"
+ top_pad="10"
visible="false"
width="120" >
<spinner.commit_callback
@@ -130,12 +176,26 @@
<button
height="22"
label="Reset to default"
+ follows="left|top"
layout="topleft"
- left="15"
+ left_delta="0"
name="default_btn"
- top="186"
+ visible="false"
+ top_pad="10"
width="150" >
<button.commit_callback
function="ClickDefault" />
</button>
+ <check_box
+ control_name="DebugSettingsHideDefault"
+ height="16"
+ initial_value="true"
+ label="Show changed settings only"
+ layout="topleft"
+ top_pad="10"
+ left="10"
+ follows="left|bottom"
+ name="hide_default"
+ width="330">
+ </check_box>
</floater>
diff --git a/indra/newview/skins/default/xui/en/outfit_accordion_tab.xml b/indra/newview/skins/default/xui/en/outfit_accordion_tab.xml
index 2a24c74feb..d74dca8b95 100644
--- a/indra/newview/skins/default/xui/en/outfit_accordion_tab.xml
+++ b/indra/newview/skins/default/xui/en/outfit_accordion_tab.xml
@@ -18,6 +18,7 @@
follows="all"
keep_one_selected="true"
multi_select="true"
+ show_item_widgets="true"
name="wearable_items_list"
translate="false"
standalone="false"
diff --git a/indra/newview/skins/default/xui/en/panel_outfits_wearing.xml b/indra/newview/skins/default/xui/en/panel_outfits_wearing.xml
index 42a7974316..b2dc975c6e 100644
--- a/indra/newview/skins/default/xui/en/panel_outfits_wearing.xml
+++ b/indra/newview/skins/default/xui/en/panel_outfits_wearing.xml
@@ -36,6 +36,7 @@
left="3"
multi_select="true"
name="cof_items_list"
+ show_item_widgets="true"
standalone="false"
top="0"
width="309"
diff --git a/indra/newview/skins/default/xui/en/panel_preferences_privacy.xml b/indra/newview/skins/default/xui/en/panel_preferences_privacy.xml
index 2ec5cef640..ef08fdf7c4 100644
--- a/indra/newview/skins/default/xui/en/panel_preferences_privacy.xml
+++ b/indra/newview/skins/default/xui/en/panel_preferences_privacy.xml
@@ -19,7 +19,7 @@
follows="left|top"
height="23"
label="Clear History"
- tool_tip="Clear login image, last location, teleport history, web and texture cache"
+ tool_tip="Clear search and teleport history, web and texture cache"
layout="topleft"
left="30"
name="clear_cache"
diff --git a/indra/newview/skins/default/xui/en/panel_profile_secondlife.xml b/indra/newview/skins/default/xui/en/panel_profile_secondlife.xml
index 551b477876..777b37d666 100644
--- a/indra/newview/skins/default/xui/en/panel_profile_secondlife.xml
+++ b/indra/newview/skins/default/xui/en/panel_profile_secondlife.xml
@@ -9,9 +9,13 @@
follows="all"
layout="topleft"
>
+ <!--
+ Date from server comes already converted to stl timezone,
+ so display it as an UTC+0
+ -->
<string
name="date_format"
- value="SL birthdate: [mth,datetime,slt] [day,datetime,slt], [year,datetime,slt]" />
+ value="SL birthdate: [mth,datetime,utc] [day,datetime,utc], [year,datetime,utc]" />
<string
name="age_format"
value="[AGE]" />
diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml
index 847a1b6df1..7177cb1273 100644
--- a/indra/newview/skins/default/xui/en/strings.xml
+++ b/indra/newview/skins/default/xui/en/strings.xml
@@ -3994,7 +3994,7 @@ Please check http://status.secondlifegrid.net to see if there is a known problem
<string name="Premium_PlusMembership">Premium Plus</string>
<string name="InternalMembership">Internal</string> <!-- No need to translate -->
- <string name="MembershipUpgradeText">Upgrade to Premium</string>
+ <string name="MembershipUpgradeText">Change membership plan...</string>
<string name="MembershipPremiumText">My Premium membership</string>
<!-- Question strings for delete items notifications -->
diff --git a/indra/newview/skins/default/xui/en/widgets/filter_editor.xml b/indra/newview/skins/default/xui/en/widgets/filter_editor.xml
index 1c4822b8d5..9c80deeafc 100644
--- a/indra/newview/skins/default/xui/en/widgets/filter_editor.xml
+++ b/indra/newview/skins/default/xui/en/widgets/filter_editor.xml
@@ -6,7 +6,7 @@
text_pad_left="7"
select_on_focus="true"
text_tentative_color="TextFgTentativeColor"
- highlight_text_field="false"
+ highlight_text_field="true"
background_image="TextField_Search_Off"
background_image_disabled="TextField_Search_Disabled"
background_image_focused="TextField_Search_Active"
diff --git a/indra/newview/skins/default/xui/en/widgets/search_editor.xml b/indra/newview/skins/default/xui/en/widgets/search_editor.xml
index dc5a07bf4f..18d99f1ed1 100644
--- a/indra/newview/skins/default/xui/en/widgets/search_editor.xml
+++ b/indra/newview/skins/default/xui/en/widgets/search_editor.xml
@@ -7,7 +7,7 @@
text_pad_right="6"
select_on_focus="true"
text_tentative_color="TextFgTentativeColor"
- highlight_text_field="false"
+ highlight_text_field="true"
background_image="TextField_Search_Off"
background_image_disabled="TextField_Search_Disabled"
background_image_focused="TextField_Search_Active"
diff --git a/indra/newview/skins/default/xui/en/widgets/wearable_outfit_list_item.xml b/indra/newview/skins/default/xui/en/widgets/wearable_outfit_list_item.xml
new file mode 100644
index 0000000000..cd84b91b1f
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/widgets/wearable_outfit_list_item.xml
@@ -0,0 +1,64 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<inventory_list_item
+ follows="top|right|left"
+ height="20"
+ name="inventory_item"
+ tab_stop="false"
+ hover_image="ListItem_Over"
+ selected_image="ListItem_Select"
+ separator_image="Wearables_Divider"
+ width="380">
+ <!-- DEFAULT style for inventory list item -->
+ <default_style
+ font="SansSerifSmall"
+ font.style="NORMAL" />
+
+ <!-- style for inventory list item WORN on avatar -->
+ <worn_style
+ font="SansSerifSmall"
+ font.style="BOLD"
+ color="EmphasisColor" />
+ <item_icon
+ height="16"
+ follows="top|left"
+ image_name="Inv_Object"
+ layout="topleft"
+ left="0"
+ name="item_icon"
+ top="0"
+ width="16" />
+ <item_name
+ follows="left|right"
+ height="20"
+ layout="topleft"
+ left="21"
+ parse_urls="false"
+ use_ellipses="true"
+ name="item_name"
+ text_color="white"
+ top="4"
+ value="..."
+ width="359" />
+ <add_btn
+ name="add_wearable"
+ layout="topleft"
+ follows="top|right"
+ image_unselected="Add_Icon"
+ image_selected="Add_Icon"
+ top="1"
+ left="0"
+ height="16"
+ width="16"
+ tab_stop="false" />
+ <remove_btn
+ name="remove_wearable"
+ layout="topleft"
+ follows="top|right"
+ image_unselected="Remove_Icon"
+ image_selected="Remove_Icon"
+ top="1"
+ left="26"
+ height="16"
+ width="16"
+ tab_stop="false" />
+</inventory_list_item>
diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py
index 59eb18b734..6d68fd5453 100755
--- a/indra/newview/viewer_manifest.py
+++ b/indra/newview/viewer_manifest.py
@@ -518,7 +518,7 @@ class WindowsManifest(ViewerManifest):
self.path("alut.dll")
# For textures
- self.path("openjpeg.dll")
+ self.path("openjp2.dll")
# Uriparser
self.path("uriparser.dll")
@@ -1501,7 +1501,7 @@ class Linux_i686_Manifest(LinuxManifest):
self.path("libdirectfb-1.*.so.*")
self.path("libfusion-1.*.so.*")
self.path("libdirect-1.*.so.*")
- self.path("libopenjpeg.so*")
+ self.path("libopenjp2.so*")
self.path("libdirectfb-1.4.so.5")
self.path("libfusion-1.4.so.5")
self.path("libdirect-1.4.so.5*")