summaryrefslogtreecommitdiff
path: root/indra/newview
diff options
context:
space:
mode:
Diffstat (limited to 'indra/newview')
-rw-r--r--indra/newview/CMakeLists.txt2
-rw-r--r--indra/newview/VIEWER_VERSION.txt2
-rw-r--r--indra/newview/app_settings/settings.xml2
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/postDeferredTonemap.glsl129
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/tonemapUtilF.glsl180
-rw-r--r--indra/newview/app_settings/shaders/class1/environment/srgbF.glsl20
-rw-r--r--indra/newview/app_settings/shaders/class1/environment/waterFogF.glsl4
-rw-r--r--indra/newview/app_settings/shaders/class1/objects/simpleColorF.glsl57
-rw-r--r--indra/newview/app_settings/shaders/class1/objects/simpleNoAtmosV.glsl43
-rw-r--r--indra/newview/app_settings/shaders/class2/deferred/alphaF.glsl2
-rw-r--r--indra/newview/app_settings/shaders/class3/deferred/materialF.glsl2
-rw-r--r--indra/newview/app_settings/shaders/class3/deferred/reflectionProbeF.glsl15
-rw-r--r--indra/newview/app_settings/shaders/class3/deferred/waterHazeF.glsl14
-rw-r--r--indra/newview/app_settings/shaders/class3/environment/underWaterF.glsl8
-rw-r--r--indra/newview/app_settings/shaders/class3/environment/waterF.glsl210
-rw-r--r--indra/newview/featuretable.txt9
-rw-r--r--indra/newview/featuretable_mac.txt9
-rw-r--r--indra/newview/gltfscenemanager.cpp4
-rw-r--r--indra/newview/llagent.cpp13
-rw-r--r--indra/newview/llagentpicksinfo.cpp12
-rw-r--r--indra/newview/llagentpicksinfo.h12
-rw-r--r--indra/newview/llappearancemgr.cpp11
-rw-r--r--indra/newview/llappviewer.cpp181
-rw-r--r--indra/newview/llappviewer.h32
-rw-r--r--indra/newview/llconversationmodel.cpp5
-rw-r--r--indra/newview/lldrawpool.cpp4
-rw-r--r--indra/newview/lldrawpool.h3
-rw-r--r--indra/newview/lldrawpoolwater.cpp245
-rw-r--r--indra/newview/lldrawpoolwater.h2
-rw-r--r--indra/newview/lldrawpoolwaterexclusion.cpp79
-rw-r--r--indra/newview/lldrawpoolwaterexclusion.h61
-rw-r--r--indra/newview/llface.cpp23
-rw-r--r--indra/newview/llfloaterimsessiontab.cpp3
-rw-r--r--indra/newview/llfloatersnapshot.cpp22
-rw-r--r--indra/newview/llgltfmaterialpreviewmgr.cpp4
-rw-r--r--indra/newview/llheroprobemanager.cpp15
-rw-r--r--indra/newview/llhudrender.cpp2
-rw-r--r--indra/newview/llinventorybridge.cpp52
-rw-r--r--indra/newview/llinventoryfunctions.cpp16
-rw-r--r--indra/newview/llinventoryfunctions.h18
-rw-r--r--indra/newview/llinventorymodel.cpp41
-rw-r--r--indra/newview/llinventorymodel.h3
-rw-r--r--indra/newview/llinventorypanel.cpp4
-rw-r--r--indra/newview/lllogininstance.cpp1
-rw-r--r--indra/newview/lllogininstance.h2
-rw-r--r--indra/newview/llpanelcontents.cpp68
-rw-r--r--indra/newview/llpanelcontents.h2
-rw-r--r--indra/newview/llpanelface.cpp4
-rw-r--r--indra/newview/llpanelgroupbulk.cpp32
-rw-r--r--indra/newview/llpanelgroupbulkban.cpp33
-rw-r--r--indra/newview/llpanelgroupbulkimpl.h3
-rw-r--r--indra/newview/llpanelmaininventory.cpp10
-rw-r--r--indra/newview/llpanelobjectinventory.h2
-rw-r--r--indra/newview/llpanelprimmediacontrols.cpp4
-rw-r--r--indra/newview/llprogressview.cpp154
-rw-r--r--indra/newview/llprogressview.h26
-rw-r--r--indra/newview/llreflectionmap.cpp29
-rw-r--r--indra/newview/llreflectionmap.h12
-rw-r--r--indra/newview/llreflectionmapmanager.cpp14
-rw-r--r--indra/newview/llsettingsvo.cpp6
-rw-r--r--indra/newview/llspatialpartition.cpp16
-rw-r--r--indra/newview/llstartup.cpp37
-rw-r--r--indra/newview/llviewercamera.cpp4
-rw-r--r--indra/newview/llviewercontrol.cpp10
-rw-r--r--indra/newview/llviewermenu.cpp7
-rw-r--r--indra/newview/llviewerobject.h3
-rw-r--r--indra/newview/llviewerobjectlist.cpp84
-rw-r--r--indra/newview/llviewerobjectlist.h5
-rw-r--r--indra/newview/llviewerparcelmgr.cpp10
-rw-r--r--indra/newview/llviewershadermgr.cpp53
-rw-r--r--indra/newview/llviewershadermgr.h2
-rw-r--r--indra/newview/llviewertexture.cpp68
-rw-r--r--indra/newview/llviewertexture.h5
-rw-r--r--indra/newview/llviewertexturelist.cpp16
-rw-r--r--indra/newview/llviewerwindow.cpp9
-rw-r--r--indra/newview/llviewerwindow.h1
-rw-r--r--indra/newview/llvoavatar.cpp10
-rw-r--r--indra/newview/llvoiceclient.cpp1
-rw-r--r--indra/newview/llvoicevivox.cpp2
-rw-r--r--indra/newview/llvoicewebrtc.cpp20
-rw-r--r--indra/newview/llvovolume.cpp43
-rw-r--r--indra/newview/pipeline.cpp111
-rw-r--r--indra/newview/pipeline.h6
-rw-r--r--indra/newview/skins/default/textures/3p_icons/fmod_logo.pngbin14486 -> 0 bytes
-rw-r--r--indra/newview/skins/default/textures/3p_icons/havok_logo.pngbin41488 -> 0 bytes
-rw-r--r--indra/newview/skins/default/textures/3p_icons/vivox_logo.pngbin2331 -> 0 bytes
-rw-r--r--indra/newview/skins/default/xui/de/panel_progress.xml2
-rw-r--r--indra/newview/skins/default/xui/en/floater_preferences_graphics_advanced.xml53
-rw-r--r--indra/newview/skins/default/xui/en/menu_login.xml9
-rw-r--r--indra/newview/skins/default/xui/en/menu_viewer.xml9
-rw-r--r--indra/newview/skins/default/xui/en/panel_preferences_setup.xml2
-rw-r--r--indra/newview/skins/default/xui/en/panel_progress.xml50
-rw-r--r--indra/newview/skins/default/xui/es/panel_progress.xml2
-rw-r--r--indra/newview/skins/default/xui/fr/panel_progress.xml2
-rw-r--r--indra/newview/skins/default/xui/it/panel_progress.xml2
-rw-r--r--indra/newview/skins/default/xui/ja/panel_preferences_setup.xml2
-rw-r--r--indra/newview/skins/default/xui/ja/panel_progress.xml4
-rw-r--r--indra/newview/skins/default/xui/pl/panel_progress.xml9
-rw-r--r--indra/newview/skins/default/xui/pt/panel_progress.xml2
99 files changed, 1633 insertions, 1015 deletions
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index b54ec7f035..e427d64171 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -167,6 +167,7 @@ set(viewer_SOURCE_FILES
lldrawpooltree.cpp
lldrawpoolwater.cpp
lldrawpoolwlsky.cpp
+ lldrawpoolwaterexclusion.cpp
lldynamictexture.cpp
llemote.cpp
llenvironment.cpp
@@ -840,6 +841,7 @@ set(viewer_HEADER_FILES
lldrawpooltree.h
lldrawpoolwater.h
lldrawpoolwlsky.h
+ lldrawpoolwaterexclusion.h
lldynamictexture.h
llemote.h
llenvironment.h
diff --git a/indra/newview/VIEWER_VERSION.txt b/indra/newview/VIEWER_VERSION.txt
index e0eaaa0bbc..0f9f025fe4 100644
--- a/indra/newview/VIEWER_VERSION.txt
+++ b/indra/newview/VIEWER_VERSION.txt
@@ -1 +1 @@
-7.1.11
+7.1.12
diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index 4739728bee..1aec56447d 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -12783,7 +12783,7 @@
<key>UpdaterWillingToTest</key>
<map>
<key>Comment</key>
- <string>Whether or not the updater should offer test candidate upgrades.</string>
+ <string>Whether or not the updater should offer Beta upgrades.</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
diff --git a/indra/newview/app_settings/shaders/class1/deferred/postDeferredTonemap.glsl b/indra/newview/app_settings/shaders/class1/deferred/postDeferredTonemap.glsl
index fc6d4d7727..c4610bffac 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/postDeferredTonemap.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/postDeferredTonemap.glsl
@@ -28,138 +28,11 @@
out vec4 frag_color;
uniform sampler2D diffuseRect;
-uniform sampler2D exposureMap;
-uniform vec2 screen_res;
in vec2 vary_fragcoord;
vec3 linear_to_srgb(vec3 cl);
-
-//===============================================================
-// tone mapping taken from Khronos sample implementation
-//===============================================================
-
-// sRGB => XYZ => D65_2_D60 => AP1 => RRT_SAT
-const mat3 ACESInputMat = mat3
-(
- 0.59719, 0.07600, 0.02840,
- 0.35458, 0.90834, 0.13383,
- 0.04823, 0.01566, 0.83777
-);
-
-
-// ODT_SAT => XYZ => D60_2_D65 => sRGB
-const mat3 ACESOutputMat = mat3
-(
- 1.60475, -0.10208, -0.00327,
- -0.53108, 1.10813, -0.07276,
- -0.07367, -0.00605, 1.07602
-);
-
-// ACES tone map (faster approximation)
-// see: https://knarkowicz.wordpress.com/2016/01/06/aces-filmic-tone-mapping-curve/
-vec3 toneMapACES_Narkowicz(vec3 color)
-{
- const float A = 2.51;
- const float B = 0.03;
- const float C = 2.43;
- const float D = 0.59;
- const float E = 0.14;
- return clamp((color * (A * color + B)) / (color * (C * color + D) + E), 0.0, 1.0);
-}
-
-
-// ACES filmic tone map approximation
-// see https://github.com/TheRealMJP/BakingLab/blob/master/BakingLab/ACES.hlsl
-vec3 RRTAndODTFit(vec3 color)
-{
- vec3 a = color * (color + 0.0245786) - 0.000090537;
- vec3 b = color * (0.983729 * color + 0.4329510) + 0.238081;
- return a / b;
-}
-
-
-// tone mapping
-vec3 toneMapACES_Hill(vec3 color)
-{
- color = ACESInputMat * color;
-
- // Apply RRT and ODT
- color = RRTAndODTFit(color);
-
- color = ACESOutputMat * color;
-
- // Clamp to [0, 1]
- color = clamp(color, 0.0, 1.0);
-
- return color;
-}
-
-// Khronos Neutral tonemapping
-// https://github.com/KhronosGroup/ToneMapping/tree/main
-// Input color is non-negative and resides in the Linear Rec. 709 color space.
-// Output color is also Linear Rec. 709, but in the [0, 1] range.
-vec3 PBRNeutralToneMapping( vec3 color )
-{
- const float startCompression = 0.8 - 0.04;
- const float desaturation = 0.15;
-
- float x = min(color.r, min(color.g, color.b));
- float offset = x < 0.08 ? x - 6.25 * x * x : 0.04;
- color -= offset;
-
- float peak = max(color.r, max(color.g, color.b));
- if (peak < startCompression) return color;
-
- const float d = 1. - startCompression;
- float newPeak = 1. - d * d / (peak + d - startCompression);
- color *= newPeak / peak;
-
- float g = 1. - 1. / (desaturation * (peak - newPeak) + 1.);
- return mix(color, newPeak * vec3(1, 1, 1), g);
-}
-
-uniform float exposure;
-uniform float tonemap_mix;
-uniform int tonemap_type;
-
-vec3 toneMap(vec3 color)
-{
-#ifndef NO_POST
- float exp_scale = texture(exposureMap, vec2(0.5,0.5)).r;
-
- color *= exposure * exp_scale;
-
- vec3 clamped_color = clamp(color.rgb, vec3(0.0), vec3(1.0));
-
- switch(tonemap_type)
- {
- case 0:
- color = PBRNeutralToneMapping(color);
- break;
- case 1:
- color = toneMapACES_Hill(color);
- break;
- }
-
- // mix tonemapped and linear here to provide adjustment
- color = mix(clamped_color, color, tonemap_mix);
-#endif
-
- return color;
-}
-
-//===============================================================
-
-void debugExposure(inout vec3 color)
-{
- float exp_scale = texture(exposureMap, vec2(0.5,0.5)).r;
- exp_scale *= 0.5;
- if (abs(vary_fragcoord.y-exp_scale) < 0.01 && vary_fragcoord.x < 0.1)
- {
- color = vec3(1,0,0);
- }
-}
+vec3 toneMap(vec3 color);
void main()
{
diff --git a/indra/newview/app_settings/shaders/class1/deferred/tonemapUtilF.glsl b/indra/newview/app_settings/shaders/class1/deferred/tonemapUtilF.glsl
new file mode 100644
index 0000000000..a63b8d7c2b
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class1/deferred/tonemapUtilF.glsl
@@ -0,0 +1,180 @@
+/**
+ * @file postDeferredTonemap.glsl
+ *
+ * $LicenseInfo:firstyear=2024&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2024, 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$
+ */
+
+/*[EXTRA_CODE_HERE]*/
+
+uniform sampler2D exposureMap;
+uniform vec2 screen_res;
+in vec2 vary_fragcoord;
+
+//===============================================================
+// tone mapping taken from Khronos sample implementation
+//===============================================================
+
+// sRGB => XYZ => D65_2_D60 => AP1 => RRT_SAT
+const mat3 ACESInputMat = mat3
+(
+ 0.59719, 0.07600, 0.02840,
+ 0.35458, 0.90834, 0.13383,
+ 0.04823, 0.01566, 0.83777
+);
+
+
+// ODT_SAT => XYZ => D60_2_D65 => sRGB
+const mat3 ACESOutputMat = mat3
+(
+ 1.60475, -0.10208, -0.00327,
+ -0.53108, 1.10813, -0.07276,
+ -0.07367, -0.00605, 1.07602
+);
+
+// ACES tone map (faster approximation)
+// see: https://knarkowicz.wordpress.com/2016/01/06/aces-filmic-tone-mapping-curve/
+vec3 toneMapACES_Narkowicz(vec3 color)
+{
+ const float A = 2.51;
+ const float B = 0.03;
+ const float C = 2.43;
+ const float D = 0.59;
+ const float E = 0.14;
+ return clamp((color * (A * color + B)) / (color * (C * color + D) + E), 0.0, 1.0);
+}
+
+
+// ACES filmic tone map approximation
+// see https://github.com/TheRealMJP/BakingLab/blob/master/BakingLab/ACES.hlsl
+vec3 RRTAndODTFit(vec3 color)
+{
+ vec3 a = color * (color + 0.0245786) - 0.000090537;
+ vec3 b = color * (0.983729 * color + 0.4329510) + 0.238081;
+ return a / b;
+}
+
+
+// tone mapping
+vec3 toneMapACES_Hill(vec3 color)
+{
+ color = ACESInputMat * color;
+
+ // Apply RRT and ODT
+ color = RRTAndODTFit(color);
+
+ color = ACESOutputMat * color;
+
+ // Clamp to [0, 1]
+ color = clamp(color, 0.0, 1.0);
+
+ return color;
+}
+
+// Khronos Neutral tonemapping
+// https://github.com/KhronosGroup/ToneMapping/tree/main
+// Input color is non-negative and resides in the Linear Rec. 709 color space.
+// Output color is also Linear Rec. 709, but in the [0, 1] range.
+vec3 PBRNeutralToneMapping( vec3 color )
+{
+ const float startCompression = 0.8 - 0.04;
+ const float desaturation = 0.15;
+
+ float x = min(color.r, min(color.g, color.b));
+ float offset = x < 0.08 ? x - 6.25 * x * x : 0.04;
+ color -= offset;
+
+ float peak = max(color.r, max(color.g, color.b));
+ if (peak < startCompression) return color;
+
+ const float d = 1. - startCompression;
+ float newPeak = 1. - d * d / (peak + d - startCompression);
+ color *= newPeak / peak;
+
+ float g = 1. - 1. / (desaturation * (peak - newPeak) + 1.);
+ return mix(color, newPeak * vec3(1, 1, 1), g);
+}
+
+uniform float exposure;
+uniform float tonemap_mix;
+uniform int tonemap_type;
+
+vec3 toneMap(vec3 color)
+{
+#ifndef NO_POST
+ float exp_scale = texture(exposureMap, vec2(0.5,0.5)).r;
+
+ color *= exposure * exp_scale;
+
+ vec3 clamped_color = clamp(color.rgb, vec3(0.0), vec3(1.0));
+
+ switch(tonemap_type)
+ {
+ case 0:
+ color = PBRNeutralToneMapping(color);
+ break;
+ case 1:
+ color = toneMapACES_Hill(color);
+ break;
+ }
+
+ // mix tonemapped and linear here to provide adjustment
+ color = mix(clamped_color, color, tonemap_mix);
+#endif
+
+ return color;
+}
+
+
+vec3 toneMapNoExposure(vec3 color)
+{
+#ifndef NO_POST
+ vec3 clamped_color = clamp(color.rgb, vec3(0.0), vec3(1.0));
+
+ switch(tonemap_type)
+ {
+ case 0:
+ color = PBRNeutralToneMapping(color);
+ break;
+ case 1:
+ color = toneMapACES_Hill(color);
+ break;
+ }
+
+ // mix tonemapped and linear here to provide adjustment
+ color = mix(clamped_color, color, tonemap_mix);
+#endif
+
+ return color;
+}
+
+
+//===============================================================
+
+void debugExposure(inout vec3 color)
+{
+ float exp_scale = texture(exposureMap, vec2(0.5,0.5)).r;
+ exp_scale *= 0.5;
+ if (abs(vary_fragcoord.y-exp_scale) < 0.01 && vary_fragcoord.x < 0.1)
+ {
+ color = vec3(1,0,0);
+ }
+}
diff --git a/indra/newview/app_settings/shaders/class1/environment/srgbF.glsl b/indra/newview/app_settings/shaders/class1/environment/srgbF.glsl
index d7f6d20547..bf8737615f 100644
--- a/indra/newview/app_settings/shaders/class1/environment/srgbF.glsl
+++ b/indra/newview/app_settings/shaders/class1/environment/srgbF.glsl
@@ -41,6 +41,26 @@ vec3 srgb_to_linear(vec3 cs)
}
+
+vec4 srgb_to_linear4(vec4 cs)
+{
+ vec4 low_range = cs / vec4(12.92);
+ vec4 high_range = pow((cs+vec4(0.055))/vec4(1.055), vec4(2.4));
+ bvec4 lte = lessThanEqual(cs,vec4(0.04045));
+
+#ifdef OLD_SELECT
+ vec4 result;
+ result.r = lte.r ? low_range.r : high_range.r;
+ result.g = lte.g ? low_range.g : high_range.g;
+ result.b = lte.b ? low_range.b : high_range.b;
+ result.a = lte.a ? low_range.a : high_range.a;
+ return result;
+#else
+ return mix(high_range, low_range, lte);
+#endif
+
+}
+
vec3 linear_to_srgb(vec3 cl)
{
cl = clamp(cl, vec3(0), vec3(1));
diff --git a/indra/newview/app_settings/shaders/class1/environment/waterFogF.glsl b/indra/newview/app_settings/shaders/class1/environment/waterFogF.glsl
index 20b61e9302..44a979e565 100644
--- a/indra/newview/app_settings/shaders/class1/environment/waterFogF.glsl
+++ b/indra/newview/app_settings/shaders/class1/environment/waterFogF.glsl
@@ -66,11 +66,11 @@ vec4 getWaterFogViewNoClip(vec3 pos)
float t2 = kd + ks * es;
float t3 = pow(F, t2*l) - 1.0;
- float L = min(t1/t2*t3, 1.0);
+ float L = pow(min(t1/t2*t3, 1.0), 1.0/1.7);
float D = pow(0.98, l*kd);
- return vec4(srgb_to_linear(kc.rgb*L), D);
+ return vec4(srgb_to_linear(kc.rgb)*L, D);
}
vec4 getWaterFogView(vec3 pos)
diff --git a/indra/newview/app_settings/shaders/class1/objects/simpleColorF.glsl b/indra/newview/app_settings/shaders/class1/objects/simpleColorF.glsl
new file mode 100644
index 0000000000..dea76da5a5
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class1/objects/simpleColorF.glsl
@@ -0,0 +1,57 @@
+/**
+ * @file simpleColorF.glsl
+ *
+ * $LicenseInfo:firstyear=2025&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2007, 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$
+ */
+
+out vec4 frag_color;
+
+in vec4 vertex_color;
+in vec4 vertex_position;
+
+uniform vec4 waterPlane;
+uniform float waterSign;
+
+void waterClip(vec3 pos)
+{
+ // TODO: make this less branchy
+ if (waterSign > 0)
+ {
+ if ((dot(pos.xyz, waterPlane.xyz) + waterPlane.w) < 0.0)
+ {
+ discard;
+ }
+ }
+ else
+ {
+ if ((dot(pos.xyz, waterPlane.xyz) + waterPlane.w) > 0.0)
+ {
+ discard;
+ }
+ }
+}
+
+void main()
+{
+
+ frag_color = vertex_color;
+}
diff --git a/indra/newview/app_settings/shaders/class1/objects/simpleNoAtmosV.glsl b/indra/newview/app_settings/shaders/class1/objects/simpleNoAtmosV.glsl
new file mode 100644
index 0000000000..4564e56313
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class1/objects/simpleNoAtmosV.glsl
@@ -0,0 +1,43 @@
+/**
+ * @file simpleNoAtmosV.glsl
+ *
+ * $LicenseInfo:firstyear=2007&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2007, 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_matrix;
+uniform mat4 modelview_projection_matrix;
+
+uniform vec4 color;
+
+in vec3 position;
+
+out vec4 vertex_color;
+out vec4 vertex_position;
+
+void main()
+{
+ //transform vertex
+ vec4 pos = (modelview_matrix * vec4(position.xyz, 1.0));
+ vertex_position = modelview_projection_matrix * vec4(position.xyz, 1.0);
+ gl_Position = vertex_position;
+ vertex_color = color;
+}
diff --git a/indra/newview/app_settings/shaders/class2/deferred/alphaF.glsl b/indra/newview/app_settings/shaders/class2/deferred/alphaF.glsl
index d6569cda33..50b40e9c20 100644
--- a/indra/newview/app_settings/shaders/class2/deferred/alphaF.glsl
+++ b/indra/newview/app_settings/shaders/class2/deferred/alphaF.glsl
@@ -150,7 +150,7 @@ vec3 calcPointLightOrSpotLight(vec3 light_col, vec3 diffuse, vec3 v, vec3 n, vec
float amb_da = 0.0;//ambiance;
if (da > 0.0)
{
- lit = max(da * dist_atten,0.0);
+ lit = clamp(da * dist_atten, 0.0, 1.0);
col = lit * light_col * diffuse;
amb_da += (da*0.5+0.5) * ambiance;
}
diff --git a/indra/newview/app_settings/shaders/class3/deferred/materialF.glsl b/indra/newview/app_settings/shaders/class3/deferred/materialF.glsl
index a4d3962d12..f8803f1a29 100644
--- a/indra/newview/app_settings/shaders/class3/deferred/materialF.glsl
+++ b/indra/newview/app_settings/shaders/class3/deferred/materialF.glsl
@@ -140,7 +140,7 @@ vec3 calcPointLightOrSpotLight(vec3 light_col, vec3 npos, vec3 diffuse, vec4 spe
float amb_da = ambiance;
if (da >= 0.0)
{
- lit = max(da * dist_atten, 0.0);
+ lit = clamp(da * dist_atten, 0.0, 1.0);
col = lit * light_col * diffuse;
amb_da += (da*0.5 + 0.5) * ambiance;
}
diff --git a/indra/newview/app_settings/shaders/class3/deferred/reflectionProbeF.glsl b/indra/newview/app_settings/shaders/class3/deferred/reflectionProbeF.glsl
index 4bae7b6deb..2f577f8459 100644
--- a/indra/newview/app_settings/shaders/class3/deferred/reflectionProbeF.glsl
+++ b/indra/newview/app_settings/shaders/class3/deferred/reflectionProbeF.glsl
@@ -38,6 +38,8 @@ uniform float max_probe_lod;
uniform bool transparent_surface;
+uniform int classic_mode;
+
#define MAX_REFMAP_COUNT 256 // must match LL_MAX_REFLECTION_PROBE_COUNT
layout (std140) uniform ReflectionProbes
@@ -739,7 +741,10 @@ void doProbeSample(inout vec3 ambenv, inout vec3 glossenv,
vec3 refnormpersp = reflect(pos.xyz, norm.xyz);
- ambenv = sampleProbeAmbient(pos, norm, amblit);
+ ambenv = amblit;
+
+ if (classic_mode == 0)
+ ambenv = sampleProbeAmbient(pos, norm, amblit);
float lod = (1.0-glossiness)*reflection_lods;
glossenv = sampleProbes(pos, normalize(refnormpersp), lod);
@@ -784,9 +789,6 @@ void sampleReflectionProbesWater(inout vec3 ambenv, inout vec3 glossenv,
probeIndex[probeInfluences++] = 0;
doProbeSample(ambenv, glossenv, tc, pos, norm, glossiness, false, amblit);
-
- // fudge factor to get PBR water at a similar luminance ot legacy water
- glossenv *= 0.4;
}
void debugTapRefMap(vec3 pos, vec3 dir, float depth, int i, inout vec4 col)
@@ -845,7 +847,10 @@ void sampleReflectionProbesLegacy(out vec3 ambenv, out vec3 glossenv, out vec3 l
vec3 refnormpersp = reflect(pos.xyz, norm.xyz);
- ambenv = sampleProbeAmbient(pos, norm, amblit);
+ ambenv = amblit;
+
+ if (classic_mode == 0)
+ ambenv = sampleProbeAmbient(pos, norm, amblit);
if (glossiness > 0.0)
{
diff --git a/indra/newview/app_settings/shaders/class3/deferred/waterHazeF.glsl b/indra/newview/app_settings/shaders/class3/deferred/waterHazeF.glsl
index 2bf785e773..091c25d15e 100644
--- a/indra/newview/app_settings/shaders/class3/deferred/waterHazeF.glsl
+++ b/indra/newview/app_settings/shaders/class3/deferred/waterHazeF.glsl
@@ -35,13 +35,25 @@ vec4 getWaterFogView(vec3 pos);
uniform int above_water;
+uniform sampler2D exclusionTex;
+
void main()
{
vec2 tc = vary_fragcoord.xy/vary_fragcoord.w*0.5+0.5;
float depth = getDepth(tc.xy);
+ float mask = texture(exclusionTex, tc.xy).r;
if (above_water > 0)
{
+ // Just discard if we're in the exclusion mask.
+ // The previous invisiprim hack we're replacing would also crank up water fog desntiy.
+ // But doing that makes exclusion surfaces very slow as we'd need to render even more into the mask.
+ // - Geenz 2025-02-06
+ if (mask < 1)
+ {
+ discard;
+ }
+
// we want to depth test when the camera is above water, but some GPUs have a hard time
// with depth testing against render targets that are bound for sampling in the same shader
// so we do it manually here
@@ -51,11 +63,13 @@ void main()
{
discard;
}
+
}
vec4 pos = getPositionWithDepth(tc, depth);
vec4 fogged = getWaterFogView(pos.xyz);
+ fogged.a = max(pow(fogged.a, 1.7), 0);
frag_color = max(fogged, vec4(0)); //output linear since local lights will be added to this shader's results
diff --git a/indra/newview/app_settings/shaders/class3/environment/underWaterF.glsl b/indra/newview/app_settings/shaders/class3/environment/underWaterF.glsl
index 1c02dc764d..fa410e9f11 100644
--- a/indra/newview/app_settings/shaders/class3/environment/underWaterF.glsl
+++ b/indra/newview/app_settings/shaders/class3/environment/underWaterF.glsl
@@ -26,6 +26,7 @@
out vec4 frag_color;
uniform sampler2D bumpMap;
+uniform sampler2D exclusionTex;
#ifdef TRANSPARENT_WATER
uniform sampler2D screenTex;
@@ -59,6 +60,9 @@ void mirrorClip(vec3 position);
void main()
{
mirrorClip(vary_position);
+ vec2 screen_tc = (refCoord.xy/refCoord.z) * 0.5 + 0.5;
+ float water_mask = texture(exclusionTex, screen_tc).r;
+
vec4 color;
//get detail normals
@@ -68,8 +72,8 @@ void main()
vec3 wavef = normalize(wave1+wave2+wave3);
//figure out distortion vector (ripply)
- vec2 distort = (refCoord.xy/refCoord.z) * 0.5 + 0.5;
- distort = distort+wavef.xy*refScale;
+ vec2 distort = screen_tc;
+ distort = mix(distort, distort+wavef.xy*refScale, water_mask);
#ifdef TRANSPARENT_WATER
vec4 fb = texture(screenTex, distort);
diff --git a/indra/newview/app_settings/shaders/class3/environment/waterF.glsl b/indra/newview/app_settings/shaders/class3/environment/waterF.glsl
index 84c287fc50..028813ef23 100644
--- a/indra/newview/app_settings/shaders/class3/environment/waterF.glsl
+++ b/indra/newview/app_settings/shaders/class3/environment/waterF.glsl
@@ -25,6 +25,8 @@
// class3/environment/waterF.glsl
+#define WATER_MINIMAL 1
+
out vec4 frag_color;
#ifdef HAS_SUN_SHADOW
@@ -86,23 +88,17 @@ uniform sampler2D screenTex;
uniform sampler2D depthMap;
#endif
-uniform sampler2D refTex;
+uniform sampler2D exclusionTex;
-uniform float sunAngle;
-uniform float sunAngle2;
+uniform int classic_mode;
uniform vec3 lightDir;
uniform vec3 specular;
-uniform float lightExp;
+uniform float blurMultiplier;
uniform float refScale;
uniform float kd;
-uniform vec2 screenRes;
uniform vec3 normScale;
uniform float fresnelScale;
uniform float fresnelOffset;
-uniform float blurMultiplier;
-uniform vec4 waterFogColor;
-uniform vec3 waterFogColorLinear;
-
//bigWave is (refCoord.w, view.w);
in vec4 refCoord;
@@ -122,6 +118,10 @@ vec3 BlendNormal(vec3 bump1, vec3 bump2)
vec3 srgb_to_linear(vec3 col);
vec3 linear_to_srgb(vec3 col);
+vec3 atmosLighting(vec3 light);
+vec3 scaleSoftClip(vec3 light);
+vec3 toneMapNoExposure(vec3 color);
+
vec3 vN, vT, vB;
vec3 transform_normal(vec3 vNt)
@@ -132,59 +132,107 @@ vec3 transform_normal(vec3 vNt)
void sampleReflectionProbesWater(inout vec3 ambenv, inout vec3 glossenv,
vec2 tc, vec3 pos, vec3 norm, float glossiness, vec3 amblit_linear);
+void sampleReflectionProbes(inout vec3 ambenv, inout vec3 glossenv,
+ vec2 tc, vec3 pos, vec3 norm, float glossiness, bool transparent, vec3 amblit_linear);
+
+void sampleReflectionProbesLegacy(inout vec3 ambenv, inout vec3 glossenv, inout vec3 legacyenv,
+ vec2 tc, vec3 pos, vec3 norm, float glossiness, float envIntensity, bool transparent, vec3 amblit);
+
+
vec3 getPositionWithNDC(vec3 ndc);
+void generateWaveNormals(out vec3 wave1, out vec3 wave2, out vec3 wave3)
+{
+ // Generate all of our wave normals.
+ // We layer these back and forth.
+
+ vec2 bigwave = vec2(refCoord.w, view.w);
+
+ vec3 wave1_a = texture(bumpMap, bigwave).xyz * 2.0 - 1.0;
+ vec3 wave2_a = texture(bumpMap, littleWave.xy).xyz * 2.0 - 1.0;
+ vec3 wave3_a = texture(bumpMap, littleWave.zw).xyz * 2.0 - 1.0;
+
+ vec3 wave1_b = texture(bumpMap2, bigwave).xyz * 2.0 - 1.0;
+ vec3 wave2_b = texture(bumpMap2, littleWave.xy).xyz * 2.0 - 1.0;
+ vec3 wave3_b = texture(bumpMap2, littleWave.zw).xyz * 2.0 - 1.0;
+
+ wave1 = BlendNormal(wave1_a, wave1_b);
+ wave2 = BlendNormal(wave2_a, wave2_b);
+ wave3 = BlendNormal(wave3_a, wave3_b);
+}
+
+void calculateFresnelFactors(out vec3 df3, out vec2 df2, vec3 viewVec, vec3 wave1, vec3 wave2, vec3 wave3, vec3 wavef)
+{
+ // We calculate the fresnel here.
+ // We do this by getting the dot product for each sets of waves, and applying scale and offset.
+
+ df3 = max(vec3(0), vec3(
+ dot(viewVec, wave1),
+ dot(viewVec, (wave2 + wave3) * 0.5),
+ dot(viewVec, wave3)
+ ) * fresnelScale + fresnelOffset);
+
+ df3 *= df3;
+
+ df2 = max(vec2(0), vec2(
+ df3.x + df3.y + df3.z,
+ dot(viewVec, wavef) * fresnelScale + fresnelOffset
+ ));
+}
+
void main()
{
mirrorClip(vary_position);
+
vN = vary_normal;
vT = vary_tangent;
vB = cross(vN, vT);
vec3 pos = vary_position.xyz;
+ float linear_depth = 1.0 / -pos.z;
float dist = length(pos.xyz);
//normalize view vector
vec3 viewVec = normalize(pos.xyz);
- //get wave normals
- vec2 bigwave = vec2(refCoord.w, view.w);
- vec3 wave1_a = texture(bumpMap, bigwave, -2.0 ).xyz*2.0-1.0;
- vec3 wave2_a = texture(bumpMap, littleWave.xy).xyz*2.0-1.0;
- vec3 wave3_a = texture(bumpMap, littleWave.zw).xyz*2.0-1.0;
+ // Setup our waves.
- vec3 wave1_b = texture(bumpMap2, bigwave ).xyz*2.0-1.0;
- vec3 wave2_b = texture(bumpMap2, littleWave.xy).xyz*2.0-1.0;
- vec3 wave3_b = texture(bumpMap2, littleWave.zw).xyz*2.0-1.0;
+ vec3 wave1 = vec3(0, 0, 1);
+ vec3 wave2 = vec3(0, 0, 1);
+ vec3 wave3 = vec3(0, 0, 1);
- //wave1_a = wave2_a = wave3_a = wave1_b = wave2_b = wave3_b = vec3(0,0,1);
-
- vec3 wave1 = BlendNormal(wave1_a, wave1_b);
- vec3 wave2 = BlendNormal(wave2_a, wave2_b);
- vec3 wave3 = BlendNormal(wave3_a, wave3_b);
+ generateWaveNormals(wave1, wave2, wave3);
+ float dmod = sqrt(dist);
vec2 distort = (refCoord.xy/refCoord.z) * 0.5 + 0.5;
- //wave1 = transform_normal(wave1);
- //wave2 = transform_normal(wave2);
- //wave3 = transform_normal(wave3);
-
vec3 wavef = (wave1 + wave2 * 0.4 + wave3 * 0.6) * 0.5;
+ vec3 df3 = vec3(0);
+ vec2 df2 = vec2(0);
+
+ vec3 sunlit;
+ vec3 amblit;
+ vec3 additive;
+ vec3 atten;
+ calcAtmosphericVarsLinear(pos.xyz, wavef, vary_light_dir, sunlit, amblit, additive, atten);
+
+ calculateFresnelFactors(df3, df2, normalize(view.xyz), wave1, wave2, wave3, wavef);
+
vec3 waver = wavef*3.0;
vec3 up = transform_normal(vec3(0,0,1));
float vdu = -dot(viewVec, up)*2.0;
- vec3 wave_ibl = wavef;
+ vec3 wave_ibl = wavef * normScale;
wave_ibl.z *= 2.0;
wave_ibl = transform_normal(normalize(wave_ibl));
vec3 norm = transform_normal(normalize(wavef));
vdu = clamp(vdu, 0.0, 1.0);
- wavef.z *= max(vdu*vdu*vdu, 0.1);
+ //wavef.z *= max(vdu*vdu*vdu, 0.1);
wavef = normalize(wavef);
@@ -194,62 +242,66 @@ void main()
float dist2 = dist;
dist = max(dist, 5.0);
- float dmod = sqrt(dist);
-
//figure out distortion vector (ripply)
- vec2 distort2 = distort + waver.xy * refScale / max(dmod, 1.0);
+ vec2 distort2 = distort + waver.xy * refScale / max(dmod, 1.0) * 2.0;
distort2 = clamp(distort2, vec2(0), vec2(0.999));
- vec3 sunlit;
- vec3 amblit;
- vec3 additive;
- vec3 atten;
-
float shadow = 1.0f;
+ float water_mask = texture(exclusionTex, distort).r;
+
#ifdef HAS_SUN_SHADOW
shadow = sampleDirectionalShadow(pos.xyz, norm.xyz, distort);
#endif
- calcAtmosphericVarsLinear(pos.xyz, wavef, vary_light_dir, sunlit, amblit, additive, atten);
-
vec3 sunlit_linear = srgb_to_linear(sunlit);
-
+ float fade = 0.0;
#ifdef TRANSPARENT_WATER
- vec4 fb = texture(screenTex, distort2);
- float depth = texture(depthMap, distort2).r;
- vec3 refPos = getPositionWithNDC(vec3(distort2*2.0-vec2(1.0), depth*2.0-1.0));
+ float depth = texture(depthMap, distort).r;
+
+ vec3 refPos = getPositionWithNDC(vec3(distort*2.0-vec2(1.0), depth*2.0-1.0));
+
+ // Calculate some distance fade in the water to better assist with refraction blending and reducing the refraction texture's "disconnect".
+ fade = max(0.0,min(1.0, (pos.z - refPos.z) / 10.0)) * water_mask;
+ distort2 = mix(distort, distort2, min(1.0, fade * 10.0));
+ depth = texture(depthMap, distort2).r;
+
+ refPos = getPositionWithNDC(vec3(distort2 * 2.0 - vec2(1.0), depth * 2.0 - 1.0));
- if (refPos.z > pos.z-0.05)
+ if (pos.z < refPos.z - 0.05)
{
- //we sampled an above water sample, don't distort
distort2 = distort;
- fb = texture(screenTex, distort2);
- depth = texture(depthMap, distort2).r;
- refPos = getPositionWithNDC(vec3(distort2 * 2.0 - vec2(1.0), depth * 2.0 - 1.0));
}
+ vec4 fb = texture(screenTex, distort2);
+
#else
vec4 fb = applyWaterFogViewLinear(viewVec*2048.0, vec4(1.0));
-#endif
- // fudge sample on other side of water to be a tad darker
- fb.rgb *= 0.75;
+ if (water_mask < 1.0)
+ discard;
+#endif
- float metallic = 0.0;
- float perceptualRoughness = 0.05;
+ float metallic = 1.0;
+ float perceptualRoughness = blurMultiplier;
float gloss = 1.0 - perceptualRoughness;
vec3 irradiance = vec3(0);
vec3 radiance = vec3(0);
- sampleReflectionProbesWater(irradiance, radiance, distort2, pos.xyz, wave_ibl.xyz, gloss, amblit);
+ vec3 legacyenv = vec3(0);
- irradiance = vec3(0);
+ // TODO: Make this an option.
+#ifdef WATER_MINIMAL
+ sampleReflectionProbesWater(irradiance, radiance, distort2, pos.xyz, wave_ibl.xyz, gloss, amblit);
+#elif WATER_MINIMAL_PLUS
+ sampleReflectionProbes(irradiance, radiance, distort2, pos.xyz, wave_ibl.xyz, gloss, false, amblit);
+#endif
vec3 diffuseColor = vec3(0);
vec3 specularColor = vec3(0);
- calcDiffuseSpecular(vec3(1), metallic, diffuseColor, specularColor);
+ vec3 specular_linear = srgb_to_linear(specular);
+ calcDiffuseSpecular(specular_linear, metallic, diffuseColor, specularColor);
vec3 v = -normalize(pos.xyz);
@@ -257,46 +309,36 @@ void main()
float ao = 1.0;
vec3 light_dir = transform_normal(lightDir);
- perceptualRoughness = 0.0;
- metallic = 1.0;
-
float NdotV = clamp(abs(dot(norm, v)), 0.001, 1.0);
- float nl = 0;
+ float nl = 0.0;
vec3 diffPunc = vec3(0);
vec3 specPunc = vec3(0);
- pbrPunctual(vec3(0), specularColor, 0.1, metallic, normalize(wavef+up*max(dist, 32.0)/32.0*(1.0-vdu)), v, normalize(light_dir), nl, diffPunc, specPunc);
-
- vec3 punctual = clamp(nl * (diffPunc + specPunc), vec3(0), vec3(10));
-
- vec3 color = punctual * sunlit_linear * 2.75 * shadow;
- vec3 iblDiff;
- vec3 iblSpec;
- pbrIbl(vec3(0), vec3(1), radiance, vec3(0), ao, NdotV, 0.0, iblDiff, iblSpec);
-
- color += iblDiff + iblSpec;
+ pbrPunctual(diffuseColor, specularColor, perceptualRoughness, metallic, normalize(wavef+up*max(dist, 32.0)/32.0*(1.0-vdu)), v, normalize(light_dir), nl, diffPunc, specPunc);
- float nv = clamp(abs(dot(norm.xyz, v)), 0.001, 1.0);
- vec2 brdf = BRDF(clamp(nv, 0.0, 1.0), 1.0);
- float f = 1.0-brdf.y; //1.0 - (brdf.x+brdf.y);
- f *= 0.9;
- f *= f;
+ vec3 punctual = clamp(nl * (diffPunc + specPunc), vec3(0), vec3(10)) * sunlit_linear * shadow;
+ radiance *= df2.y;
+ //radiance = toneMapNoExposure(radiance);
+ vec3 color = vec3(0);
+ color = mix(fb.rgb, radiance, min(1.0, df2.x)) + punctual.rgb;
- // incoming scale is [0, 1] with 0.5 being default
- // shift to 0.5 to 1.5
- f *= (fresnelScale - 0.5)+1.0;
+ float water_haze_scale = 4.0;
- // incoming offset is [0, 1] with 0.5 being default
- // shift from -1 to 1
- f += (fresnelOffset - 0.5) * 2.0;
+ if (classic_mode > 0)
+ water_haze_scale = 1.0;
- f = clamp(f, 0.0, 1.0);
+ // This looks super janky, but we do this to restore water haze in the distance.
+ // These values were finagled in to try and bring back some of the distant brightening on legacy water. Also works reasonably well on PBR skies such as PBR midday.
+ // color = mix(color, additive * water_haze_scale, (1 - atten));
- color = ((1.0 - f) * color) + fb.rgb;
+ // We shorten the fade here at the shoreline so it doesn't appear too soft from a distance.
+ fade *= 60.0;
+ fade = min(1.0, fade);
+ color = mix(fb.rgb, color, fade);
- float spec = min(max(max(punctual.r, punctual.g), punctual.b), 0.05);
+ float spec = min(max(max(punctual.r, punctual.g), punctual.b), 0.0);
- frag_color = max(vec4(color, spec), vec4(0));
+ frag_color = min(vec4(1),max(vec4(color.rgb, spec * water_mask), vec4(0)));
}
diff --git a/indra/newview/featuretable.txt b/indra/newview/featuretable.txt
index d894e1b24e..cb79410d72 100644
--- a/indra/newview/featuretable.txt
+++ b/indra/newview/featuretable.txt
@@ -85,6 +85,7 @@ RenderExposure 1 4
RenderTonemapType 1 1
RenderTonemapMix 1 1
RenderDisableVintageMode 1 1
+RenderMaxTextureResolution 1 2048
//
// Low Graphics Settings
@@ -126,6 +127,7 @@ RenderExposure 1 1
RenderTonemapType 1 1
RenderTonemapMix 1 0.7
RenderDisableVintageMode 1 0
+RenderMaxTextureResolution 1 512
//
// Medium Low Graphics Settings
@@ -167,6 +169,7 @@ RenderExposure 1 1
RenderTonemapType 1 1
RenderTonemapMix 1 0.7
RenderDisableVintageMode 1 0
+RenderMaxTextureResolution 1 1024
//
// Medium Graphics Settings (standard)
@@ -207,6 +210,7 @@ RenderCASSharpness 1 0
RenderExposure 1 1
RenderTonemapType 1 1
RenderTonemapMix 1 0.7
+RenderMaxTextureResolution 1 2048
//
// Medium High Graphics Settings
@@ -247,6 +251,7 @@ RenderCASSharpness 1 0
RenderExposure 1 1
RenderTonemapType 1 1
RenderTonemapMix 1 0.7
+RenderMaxTextureResolution 1 2048
//
// High Graphics Settings (SSAO + sun shadows)
@@ -287,6 +292,7 @@ RenderCASSharpness 1 0.4
RenderExposure 1 1
RenderTonemapType 1 1
RenderTonemapMix 1 0.7
+RenderMaxTextureResolution 1 2048
//
// High Ultra Graphics Settings (deferred + SSAO + all shadows)
@@ -327,6 +333,7 @@ RenderCASSharpness 1 0.4
RenderExposure 1 1
RenderTonemapType 1 1
RenderTonemapMix 1 0.7
+RenderMaxTextureResolution 1 2048
//
// Ultra graphics (REALLY PURTY!)
@@ -367,6 +374,7 @@ RenderCASSharpness 1 0.4
RenderExposure 1 1
RenderTonemapType 1 1
RenderTonemapMix 1 0.7
+RenderMaxTextureResolution 1 2048
//
// Class Unknown Hardware (unknown)
@@ -399,6 +407,7 @@ RenderShadowDetail 0 0
RenderReflectionProbeDetail 0 -1
RenderMirrors 0 0
RenderDisableVintageMode 1 0
+RenderMaxTextureResolution 1 2048
list Intel
RenderAnisotropic 1 0
diff --git a/indra/newview/featuretable_mac.txt b/indra/newview/featuretable_mac.txt
index eedce61509..f3c3c4fcd9 100644
--- a/indra/newview/featuretable_mac.txt
+++ b/indra/newview/featuretable_mac.txt
@@ -85,6 +85,7 @@ RenderTonemapType 1 1
RenderTonemapMix 1 1
RenderDisableVintageMode 1 1
RenderDownScaleMethod 1 0
+RenderMaxTextureResolution 1 2048
//
// Low Graphics Settings
@@ -126,6 +127,7 @@ RenderExposure 1 1
RenderTonemapType 1 1
RenderTonemapMix 1 0.7
RenderDisableVintageMode 1 0
+RenderMaxTextureResolution 1 512
//
@@ -168,6 +170,7 @@ RenderExposure 1 1
RenderTonemapType 1 1
RenderTonemapMix 1 0.7
RenderDisableVintageMode 1 0
+RenderMaxTextureResolution 1 1024
//
// Medium Graphics Settings (standard)
@@ -208,6 +211,7 @@ RenderCASSharpness 1 0
RenderExposure 1 1
RenderTonemapType 1 1
RenderTonemapMix 1 0.7
+RenderMaxTextureResolution 1 2048
//
// Medium High Graphics Settings
@@ -248,6 +252,7 @@ RenderCASSharpness 1 0
RenderExposure 1 1
RenderTonemapType 1 1
RenderTonemapMix 1 0.7
+RenderMaxTextureResolution 1 2048
//
// High Graphics Settings (SSAO + sun shadows)
@@ -288,6 +293,7 @@ RenderCASSharpness 1 0
RenderExposure 1 1
RenderTonemapType 1 1
RenderTonemapMix 1 0.7
+RenderMaxTextureResolution 1 2048
//
// High Ultra Graphics Settings (SSAO + all shadows)
@@ -328,6 +334,7 @@ RenderCASSharpness 1 0.4
RenderExposure 1 1
RenderTonemapType 1 1
RenderTonemapMix 1 0.7
+RenderMaxTextureResolution 1 2048
//
// Ultra graphics (REALLY PURTY!)
@@ -368,6 +375,7 @@ RenderCASSharpness 1 0.4
RenderExposure 1 1
RenderTonemapType 1 1
RenderTonemapMix 1 0.7
+RenderMaxTextureResolution 1 2048
//
// Class Unknown Hardware (unknown)
@@ -399,6 +407,7 @@ RenderDeferredSSAO 0 0
RenderShadowDetail 0 0
RenderMirrors 0 0
RenderDisableVintageMode 1 0
+RenderMaxTextureResolution 1 2048
list TexUnit8orLess
RenderDeferredSSAO 0 0
diff --git a/indra/newview/gltfscenemanager.cpp b/indra/newview/gltfscenemanager.cpp
index f362fa51cb..737e1da7d1 100644
--- a/indra/newview/gltfscenemanager.cpp
+++ b/indra/newview/gltfscenemanager.cpp
@@ -975,9 +975,9 @@ void renderAssetDebug(LLViewerObject* obj, Asset* asset)
LLVector4a t;
agent_to_asset.affineTransform(gDebugRaycastStart, t);
- start = glm::make_vec4(t.getF32ptr());
+ start = vec4(t);
agent_to_asset.affineTransform(gDebugRaycastEnd, t);
- end = glm::make_vec4(t.getF32ptr());
+ end = vec4(t);
start.w = end.w = 1.0;
diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp
index 26c080bf89..8756baa04a 100644
--- a/indra/newview/llagent.cpp
+++ b/indra/newview/llagent.cpp
@@ -4879,10 +4879,19 @@ void LLAgent::parseTeleportMessages(const std::string& xml_filename)
LLXMLNodePtr root;
bool success = LLUICtrlFactory::getLayeredXMLNode(xml_filename, root);
- if (!success || !root || !root->hasName( "teleport_messages" ))
+ if (!success)
{
+ LLError::LLUserWarningMsg::showMissingFiles();
LL_ERRS() << "Problem reading teleport string XML file: "
- << xml_filename << LL_ENDL;
+ << xml_filename << LL_ENDL;
+ return;
+ }
+
+ if (!root || !root->hasName("teleport_messages"))
+ {
+ LLError::LLUserWarningMsg::showMissingFiles();
+ LL_ERRS() << "Invalid teleport string XML file: "
+ << xml_filename << LL_ENDL;
return;
}
diff --git a/indra/newview/llagentpicksinfo.cpp b/indra/newview/llagentpicksinfo.cpp
index e2a2d2d8a9..265e4060ff 100644
--- a/indra/newview/llagentpicksinfo.cpp
+++ b/indra/newview/llagentpicksinfo.cpp
@@ -28,6 +28,7 @@
#include "llagentpicksinfo.h"
#include "llagent.h"
+#include "llagentbenefits.h"
#include "llavatarpropertiesprocessor.h"
const S32 MAX_AVATAR_PICKS = 10;
@@ -85,10 +86,9 @@ private:
LLAgentPicksInfo::LLAgentPicksInfo()
: mAgentPicksObserver(NULL)
- , mMaxNumberOfPicks(MAX_AVATAR_PICKS)
// Disable Pick creation until we get number of Picks from server - in case
// avatar has maximum number of Picks.
- , mNumberOfPicks(mMaxNumberOfPicks)
+ , mNumberOfPicks(S32_MAX)
{
}
@@ -110,7 +110,13 @@ void LLAgentPicksInfo::requestNumberOfPicks()
mAgentPicksObserver->sendAgentPicksRequest();
}
-bool LLAgentPicksInfo::isPickLimitReached()
+// static
+S32 LLAgentPicksInfo::getMaxNumberOfPicks()
+{
+ return LLAgentBenefitsMgr::current().getPicksLimit();
+}
+
+bool LLAgentPicksInfo::isPickLimitReached() const
{
return getNumberOfPicks() >= getMaxNumberOfPicks();
}
diff --git a/indra/newview/llagentpicksinfo.h b/indra/newview/llagentpicksinfo.h
index 9bc105a655..3514ade65d 100644
--- a/indra/newview/llagentpicksinfo.h
+++ b/indra/newview/llagentpicksinfo.h
@@ -52,17 +52,17 @@ public:
/**
* Returns number of Picks.
*/
- S32 getNumberOfPicks() { return mNumberOfPicks; }
+ S32 getNumberOfPicks() const { return mNumberOfPicks; }
/**
* Returns maximum number of Picks.
*/
- S32 getMaxNumberOfPicks() { return mMaxNumberOfPicks; }
+ static S32 getMaxNumberOfPicks();
/**
* Returns true if Agent has maximum allowed number of Picks.
*/
- bool isPickLimitReached();
+ bool isPickLimitReached() const;
/**
* After creating or deleting a Pick we can assume operation on server will be
@@ -83,15 +83,9 @@ private:
*/
void setNumberOfPicks(S32 number) { mNumberOfPicks = number; }
- /**
- * Sets maximum number of Picks.
- */
- void setMaxNumberOfPicks(S32 max_picks) { mMaxNumberOfPicks = max_picks; }
-
private:
LLAgentPicksObserver* mAgentPicksObserver;
- S32 mMaxNumberOfPicks;
S32 mNumberOfPicks;
};
diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp
index 946d674e8b..4e0c5d7df0 100644
--- a/indra/newview/llappearancemgr.cpp
+++ b/indra/newview/llappearancemgr.cpp
@@ -537,9 +537,14 @@ LLUpdateAppearanceOnDestroy::~LLUpdateAppearanceOnDestroy()
selfStopPhase("update_appearance_on_destroy");
- LLAppearanceMgr::instance().updateAppearanceFromCOF(mEnforceItemRestrictions,
- mEnforceOrdering,
- mPostUpdateFunc);
+ //avoid calling an update inside coroutine
+ bool force_restrictions(mEnforceItemRestrictions);
+ bool enforce_ordering(mEnforceOrdering);
+ nullary_func_t post_update_func(mPostUpdateFunc);
+ doOnIdleOneTime([force_restrictions,enforce_ordering,post_update_func]()
+ {
+ LLAppearanceMgr::instance().updateAppearanceFromCOF(force_restrictions, enforce_ordering, post_update_func);
+ });
}
}
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index 7c040a3ca1..2c203869c7 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -305,6 +305,7 @@ bool gUseQuickTime = true;
eLastExecEvent gLastExecEvent = LAST_EXEC_NORMAL;
S32 gLastExecDuration = -1; // (<0 indicates unknown)
+LLUUID gLastAgentSessionId;
#if LL_WINDOWS
# define LL_PLATFORM_KEY "win"
@@ -381,7 +382,6 @@ const int MAX_MARKER_LENGTH = 1024;
const std::string MARKER_FILE_NAME("SecondLife.exec_marker");
const std::string START_MARKER_FILE_NAME("SecondLife.start_marker");
const std::string ERROR_MARKER_FILE_NAME("SecondLife.error_marker");
-const std::string LLERROR_MARKER_FILE_NAME("SecondLife.llerror_marker");
const std::string LOGOUT_MARKER_FILE_NAME("SecondLife.logout_marker");
static bool gDoDisconnect = false;
static std::string gLaunchFileOnQuit;
@@ -2262,6 +2262,7 @@ bool LLAppViewer::initThreads()
return true;
}
+// Callback for all LL_ERROR calls
void errorCallback(LLError::ELevel level, const std::string &error_string)
{
if (level == LLError::LEVEL_ERROR)
@@ -2277,15 +2278,38 @@ void errorCallback(LLError::ELevel level, const std::string &error_string)
// haven't actually trashed anything yet, we can afford to write the whole
// static info file.
LLAppViewer::instance()->writeDebugInfo();
+
+ std::string error_marker_file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, ERROR_MARKER_FILE_NAME);
+ if (!LLAPRFile::isExist(error_marker_file, NULL, LL_APR_RB))
+ {
+ // If marker doesn't exist, create a marker with llerror code for next launch
+ // otherwise don't override existing file
+ LLAppViewer::instance()->createErrorMarker(LAST_EXEC_LLERROR_CRASH);
+ }
}
}
-void errorMSG(const std::string& title_string, const std::string& message_string)
+// Callback for LLError::LLUserWarningMsg
+void errorHandler(const std::string& title_string, const std::string& message_string, S32 code)
{
if (!message_string.empty())
{
OSMessageBox(message_string, title_string.empty() ? LLTrans::getString("MBFatalError") : title_string, OSMB_OK);
}
+ switch (code)
+ {
+ case LLError::LLUserWarningMsg::ERROR_OTHER:
+ LLAppViewer::instance()->createErrorMarker(LAST_EXEC_OTHER_CRASH);
+ break;
+ case LLError::LLUserWarningMsg::ERROR_BAD_ALLOC:
+ LLAppViewer::instance()->createErrorMarker(LAST_EXEC_BAD_ALLOC);
+ break;
+ case LLError::LLUserWarningMsg::ERROR_MISSING_FILES:
+ LLAppViewer::instance()->createErrorMarker(LAST_EXEC_MISSING_FILES);
+ break;
+ default:
+ break;
+ }
}
void LLAppViewer::initLoggingAndGetLastDuration()
@@ -2299,7 +2323,7 @@ void LLAppViewer::initLoggingAndGetLastDuration()
LLError::addGenericRecorder(&errorCallback);
//LLError::setTimeFunction(getRuntime);
- LLError::LLUserWarningMsg::setHandler(errorMSG);
+ LLError::LLUserWarningMsg::setHandler(errorHandler);
if (mSecondInstance)
@@ -2591,6 +2615,7 @@ bool LLAppViewer::initConfiguration()
OSMessageBox(
"Unable to load default settings file. The installation may be corrupted.",
LLStringUtil::null,OSMB_OK);
+ LLAppViewer::instance()->createErrorMarker(LAST_EXEC_MISSING_FILES);
return false;
}
@@ -3755,16 +3780,21 @@ bool LLAppViewer::markerIsSameVersion(const std::string& marker_name) const
bool sameVersion = false;
std::string my_version(LLVersionInfo::instance().getChannelAndVersion());
- char marker_version[MAX_MARKER_LENGTH];
+ char marker_data[MAX_MARKER_LENGTH];
S32 marker_version_length;
LLAPRFile marker_file;
marker_file.open(marker_name, LL_APR_RB);
if (marker_file.getFileHandle())
{
- marker_version_length = marker_file.read(marker_version, sizeof(marker_version));
- std::string marker_string(marker_version, marker_version_length);
- if ( 0 == my_version.compare( 0, my_version.length(), marker_version, 0, marker_version_length ) )
+ marker_version_length = marker_file.read(marker_data, sizeof(marker_data));
+ std::string marker_string(marker_data, marker_version_length);
+ size_t pos = marker_string.find('\n');
+ if (pos != std::string::npos)
+ {
+ marker_string = marker_string.substr(0, pos);
+ }
+ if ( 0 == my_version.compare( 0, my_version.length(), marker_string, 0, marker_string.length()) )
{
sameVersion = true;
}
@@ -3778,6 +3808,88 @@ bool LLAppViewer::markerIsSameVersion(const std::string& marker_name) const
return sameVersion;
}
+void LLAppViewer::recordSessionToMarker()
+{
+ std::string marker_version(LLVersionInfo::instance().getChannelAndVersion());
+ std::string uuid_str = "\n" + gAgentSessionID.asString();
+ if (marker_version.length() + uuid_str.length() > MAX_MARKER_LENGTH)
+ {
+ LL_WARNS_ONCE("MarkerFile") << "Version length (" << marker_version.length() << ")"
+ << " greater than maximum (" << MAX_MARKER_LENGTH << ")"
+ << ": marker matching may be incorrect"
+ << LL_ENDL;
+ }
+
+ mMarkerFile.seek(APR_SET, (S32)marker_version.length());
+ mMarkerFile.write(uuid_str.data(), (S32)uuid_str.length());
+}
+
+LLUUID LLAppViewer::getMarkerSessionId(const std::string& marker_name) const
+{
+ std::string data;
+ if (getMarkerData(marker_name, data))
+ {
+ return LLUUID(data);
+ }
+ return LLUUID();
+}
+
+S32 LLAppViewer::getMarkerErrorCode(const std::string& marker_name) const
+{
+ std::string data;
+ if (getMarkerData(marker_name, data))
+ {
+ if (data.empty())
+ {
+ return 0;
+ }
+ else
+ {
+ return std::stoi(data);
+ }
+ }
+ return -1;
+}
+
+bool LLAppViewer::getMarkerData(const std::string& marker_name, std::string& data) const
+{
+ bool sameVersion = false;
+
+ std::string my_version(LLVersionInfo::instance().getChannelAndVersion());
+ char marker_data[MAX_MARKER_LENGTH];
+ S32 marker_version_length;
+
+ LLAPRFile marker_file;
+ marker_file.open(marker_name, LL_APR_RB);
+ if (marker_file.getFileHandle())
+ {
+ marker_version_length = marker_file.read(marker_data, sizeof(marker_data));
+ marker_file.close();
+ std::string marker_string(marker_data, marker_version_length);
+ size_t pos = marker_string.find('\n');
+ if (pos != std::string::npos)
+ {
+ data = marker_string.substr(pos + 1, marker_version_length - pos - 1);
+ marker_string = marker_string.substr(0, pos);
+ }
+ if (0 == my_version.compare(0, my_version.length(), marker_string, 0, marker_string.length()))
+ {
+ sameVersion = true;
+ }
+ else
+ {
+ return false;
+ }
+ LL_DEBUGS("MarkerFile") << "Compare markers for '" << marker_name << "': "
+ << "\n mine '" << my_version << "'"
+ << "\n marker '" << marker_string << "'"
+ << "\n " << (sameVersion ? "same" : "different") << " version"
+ << LL_ENDL;
+ return true;
+ }
+ return false;
+}
+
void LLAppViewer::processMarkerFiles()
{
//We've got 4 things to test for here
@@ -3796,6 +3908,10 @@ void LLAppViewer::processMarkerFiles()
// File exists...
// first, read it to see if it was created by the same version (we need this later)
marker_is_same_version = markerIsSameVersion(mMarkerFileName);
+ if (marker_is_same_version)
+ {
+ gLastAgentSessionId = getMarkerSessionId(mMarkerFileName);
+ }
// now test to see if this file is locked by a running process (try to open for write)
marker_log_stream << "Checking exec marker file for lock...";
@@ -3885,44 +4001,27 @@ void LLAppViewer::processMarkerFiles()
}
LLAPRFile::remove(logout_marker_file);
}
- // further refine based on whether or not a marker created during an llerr crash is found
- std::string llerror_marker_file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, LLERROR_MARKER_FILE_NAME);
- if(LLAPRFile::isExist(llerror_marker_file, NULL, LL_APR_RB))
- {
- if (markerIsSameVersion(llerror_marker_file))
- {
- if ( gLastExecEvent == LAST_EXEC_LOGOUT_FROZE )
- {
- gLastExecEvent = LAST_EXEC_LOGOUT_CRASH;
- LL_INFOS("MarkerFile") << "LLError marker '"<< llerror_marker_file << "' crashed, setting LastExecEvent to LOGOUT_CRASH" << LL_ENDL;
- }
- else
- {
- gLastExecEvent = LAST_EXEC_LLERROR_CRASH;
- LL_INFOS("MarkerFile") << "LLError marker '"<< llerror_marker_file << "' crashed, setting LastExecEvent to LLERROR_CRASH" << LL_ENDL;
- }
- }
- else
- {
- LL_INFOS("MarkerFile") << "LLError marker '"<< llerror_marker_file << "' found, but versions did not match" << LL_ENDL;
- }
- LLAPRFile::remove(llerror_marker_file);
- }
// and last refine based on whether or not a marker created during a non-llerr crash is found
std::string error_marker_file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, ERROR_MARKER_FILE_NAME);
if(LLAPRFile::isExist(error_marker_file, NULL, LL_APR_RB))
{
- if (markerIsSameVersion(error_marker_file))
+ S32 marker_code = getMarkerErrorCode(error_marker_file);
+ if (marker_code >= 0)
{
if (gLastExecEvent == LAST_EXEC_LOGOUT_FROZE)
{
gLastExecEvent = LAST_EXEC_LOGOUT_CRASH;
LL_INFOS("MarkerFile") << "Error marker '"<< error_marker_file << "' crashed, setting LastExecEvent to LOGOUT_CRASH" << LL_ENDL;
}
+ else if (marker_code > 0 && marker_code < (S32)LAST_EXEC_COUNT)
+ {
+ gLastExecEvent = (eLastExecEvent)marker_code;
+ LL_INFOS("MarkerFile") << "Error marker '"<< error_marker_file << "' crashed, setting LastExecEvent to " << gLastExecEvent << LL_ENDL;
+ }
else
{
gLastExecEvent = LAST_EXEC_OTHER_CRASH;
- LL_INFOS("MarkerFile") << "Error marker '"<< error_marker_file << "' crashed, setting LastExecEvent to " << gLastExecEvent << LL_ENDL;
+ LL_INFOS("MarkerFile") << "Error marker '" << error_marker_file << "' crashed, setting LastExecEvent to " << gLastExecEvent << LL_ENDL;
}
}
else
@@ -5212,6 +5311,24 @@ void LLAppViewer::postToMainCoro(const LL::WorkQueue::Work& work)
gMainloopWork.post(work);
}
+void LLAppViewer::createErrorMarker(eLastExecEvent error_code) const
+{
+ if (!mSecondInstance)
+ {
+ std::string error_marker = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, ERROR_MARKER_FILE_NAME);
+
+ LLAPRFile file;
+ file.open(error_marker, LL_APR_WB);
+ if (file.getFileHandle())
+ {
+ recordMarkerVersion(file);
+ std::string data = "\n" + std::to_string((S32)error_code);
+ file.write(data.data(), static_cast<S32>(data.length()));
+ file.close();
+ }
+ }
+}
+
void LLAppViewer::outOfMemorySoftQuit()
{
if (!mQuitRequested)
diff --git a/indra/newview/llappviewer.h b/indra/newview/llappviewer.h
index 4ce4259ed8..b4756eecd6 100644
--- a/indra/newview/llappviewer.h
+++ b/indra/newview/llappviewer.h
@@ -66,6 +66,20 @@ class LLViewerRegion;
extern LLTrace::BlockTimerStatHandle FTM_FRAME;
+typedef enum
+{
+ LAST_EXEC_NORMAL = 0,
+ LAST_EXEC_FROZE,
+ LAST_EXEC_LLERROR_CRASH,
+ LAST_EXEC_OTHER_CRASH,
+ LAST_EXEC_LOGOUT_FROZE,
+ LAST_EXEC_LOGOUT_CRASH,
+ LAST_EXEC_BAD_ALLOC,
+ LAST_EXEC_MISSING_FILES,
+ LAST_EXEC_GRAPHICS_INIT,
+ LAST_EXEC_COUNT
+} eLastExecEvent;
+
class LLAppViewer : public LLApp
{
public:
@@ -147,6 +161,7 @@ public:
void saveExperienceCache();
void removeMarkerFiles();
+ void recordSessionToMarker();
void removeDumpDir();
// LLAppViewer testing helpers.
@@ -227,6 +242,9 @@ public:
// post given work to the "mainloop" work queue for handling on the main thread
void postToMainCoro(const LL::WorkQueue::Work& work);
+ // Writes an error code into the error_marker file for use on next startup.
+ void createErrorMarker(eLastExecEvent error_code) const;
+
// Attempt a 'soft' quit with disconnect and saving of settings/cache.
// Intended to be thread safe.
// Good chance of viewer crashing either way, but better than alternatives.
@@ -272,6 +290,9 @@ private:
void processMarkerFiles();
static void recordMarkerVersion(LLAPRFile& marker_file);
bool markerIsSameVersion(const std::string& marker_name) const;
+ LLUUID getMarkerSessionId(const std::string& marker_name) const;
+ S32 getMarkerErrorCode(const std::string& marker_name) const;
+ bool getMarkerData(const std::string& marker_name, std::string &data) const;
void idle();
void idleShutdown();
@@ -347,18 +368,9 @@ private:
extern LLSD gDebugInfo;
extern bool gShowObjectUpdates;
-typedef enum
-{
- LAST_EXEC_NORMAL = 0,
- LAST_EXEC_FROZE,
- LAST_EXEC_LLERROR_CRASH,
- LAST_EXEC_OTHER_CRASH,
- LAST_EXEC_LOGOUT_FROZE,
- LAST_EXEC_LOGOUT_CRASH
-} eLastExecEvent;
-
extern eLastExecEvent gLastExecEvent; // llstartup
extern S32 gLastExecDuration; ///< the duration of the previous run in seconds (<0 indicates unknown)
+extern LLUUID gLastAgentSessionId; // will be set if agent logged in
extern const char* gPlatform;
diff --git a/indra/newview/llconversationmodel.cpp b/indra/newview/llconversationmodel.cpp
index 0c939add95..af5a46742c 100644
--- a/indra/newview/llconversationmodel.cpp
+++ b/indra/newview/llconversationmodel.cpp
@@ -357,8 +357,9 @@ void LLConversationItemSession::clearParticipants()
void LLConversationItemSession::clearAndDeparentModels()
{
- for (LLFolderViewModelItem* child : mChildren)
+ for (child_list_t::iterator it = mChildren.begin(); it != mChildren.end();)
{
+ LLFolderViewModelItem* child = *it;
if (child->getNumRefs() == 0)
{
// LLConversationItemParticipant can be created but not assigned to any view,
@@ -370,8 +371,8 @@ void LLConversationItemSession::clearAndDeparentModels()
// Model is still assigned to some view/widget
child->setParent(NULL);
}
+ it = mChildren.erase(it);
}
- mChildren.clear();
}
LLConversationItemParticipant* LLConversationItemSession::findParticipant(const LLUUID& participant_id)
diff --git a/indra/newview/lldrawpool.cpp b/indra/newview/lldrawpool.cpp
index 74d7997a8d..325c3f9b94 100644
--- a/indra/newview/lldrawpool.cpp
+++ b/indra/newview/lldrawpool.cpp
@@ -42,6 +42,7 @@
#include "lldrawpooltree.h"
#include "lldrawpoolterrain.h"
#include "lldrawpoolwater.h"
+#include "lldrawpoolwaterexclusion.h"
#include "llface.h"
#include "llviewerobjectlist.h" // For debug listing.
#include "pipeline.h"
@@ -119,6 +120,9 @@ LLDrawPool *LLDrawPool::createPool(const U32 type, LLViewerTexture *tex0)
case POOL_GLTF_PBR_ALPHA_MASK:
poolp = new LLDrawPoolGLTFPBR(LLDrawPool::POOL_GLTF_PBR_ALPHA_MASK);
break;
+ case POOL_WATEREXCLUSION:
+ poolp = new LLDrawPoolWaterExclusion();
+ break;
default:
LL_ERRS() << "Unknown draw pool type!" << LL_ENDL;
return NULL;
diff --git a/indra/newview/lldrawpool.h b/indra/newview/lldrawpool.h
index bc412214c7..1c8864a9df 100644
--- a/indra/newview/lldrawpool.h
+++ b/indra/newview/lldrawpool.h
@@ -55,6 +55,7 @@ public:
// based on fill rate and likelihood to occlude future passes (faster, large occluders first).
//
POOL_SKY = 1,
+ POOL_WATEREXCLUSION,
POOL_WL_SKY,
POOL_SIMPLE,
POOL_FULLBRIGHT,
@@ -140,7 +141,7 @@ public:
PASS_GRASS,
PASS_FULLBRIGHT,
PASS_FULLBRIGHT_RIGGED,
- PASS_INVISIBLE,
+ PASS_INVISIBLE, // Formerly, invisiprims. Now, water exclusion surfaces.
PASS_INVISIBLE_RIGGED,
PASS_INVISI_SHINY,
PASS_INVISI_SHINY_RIGGED,
diff --git a/indra/newview/lldrawpoolwater.cpp b/indra/newview/lldrawpoolwater.cpp
index 53d6e528b6..32de0e5ee7 100644
--- a/indra/newview/lldrawpoolwater.cpp
+++ b/indra/newview/lldrawpoolwater.cpp
@@ -176,173 +176,156 @@ void LLDrawPoolWater::renderPostDeferred(S32 pass)
light_diffuse *= (1.5f + (6.f * ground_proj_sq));
}
- // set up normal maps filtering
- for (auto norm_map : mWaterNormp)
- {
- if (norm_map) norm_map->setFilteringOption(has_normal_mips ? LLTexUnit::TFO_ANISOTROPIC : LLTexUnit::TFO_POINT);
- }
+ LLTexUnit::eTextureFilterOptions filter_mode = has_normal_mips ? LLTexUnit::TFO_ANISOTROPIC : LLTexUnit::TFO_POINT;
LLColor4 specular(sun_up ? psky->getSunlightColor() : psky->getMoonlightColor());
F32 phase_time = (F32) LLFrameTimer::getElapsedSeconds() * 0.5f;
LLGLSLShader *shader = nullptr;
- // two passes, first with standard water shader bound, second with edge water shader bound
- for (int edge = 0; edge < 2; edge++)
+ // One pass, one of two shaders. Void water and region water share state.
+ // There isn't a good reason anymore to really have void water run in a separate pass.
+ // It also just introduced a bunch of weird state consistency stuff that we really don't need.
+ // Not to mention, re-binding the the same shader and state for that shader is kind of wasteful.
+ // - Geenz 2025-02-11
+ // select shader
+ if (underwater)
{
- // select shader
- if (underwater)
- {
- shader = &gUnderWaterProgram;
- }
- else
- {
- if (edge)
- {
- shader = &gWaterEdgeProgram;
- }
- else
- {
- shader = &gWaterProgram;
- }
- }
+ shader = &gUnderWaterProgram;
+ }
+ else
+ {
+ shader = &gWaterProgram;
+ }
- gPipeline.bindDeferredShader(*shader, nullptr, &gPipeline.mWaterDis);
+ gPipeline.bindDeferredShader(*shader, nullptr, &gPipeline.mWaterDis);
- //bind normal map
- S32 bumpTex = shader->enableTexture(LLViewerShaderMgr::BUMP_MAP);
- S32 bumpTex2 = shader->enableTexture(LLViewerShaderMgr::BUMP_MAP2);
+ LLViewerTexture* tex_a = mWaterNormp[0];
+ LLViewerTexture* tex_b = mWaterNormp[1];
- LLViewerTexture* tex_a = mWaterNormp[0];
- LLViewerTexture* tex_b = mWaterNormp[1];
+ F32 blend_factor = (F32)pwater->getBlendFactor();
- F32 blend_factor = (F32)pwater->getBlendFactor();
+ if (tex_a && (!tex_b || (tex_a == tex_b)))
+ {
+ shader->bindTexture(LLViewerShaderMgr::BUMP_MAP, tex_a);
+ tex_a->setFilteringOption(filter_mode);
+ blend_factor = 0; // only one tex provided, no blending
+ }
+ else if (tex_b && !tex_a)
+ {
+ shader->bindTexture(LLViewerShaderMgr::BUMP_MAP, tex_b);
+ tex_a->setFilteringOption(filter_mode);
+ blend_factor = 0; // only one tex provided, no blending
+ }
+ else if (tex_b != tex_a)
+ {
+ shader->bindTexture(LLViewerShaderMgr::BUMP_MAP, tex_a);
+ tex_a->setFilteringOption(filter_mode);
+ shader->bindTexture(LLViewerShaderMgr::BUMP_MAP2, tex_b);
+ tex_b->setFilteringOption(filter_mode);
+ }
- gGL.getTexUnit(bumpTex)->unbind(LLTexUnit::TT_TEXTURE);
- gGL.getTexUnit(bumpTex2)->unbind(LLTexUnit::TT_TEXTURE);
+ shader->bindTexture(LLShaderMgr::WATER_EXCLUSIONTEX, &gPipeline.mWaterExclusionMask);
- if (tex_a && (!tex_b || (tex_a == tex_b)))
- {
- gGL.getTexUnit(bumpTex)->bind(tex_a);
- blend_factor = 0; // only one tex provided, no blending
- }
- else if (tex_b && !tex_a)
- {
- gGL.getTexUnit(bumpTex)->bind(tex_b);
- blend_factor = 0; // only one tex provided, no blending
- }
- else if (tex_b != tex_a)
- {
- gGL.getTexUnit(bumpTex)->bind(tex_a);
- gGL.getTexUnit(bumpTex2)->bind(tex_b);
- }
+ shader->uniform1f(LLShaderMgr::BLEND_FACTOR, blend_factor);
- // bind reflection texture from RenderTarget
- S32 screentex = shader->enableTexture(LLShaderMgr::WATER_SCREENTEX);
+ F32 fog_density = pwater->getModifiedWaterFogDensity(underwater);
- F32 screenRes[] = { 1.f / gGLViewport[2], 1.f / gGLViewport[3] };
+ shader->bindTexture(LLShaderMgr::WATER_SCREENTEX, &gPipeline.mWaterDis);
- shader->uniform2fv(LLShaderMgr::DEFERRED_SCREEN_RES, 1, screenRes);
- shader->uniform1f(LLShaderMgr::BLEND_FACTOR, blend_factor);
+ if (mShaderLevel == 1)
+ {
+ fog_color.mV[VALPHA] = (F32)(log(fog_density) / log(2));
+ }
- F32 fog_density = pwater->getModifiedWaterFogDensity(underwater);
+ F32 water_height = environment.getWaterHeight();
+ F32 camera_height = LLViewerCamera::getInstance()->getOrigin().mV[2];
+ shader->uniform1f(LLShaderMgr::WATER_WATERHEIGHT, camera_height - water_height);
+ shader->uniform1f(LLShaderMgr::WATER_TIME, phase_time);
+ shader->uniform3fv(LLShaderMgr::WATER_EYEVEC, 1, LLViewerCamera::getInstance()->getOrigin().mV);
- if (screentex > -1)
- {
- shader->uniform1f(LLShaderMgr::WATER_FOGDENSITY, fog_density);
- gGL.getTexUnit(screentex)->bind(&gPipeline.mWaterDis);
- }
+ shader->uniform3fv(LLShaderMgr::WATER_SPECULAR, 1, light_diffuse.mV);
- if (mShaderLevel == 1)
- {
- fog_color.mV[VALPHA] = (F32)(log(fog_density) / log(2));
- }
+ shader->uniform2fv(LLShaderMgr::WATER_WAVE_DIR1, 1, pwater->getWave1Dir().mV);
+ shader->uniform2fv(LLShaderMgr::WATER_WAVE_DIR2, 1, pwater->getWave2Dir().mV);
- F32 water_height = environment.getWaterHeight();
- F32 camera_height = LLViewerCamera::getInstance()->getOrigin().mV[2];
- shader->uniform1f(LLShaderMgr::WATER_WATERHEIGHT, camera_height - water_height);
- shader->uniform1f(LLShaderMgr::WATER_TIME, phase_time);
- shader->uniform3fv(LLShaderMgr::WATER_EYEVEC, 1, LLViewerCamera::getInstance()->getOrigin().mV);
+ shader->uniform3fv(LLShaderMgr::WATER_LIGHT_DIR, 1, light_dir.mV);
- shader->uniform4fv(LLShaderMgr::SPECULAR_COLOR, 1, specular.mV);
- shader->uniform4fv(LLShaderMgr::WATER_FOGCOLOR, 1, fog_color.mV);
- shader->uniform3fv(LLShaderMgr::WATER_FOGCOLOR_LINEAR, 1, fog_color_linear.mV);
+ shader->uniform3fv(LLShaderMgr::WATER_NORM_SCALE, 1, pwater->getNormalScale().mV);
+ shader->uniform1f(LLShaderMgr::WATER_FRESNEL_SCALE, pwater->getFresnelScale());
+ shader->uniform1f(LLShaderMgr::WATER_FRESNEL_OFFSET, pwater->getFresnelOffset());
+ shader->uniform1f(LLShaderMgr::WATER_BLUR_MULTIPLIER, fmaxf(0, pwater->getBlurMultiplier()) * 2);
- shader->uniform3fv(LLShaderMgr::WATER_SPECULAR, 1, light_diffuse.mV);
- shader->uniform1f(LLShaderMgr::WATER_SPECULAR_EXP, light_exp);
+ static LLStaticHashedString s_exposure("exposure");
+ static LLStaticHashedString tonemap_mix("tonemap_mix");
+ static LLStaticHashedString tonemap_type("tonemap_type");
- shader->uniform2fv(LLShaderMgr::WATER_WAVE_DIR1, 1, pwater->getWave1Dir().mV);
- shader->uniform2fv(LLShaderMgr::WATER_WAVE_DIR2, 1, pwater->getWave2Dir().mV);
+ static LLCachedControl<F32> exposure(gSavedSettings, "RenderExposure", 1.f);
- shader->uniform3fv(LLShaderMgr::WATER_LIGHT_DIR, 1, light_dir.mV);
+ F32 e = llclamp(exposure(), 0.5f, 4.f);
- shader->uniform3fv(LLShaderMgr::WATER_NORM_SCALE, 1, pwater->getNormalScale().mV);
- shader->uniform1f(LLShaderMgr::WATER_FRESNEL_SCALE, pwater->getFresnelScale());
- shader->uniform1f(LLShaderMgr::WATER_FRESNEL_OFFSET, pwater->getFresnelOffset());
- shader->uniform1f(LLShaderMgr::WATER_BLUR_MULTIPLIER, pwater->getBlurMultiplier());
+ static LLCachedControl<bool> should_auto_adjust(gSavedSettings, "RenderSkyAutoAdjustLegacy", false);
- F32 sunAngle = llmax(0.f, light_dir.mV[1]);
- F32 scaledAngle = 1.f - sunAngle;
+ shader->uniform1f(s_exposure, e);
+ static LLCachedControl<U32> tonemap_type_setting(gSavedSettings, "RenderTonemapType", 0U);
+ shader->uniform1i(tonemap_type, tonemap_type_setting);
+ shader->uniform1f(tonemap_mix, psky->getTonemapMix(should_auto_adjust()));
- shader->uniform1i(LLShaderMgr::SUN_UP_FACTOR, sun_up ? 1 : 0);
- shader->uniform1f(LLShaderMgr::WATER_SUN_ANGLE, sunAngle);
- shader->uniform1f(LLShaderMgr::WATER_SCALED_ANGLE, scaledAngle);
- shader->uniform1f(LLShaderMgr::WATER_SUN_ANGLE2, 0.1f + 0.2f * sunAngle);
- shader->uniform1i(LLShaderMgr::WATER_EDGE_FACTOR, edge ? 1 : 0);
+ F32 sunAngle = llmax(0.f, light_dir.mV[1]);
+ F32 scaledAngle = 1.f - sunAngle;
- // SL-15861 This was changed from getRotatedLightNorm() as it was causing
- // lightnorm in shaders\class1\windlight\atmosphericsFuncs.glsl in have inconsistent additive lighting for 180 degrees of the FOV.
- LLVector4 rotated_light_direction = LLEnvironment::instance().getClampedLightNorm();
- shader->uniform3fv(LLViewerShaderMgr::LIGHTNORM, 1, rotated_light_direction.mV);
+ shader->uniform1i(LLShaderMgr::SUN_UP_FACTOR, sun_up ? 1 : 0);
- shader->uniform3fv(LLShaderMgr::WL_CAMPOSLOCAL, 1, LLViewerCamera::getInstance()->getOrigin().mV);
+ // SL-15861 This was changed from getRotatedLightNorm() as it was causing
+ // lightnorm in shaders\class1\windlight\atmosphericsFuncs.glsl in have inconsistent additive lighting for 180 degrees of the FOV.
+ LLVector4 rotated_light_direction = LLEnvironment::instance().getClampedLightNorm();
+ shader->uniform3fv(LLViewerShaderMgr::LIGHTNORM, 1, rotated_light_direction.mV);
- if (LLViewerCamera::getInstance()->cameraUnderWater())
- {
- shader->uniform1f(LLShaderMgr::WATER_REFSCALE, pwater->getScaleBelow());
- }
- else
- {
- shader->uniform1f(LLShaderMgr::WATER_REFSCALE, pwater->getScaleAbove());
- }
+ shader->uniform3fv(LLShaderMgr::WL_CAMPOSLOCAL, 1, LLViewerCamera::getInstance()->getOrigin().mV);
- LLGLDisable cullface(GL_CULL_FACE);
+ if (LLViewerCamera::getInstance()->cameraUnderWater())
+ {
+ shader->uniform1f(LLShaderMgr::WATER_REFSCALE, pwater->getScaleBelow());
+ }
+ else
+ {
+ shader->uniform1f(LLShaderMgr::WATER_REFSCALE, pwater->getScaleAbove());
+ }
- LLVOWater* water = nullptr;
- for (LLFace* const& face : mDrawFace)
- {
- if (!face) continue;
- water = static_cast<LLVOWater*>(face->getViewerObject());
- if (!water) continue;
-
- if ((bool)edge == (bool)water->getIsEdgePatch())
- {
- face->renderIndexed();
-
- // Note non-void water being drawn, updates required
- if (!edge) // SL-16461 remove !LLPipeline::sUseOcclusion check
- {
- sNeedsReflectionUpdate = true;
- sNeedsDistortionUpdate = true;
- }
- }
- }
+ LLGLDisable cullface(GL_CULL_FACE);
- shader->disableTexture(LLShaderMgr::ENVIRONMENT_MAP, LLTexUnit::TT_CUBE_MAP);
- shader->disableTexture(LLShaderMgr::WATER_SCREENTEX);
- shader->disableTexture(LLShaderMgr::BUMP_MAP);
- shader->disableTexture(LLShaderMgr::WATER_REFTEX);
+ // Only push the water planes once.
+ // Previously we did this twice: once for void water and one for region water.
+ // However, the void water and region water shaders are the same exact shader.
+ // They also had the same exact state with the sole exception setting an edge water flag.
+ // That flag was not actually used anywhere in the shaders.
+ // - Geenz 2025-02-11
+ pushWaterPlanes(0);
- // clean up
- gPipeline.unbindDeferredShader(*shader);
+ // clean up
+ gPipeline.unbindDeferredShader(*shader);
- gGL.getTexUnit(bumpTex)->unbind(LLTexUnit::TT_TEXTURE);
- gGL.getTexUnit(bumpTex2)->unbind(LLTexUnit::TT_TEXTURE);
- }
+ gGL.setColorMask(true, false);
+}
- gGL.getTexUnit(0)->activate();
- gGL.getTexUnit(0)->enable(LLTexUnit::TT_TEXTURE);
+void LLDrawPoolWater::pushWaterPlanes(int pass)
+{
+ LLVOWater* water = nullptr;
+ for (LLFace* const& face : mDrawFace)
+ {
+ water = static_cast<LLVOWater*>(face->getViewerObject());
- gGL.setColorMask(true, false);
+ face->renderIndexed();
+
+ // Note non-void water being drawn, updates required
+ // Previously we had some logic to determine if this pass was also our water edge pass.
+ // Now we only have one pass. Check if we're doing a region water plane or void water plane.
+ // - Geenz 2025-02-11
+ if (!water->getIsEdgePatch())
+ {
+ sNeedsReflectionUpdate = true;
+ sNeedsDistortionUpdate = true;
+ }
+ }
}
LLViewerTexture *LLDrawPoolWater::getDebugTexture()
diff --git a/indra/newview/lldrawpoolwater.h b/indra/newview/lldrawpoolwater.h
index f64477a059..7fc9b68bcf 100644
--- a/indra/newview/lldrawpoolwater.h
+++ b/indra/newview/lldrawpoolwater.h
@@ -74,6 +74,8 @@ public:
void setOpaqueTexture(const LLUUID& opaqueTextureId);
void setNormalMaps(const LLUUID& normalMapId, const LLUUID& nextNormalMapId);
+ void pushWaterPlanes(int pass);
+
protected:
void renderOpaqueLegacyWater();
};
diff --git a/indra/newview/lldrawpoolwaterexclusion.cpp b/indra/newview/lldrawpoolwaterexclusion.cpp
new file mode 100644
index 0000000000..d796bf39bf
--- /dev/null
+++ b/indra/newview/lldrawpoolwaterexclusion.cpp
@@ -0,0 +1,79 @@
+/**
+ * @file lldrawpool.cpp
+ * @brief LLDrawPoolMaterials class implementation
+ * @author Jonathan "Geenz" Goodman
+ *
+ * $LicenseInfo:firstyear=2002&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2013, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+#include "lldrawpoolwaterexclusion.h"
+#include "llviewershadermgr.h"
+#include "pipeline.h"
+#include "llglcommonfunc.h"
+#include "llvoavatar.h"
+#include "lldrawpoolwater.h"
+
+LLDrawPoolWaterExclusion::LLDrawPoolWaterExclusion() : LLRenderPass(LLDrawPool::POOL_WATEREXCLUSION)
+{
+ LL_INFOS("DPInvisible") << "Creating water exclusion draw pool" << LL_ENDL;
+}
+
+
+void LLDrawPoolWaterExclusion::render(S32 pass)
+{ // render invisiprims
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; // LL_RECORD_BLOCK_TIME(FTM_RENDER_INVISIBLE);
+
+ if (gPipeline.shadersLoaded())
+ {
+ gDrawColorProgram.bind();
+ }
+
+
+ LLGLDepthTest depth(GL_TRUE);
+ gDrawColorProgram.uniform4f(LLShaderMgr::DIFFUSE_COLOR, 1, 1, 1, 1);
+
+ LLDrawPoolWater* pwaterpool = (LLDrawPoolWater*)gPipeline.getPool(LLDrawPool::POOL_WATER);
+ if (pwaterpool)
+ {
+ // Just treat our water planes as double sided for the purposes of generating the exclusion mask.
+ LLGLDisable cullface(GL_CULL_FACE);
+ pwaterpool->pushWaterPlanes(0);
+
+ // Take care of the edge water tiles.
+ pwaterpool->pushWaterPlanes(1);
+ }
+
+ gDrawColorProgram.uniform4f(LLShaderMgr::DIFFUSE_COLOR, 0, 0, 0, 1);
+
+ static LLStaticHashedString waterSign("waterSign");
+ gDrawColorProgram.uniform1f(waterSign, 1.f);
+
+ pushBatches(LLRenderPass::PASS_INVISIBLE, false, false);
+
+
+ if (gPipeline.shadersLoaded())
+ {
+ gDrawColorProgram.unbind();
+ }
+}
diff --git a/indra/newview/lldrawpoolwaterexclusion.h b/indra/newview/lldrawpoolwaterexclusion.h
new file mode 100644
index 0000000000..e95721a443
--- /dev/null
+++ b/indra/newview/lldrawpoolwaterexclusion.h
@@ -0,0 +1,61 @@
+/**
+ * @file lldrawpoolwaterexclusion.h
+ * @brief LLDrawPoolWaterExclusion class definition
+ * @author Jonathan "Geenz" Goodman
+ *
+ * $LicenseInfo:firstyear=2025&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2013, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLDRAWPOOLWATEREXCLUSION_H
+#define LL_LLDRAWPOOLWATEREXCLUSION_H
+
+#include "v4coloru.h"
+#include "v2math.h"
+#include "v3math.h"
+#include "llvertexbuffer.h"
+#include "lldrawpool.h"
+
+class LLViewerTexture;
+class LLDrawInfo;
+class LLGLSLShader;
+
+class LLDrawPoolWaterExclusion : public LLRenderPass
+{
+public:
+ LLDrawPoolWaterExclusion();
+
+ enum
+ {
+ VERTEX_DATA_MASK = LLVertexBuffer::MAP_VERTEX
+ };
+
+ virtual U32 getVertexDataMask() { return VERTEX_DATA_MASK; }
+
+ virtual void prerender() {}
+
+ virtual void render(S32 pass = 0);
+ virtual void beginRenderPass(S32 pass) {}
+ virtual void endRenderPass(S32 pass) {}
+ virtual S32 getNumPasses() { return 1; }
+};
+
+#endif // LL_LLDRAWPOOLWATEREXCLUSION_H
diff --git a/indra/newview/llface.cpp b/indra/newview/llface.cpp
index e06127c1c8..85f902db8d 100644
--- a/indra/newview/llface.cpp
+++ b/indra/newview/llface.cpp
@@ -896,7 +896,7 @@ LLVector2 LLFace::surfaceToTexture(LLVector2 surface_coord, const LLVector4a& po
//VECTORIZE THIS
// see if we have a non-default mapping
- U8 texgen = getTextureEntry()->getTexGen();
+ U8 texgen = tep->getTexGen();
if (texgen != LLTextureEntry::TEX_GEN_DEFAULT)
{
LLVector4a& center = *(mDrawablep->getVOVolume()->getVolume()->getVolumeFace(mTEOffset).mCenter);
@@ -986,8 +986,17 @@ bool LLFace::calcAlignedPlanarTE(const LLFace* align_to, LLVector2* res_st_offs
return false;
}
const LLTextureEntry *orig_tep = align_to->getTextureEntry();
+ if (!orig_tep)
+ {
+ return false;
+ }
+ const LLTextureEntry* tep = getTextureEntry();
+ if (!tep)
+ {
+ return false;
+ }
if ((orig_tep->getTexGen() != LLTextureEntry::TEX_GEN_PLANAR) ||
- (getTextureEntry()->getTexGen() != LLTextureEntry::TEX_GEN_PLANAR))
+ (tep->getTexGen() != LLTextureEntry::TEX_GEN_PLANAR))
{
return false;
}
@@ -1566,7 +1575,8 @@ bool LLFace::getGeometryVolume(const LLVolume& volume,
bump_t_primary_light_ray.load3((offset_multiple * t_scale * primary_light_ray).mV);
}
- U8 texgen = getTextureEntry()->getTexGen();
+ const LLTextureEntry* tep = getTextureEntry();
+ U8 texgen = tep ? tep->getTexGen() : LLTextureEntry::TEX_GEN_DEFAULT;
if (rebuild_tcoord && texgen != LLTextureEntry::TEX_GEN_DEFAULT)
{ //planar texgen needs binormals
mVObjp->getVolume()->genTangents(face_index);
@@ -2054,7 +2064,12 @@ bool LLFace::getGeometryVolume(const LLVolume& volume,
LLStrider<LLColor4U> emissive;
mVertexBuffer->getEmissiveStrider(emissive, mGeomIndex, mGeomCount);
- U8 glow = (U8) llclamp((S32) (getTextureEntry()->getGlow()*255), 0, 255);
+ const LLTextureEntry* tep = getTextureEntry();
+ U8 glow = 0;
+ if (tep)
+ {
+ glow = (U8)llclamp((S32)(tep->getGlow() * 255), 0, 255);
+ }
LLVector4a src;
diff --git a/indra/newview/llfloaterimsessiontab.cpp b/indra/newview/llfloaterimsessiontab.cpp
index 7b1c0ba5d4..335aba2cc9 100644
--- a/indra/newview/llfloaterimsessiontab.cpp
+++ b/indra/newview/llfloaterimsessiontab.cpp
@@ -634,7 +634,8 @@ void LLFloaterIMSessionTab::appendMessage(const LLChat& chat, const LLSD& args)
chat_args["show_names_for_p2p_conv"] = !mIsP2PChat ||
gSavedSettings.getBOOL("IMShowNamesForP2PConv");
- mChatHistory->appendMessage(chat, chat_args);
+ static const LLStyle::Params input_append_params = LLStyle::Params();
+ mChatHistory->appendMessage(chat, chat_args, input_append_params);
}
void LLFloaterIMSessionTab::updateUsedEmojis(LLWStringView text)
diff --git a/indra/newview/llfloatersnapshot.cpp b/indra/newview/llfloatersnapshot.cpp
index fb4537f22a..68b9e758a1 100644
--- a/indra/newview/llfloatersnapshot.cpp
+++ b/indra/newview/llfloatersnapshot.cpp
@@ -60,6 +60,10 @@ LLPanelSnapshot* LLFloaterSnapshot::Impl::getActivePanel(LLFloaterSnapshotBase*
{
LLSideTrayPanelContainer* panel_container = floater->getChild<LLSideTrayPanelContainer>("panel_container");
LLPanelSnapshot* active_panel = dynamic_cast<LLPanelSnapshot*>(panel_container->getCurrentPanel());
+ if (!active_panel)
+ {
+ LL_WARNS() << "No snapshot active panel, current panel index: " << panel_container->getCurrentPanelIndex() << LL_ENDL;
+ }
if (!ok_if_not_found)
{
llassert_always(active_panel != NULL);
@@ -643,20 +647,18 @@ void LLFloaterSnapshotBase::ImplBase::setWorking(bool working)
working_lbl->setVisible(working);
mFloater->getChild<LLUICtrl>("working_indicator")->setVisible(working);
- if (working)
- {
- const std::string panel_name = getActivePanel(mFloater, false)->getName();
- const std::string prefix = panel_name.substr(getSnapshotPanelPrefix().size());
- std::string progress_text = mFloater->getString(prefix + "_" + "progress_str");
- working_lbl->setValue(progress_text);
- }
-
// All controls should be disabled while posting.
mFloater->setCtrlsEnabled(!working);
- LLPanelSnapshot* active_panel = getActivePanel(mFloater);
- if (active_panel)
+ if (LLPanelSnapshot* active_panel = getActivePanel(mFloater))
{
active_panel->enableControls(!working);
+ if (working)
+ {
+ const std::string panel_name = active_panel->getName();
+ const std::string prefix = panel_name.substr(getSnapshotPanelPrefix().size());
+ std::string progress_text = mFloater->getString(prefix + "_" + "progress_str");
+ working_lbl->setValue(progress_text);
+ }
}
}
diff --git a/indra/newview/llgltfmaterialpreviewmgr.cpp b/indra/newview/llgltfmaterialpreviewmgr.cpp
index cf6b08797d..da1f1a466f 100644
--- a/indra/newview/llgltfmaterialpreviewmgr.cpp
+++ b/indra/newview/llgltfmaterialpreviewmgr.cpp
@@ -472,9 +472,9 @@ bool LLGLTFPreviewTexture::render()
gPipeline.setupHWLights();
glm::mat4 mat = get_current_modelview();
- glm::vec4 transformed_light_dir = glm::make_vec4(light_dir.mV);
+ glm::vec4 transformed_light_dir(light_dir);
transformed_light_dir = mat * transformed_light_dir;
- SetTemporarily<LLVector4> force_sun_direction_high_graphics(&gPipeline.mTransformedSunDir, LLVector4(glm::value_ptr(transformed_light_dir)));
+ SetTemporarily<LLVector4> force_sun_direction_high_graphics(&gPipeline.mTransformedSunDir, LLVector4(transformed_light_dir));
// Override lights to ensure the sun is always shining from a certain direction (low graphics)
// See also force_sun_direction_high_graphics and fixup_shader_constants
{
diff --git a/indra/newview/llheroprobemanager.cpp b/indra/newview/llheroprobemanager.cpp
index 368306ded8..cf606e8863 100644
--- a/indra/newview/llheroprobemanager.cpp
+++ b/indra/newview/llheroprobemanager.cpp
@@ -89,9 +89,11 @@ void LLHeroProbeManager::update()
initReflectionMaps();
+ static LLCachedControl<bool> render_hdr(gSavedSettings, "RenderHDREnabled", true);
+
if (!mRenderTarget.isComplete())
{
- U32 color_fmt = GL_RGBA16F;
+ U32 color_fmt = render_hdr ? GL_RGBA16F : GL_RGBA8;
mRenderTarget.allocate(mProbeResolution, mProbeResolution, color_fmt, true);
}
@@ -103,7 +105,7 @@ void LLHeroProbeManager::update()
mMipChain.resize(count);
for (U32 i = 0; i < count; ++i)
{
- mMipChain[i].allocate(res, res, GL_RGBA16F);
+ mMipChain[i].allocate(res, res, render_hdr ? GL_RGBA16F : GL_RGBA8);
res /= 2;
}
}
@@ -220,7 +222,7 @@ void LLHeroProbeManager::renderProbes()
static LLCachedControl<S32> sUpdateRate(gSavedSettings, "RenderHeroProbeUpdateRate", 0);
F32 near_clip = 0.01f;
- if (mNearestHero != nullptr &&
+ if (mNearestHero != nullptr && !mNearestHero->isDead() &&
!gTeleportDisplay && !gDisconnected && !LLAppViewer::instance()->logoutRequestSent())
{
LL_PROFILE_ZONE_NAMED_CATEGORY_DISPLAY("hpmu - realtime");
@@ -249,12 +251,13 @@ void LLHeroProbeManager::renderProbes()
LL_PROFILE_ZONE_NUM(gFrameCount % rate);
LL_PROFILE_ZONE_NUM(rate);
+ bool dynamic = mNearestHero->getReflectionProbeIsDynamic() && sDetail() > 0;
for (U32 i = 0; i < 6; ++i)
{
if ((gFrameCount % rate) == (i % rate))
{ // update 6/rate faces per frame
LL_PROFILE_ZONE_NUM(i);
- updateProbeFace(mProbes[0], i, mNearestHero->getReflectionProbeIsDynamic() && sDetail > 0, near_clip);
+ updateProbeFace(mProbes[0], i, dynamic, near_clip);
}
}
generateRadiance(mProbes[0]);
@@ -539,8 +542,10 @@ void LLHeroProbeManager::initReflectionMaps()
mTexture = new LLCubeMapArray();
+ static LLCachedControl<bool> render_hdr(gSavedSettings, "RenderHDREnabled", true);
+
// store mReflectionProbeCount+2 cube maps, final two cube maps are used for render target and radiance map generation source)
- mTexture->allocate(mProbeResolution, 3, mReflectionProbeCount + 2);
+ mTexture->allocate(mProbeResolution, 3, mReflectionProbeCount + 2, true, render_hdr);
if (mDefaultProbe.isNull())
{
diff --git a/indra/newview/llhudrender.cpp b/indra/newview/llhudrender.cpp
index 135fba7897..6850e57b94 100644
--- a/indra/newview/llhudrender.cpp
+++ b/indra/newview/llhudrender.cpp
@@ -106,7 +106,7 @@ void hud_render_text(const LLWString &wstr, const LLVector3 &pos_agent,
LLRect world_view_rect = gViewerWindow->getWorldViewRectRaw();
glm::ivec4 viewport(world_view_rect.mLeft, world_view_rect.mBottom, world_view_rect.getWidth(), world_view_rect.getHeight());
- glm::vec3 win_coord = glm::project(glm::make_vec3(render_pos.mV), get_current_modelview(), get_current_projection(), viewport);
+ glm::vec3 win_coord = glm::project(glm::vec3(render_pos), get_current_modelview(), get_current_projection(), viewport);
//fonts all render orthographically, set up projection``
gGL.matrixMode(LLRender::MM_PROJECTION);
diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp
index d511171679..c103d40a38 100644
--- a/indra/newview/llinventorybridge.cpp
+++ b/indra/newview/llinventorybridge.cpp
@@ -4231,14 +4231,9 @@ void LLFolderBridge::staticFolderOptionsMenu()
bool LLFolderBridge::checkFolderForContentsOfType(LLInventoryModel* model, LLInventoryCollectFunctor& is_type)
{
- LLInventoryModel::cat_array_t cat_array;
- LLInventoryModel::item_array_t item_array;
- model->collectDescendentsIf(mUUID,
- cat_array,
- item_array,
+ return model->hasMatchingDescendents(mUUID,
LLInventoryModel::EXCLUDE_TRASH,
is_type);
- return !item_array.empty();
}
void LLFolderBridge::buildContextMenuOptions(U32 flags, menuentry_vec_t& items, menuentry_vec_t& disabled_items)
@@ -4415,21 +4410,26 @@ void LLFolderBridge::buildContextMenuOptions(U32 flags, menuentry_vec_t& items
//Added by aura to force inventory pull on right-click to display folder options correctly. 07-17-06
mCallingCards = mWearables = false;
- LLIsType is_callingcard(LLAssetType::AT_CALLINGCARD);
- if (checkFolderForContentsOfType(model, is_callingcard))
+ if (gInventory.getRootFolderID() != mUUID)
{
- mCallingCards=true;
- }
+ LLIsType is_callingcard(LLAssetType::AT_CALLINGCARD);
+ if (checkFolderForContentsOfType(model, is_callingcard))
+ {
+ mCallingCards = true;
+ }
- LLFindWearables is_wearable;
- LLIsType is_object( LLAssetType::AT_OBJECT );
- LLIsType is_gesture( LLAssetType::AT_GESTURE );
+ const std::vector<LLAssetType::EType> types = { LLAssetType::AT_CLOTHING, LLAssetType::AT_BODYPART, LLAssetType::AT_OBJECT, LLAssetType::AT_GESTURE };
+ LLIsOneOfTypes is_wearable(types);
- if (checkFolderForContentsOfType(model, is_wearable) ||
- checkFolderForContentsOfType(model, is_object) ||
- checkFolderForContentsOfType(model, is_gesture) )
+ if (checkFolderForContentsOfType(model, is_wearable))
+ {
+ mWearables = true;
+ }
+ }
+ else
{
- mWearables=true;
+ // Assume that there are wearables in the root folder
+ mWearables = true;
}
items.push_back(std::string("Set favorite folder"));
@@ -4444,13 +4444,10 @@ void LLFolderBridge::buildContextMenuOptions(U32 flags, menuentry_vec_t& items
LLFolderType::EType type = category->getPreferredType();
const bool is_system_folder = LLFolderType::lookupIsProtectedType(type);
- LLFindWearables is_wearable;
- LLIsType is_object(LLAssetType::AT_OBJECT);
- LLIsType is_gesture(LLAssetType::AT_GESTURE);
+ const std::vector<LLAssetType::EType> types = { LLAssetType::AT_CLOTHING, LLAssetType::AT_BODYPART, LLAssetType::AT_OBJECT, LLAssetType::AT_GESTURE };
+ LLIsOneOfTypes is_wearable(types);
- if (checkFolderForContentsOfType(model, is_wearable) ||
- checkFolderForContentsOfType(model, is_object) ||
- checkFolderForContentsOfType(model, is_gesture))
+ if (checkFolderForContentsOfType(model, is_wearable))
{
mWearables = true;
}
@@ -4573,14 +4570,11 @@ void LLFolderBridge::buildContextMenuFolderOptions(U32 flags, menuentry_vec_t&
// wearables related functionality for folders.
//is_wearable
- LLFindWearables is_wearable;
- LLIsType is_object( LLAssetType::AT_OBJECT );
- LLIsType is_gesture( LLAssetType::AT_GESTURE );
+ const std::vector<LLAssetType::EType> types = { LLAssetType::AT_CLOTHING, LLAssetType::AT_BODYPART, LLAssetType::AT_OBJECT, LLAssetType::AT_GESTURE };
+ LLIsOneOfTypes is_wearable(types);
if (mWearables ||
- checkFolderForContentsOfType(model, is_wearable) ||
- checkFolderForContentsOfType(model, is_object) ||
- checkFolderForContentsOfType(model, is_gesture) )
+ checkFolderForContentsOfType(model, is_wearable))
{
// Only enable add/replace outfit for non-system folders.
if (!is_system_folder)
diff --git a/indra/newview/llinventoryfunctions.cpp b/indra/newview/llinventoryfunctions.cpp
index dadd0590a9..1ccefa3212 100644
--- a/indra/newview/llinventoryfunctions.cpp
+++ b/indra/newview/llinventoryfunctions.cpp
@@ -2634,6 +2634,22 @@ bool LLIsType::operator()(LLInventoryCategory* cat, LLInventoryItem* item)
return false;
}
+bool LLIsOneOfTypes::operator()(LLInventoryCategory* cat, LLInventoryItem* item)
+{
+ for (LLAssetType::EType &type : mTypes)
+ {
+ if (type == LLAssetType::AT_CATEGORY)
+ {
+ if (cat) return true;
+ }
+ if (item)
+ {
+ if (item->getType() == type) return true;
+ }
+ }
+ return false;
+}
+
bool LLIsNotType::operator()(LLInventoryCategory* cat, LLInventoryItem* item)
{
if(mType == LLAssetType::AT_CATEGORY)
diff --git a/indra/newview/llinventoryfunctions.h b/indra/newview/llinventoryfunctions.h
index a25c0d5ad6..13a64f21dc 100644
--- a/indra/newview/llinventoryfunctions.h
+++ b/indra/newview/llinventoryfunctions.h
@@ -246,6 +246,24 @@ protected:
};
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// Class LLIsOneOfTypes
+//
+// Implementation of a LLInventoryCollectFunctor which returns true if
+// the type is one of the types passed in during construction.
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+class LLIsOneOfTypes : public LLInventoryCollectFunctor
+{
+public:
+ LLIsOneOfTypes(const std::vector<LLAssetType::EType> &types) : mTypes(types) {}
+ virtual ~LLIsOneOfTypes() {}
+ virtual bool operator()(LLInventoryCategory* cat,
+ LLInventoryItem* item);
+protected:
+ std::vector <LLAssetType::EType> mTypes;
+};
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Class LLIsNotType
//
// Implementation of a LLInventoryCollectFunctor which returns false if the
diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp
index 53ea02983a..b6ff31a7ed 100644
--- a/indra/newview/llinventorymodel.cpp
+++ b/indra/newview/llinventorymodel.cpp
@@ -1305,6 +1305,47 @@ void LLInventoryModel::collectDescendentsIf(const LLUUID& id,
}
}
+bool LLInventoryModel::hasMatchingDescendents(const LLUUID& id,
+ bool include_trash,
+ LLInventoryCollectFunctor& matches)
+{
+ if (!include_trash)
+ {
+ const LLUUID trash_id = findCategoryUUIDForType(LLFolderType::FT_TRASH);
+ if (trash_id.notNull() && (trash_id == id))
+ return false;
+ }
+ cat_array_t* cat_array = get_ptr_in_map(mParentChildCategoryTree, id);
+ if (cat_array)
+ {
+ for (auto& cat : *cat_array)
+ {
+ if (matches(cat, NULL))
+ {
+ return true;
+ }
+ if (hasMatchingDescendents(cat->getUUID(), include_trash, matches))
+ {
+ return true;
+ }
+ }
+ }
+
+ item_array_t* item_array = get_ptr_in_map(mParentChildItemTree, id);
+
+ if (item_array)
+ {
+ for (auto& item : *item_array)
+ {
+ if (matches(NULL, item))
+ {
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
void LLInventoryModel::addChangedMaskForLinks(const LLUUID& object_id, U32 mask)
{
const LLInventoryObject *obj = getObject(object_id);
diff --git a/indra/newview/llinventorymodel.h b/indra/newview/llinventorymodel.h
index 1472b705e4..d28743357e 100644
--- a/indra/newview/llinventorymodel.h
+++ b/indra/newview/llinventorymodel.h
@@ -287,6 +287,9 @@ public:
item_array_t& items,
bool include_trash,
LLInventoryCollectFunctor& add);
+ bool hasMatchingDescendents(const LLUUID& id,
+ bool include_trash,
+ LLInventoryCollectFunctor& add);
// Collect all items in inventory that are linked to item_id.
// Assumes item_id is itself not a linked item.
diff --git a/indra/newview/llinventorypanel.cpp b/indra/newview/llinventorypanel.cpp
index bf12e6a7e0..1795de727d 100644
--- a/indra/newview/llinventorypanel.cpp
+++ b/indra/newview/llinventorypanel.cpp
@@ -580,7 +580,7 @@ void LLInventoryPanel::itemChanged(const LLUUID& item_id, U32 mask, const LLInve
{
if (model_item && view_item && viewmodel_item)
{
- const LLUUID& idp = viewmodel_item->getUUID();
+ const LLUUID idp = viewmodel_item->getUUID();
removeItemID(idp);
view_item->destroyView();
}
@@ -1335,6 +1335,8 @@ void LLInventoryPanel::openStartFolderOrMyInventory()
LLFolderViewFolder *fchild = dynamic_cast<LLFolderViewFolder*>(child);
if (fchild
&& fchild->getViewModelItem()
+ // Is this right? Name might be localized,
+ // use FT_ROOT_INVENTORY or gInventory.getRootFolderID()?
&& fchild->getViewModelItem()->getName() == "My Inventory")
{
fchild->setOpen(true);
diff --git a/indra/newview/lllogininstance.cpp b/indra/newview/lllogininstance.cpp
index ad04c11cc6..cbc3744aa3 100644
--- a/indra/newview/lllogininstance.cpp
+++ b/indra/newview/lllogininstance.cpp
@@ -212,6 +212,7 @@ void LLLoginInstance::constructAuthParams(LLPointer<LLCredential> user_credentia
request_params["read_critical"] = false; // handleTOSResponse
request_params["last_exec_event"] = mLastExecEvent;
request_params["last_exec_duration"] = mLastExecDuration;
+ request_params["last_exec_session_id"] = mLastAgentSessionId.asString();
request_params["mac"] = (char*)hashed_unique_id_string;
request_params["version"] = LLVersionInfo::instance().getVersion();
request_params["channel"] = LLVersionInfo::instance().getChannel();
diff --git a/indra/newview/lllogininstance.h b/indra/newview/lllogininstance.h
index 624408d46d..748909c069 100644
--- a/indra/newview/lllogininstance.h
+++ b/indra/newview/lllogininstance.h
@@ -64,6 +64,7 @@ public:
void setSerialNumber(const std::string& sn) { mSerialNumber = sn; }
void setLastExecEvent(int lee) { mLastExecEvent = lee; }
void setLastExecDuration(S32 duration) { mLastExecDuration = duration; }
+ void setLastAgentSessionId(const LLUUID& id) { mLastAgentSessionId = id; }
void setPlatformInfo(const std::string platform, const std::string platform_version, const std::string platform_name);
void setNotificationsInterface(LLNotificationsInterface* ni) { mNotifications = ni; }
@@ -101,6 +102,7 @@ private:
std::string mSerialNumber;
int mLastExecEvent;
S32 mLastExecDuration;
+ LLUUID mLastAgentSessionId;
std::string mPlatform;
std::string mPlatformVersion;
std::string mPlatformVersionName;
diff --git a/indra/newview/llpanelcontents.cpp b/indra/newview/llpanelcontents.cpp
index dbf56c2b6d..7910bcb41d 100644
--- a/indra/newview/llpanelcontents.cpp
+++ b/indra/newview/llpanelcontents.cpp
@@ -139,32 +139,60 @@ void LLPanelContents::getState(LLViewerObject *objectp )
void LLPanelContents::onFilterEdit()
{
const std::string& filter_substring = mFilterEditor->getText();
- if (filter_substring.empty())
+ if (!mPanelInventoryObject->hasInventory())
{
- if (mPanelInventoryObject->getFilter().getFilterSubString().empty())
- {
- // The current filter and the new filter are empty, nothing to do
- return;
- }
-
- mSavedFolderState.setApply(true);
- mPanelInventoryObject->getRootFolder()->applyFunctorRecursively(mSavedFolderState);
-
- // Add a folder with the current item to the list of previously opened folders
- LLOpenFoldersWithSelection opener;
- mPanelInventoryObject->getRootFolder()->applyFunctorRecursively(opener);
- mPanelInventoryObject->getRootFolder()->scrollToShowSelection();
+ mDirtyFilter = true;
}
- else if (mPanelInventoryObject->getFilter().getFilterSubString().empty())
+ else
{
- // The first letter in search term, save existing folder open state
- if (!mPanelInventoryObject->getFilter().isNotDefault())
+ LLFolderView* root_folder = mPanelInventoryObject->getRootFolder();
+ if (filter_substring.empty())
{
- mSavedFolderState.setApply(false);
- mPanelInventoryObject->getRootFolder()->applyFunctorRecursively(mSavedFolderState);
+ if (mPanelInventoryObject->getFilter().getFilterSubString().empty())
+ {
+ // The current filter and the new filter are empty, nothing to do
+ return;
+ }
+
+ if (mDirtyFilter && !mSavedFolderState.hasOpenFolders())
+ {
+ if (root_folder)
+ {
+ root_folder->setOpenArrangeRecursively(true, LLFolderViewFolder::ERecurseType::RECURSE_DOWN);
+ }
+ }
+ else
+ {
+ mSavedFolderState.setApply(true);
+ if (root_folder)
+ {
+ root_folder->applyFunctorRecursively(mSavedFolderState);
+ }
+ }
+ mDirtyFilter = false;
+
+ // Add a folder with the current item to the list of previously opened folders
+ if (root_folder)
+ {
+ LLOpenFoldersWithSelection opener;
+ root_folder->applyFunctorRecursively(opener);
+ root_folder->scrollToShowSelection();
+ }
+ }
+ else if (mPanelInventoryObject->getFilter().getFilterSubString().empty())
+ {
+ // The first letter in search term, save existing folder open state
+ if (!mPanelInventoryObject->getFilter().isNotDefault())
+ {
+ mSavedFolderState.setApply(false);
+ if (root_folder)
+ {
+ root_folder->applyFunctorRecursively(mSavedFolderState);
+ }
+ mDirtyFilter = false;
+ }
}
}
-
mPanelInventoryObject->getFilter().setFilterSubString(filter_substring);
}
diff --git a/indra/newview/llpanelcontents.h b/indra/newview/llpanelcontents.h
index bb6308e8b8..6e02b17bab 100644
--- a/indra/newview/llpanelcontents.h
+++ b/indra/newview/llpanelcontents.h
@@ -70,6 +70,8 @@ protected:
void getState(LLViewerObject *object);
void onFilterEdit();
+ bool mDirtyFilter { false };
+
public:
class LLFilterEditor* mFilterEditor;
LLSaveFolderState mSavedFolderState;
diff --git a/indra/newview/llpanelface.cpp b/indra/newview/llpanelface.cpp
index b07946dd5d..74fb2f0f93 100644
--- a/indra/newview/llpanelface.cpp
+++ b/indra/newview/llpanelface.cpp
@@ -898,6 +898,10 @@ struct LLPanelFaceGetIsAlignedTEFunctor : public LLSelectedTEFunctor
if (facep->calcAlignedPlanarTE(mCenterFace, &aligned_st_offset, &aligned_st_scale, &aligned_st_rot))
{
const LLTextureEntry* tep = facep->getTextureEntry();
+ if (!tep)
+ {
+ return false;
+ }
LLVector2 st_offset, st_scale;
tep->getOffset(&st_offset.mV[VX], &st_offset.mV[VY]);
tep->getScale(&st_scale.mV[VX], &st_scale.mV[VY]);
diff --git a/indra/newview/llpanelgroupbulk.cpp b/indra/newview/llpanelgroupbulk.cpp
index 433db74cda..8032e207cd 100644
--- a/indra/newview/llpanelgroupbulk.cpp
+++ b/indra/newview/llpanelgroupbulk.cpp
@@ -56,6 +56,7 @@ LLPanelGroupBulkImpl::LLPanelGroupBulkImpl(const LLUUID& group_id) :
mGroupID(group_id),
mBulkAgentList(NULL),
mOKButton(NULL),
+ mAddButton(nullptr),
mRemoveButton(NULL),
mGroupName(NULL),
mLoadingText(),
@@ -79,29 +80,18 @@ LLPanelGroupBulkImpl::~LLPanelGroupBulkImpl()
}
}
-// static
-void LLPanelGroupBulkImpl::callbackClickAdd(void* userdata)
+void LLPanelGroupBulkImpl::callbackClickAdd(LLPanelGroupBulk* panelp)
{
- if (LLPanelGroupBulk* panelp = (LLPanelGroupBulk*)userdata)
- {
- // Right now this is hard coded with some knowledge that it is part
- // of a floater since the avatar picker needs to be added as a dependent
- // floater to the parent floater.
- // Soon the avatar picker will be embedded into this panel
- // instead of being it's own separate floater. But that is next week.
- // This will do for now. -jwolk May 10, 2006
- LLView* button = panelp->findChild<LLButton>("add_button");
- LLFloater* root_floater = gFloaterView->getParentFloater(panelp);
- LLFloaterAvatarPicker* picker = LLFloaterAvatarPicker::show(
- [&](const uuid_vec_t& agent_ids, const std::vector<LLAvatarName>&)
- {
- panelp->mImplementation->addUsers(agent_ids);
- }, true, false, false, root_floater->getName(), button);
- if (picker)
+ LLFloater* root_floater = gFloaterView->getParentFloater(panelp);
+ LLFloaterAvatarPicker* picker = LLFloaterAvatarPicker::show(
+ [this](const uuid_vec_t& agent_ids, const std::vector<LLAvatarName>&)
{
- root_floater->addDependentFloater(picker);
- LLGroupMgr::getInstance()->sendCapGroupMembersRequest(panelp->mImplementation->mGroupID);
- }
+ addUsers(agent_ids);
+ }, true, false, false, root_floater->getName(), mAddButton);
+ if (picker)
+ {
+ root_floater->addDependentFloater(picker);
+ LLGroupMgr::getInstance()->sendCapGroupMembersRequest(mGroupID);
}
}
diff --git a/indra/newview/llpanelgroupbulkban.cpp b/indra/newview/llpanelgroupbulkban.cpp
index 3c764887a6..1d3edad0f3 100644
--- a/indra/newview/llpanelgroupbulkban.cpp
+++ b/indra/newview/llpanelgroupbulkban.cpp
@@ -68,35 +68,26 @@ bool LLPanelGroupBulkBan::postBuild()
mImplementation->mBulkAgentList->setCommitCallback(LLPanelGroupBulkImpl::callbackSelect, mImplementation);
}
- LLButton* button = getChild<LLButton>("add_button", recurse);
- if ( button )
+ mImplementation->mAddButton = getChild<LLButton>("add_button", recurse);
+ // default to opening avatarpicker automatically
+ mImplementation->mAddButton->setClickedCallback(
+ [this](LLUICtrl* ctrl, const LLSD& param)
{
- // default to opening avatarpicker automatically
- // (*impl::callbackClickAdd)((void*)this);
- button->setClickedCallback(LLPanelGroupBulkImpl::callbackClickAdd, this);
- }
+ mImplementation->callbackClickAdd(this);
+ });
mImplementation->mRemoveButton =
getChild<LLButton>("remove_button", recurse);
- if ( mImplementation->mRemoveButton )
- {
- mImplementation->mRemoveButton->setClickedCallback(LLPanelGroupBulkImpl::callbackClickRemove, mImplementation);
- mImplementation->mRemoveButton->setEnabled(false);
- }
+ mImplementation->mRemoveButton->setClickedCallback(LLPanelGroupBulkImpl::callbackClickRemove, mImplementation);
+ mImplementation->mRemoveButton->setEnabled(false);
mImplementation->mOKButton =
getChild<LLButton>("ban_button", recurse);
- if ( mImplementation->mOKButton )
- {
- mImplementation->mOKButton->setClickedCallback(LLPanelGroupBulkBan::callbackClickSubmit, this);
- mImplementation->mOKButton->setEnabled(false);
- }
+ mImplementation->mOKButton->setClickedCallback(LLPanelGroupBulkBan::callbackClickSubmit, this);
+ mImplementation->mOKButton->setEnabled(false);
- button = getChild<LLButton>("cancel_button", recurse);
- if ( button )
- {
- button->setClickedCallback(LLPanelGroupBulkImpl::callbackClickCancel, mImplementation);
- }
+ LLButton* button = getChild<LLButton>("cancel_button", recurse);
+ button->setClickedCallback(LLPanelGroupBulkImpl::callbackClickCancel, mImplementation);
mImplementation->mTooManySelected = getString("ban_selection_too_large");
mImplementation->mBanNotPermitted = getString("ban_not_permitted");
diff --git a/indra/newview/llpanelgroupbulkimpl.h b/indra/newview/llpanelgroupbulkimpl.h
index 5a479f8117..5515bd6d9a 100644
--- a/indra/newview/llpanelgroupbulkimpl.h
+++ b/indra/newview/llpanelgroupbulkimpl.h
@@ -44,7 +44,7 @@ public:
LLPanelGroupBulkImpl(const LLUUID& group_id);
~LLPanelGroupBulkImpl();
- static void callbackClickAdd(void* userdata);
+ void callbackClickAdd(LLPanelGroupBulk* panelp);
static void callbackClickRemove(void* userdata);
static void callbackClickCancel(void* userdata);
@@ -70,6 +70,7 @@ public:
LLNameListCtrl* mBulkAgentList;
LLButton* mOKButton;
+ LLButton* mAddButton;
LLButton* mRemoveButton;
LLTextBox* mGroupName;
diff --git a/indra/newview/llpanelmaininventory.cpp b/indra/newview/llpanelmaininventory.cpp
index 377af4384a..a5b4db0580 100644
--- a/indra/newview/llpanelmaininventory.cpp
+++ b/indra/newview/llpanelmaininventory.cpp
@@ -2425,10 +2425,14 @@ void LLPanelMainInventory::updateCombinationVisibility()
mCombinationGalleryLayoutPanel->setVisible(!is_gallery_empty);
mCombinationListLayoutPanel->setVisible(show_inv_pane);
- mCombinationInventoryPanel->getRootFolder()->setForceArrange(!show_inv_pane);
- if(mCombinationInventoryPanel->hasVisibleItems())
+ LLFolderView* root_folder = mCombinationInventoryPanel->getRootFolder();
+ if (root_folder)
{
- mForceShowInvLayout = false;
+ root_folder->setForceArrange(!show_inv_pane);
+ if (mCombinationInventoryPanel->hasVisibleItems())
+ {
+ mForceShowInvLayout = false;
+ }
}
if(is_gallery_empty)
{
diff --git a/indra/newview/llpanelobjectinventory.h b/indra/newview/llpanelobjectinventory.h
index abb48dbeed..154639e4bb 100644
--- a/indra/newview/llpanelobjectinventory.h
+++ b/indra/newview/llpanelobjectinventory.h
@@ -85,6 +85,8 @@ public:
static void idle(void* user_data);
+ bool hasInventory(){ return mHaveInventory; };
+
protected:
void reset();
/*virtual*/ void inventoryChanged(LLViewerObject* object,
diff --git a/indra/newview/llpanelprimmediacontrols.cpp b/indra/newview/llpanelprimmediacontrols.cpp
index 4db0a5b59d..b8c12ce0b9 100644
--- a/indra/newview/llpanelprimmediacontrols.cpp
+++ b/indra/newview/llpanelprimmediacontrols.cpp
@@ -660,11 +660,11 @@ void LLPanelPrimMediaControls::updateShape()
for(; vert_it != vert_end; ++vert_it)
{
// project silhouette vertices into screen space
- glm::vec3 screen_vert(glm::make_vec3(vert_it->mV));
+ glm::vec3 screen_vert(*vert_it);
screen_vert = mul_mat4_vec3(mat, screen_vert);
// add to screenspace bounding box
- update_min_max(min, max, LLVector3(glm::value_ptr(screen_vert)));
+ update_min_max(min, max, LLVector3(screen_vert));
}
// convert screenspace bbox to pixels (in screen coords)
diff --git a/indra/newview/llprogressview.cpp b/indra/newview/llprogressview.cpp
index 3add43a3c0..2c09943b83 100644
--- a/indra/newview/llprogressview.cpp
+++ b/indra/newview/llprogressview.cpp
@@ -81,10 +81,9 @@ bool LLProgressView::postBuild()
{
mProgressBar = getChild<LLProgressBar>("login_progress_bar");
- mLogosLabel = getChild<LLTextBox>("logos_lbl");
-
mProgressText = getChild<LLTextBox>("progress_text");
mMessageText = getChild<LLTextBox>("message_text");
+ mMessageTextRectInitial = mMessageText->getRect(); // auto resizes, save initial size
// media control that is used to play intro video
mMediaCtrl = getChild<LLMediaCtrl>("login_media_panel");
@@ -96,6 +95,12 @@ bool LLProgressView::postBuild()
mCancelBtn = getChild<LLButton>("cancel_btn");
mCancelBtn->setClickedCallback( LLProgressView::onCancelButtonClicked, NULL );
+ mLayoutPanel4 = getChild<LLView>("panel4");
+ mLayoutPanel4RectInitial = mLayoutPanel4->getRect();
+
+ mLayoutMOTD = getChild<LLView>("panel_motd");
+ mLayoutMOTDRectInitial = mLayoutMOTD->getRect();
+
getChild<LLTextBox>("title_text")->setText(LLStringExplicit(LLAppViewer::instance()->getSecondLifeTitle()));
getChild<LLTextBox>("message_text")->setClickedCallback(onClickMessage, this);
@@ -234,33 +239,6 @@ void LLProgressView::drawStartTexture(F32 alpha)
gGL.popMatrix();
}
-void LLProgressView::drawLogos(F32 alpha)
-{
- if (mLogosList.empty())
- {
- return;
- }
-
- // logos are tied to label,
- // due to potential resizes we have to figure offsets out on draw or resize
- S32 offset_x, offset_y;
- mLogosLabel->localPointToScreen(0, 0, &offset_x, &offset_y);
- std::vector<TextureData>::const_iterator iter = mLogosList.begin();
- std::vector<TextureData>::const_iterator end = mLogosList.end();
- for (; iter != end; iter++)
- {
- gl_draw_scaled_image_with_border(iter->mDrawRect.mLeft + offset_x,
- iter->mDrawRect.mBottom + offset_y,
- iter->mDrawRect.getWidth(),
- iter->mDrawRect.getHeight(),
- iter->mTexturep.get(),
- UI_VERTEX_COLOR % alpha,
- false,
- iter->mClipRect,
- iter->mOffsetRect);
- }
-}
-
void LLProgressView::draw()
{
static LLTimer timer;
@@ -276,7 +254,6 @@ void LLProgressView::draw()
}
LLPanel::draw();
- drawLogos(alpha);
return;
}
@@ -289,7 +266,6 @@ void LLProgressView::draw()
drawStartTexture(alpha);
LLPanel::draw();
- drawLogos(alpha);
// faded out completely - remove panel and reveal world
if (mFadeToWorldTimer.getElapsedTimeF32() > FADE_TO_WORLD_TIME )
@@ -324,7 +300,6 @@ void LLProgressView::draw()
drawStartTexture(1.0f);
// draw children
LLPanel::draw();
- drawLogos(1.0f);
}
void LLProgressView::setText(const std::string& text)
@@ -341,109 +316,18 @@ void LLProgressView::setMessage(const std::string& msg)
{
mMessage = msg;
mMessageText->setValue(mMessage);
-}
-
-void LLProgressView::loadLogo(const std::string &path,
- const U8 image_codec,
- const LLRect &pos_rect,
- const LLRectf &clip_rect,
- const LLRectf &offset_rect)
-{
- // We need these images very early, so we have to force-load them, otherwise they might not load in time.
- if (!gDirUtilp->fileExists(path))
+ S32 height = mMessageText->getTextPixelHeight();
+ S32 delta = height - mMessageTextRectInitial.getHeight();
+ if (delta > 0)
{
- return;
+ mLayoutPanel4->reshape(mLayoutPanel4RectInitial.getWidth(), mLayoutPanel4RectInitial.getHeight() + delta);
+ mLayoutMOTD->reshape(mLayoutMOTDRectInitial.getWidth(), mLayoutMOTDRectInitial.getHeight() + delta);
}
-
- LLPointer<LLImageFormatted> start_image_frmted = LLImageFormatted::createFromType(image_codec);
- if (!start_image_frmted->load(path))
- {
- LL_WARNS("AppInit") << "Image load failed: " << path << LL_ENDL;
- return;
- }
-
- LLPointer<LLImageRaw> raw = new LLImageRaw;
- if (!start_image_frmted->decode(raw, 0.0f))
+ else
{
- LL_WARNS("AppInit") << "Image decode failed " << path << LL_ENDL;
- return;
+ mLayoutPanel4->reshape(mLayoutPanel4RectInitial.getWidth(), mLayoutPanel4RectInitial.getHeight());
+ mLayoutMOTD->reshape(mLayoutMOTDRectInitial.getWidth(), mLayoutMOTDRectInitial.getHeight());
}
- // HACK: getLocalTexture allows only power of two dimentions
- raw->expandToPowerOfTwo();
-
- TextureData data;
- data.mTexturep = LLViewerTextureManager::getLocalTexture(raw.get(), false);
- data.mDrawRect = pos_rect;
- data.mClipRect = clip_rect;
- data.mOffsetRect = offset_rect;
- mLogosList.push_back(data);
-}
-
-void LLProgressView::initLogos()
-{
- mLogosList.clear();
-
-#if LL_FMODSTUDIO || LL_HAVOK
- const U8 image_codec = IMG_CODEC_PNG;
- const LLRectf default_clip(0.f, 1.f, 1.f, 0.f);
- //const S32 default_height = 28;
- const S32 default_pad = 15;
-
- S32 icon_width, icon_height;
-
- // We don't know final screen rect yet, so we can't precalculate position fully
- S32 texture_start_x = (S32)mLogosLabel->getFont()->getWidthF32(mLogosLabel->getWText().c_str()) + default_pad;
- S32 texture_start_y = -7;
-#endif //LL_FMODSTUDIO || LL_HAVOK
-
- // Normally we would just preload these textures from textures.xml,
- // and display them via icon control, but they are only needed on
- // startup and preloaded/UI ones stay forever
- // (and this code was done already so simply reused it)
- std::string temp_str = gDirUtilp->getExpandedFilename(LL_PATH_DEFAULT_SKIN, "textures", "3p_icons");
-
- temp_str += gDirUtilp->getDirDelimiter();
-
-#ifdef LL_FMODSTUDIO
- // original image size is 264x96, it is on longer side but
- // with no internal paddings so it gets additional padding
- icon_width = 77;
- icon_height = 21;
- S32 pad_fmod_y = 4;
- texture_start_x++;
- loadLogo(temp_str + "fmod_logo.png",
- image_codec,
- LLRect(texture_start_x, texture_start_y + pad_fmod_y + icon_height, texture_start_x + icon_width, texture_start_y + pad_fmod_y),
- default_clip,
- default_clip);
-
- texture_start_x += icon_width + default_pad + 1;
-#endif //LL_FMODSTUDIO
-#ifdef LL_HAVOK
- // original image size is 342x113, central element is on a larger side
- // plus internal padding, so it gets slightly more height than desired 32
- icon_width = 88;
- icon_height = 29;
- S32 pad_havok_y = -1;
- loadLogo(temp_str + "havok_logo.png",
- image_codec,
- LLRect(texture_start_x, texture_start_y + pad_havok_y + icon_height, texture_start_x + icon_width, texture_start_y + pad_havok_y),
- default_clip,
- default_clip);
-
- texture_start_x += icon_width + default_pad;
-#endif //LL_HAVOK
-
-/*
- // 108x41
- icon_width = 74;
- icon_height = default_height;
- loadLogo(temp_str + "vivox_logo.png",
- image_codec,
- LLRect(texture_start_x, texture_start_y + icon_height, texture_start_x + icon_width, texture_start_y),
- default_clip,
- default_clip);
-*/
}
void LLProgressView::initStartTexture(S32 location_id, bool is_in_production)
@@ -524,19 +408,11 @@ void LLProgressView::initStartTexture(S32 location_id, bool is_in_production)
void LLProgressView::initTextures(S32 location_id, bool is_in_production)
{
initStartTexture(location_id, is_in_production);
- initLogos();
-
- childSetVisible("panel_icons", !mLogosList.empty());
- childSetVisible("panel_top_spacer", mLogosList.empty());
}
void LLProgressView::releaseTextures()
{
gStartTexture = NULL;
- mLogosList.clear();
-
- childSetVisible("panel_top_spacer", true);
- childSetVisible("panel_icons", false);
}
void LLProgressView::setCancelButtonVisible(bool b, const std::string& label)
diff --git a/indra/newview/llprogressview.h b/indra/newview/llprogressview.h
index 15b04a8eb9..250ee511d7 100644
--- a/indra/newview/llprogressview.h
+++ b/indra/newview/llprogressview.h
@@ -53,7 +53,6 @@ public:
/*virtual*/ void draw();
void drawStartTexture(F32 alpha);
- void drawLogos(F32 alpha);
/*virtual*/ bool handleHover(S32 x, S32 y, MASK mask);
/*virtual*/ bool handleKeyHere(KEY key, MASK mask);
@@ -86,7 +85,6 @@ public:
protected:
LLProgressBar* mProgressBar;
LLMediaCtrl* mMediaCtrl;
- LLTextBox* mLogosLabel = nullptr;
LLTextBox* mProgressText = nullptr;
LLTextBox* mMessageText = nullptr;
F32 mPercentDone;
@@ -95,6 +93,13 @@ protected:
LLFrameTimer mFadeToWorldTimer;
LLFrameTimer mFadeFromLoginTimer;
LLRect mOutlineRect;
+ LLView* mLayoutPanel4 = nullptr;
+ LLView* mLayoutMOTD = nullptr;
+ // Rects for resizing purposes
+ LLRect mMessageTextRectInitial;
+ LLRect mLayoutPanel4RectInitial;
+ LLRect mLayoutMOTDRectInitial;
+
bool mMouseDownInActiveArea;
bool mStartupComplete;
@@ -105,25 +110,8 @@ protected:
bool handleUpdate(const LLSD& event_data);
static void onIdle(void* user_data);
- void loadLogo(const std::string &path, const U8 image_codec, const LLRect &pos_rect, const LLRectf &clip_rect, const LLRectf &offset_rect);
- // logos have unusual location and need to be preloaded to not appear grey, then deleted
- void initLogos();
// Loads a bitmap to display during load
void initStartTexture(S32 location_id, bool is_in_production);
-
-private:
- // We need to draw textures on login, but only once.
- // So this vector gets filled up for textures to render and gets cleaned later
- // Some textures have unusual requirements, so we are rendering directly
- class TextureData
- {
- public:
- LLPointer<LLViewerTexture> mTexturep;
- LLRect mDrawRect;
- LLRectf mClipRect;
- LLRectf mOffsetRect;
- };
- std::vector<TextureData> mLogosList;
};
#endif // LL_LLPROGRESSVIEW_H
diff --git a/indra/newview/llreflectionmap.cpp b/indra/newview/llreflectionmap.cpp
index f77d37f821..f3adb52d5e 100644
--- a/indra/newview/llreflectionmap.cpp
+++ b/indra/newview/llreflectionmap.cpp
@@ -65,8 +65,9 @@ void LLReflectionMap::update(U32 resolution, U32 face, bool force_dynamic, F32 n
}
F32 clip = (near_clip > 0) ? near_clip : getNearClip();
+ bool dynamic = force_dynamic || getIsDynamic();
- gViewerWindow->cubeSnapshot(LLVector3(mOrigin), mCubeArray, mCubeIndex, face, clip, getIsDynamic() || force_dynamic, useClipPlane, clipPlane);
+ gViewerWindow->cubeSnapshot(LLVector3(mOrigin), mCubeArray, mCubeIndex, face, clip, dynamic, useClipPlane, clipPlane);
}
void LLReflectionMap::autoAdjustOrigin()
@@ -185,7 +186,7 @@ void LLReflectionMap::autoAdjustOrigin()
}
}
-bool LLReflectionMap::intersects(LLReflectionMap* other)
+bool LLReflectionMap::intersects(LLReflectionMap* other) const
{
LLVector4a delta;
delta.setSub(other->mOrigin, mOrigin);
@@ -201,24 +202,24 @@ bool LLReflectionMap::intersects(LLReflectionMap* other)
extern LLControlGroup gSavedSettings;
-F32 LLReflectionMap::getAmbiance()
+F32 LLReflectionMap::getAmbiance() const
{
F32 ret = 0.f;
- if (mViewerObject && mViewerObject->getVolume())
+ if (mViewerObject && mViewerObject->getVolumeConst())
{
- ret = ((LLVOVolume*)mViewerObject)->getReflectionProbeAmbiance();
+ ret = mViewerObject->getReflectionProbeAmbiance();
}
return ret;
}
-F32 LLReflectionMap::getNearClip()
+F32 LLReflectionMap::getNearClip() const
{
const F32 MINIMUM_NEAR_CLIP = 0.1f;
F32 ret = 0.f;
- if (mViewerObject && mViewerObject->getVolume())
+ if (mViewerObject && mViewerObject->getVolumeConst())
{
ret = mViewerObject->getReflectionProbeNearClip();
}
@@ -234,11 +235,13 @@ F32 LLReflectionMap::getNearClip()
return llmax(ret, MINIMUM_NEAR_CLIP);
}
-bool LLReflectionMap::getIsDynamic()
+bool LLReflectionMap::getIsDynamic() const
{
- if (gSavedSettings.getS32("RenderReflectionProbeDetail") > (S32) LLReflectionMapManager::DetailLevel::STATIC_ONLY &&
+ static LLCachedControl<S32> detail(gSavedSettings, "RenderReflectionProbeDetail", 1);
+ if (detail() > (S32)LLReflectionMapManager::DetailLevel::STATIC_ONLY &&
mViewerObject &&
- mViewerObject->getVolume())
+ !mViewerObject->isDead() &&
+ mViewerObject->getVolumeConst())
{
return mViewerObject->getReflectionProbeIsDynamic();
}
@@ -256,7 +259,7 @@ bool LLReflectionMap::getBox(LLMatrix4& box)
glm::mat4 mv(get_current_modelview());
LLVector3 s = mViewerObject->getScale().scaledVec(LLVector3(0.5f, 0.5f, 0.5f));
mRadius = s.magVec();
- glm::mat4 scale = glm::scale(glm::make_vec3(s.mV));
+ glm::mat4 scale = glm::scale(glm::vec3(s));
if (mViewerObject->mDrawable != nullptr)
{
// object to agent space (no scale)
@@ -278,12 +281,12 @@ bool LLReflectionMap::getBox(LLMatrix4& box)
return false;
}
-bool LLReflectionMap::isActive()
+bool LLReflectionMap::isActive() const
{
return mCubeIndex != -1;
}
-bool LLReflectionMap::isRelevant()
+bool LLReflectionMap::isRelevant() const
{
static LLCachedControl<S32> RenderReflectionProbeLevel(gSavedSettings, "RenderReflectionProbeLevel", 3);
diff --git a/indra/newview/llreflectionmap.h b/indra/newview/llreflectionmap.h
index 117ea4cfa6..d20bba7059 100644
--- a/indra/newview/llreflectionmap.h
+++ b/indra/newview/llreflectionmap.h
@@ -58,16 +58,16 @@ public:
void autoAdjustOrigin();
// return true if given Reflection Map's influence volume intersect's with this one's
- bool intersects(LLReflectionMap* other);
+ bool intersects(LLReflectionMap* other) const;
// Get the ambiance value to use for this probe
- F32 getAmbiance();
+ F32 getAmbiance() const;
// Get the near clip plane distance to use for this probe
- F32 getNearClip();
+ F32 getNearClip() const;
// Return true if this probe should include avatars in its reflection map
- bool getIsDynamic();
+ bool getIsDynamic() const;
// get the encoded bounding box of this probe's influence volume
// will only return a box if this probe is associated with a VOVolume
@@ -76,13 +76,13 @@ public:
bool getBox(LLMatrix4& box);
// return true if this probe is active for rendering
- bool isActive();
+ bool isActive() const;
// perform occlusion query/readback
void doOcclusion(const LLVector4a& eye);
// return false if this probe isn't currently relevant (for example, disabled due to graphics preferences)
- bool isRelevant();
+ bool isRelevant() const;
// point at which environment map was last generated from (in agent space)
LLVector4a mOrigin;
diff --git a/indra/newview/llreflectionmapmanager.cpp b/indra/newview/llreflectionmapmanager.cpp
index 69ade8d796..c03f5e7b79 100644
--- a/indra/newview/llreflectionmapmanager.cpp
+++ b/indra/newview/llreflectionmapmanager.cpp
@@ -223,9 +223,11 @@ void LLReflectionMapManager::update()
initReflectionMaps();
+ static LLCachedControl<bool> render_hdr(gSavedSettings, "RenderHDREnabled", true);
+
if (!mRenderTarget.isComplete())
{
- U32 color_fmt = GL_RGB16F;
+ U32 color_fmt = render_hdr ? GL_RGBA16F : GL_RGBA8;
U32 targetRes = mProbeResolution * 4; // super sample
mRenderTarget.allocate(targetRes, targetRes, color_fmt, true);
}
@@ -238,7 +240,7 @@ void LLReflectionMapManager::update()
mMipChain.resize(count);
for (U32 i = 0; i < count; ++i)
{
- mMipChain[i].allocate(res, res, GL_RGB16F);
+ mMipChain[i].allocate(res, res, render_hdr ? GL_RGB16F : GL_RGB8);
res /= 2;
}
}
@@ -306,7 +308,7 @@ void LLReflectionMapManager::update()
LLReflectionMap* probe = mProbes[i];
llassert(probe != nullptr);
- if (probe->mCubeIndex != -1 && mUpdatingProbe != probe)
+ if (probe && probe->mCubeIndex != -1 && mUpdatingProbe != probe)
{ // free this index
mCubeFree.push_back(probe->mCubeIndex);
@@ -1425,11 +1427,13 @@ void LLReflectionMapManager::initReflectionMaps()
{
mTexture = new LLCubeMapArray();
+ static LLCachedControl<bool> render_hdr(gSavedSettings, "RenderHDREnabled", true);
+
// store mReflectionProbeCount+2 cube maps, final two cube maps are used for render target and radiance map generation source)
- mTexture->allocate(mProbeResolution, 3, mReflectionProbeCount + 2);
+ mTexture->allocate(mProbeResolution, 3, mReflectionProbeCount + 2, true, render_hdr);
mIrradianceMaps = new LLCubeMapArray();
- mIrradianceMaps->allocate(LL_IRRADIANCE_MAP_RESOLUTION, 3, mReflectionProbeCount, false);
+ mIrradianceMaps->allocate(LL_IRRADIANCE_MAP_RESOLUTION, 3, mReflectionProbeCount, false, render_hdr);
}
// reset probe state
diff --git a/indra/newview/llsettingsvo.cpp b/indra/newview/llsettingsvo.cpp
index cf96072ae2..62df6cd275 100644
--- a/indra/newview/llsettingsvo.cpp
+++ b/indra/newview/llsettingsvo.cpp
@@ -807,7 +807,7 @@ void LLSettingsVOSky::applySpecial(void *ptarget, bool force)
static LLCachedControl<F32> tonemap_mix_setting(gSavedSettings, "RenderTonemapMix", 1.f);
// sky is a "classic" sky following pre SL 7.0 shading
- bool classic_mode = psky->canAutoAdjust();
+ bool classic_mode = psky->canAutoAdjust() && !should_auto_adjust();
if (!classic_mode)
{
@@ -1093,8 +1093,8 @@ void LLSettingsVOWater::applySpecial(void *ptarget, bool force)
LLVector4 waterPlane(enorm.x, enorm.y, enorm.z, -glm::dot(ep, enorm));
- norm = glm::make_vec3(gPipeline.mHeroProbeManager.mMirrorNormal.mV);
- p = glm::make_vec3(gPipeline.mHeroProbeManager.mMirrorPosition.mV);
+ norm = glm::vec3(gPipeline.mHeroProbeManager.mMirrorNormal);
+ p = glm::vec3(gPipeline.mHeroProbeManager.mMirrorPosition);
enorm = mul_mat4_vec3(invtrans, norm);
enorm = glm::normalize(enorm);
ep = mul_mat4_vec3(mat, p);
diff --git a/indra/newview/llspatialpartition.cpp b/indra/newview/llspatialpartition.cpp
index c56900d986..a90ff73578 100644
--- a/indra/newview/llspatialpartition.cpp
+++ b/indra/newview/llspatialpartition.cpp
@@ -2615,12 +2615,8 @@ void renderTexturePriority(LLDrawable* drawable)
LLGLDisable blend(GL_BLEND);
- //LLViewerTexture* imagep = facep->getTexture();
- //if (imagep)
if (facep)
{
-
- //F32 vsize = imagep->mMaxVirtualSize;
F32 vsize = facep->getPixelArea();
if (vsize > sCurMaxTexPriority)
@@ -2646,18 +2642,6 @@ void renderTexturePriority(LLDrawable* drawable)
size.mul(0.5f);
size.add(LLVector4a(0.01f));
drawBox(center, size);
-
- /*S32 boost = imagep->getBoostLevel();
- if (boost>LLGLTexture::BOOST_NONE)
- {
- F32 t = (F32) boost / (F32) (LLGLTexture::BOOST_MAX_LEVEL-1);
- LLVector4 col = lerp(boost_cold, boost_hot, t);
- LLGLEnable blend_on(GL_BLEND);
- gGL.blendFunc(GL_SRC_ALPHA, GL_ONE);
- gGL.diffuseColor4fv(col.mV);
- drawBox(center, size);
- gGL.blendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- }*/
}
}
diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp
index 9b715be26e..6bf203c140 100644
--- a/indra/newview/llstartup.cpp
+++ b/indra/newview/llstartup.cpp
@@ -1072,6 +1072,7 @@ bool idle_startup()
login->setSerialNumber(LLAppViewer::instance()->getSerialNumber());
login->setLastExecEvent(gLastExecEvent);
login->setLastExecDuration(gLastExecDuration);
+ login->setLastAgentSessionId(gLastAgentSessionId);
// This call to LLLoginInstance::connect() starts the
// authentication process.
@@ -1420,7 +1421,7 @@ bool idle_startup()
}
else if (regionp->capabilitiesError())
{
- LL_WARNS("AppInit") << "Failed to get capabilities. Backing up to login screen!" << LL_ENDL;
+ LL_WARNS("AppInit") << "Failed to get capabilities. Logging out and backing up to login screen!" << LL_ENDL;
if (gRememberPassword)
{
LLNotificationsUtil::add("LoginPacketNeverReceived", LLSD(), LLSD(), login_alert_status);
@@ -1429,6 +1430,15 @@ bool idle_startup()
{
LLNotificationsUtil::add("LoginPacketNeverReceivedNoTP", LLSD(), LLSD(), login_alert_status);
}
+
+ // Session was created, don't just hang up on server, send a logout request
+ LLMessageSystem* msg = gMessageSystem;
+ msg->newMessageFast(_PREHASH_LogoutRequest);
+ msg->nextBlockFast(_PREHASH_AgentData);
+ msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
+ msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
+ gAgent.sendReliableMessage();
+
reset_login();
}
else
@@ -1436,7 +1446,7 @@ bool idle_startup()
U32 num_retries = regionp->getNumSeedCapRetries();
if (num_retries > MAX_SEED_CAP_ATTEMPTS_BEFORE_ABORT)
{
- LL_WARNS("AppInit") << "Failed to get capabilities. Backing up to login screen!" << LL_ENDL;
+ LL_WARNS("AppInit") << "Failed to get capabilities. Logging out and backing up to login screen!" << LL_ENDL;
if (gRememberPassword)
{
LLNotificationsUtil::add("LoginPacketNeverReceived", LLSD(), LLSD(), login_alert_status);
@@ -1445,6 +1455,15 @@ bool idle_startup()
{
LLNotificationsUtil::add("LoginPacketNeverReceivedNoTP", LLSD(), LLSD(), login_alert_status);
}
+
+ // Session was created, don't just hang up on server, send a logout request
+ LLMessageSystem* msg = gMessageSystem;
+ msg->newMessageFast(_PREHASH_LogoutRequest);
+ msg->nextBlockFast(_PREHASH_AgentData);
+ msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
+ msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
+ gAgent.sendReliableMessage();
+
reset_login();
}
else if (num_retries > 0)
@@ -1534,7 +1553,7 @@ bool idle_startup()
// create a container's instance for start a controlling conversation windows
// by the voice's events
LLFloaterIMContainer *im_inst = LLFloaterIMContainer::getInstance();
- if(gAgent.isFirstLogin())
+ if(gAgent.isFirstLogin() && im_inst)
{
im_inst->openFloater(im_inst->getKey());
}
@@ -1747,7 +1766,7 @@ bool idle_startup()
if (!gAgentMovementCompleted && timeout.getElapsedTimeF32() > STATE_AGENT_WAIT_TIMEOUT)
{
- LL_WARNS("AppInit") << "Backing up to login screen!" << LL_ENDL;
+ LL_WARNS("AppInit") << "Timeout on agent movement. Sending logout and backing up to login screen!" << LL_ENDL;
if (gRememberPassword)
{
LLNotificationsUtil::add("LoginPacketNeverReceived", LLSD(), LLSD(), login_alert_status);
@@ -1756,6 +1775,15 @@ bool idle_startup()
{
LLNotificationsUtil::add("LoginPacketNeverReceivedNoTP", LLSD(), LLSD(), login_alert_status);
}
+
+ // Session was created, don't just hang up on server, send a logout request
+ LLMessageSystem* msg = gMessageSystem;
+ msg->newMessageFast(_PREHASH_LogoutRequest);
+ msg->nextBlockFast(_PREHASH_AgentData);
+ msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
+ msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
+ gAgent.sendReliableMessage();
+
reset_login();
}
return false;
@@ -3564,6 +3592,7 @@ bool process_login_success_response()
text = response["session_id"].asString();
if(!text.empty()) gAgentSessionID.set(text);
gDebugInfo["SessionID"] = text;
+ LLAppViewer::instance()->recordSessionToMarker();
// Session id needed for parcel info request in LLUrlEntryParcel
// to resolve parcel name.
diff --git a/indra/newview/llviewercamera.cpp b/indra/newview/llviewercamera.cpp
index f5acc840be..6cf99b68b2 100644
--- a/indra/newview/llviewercamera.cpp
+++ b/indra/newview/llviewercamera.cpp
@@ -420,7 +420,7 @@ bool LLViewerCamera::projectPosAgentToScreen(const LLVector3 &pos_agent, LLCoord
LLRect world_view_rect = gViewerWindow->getWorldViewRectRaw();
glm::ivec4 viewport(world_view_rect.mLeft, world_view_rect.mBottom, world_view_rect.getWidth(), world_view_rect.getHeight());
- glm::vec3 win_coord = glm::project(glm::make_vec3(pos_agent.mV), get_current_modelview(), get_current_projection(), viewport);
+ glm::vec3 win_coord = glm::project(glm::vec3(pos_agent), get_current_modelview(), get_current_projection(), viewport);
{
// convert screen coordinates to virtual UI coordinates
@@ -515,7 +515,7 @@ bool LLViewerCamera::projectPosAgentToScreenEdge(const LLVector3 &pos_agent,
LLRect world_view_rect = gViewerWindow->getWorldViewRectRaw();
glm::ivec4 viewport(world_view_rect.mLeft, world_view_rect.mBottom, world_view_rect.getWidth(), world_view_rect.getHeight());
- glm::vec3 win_coord = glm::project(glm::make_vec3(pos_agent.mV), get_current_modelview(), get_current_projection(), viewport);
+ glm::vec3 win_coord = glm::project(glm::vec3(pos_agent), get_current_modelview(), get_current_projection(), viewport);
{
win_coord.x /= gViewerWindow->getDisplayScale().mV[VX];
diff --git a/indra/newview/llviewercontrol.cpp b/indra/newview/llviewercontrol.cpp
index 18746e76fc..598ad89907 100644
--- a/indra/newview/llviewercontrol.cpp
+++ b/indra/newview/llviewercontrol.cpp
@@ -261,6 +261,8 @@ static bool handleDisableVintageMode(const LLSD& newvalue)
static bool handleEnableHDR(const LLSD& newvalue)
{
+ gPipeline.mReflectionMapManager.reset();
+ gPipeline.mHeroProbeManager.reset();
return handleReleaseGLBufferChanged(newvalue) && handleSetShaderChanged(newvalue);
}
@@ -448,11 +450,11 @@ static bool handleReflectionProbeDetailChanged(const LLSD& newvalue)
if (gPipeline.isInit())
{
LLPipeline::refreshCachedSettings();
+ gPipeline.mReflectionMapManager.reset();
+ gPipeline.mHeroProbeManager.reset();
gPipeline.releaseGLBuffers();
gPipeline.createGLBuffers();
LLViewerShaderMgr::instance()->setShaders();
- gPipeline.mReflectionMapManager.reset();
- gPipeline.mHeroProbeManager.reset();
}
return true;
}
@@ -762,9 +764,9 @@ LLPointer<LLControlVariable> setting_get_control(LLControlGroup& group, const st
LLPointer<LLControlVariable> cntrl_ptr = group.getControl(setting);
if (cntrl_ptr.isNull())
{
+ LLError::LLUserWarningMsg::showMissingFiles();
LL_ERRS() << "Unable to set up setting listener for " << setting
- << ". Please reinstall viewer from https ://secondlife.com/support/downloads/ and contact https://support.secondlife.com if issue persists after reinstall."
- << LL_ENDL;
+ << "." << LL_ENDL;
}
return cntrl_ptr;
}
diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp
index cbc615b01a..bdae400f1d 100644
--- a/indra/newview/llviewermenu.cpp
+++ b/indra/newview/llviewermenu.cpp
@@ -5211,15 +5211,16 @@ void handle_take(bool take_separate)
// MAINT-290
// Reason: Showing the confirmation dialog resets object selection, thus there is nothing to derez.
// Fix: pass selection to the confirm_take, so that selection doesn't "die" after confirmation dialog is opened
- params.functor.function([take_separate](const LLSD &notification, const LLSD &response)
+ LLObjectSelectionHandle obj_selection = LLSelectMgr::instance().getSelection();
+ params.functor.function([take_separate, obj_selection](const LLSD &notification, const LLSD &response)
{
if (take_separate)
{
- confirm_take_separate(notification, response, LLSelectMgr::instance().getSelection());
+ confirm_take_separate(notification, response, obj_selection);
}
else
{
- confirm_take(notification, response, LLSelectMgr::instance().getSelection());
+ confirm_take(notification, response, obj_selection);
}
});
diff --git a/indra/newview/llviewerobject.h b/indra/newview/llviewerobject.h
index 09f813accc..9c9d2f62cf 100644
--- a/indra/newview/llviewerobject.h
+++ b/indra/newview/llviewerobject.h
@@ -728,6 +728,9 @@ public:
// index into LLViewerObjectList::mActiveObjects or -1 if not in list
S32 mListIndex;
+ // last index data for mIndexAndLocalIDToUUID
+ U32 mRegionIndex;
+
LLPointer<LLViewerTexture> *mTEImages;
LLPointer<LLViewerTexture> *mTENormalMaps;
LLPointer<LLViewerTexture> *mTESpecularMaps;
diff --git a/indra/newview/llviewerobjectlist.cpp b/indra/newview/llviewerobjectlist.cpp
index d667fdbea8..d72d428c08 100644
--- a/indra/newview/llviewerobjectlist.cpp
+++ b/indra/newview/llviewerobjectlist.cpp
@@ -164,21 +164,14 @@ U64 LLViewerObjectList::getIndex(const U32 local_id,
return (((U64)index) << 32) | (U64)local_id;
}
-bool LLViewerObjectList::removeFromLocalIDTable(const LLViewerObject* objectp)
+bool LLViewerObjectList::removeFromLocalIDTable(LLViewerObject* objectp)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK;
- if(objectp && objectp->getRegion())
+ if(objectp && objectp->mRegionIndex != 0)
{
U32 local_id = objectp->mLocalID;
- U32 ip = objectp->getRegion()->getHost().getAddress();
- U32 port = objectp->getRegion()->getHost().getPort();
- U64 ipport = (((U64)ip) << 32) | (U64)port;
- U32 index = mIPAndPortToIndex[ipport];
-
- // LL_INFOS() << "Removing object from table, local ID " << local_id << ", ip " << ip << ":" << port << LL_ENDL;
-
- U64 indexid = (((U64)index) << 32) | (U64)local_id;
+ U64 indexid = (((U64)objectp->mRegionIndex) << 32) | (U64)local_id;
std::map<U64, LLUUID>::iterator iter = mIndexAndLocalIDToUUID.find(indexid);
if (iter == mIndexAndLocalIDToUUID.end())
@@ -190,6 +183,7 @@ bool LLViewerObjectList::removeFromLocalIDTable(const LLViewerObject* objectp)
if (iter->second == objectp->getID())
{ // Full UUIDs match, so remove the entry
mIndexAndLocalIDToUUID.erase(iter);
+ objectp->mRegionIndex = 0;
return true;
}
// UUIDs did not match - this would zap a valid entry, so don't erase it
@@ -203,7 +197,8 @@ bool LLViewerObjectList::removeFromLocalIDTable(const LLViewerObject* objectp)
void LLViewerObjectList::setUUIDAndLocal(const LLUUID &id,
const U32 local_id,
const U32 ip,
- const U32 port)
+ const U32 port,
+ LLViewerObject* objectp)
{
U64 ipport = (((U64)ip) << 32) | (U64)port;
@@ -215,6 +210,7 @@ void LLViewerObjectList::setUUIDAndLocal(const LLUUID &id,
mIPAndPortToIndex[ipport] = index;
}
+ objectp->mRegionIndex = index; // should never be zero, sSimulatorMachineIndex starts from 1
U64 indexid = (((U64)index) << 32) | (U64)local_id;
mIndexAndLocalIDToUUID[indexid] = id;
@@ -335,7 +331,8 @@ LLViewerObject* LLViewerObjectList::processObjectUpdateFromCache(LLVOCacheEntry*
removeFromLocalIDTable(objectp);
setUUIDAndLocal(fullid, entry->getLocalID(),
regionp->getHost().getAddress(),
- regionp->getHost().getPort());
+ regionp->getHost().getPort(),
+ objectp);
if (objectp->mLocalID != entry->getLocalID())
{ // Update local ID in object with the one sent from the region
@@ -582,7 +579,8 @@ void LLViewerObjectList::processObjectUpdate(LLMessageSystem *mesgsys,
setUUIDAndLocal(fullid,
local_id,
gMessageSystem->getSenderIP(),
- gMessageSystem->getSenderPort());
+ gMessageSystem->getSenderPort(),
+ objectp);
if (objectp->mLocalID != local_id)
{ // Update local ID in object with the one sent from the region
@@ -1381,11 +1379,20 @@ void LLViewerObjectList::killObjects(LLViewerRegion *regionp)
void LLViewerObjectList::killAllObjects()
{
// Used only on global destruction.
- LLViewerObject *objectp;
+ // Mass cleanup to not clear lists one item at a time
+ mIndexAndLocalIDToUUID.clear();
+ mActiveObjects.clear();
+ mMapObjects.clear();
+
+ LLViewerObject *objectp;
for (vobj_list_t::iterator iter = mObjects.begin(); iter != mObjects.end(); ++iter)
{
objectp = *iter;
+ objectp->setOnActiveList(false);
+ objectp->setListIndex(-1);
+ objectp->mRegionIndex = 0;
+ objectp->mOnMap = false;
killObject(objectp);
// Object must be dead, or it's the LLVOAvatarSelf which never dies.
llassert((objectp == gAgentAvatarp) || objectp->isDead());
@@ -1398,18 +1405,6 @@ void LLViewerObjectList::killAllObjects()
LL_WARNS() << "LLViewerObjectList::killAllObjects still has entries in mObjects: " << mObjects.size() << LL_ENDL;
mObjects.clear();
}
-
- if (!mActiveObjects.empty())
- {
- LL_WARNS() << "Some objects still on active object list!" << LL_ENDL;
- mActiveObjects.clear();
- }
-
- if (!mMapObjects.empty())
- {
- LL_WARNS() << "Some objects still on map object list!" << LL_ENDL;
- mMapObjects.clear();
- }
}
void LLViewerObjectList::cleanDeadObjects(bool use_timer)
@@ -1471,20 +1466,25 @@ void LLViewerObjectList::removeFromActiveList(LLViewerObject* objectp)
{
S32 idx = objectp->getListIndex();
if (idx != -1)
- { //remove by moving last element to this object's position
- llassert(mActiveObjects[idx] == objectp);
-
+ {
objectp->setListIndex(-1);
- S32 last_index = static_cast<S32>(mActiveObjects.size()) - 1;
-
- if (idx != last_index)
+ S32 size = (S32)mActiveObjects.size();
+ if (size > 0) // mActiveObjects could have been cleaned already
{
- mActiveObjects[idx] = mActiveObjects[last_index];
- mActiveObjects[idx]->setListIndex(idx);
- }
+ // Remove by moving last element to this object's position
- mActiveObjects.pop_back();
+ llassert(idx < size); // idx should be always within mActiveObjects, unless killAllObjects was called
+ llassert(mActiveObjects[idx] == objectp); // object should be there
+
+ S32 last_index = size - 1;
+ if (idx < last_index)
+ {
+ mActiveObjects[idx] = mActiveObjects[last_index];
+ mActiveObjects[idx]->setListIndex(idx);
+ } // else assume it's the last element, no need to swap
+ mActiveObjects.pop_back();
+ }
}
}
@@ -1509,9 +1509,9 @@ void LLViewerObjectList::updateActive(LLViewerObject *objectp)
mActiveObjects.push_back(objectp);
objectp->setListIndex(static_cast<S32>(mActiveObjects.size()) - 1);
objectp->setOnActiveList(true);
- }
- else
- {
+ }
+ else
+ {
llassert(idx < mActiveObjects.size());
llassert(mActiveObjects[idx] == objectp);
@@ -1863,7 +1863,8 @@ LLViewerObject *LLViewerObjectList::createObjectFromCache(const LLPCode pcode, L
setUUIDAndLocal(uuid,
local_id,
regionp->getHost().getAddress(),
- regionp->getHost().getPort());
+ regionp->getHost().getPort(),
+ objectp);
mObjects.push_back(objectp);
updateActive(objectp);
@@ -1901,7 +1902,8 @@ LLViewerObject *LLViewerObjectList::createObject(const LLPCode pcode, LLViewerRe
setUUIDAndLocal(fullid,
local_id,
gMessageSystem->getSenderIP(),
- gMessageSystem->getSenderPort());
+ gMessageSystem->getSenderPort(),
+ objectp);
mObjects.push_back(objectp);
diff --git a/indra/newview/llviewerobjectlist.h b/indra/newview/llviewerobjectlist.h
index dc31995eb1..547ef9fb2d 100644
--- a/indra/newview/llviewerobjectlist.h
+++ b/indra/newview/llviewerobjectlist.h
@@ -179,9 +179,10 @@ public:
void setUUIDAndLocal(const LLUUID &id,
const U32 local_id,
const U32 ip,
- const U32 port); // Requires knowledge of message system info!
+ const U32 port,
+ LLViewerObject* objectp); // Requires knowledge of message system info!
- bool removeFromLocalIDTable(const LLViewerObject* objectp);
+ bool removeFromLocalIDTable(LLViewerObject* objectp);
// Used ONLY by the orphaned object code.
U64 getIndex(const U32 local_id, const U32 ip, const U32 port);
diff --git a/indra/newview/llviewerparcelmgr.cpp b/indra/newview/llviewerparcelmgr.cpp
index 8c24b2438b..8e6657b4b9 100644
--- a/indra/newview/llviewerparcelmgr.cpp
+++ b/indra/newview/llviewerparcelmgr.cpp
@@ -1824,6 +1824,16 @@ void LLViewerParcelMgr::processParcelProperties(LLMessageSystem *msg, void **use
S32 bitmap_size = parcel_mgr.mParcelsPerEdge
* parcel_mgr.mParcelsPerEdge
/ 8;
+ S32 size = msg->getSizeFast(_PREHASH_ParcelData, _PREHASH_Bitmap);
+ if (size != bitmap_size)
+ {
+ // Might be better to ignore bitmap and drop highlights
+ LL_WARNS("ParcelMgr") << "Parcel Bitmap size expected: " << bitmap_size
+ << " actual " << size
+ << ". Bitmap might be corrupted!" << LL_ENDL;
+ bitmap_size = size;
+ }
+
U8* bitmap = new U8[ bitmap_size ];
msg->getBinaryDataFast(_PREHASH_ParcelData, _PREHASH_Bitmap, bitmap, bitmap_size);
diff --git a/indra/newview/llviewershadermgr.cpp b/indra/newview/llviewershadermgr.cpp
index c54e54237e..7ef13c3a35 100644
--- a/indra/newview/llviewershadermgr.cpp
+++ b/indra/newview/llviewershadermgr.cpp
@@ -101,6 +101,7 @@ LLGLSLShader gReflectionProbeDisplayProgram;
LLGLSLShader gCopyProgram;
LLGLSLShader gCopyDepthProgram;
LLGLSLShader gPBRTerrainBakeProgram;
+LLGLSLShader gDrawColorProgram;
//object shaders
LLGLSLShader gObjectPreviewProgram;
@@ -113,7 +114,6 @@ LLGLSLShader gObjectAlphaMaskNoColorProgram;
//environment shaders
LLGLSLShader gWaterProgram;
-LLGLSLShader gWaterEdgeProgram;
LLGLSLShader gUnderWaterProgram;
//interface shaders
@@ -409,7 +409,6 @@ void LLViewerShaderMgr::finalizeShaderList()
//ONLY shaders that need WL Param management should be added here
mShaderList.push_back(&gAvatarProgram);
mShaderList.push_back(&gWaterProgram);
- mShaderList.push_back(&gWaterEdgeProgram);
mShaderList.push_back(&gAvatarEyeballProgram);
mShaderList.push_back(&gImpostorProgram);
mShaderList.push_back(&gObjectBumpProgram);
@@ -623,6 +622,8 @@ void LLViewerShaderMgr::setShaders()
else
{
// "ShaderLoading" and "Shader" need to be logged
+ LL_WARNS("Shader") << "Failed loading basic shaders. Retrying with increased log level..." << LL_ENDL;
+
LLError::ELevel lvl = LLError::getDefaultLevel();
LLError::setDefaultLevel(LLError::LEVEL_DEBUG);
loadBasicShaders();
@@ -843,7 +844,7 @@ std::string LLViewerShaderMgr::loadBasicShaders()
// Note usage of GL_VERTEX_SHADER
if (loadShaderFile(shaders[i].first, shaders[i].second, GL_VERTEX_SHADER, &attribs) == 0)
{
- LL_WARNS("Shader") << "Failed to load vertex shader " << shaders[i].first << LL_ENDL;
+ LL_WARNS("Shader") << "Failed to load basic vertex shader " << i << ": " << shaders[i].first << LL_ENDL;
return shaders[i].first;
}
}
@@ -874,6 +875,7 @@ std::string LLViewerShaderMgr::loadBasicShaders()
index_channels.push_back(-1); shaders.push_back( make_pair( "deferred/shadowUtil.glsl", 1) );
index_channels.push_back(-1); shaders.push_back( make_pair( "deferred/aoUtil.glsl", 1) );
index_channels.push_back(-1); shaders.push_back( make_pair( "deferred/pbrterrainUtilF.glsl", 1) );
+ index_channels.push_back(-1); shaders.push_back( make_pair( "deferred/tonemapUtilF.glsl", 1) );
index_channels.push_back(-1); shaders.push_back( make_pair( "deferred/reflectionProbeF.glsl", has_reflection_probes ? 3 : 2) );
index_channels.push_back(-1); shaders.push_back( make_pair( "deferred/screenSpaceReflUtil.glsl", ssr ? 3 : 1) );
index_channels.push_back(-1); shaders.push_back( make_pair( "lighting/lightNonIndexedF.glsl", mShaderLevel[SHADER_LIGHTING] ) );
@@ -906,7 +908,6 @@ bool LLViewerShaderMgr::loadShadersWater()
if (mShaderLevel[SHADER_WATER] == 0)
{
gWaterProgram.unload();
- gWaterEdgeProgram.unload();
gUnderWaterProgram.unload();
return true;
}
@@ -920,6 +921,7 @@ bool LLViewerShaderMgr::loadShadersWater()
gWaterProgram.mFeatures.hasGamma = true;
gWaterProgram.mFeatures.hasSrgb = true;
gWaterProgram.mFeatures.hasReflectionProbes = true;
+ gWaterProgram.mFeatures.hasTonemap = true;
gWaterProgram.mFeatures.hasShadows = use_sun_shadow;
gWaterProgram.mShaderFiles.clear();
gWaterProgram.mShaderFiles.push_back(make_pair("environment/waterV.glsl", GL_VERTEX_SHADER));
@@ -943,36 +945,6 @@ bool LLViewerShaderMgr::loadShadersWater()
if (success)
{
- // load water shader
- gWaterEdgeProgram.mName = "Water Edge Shader";
- gWaterEdgeProgram.mFeatures.calculatesAtmospherics = true;
- gWaterEdgeProgram.mFeatures.hasAtmospherics = true;
- gWaterEdgeProgram.mFeatures.hasGamma = true;
- gWaterEdgeProgram.mFeatures.hasSrgb = true;
- gWaterEdgeProgram.mFeatures.hasReflectionProbes = true;
- gWaterEdgeProgram.mFeatures.hasShadows = use_sun_shadow;
- gWaterEdgeProgram.mShaderFiles.clear();
- gWaterEdgeProgram.mShaderFiles.push_back(make_pair("environment/waterV.glsl", GL_VERTEX_SHADER));
- gWaterEdgeProgram.mShaderFiles.push_back(make_pair("environment/waterF.glsl", GL_FRAGMENT_SHADER));
- gWaterEdgeProgram.clearPermutations();
- gWaterEdgeProgram.addPermutation("WATER_EDGE", "1");
- if (LLPipeline::sRenderTransparentWater)
- {
- gWaterEdgeProgram.addPermutation("TRANSPARENT_WATER", "1");
- }
-
- if (use_sun_shadow)
- {
- gWaterEdgeProgram.addPermutation("HAS_SUN_SHADOW", "1");
- }
- gWaterEdgeProgram.mShaderGroup = LLGLSLShader::SG_WATER;
- gWaterEdgeProgram.mShaderLevel = mShaderLevel[SHADER_WATER];
- success = gWaterEdgeProgram.createShader();
- llassert(success);
- }
-
- if (success)
- {
//load under water vertex shader
gUnderWaterProgram.mName = "Underwater Shader";
gUnderWaterProgram.mFeatures.calculatesAtmospherics = true;
@@ -2481,6 +2453,7 @@ bool LLViewerShaderMgr::loadShadersDeferred()
gDeferredPostTonemapProgram.mName = "Deferred Tonemap Post Process";
gDeferredPostTonemapProgram.mFeatures.hasSrgb = true;
gDeferredPostTonemapProgram.mFeatures.isDeferred = true;
+ gDeferredPostTonemapProgram.mFeatures.hasTonemap = true;
gDeferredPostTonemapProgram.mShaderFiles.clear();
gDeferredPostTonemapProgram.clearPermutations();
gDeferredPostTonemapProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredNoTCV.glsl", GL_VERTEX_SHADER));
@@ -2495,6 +2468,7 @@ bool LLViewerShaderMgr::loadShadersDeferred()
gNoPostTonemapProgram.mName = "No Post Tonemap Post Process";
gNoPostTonemapProgram.mFeatures.hasSrgb = true;
gNoPostTonemapProgram.mFeatures.isDeferred = true;
+ gNoPostTonemapProgram.mFeatures.hasTonemap = true;
gNoPostTonemapProgram.mShaderFiles.clear();
gNoPostTonemapProgram.clearPermutations();
gNoPostTonemapProgram.addPermutation("NO_POST", "1");
@@ -3353,6 +3327,17 @@ bool LLViewerShaderMgr::loadShadersInterface()
success = gCopyDepthProgram.createShader();
}
+ if (success)
+ {
+ gDrawColorProgram.mName = "Draw Color Shader";
+ gDrawColorProgram.mShaderFiles.clear();
+ gDrawColorProgram.mShaderFiles.push_back(make_pair("objects/simpleNoAtmosV.glsl", GL_VERTEX_SHADER));
+ gDrawColorProgram.mShaderFiles.push_back(make_pair("objects/simpleColorF.glsl", GL_FRAGMENT_SHADER));
+ gDrawColorProgram.clearPermutations();
+ gDrawColorProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];
+ success = gDrawColorProgram.createShader();
+ }
+
if (gSavedSettings.getBOOL("LocalTerrainPaintEnabled"))
{
if (success)
diff --git a/indra/newview/llviewershadermgr.h b/indra/newview/llviewershadermgr.h
index b08796025a..7ad2da9464 100644
--- a/indra/newview/llviewershadermgr.h
+++ b/indra/newview/llviewershadermgr.h
@@ -175,6 +175,7 @@ extern LLGLSLShader gReflectionProbeDisplayProgram;
extern LLGLSLShader gCopyProgram;
extern LLGLSLShader gCopyDepthProgram;
extern LLGLSLShader gPBRTerrainBakeProgram;
+extern LLGLSLShader gDrawColorProgram;
//output tex0[tc0] - tex1[tc1]
extern LLGLSLShader gTwoTextureCompareProgram;
@@ -191,7 +192,6 @@ extern LLGLSLShader gObjectAlphaMaskNoColorProgram;
//environment shaders
extern LLGLSLShader gWaterProgram;
-extern LLGLSLShader gWaterEdgeProgram;
extern LLGLSLShader gUnderWaterProgram;
extern LLGLSLShader gGlowProgram;
extern LLGLSLShader gGlowExtractProgram;
diff --git a/indra/newview/llviewertexture.cpp b/indra/newview/llviewertexture.cpp
index 36b6787ace..609ad38e96 100644
--- a/indra/newview/llviewertexture.cpp
+++ b/indra/newview/llviewertexture.cpp
@@ -87,6 +87,7 @@ S32 LLViewerTexture::sRawCount = 0;
S32 LLViewerTexture::sAuxCount = 0;
LLFrameTimer LLViewerTexture::sEvaluationTimer;
F32 LLViewerTexture::sDesiredDiscardBias = 0.f;
+U32 LLViewerTexture::sBiasTexturesUpdated = 0;
S32 LLViewerTexture::sMaxSculptRez = 128; //max sculpt image size
constexpr S32 MAX_CACHED_RAW_IMAGE_AREA = 64 * 64;
@@ -107,12 +108,6 @@ LLViewerTexture::EDebugTexels LLViewerTexture::sDebugTexelsMode = LLViewerTextur
const F64 log_2 = log(2.0);
-#if ADDRESS_SIZE == 32
-const U32 DESIRED_NORMAL_TEXTURE_SIZE = (U32)LLViewerFetchedTexture::MAX_IMAGE_SIZE_DEFAULT / 2;
-#else
-const U32 DESIRED_NORMAL_TEXTURE_SIZE = (U32)LLViewerFetchedTexture::MAX_IMAGE_SIZE_DEFAULT;
-#endif
-
//----------------------------------------------------------------------------------------------
//namespace: LLViewerTextureAccess
//----------------------------------------------------------------------------------------------
@@ -518,6 +513,7 @@ void LLViewerTexture::updateClass()
bool is_sys_low = isSystemMemoryLow();
bool is_low = is_sys_low || over_pct > 0.f;
+ F32 discard_bias = sDesiredDiscardBias;
static bool was_low = false;
static bool was_sys_low = false;
@@ -556,12 +552,13 @@ void LLViewerTexture::updateClass()
// don't execute above until the slam to 1.5 has a chance to take effect
sEvaluationTimer.reset();
- // lower discard bias over time when free memory is available
- if (sDesiredDiscardBias > 1.f && over_pct < 0.f)
+ // lower discard bias over time when at least 10% of budget is free
+ const F32 FREE_PERCENTAGE_TRESHOLD = -0.1f;
+ if (sDesiredDiscardBias > 1.f && over_pct < FREE_PERCENTAGE_TRESHOLD)
{
static LLCachedControl<F32> high_mem_discard_decrement(gSavedSettings, "RenderHighMemMinDiscardDecrement", .1f);
- F32 decrement = high_mem_discard_decrement - llmin(over_pct, 0.f);
+ F32 decrement = high_mem_discard_decrement - llmin(over_pct - FREE_PERCENTAGE_TRESHOLD, 0.f);
sDesiredDiscardBias -= decrement * gFrameIntervalSeconds;
}
}
@@ -603,6 +600,12 @@ void LLViewerTexture::updateClass()
}
sDesiredDiscardBias = llclamp(sDesiredDiscardBias, 1.f, 4.f);
+ if (discard_bias != sDesiredDiscardBias)
+ {
+ // bias changed, reset texture update counter to
+ // let updates happen at an increased rate.
+ sBiasTexturesUpdated = 0;
+ }
LLViewerTexture::sFreezeImageUpdates = false;
}
@@ -1685,6 +1688,16 @@ void LLViewerFetchedTexture::processTextureStats()
static LLCachedControl<bool> textures_fullres(gSavedSettings,"TextureLoadFullRes", false);
+ U32 max_tex_res = MAX_IMAGE_SIZE_DEFAULT;
+ if (mBoostLevel < LLGLTexture::BOOST_HIGH)
+ {
+ // restrict texture resolution to download based on RenderMaxTextureResolution
+ static LLCachedControl<U32> max_texture_resolution(gSavedSettings, "RenderMaxTextureResolution", 2048);
+ // sanity clamp debug setting to avoid settings hack shenanigans
+ max_tex_res = (U32)llclamp((U32)max_texture_resolution, 512, MAX_IMAGE_SIZE_DEFAULT);
+ mMaxVirtualSize = llmin(mMaxVirtualSize, (F32)(max_tex_res * max_tex_res));
+ }
+
if (textures_fullres)
{
mDesiredDiscardLevel = 0;
@@ -1706,10 +1719,9 @@ void LLViewerFetchedTexture::processTextureStats()
}
else
{
- U32 desired_size = MAX_IMAGE_SIZE_DEFAULT; // MAX_IMAGE_SIZE_DEFAULT = 2048 and max size ever is 4096
if(!mKnownDrawWidth || !mKnownDrawHeight || (S32)mFullWidth <= mKnownDrawWidth || (S32)mFullHeight <= mKnownDrawHeight)
{
- if (mFullWidth > desired_size || mFullHeight > desired_size)
+ if (mFullWidth > max_tex_res || mFullHeight > max_tex_res)
{
mDesiredDiscardLevel = 1;
}
@@ -2913,8 +2925,6 @@ LLViewerLODTexture::LLViewerLODTexture(const std::string& url, FTType f_type, co
void LLViewerLODTexture::init(bool firstinit)
{
mTexelsPerImage = 64*64;
- mDiscardVirtualSize = 0.f;
- mCalculatedDiscardLevel = -1.f;
}
//virtual
@@ -2939,12 +2949,14 @@ void LLViewerLODTexture::processTextureStats()
static LLCachedControl<bool> textures_fullres(gSavedSettings,"TextureLoadFullRes", false);
- { // restrict texture resolution to download based on RenderMaxTextureResolution
+ F32 max_tex_res = MAX_IMAGE_SIZE_DEFAULT;
+ if (mBoostLevel < LLGLTexture::BOOST_HIGH)
+ {
+ // restrict texture resolution to download based on RenderMaxTextureResolution
static LLCachedControl<U32> max_texture_resolution(gSavedSettings, "RenderMaxTextureResolution", 2048);
// sanity clamp debug setting to avoid settings hack shenanigans
- F32 tex_res = (F32)llclamp((S32)max_texture_resolution, 512, 2048);
- tex_res *= tex_res;
- mMaxVirtualSize = llmin(mMaxVirtualSize, tex_res);
+ max_tex_res = (F32)llclamp((S32)max_texture_resolution, 512, MAX_IMAGE_SIZE_DEFAULT);
+ mMaxVirtualSize = llmin(mMaxVirtualSize, max_tex_res * max_tex_res);
}
if (textures_fullres)
@@ -2993,19 +3005,12 @@ void LLViewerLODTexture::processTextureStats()
{
// Calculate the required scale factor of the image using pixels per texel
discard_level = (F32)(log(mTexelsPerImage / mMaxVirtualSize) / log_4);
- mDiscardVirtualSize = mMaxVirtualSize;
- mCalculatedDiscardLevel = discard_level;
}
discard_level = floorf(discard_level);
F32 min_discard = 0.f;
- U32 desired_size = MAX_IMAGE_SIZE_DEFAULT; // MAX_IMAGE_SIZE_DEFAULT = 2048 and max size ever is 4096
- if (mBoostLevel <= LLGLTexture::BOOST_SCULPTED)
- {
- desired_size = DESIRED_NORMAL_TEXTURE_SIZE;
- }
- if (mFullWidth > desired_size || mFullHeight > desired_size)
+ if (mFullWidth > max_tex_res || mFullHeight > max_tex_res)
min_discard = 1.f;
discard_level = llclamp(discard_level, min_discard, (F32)MAX_DISCARD_LEVEL);
@@ -3543,18 +3548,7 @@ void LLViewerMediaTexture::setPlaying(bool playing)
for(std::list< LLFace* >::iterator iter = mMediaFaceList.begin(); iter!= mMediaFaceList.end(); ++iter)
{
LLFace* facep = *iter;
- const LLTextureEntry* te = facep->getTextureEntry();
- if (te->getGLTFMaterial())
- {
- // PBR material, switch emissive and basecolor
- switchTexture(LLRender::EMISSIVE_MAP, *iter);
- switchTexture(LLRender::BASECOLOR_MAP, *iter);
- }
- else
- {
- // blinn-phong material, switch diffuse map only
- switchTexture(LLRender::DIFFUSE_MAP, *iter);
- }
+ switchTexture(LLRender::DIFFUSE_MAP, facep);
}
}
else //stop playing this media
diff --git a/indra/newview/llviewertexture.h b/indra/newview/llviewertexture.h
index 4241ef958f..e1582c74bd 100644
--- a/indra/newview/llviewertexture.h
+++ b/indra/newview/llviewertexture.h
@@ -220,6 +220,7 @@ public:
static S32 sAuxCount;
static LLFrameTimer sEvaluationTimer;
static F32 sDesiredDiscardBias;
+ static U32 sBiasTexturesUpdated;
static S32 sMaxSculptRez ;
static U32 sMinLargeImageSize ;
static U32 sMaxSmallImageSize ;
@@ -540,10 +541,6 @@ public:
private:
void init(bool firstinit) ;
-
-private:
- F32 mDiscardVirtualSize; // Virtual size used to calculate desired discard
- F32 mCalculatedDiscardLevel; // Last calculated discard level
};
//
diff --git a/indra/newview/llviewertexturelist.cpp b/indra/newview/llviewertexturelist.cpp
index c2eb8ddd25..a4a001eceb 100644
--- a/indra/newview/llviewertexturelist.cpp
+++ b/indra/newview/llviewertexturelist.cpp
@@ -276,7 +276,7 @@ void LLViewerTextureList::doPrefetchImages()
S32 pixel_area = imagesd["area"];
S32 texture_type = imagesd["type"];
- if(LLViewerTexture::FETCHED_TEXTURE == texture_type || LLViewerTexture::LOD_TEXTURE == texture_type)
+ if((LLViewerTexture::FETCHED_TEXTURE == texture_type || LLViewerTexture::LOD_TEXTURE == texture_type))
{
LLViewerFetchedTexture* image = LLViewerTextureManager::getFetchedTexture(uuid, FTT_DEFAULT, MIPMAP_TRUE, LLGLTexture::BOOST_NONE, texture_type);
if (image)
@@ -1091,7 +1091,8 @@ F32 LLViewerTextureList::updateImagesCreateTextures(F32 max_time)
imagep->mCreatePending = false;
mCreateTextureList.pop();
- if (imagep->hasGLTexture() && imagep->getDiscardLevel() < imagep->getDesiredDiscardLevel())
+ if (imagep->hasGLTexture() && imagep->getDiscardLevel() < imagep->getDesiredDiscardLevel() &&
+ (imagep->getDesiredDiscardLevel() <= MAX_DISCARD_LEVEL))
{
// NOTE: this may happen if the desired discard reduces while a decode is in progress and does not
// necessarily indicate a problem, but if log occurrences excede that of dsiplay_stats: FPS,
@@ -1208,10 +1209,17 @@ F32 LLViewerTextureList::updateImagesFetchTextures(F32 max_time)
//update MIN_UPDATE_COUNT or 5% of other textures, whichever is greater
update_count = llmax((U32) MIN_UPDATE_COUNT, (U32) mUUIDMap.size()/20);
- if (LLViewerTexture::sDesiredDiscardBias > 1.f)
+ if (LLViewerTexture::sDesiredDiscardBias > 1.f
+ && LLViewerTexture::sBiasTexturesUpdated < (U32)mUUIDMap.size())
{
- // we are over memory target, update more agresively
+ // We are over memory target. Bias affects discard rates, so update
+ // existing textures agresively to free memory faster.
update_count = (S32)(update_count * LLViewerTexture::sDesiredDiscardBias);
+
+ // This isn't particularly precise and can overshoot, but it doesn't need
+ // to be, just making sure it did a full circle and doesn't get stuck updating
+ // at bias = 4 with 4 times the rate permanently.
+ LLViewerTexture::sBiasTexturesUpdated += update_count;
}
update_count = llmin(update_count, (U32) mUUIDMap.size());
diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp
index d399cc6469..f1d406f199 100644
--- a/indra/newview/llviewerwindow.cpp
+++ b/indra/newview/llviewerwindow.cpp
@@ -1746,6 +1746,7 @@ bool LLViewerWindow::handleDeviceChange(LLWindow *window)
bool LLViewerWindow::handleDPIChanged(LLWindow *window, F32 ui_scale_factor, S32 window_width, S32 window_height)
{
+ LLFontGL::sResolutionGeneration++;
if (ui_scale_factor >= MIN_UI_SCALE && ui_scale_factor <= MAX_UI_SCALE)
{
LLViewerWindow::reshape(window_width, window_height);
@@ -1759,6 +1760,12 @@ bool LLViewerWindow::handleDPIChanged(LLWindow *window, F32 ui_scale_factor, S32
}
}
+bool LLViewerWindow::handleDisplayChanged()
+{
+ LLFontGL::sResolutionGeneration++;
+ return false;
+}
+
bool LLViewerWindow::handleWindowDidChangeScreen(LLWindow *window)
{
LLCoordScreen window_rect;
@@ -1927,6 +1934,7 @@ LLViewerWindow::LLViewerWindow(const Params& p)
mDisplayScale.setVec(llmax(1.f / mWindow->getPixelAspectRatio(), 1.f), llmax(mWindow->getPixelAspectRatio(), 1.f));
mDisplayScale *= ui_scale_factor;
LLUI::setScaleFactor(mDisplayScale);
+ LLFontGL::sResolutionGeneration++;
{
LLCoordWindow size;
@@ -2496,6 +2504,7 @@ void LLViewerWindow::reshape(S32 width, S32 height)
bool display_scale_changed = mDisplayScale != LLUI::getScaleFactor();
LLUI::setScaleFactor(mDisplayScale);
+ LLFontGL::sResolutionGeneration++;
// update our window rectangle
mWindowRectScaled.mRight = mWindowRectScaled.mLeft + ll_round((F32)width / mDisplayScale.mV[VX]);
diff --git a/indra/newview/llviewerwindow.h b/indra/newview/llviewerwindow.h
index 1b995ea650..fbc2c58fbf 100644
--- a/indra/newview/llviewerwindow.h
+++ b/indra/newview/llviewerwindow.h
@@ -225,6 +225,7 @@ public:
/*virtual*/ bool handleTimerEvent(LLWindow *window);
/*virtual*/ bool handleDeviceChange(LLWindow *window);
/*virtual*/ bool handleDPIChanged(LLWindow *window, F32 ui_scale_factor, S32 window_width, S32 window_height);
+ /*virtual*/ bool handleDisplayChanged();
/*virtual*/ bool handleWindowDidChangeScreen(LLWindow *window);
/*virtual*/ void handlePingWatchdog(LLWindow *window, const char * msg);
diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp
index 2ef45442ee..f5dfcca873 100644
--- a/indra/newview/llvoavatar.cpp
+++ b/indra/newview/llvoavatar.cpp
@@ -1944,8 +1944,8 @@ bool LLVOAvatar::lineSegmentIntersect(const LLVector4a& start, const LLVector4a&
glm::mat4 inverse = glm::inverse(mat);
glm::mat4 norm_mat = glm::transpose(inverse);
- glm::vec3 p1(glm::make_vec3(start.getF32ptr()));
- glm::vec3 p2(glm::make_vec3(end.getF32ptr()));
+ glm::vec3 p1(start);
+ glm::vec3 p2(end);
p1 = mul_mat4_vec3(inverse, p1);
p2 = mul_mat4_vec3(inverse, p2);
@@ -1953,12 +1953,12 @@ bool LLVOAvatar::lineSegmentIntersect(const LLVector4a& start, const LLVector4a&
LLVector3 position;
LLVector3 norm;
- if (linesegment_sphere(LLVector3(glm::value_ptr(p1)), LLVector3(glm::value_ptr(p2)), LLVector3(0,0,0), 1.f, position, norm))
+ if (linesegment_sphere(LLVector3(p1), LLVector3(p2), LLVector3(0,0,0), 1.f, position, norm))
{
- glm::vec3 res_pos(glm::make_vec3(position.mV));
+ glm::vec3 res_pos(position);
res_pos = mul_mat4_vec3(mat, res_pos);
- glm::vec3 res_norm(glm::make_vec3(norm.mV));
+ glm::vec3 res_norm(norm);
res_norm = glm::normalize(res_norm);
res_norm = glm::mat3(norm_mat) * res_norm;
diff --git a/indra/newview/llvoiceclient.cpp b/indra/newview/llvoiceclient.cpp
index 3d8ffc35e7..e5eb2f8008 100644
--- a/indra/newview/llvoiceclient.cpp
+++ b/indra/newview/llvoiceclient.cpp
@@ -293,6 +293,7 @@ void LLVoiceClient::setNonSpatialVoiceModule(const std::string &voice_server_typ
void LLVoiceClient::setHidden(bool hidden)
{
+ LL_INFOS("Voice") << "( " << (hidden ? "true" : "false") << " )" << LL_ENDL;
#if !__FreeBSD__
LLWebRTCVoiceClient::getInstance()->setHidden(hidden);
#endif
diff --git a/indra/newview/llvoicevivox.cpp b/indra/newview/llvoicevivox.cpp
index d64c25d312..7faef8cc41 100644
--- a/indra/newview/llvoicevivox.cpp
+++ b/indra/newview/llvoicevivox.cpp
@@ -2014,7 +2014,7 @@ bool LLVivoxVoiceClient::waitForChannel()
{
recordingAndPlaybackMode();
}
- else if (mProcessChannels && (mNextAudioSession == NULL) && checkParcelChanged())
+ else if (mProcessChannels && ((mNextAudioSession == NULL) || checkParcelChanged()))
{
// the parcel is changed, or we have no pending audio sessions,
// so try to request the parcel voice info
diff --git a/indra/newview/llvoicewebrtc.cpp b/indra/newview/llvoicewebrtc.cpp
index b2e5de5371..0bb65f7431 100644
--- a/indra/newview/llvoicewebrtc.cpp
+++ b/indra/newview/llvoicewebrtc.cpp
@@ -345,6 +345,8 @@ void LLWebRTCVoiceClient::updateSettings()
static LLCachedControl<std::string> sOutputDevice(gSavedSettings, "VoiceOutputAudioDevice");
setRenderDevice(sOutputDevice);
+ LL_INFOS("Voice") << "Input device: " << std::quoted(sInputDevice()) << ", output device: " << std::quoted(sOutputDevice()) << LL_ENDL;
+
static LLCachedControl<F32> sMicLevel(gSavedSettings, "AudioLevelMic");
setMicGain(sMicLevel);
@@ -896,7 +898,7 @@ void LLWebRTCVoiceClient::OnConnectionShutDown(const std::string &channelID, con
{
if (mSession && mSession->mChannelID == channelID)
{
- LL_DEBUGS("Voice") << "Main WebRTC Connection Shut Down." << LL_ENDL;
+ LL_INFOS("Voice") << "Main WebRTC Connection Shut Down." << LL_ENDL;
}
}
mSession->removeAllParticipants(regionID);
@@ -1504,6 +1506,11 @@ bool LLWebRTCVoiceClient::compareChannels(const LLSD &channelInfo1, const LLSD &
// we're muting the mic, so tell each session such
void LLWebRTCVoiceClient::setMuteMic(bool muted)
{
+ if (mMuteMic != muted)
+ {
+ LL_INFOS("Voice") << "( " << (muted ? "true" : "false") << " )" << LL_ENDL;
+ }
+
mMuteMic = muted;
// when you're hidden, your mic is always muted.
if (!mHidden)
@@ -1552,14 +1559,10 @@ void LLWebRTCVoiceClient::setVoiceEnabled(bool enabled)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_VOICE;
- LL_DEBUGS("Voice")
- << "( " << (enabled ? "enabled" : "disabled") << " )"
- << " was "<< (mVoiceEnabled ? "enabled" : "disabled")
- << " coro "<< (mIsCoroutineActive ? "active" : "inactive")
- << LL_ENDL;
-
if (enabled != mVoiceEnabled)
{
+ LL_INFOS("Voice") << "( " << (enabled ? "enabled" : "disabled") << " )"
+ << ", coro: " << (mIsCoroutineActive ? "active" : "inactive") << LL_ENDL;
// TODO: Refactor this so we don't call into LLVoiceChannel, but simply
// use the status observer
mVoiceEnabled = enabled;
@@ -2483,7 +2486,7 @@ void LLVoiceWebRTCConnection::breakVoiceConnectionCoro(connectionPtr_t connectio
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_VOICE;
- LL_DEBUGS("Voice") << "Disconnecting voice." << LL_ENDL;
+ LL_INFOS("Voice") << "Disconnecting voice." << LL_ENDL;
if (connection->mWebRTCDataInterface)
{
connection->mWebRTCDataInterface->unsetDataObserver(connection.get());
@@ -2591,6 +2594,7 @@ void LLVoiceWebRTCSpatialConnection::requestVoiceConnection()
LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
+ LL_INFOS("Voice") << "Voice connection request: " << (status ? "Success" : status.toString()) << LL_ENDL;
if (status)
{
OnVoiceConnectionRequestSuccess(result);
diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp
index 7740376d5c..3fb7a3c156 100644
--- a/indra/newview/llvovolume.cpp
+++ b/indra/newview/llvovolume.cpp
@@ -645,8 +645,12 @@ void LLVOVolume::animateTextures()
// LLVOVolume::updateTextureVirtualSize when the
// mTextureMatrix is not yet present
gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_TCOORD);
- mDrawable->getSpatialGroup()->dirtyGeom();
- gPipeline.markRebuild(mDrawable->getSpatialGroup());
+ LLSpatialGroup* group = mDrawable->getSpatialGroup();
+ if (group)
+ {
+ group->dirtyGeom();
+ gPipeline.markRebuild(group);
+ }
}
}
@@ -5735,13 +5739,23 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
continue;
}
- LLFetchedGLTFMaterial *gltf_mat = (LLFetchedGLTFMaterial*) facep->getTextureEntry()->getGLTFRenderMaterial();
+ LLFetchedGLTFMaterial* gltf_mat = nullptr;
+ const LLTextureEntry* te = facep->getTextureEntry();
+ if (te)
+ {
+ gltf_mat = (LLFetchedGLTFMaterial*)te->getGLTFRenderMaterial();
+ } // if not te, continue?
bool is_pbr = gltf_mat != nullptr;
if (is_pbr)
{
// tell texture streaming system to ignore blinn-phong textures
- facep->setTexture(LLRender::DIFFUSE_MAP, nullptr);
+ // except the special case of the diffuse map containing a
+ // media texture that will be reused for swapping on to the pbr face
+ if (!facep->hasMedia())
+ {
+ facep->setTexture(LLRender::DIFFUSE_MAP, nullptr);
+ }
facep->setTexture(LLRender::NORMAL_MAP, nullptr);
facep->setTexture(LLRender::SPECULAR_MAP, nullptr);
@@ -5797,10 +5811,9 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
{
cur_total += facep->getGeomCount();
- const LLTextureEntry* te = facep->getTextureEntry();
LLViewerTexture* tex = facep->getTexture();
- if (te->getGlow() > 0.f)
+ if (te && te->getGlow() > 0.f)
{
emissive = true;
}
@@ -5894,6 +5907,7 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
facep->mLastUpdateTime = gFrameTimeSeconds;
}
+ if (te)
{
LLGLTFMaterial* gltf_mat = te->getGLTFRenderMaterial();
@@ -5958,6 +5972,11 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
add_face(sFullbrightFaces, fullbright_count, facep);
}
}
+ else // no texture entry
+ {
+ facep->setState(LLFace::FULLBRIGHT);
+ add_face(sFullbrightFaces, fullbright_count, facep);
+ }
}
}
else
@@ -6712,8 +6731,11 @@ U32 LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace
{ //shiny
if (tex->getPrimaryFormat() == GL_ALPHA)
{ //invisiprim+shiny
- registerFace(group, facep, LLRenderPass::PASS_INVISI_SHINY);
- registerFace(group, facep, LLRenderPass::PASS_INVISIBLE);
+ if (!facep->getViewerObject()->isAttachment() && !facep->getViewerObject()->isRiggedMesh())
+ {
+ registerFace(group, facep, LLRenderPass::PASS_INVISI_SHINY);
+ registerFace(group, facep, LLRenderPass::PASS_INVISIBLE);
+ }
}
else if (!hud_group)
{ //deferred rendering
@@ -6749,7 +6771,10 @@ U32 LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace
{ //not alpha and not shiny
if (!is_alpha && tex->getPrimaryFormat() == GL_ALPHA)
{ //invisiprim
- registerFace(group, facep, LLRenderPass::PASS_INVISIBLE);
+ if (!facep->getViewerObject()->isAttachment() && !facep->getViewerObject()->isRiggedMesh())
+ {
+ registerFace(group, facep, LLRenderPass::PASS_INVISIBLE);
+ }
}
else if (fullbright || bake_sunlight)
{ //fullbright
diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index 3240e2a663..e441e189ad 100644
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -431,6 +431,7 @@ void LLPipeline::init()
stop_glerror();
//create render pass pools
+ getPool(LLDrawPool::POOL_WATEREXCLUSION);
getPool(LLDrawPool::POOL_ALPHA_PRE_WATER);
getPool(LLDrawPool::POOL_ALPHA_POST_WATER);
getPool(LLDrawPool::POOL_SIMPLE);
@@ -673,6 +674,8 @@ void LLPipeline::cleanup()
// don't delete wl sky pool it was handled above in the for loop
//delete mWLSkyPool;
mWLSkyPool = NULL;
+ delete mWaterExclusionPool;
+ mWaterExclusionPool = nullptr;
releaseGLBuffers();
@@ -907,6 +910,15 @@ bool LLPipeline::allocateScreenBufferInternal(U32 resX, U32 resY)
mPostMap.allocate(resX, resY, screenFormat);
+ // The water exclusion mask needs its own depth buffer so we can take care of the problem of multiple water planes.
+ // Should we ever make water not just a plane, it also aids with that as well as the water planes will be rendered into the mask.
+ // Why do we do this? Because it saves us some janky logic in the exclusion shader when we generate the mask.
+ // Regardless, this should always only be an R8 texture unless we choose to start having multiple kinds of exclusion that 8 bits can't handle.
+ // - Geenz 2025-02-06
+ bool success = mWaterExclusionMask.allocate(resX, resY, GL_R8, true);
+
+ assert(success);
+
// used to scale down textures
// See LLViwerTextureList::updateImagesCreateTextures and LLImageGL::scaleDown
mDownResMap.allocate(1024, 1024, GL_RGBA);
@@ -1166,6 +1178,8 @@ void LLPipeline::releaseGLBuffers()
mSceneMap.release();
+ mWaterExclusionMask.release();
+
mPostMap.release();
mFXAAMap.release();
@@ -1676,6 +1690,10 @@ LLDrawPool *LLPipeline::findPool(const U32 type, LLViewerTexture *tex0)
poolp = mPBRAlphaMaskPool;
break;
+ case LLDrawPool::POOL_WATEREXCLUSION:
+ poolp = mWaterExclusionPool;
+ break;
+
default:
llassert(0);
LL_ERRS() << "Invalid Pool Type in LLPipeline::findPool() type=" << type << LL_ENDL;
@@ -3855,7 +3873,12 @@ void LLPipeline::renderSelectedFaces(const LLColor4& color)
for (auto facep : mSelectedFaces)
{
- if (!facep || facep->getDrawable()->isDead())
+ if (!facep || !facep->getViewerObject())
+ {
+ LLSelectMgr::getInstance()->clearSelections();
+ return;
+ }
+ if (!facep->getDrawable() || facep->getDrawable()->isDead())
{
LL_ERRS() << "Bad face on selection" << LL_ENDL;
return;
@@ -4067,6 +4090,8 @@ void LLPipeline::renderGeomDeferred(LLCamera& camera, bool do_occlusion)
#endif
}
+// Render all of our geometry that's required after our deferred pass.
+// This is gonna be stuff like alpha, water, etc.
void LLPipeline::renderGeomPostDeferred(LLCamera& camera)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL;
@@ -4085,6 +4110,10 @@ void LLPipeline::renderGeomPostDeferred(LLCamera& camera)
bool done_atmospherics = LLPipeline::sRenderingHUDs; //skip atmospherics on huds
bool done_water_haze = done_atmospherics;
+ bool done_water_exclusion = false;
+
+ // do water exclusion just before water pass.
+ U32 water_exclusion_pass = LLDrawPool::POOL_WATEREXCLUSION;
// do atmospheric haze just before post water alpha
U32 atmospherics_pass = LLDrawPool::POOL_ALPHA_POST_WATER;
@@ -4123,6 +4152,12 @@ void LLPipeline::renderGeomPostDeferred(LLCamera& camera)
cur_type = poolp->getType();
+ if (cur_type >= water_exclusion_pass && !done_water_exclusion)
+ { // do water exclusion against depth buffer before rendering alpha
+ doWaterExclusionMask();
+ done_water_exclusion = true;
+ }
+
if (cur_type >= atmospherics_pass && !done_atmospherics)
{ // do atmospherics against depth buffer before rendering alpha
doAtmospherics();
@@ -5238,6 +5273,17 @@ void LLPipeline::addToQuickLookup( LLDrawPool* new_poolp )
}
break;
+ case LLDrawPool::POOL_WATEREXCLUSION:
+ if (mWaterExclusionPool)
+ {
+ llassert(0);
+ LL_WARNS() << "LLPipeline::addPool(): Ignoring duplicate Water Exclusion Pool" << LL_ENDL;
+ }
+ else
+ {
+ mWaterExclusionPool = new_poolp;
+ }
+ break;
default:
llassert(0);
@@ -5360,6 +5406,11 @@ void LLPipeline::removeFromQuickLookup( LLDrawPool* poolp )
mPBRAlphaMaskPool = NULL;
break;
+ case LLDrawPool::POOL_WATEREXCLUSION:
+ llassert(poolp == mWaterExclusionPool);
+ mWaterExclusionPool = nullptr;
+ break;
+
default:
llassert(0);
LL_WARNS() << "Invalid Pool Type in LLPipeline::removeFromQuickLookup() type=" << poolp->getType() << LL_ENDL;
@@ -7118,7 +7169,7 @@ void LLPipeline::generateExposure(LLRenderTarget* src, LLRenderTarget* dst, bool
LLSettingsSky::ptr_t sky = LLEnvironment::instance().getCurrentSky();
- F32 probe_ambiance = LLEnvironment::instance().getCurrentSky()->getReflectionProbeAmbiance(should_auto_adjust);
+ F32 probe_ambiance = LLEnvironment::instance().getCurrentSky()->getReflectionProbeAmbiance(should_auto_adjust());
F32 exp_min = 1.f;
F32 exp_max = 1.f;
@@ -7129,13 +7180,13 @@ void LLPipeline::generateExposure(LLRenderTarget* src, LLRenderTarget* dst, bool
{
if (dynamic_exposure_enabled)
{
- exp_min = sky->getHDROffset() - sky->getHDRMin();
- exp_max = sky->getHDROffset() + sky->getHDRMax();
+ exp_min = sky->getHDROffset(should_auto_adjust()) - sky->getHDRMin(should_auto_adjust());
+ exp_max = sky->getHDROffset(should_auto_adjust()) + sky->getHDRMax(should_auto_adjust());
}
else
{
- exp_min = sky->getHDROffset();
- exp_max = sky->getHDROffset();
+ exp_min = sky->getHDROffset(should_auto_adjust());
+ exp_max = sky->getHDROffset(should_auto_adjust());
}
}
else if (dynamic_exposure_enabled)
@@ -7155,7 +7206,7 @@ void LLPipeline::generateExposure(LLRenderTarget* src, LLRenderTarget* dst, bool
shader->uniform1f(dt, gFrameIntervalSeconds);
shader->uniform2f(noiseVec, ll_frand() * 2.0f - 1.0f, ll_frand() * 2.0f - 1.0f);
shader->uniform4f(dynamic_exposure_params, dynamic_exposure_coefficient, exp_min, exp_max, dynamic_exposure_speed_error);
- shader->uniform4f(dynamic_exposure_params2, sky->getHDROffset(), exp_min, exp_max, dynamic_exposure_speed_target);
+ shader->uniform4f(dynamic_exposure_params2, sky->getHDROffset(should_auto_adjust()), exp_min, exp_max, dynamic_exposure_speed_target);
mScreenTriangleVB->setBuffer();
mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3);
@@ -7213,7 +7264,7 @@ void LLPipeline::tonemap(LLRenderTarget* src, LLRenderTarget* dst)
static LLCachedControl<U32> tonemap_type_setting(gSavedSettings, "RenderTonemapType", 0U);
shader.uniform1i(tonemap_type, tonemap_type_setting);
- shader.uniform1f(tonemap_mix, psky->getTonemapMix());
+ shader.uniform1f(tonemap_mix, psky->getTonemapMix(should_auto_adjust()));
mScreenTriangleVB->setBuffer();
mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3);
@@ -8433,13 +8484,13 @@ void LLPipeline::renderDeferredLighting()
setupHWLights(); // to set mSun/MoonDir;
- glm::vec4 tc(glm::make_vec4(mSunDir.mV));
+ glm::vec4 tc(mSunDir);
tc = mat * tc;
- mTransformedSunDir.set(glm::value_ptr(tc));
+ mTransformedSunDir.set(tc);
- glm::vec4 tc_moon(glm::make_vec4(mMoonDir.mV));
+ glm::vec4 tc_moon(mMoonDir);
tc_moon = mat * tc_moon;
- mTransformedMoonDir.set(glm::value_ptr(tc_moon));
+ mTransformedMoonDir.set(tc_moon);
if ((RenderDeferredSSAO && !gCubeSnapshot) || RenderShadowDetail > 0)
{
@@ -8692,7 +8743,7 @@ void LLPipeline::renderDeferredLighting()
continue;
}
- glm::vec3 tc(glm::make_vec3(c));
+ glm::vec3 tc(center);
tc = mul_mat4_vec3(mat, tc);
fullscreen_lights.push_back(LLVector4(tc.x, tc.y, tc.z, s));
@@ -8799,13 +8850,12 @@ void LLPipeline::renderDeferredLighting()
LLDrawable* drawablep = *iter;
LLVOVolume* volume = drawablep->getVOVolume();
LLVector3 center = drawablep->getPositionAgent();
- F32* c = center.mV;
F32 light_size_final = volume->getLightRadius() * 1.5f;
F32 light_falloff_final = volume->getLightFalloff(DEFERRED_LIGHT_FALLOFF);
sVisibleLightCount++;
- glm::vec3 tc(glm::make_vec3(c));
+ glm::vec3 tc(center);
tc = mul_mat4_vec3(mat, tc);
setupSpotLight(gDeferredMultiSpotLightProgram, drawablep);
@@ -8862,6 +8912,7 @@ void LLPipeline::renderDeferredLighting()
LLPipeline::RENDER_TYPE_FULLBRIGHT_ALPHA_MASK,
LLPipeline::RENDER_TYPE_TERRAIN,
LLPipeline::RENDER_TYPE_WATER,
+ LLPipeline::RENDER_TYPE_WATEREXCLUSION,
END_RENDER_TYPES);
renderGeomPostDeferred(*LLViewerCamera::getInstance());
@@ -9000,6 +9051,8 @@ void LLPipeline::doWaterHaze()
static LLStaticHashedString above_water_str("above_water");
haze_shader.uniform1i(above_water_str, sUnderWaterRender ? -1 : 1);
+ haze_shader.bindTexture(LLShaderMgr::WATER_EXCLUSIONTEX, &mWaterExclusionMask);
+
if (LLPipeline::sUnderWaterRender)
{
LLGLDepthTest depth(GL_FALSE);
@@ -9030,6 +9083,17 @@ void LLPipeline::doWaterHaze()
}
}
+void LLPipeline::doWaterExclusionMask()
+{
+ mWaterExclusionMask.bindTarget();
+ glClearColor(1, 1, 1, 1);
+ mWaterExclusionMask.clear();
+ mWaterExclusionPool->render();
+
+ mWaterExclusionMask.flush();
+ glClearColor(0, 0, 0, 0);
+}
+
void LLPipeline::setupSpotLight(LLGLSLShader& shader, LLDrawable* drawablep)
{
//construct frustum
@@ -9946,10 +10010,7 @@ void LLPipeline::generateSunShadow(LLCamera& camera)
LLVector3 lightDir = -caster_dir;
lightDir.normVec();
- glm::vec3 light_dir(glm::make_vec3(lightDir.mV));
-
//create light space camera matrix
-
LLVector3 at = lightDir;
LLVector3 up = camera.getAtAxis();
@@ -10001,9 +10062,9 @@ void LLPipeline::generateSunShadow(LLCamera& camera)
//get good split distances for frustum
for (U32 i = 0; i < fp.size(); ++i)
{
- glm::vec3 v(glm::make_vec3(fp[i].mV));
+ glm::vec3 v(fp[i]);
v = mul_mat4_vec3(saved_view, v);
- fp[i].setVec(glm::value_ptr(v));
+ fp[i] = LLVector3(v);
}
min = fp[0];
@@ -10152,9 +10213,9 @@ void LLPipeline::generateSunShadow(LLCamera& camera)
for (U32 i = 0; i < fp.size(); i++)
{
- glm::vec3 p = glm::make_vec3(fp[i].mV);
+ glm::vec3 p(fp[i]);
p = mul_mat4_vec3(view[j], p);
- wpf.push_back(LLVector3(glm::value_ptr(p)));
+ wpf.push_back(LLVector3(p));
}
min = wpf[0];
@@ -10355,19 +10416,19 @@ void LLPipeline::generateSunShadow(LLCamera& camera)
view[j] = glm::inverse(view[j]);
//llassert(origin.isFinite());
- glm::vec3 origin_agent(glm::make_vec3(origin.mV));
+ glm::vec3 origin_agent(origin);
//translate view to origin
origin_agent = mul_mat4_vec3(view[j], origin_agent);
- eye = LLVector3(glm::value_ptr(origin_agent));
+ eye = LLVector3(origin_agent);
//llassert(eye.isFinite());
if (!hasRenderDebugMask(LLPipeline::RENDER_DEBUG_SHADOW_FRUSTA) && !gCubeSnapshot)
{
mShadowFrustOrigin[j] = eye;
}
- view[j] = look(LLVector3(glm::value_ptr(origin_agent)), lightDir, -up);
+ view[j] = look(LLVector3(origin_agent), lightDir, -up);
F32 fx = 1.f/tanf(fovx);
F32 fz = 1.f/tanf(fovz);
diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h
index 5c9b95ef4a..315e38ed8c 100644
--- a/indra/newview/pipeline.h
+++ b/indra/newview/pipeline.h
@@ -337,6 +337,9 @@ public:
// should be called just before rendering pre-water alpha objects
void doWaterHaze();
+ // Generate the water exclusion surface mask.
+ void doWaterExclusionMask();
+
void postDeferredGammaCorrect(LLRenderTarget* screen_target);
void generateSunShadow(LLCamera& camera);
@@ -500,6 +503,7 @@ public:
RENDER_TYPE_AVATAR = LLDrawPool::POOL_AVATAR,
RENDER_TYPE_CONTROL_AV = LLDrawPool::POOL_CONTROL_AV, // Animesh
RENDER_TYPE_TREE = LLDrawPool::POOL_TREE,
+ RENDER_TYPE_WATEREXCLUSION = LLDrawPool::POOL_WATEREXCLUSION,
RENDER_TYPE_VOIDWATER = LLDrawPool::POOL_VOIDWATER,
RENDER_TYPE_WATER = LLDrawPool::POOL_WATER,
RENDER_TYPE_GLTF_PBR = LLDrawPool::POOL_GLTF_PBR,
@@ -714,6 +718,7 @@ public:
LLRenderTarget mSpotShadow[2];
LLRenderTarget mPbrBrdfLut;
+ LLRenderTarget mWaterExclusionMask;
// copy of the color/depth buffer just before gamma correction
// for use by SSR
@@ -953,6 +958,7 @@ protected:
LLDrawPool* mWLSkyPool = nullptr;
LLDrawPool* mPBROpaquePool = nullptr;
LLDrawPool* mPBRAlphaMaskPool = nullptr;
+ LLDrawPool* mWaterExclusionPool = nullptr;
// Note: no need to keep an quick-lookup to avatar pools, since there's only one per avatar
diff --git a/indra/newview/skins/default/textures/3p_icons/fmod_logo.png b/indra/newview/skins/default/textures/3p_icons/fmod_logo.png
deleted file mode 100644
index 5a50e0ad34..0000000000
--- a/indra/newview/skins/default/textures/3p_icons/fmod_logo.png
+++ /dev/null
Binary files differ
diff --git a/indra/newview/skins/default/textures/3p_icons/havok_logo.png b/indra/newview/skins/default/textures/3p_icons/havok_logo.png
deleted file mode 100644
index ff1ea3a72e..0000000000
--- a/indra/newview/skins/default/textures/3p_icons/havok_logo.png
+++ /dev/null
Binary files differ
diff --git a/indra/newview/skins/default/textures/3p_icons/vivox_logo.png b/indra/newview/skins/default/textures/3p_icons/vivox_logo.png
deleted file mode 100644
index 6f20e87b7a..0000000000
--- a/indra/newview/skins/default/textures/3p_icons/vivox_logo.png
+++ /dev/null
Binary files differ
diff --git a/indra/newview/skins/default/xui/de/panel_progress.xml b/indra/newview/skins/default/xui/de/panel_progress.xml
index 8d1abdcac1..c9bed9fd9b 100644
--- a/indra/newview/skins/default/xui/de/panel_progress.xml
+++ b/indra/newview/skins/default/xui/de/panel_progress.xml
@@ -1,10 +1,8 @@
<?xml version="1.0" ?>
<panel name="login_progress_panel">
- <layout_panel name="panel_icons"/>
<layout_stack name="vertical_centering"/>
<layout_panel name="panel4"/>
<layout_panel name="center"/>
<layout_stack name="horizontal_centering">
- <text name="logos_lbl">Second Life verwendet</text>
</layout_stack>
</panel>
diff --git a/indra/newview/skins/default/xui/en/floater_preferences_graphics_advanced.xml b/indra/newview/skins/default/xui/en/floater_preferences_graphics_advanced.xml
index 0fdc1596c4..9db5502387 100644
--- a/indra/newview/skins/default/xui/en/floater_preferences_graphics_advanced.xml
+++ b/indra/newview/skins/default/xui/en/floater_preferences_graphics_advanced.xml
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<floater
- height="430"
+ height="452"
layout="topleft"
name="prefs_graphics_advanced"
help_topic="Preferences_Graphics_Advanced"
@@ -118,6 +118,41 @@
name="MaxLights"
top_delta="16"
width="336" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ top_delta="16"
+ left="30"
+ width="160"
+ name="MaxTextureResolutionLabel"
+ text_readonly_color="LabelDisabledColor">
+ Maximum LOD resolution:
+ </text>
+ <combo_box
+ control_name="RenderMaxTextureResolution"
+ height="19"
+ layout="topleft"
+ left_pad="10"
+ top_delta="0"
+ name="MaxTextureResolution"
+ tool_tip="Maximum resolution for 'level of detail' textures"
+ width="90">
+ <combo_box.item
+ label="512"
+ name="512"
+ value="512"/>
+ <combo_box.item
+ label="1024"
+ name="1024"
+ value="1024"/>
+ <combo_box.item
+ label="2048"
+ name="2048"
+ value="2048"/>
+ </combo_box>
<check_box
control_name="RenderVSyncEnable"
@@ -152,7 +187,7 @@
layout="topleft"
left="30"
top_delta="16"
- width="128"
+ width="130"
name="AvatarComplexityModeLabel"
text_readonly_color="LabelDisabledColor">
Avatar display:
@@ -160,10 +195,10 @@
<combo_box
control_name="RenderAvatarComplexityMode"
- height="18"
+ height="19"
layout="topleft"
- left_delta="130"
- top_delta="0"
+ left_pad="40"
+ top_delta="-1"
name="AvatarComplexityMode"
width="150">
<combo_box.item
@@ -195,7 +230,7 @@
max_val="101"
name="IndirectMaxComplexity"
show_text="false"
- top_delta="16"
+ top_delta="19"
width="300">
<slider.commit_callback
function="Pref.UpdateIndirectMaxComplexity"
@@ -368,7 +403,7 @@
left="30"
name="antialiasing label"
top_delta="20"
- width="120">
+ width="130">
Antialiasing:
</text>
<combo_box
@@ -403,7 +438,7 @@
left="30"
name="antialiasing quality label"
top_delta="20"
- width="120">
+ width="130">
Antialiasing Quality:
</text>
<combo_box
@@ -1015,7 +1050,7 @@
layout="topleft"
left="13"
name="horiz_border"
- top="393"
+ top="415"
top_delta="5"
width="774"/>
<button
diff --git a/indra/newview/skins/default/xui/en/menu_login.xml b/indra/newview/skins/default/xui/en/menu_login.xml
index 1d1b81e31a..5fff9b7bc0 100644
--- a/indra/newview/skins/default/xui/en/menu_login.xml
+++ b/indra/newview/skins/default/xui/en/menu_login.xml
@@ -95,18 +95,11 @@
</menu_item_call>
<menu_item_separator/>
<menu_item_call
- label="[SECOND_LIFE] News"
- name="Second Life News">
- <menu_item_call.on_click
- function="Advanced.ShowURL"
- parameter="http://community.secondlife.com/t5/Featured-News/bg-p/blog_feature_news"/>
- </menu_item_call>
- <menu_item_call
label="[SECOND_LIFE] Blogs"
name="Second Life Blogs">
<menu_item_call.on_click
function="Advanced.ShowURL"
- parameter="http://community.secondlife.com/t5/Blogs/ct-p/Blogs"/>
+ parameter="https://community.secondlife.com/news/"/>
</menu_item_call>
<menu_item_separator/>
<menu_item_call
diff --git a/indra/newview/skins/default/xui/en/menu_viewer.xml b/indra/newview/skins/default/xui/en/menu_viewer.xml
index 977b225960..607c7698c3 100644
--- a/indra/newview/skins/default/xui/en/menu_viewer.xml
+++ b/indra/newview/skins/default/xui/en/menu_viewer.xml
@@ -1796,18 +1796,11 @@ function="World.EnvPreset"
</menu_item_call>
<menu_item_separator/>
<menu_item_call
- label="[SECOND_LIFE] News"
- name="Second Life News">
- <menu_item_call.on_click
- function="Advanced.ShowURL"
- parameter="http://community.secondlife.com/t5/Featured-News/bg-p/blog_feature_news"/>
- </menu_item_call>
- <menu_item_call
label="[SECOND_LIFE] Blogs"
name="Second Life Blogs">
<menu_item_call.on_click
function="Advanced.ShowURL"
- parameter="http://community.secondlife.com/t5/Blogs/ct-p/Blogs"/>
+ parameter="https://community.secondlife.com/news/"/>
</menu_item_call>
<menu_item_separator/>
diff --git a/indra/newview/skins/default/xui/en/panel_preferences_setup.xml b/indra/newview/skins/default/xui/en/panel_preferences_setup.xml
index 28c2d2af6e..258c49785e 100644
--- a/indra/newview/skins/default/xui/en/panel_preferences_setup.xml
+++ b/indra/newview/skins/default/xui/en/panel_preferences_setup.xml
@@ -202,7 +202,7 @@
follows="left|top"
height="14"
control_name="UpdaterWillingToTest"
- label="Willing to update to release candidates"
+ label="Willing to update to Beta"
left_delta="0"
mouse_opaque="true"
name="update_willing_to_test"
diff --git a/indra/newview/skins/default/xui/en/panel_progress.xml b/indra/newview/skins/default/xui/en/panel_progress.xml
index 0742cef7c7..6b19907372 100644
--- a/indra/newview/skins/default/xui/en/panel_progress.xml
+++ b/indra/newview/skins/default/xui/en/panel_progress.xml
@@ -33,7 +33,7 @@
layout="topleft"
left="0"
orientation="vertical"
- name="vertical_centering"
+ name="vertical_centering1"
top="0"
width="670">
<layout_panel
@@ -44,40 +44,32 @@
width="670" />
<layout_panel
auto_resize="false"
- height="275"
+ height="220"
layout="topleft"
- min_height="275"
+ min_height="220"
name="panel4"
width="670">
<icon
color="LoginProgressBoxCenterColor"
follows="left|right|bottom|top"
- height="275"
image_name="Rounded_Square"
layout="topleft"
left="0"
top="0"
+ height="220"
width="670" />
<layout_stack
follows="left|right|top|bottom"
- height="275"
+ height="220"
layout="topleft"
left="0"
orientation="vertical"
- name="vertical_centering"
+ name="vertical_centering2"
animate="false"
top="0"
width="670">
<layout_panel
auto_resize="false"
- height="30"
- layout="topleft"
- min_height="30"
- name="panel_top_spacer"
- width="670">
- </layout_panel>
- <layout_panel
- auto_resize="false"
height="100"
layout="topleft"
min_height="100"
@@ -121,9 +113,9 @@
</layout_panel>
<layout_panel
auto_resize="false"
- height="110"
+ height="90"
layout="topleft"
- min_height="110"
+ min_height="90"
name="panel_motd"
width="670">
<text
@@ -132,7 +124,7 @@
font_shadow="none"
halign="left"
valign="center"
- height="100"
+ height="80"
layout="topleft"
left="45"
line_spacing.pixels="2"
@@ -142,30 +134,6 @@
right="-90"
word_wrap="true"/>
</layout_panel>
- <layout_panel
- auto_resize="false"
- height="40"
- layout="topleft"
- min_height="40"
- name="panel_icons"
- width="670">
- <!--Logos are tied to following label from code-->
- <text
- follows="left|right|top"
- layout="topleft"
- font="SansSerifLarge"
- font_shadow="none"
- halign="left"
- height="16"
- width="240"
- left="47"
- top="6"
- line_spacing.pixels="2"
- name="logos_lbl"
- text_color="LoginProgressBoxTextColor">
- Megapahit uses
- </text>
- </layout_panel>
</layout_stack>
</layout_panel>
<layout_panel
diff --git a/indra/newview/skins/default/xui/es/panel_progress.xml b/indra/newview/skins/default/xui/es/panel_progress.xml
index 64aaf246f8..c9bed9fd9b 100644
--- a/indra/newview/skins/default/xui/es/panel_progress.xml
+++ b/indra/newview/skins/default/xui/es/panel_progress.xml
@@ -1,10 +1,8 @@
<?xml version="1.0" ?>
<panel name="login_progress_panel">
- <layout_panel name="panel_icons"/>
<layout_stack name="vertical_centering"/>
<layout_panel name="panel4"/>
<layout_panel name="center"/>
<layout_stack name="horizontal_centering">
- <text name="logos_lbl">Usos de Second Life</text>
</layout_stack>
</panel>
diff --git a/indra/newview/skins/default/xui/fr/panel_progress.xml b/indra/newview/skins/default/xui/fr/panel_progress.xml
index 673ec63642..c9bed9fd9b 100644
--- a/indra/newview/skins/default/xui/fr/panel_progress.xml
+++ b/indra/newview/skins/default/xui/fr/panel_progress.xml
@@ -1,10 +1,8 @@
<?xml version="1.0" ?>
<panel name="login_progress_panel">
- <layout_panel name="panel_icons"/>
<layout_stack name="vertical_centering"/>
<layout_panel name="panel4"/>
<layout_panel name="center"/>
<layout_stack name="horizontal_centering">
- <text name="logos_lbl">Second Life utilise</text>
</layout_stack>
</panel>
diff --git a/indra/newview/skins/default/xui/it/panel_progress.xml b/indra/newview/skins/default/xui/it/panel_progress.xml
index fd2892a88f..c9bed9fd9b 100644
--- a/indra/newview/skins/default/xui/it/panel_progress.xml
+++ b/indra/newview/skins/default/xui/it/panel_progress.xml
@@ -1,10 +1,8 @@
<?xml version="1.0" ?>
<panel name="login_progress_panel">
- <layout_panel name="panel_icons"/>
<layout_stack name="vertical_centering"/>
<layout_panel name="panel4"/>
<layout_panel name="center"/>
<layout_stack name="horizontal_centering">
- <text name="logos_lbl">Utilizzi di Second Life</text>
</layout_stack>
</panel>
diff --git a/indra/newview/skins/default/xui/ja/panel_preferences_setup.xml b/indra/newview/skins/default/xui/ja/panel_preferences_setup.xml
index f487bc32a9..959f827a61 100644
--- a/indra/newview/skins/default/xui/ja/panel_preferences_setup.xml
+++ b/indra/newview/skins/default/xui/ja/panel_preferences_setup.xml
@@ -30,7 +30,7 @@
<combo_box.item label="オプションのアップデートのインストール準備ができたら通知する" name="Install_ask"/>
<combo_box.item label="必須アップデートのみインストールする" name="Install_manual"/>
</combo_box>
- <check_box label="release candidate にアップグレードします" name="update_willing_to_test"/>
+ <check_box label="Beta にアップグレードします" name="update_willing_to_test"/>
<check_box label="更新後にリリースノートを表示する" name="update_show_release_notes"/>
<text name="Proxy Settings:">
プロキシ設定:
diff --git a/indra/newview/skins/default/xui/ja/panel_progress.xml b/indra/newview/skins/default/xui/ja/panel_progress.xml
index 7fd7d5ab5c..1edada6098 100644
--- a/indra/newview/skins/default/xui/ja/panel_progress.xml
+++ b/indra/newview/skins/default/xui/ja/panel_progress.xml
@@ -1,12 +1,8 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<panel name="login_progress_panel">
- <layout_panel name="panel_icons"/>
<layout_stack name="vertical_centering"/>
<layout_panel name="panel4"/>
<layout_panel name="center"/>
<layout_stack name="horizontal_centering">
- <text name="logos_lbl">
- セカンドライフ使用
- </text>
</layout_stack>
</panel>
diff --git a/indra/newview/skins/default/xui/pl/panel_progress.xml b/indra/newview/skins/default/xui/pl/panel_progress.xml
index 22b6a8fcf5..8da982cc3f 100644
--- a/indra/newview/skins/default/xui/pl/panel_progress.xml
+++ b/indra/newview/skins/default/xui/pl/panel_progress.xml
@@ -2,14 +2,9 @@
<panel name="login_progress_panel">
<layout_stack name="horizontal_centering">
<layout_panel name="center">
- <layout_stack name="vertical_centering">
+ <layout_stack name="vertical_centering1">
<layout_panel name="panel4">
- <layout_stack name="vertical_centering">
- <layout_panel name="panel_icons">
- <text name="logos_lbl">
- Second Life używa
- </text>
- </layout_panel>
+ <layout_stack name="vertical_centering2">
</layout_stack>
</layout_panel>
</layout_stack>
diff --git a/indra/newview/skins/default/xui/pt/panel_progress.xml b/indra/newview/skins/default/xui/pt/panel_progress.xml
index 63bb663cfc..c9bed9fd9b 100644
--- a/indra/newview/skins/default/xui/pt/panel_progress.xml
+++ b/indra/newview/skins/default/xui/pt/panel_progress.xml
@@ -1,10 +1,8 @@
<?xml version="1.0" ?>
<panel name="login_progress_panel">
- <layout_panel name="panel_icons"/>
<layout_stack name="vertical_centering"/>
<layout_panel name="panel4"/>
<layout_panel name="center"/>
<layout_stack name="horizontal_centering">
- <text name="logos_lbl">Usos do Second Life</text>
</layout_stack>
</panel>