summaryrefslogtreecommitdiff
path: root/indra/newview
diff options
context:
space:
mode:
authorAndrey Lihatskiy <alihatskiy@productengine.com>2021-08-12 23:05:07 +0300
committerAndrey Lihatskiy <alihatskiy@productengine.com>2021-08-12 23:13:12 +0300
commit97f09de4fcbe2a789d01ed362d6acfcac6b007b3 (patch)
treeb35db61d9bf9902d443043d289f57f6f70334678 /indra/newview
parent54171dbc9fe3fa42ebbf59a243b7381fdb3aa662 (diff)
parentc40b8310b00f1d620a2f5a94f2514c8bf3531373 (diff)
Merge branch 'master' into DRTVWR-520-apple-notarization
# Conflicts: # autobuild.xml # build.sh # indra/CMakeLists.txt # indra/newview/CMakeLists.txt # indra/newview/llappviewermacosx.cpp # indra/newview/llappviewerwin32.h # indra/newview/viewer_manifest.py # indra/win_crash_logger/llcrashloggerwindows.cpp
Diffstat (limited to 'indra/newview')
-rw-r--r--indra/newview/CMakeLists.txt45
-rw-r--r--indra/newview/VIEWER_VERSION.txt2
-rw-r--r--indra/newview/app_settings/settings.xml29
-rw-r--r--indra/newview/featuretable.txt11
-rw-r--r--indra/newview/featuretable_linux.txt11
-rw-r--r--indra/newview/featuretable_mac.txt11
-rw-r--r--indra/newview/llagent.cpp76
-rw-r--r--indra/newview/llagent.h2
-rw-r--r--indra/newview/llappcorehttp.cpp24
-rw-r--r--indra/newview/llappcorehttp.h1
-rw-r--r--indra/newview/llappdelegate-objc.mm10
-rw-r--r--indra/newview/llappearancemgr.cpp6
-rw-r--r--indra/newview/llappviewer.cpp141
-rw-r--r--indra/newview/llappviewer.h5
-rw-r--r--indra/newview/llappviewermacosx.cpp52
-rw-r--r--indra/newview/llappviewerwin32.cpp55
-rw-r--r--indra/newview/llappviewerwin32.h16
-rw-r--r--indra/newview/llcompilequeue.cpp2
-rw-r--r--indra/newview/lldelayedgestureerror.cpp2
-rw-r--r--indra/newview/llenvironment.cpp98
-rw-r--r--indra/newview/llfloaterabout.cpp1
-rw-r--r--indra/newview/llfloatercreatelandmark.cpp2
-rw-r--r--indra/newview/llfloatereditenvironmentbase.cpp2
-rw-r--r--indra/newview/llfloaterexperienceprofile.cpp14
-rw-r--r--indra/newview/llfloaterexperienceprofile.h2
-rw-r--r--indra/newview/llfloatergridstatus.cpp1
-rw-r--r--indra/newview/llfloaterurlentry.cpp9
-rw-r--r--indra/newview/llfloaterurlentry.h1
-rw-r--r--indra/newview/llhudnametag.cpp11
-rw-r--r--indra/newview/llhudnametag.h4
-rw-r--r--indra/newview/llhudtext.cpp3
-rw-r--r--indra/newview/llinventorybridge.cpp9
-rw-r--r--indra/newview/lllandmarklist.cpp114
-rw-r--r--indra/newview/lllandmarklist.h1
-rw-r--r--indra/newview/llmediactrl.h3
-rw-r--r--indra/newview/llmeshrepository.cpp19
-rw-r--r--indra/newview/lloutfitgallery.cpp17
-rw-r--r--indra/newview/lloutfitslist.cpp5
-rw-r--r--indra/newview/llpanellogin.cpp19
-rw-r--r--indra/newview/llpanellogin.h2
-rw-r--r--indra/newview/llpanelpicks.cpp45
-rw-r--r--indra/newview/llpanelpicks.h1
-rw-r--r--indra/newview/llpreviewscript.cpp52
-rw-r--r--indra/newview/llpreviewscript.h2
-rw-r--r--indra/newview/llsechandler_basic.cpp14
-rw-r--r--indra/newview/llskinningutil.cpp7
-rw-r--r--indra/newview/llstartup.cpp3
-rw-r--r--indra/newview/llteleporthistorystorage.cpp6
-rw-r--r--indra/newview/lltoolmgr.cpp2
-rw-r--r--indra/newview/lltoolpie.cpp3
-rw-r--r--indra/newview/lltranslate.cpp2
-rw-r--r--indra/newview/llviewerassetstorage.cpp4
-rw-r--r--indra/newview/llviewerdisplay.cpp33
-rw-r--r--indra/newview/llviewerfoldertype.cpp2
-rw-r--r--indra/newview/llviewermedia.cpp9
-rw-r--r--indra/newview/llviewermenu.cpp75
-rw-r--r--indra/newview/llviewerregion.cpp15
-rw-r--r--indra/newview/llviewerregion.h2
-rw-r--r--indra/newview/llviewerwindow.cpp5
-rw-r--r--indra/newview/llvoavatar.cpp27
-rw-r--r--indra/newview/llvocache.cpp125
-rw-r--r--indra/newview/llvocache.h2
-rw-r--r--indra/newview/llvoicevivox.cpp68
-rw-r--r--indra/newview/llvoicevivox.h1
-rw-r--r--indra/newview/llvovolume.cpp26
-rw-r--r--indra/newview/llwatchdog.cpp24
-rw-r--r--indra/newview/llwatchdog.h6
-rw-r--r--indra/newview/llweb.cpp2
-rw-r--r--indra/newview/llwebprofile.cpp1
-rw-r--r--indra/newview/llwlhandlers.cpp2
-rw-r--r--indra/newview/skins/default/xui/en/floater_create_landmark.xml2
-rw-r--r--indra/newview/skins/default/xui/en/floater_preferences_graphics_advanced.xml17
-rw-r--r--indra/newview/skins/default/xui/en/floater_url_entry.xml2
-rw-r--r--indra/newview/skins/default/xui/en/menu_inventory.xml8
-rw-r--r--indra/newview/skins/default/xui/en/menu_land.xml2
-rw-r--r--indra/newview/skins/default/xui/en/menu_viewer.xml12
-rw-r--r--indra/newview/skins/default/xui/en/notifications.xml9
-rw-r--r--indra/newview/skins/default/xui/en/panel_login_first.xml26
-rw-r--r--indra/newview/skins/default/xui/en/panel_navigation_bar.xml6
-rw-r--r--indra/newview/skins/default/xui/en/panel_preferences_setup.xml45
-rw-r--r--indra/newview/skins/default/xui/en/panel_status_bar.xml6
-rw-r--r--indra/newview/skins/default/xui/en/strings.xml2
-rw-r--r--indra/newview/tests/cppfeatures_test.cpp386
-rwxr-xr-xindra/newview/viewer_manifest.py8
84 files changed, 1333 insertions, 602 deletions
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index 36b7625a94..68b5969ff1 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -8,9 +8,7 @@ include(00-Common)
include(Linking)
include(Boost)
-if (BUGSPLAT_DB)
- include(bugsplat)
-endif (BUGSPLAT_DB)
+include(bugsplat)
include(BuildPackagesInfo)
include(BuildVersion)
include(CMakeCopyIfDifferent)
@@ -96,18 +94,18 @@ include_directories(
${CMAKE_CURRENT_SOURCE_DIR}
)
-if (BUGSPLAT_DB)
- include_directories(
- ${BUGSPLAT_INCLUDE_DIR}
- )
-endif (BUGSPLAT_DB)
-
include_directories(SYSTEM
${LLCOMMON_SYSTEM_INCLUDE_DIRS}
${LLXML_SYSTEM_INCLUDE_DIRS}
${LLPHYSICSEXTENSIONS_INCLUDE_DIRS}
)
+if (USE_BUGSPLAT)
+ include_directories(AFTER
+ ${BUGSPLAT_INCLUDE_DIR}
+ )
+endif (USE_BUGSPLAT)
+
set(viewer_SOURCE_FILES
groupchatlistener.cpp
llaccountingcostmanager.cpp
@@ -1423,11 +1421,11 @@ if (DARWIN)
${COREAUDIO_LIBRARY}
)
- if (BUGSPLAT_DB)
+ if (USE_BUGSPLAT)
list(APPEND viewer_LIBRARIES
${BUGSPLAT_LIBRARIES}
)
- endif (BUGSPLAT_DB)
+ endif (USE_BUGSPLAT)
# Add resource files to the project.
set(viewer_RESOURCE_FILES
@@ -1765,10 +1763,10 @@ if (SDL_FOUND)
)
endif (SDL_FOUND)
-if (BUGSPLAT_DB)
+if (USE_BUGSPLAT)
set_property(TARGET ${VIEWER_BINARY_NAME}
- PROPERTY COMPILE_DEFINITIONS "LL_BUGSPLAT")
-endif (BUGSPLAT_DB)
+ PROPERTY COMPILE_DEFINITIONS "${BUGSPLAT_DEFINE}")
+endif (USE_BUGSPLAT)
# add package files
file(GLOB EVENT_HOST_SCRIPT_GLOB_LIST
@@ -1845,6 +1843,10 @@ if (WINDOWS)
winmm_shim
)
+ if (NOT USE_BUGSPLAT)
+ LIST(APPEND COPY_INPUT_DEPENDENCIES windows-crash-logger)
+ endif (NOT USE_BUGSPLAT)
+
if (ADDRESS_SIZE EQUAL 64)
list(APPEND COPY_INPUT_DEPENDENCIES
${SHARED_LIB_STAGING_DIR}/${CMAKE_CFG_INTDIR}/vivoxsdk_x64.dll
@@ -2065,11 +2067,11 @@ target_link_libraries(${VIEWER_BINARY_NAME}
${LLAPPEARANCE_LIBRARIES}
)
-if (BUGSPLAT_DB)
+if (USE_BUGSPLAT)
target_link_libraries(${VIEWER_BINARY_NAME}
${BUGSPLAT_LIBRARIES}
)
-endif (BUGSPLAT_DB)
+endif (USE_BUGSPLAT)
set(ARTWORK_DIR ${CMAKE_CURRENT_SOURCE_DIR} CACHE PATH
"Path to artwork files.")
@@ -2080,13 +2082,16 @@ if (LINUX)
# These are the generated targets that are copied to package/
set(COPY_INPUT_DEPENDENCIES
${VIEWER_BINARY_NAME}
- linux-crash-logger
SLPlugin
media_plugin_gstreamer010
media_plugin_libvlc
llcommon
)
+ if (NOT USE_BUGSPLAT)
+ LIST(APPEND COPY_INPUT_DEPENDENCIES linux-crash-logger)
+ endif (NOT USE_BUGSPLAT)
+
add_custom_command(
OUTPUT ${product}.tar.bz2
COMMAND ${PYTHON_EXECUTABLE}
@@ -2346,7 +2351,7 @@ if (PACKAGE AND (RELEASE_CRASH_REPORTING OR NON_RELEASE_CRASH_REPORTING) AND VIE
endif (LINUX)
endif (BUGSPLAT_DB)
- # for both BUGSPLAT_DB and Breakpad
+ # for both Bugsplat and Breakpad
add_dependencies(llpackage generate_symbols)
endif ()
@@ -2479,6 +2484,10 @@ if (LL_TESTS)
${BOOST_CONTEXT_LIBRARY}
)
+ LL_ADD_INTEGRATION_TEST(cppfeatures
+ ""
+ "${test_libs}"
+ )
LL_ADD_INTEGRATION_TEST(llsechandler_basic
llsechandler_basic.cpp
"${test_libs}"
diff --git a/indra/newview/VIEWER_VERSION.txt b/indra/newview/VIEWER_VERSION.txt
index 22beed373e..4c8366c864 100644
--- a/indra/newview/VIEWER_VERSION.txt
+++ b/indra/newview/VIEWER_VERSION.txt
@@ -1 +1 @@
-6.4.21
+6.4.23
diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index a2933b85a5..b1120c18b2 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -2076,17 +2076,6 @@
<key>Value</key>
<integer>1</integer>
</map>
- <key>BrowserPluginsEnabled</key>
- <map>
- <key>Comment</key>
- <string>Enable Web plugins in the built-in Web browser?</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Boolean</string>
- <key>Value</key>
- <integer>1</integer>
- </map>
<key>ChatBarCustomWidth</key>
<map>
<key>Comment</key>
@@ -14335,19 +14324,6 @@
<key>Value</key>
<integer>1</integer>
</map>
- <!-- SL-12594 removes fixed function rendering
- <key>VertexShaderEnable</key>
- <map>
- <key>Comment</key>
- <string>Enable/disable all GLSL shaders (debug)</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Boolean</string>
- <key>Value</key>
- <integer>0</integer>
- </map>
- <-->
<key>VivoxAutoPostCrashDumps</key>
<map>
<key>Comment</key>
@@ -14436,7 +14412,7 @@
<key>Value</key>
<integer>44125</integer>
</map>
-
+
<key>VivoxVadAuto</key>
<map>
<key>Comment</key>
@@ -14473,8 +14449,7 @@
<key>VivoxVadSensitivity</key>
<map>
<key>Comment</key>
- <string>
- A dimensionless value between 0 and 100, indicating the 'sensitivity of the VAD'. Increasing this value corresponds to decreasing the sensitivity of the VAD and 0 is turned off altogether</string>
+ <string>A dimensionless value between 0 and 100, indicating the 'sensitivity of the VAD'. Increasing this value corresponds to decreasing the sensitivity of the VAD and 0 is turned off altogether</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
diff --git a/indra/newview/featuretable.txt b/indra/newview/featuretable.txt
index e6ee458719..f1bf8d76c2 100644
--- a/indra/newview/featuretable.txt
+++ b/indra/newview/featuretable.txt
@@ -56,7 +56,6 @@ RenderVBOMappingDisable 1 1
RenderVolumeLODFactor 1 2.0
UseStartScreen 1 1
UseOcclusion 1 1
-VertexShaderEnable 1 1
WindLightUseAtmosShaders 1 1
WLSkyDetail 1 128
Disregard128DefaultDrawDistance 1 1
@@ -95,7 +94,6 @@ RenderTerrainLODFactor 1 1
RenderTransparentWater 1 0
RenderTreeLODFactor 1 0
RenderVolumeLODFactor 1 1.125
-VertexShaderEnable 1 0
WindLightUseAtmosShaders 1 0
RenderDeferred 1 0
RenderDeferredSSAO 1 0
@@ -127,7 +125,6 @@ RenderTerrainLODFactor 1 1
RenderTransparentWater 1 0
RenderTreeLODFactor 1 0
RenderVolumeLODFactor 1 1.125
-VertexShaderEnable 1 1
WindLightUseAtmosShaders 1 0
RenderDeferred 1 0
RenderDeferredSSAO 1 0
@@ -158,7 +155,6 @@ RenderTerrainLODFactor 1 1.0
RenderTransparentWater 1 1
RenderTreeLODFactor 1 0.5
RenderVolumeLODFactor 1 1.125
-VertexShaderEnable 1 1
WindLightUseAtmosShaders 1 0
RenderDeferred 1 0
RenderDeferredSSAO 1 0
@@ -189,7 +185,6 @@ RenderTerrainLODFactor 1 2.0
RenderTransparentWater 1 1
RenderTreeLODFactor 1 0.5
RenderVolumeLODFactor 1 1.125
-VertexShaderEnable 1 1
WindLightUseAtmosShaders 1 1
RenderDeferred 1 0
RenderDeferredSSAO 1 0
@@ -220,7 +215,6 @@ RenderTerrainLODFactor 1 2.0
RenderTransparentWater 1 1
RenderTreeLODFactor 1 0.5
RenderVolumeLODFactor 1 1.125
-VertexShaderEnable 1 1
WindLightUseAtmosShaders 1 1
RenderDeferred 1 1
RenderDeferredSSAO 1 0
@@ -251,7 +245,6 @@ RenderTerrainLODFactor 1 2.0
RenderTransparentWater 1 1
RenderTreeLODFactor 1 0.5
RenderVolumeLODFactor 1 1.125
-VertexShaderEnable 1 1
WindLightUseAtmosShaders 1 1
RenderDeferred 1 1
RenderDeferredSSAO 1 1
@@ -282,7 +275,6 @@ RenderTerrainLODFactor 1 2.0
RenderTransparentWater 1 1
RenderTreeLODFactor 1 0.5
RenderVolumeLODFactor 1 1.125
-VertexShaderEnable 1 1
WindLightUseAtmosShaders 1 1
RenderDeferred 1 1
RenderDeferredSSAO 1 1
@@ -312,7 +304,6 @@ RenderTerrainLODFactor 1 2.0
RenderTransparentWater 1 1
RenderTreeLODFactor 1 1.0
RenderVolumeLODFactor 1 2.0
-VertexShaderEnable 1 1
WindLightUseAtmosShaders 1 1
WLSkyDetail 1 128
RenderDeferred 1 1
@@ -380,7 +371,6 @@ list NoPixelShaders
RenderAvatarVP 0 0
RenderAvatarCloth 0 0
RenderReflectionDetail 0 0
-VertexShaderEnable 0 0
WindLightUseAtmosShaders 0 0
RenderDeferred 0 0
RenderDeferredSSAO 0 0
@@ -394,7 +384,6 @@ list NoVertexShaders
RenderAvatarVP 0 0
RenderAvatarCloth 0 0
RenderReflectionDetail 0 0
-VertexShaderEnable 0 0
WindLightUseAtmosShaders 0 0
RenderDeferred 0 0
RenderDeferredSSAO 0 0
diff --git a/indra/newview/featuretable_linux.txt b/indra/newview/featuretable_linux.txt
index bc836a99ca..5542eee6ca 100644
--- a/indra/newview/featuretable_linux.txt
+++ b/indra/newview/featuretable_linux.txt
@@ -56,7 +56,6 @@ RenderVBOMappingDisable 1 1
RenderVolumeLODFactor 1 2.0
UseStartScreen 1 1
UseOcclusion 1 1
-VertexShaderEnable 1 1
WindLightUseAtmosShaders 1 1
WLSkyDetail 1 128
Disregard128DefaultDrawDistance 1 1
@@ -94,7 +93,6 @@ RenderTerrainLODFactor 1 1
RenderTransparentWater 1 0
RenderTreeLODFactor 1 0
RenderVolumeLODFactor 1 1.125
-VertexShaderEnable 1 1
WindLightUseAtmosShaders 1 0
RenderDeferred 1 0
RenderDeferredSSAO 1 0
@@ -126,7 +124,6 @@ RenderTerrainLODFactor 1 1
RenderTransparentWater 1 0
RenderTreeLODFactor 1 0
RenderVolumeLODFactor 1 1.125
-VertexShaderEnable 1 0
WindLightUseAtmosShaders 1 0
RenderDeferred 1 0
RenderDeferredSSAO 1 0
@@ -157,7 +154,6 @@ RenderTerrainLODFactor 1 1.0
RenderTransparentWater 1 1
RenderTreeLODFactor 1 0.5
RenderVolumeLODFactor 1 1.125
-VertexShaderEnable 1 1
WindLightUseAtmosShaders 1 0
RenderDeferred 1 0
RenderDeferredSSAO 1 0
@@ -188,7 +184,6 @@ RenderTerrainLODFactor 1 2.0
RenderTransparentWater 1 1
RenderTreeLODFactor 1 0.5
RenderVolumeLODFactor 1 1.125
-VertexShaderEnable 1 1
WindLightUseAtmosShaders 1 1
RenderDeferred 1 0
RenderDeferredSSAO 1 0
@@ -219,7 +214,6 @@ RenderTerrainLODFactor 1 2.0
RenderTransparentWater 1 1
RenderTreeLODFactor 1 0.5
RenderVolumeLODFactor 1 1.125
-VertexShaderEnable 1 1
WindLightUseAtmosShaders 1 1
RenderDeferred 1 1
RenderUseAdvancedAtmospherics 1 0
@@ -250,7 +244,6 @@ RenderTerrainLODFactor 1 2.0
RenderTransparentWater 1 1
RenderTreeLODFactor 1 0.5
RenderVolumeLODFactor 1 1.125
-VertexShaderEnable 1 1
WindLightUseAtmosShaders 1 1
RenderDeferred 1 1
RenderDeferredSSAO 1 1
@@ -281,7 +274,6 @@ RenderTerrainLODFactor 1 2.0
RenderTransparentWater 1 1
RenderTreeLODFactor 1 0.5
RenderVolumeLODFactor 1 1.125
-VertexShaderEnable 1 1
WindLightUseAtmosShaders 1 1
RenderDeferred 1 1
RenderDeferredSSAO 1 1
@@ -311,7 +303,6 @@ RenderTerrainLODFactor 1 2.0
RenderTransparentWater 1 1
RenderTreeLODFactor 1 1.0
RenderVolumeLODFactor 1 2.0
-VertexShaderEnable 1 1
WindLightUseAtmosShaders 1 1
WLSkyDetail 1 128
RenderDeferred 1 1
@@ -379,7 +370,6 @@ list NoPixelShaders
RenderAvatarVP 0 0
RenderAvatarCloth 0 0
RenderReflectionDetail 0 0
-VertexShaderEnable 0 0
WindLightUseAtmosShaders 0 0
RenderDeferred 0 0
RenderDeferredSSAO 0 0
@@ -393,7 +383,6 @@ list NoVertexShaders
RenderAvatarVP 0 0
RenderAvatarCloth 0 0
RenderReflectionDetail 0 0
-VertexShaderEnable 0 0
WindLightUseAtmosShaders 0 0
RenderDeferred 0 0
RenderDeferredSSAO 0 0
diff --git a/indra/newview/featuretable_mac.txt b/indra/newview/featuretable_mac.txt
index 68202a571f..bac6fd5708 100644
--- a/indra/newview/featuretable_mac.txt
+++ b/indra/newview/featuretable_mac.txt
@@ -56,7 +56,6 @@ RenderVBOMappingDisable 1 1
RenderVolumeLODFactor 1 2.0
UseStartScreen 1 1
UseOcclusion 1 1
-VertexShaderEnable 1 1
WindLightUseAtmosShaders 1 1
WLSkyDetail 1 128
Disregard128DefaultDrawDistance 1 1
@@ -95,7 +94,6 @@ RenderTerrainLODFactor 1 1
RenderTransparentWater 1 0
RenderTreeLODFactor 1 0
RenderVolumeLODFactor 1 0.5
-VertexShaderEnable 1 0
WindLightUseAtmosShaders 1 0
RenderDeferred 1 0
RenderDeferredSSAO 1 0
@@ -127,7 +125,6 @@ RenderTerrainLODFactor 1 1
RenderTransparentWater 1 0
RenderTreeLODFactor 1 0
RenderVolumeLODFactor 1 0.5
-VertexShaderEnable 1 1
WindLightUseAtmosShaders 1 0
RenderDeferred 1 0
RenderDeferredSSAO 1 0
@@ -158,7 +155,6 @@ RenderTerrainLODFactor 1 1.0
RenderTransparentWater 1 1
RenderTreeLODFactor 1 0.5
RenderVolumeLODFactor 1 1.125
-VertexShaderEnable 1 1
WindLightUseAtmosShaders 1 0
RenderDeferred 1 0
RenderDeferredSSAO 1 0
@@ -189,7 +185,6 @@ RenderTerrainLODFactor 1 2.0
RenderTransparentWater 1 1
RenderTreeLODFactor 1 0.5
RenderVolumeLODFactor 1 1.125
-VertexShaderEnable 1 1
WindLightUseAtmosShaders 1 1
RenderDeferred 1 0
RenderDeferredSSAO 1 0
@@ -220,7 +215,6 @@ RenderTerrainLODFactor 1 2.0
RenderTransparentWater 1 1
RenderTreeLODFactor 1 0.5
RenderVolumeLODFactor 1 1.125
-VertexShaderEnable 1 1
WindLightUseAtmosShaders 1 1
RenderDeferred 1 1
RenderDeferredSSAO 1 0
@@ -251,7 +245,6 @@ RenderTerrainLODFactor 1 2.0
RenderTransparentWater 1 1
RenderTreeLODFactor 1 0.5
RenderVolumeLODFactor 1 1.125
-VertexShaderEnable 1 1
WindLightUseAtmosShaders 1 1
RenderDeferred 1 1
RenderDeferredSSAO 1 1
@@ -282,7 +275,6 @@ RenderTerrainLODFactor 1 2.0
RenderTransparentWater 1 1
RenderTreeLODFactor 1 0.5
RenderVolumeLODFactor 1 1.125
-VertexShaderEnable 1 1
WindLightUseAtmosShaders 1 1
RenderDeferred 1 1
RenderDeferredSSAO 1 1
@@ -312,7 +304,6 @@ RenderTerrainLODFactor 1 2.0
RenderTransparentWater 1 1
RenderTreeLODFactor 1 1.0
RenderVolumeLODFactor 1 2.0
-VertexShaderEnable 1 1
WindLightUseAtmosShaders 1 1
WLSkyDetail 1 128
RenderDeferred 1 1
@@ -374,7 +365,6 @@ list NoPixelShaders
RenderAvatarVP 0 0
RenderAvatarCloth 0 0
RenderReflectionDetail 0 0
-VertexShaderEnable 0 0
WindLightUseAtmosShaders 0 0
RenderDeferred 0 0
RenderDeferredSSAO 0 0
@@ -388,7 +378,6 @@ list NoVertexShaders
RenderAvatarVP 0 0
RenderAvatarCloth 0 0
RenderReflectionDetail 0 0
-VertexShaderEnable 0 0
WindLightUseAtmosShaders 0 0
RenderDeferred 0 0
RenderDeferredSSAO 0 0
diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp
index 3c50493d79..389448654a 100644
--- a/indra/newview/llagent.cpp
+++ b/indra/newview/llagent.cpp
@@ -108,7 +108,8 @@ const U8 AGENT_STATE_EDITING = 0x10;
// Autopilot constants
const F32 AUTOPILOT_HEIGHT_ADJUST_DISTANCE = 8.f; // meters
const F32 AUTOPILOT_MIN_TARGET_HEIGHT_OFF_GROUND = 1.f; // meters
-const F32 AUTOPILOT_MAX_TIME_NO_PROGRESS = 1.5f; // seconds
+const F32 AUTOPILOT_MAX_TIME_NO_PROGRESS_WALK = 1.5f; // seconds
+const F32 AUTOPILOT_MAX_TIME_NO_PROGRESS_FLY = 2.5f; // seconds. Flying is less presize, needs a bit more time
const F32 MAX_VELOCITY_AUTO_LAND_SQUARED = 4.f * 4.f;
const F64 CHAT_AGE_FAST_RATE = 3.0;
@@ -879,13 +880,12 @@ boost::signals2::connection LLAgent::addParcelChangedCallback(parcel_changed_cal
}
// static
-void LLAgent::capabilityReceivedCallback(const LLUUID &region_id)
+void LLAgent::capabilityReceivedCallback(const LLUUID &region_id, LLViewerRegion *regionp)
{
- LLViewerRegion* region = gAgent.getRegion();
- if (region && region->getRegionID() == region_id)
+ if (regionp && regionp->getRegionID() == region_id)
{
- region->requestSimulatorFeatures();
- LLAppViewer::instance()->updateNameLookupUrl();
+ regionp->requestSimulatorFeatures();
+ LLAppViewer::instance()->updateNameLookupUrl(regionp);
}
}
@@ -936,7 +936,7 @@ void LLAgent::setRegion(LLViewerRegion *regionp)
if (regionp->capabilitiesReceived())
{
regionp->requestSimulatorFeatures();
- LLAppViewer::instance()->updateNameLookupUrl();
+ LLAppViewer::instance()->updateNameLookupUrl(regionp);
}
else
{
@@ -962,11 +962,11 @@ void LLAgent::setRegion(LLViewerRegion *regionp)
if (regionp->capabilitiesReceived())
{
- LLAppViewer::instance()->updateNameLookupUrl();
+ LLAppViewer::instance()->updateNameLookupUrl(regionp);
}
else
{
- regionp->setCapabilitiesReceivedCallback([](const LLUUID &region_id) {LLAppViewer::instance()->updateNameLookupUrl(); });
+ regionp->setCapabilitiesReceivedCallback([](const LLUUID &region_id, LLViewerRegion* regionp) {LLAppViewer::instance()->updateNameLookupUrl(regionp); });
}
}
@@ -1563,6 +1563,12 @@ void LLAgent::startAutoPilotGlobal(
{
return;
}
+
+ if (target_global.isExactlyZero())
+ {
+ LL_WARNS() << "Canceling attempt to start autopilot towards invalid position" << LL_ENDL;
+ return;
+ }
// Are there any pending callbacks from previous auto pilot requests?
if (mAutoPilotFinishedCallback)
@@ -1778,7 +1784,16 @@ void LLAgent::autoPilot(F32 *delta_yaw)
if (target_dist >= mAutoPilotTargetDist)
{
mAutoPilotNoProgressFrameCount++;
- if (mAutoPilotNoProgressFrameCount > AUTOPILOT_MAX_TIME_NO_PROGRESS * gFPSClamped)
+ bool out_of_time = false;
+ if (getFlying())
+ {
+ out_of_time = mAutoPilotNoProgressFrameCount > AUTOPILOT_MAX_TIME_NO_PROGRESS_FLY * gFPSClamped;
+ }
+ else
+ {
+ out_of_time = mAutoPilotNoProgressFrameCount > AUTOPILOT_MAX_TIME_NO_PROGRESS_WALK * gFPSClamped;
+ }
+ if (out_of_time)
{
stopAutoPilot();
return;
@@ -1827,7 +1842,7 @@ void LLAgent::autoPilot(F32 *delta_yaw)
F32 slow_distance;
if (getFlying())
{
- slow_distance = llmax(6.f, mAutoPilotStopDistance + 5.f);
+ slow_distance = llmax(8.f, mAutoPilotStopDistance + 5.f);
}
else
{
@@ -1871,14 +1886,41 @@ void LLAgent::autoPilot(F32 *delta_yaw)
}
else if (mAutoPilotTargetDist > mAutoPilotStopDistance)
{
- // walking/flying slow
+ // walking/flying slow
+ U32 movement_flag = 0;
+
if (at * direction > 0.9f)
{
- setControlFlags(AGENT_CONTROL_AT_POS);
- }
- else if (at * direction < -0.9f)
- {
- setControlFlags(AGENT_CONTROL_AT_NEG);
+ movement_flag = AGENT_CONTROL_AT_POS;
+ }
+ else if (at * direction < -0.9f)
+ {
+ movement_flag = AGENT_CONTROL_AT_NEG;
+ }
+
+ if (getFlying())
+ {
+ // flying is too fast and has high inertia, artificially slow it down
+ // Don't update flags too often, server might not react
+ static U64 last_time_microsec = 0;
+ U64 time_microsec = LLTimer::getTotalTime();
+ U64 delta = time_microsec - last_time_microsec;
+ // fly during ~0-40 ms, stop during ~40-250 ms
+ if (delta > 250000) // 250ms
+ {
+ // reset even if !movement_flag
+ last_time_microsec = time_microsec;
+ }
+ else if (delta > 40000) // 40 ms
+ {
+ clearControlFlags(AGENT_CONTROL_AT_POS | AGENT_CONTROL_AT_POS);
+ movement_flag = 0;
+ }
+ }
+
+ if (movement_flag)
+ {
+ setControlFlags(movement_flag);
}
}
diff --git a/indra/newview/llagent.h b/indra/newview/llagent.h
index a792d3e11f..134540c6b3 100644
--- a/indra/newview/llagent.h
+++ b/indra/newview/llagent.h
@@ -254,7 +254,7 @@ public:
boost::signals2::connection addParcelChangedCallback(parcel_changed_callback_t);
private:
- static void capabilityReceivedCallback(const LLUUID &region_id);
+ static void capabilityReceivedCallback(const LLUUID &region_id, LLViewerRegion *regionp);
typedef boost::signals2::signal<void()> parcel_changed_signal_t;
parcel_changed_signal_t mParcelChangedSignal;
diff --git a/indra/newview/llappcorehttp.cpp b/indra/newview/llappcorehttp.cpp
index 134a34137b..3da87e657c 100644
--- a/indra/newview/llappcorehttp.cpp
+++ b/indra/newview/llappcorehttp.cpp
@@ -116,6 +116,7 @@ static const struct
};
static void setting_changed();
+static void ssl_verification_changed();
LLAppCoreHttp::HttpClass::HttpClass()
@@ -195,6 +196,23 @@ void LLAppCoreHttp::init()
LL_WARNS("Init") << "Failed to set SSL Verification. Reason: " << status.toString() << LL_ENDL;
}
+ // Set up Default SSL Verification option.
+ const std::string no_verify_ssl("NoVerifySSLCert");
+ if (gSavedSettings.controlExists(no_verify_ssl))
+ {
+ LLPointer<LLControlVariable> cntrl_ptr = gSavedSettings.getControl(no_verify_ssl);
+ if (cntrl_ptr.isNull())
+ {
+ LL_WARNS("Init") << "Unable to set signal on global setting '" << no_verify_ssl
+ << "'" << LL_ENDL;
+ }
+ else
+ {
+ mSSLNoVerifySignal = cntrl_ptr->getCommitSignal()->connect(boost::bind(&ssl_verification_changed));
+ LLCore::HttpOptions::setDefaultSSLVerifyPeer(!cntrl_ptr->getValue().asBoolean());
+ }
+ }
+
// Tracing levels for library & libcurl (note that 2 & 3 are beyond spammy):
// 0 - None
// 1 - Basic start, stop simple transitions
@@ -296,6 +314,11 @@ void setting_changed()
LLAppViewer::instance()->getAppCoreHttp().refreshSettings(false);
}
+void ssl_verification_changed()
+{
+ LLCore::HttpOptions::setDefaultSSLVerifyPeer(!gSavedSettings.getBOOL("NoVerifySSLCert"));
+}
+
namespace
{
// The NoOpDeletor is used when wrapping LLAppCoreHttp in a smart pointer below for
@@ -355,6 +378,7 @@ void LLAppCoreHttp::cleanup()
{
mHttpClasses[i].mSettingsSignal.disconnect();
}
+ mSSLNoVerifySignal.disconnect();
mPipelinedSignal.disconnect();
delete mRequest;
diff --git a/indra/newview/llappcorehttp.h b/indra/newview/llappcorehttp.h
index 95c138d598..751c498ab0 100644
--- a/indra/newview/llappcorehttp.h
+++ b/indra/newview/llappcorehttp.h
@@ -256,6 +256,7 @@ private:
HttpClass mHttpClasses[AP_COUNT];
bool mPipelined; // Global setting
boost::signals2::connection mPipelinedSignal; // Signal for 'HttpPipelining' setting
+ boost::signals2::connection mSSLNoVerifySignal; // Signal for 'NoVerifySSLCert' setting
static LLCore::HttpStatus sslVerify(const std::string &uri, const LLCore::HttpHandler::ptr_t &handler, void *appdata);
};
diff --git a/indra/newview/llappdelegate-objc.mm b/indra/newview/llappdelegate-objc.mm
index 3f1b5139c5..aeb3294f53 100644
--- a/indra/newview/llappdelegate-objc.mm
+++ b/indra/newview/llappdelegate-objc.mm
@@ -66,6 +66,7 @@
constructViewer();
#if defined(LL_BUGSPLAT)
+ infos("bugsplat setup");
// Engage BugsplatStartupManager *before* calling initViewer() to handle
// any crashes during initialization.
// https://www.bugsplat.com/docs/platforms/os-x#initialization
@@ -74,6 +75,7 @@
[BugsplatStartupManager sharedManager].delegate = self;
[[BugsplatStartupManager sharedManager] start];
#endif
+ infos("post-bugsplat setup");
frameTimer = nil;
@@ -301,9 +303,13 @@ struct AttachmentInfo
// We "happen to know" that info[0].basename is "SecondLife.old" -- due to
// the fact that BugsplatMac only notices a crash during the viewer run
- // following the crash. Replace .old with .log to reduce confusion.
+ // following the crash.
+ // The Bugsplat service doesn't respect the MIME type above when returning
+ // the log data to a browser, so take this opportunity to rename the file
+ // from <base>.old to <base>_log.txt
info[0].basename =
- boost::filesystem::path(info[0].pathname).stem().string() + ".log";
+ boost::filesystem::path(info[0].pathname).stem().string() + "_log.txt";
+ infos("attachmentsForBugsplatStartupManager attaching log " + info[0].basename);
NSMutableArray *attachments = [[NSMutableArray alloc] init];
diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp
index e8a3305645..9fc2e9ead8 100644
--- a/indra/newview/llappearancemgr.cpp
+++ b/indra/newview/llappearancemgr.cpp
@@ -3626,7 +3626,7 @@ void LLAppearanceMgr::serverAppearanceUpdateCoro(LLCoreHttpUtil::HttpCoroutineAd
}
llcoro::suspend();
- if (LLApp::isQuitting())
+ if (LLApp::isExiting())
{
return;
}
@@ -3693,7 +3693,7 @@ void LLAppearanceMgr::serverAppearanceUpdateCoro(LLCoreHttpUtil::HttpCoroutineAd
LLSD result = httpAdapter->postAndSuspend(httpRequest, url, postData);
- if (LLApp::isQuitting())
+ if (LLApp::isExiting())
{
return;
}
@@ -3733,7 +3733,7 @@ void LLAppearanceMgr::serverAppearanceUpdateCoro(LLCoreHttpUtil::HttpCoroutineAd
LL_WARNS("Avatar") << "Bake retry #" << retryCount << " in " << timeout << " seconds." << LL_ENDL;
llcoro::suspendUntilTimeout(timeout);
- if (LLApp::isQuitting())
+ if (LLApp::isExiting())
{
return;
}
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index 91d9980639..72eb344ded 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -730,14 +730,14 @@ LLAppViewer::LLAppViewer()
// from the previous viewer run between this constructor call and the
// init() call, which will overwrite the static_debug_info.log file for
// THIS run. So setDebugFileNames() early.
-#if LL_BUGSPLAT
+# ifdef LL_BUGSPLAT
// MAINT-8917: don't create a dump directory just for the
// static_debug_info.log file
std::string logdir = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "");
-#else // ! LL_BUGSPLAT
+# else // ! LL_BUGSPLAT
// write Google Breakpad minidump files to a per-run dump directory to avoid multiple viewer issues.
std::string logdir = gDirUtilp->getExpandedFilename(LL_PATH_DUMP, "");
-#endif // ! LL_BUGSPLAT
+# endif // ! LL_BUGSPLAT
mDumpPath = logdir;
setDebugFileNames(logdir);
@@ -762,17 +762,6 @@ public:
}
};
-namespace {
-// With Xcode 6, _exit() is too magical to use with boost::bind(), so provide
-// this little helper function.
-void fast_exit(int rc)
-{
- _exit(rc);
-}
-
-
-}
-
bool LLAppViewer::init()
{
@@ -824,9 +813,9 @@ bool LLAppViewer::init()
if (rc >= 0)
{
// QAModeTermCode set, terminate with that rc on LL_ERRS. Use
- // fast_exit() rather than exit() because normal cleanup depends too
+ // _exit() rather than exit() because normal cleanup depends too
// much on successful startup!
- LLError::setFatalFunction(boost::bind(fast_exit, rc));
+ LLError::setFatalFunction([rc](const std::string&){ _exit(rc); });
}
mAlloc.setProfilingEnabled(gSavedSettings.getBOOL("MemProfiling"));
@@ -2196,28 +2185,6 @@ bool LLAppViewer::cleanup()
return true;
}
-// A callback for LL_ERRS() to call during the watchdog error.
-void watchdog_llerrs_callback(const std::string &error_string)
-{
- gLLErrorActivated = true;
-
- gDebugInfo["FatalMessage"] = error_string;
- LLAppViewer::instance()->writeDebugInfo();
-
-#ifdef LL_WINDOWS
- RaiseException(0,0,0,0);
-#else
- raise(SIGQUIT);
-#endif
-}
-
-// A callback for the watchdog to call.
-void watchdog_killer_callback()
-{
- LLError::setFatalFunction(watchdog_llerrs_callback);
- LL_ERRS() << "Watchdog killer event" << LL_ENDL;
-}
-
bool LLAppViewer::initThreads()
{
static const bool enable_threads = true;
@@ -2252,24 +2219,23 @@ bool LLAppViewer::initThreads()
return true;
}
-void errorCallback(const std::string &error_string)
+void errorCallback(LLError::ELevel level, const std::string &error_string)
{
+ if (level == LLError::LEVEL_ERROR)
+ {
#ifndef LL_RELEASE_FOR_DOWNLOAD
- OSMessageBox(error_string, LLTrans::getString("MBFatalError"), OSMB_OK);
+ OSMessageBox(error_string, LLTrans::getString("MBFatalError"), OSMB_OK);
#endif
- //Set the ErrorActivated global so we know to create a marker file
- gLLErrorActivated = true;
+ //Set the ErrorActivated global so we know to create a marker file
+ gLLErrorActivated = true;
- gDebugInfo["FatalMessage"] = error_string;
- // We're not already crashing -- we simply *intend* to crash. Since we
- // haven't actually trashed anything yet, we can afford to write the whole
- // static info file.
- LLAppViewer::instance()->writeDebugInfo();
-
-#ifndef SHADER_CRASH_NONFATAL
- LLError::crashAndLoop(error_string);
-#endif
+ gDebugInfo["FatalMessage"] = error_string;
+ // We're not already crashing -- we simply *intend* to crash. Since we
+ // haven't actually trashed anything yet, we can afford to write the whole
+ // static info file.
+ LLAppViewer::instance()->writeDebugInfo();
+ }
}
void LLAppViewer::initLoggingAndGetLastDuration()
@@ -2280,7 +2246,7 @@ void LLAppViewer::initLoggingAndGetLastDuration()
LLError::initForApplication( gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, "")
,gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "")
);
- LLError::setFatalFunction(errorCallback);
+ LLError::addGenericRecorder(&errorCallback);
//LLError::setTimeFunction(getRuntime);
// Remove the last ".old" log file.
@@ -3039,11 +3005,16 @@ bool LLAppViewer::initWindow()
use_watchdog = bool(watchdog_enabled_setting);
}
+ LL_INFOS("AppInit") << "watchdog"
+ << (use_watchdog ? " " : " NOT ")
+ << "enabled"
+ << " (setting = " << watchdog_enabled_setting << ")"
+ << LL_ENDL;
+
if (use_watchdog)
{
- LLWatchdog::getInstance()->init(watchdog_killer_callback);
+ LLWatchdog::getInstance()->init();
}
- LL_INFOS("AppInit") << "watchdog setting is done." << LL_ENDL;
LLNotificationsUI::LLNotificationManager::getInstance();
@@ -3476,8 +3447,8 @@ void LLAppViewer::writeSystemInfo()
gDebugInfo["CPUInfo"]["CPUSSE"] = gSysCPU.hasSSE();
gDebugInfo["CPUInfo"]["CPUSSE2"] = gSysCPU.hasSSE2();
- gDebugInfo["RAMInfo"]["Physical"] = (LLSD::Integer)(gSysMemory.getPhysicalMemoryKB().value());
- gDebugInfo["RAMInfo"]["Allocated"] = (LLSD::Integer)(gMemoryAllocated.valueInUnits<LLUnits::Kilobytes>());
+ gDebugInfo["RAMInfo"]["Physical"] = LLSD::Integer(gSysMemory.getPhysicalMemoryKB().value());
+ gDebugInfo["RAMInfo"]["Allocated"] = LLSD::Integer(gMemoryAllocated.valueInUnits<LLUnits::Kilobytes>());
gDebugInfo["OSInfo"] = LLOSInfo::instance().getOSStringSimple();
// The user is not logged on yet, but record the current grid choice login url
@@ -3490,12 +3461,18 @@ void LLAppViewer::writeSystemInfo()
gDebugInfo["MainloopThreadID"] = (S32)thread_id;
#endif
+#ifndef LL_BUGSPLAT
// "CrashNotHandled" is set here, while things are running well,
// in case of a freeze. If there is a freeze, the crash logger will be launched
// and can read this value from the debug_info.log.
// If the crash is handled by LLAppViewer::handleViewerCrash, ie not a freeze,
// then the value of "CrashNotHandled" will be set to true.
- gDebugInfo["CrashNotHandled"] = (LLSD::Boolean)true;
+ gDebugInfo["CrashNotHandled"] = LLSD::Boolean(true);
+#else // LL_BUGSPLAT
+ // "CrashNotHandled" is obsolete; it used (not very successsfully)
+ // to try to distinguish crashes from freezes - the intent here to to avoid calling it a freeze
+ gDebugInfo["CrashNotHandled"] = LLSD::Boolean(false);
+#endif // ! LL_BUGSPLAT
// Insert crash host url (url to post crash log to) if configured. This insures
// that the crash report will go to the proper location in the case of a
@@ -3526,7 +3503,7 @@ void LLAppViewer::writeSystemInfo()
gDebugInfo["SettingsFilename"] = gSavedSettings.getString("ClientSettingsFile");
gDebugInfo["ViewerExePath"] = gDirUtilp->getExecutablePathAndName();
gDebugInfo["CurrentPath"] = gDirUtilp->getCurPath();
- gDebugInfo["FirstLogin"] = (LLSD::Boolean) gAgent.isFirstLogin();
+ gDebugInfo["FirstLogin"] = LLSD::Boolean(gAgent.isFirstLogin());
gDebugInfo["FirstRunThisInstall"] = gSavedSettings.getBOOL("FirstRunThisInstall");
gDebugInfo["StartupState"] = LLStartUp::getStartupStateString();
@@ -3656,7 +3633,7 @@ void LLAppViewer::handleViewerCrash()
// The crash is being handled here so set this value to false.
// Otherwise the crash logger will think this crash was a freeze.
- gDebugInfo["Dynamic"]["CrashNotHandled"] = (LLSD::Boolean)false;
+ gDebugInfo["Dynamic"]["CrashNotHandled"] = LLSD::Boolean(false);
//Write out the crash status file
//Use marker file style setup, as that's the simplest, especially since
@@ -3729,6 +3706,8 @@ void LLAppViewer::handleViewerCrash()
if (LLWorld::instanceExists()) LLWorld::getInstance()->getInfo(gDebugInfo["Dynamic"]);
+ gDebugInfo["FatalMessage"] = LLError::getFatalMessage();
+
// Close the debug file
pApp->writeDebugInfo(false); //false answers the isStatic question with the least overhead.
}
@@ -3827,9 +3806,8 @@ void LLAppViewer::processMarkerFiles()
else if (marker_is_same_version)
{
// the file existed, is ours, and matched our version, so we can report on what it says
- LL_INFOS("MarkerFile") << "Exec marker '"<< mMarkerFileName << "' found; last exec FROZE" << LL_ENDL;
- gLastExecEvent = LAST_EXEC_FROZE;
-
+ LL_INFOS("MarkerFile") << "Exec marker '"<< mMarkerFileName << "' found; last exec crashed" << LL_ENDL;
+ gLastExecEvent = LAST_EXEC_OTHER_CRASH;
}
else
{
@@ -5373,10 +5351,9 @@ void LLAppViewer::sendLogoutRequest()
}
}
-void LLAppViewer::updateNameLookupUrl()
+void LLAppViewer::updateNameLookupUrl(const LLViewerRegion * regionp)
{
- LLViewerRegion* region = gAgent.getRegion();
- if (!region || !region->capabilitiesReceived())
+ if (!regionp || !regionp->capabilitiesReceived())
{
return;
}
@@ -5385,7 +5362,7 @@ void LLAppViewer::updateNameLookupUrl()
bool had_capability = LLAvatarNameCache::getInstance()->hasNameLookupURL();
std::string name_lookup_url;
name_lookup_url.reserve(128); // avoid a memory allocation below
- name_lookup_url = region->getCapability("GetDisplayNames");
+ name_lookup_url = regionp->getCapability("GetDisplayNames");
bool have_capability = !name_lookup_url.empty();
if (have_capability)
{
@@ -5696,6 +5673,33 @@ void LLAppViewer::forceErrorDriverCrash()
glDeleteTextures(1, NULL);
}
+void LLAppViewer::forceErrorCoroutineCrash()
+{
+ LL_WARNS() << "Forcing a crash in LLCoros" << LL_ENDL;
+ LLCoros::instance().launch("LLAppViewer::crashyCoro", [] {throw LLException("A deliberate crash from LLCoros"); });
+}
+
+void LLAppViewer::forceErrorThreadCrash()
+{
+ class LLCrashTestThread : public LLThread
+ {
+ public:
+
+ LLCrashTestThread() : LLThread("Crash logging test thread")
+ {
+ }
+
+ void run()
+ {
+ LL_ERRS() << "This is a deliberate llerror in thread" << LL_ENDL;
+ }
+ };
+
+ LL_WARNS() << "This is a deliberate crash in a thread" << LL_ENDL;
+ LLCrashTestThread *thread = new LLCrashTestThread();
+ thread->start();
+}
+
void LLAppViewer::initMainloopTimeout(const std::string& state, F32 secs)
{
if(!mMainloopTimeout)
@@ -5739,11 +5743,6 @@ void LLAppViewer::pauseMainloopTimeout()
void LLAppViewer::pingMainloopTimeout(const std::string& state, F32 secs)
{
-// if(!restoreErrorTrap())
-// {
-// LL_WARNS() << "!!!!!!!!!!!!! Its an error trap!!!!" << state << LL_ENDL;
-// }
-
if(mMainloopTimeout)
{
if(secs < 0.0f)
diff --git a/indra/newview/llappviewer.h b/indra/newview/llappviewer.h
index e9c467bd01..95f6efa29a 100644
--- a/indra/newview/llappviewer.h
+++ b/indra/newview/llappviewer.h
@@ -57,6 +57,7 @@ class LLImageDecodeThread;
class LLTextureFetch;
class LLWatchdogTimeout;
class LLViewerJoystick;
+class LLViewerRegion;
extern LLTrace::BlockTimerStatHandle FTM_FRAME;
@@ -149,6 +150,8 @@ public:
virtual void forceErrorInfiniteLoop();
virtual void forceErrorSoftwareException();
virtual void forceErrorDriverCrash();
+ virtual void forceErrorCoroutineCrash();
+ virtual void forceErrorThreadCrash();
// The list is found in app_settings/settings_files.xml
// but since they are used explicitly in code,
@@ -208,7 +211,7 @@ public:
// llcorehttp init/shutdown/config information.
LLAppCoreHttp & getAppCoreHttp() { return mAppCoreHttp; }
- void updateNameLookupUrl();
+ void updateNameLookupUrl(const LLViewerRegion* regionp);
protected:
virtual bool initWindow(); // Initialize the viewer's window.
diff --git a/indra/newview/llappviewermacosx.cpp b/indra/newview/llappviewermacosx.cpp
index 862e2b45df..aa932f9c89 100644
--- a/indra/newview/llappviewermacosx.cpp
+++ b/indra/newview/llappviewermacosx.cpp
@@ -68,39 +68,21 @@ namespace
int gArgC;
char** gArgV;
LLAppViewerMacOSX* gViewerAppPtr = NULL;
-
- void (*gOldTerminateHandler)() = NULL;
std::string gHandleSLURL;
}
-static void exceptionTerminateHandler()
-{
- // reinstall default terminate() handler in case we re-terminate.
- if (gOldTerminateHandler) std::set_terminate(gOldTerminateHandler);
- // treat this like a regular viewer crash, with nice stacktrace etc.
- long *null_ptr;
- null_ptr = 0;
- *null_ptr = 0xDEADBEEF; //Force an exception that will trigger breakpad.
- //LLAppViewer::handleViewerCrash();
- // we've probably been killed-off before now, but...
- gOldTerminateHandler(); // call old terminate() handler
-}
-
void constructViewer()
{
// Set the working dir to <bundle>/Contents/Resources
if (chdir(gDirUtilp->getAppRODataDir().c_str()) == -1)
{
- LL_WARNS() << "Could not change directory to "
+ LL_WARNS("InitOSX") << "Could not change directory to "
<< gDirUtilp->getAppRODataDir() << ": " << strerror(errno)
<< LL_ENDL;
}
gViewerAppPtr = new LLAppViewerMacOSX();
- // install unexpected exception handler
- gOldTerminateHandler = std::set_terminate(exceptionTerminateHandler);
-
gViewerAppPtr->setErrorHandler(LLAppViewer::handleViewerCrash);
}
@@ -109,7 +91,7 @@ bool initViewer()
bool ok = gViewerAppPtr->init();
if(!ok)
{
- LL_WARNS() << "Application init failed." << LL_ENDL;
+ LL_WARNS("InitOSX") << "Application init failed." << LL_ENDL;
}
else if (!gHandleSLURL.empty())
{
@@ -172,7 +154,7 @@ class CrashMetadataSingleton: public CrashMetadata, public LLSingleton<CrashMeta
std::string get_metadata(const LLSD& info, const LLSD::String& key) const
{
std::string data(info[key].asString());
- LL_INFOS() << " " << key << "='" << data << "'" << LL_ENDL;
+ LL_INFOS("Bugsplat") << " " << key << "='" << data << "'" << LL_ENDL;
return data;
}
};
@@ -188,22 +170,22 @@ CrashMetadataSingleton::CrashMetadataSingleton()
LLSD info;
if (! static_file.is_open())
{
- LL_INFOS() << "Can't open '" << staticDebugPathname
+ LL_WARNS("Bugsplat") << "Can't open '" << staticDebugPathname
<< "'; no metadata about previous run" << LL_ENDL;
}
else if (! LLSDSerialize::deserialize(info, static_file, LLSDSerialize::SIZE_UNLIMITED))
{
- LL_INFOS() << "Can't parse '" << staticDebugPathname
+ LL_WARNS("Bugsplat") << "Can't parse '" << staticDebugPathname
<< "'; no metadata about previous run" << LL_ENDL;
}
else
{
- LL_INFOS() << "Metadata from '" << staticDebugPathname << "':" << LL_ENDL;
- logFilePathname = get_metadata(info, "SLLog");
- userSettingsPathname = get_metadata(info, "SettingsFilename");
+ LL_INFOS("Bugsplat") << "Previous run metadata from '" << staticDebugPathname << "':" << LL_ENDL;
+ logFilePathname = get_metadata(info, "SLLog");
+ userSettingsPathname = get_metadata(info, "SettingsFilename");
accountSettingsPathname = get_metadata(info, "PerAccountSettingsFilename");
- OSInfo = get_metadata(info, "OSInfo");
- agentFullname = get_metadata(info, "LoginName");
+ OSInfo = get_metadata(info, "OSInfo");
+ agentFullname = get_metadata(info, "LoginName");
// Translate underscores back to spaces
LLStringUtil::replaceChar(agentFullname, '_', ' ');
regionName = get_metadata(info, "CurrentRegion");
@@ -219,7 +201,7 @@ CrashMetadata& CrashMetadata_instance()
void infos(const std::string& message)
{
- LL_INFOS() << message << LL_ENDL;
+ LL_INFOS("InitOSX", "Bugsplat") << message << LL_ENDL;
}
int main( int argc, char **argv )
@@ -324,11 +306,12 @@ bool LLAppViewerMacOSX::restoreErrorTrap()
unsigned int reset_count = 0;
-#define SET_SIG(S) sigaction(SIGABRT, &act, &old_act); \
- if(act.sa_sigaction != old_act.sa_sigaction) \
- ++reset_count;
+#define SET_SIG(SIGNAL) sigaction(SIGNAL, &act, &old_act); \
+ if(act.sa_sigaction != old_act.sa_sigaction) ++reset_count;
// Synchronous signals
- SET_SIG(SIGABRT)
+# ifndef LL_BUGSPLAT
+ SET_SIG(SIGABRT) // let bugsplat catch this
+# endif
SET_SIG(SIGALRM)
SET_SIG(SIGBUS)
SET_SIG(SIGFPE)
@@ -366,7 +349,8 @@ std::string LLAppViewerMacOSX::generateSerialNumber()
CFStringRef serialNumber = NULL;
io_service_t platformExpert = IOServiceGetMatchingService(kIOMasterPortDefault,
IOServiceMatching("IOPlatformExpertDevice"));
- if (platformExpert) {
+ if (platformExpert)
+ {
serialNumber = (CFStringRef) IORegistryEntryCreateCFProperty(platformExpert,
CFSTR(kIOPlatformSerialNumberKey),
kCFAllocatorDefault, 0);
diff --git a/indra/newview/llappviewerwin32.cpp b/indra/newview/llappviewerwin32.cpp
index f0bede5321..25d18fa11f 100644
--- a/indra/newview/llappviewerwin32.cpp
+++ b/indra/newview/llappviewerwin32.cpp
@@ -177,7 +177,7 @@ static void exceptionTerminateHandler()
long *null_ptr;
null_ptr = 0;
*null_ptr = 0xDEADBEEF; //Force an exception that will trigger breakpad.
- //LLAppViewer::handleViewerCrash();
+
// we've probably been killed-off before now, but...
gOldTerminateHandler(); // call old terminate() handler
}
@@ -365,10 +365,6 @@ int APIENTRY WINMAIN(HINSTANCE hInstance,
viewer_app_ptr->setErrorHandler(LLAppViewer::handleViewerCrash);
-#if LL_SEND_CRASH_REPORTS
- // ::SetUnhandledExceptionFilter(catchallCrashHandler);
-#endif
-
// Set a debug info flag to indicate if multiple instances are running.
bool found_other_instance = !create_app_mutex();
gDebugInfo["FoundOtherInstanceAtStartup"] = LLSD::Boolean(found_other_instance);
@@ -606,6 +602,13 @@ bool LLAppViewerWin32::init()
#else // LL_BUGSPLAT
#pragma message("Building with BugSplat")
+ if (!isSecondInstance())
+ {
+ // Cleanup previous session
+ std::string log_file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "bugsplat.log");
+ LLFile::remove(log_file, ENOENT);
+ }
+
std::string build_data_fname(
gDirUtilp->getExpandedFilename(LL_PATH_EXECUTABLE, "build_data.json"));
// Use llifstream instead of std::ifstream because LL_PATH_EXECUTABLE
@@ -613,7 +616,7 @@ bool LLAppViewerWin32::init()
llifstream inf(build_data_fname.c_str());
if (! inf.is_open())
{
- LL_WARNS() << "Can't initialize BugSplat, can't read '" << build_data_fname
+ LL_WARNS("BUGSPLAT") << "Can't initialize BugSplat, can't read '" << build_data_fname
<< "'" << LL_ENDL;
}
else
@@ -623,7 +626,7 @@ bool LLAppViewerWin32::init()
if (! reader.parse(inf, build_data, false)) // don't collect comments
{
// gah, the typo is baked into Json::Reader API
- LL_WARNS() << "Can't initialize BugSplat, can't parse '" << build_data_fname
+ LL_WARNS("BUGSPLAT") << "Can't initialize BugSplat, can't parse '" << build_data_fname
<< "': " << reader.getFormatedErrorMessages() << LL_ENDL;
}
else
@@ -631,7 +634,7 @@ bool LLAppViewerWin32::init()
Json::Value BugSplat_DB = build_data["BugSplat DB"];
if (! BugSplat_DB)
{
- LL_WARNS() << "Can't initialize BugSplat, no 'BugSplat DB' entry in '"
+ LL_WARNS("BUGSPLAT") << "Can't initialize BugSplat, no 'BugSplat DB' entry in '"
<< build_data_fname << "'" << LL_ENDL;
}
else
@@ -642,18 +645,35 @@ bool LLAppViewerWin32::init()
LL_VIEWER_VERSION_PATCH << '.' <<
LL_VIEWER_VERSION_BUILD));
+ DWORD dwFlags = MDSF_NONINTERACTIVE | // automatically submit report without prompting
+ MDSF_PREVENTHIJACKING; // disallow swiping Exception filter
+
+ bool needs_log_file = !isSecondInstance() && debugLoggingEnabled("BUGSPLAT");
+ if (needs_log_file)
+ {
+ // Startup only!
+ LL_INFOS("BUGSPLAT") << "Engaged BugSplat logging to bugsplat.log" << LL_ENDL;
+ dwFlags |= MDSF_LOGFILE | MDSF_LOG_VERBOSE;
+ }
+
// have to convert normal wide strings to strings of __wchar_t
sBugSplatSender = new MiniDmpSender(
WCSTR(BugSplat_DB.asString()),
WCSTR(LL_TO_WSTRING(LL_VIEWER_CHANNEL)),
WCSTR(version_string),
nullptr, // szAppIdentifier -- set later
- MDSF_NONINTERACTIVE | // automatically submit report without prompting
- MDSF_PREVENTHIJACKING); // disallow swiping Exception filter
+ dwFlags);
sBugSplatSender->setCallback(bugsplatSendLog);
+ if (needs_log_file)
+ {
+ // Log file will be created in %TEMP%, but it will be moved into logs folder in case of crash
+ std::string log_file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "bugsplat.log");
+ sBugSplatSender->setLogFilePath(WCSTR(log_file));
+ }
+
// engage stringize() overload that converts from wstring
- LL_INFOS() << "Engaged BugSplat(" << LL_TO_STRING(LL_VIEWER_CHANNEL)
+ LL_INFOS("BUGSPLAT") << "Engaged BugSplat(" << LL_TO_STRING(LL_VIEWER_CHANNEL)
<< ' ' << stringize(version_string) << ')' << LL_ENDL;
} // got BugSplat_DB
} // parsed build_data.json
@@ -682,6 +702,16 @@ bool LLAppViewerWin32::cleanup()
return result;
}
+void LLAppViewerWin32::reportCrashToBugsplat(void* pExcepInfo)
+{
+#if defined(LL_BUGSPLAT)
+ if (sBugSplatSender)
+ {
+ sBugSplatSender->createReport((EXCEPTION_POINTERS*)pExcepInfo);
+ }
+#endif // LL_BUGSPLAT
+}
+
void LLAppViewerWin32::initLoggingAndGetLastDuration()
{
LLAppViewer::initLoggingAndGetLastDuration();
@@ -810,8 +840,7 @@ bool LLAppViewerWin32::beingDebugged()
bool LLAppViewerWin32::restoreErrorTrap()
{
- return true;
- //return LLWinDebug::checkExceptionHandler();
+ return true; // we don't check for handler collisions on windows, so just say they're ok
}
//virtual
diff --git a/indra/newview/llappviewerwin32.h b/indra/newview/llappviewerwin32.h
index 2699224e58..82b6b0c77c 100644
--- a/indra/newview/llappviewerwin32.h
+++ b/indra/newview/llappviewerwin32.h
@@ -40,19 +40,21 @@ public:
//
// Main application logic
//
- virtual bool init(); // Override to do application initialization
- virtual bool cleanup();
+ bool init() override; // Override to do application initialization
+ bool cleanup() override;
+
+ void reportCrashToBugsplat(void* pExcepInfo) override;
protected:
- virtual void initLoggingAndGetLastDuration(); // Override to clean stack_trace info.
- virtual void initConsole(); // Initialize OS level debugging console.
- virtual bool initHardwareTest(); // Win32 uses DX9 to test hardware.
- virtual bool initParseCommandLine(LLCommandLineParser& clp);
+ void initLoggingAndGetLastDuration() override; // Override to clean stack_trace info.
+ void initConsole() override; // Initialize OS level debugging console.
+ bool initHardwareTest() override; // Win32 uses DX9 to test hardware.
+ bool initParseCommandLine(LLCommandLineParser& clp) override;
virtual bool beingDebugged();
virtual bool restoreErrorTrap();
- virtual bool sendURLToOtherInstance(const std::string& url);
+ bool sendURLToOtherInstance(const std::string& url) override;
std::string generateSerialNumber();
diff --git a/indra/newview/llcompilequeue.cpp b/indra/newview/llcompilequeue.cpp
index 3aaaaf52f5..bf10a9f2b4 100644
--- a/indra/newview/llcompilequeue.cpp
+++ b/indra/newview/llcompilequeue.cpp
@@ -347,7 +347,7 @@ void LLFloaterCompileQueue::processExperienceIdResults(LLSD result, LLUUID paren
bool LLFloaterCompileQueue::processScript(LLHandle<LLFloaterCompileQueue> hfloater,
const LLPointer<LLViewerObject> &object, LLInventoryObject* inventory, LLEventPump &pump)
{
- if (LLApp::isQuitting())
+ if (LLApp::isExiting())
{
// Reply from coroutine came on shutdown
// We are quiting, don't start any more coroutines!
diff --git a/indra/newview/lldelayedgestureerror.cpp b/indra/newview/lldelayedgestureerror.cpp
index ef1b644ad4..934a38bb8e 100644
--- a/indra/newview/lldelayedgestureerror.cpp
+++ b/indra/newview/lldelayedgestureerror.cpp
@@ -113,7 +113,7 @@ bool LLDelayedGestureError::doDialog(const LLErrorEntry &ent, bool uuid_ok)
}
}
- if(!LLApp::isQuitting())
+ if(!LLApp::isExiting())
{
LLNotificationsUtil::add(ent.mNotifyName, args);
}
diff --git a/indra/newview/llenvironment.cpp b/indra/newview/llenvironment.cpp
index 190051d763..8881d11802 100644
--- a/indra/newview/llenvironment.cpp
+++ b/indra/newview/llenvironment.cpp
@@ -1029,7 +1029,7 @@ void LLEnvironment::onRegionChange()
}
if (!cur_region->capabilitiesReceived())
{
- cur_region->setCapabilitiesReceivedCallback([](const LLUUID &region_id) { LLEnvironment::instance().requestRegion(); });
+ cur_region->setCapabilitiesReceivedCallback([](const LLUUID &region_id, LLViewerRegion* regionp) { LLEnvironment::instance().requestRegion(); });
return;
}
requestRegion();
@@ -1154,9 +1154,38 @@ void LLEnvironment::setEnvironment(LLEnvironment::EnvSelection_t env, LLEnvironm
}
else if (!environment->getSky())
{
- LL_DEBUGS("ENVIRONMENT") << "Blank sky for " << env_selection_to_string(env) << ". Reusing environment for sky." << LL_ENDL;
- environment->setSky(mCurrentEnvironment->getSky());
- environment->setFlags(DayInstance::NO_ANIMATE_SKY);
+ if (mCurrentEnvironment->getEnvironmentSelection() != ENV_NONE)
+ {
+ // Note: This looks suspicious. Shouldn't we assign whole day if mCurrentEnvironment has whole day?
+ // and then add water/sky on top
+ // This looks like it will result in sky using single keyframe instead of whole day if day is present
+ // when setting static water without static sky
+ environment->setSky(mCurrentEnvironment->getSky());
+ environment->setFlags(DayInstance::NO_ANIMATE_SKY);
+ }
+ else
+ {
+ // Environment is not properly initialized yet, but we should have environment by this point
+ DayInstance::ptr_t substitute = getEnvironmentInstance(ENV_PARCEL, true);
+ if (!substitute || !substitute->getSky())
+ {
+ substitute = getEnvironmentInstance(ENV_REGION, true);
+ }
+ if (!substitute || !substitute->getSky())
+ {
+ substitute = getEnvironmentInstance(ENV_DEFAULT, true);
+ }
+
+ if (substitute && substitute->getSky())
+ {
+ environment->setSky(substitute->getSky());
+ environment->setFlags(DayInstance::NO_ANIMATE_SKY);
+ }
+ else
+ {
+ LL_WARNS("ENVIRONMENT") << "Failed to assign substitute water/sky, environment is not properly initialized" << LL_ENDL;
+ }
+ }
}
if (fixed.second)
@@ -1167,9 +1196,38 @@ void LLEnvironment::setEnvironment(LLEnvironment::EnvSelection_t env, LLEnvironm
}
else if (!environment->getWater())
{
- LL_DEBUGS("ENVIRONMENT") << "Blank water for " << env_selection_to_string(env) << ". Reusing environment for water." << LL_ENDL;
- environment->setWater(mCurrentEnvironment->getWater());
- environment->setFlags(DayInstance::NO_ANIMATE_WATER);
+ if (mCurrentEnvironment->getEnvironmentSelection() != ENV_NONE)
+ {
+ // Note: This looks suspicious. Shouldn't we assign whole day if mCurrentEnvironment has whole day?
+ // and then add water/sky on top
+ // This looks like it will result in water using single keyframe instead of whole day if day is present
+ // when setting static sky without static water
+ environment->setWater(mCurrentEnvironment->getWater());
+ environment->setFlags(DayInstance::NO_ANIMATE_WATER);
+ }
+ else
+ {
+ // Environment is not properly initialized yet, but we should have environment by this point
+ DayInstance::ptr_t substitute = getEnvironmentInstance(ENV_PARCEL, true);
+ if (!substitute || !substitute->getWater())
+ {
+ substitute = getEnvironmentInstance(ENV_REGION, true);
+ }
+ if (!substitute || !substitute->getWater())
+ {
+ substitute = getEnvironmentInstance(ENV_DEFAULT, true);
+ }
+
+ if (substitute && substitute->getWater())
+ {
+ environment->setWater(substitute->getWater());
+ environment->setFlags(DayInstance::NO_ANIMATE_WATER);
+ }
+ else
+ {
+ LL_WARNS("ENVIRONMENT") << "Failed to assign substitute water/sky, environment is not properly initialized" << LL_ENDL;
+ }
+ }
}
if (!mSignalEnvChanged.empty())
@@ -1694,8 +1752,11 @@ void LLEnvironment::recordEnvironment(S32 parcel_id, LLEnvironment::EnvironmentI
}
else
{
- setEnvironment(ENV_REGION, envinfo->mDayCycle, envinfo->mDayLength, envinfo->mDayOffset, envinfo->mEnvVersion);
mTrackAltitudes = envinfo->mAltitudes;
+ // update track selection based on new altitudes
+ mCurrentTrack = calculateSkyTrackForAltitude(gAgent.getPositionAgent().mV[VZ]);
+
+ setEnvironment(ENV_REGION, envinfo->mDayCycle, envinfo->mDayLength, envinfo->mDayOffset, envinfo->mEnvVersion);
}
LL_DEBUGS("ENVIRONMENT") << "Altitudes set to {" << mTrackAltitudes[0] << ", "<< mTrackAltitudes[1] << ", " << mTrackAltitudes[2] << ", " << mTrackAltitudes[3] << LL_ENDL;
@@ -1927,6 +1988,10 @@ void LLEnvironment::coroRequestEnvironment(S32 parcel_id, LLEnvironment::environ
{
LL_WARNS("ENVIRONMENT") << "Couldn't retrieve environment settings for " << ((parcel_id == INVALID_PARCEL_ID) ? ("region!") : ("parcel!")) << LL_ENDL;
}
+ else if (LLApp::isExiting())
+ {
+ return;
+ }
else
{
LLSD environment = result[KEY_ENVIRONMENT];
@@ -2016,6 +2081,10 @@ void LLEnvironment::coroUpdateEnvironment(S32 parcel_id, S32 track_no, UpdateInf
notify = LLSD::emptyMap();
notify["FAIL_REASON"] = result["message"].asString();
}
+ else if (LLApp::isExiting())
+ {
+ return;
+ }
else
{
LLSD environment = result[KEY_ENVIRONMENT];
@@ -2078,6 +2147,10 @@ void LLEnvironment::coroResetEnvironment(S32 parcel_id, S32 track_no, environmen
notify = LLSD::emptyMap();
notify["FAIL_REASON"] = result["message"].asString();
}
+ else if (LLApp::isExiting())
+ {
+ return;
+ }
else
{
LLSD environment = result[KEY_ENVIRONMENT];
@@ -2315,6 +2388,15 @@ void LLEnvironment::onAgentPositionHasChanged(const LLVector3 &localpos)
return;
mCurrentTrack = trackno;
+
+ LLViewerRegion* cur_region = gAgent.getRegion();
+ if (!cur_region || !cur_region->capabilitiesReceived())
+ {
+ // Environment not ready, environment will be updated later, don't cause 'blend' yet.
+ // But keep mCurrentTrack updated in case we won't get new altitudes for some reason
+ return;
+ }
+
for (S32 env = ENV_LOCAL; env < ENV_DEFAULT; ++env)
{
if (mEnvironments[env])
diff --git a/indra/newview/llfloaterabout.cpp b/indra/newview/llfloaterabout.cpp
index 171858e472..1fbd198019 100644
--- a/indra/newview/llfloaterabout.cpp
+++ b/indra/newview/llfloaterabout.cpp
@@ -236,6 +236,7 @@ void LLFloaterAbout::fetchServerReleaseNotesCoro(const std::string& cap_url)
httpOpts->setWantHeaders(true);
httpOpts->setFollowRedirects(false);
+ httpOpts->setSSLVerifyPeer(false); // We want this data even if SSL verification fails
LLSD result = httpAdapter->getAndSuspend(httpRequest, cap_url, httpOpts);
diff --git a/indra/newview/llfloatercreatelandmark.cpp b/indra/newview/llfloatercreatelandmark.cpp
index eb93a6a75a..6b1d9306fb 100644
--- a/indra/newview/llfloatercreatelandmark.cpp
+++ b/indra/newview/llfloatercreatelandmark.cpp
@@ -320,4 +320,4 @@ void LLFloaterCreateLandmark::setItem(const uuid_set_t& items)
}
}
}
-} \ No newline at end of file
+}
diff --git a/indra/newview/llfloatereditenvironmentbase.cpp b/indra/newview/llfloatereditenvironmentbase.cpp
index e888144b6a..2850951668 100644
--- a/indra/newview/llfloatereditenvironmentbase.cpp
+++ b/indra/newview/llfloatereditenvironmentbase.cpp
@@ -262,7 +262,7 @@ void LLFloaterEditEnvironmentBase::onSaveAsCommit(const LLSD& notification, cons
{
const LLUUID &marketplacelistings_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_MARKETPLACE_LISTINGS, false);
LLUUID parent_id = mInventoryItem->getParentUUID();
- if (marketplacelistings_id == parent_id)
+ if (marketplacelistings_id == parent_id || gInventory.isObjectDescendentOf(mInventoryItem->getUUID(), gInventory.getLibraryRootFolderID()))
{
parent_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_SETTINGS);
}
diff --git a/indra/newview/llfloaterexperienceprofile.cpp b/indra/newview/llfloaterexperienceprofile.cpp
index 2c9a8e64b7..a99a096ea7 100644
--- a/indra/newview/llfloaterexperienceprofile.cpp
+++ b/indra/newview/llfloaterexperienceprofile.cpp
@@ -211,6 +211,20 @@ bool LLFloaterExperienceProfile::experiencePermission( LLHandle<LLFloaterExperie
return false;
}
+bool LLFloaterExperienceProfile::matchesKey(const LLSD& key)
+{
+ if (key.has("experience_id"))
+ {
+ return mExperienceId == key["experience_id"].asUUID();
+ }
+ else if (key.isUUID())
+ {
+ return mExperienceId == key.asUUID();
+ }
+ // Assume NULL uuid
+ return mExperienceId.isNull();
+}
+
void LLFloaterExperienceProfile::onClickEdit()
{
diff --git a/indra/newview/llfloaterexperienceprofile.h b/indra/newview/llfloaterexperienceprofile.h
index 1394418d91..f9b6e2e2eb 100644
--- a/indra/newview/llfloaterexperienceprofile.h
+++ b/indra/newview/llfloaterexperienceprofile.h
@@ -51,6 +51,8 @@ public:
LLFloaterExperienceProfile(const LLSD& data);
virtual ~LLFloaterExperienceProfile();
+
+ /* virtual */ bool matchesKey(const LLSD& key);
LLUUID getExperienceId() const { return mExperienceId; }
void setPreferences( const LLSD& content );
diff --git a/indra/newview/llfloatergridstatus.cpp b/indra/newview/llfloatergridstatus.cpp
index faa7e9f3db..9745e17bbb 100644
--- a/indra/newview/llfloatergridstatus.cpp
+++ b/indra/newview/llfloatergridstatus.cpp
@@ -95,6 +95,7 @@ void LLFloaterGridStatus::getGridStatusRSSCoro()
LLCore::HttpOptions::ptr_t httpOpts(new LLCore::HttpOptions);
LLCore::HttpHeaders::ptr_t httpHeaders(new LLCore::HttpHeaders);
+ httpOpts->setSSLVerifyPeer(false); // We want this data even if SSL fails
httpHeaders->append(HTTP_OUT_HEADER_CONTENT_TYPE, HTTP_CONTENT_TEXT_XML);
std::string url = gSavedSettings.getString("GridStatusRSS");
diff --git a/indra/newview/llfloaterurlentry.cpp b/indra/newview/llfloaterurlentry.cpp
index f2efef0c33..63bce3d2eb 100644
--- a/indra/newview/llfloaterurlentry.cpp
+++ b/indra/newview/llfloaterurlentry.cpp
@@ -122,8 +122,7 @@ void LLFloaterURLEntry::headerFetchComplete(S32 status, const std::string& mime_
}
}
- // Decrement the cursor
- getWindow()->decBusyCount();
+
getChildView("loading_label")->setVisible( false);
closeFloater();
}
@@ -302,3 +301,9 @@ bool LLFloaterURLEntry::callback_clear_url_list(const LLSD& notification, const
}
return false;
}
+
+void LLFloaterURLEntry::onClose( bool app_quitting )
+{
+ // Decrement the cursor
+ getWindow()->decBusyCount();
+}
diff --git a/indra/newview/llfloaterurlentry.h b/indra/newview/llfloaterurlentry.h
index 20f4604907..04a8eca069 100644
--- a/indra/newview/llfloaterurlentry.h
+++ b/indra/newview/llfloaterurlentry.h
@@ -42,6 +42,7 @@ public:
// that panel via the handle.
static LLHandle<LLFloater> show(LLHandle<LLPanel> panel_land_media_handle, const std::string media_url);
/*virtual*/ BOOL postBuild();
+ /*virtual*/ void onClose( bool app_quitting );
void headerFetchComplete(S32 status, const std::string& mime_type);
bool addURLToCombobox(const std::string& media_url);
diff --git a/indra/newview/llhudnametag.cpp b/indra/newview/llhudnametag.cpp
index 4ed802138d..9d49c30a49 100644
--- a/indra/newview/llhudnametag.cpp
+++ b/indra/newview/llhudnametag.cpp
@@ -105,6 +105,9 @@ LLHUDNameTag::LLHUDNameTag(const U8 type)
{
LLPointer<LLHUDNameTag> ptr(this);
sTextObjects.insert(ptr);
+
+ mRoundedRectImgp = LLUI::getUIImage("Rounded_Rect");
+ mRoundedRectTopImgp = LLUI::getUIImage("Rounded_Rect_Top");
}
LLHUDNameTag::~LLHUDNameTag()
@@ -274,9 +277,6 @@ void LLHUDNameTag::renderText(BOOL for_select)
mOffsetY = lltrunc(mHeight * ((mVertAlignment == ALIGN_VERT_CENTER) ? 0.5f : 1.f));
- // *TODO: cache this image
- LLUIImagePtr imagep = LLUI::getUIImage("Rounded_Rect");
-
// *TODO: make this a per-text setting
LLColor4 bg_color = LLUIColorTable::instance().getColor("NameTagBackground");
bg_color.setAlpha(gSavedSettings.getF32("ChatBubbleOpacity") * alpha_factor);
@@ -306,17 +306,16 @@ void LLHUDNameTag::renderText(BOOL for_select)
LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE);
LLRect screen_rect;
screen_rect.setCenterAndSize(0, static_cast<S32>(lltrunc(-mHeight / 2 + mOffsetY)), static_cast<S32>(lltrunc(mWidth)), static_cast<S32>(lltrunc(mHeight)));
- imagep->draw3D(render_position, x_pixel_vec, y_pixel_vec, screen_rect, bg_color);
+ mRoundedRectImgp->draw3D(render_position, x_pixel_vec, y_pixel_vec, screen_rect, bg_color);
if (mLabelSegments.size())
{
- LLUIImagePtr rect_top_image = LLUI::getUIImage("Rounded_Rect_Top");
LLRect label_top_rect = screen_rect;
const S32 label_height = ll_round((mFontp->getLineHeight() * (F32)mLabelSegments.size() + (VERTICAL_PADDING / 3.f)));
label_top_rect.mBottom = label_top_rect.mTop - label_height;
LLColor4 label_top_color = text_color;
label_top_color.mV[VALPHA] = gSavedSettings.getF32("ChatBubbleOpacity") * alpha_factor;
- rect_top_image->draw3D(render_position, x_pixel_vec, y_pixel_vec, label_top_rect, label_top_color);
+ mRoundedRectTopImgp->draw3D(render_position, x_pixel_vec, y_pixel_vec, label_top_rect, label_top_color);
}
F32 y_offset = (F32)mOffsetY;
diff --git a/indra/newview/llhudnametag.h b/indra/newview/llhudnametag.h
index 20272a8232..7577dd5de6 100644
--- a/indra/newview/llhudnametag.h
+++ b/indra/newview/llhudnametag.h
@@ -40,8 +40,8 @@
#include <set>
#include <vector>
-class LLDrawable;
class LLHUDNameTag;
+class LLUIImage;
struct llhudnametag_further_away
{
@@ -171,6 +171,8 @@ private:
EVertAlignment mVertAlignment;
S32 mLOD;
BOOL mHidden;
+ LLPointer<LLUIImage> mRoundedRectImgp;
+ LLPointer<LLUIImage> mRoundedRectTopImgp;
static BOOL sDisplayText ;
static std::set<LLPointer<LLHUDNameTag> > sTextObjects;
diff --git a/indra/newview/llhudtext.cpp b/indra/newview/llhudtext.cpp
index 72d28a3d44..7c957ac712 100644
--- a/indra/newview/llhudtext.cpp
+++ b/indra/newview/llhudtext.cpp
@@ -138,9 +138,6 @@ void LLHUDText::renderText()
mOffsetY = lltrunc(mHeight * ((mVertAlignment == ALIGN_VERT_CENTER) ? 0.5f : 1.f));
- // *TODO: cache this image
- LLUIImagePtr imagep = LLUI::getUIImage("Rounded_Square");
-
// *TODO: make this a per-text setting
LLColor4 bg_color = LLUIColorTable::instance().getColor("ObjectBubbleColor");
bg_color.setAlpha(gSavedSettings.getF32("ChatBubbleOpacity") * alpha_factor);
diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp
index 8b61e6c61a..fc8179f3b4 100644
--- a/indra/newview/llinventorybridge.cpp
+++ b/indra/newview/llinventorybridge.cpp
@@ -3970,6 +3970,12 @@ void LLFolderBridge::buildContextMenuOptions(U32 flags, menuentry_vec_t& items
const LLUUID &lost_and_found_id = model->findCategoryUUIDForType(LLFolderType::FT_LOST_AND_FOUND);
const LLUUID &favorites = model->findCategoryUUIDForType(LLFolderType::FT_FAVORITE);
const LLUUID &marketplace_listings_id = model->findCategoryUUIDForType(LLFolderType::FT_MARKETPLACE_LISTINGS, false);
+ const LLUUID &outfits_id = model->findCategoryUUIDForType(LLFolderType::FT_MY_OUTFITS, false);
+
+ if (outfits_id == mUUID)
+ {
+ items.push_back(std::string("New Outfit"));
+ }
if (lost_and_found_id == mUUID)
{
@@ -4068,7 +4074,8 @@ void LLFolderBridge::buildContextMenuOptions(U32 flags, menuentry_vec_t& items
// Not sure what the right thing is to do here.
if (!isCOFFolder() && cat && (cat->getPreferredType() != LLFolderType::FT_OUTFIT))
{
- if (!isInboxFolder()) // don't allow creation in inbox
+ if (!isInboxFolder() // don't allow creation in inbox
+ && outfits_id != mUUID)
{
// Do not allow to create 2-level subfolder in the Calling Card/Friends folder. EXT-694.
if (!LLFriendCardsManager::instance().isCategoryInFriendFolder(cat))
diff --git a/indra/newview/lllandmarklist.cpp b/indra/newview/lllandmarklist.cpp
index 543d2a087f..9106d4e986 100644
--- a/indra/newview/lllandmarklist.cpp
+++ b/indra/newview/lllandmarklist.cpp
@@ -74,6 +74,16 @@ LLLandmark* LLLandmarkList::getAsset(const LLUUID& asset_uuid, loaded_callback_t
{
return NULL;
}
+
+ if (cb)
+ {
+ // Multiple different sources can request same landmark,
+ // mLoadedCallbackMap is a multimap that allows multiple pairs with same key
+ // Todo: this might need to be improved to not hold identical callbacks multiple times
+ loaded_callback_map_t::value_type vt(asset_uuid, cb);
+ mLoadedCallbackMap.insert(vt);
+ }
+
if ( mWaitList.find(asset_uuid) != mWaitList.end() )
{
// Landmark is sheduled for download, but not requested yet
@@ -89,12 +99,6 @@ LLLandmark* LLLandmarkList::getAsset(const LLUUID& asset_uuid, loaded_callback_t
return NULL;
}
}
-
- if (cb)
- {
- loaded_callback_map_t::value_type vt(asset_uuid, cb);
- mLoadedCallbackMap.insert(vt);
- }
if (mRequestedList.size() > MAX_SIMULTANEOUS_REQUESTS)
{
@@ -132,36 +136,49 @@ void LLLandmarkList::processGetAssetReply(
LLVFile file(vfs, uuid, type);
S32 file_length = file.getSize();
- std::vector<char> buffer(file_length + 1);
- file.read( (U8*)&buffer[0], file_length);
- buffer[ file_length ] = 0;
+ if (file_length > 0)
+ {
+ std::vector<char> buffer(file_length + 1);
+ file.read((U8*)&buffer[0], file_length);
+ buffer[file_length] = 0;
- LLLandmark* landmark = LLLandmark::constructFromString(&buffer[0]);
- if (landmark)
- {
- gLandmarkList.mList[ uuid ] = landmark;
- gLandmarkList.mRequestedList.erase(uuid);
-
- LLVector3d pos;
- if(!landmark->getGlobalPos(pos))
- {
- LLUUID region_id;
- if(landmark->getRegionID(region_id))
- {
- LLLandmark::requestRegionHandle(
- gMessageSystem,
- gAgent.getRegionHost(),
- region_id,
- boost::bind(&LLLandmarkList::onRegionHandle, &gLandmarkList, uuid));
- }
-
- // the callback will be called when we get the region handle.
- }
- else
- {
- gLandmarkList.makeCallbacks(uuid);
- }
- }
+ LLLandmark* landmark = LLLandmark::constructFromString(&buffer[0], buffer.size());
+ if (landmark)
+ {
+ gLandmarkList.mList[uuid] = landmark;
+ gLandmarkList.mRequestedList.erase(uuid);
+
+ LLVector3d pos;
+ if (!landmark->getGlobalPos(pos))
+ {
+ LLUUID region_id;
+ if (landmark->getRegionID(region_id))
+ {
+ LLLandmark::requestRegionHandle(
+ gMessageSystem,
+ gAgent.getRegionHost(),
+ region_id,
+ boost::bind(&LLLandmarkList::onRegionHandle, &gLandmarkList, uuid));
+ }
+
+ // the callback will be called when we get the region handle.
+ }
+ else
+ {
+ gLandmarkList.makeCallbacks(uuid);
+ }
+ }
+ else
+ {
+ // failed to parse, shouldn't happen
+ gLandmarkList.eraseCallbacks(uuid);
+ }
+ }
+ else
+ {
+ // got a good status, but no file, shouldn't happen
+ gLandmarkList.eraseCallbacks(uuid);
+ }
}
else
{
@@ -179,7 +196,7 @@ void LLLandmarkList::processGetAssetReply(
gLandmarkList.mBadList.insert(uuid);
gLandmarkList.mRequestedList.erase(uuid); //mBadList effectively blocks any load, so no point keeping id in requests
- // todo: this should clean mLoadedCallbackMap!
+ gLandmarkList.eraseCallbacks(uuid);
}
// getAssetData can fire callback immediately, causing
@@ -223,32 +240,39 @@ BOOL LLLandmarkList::assetExists(const LLUUID& asset_uuid)
void LLLandmarkList::onRegionHandle(const LLUUID& landmark_id)
{
LLLandmark* landmark = getAsset(landmark_id);
-
- if (!landmark)
- {
- LL_WARNS() << "Got region handle but the landmark not found." << LL_ENDL;
- return;
- }
+ if (!landmark)
+ {
+ LL_WARNS() << "Got region handle but the landmark " << landmark_id << " not found." << LL_ENDL;
+ eraseCallbacks(landmark_id);
+ return;
+ }
// Calculate landmark global position.
// This should succeed since the region handle is available.
LLVector3d pos;
if (!landmark->getGlobalPos(pos))
{
- LL_WARNS() << "Got region handle but the landmark global position is still unknown." << LL_ENDL;
- return;
+ LL_WARNS() << "Got region handle but the landmark " << landmark_id << " global position is still unknown." << LL_ENDL;
+ eraseCallbacks(landmark_id);
+ return;
}
+ // Call this even if no landmark exists to clean mLoadedCallbackMap
makeCallbacks(landmark_id);
}
+void LLLandmarkList::eraseCallbacks(const LLUUID& landmark_id)
+{
+ mLoadedCallbackMap.erase(landmark_id);
+}
+
void LLLandmarkList::makeCallbacks(const LLUUID& landmark_id)
{
LLLandmark* landmark = getAsset(landmark_id);
if (!landmark)
{
- LL_WARNS() << "Landmark to make callbacks for not found." << LL_ENDL;
+ LL_WARNS() << "Landmark " << landmark_id << " to make callbacks for not found." << LL_ENDL;
}
// make all the callbacks here.
diff --git a/indra/newview/lllandmarklist.h b/indra/newview/lllandmarklist.h
index 2e7bd25610..4f3b11660d 100644
--- a/indra/newview/lllandmarklist.h
+++ b/indra/newview/lllandmarklist.h
@@ -65,6 +65,7 @@ public:
protected:
void onRegionHandle(const LLUUID& landmark_id);
+ void eraseCallbacks(const LLUUID& landmark_id);
void makeCallbacks(const LLUUID& landmark_id);
typedef std::map<LLUUID, LLLandmark*> landmark_list_t;
diff --git a/indra/newview/llmediactrl.h b/indra/newview/llmediactrl.h
index 958c76f261..bd24c47a4f 100644
--- a/indra/newview/llmediactrl.h
+++ b/indra/newview/llmediactrl.h
@@ -31,6 +31,7 @@
#include "lluictrl.h"
#include "llframetimer.h"
+#include "llnotificationptr.h"
class LLViewBorder;
class LLUICtrlFactory;
@@ -145,7 +146,7 @@ public:
void setTextureSize(S32 width, S32 height);
- void showNotification(boost::shared_ptr<class LLNotification> notify);
+ void showNotification(LLNotificationPtr notify);
void hideNotification();
void setTrustedContent(bool trusted);
diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp
index 3e8731dfe6..2c1c1191da 100644
--- a/indra/newview/llmeshrepository.cpp
+++ b/indra/newview/llmeshrepository.cpp
@@ -881,7 +881,7 @@ void LLMeshRepoThread::run()
LL_WARNS(LOG_MESH) << "Convex decomposition unable to be loaded. Expect severe problems." << LL_ENDL;
}
- while (!LLApp::isQuitting())
+ while (!LLApp::isExiting())
{
// *TODO: Revise sleep/wake strategy and try to move away
// from polling operations in this thread. We can sleep
@@ -898,7 +898,7 @@ void LLMeshRepoThread::run()
mSignal->wait();
- if (LLApp::isQuitting())
+ if (LLApp::isExiting())
{
break;
}
@@ -1168,7 +1168,7 @@ void LLMeshRepoThread::loadMeshPhysicsShape(const LLUUID& mesh_id)
void LLMeshRepoThread::lockAndLoadMeshLOD(const LLVolumeParams& mesh_params, S32 lod)
{
- if (!LLAppViewer::isQuitting())
+ if (!LLAppViewer::isExiting())
{
loadMeshLOD(mesh_params, lod);
}
@@ -2654,7 +2654,7 @@ void LLMeshUploadThread::doWholeModelUpload()
LL_DEBUGS(LOG_MESH) << "POST request issued." << LL_ENDL;
mHttpRequest->update(0);
- while (! LLApp::isQuitting() && ! finished() && ! isDiscarded())
+ while (! LLApp::isExiting() && ! finished() && ! isDiscarded())
{
ms_sleep(sleep_time);
sleep_time = llmin(250U, sleep_time + sleep_time);
@@ -2703,7 +2703,7 @@ void LLMeshUploadThread::requestWholeModelFee()
U32 sleep_time(10);
mHttpRequest->update(0);
- while (! LLApp::isQuitting() && ! finished() && ! isDiscarded())
+ while (! LLApp::isExiting() && ! finished() && ! isDiscarded())
{
ms_sleep(sleep_time);
sleep_time = llmin(250U, sleep_time + sleep_time);
@@ -3149,7 +3149,7 @@ common_exit:
LLMeshHeaderHandler::~LLMeshHeaderHandler()
{
- if (!LLApp::isQuitting())
+ if (!LLApp::isExiting())
{
if (! mProcessed)
{
@@ -3292,7 +3292,7 @@ void LLMeshHeaderHandler::processData(LLCore::BufferArray * /* body */, S32 /* b
LLMeshLODHandler::~LLMeshLODHandler()
{
- if (! LLApp::isQuitting())
+ if (! LLApp::isExiting())
{
if (! mProcessed)
{
@@ -3553,7 +3553,7 @@ void LLMeshRepository::shutdown()
mUploads[i]->discard() ; //discard the uploading requests.
}
- mThread->mSignal->signal();
+ mThread->mSignal->broadcast();
while (!mThread->isStopped())
{
@@ -4682,7 +4682,8 @@ void LLPhysicsDecomp::shutdown()
if (mSignal)
{
mQuitting = true;
- mSignal->signal();
+ // There is only one wait(), but just in case 'broadcast'
+ mSignal->broadcast();
while (!isStopped())
{
diff --git a/indra/newview/lloutfitgallery.cpp b/indra/newview/lloutfitgallery.cpp
index 272e7ae351..c1b622ffff 100644
--- a/indra/newview/lloutfitgallery.cpp
+++ b/indra/newview/lloutfitgallery.cpp
@@ -67,6 +67,7 @@ LLOutfitGallery::LLOutfitGallery(const LLOutfitGallery::Params& p)
mOutfitsObserver(NULL),
mScrollPanel(NULL),
mGalleryPanel(NULL),
+ mLastRowPanel(NULL),
mGalleryCreated(false),
mRowCount(0),
mItemsAddedCount(0),
@@ -166,9 +167,7 @@ bool compareGalleryItem(LLOutfitGalleryItem* item1, LLOutfitGalleryItem* item2)
std::string name1 = item1->getItemName();
std::string name2 = item2->getItemName();
- LLStringUtil::toUpper(name1);
- LLStringUtil::toUpper(name2);
- return name1 < name2;
+ return (LLStringUtil::compareDict(name1, name2) < 0);
}
else
{
@@ -241,7 +240,15 @@ void LLOutfitGallery::removeLastRow()
mGalleryPanel->removeChild(mLastRowPanel);
mUnusedRowPanels.push_back(mLastRowPanel);
mRowPanels.pop_back();
- mLastRowPanel = mRowPanels.back();
+ if (mRowPanels.size() > 0)
+ {
+ // Just removed last row
+ mLastRowPanel = mRowPanels.back();
+ }
+ else
+ {
+ mLastRowPanel = NULL;
+ }
}
LLPanel* LLOutfitGallery::addToRow(LLPanel* row_stack, LLOutfitGalleryItem* item, int pos, int hgap)
@@ -1111,7 +1118,7 @@ void LLOutfitGallery::refreshOutfit(const LLUUID& category_id)
}
}
- if (mGalleryCreated && !LLApp::isQuitting())
+ if (mGalleryCreated && !LLApp::isExiting())
{
reArrangeRows();
}
diff --git a/indra/newview/lloutfitslist.cpp b/indra/newview/lloutfitslist.cpp
index 71ab826e1c..423e57978a 100644
--- a/indra/newview/lloutfitslist.cpp
+++ b/indra/newview/lloutfitslist.cpp
@@ -59,10 +59,7 @@ bool LLOutfitTabNameComparator::compare(const LLAccordionCtrlTab* tab1, const LL
std::string name1 = tab1->getTitle();
std::string name2 = tab2->getTitle();
- LLStringUtil::toUpper(name1);
- LLStringUtil::toUpper(name2);
-
- return name1 < name2;
+ return (LLStringUtil::compareDict(name1, name2) < 0);
}
struct outfit_accordion_tab_params : public LLInitParam::Block<outfit_accordion_tab_params, LLAccordionCtrlTab::Params>
diff --git a/indra/newview/llpanellogin.cpp b/indra/newview/llpanellogin.cpp
index 3964dc075c..381b80fb66 100644
--- a/indra/newview/llpanellogin.cpp
+++ b/indra/newview/llpanellogin.cpp
@@ -254,7 +254,7 @@ LLPanelLogin::LLPanelLogin(const LLRect &rect,
LLLineEditor* password_edit(getChild<LLLineEditor>("password_edit"));
password_edit->setKeystrokeCallback(onPassKey, this);
// STEAM-14: When user presses Enter with this field in focus, initiate login
- password_edit->setCommitCallback(boost::bind(&LLPanelLogin::onClickConnect, this));
+ password_edit->setCommitCallback(boost::bind(&LLPanelLogin::onClickConnect, false));
// change z sort of clickable text to be behind buttons
sendChildToBack(getChildView("forgot_password_text"));
@@ -265,7 +265,7 @@ LLPanelLogin::LLPanelLogin(const LLRect &rect,
{
LLComboBox* favorites_combo = getChild<LLComboBox>("start_location_combo");
updateLocationSelectorsVisibility(); // separate so that it can be called from preferences
- favorites_combo->setReturnCallback(boost::bind(&LLPanelLogin::onClickConnect, this));
+ favorites_combo->setReturnCallback(boost::bind(&LLPanelLogin::onClickConnect, false));
favorites_combo->setFocusLostCallback(boost::bind(&LLPanelLogin::onLocationSLURL, this));
LLComboBox* server_choice_combo = getChild<LLComboBox>("server_combo");
@@ -458,6 +458,9 @@ void LLPanelLogin::addFavoritesToStartLocation()
if (combo->getValue().asString().empty())
{
combo->selectFirstItem();
+ // Value 'home' or 'last' should have been taken from NextLoginLocation
+ // but NextLoginLocation was not set, so init it from combo explicitly
+ onLocationSLURL();
}
}
@@ -1004,12 +1007,15 @@ void LLPanelLogin::handleMediaEvent(LLPluginClassMedia* /*self*/, EMediaEvent ev
// Protected methods
//---------------------------------------------------------------------------
// static
-void LLPanelLogin::onClickConnect(void *)
+void LLPanelLogin::onClickConnect(bool commit_fields)
{
if (sInstance && sInstance->mCallback)
{
- // JC - Make sure the fields all get committed.
- sInstance->setFocus(FALSE);
+ if (commit_fields)
+ {
+ // JC - Make sure the fields all get committed.
+ sInstance->setFocus(FALSE);
+ }
LLComboBox* combo = sInstance->getChild<LLComboBox>("server_combo");
LLSD combo_val = combo->getSelectedValue();
@@ -1132,7 +1138,7 @@ void LLPanelLogin::onUserListCommit(void*)
}
else
{
- onClickConnect(NULL);
+ onClickConnect();
}
}
}
@@ -1364,6 +1370,7 @@ void LLPanelLogin::onSelectServer()
{
// the grid specified by the location is not this one, so clear the combo
location_combo->setCurrentByIndex(0); // last location on the new grid
+ onLocationSLURL();
}
}
break;
diff --git a/indra/newview/llpanellogin.h b/indra/newview/llpanellogin.h
index 788c269ffd..c5e6b41def 100644
--- a/indra/newview/llpanellogin.h
+++ b/indra/newview/llpanellogin.h
@@ -99,7 +99,7 @@ private:
static void setFields(LLPointer<LLCredential> credential);
- static void onClickConnect(void*);
+ static void onClickConnect(bool commit_fields = true);
static void onClickNewAccount(void*);
static void onClickVersion(void*);
static void onClickForgotPassword(void*);
diff --git a/indra/newview/llpanelpicks.cpp b/indra/newview/llpanelpicks.cpp
index 4762e15d8f..8294977f99 100644
--- a/indra/newview/llpanelpicks.cpp
+++ b/indra/newview/llpanelpicks.cpp
@@ -483,19 +483,7 @@ void LLPanelPicks::processProperties(void* data, EAvatarProcessorType type)
mNoClassifieds = !mClassifiedsList->size();
}
- bool no_data = mNoPicks && mNoClassifieds;
- mNoItemsLabel->setVisible(no_data);
- if (no_data)
- {
- if(getAvatarId() == gAgentID)
- {
- mNoItemsLabel->setValue(LLTrans::getString("NoPicksClassifiedsText"));
- }
- else
- {
- mNoItemsLabel->setValue(LLTrans::getString("NoAvatarPicksClassifiedsText"));
- }
- }
+ updateNoItemsLabel();
}
LLPickItem* LLPanelPicks::getSelectedPickItem()
@@ -724,6 +712,13 @@ bool LLPanelPicks::callbackDeletePick(const LLSD& notification, const LLSD& resp
{
LLAvatarPropertiesProcessor::instance().sendPickDelete(pick_value[PICK_ID]);
mPicksList->removeItemByValue(pick_value);
+
+ mNoPicks = !mPicksList->size();
+ if (mNoPicks)
+ {
+ showAccordion("tab_picks", false);
+ }
+ updateNoItemsLabel();
}
updateButtons();
return false;
@@ -738,6 +733,13 @@ bool LLPanelPicks::callbackDeleteClassified(const LLSD& notification, const LLSD
{
LLAvatarPropertiesProcessor::instance().sendClassifiedDelete(value[CLASSIFIED_ID]);
mClassifiedsList->removeItemByValue(value);
+
+ mNoClassifieds = !mClassifiedsList->size();
+ if (mNoClassifieds)
+ {
+ showAccordion("tab_classifieds", false);
+ }
+ updateNoItemsLabel();
}
updateButtons();
return false;
@@ -851,6 +853,23 @@ void LLPanelPicks::updateButtons()
}
}
+void LLPanelPicks::updateNoItemsLabel()
+{
+ bool no_data = mNoPicks && mNoClassifieds;
+ mNoItemsLabel->setVisible(no_data);
+ if (no_data)
+ {
+ if (getAvatarId() == gAgentID)
+ {
+ mNoItemsLabel->setValue(LLTrans::getString("NoPicksClassifiedsText"));
+ }
+ else
+ {
+ mNoItemsLabel->setValue(LLTrans::getString("NoAvatarPicksClassifiedsText"));
+ }
+ }
+}
+
void LLPanelPicks::setProfilePanel(LLPanelProfile* profile_panel)
{
mProfilePanel = profile_panel;
diff --git a/indra/newview/llpanelpicks.h b/indra/newview/llpanelpicks.h
index 3bb7413ac3..fd7688b99d 100644
--- a/indra/newview/llpanelpicks.h
+++ b/indra/newview/llpanelpicks.h
@@ -87,6 +87,7 @@ public:
protected:
/*virtual*/void updateButtons();
+ void updateNoItemsLabel();
private:
void onClickDelete();
diff --git a/indra/newview/llpreviewscript.cpp b/indra/newview/llpreviewscript.cpp
index 4c539ded38..f13910cde5 100644
--- a/indra/newview/llpreviewscript.cpp
+++ b/indra/newview/llpreviewscript.cpp
@@ -636,14 +636,17 @@ bool LLScriptEdCore::writeToFile(const std::string& filename)
void LLScriptEdCore::sync()
{
- // Sync with external editor.
- std::string tmp_file = mContainer->getTmpFileName();
- llstat s;
- if (LLFile::stat(tmp_file, &s) == 0) // file exists
- {
- if (mLiveFile) mLiveFile->ignoreNextUpdate();
- writeToFile(tmp_file);
- }
+ // Sync with external editor.
+ if (mLiveFile)
+ {
+ std::string tmp_file = mLiveFile->filename();
+ llstat s;
+ if (LLFile::stat(tmp_file, &s) == 0) // file exists
+ {
+ mLiveFile->ignoreNextUpdate();
+ writeToFile(tmp_file);
+ }
+ }
}
bool LLScriptEdCore::hasChanged()
@@ -1027,9 +1030,25 @@ void LLScriptEdCore::openInExternalEditor()
{
delete mLiveFile; // deletes file
- // Save the script to a temporary file.
- std::string filename = mContainer->getTmpFileName();
- writeToFile(filename);
+ // Generate a suitable filename
+ std::string script_name = mScriptName;
+ std::string forbidden_chars = "<>:\"\\/|?*";
+ for (std::string::iterator c = forbidden_chars.begin(); c != forbidden_chars.end(); c++)
+ {
+ script_name.erase(std::remove(script_name.begin(), script_name.end(), *c), script_name.end());
+ }
+ std::string filename = mContainer->getTmpFileName(script_name);
+
+ // Save the script to a temporary file.
+ if (!writeToFile(filename))
+ {
+ // In case some characters from script name are forbidden
+ // and not accounted for, name is too long or some other issue,
+ // try file that doesn't include script name
+ script_name.clear();
+ filename = mContainer->getTmpFileName(script_name);
+ writeToFile(filename);
+ }
// Start watching file changes.
mLiveFile = new LLLiveLSLFile(filename, boost::bind(&LLScriptEdContainer::onExternalChange, mContainer, _1));
@@ -1419,7 +1438,7 @@ LLScriptEdContainer::LLScriptEdContainer(const LLSD& key) :
{
}
-std::string LLScriptEdContainer::getTmpFileName()
+std::string LLScriptEdContainer::getTmpFileName(const std::string& script_name)
{
// Take script inventory item id (within the object inventory)
// to consideration so that it's possible to edit multiple scripts
@@ -1431,7 +1450,14 @@ std::string LLScriptEdContainer::getTmpFileName()
LLMD5 script_id_hash((const U8 *)script_id.c_str());
script_id_hash.hex_digest(script_id_hash_str);
- return std::string(LLFile::tmpdir()) + "sl_script_" + script_id_hash_str + ".lsl";
+ if (script_name.empty())
+ {
+ return std::string(LLFile::tmpdir()) + "sl_script_" + script_id_hash_str + ".lsl";
+ }
+ else
+ {
+ return std::string(LLFile::tmpdir()) + "sl_script_" + script_name + "_" + script_id_hash_str + ".lsl";
+ }
}
bool LLScriptEdContainer::onExternalChange(const std::string& filename)
diff --git a/indra/newview/llpreviewscript.h b/indra/newview/llpreviewscript.h
index 3cf22a0e6e..c1fea31063 100644
--- a/indra/newview/llpreviewscript.h
+++ b/indra/newview/llpreviewscript.h
@@ -205,7 +205,7 @@ public:
LLScriptEdContainer(const LLSD& key, const bool live);
protected:
- std::string getTmpFileName();
+ std::string getTmpFileName(const std::string& script_name);
bool onExternalChange(const std::string& filename);
virtual void saveIfNeeded(bool sync = true) = 0;
diff --git a/indra/newview/llsechandler_basic.cpp b/indra/newview/llsechandler_basic.cpp
index 94331fddfa..b4853d270a 100644
--- a/indra/newview/llsechandler_basic.cpp
+++ b/indra/newview/llsechandler_basic.cpp
@@ -915,11 +915,19 @@ void _validateCert(int validation_policy,
}
if (validation_policy & VALIDATION_POLICY_SSL_KU)
{
+ // This stanza of code was changed 2021-06-09 as per details in SL-15370.
+ // Brief summary: a renewed certificate from Akamai only contains the
+ // 'Digital Signature' field and not the 'Key Encipherment' one. This code
+ // used to look for both and throw an exception at startup (ignored) and
+ // (for example) when buying L$ in the Viewer (fails with a UI message
+ // and an entry in the Viewer log). This modified code removes the second
+ // check for the 'Key Encipherment' field. If Akamai can provide a
+ // replacement certificate that has both fields, then this modified code
+ // will not be required.
if (current_cert_info.has(CERT_KEY_USAGE) && current_cert_info[CERT_KEY_USAGE].isArray() &&
- (!(_LLSDArrayIncludesValue(current_cert_info[CERT_KEY_USAGE],
- LLSD((std::string)CERT_KU_DIGITAL_SIGNATURE))) ||
!(_LLSDArrayIncludesValue(current_cert_info[CERT_KEY_USAGE],
- LLSD((std::string)CERT_KU_KEY_ENCIPHERMENT)))))
+ LLSD((std::string)CERT_KU_DIGITAL_SIGNATURE)))
+ )
{
LLTHROW(LLCertKeyUsageValidationException(current_cert_info));
}
diff --git a/indra/newview/llskinningutil.cpp b/indra/newview/llskinningutil.cpp
index f325315933..e02b21f036 100644
--- a/indra/newview/llskinningutil.cpp
+++ b/indra/newview/llskinningutil.cpp
@@ -131,7 +131,12 @@ void LLSkinningUtil::initSkinningMatrixPalette(
initJointNums(const_cast<LLMeshSkinInfo*>(skin), avatar);
for (U32 j = 0; j < count; ++j)
{
- LLJoint *joint = avatar->getJoint(skin->mJointNums[j]);
+ S32 joint_num = skin->mJointNums[j];
+ LLJoint *joint = NULL;
+ if (joint_num >= 0 && joint_num < LL_CHARACTER_MAX_ANIMATED_JOINTS)
+ {
+ joint = avatar->getJoint(joint_num);
+ }
llassert(joint);
if (joint)
{
diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp
index c5d5be3509..1242131534 100644
--- a/indra/newview/llstartup.cpp
+++ b/indra/newview/llstartup.cpp
@@ -1838,9 +1838,6 @@ bool idle_startup()
display_startup();
- //all categories loaded. lets create "My Favorites" category
- gInventory.findCategoryUUIDForType(LLFolderType::FT_FAVORITE,true);
-
// set up callbacks
LL_INFOS() << "Registering Callbacks" << LL_ENDL;
LLMessageSystem* msg = gMessageSystem;
diff --git a/indra/newview/llteleporthistorystorage.cpp b/indra/newview/llteleporthistorystorage.cpp
index 93fa457bd0..7d4988c0cc 100644
--- a/indra/newview/llteleporthistorystorage.cpp
+++ b/indra/newview/llteleporthistorystorage.cpp
@@ -203,6 +203,12 @@ void LLTeleportHistoryStorage::load()
std::string line;
while (std::getline(file, line))
{
+ if (line.empty())
+ {
+ LL_WARNS() << "Teleport history contains empty line."<< LL_ENDL;
+ continue;
+ }
+
LLSD s_item;
std::istringstream iss(line);
if (parser->parse(iss, s_item, line.length()) == LLSDParser::PARSE_FAILURE)
diff --git a/indra/newview/lltoolmgr.cpp b/indra/newview/lltoolmgr.cpp
index 3fcf193dec..fa2dd60ee0 100644
--- a/indra/newview/lltoolmgr.cpp
+++ b/indra/newview/lltoolmgr.cpp
@@ -405,7 +405,7 @@ void LLToolMgr::clearTransientTool()
void LLToolMgr::onAppFocusLost()
{
- if (LLApp::isQuitting())
+ if (LLApp::isExiting())
return;
if (mSelectedTool)
diff --git a/indra/newview/lltoolpie.cpp b/indra/newview/lltoolpie.cpp
index 322d0bc727..75a5fabdc2 100644
--- a/indra/newview/lltoolpie.cpp
+++ b/indra/newview/lltoolpie.cpp
@@ -1234,7 +1234,8 @@ BOOL LLToolPie::handleTooltipObject( LLViewerObject* hover_object, std::string l
BOOL LLToolPie::handleToolTip(S32 local_x, S32 local_y, MASK mask)
{
- if (!LLUI::getInstance()->mSettingGroups["config"]->getBOOL("ShowHoverTips")) return TRUE;
+ static LLCachedControl<bool> show_hover_tips(*LLUI::getInstance()->mSettingGroups["config"], "ShowHoverTips", true);
+ if (!show_hover_tips) return TRUE;
if (!mHoverPick.isValid()) return TRUE;
LLViewerObject* hover_object = mHoverPick.getObject();
diff --git a/indra/newview/lltranslate.cpp b/indra/newview/lltranslate.cpp
index fa3b44f702..553a3cd086 100644
--- a/indra/newview/lltranslate.cpp
+++ b/indra/newview/lltranslate.cpp
@@ -144,6 +144,7 @@ void LLTranslationAPIHandler::verifyKeyCoro(LLTranslate::EService service, std::
httpHeaders->append(HTTP_OUT_HEADER_USER_AGENT, user_agent);
httpOpts->setFollowRedirects(true);
+ httpOpts->setSSLVerifyPeer(false);
std::string url = this->getKeyVerificationURL(key);
if (url.empty())
@@ -185,6 +186,7 @@ void LLTranslationAPIHandler::translateMessageCoro(LanguagePair_t fromTo, std::s
httpHeaders->append(HTTP_OUT_HEADER_ACCEPT, HTTP_CONTENT_TEXT_PLAIN);
httpHeaders->append(HTTP_OUT_HEADER_USER_AGENT, user_agent);
+ httpOpts->setSSLVerifyPeer(false);
std::string url = this->getTranslateURL(fromTo.first, fromTo.second, msg);
if (url.empty())
diff --git a/indra/newview/llviewerassetstorage.cpp b/indra/newview/llviewerassetstorage.cpp
index 7842d24279..c1b129750a 100644
--- a/indra/newview/llviewerassetstorage.cpp
+++ b/indra/newview/llviewerassetstorage.cpp
@@ -115,6 +115,7 @@ LLViewerAssetStorage::LLViewerAssetStorage(LLMessageSystem *msg, LLXferManager *
mCountSucceeded(0),
mTotalBytesFetched(0)
{
+ LLCoprocedureManager::instance().initializePool(VIEWER_ASSET_STORAGE_CORO_POOL);
}
@@ -128,6 +129,7 @@ LLViewerAssetStorage::LLViewerAssetStorage(LLMessageSystem *msg, LLXferManager *
mCountSucceeded(0),
mTotalBytesFetched(0)
{
+ LLCoprocedureManager::instance().initializePool(VIEWER_ASSET_STORAGE_CORO_POOL);
}
LLViewerAssetStorage::~LLViewerAssetStorage()
@@ -544,7 +546,7 @@ void LLViewerAssetStorage::assetRequestCoro(
LLSD result = httpAdapter->getRawAndSuspend(httpRequest, url, httpOpts);
- if (LLApp::isQuitting() || !gAssetStorage)
+ if (LLApp::isExiting() || !gAssetStorage)
{
// Bail out if result arrives after shutdown has been started.
return;
diff --git a/indra/newview/llviewerdisplay.cpp b/indra/newview/llviewerdisplay.cpp
index 066c874eb8..109dc93261 100644
--- a/indra/newview/llviewerdisplay.cpp
+++ b/indra/newview/llviewerdisplay.cpp
@@ -1499,10 +1499,9 @@ void render_ui_2d()
if (gSavedSettings.getBOOL("RenderUIBuffer"))
{
- LLUI* ui_inst = LLUI::getInstance();
- if (ui_inst->mDirty)
+ if (LLView::sIsRectDirty)
{
- ui_inst->mDirty = FALSE;
+ LLView::sIsRectDirty = false;
LLRect t_rect;
gPipeline.mUIScreen.bindTarget();
@@ -1510,25 +1509,25 @@ void render_ui_2d()
{
static const S32 pad = 8;
- ui_inst->mDirtyRect.mLeft -= pad;
- ui_inst->mDirtyRect.mRight += pad;
- ui_inst->mDirtyRect.mBottom -= pad;
- ui_inst->mDirtyRect.mTop += pad;
+ LLView::sDirtyRect.mLeft -= pad;
+ LLView::sDirtyRect.mRight += pad;
+ LLView::sDirtyRect.mBottom -= pad;
+ LLView::sDirtyRect.mTop += pad;
LLGLEnable scissor(GL_SCISSOR_TEST);
- static LLRect last_rect = ui_inst->mDirtyRect;
+ static LLRect last_rect = LLView::sDirtyRect;
//union with last rect to avoid mouse poop
- last_rect.unionWith(ui_inst->mDirtyRect);
+ last_rect.unionWith(LLView::sDirtyRect);
- t_rect = ui_inst->mDirtyRect;
- ui_inst->mDirtyRect = last_rect;
+ t_rect = LLView::sDirtyRect;
+ LLView::sDirtyRect = last_rect;
last_rect = t_rect;
-
- last_rect.mLeft = LLRect::tCoordType(last_rect.mLeft / ui_inst->getScaleFactor().mV[0]);
- last_rect.mRight = LLRect::tCoordType(last_rect.mRight / ui_inst->getScaleFactor().mV[0]);
- last_rect.mTop = LLRect::tCoordType(last_rect.mTop / ui_inst->getScaleFactor().mV[1]);
- last_rect.mBottom = LLRect::tCoordType(last_rect.mBottom / ui_inst->getScaleFactor().mV[1]);
+
+ last_rect.mLeft = LLRect::tCoordType(last_rect.mLeft / LLUI::getScaleFactor().mV[0]);
+ last_rect.mRight = LLRect::tCoordType(last_rect.mRight / LLUI::getScaleFactor().mV[0]);
+ last_rect.mTop = LLRect::tCoordType(last_rect.mTop / LLUI::getScaleFactor().mV[1]);
+ last_rect.mBottom = LLRect::tCoordType(last_rect.mBottom / LLUI::getScaleFactor().mV[1]);
LLRect clip_rect(last_rect);
@@ -1540,7 +1539,7 @@ void render_ui_2d()
gPipeline.mUIScreen.flush();
gGL.setColorMask(true, false);
- ui_inst->mDirtyRect = t_rect;
+ LLView::sDirtyRect = t_rect;
}
LLGLDisable cull(GL_CULL_FACE);
diff --git a/indra/newview/llviewerfoldertype.cpp b/indra/newview/llviewerfoldertype.cpp
index afa84a5afc..f770db31dd 100644
--- a/indra/newview/llviewerfoldertype.cpp
+++ b/indra/newview/llviewerfoldertype.cpp
@@ -130,7 +130,7 @@ LLViewerFolderDictionary::LLViewerFolderDictionary()
addEntry(LLFolderType::FT_FAVORITE, new ViewerFolderEntry("Favorites", "Inv_SysOpen", "Inv_SysClosed", FALSE, true));
addEntry(LLFolderType::FT_CURRENT_OUTFIT, new ViewerFolderEntry("Current Outfit", "Inv_SysOpen", "Inv_SysClosed", TRUE, false));
- addEntry(LLFolderType::FT_OUTFIT, new ViewerFolderEntry("New Outfit", "Inv_LookFolderOpen", "Inv_LookFolderClosed", TRUE, true));
+ addEntry(LLFolderType::FT_OUTFIT, new ViewerFolderEntry("New Outfit", "Inv_LookFolderOpen", "Inv_LookFolderClosed", TRUE, false));
addEntry(LLFolderType::FT_MY_OUTFITS, new ViewerFolderEntry("My Outfits", "Inv_SysOpen", "Inv_SysClosed", TRUE, true));
addEntry(LLFolderType::FT_MESH, new ViewerFolderEntry("Meshes", "Inv_SysOpen", "Inv_SysClosed", FALSE, true));
addEntry(LLFolderType::FT_SETTINGS, new ViewerFolderEntry("Settings", "Inv_SysOpen", "Inv_SysClosed", FALSE, true));
diff --git a/indra/newview/llviewermedia.cpp b/indra/newview/llviewermedia.cpp
index 9ed2df2759..d35dbda907 100644
--- a/indra/newview/llviewermedia.cpp
+++ b/indra/newview/llviewermedia.cpp
@@ -1237,6 +1237,7 @@ void LLViewerMedia::getOpenIDCookieCoro(std::string url)
httpOpts->setFollowRedirects(true);
httpOpts->setWantHeaders(true);
+ httpOpts->setSSLVerifyPeer(false); // viewer's cert bundle doesn't appear to agree with web certs from "https://my.secondlife.com/"
LLURL hostUrl(url.c_str());
std::string hostAuth = hostUrl.getAuthority();
@@ -1744,14 +1745,14 @@ LLPluginClassMedia* LLViewerMediaImpl::newSourceFromMediaType(std::string media_
bool cookies_enabled = gSavedSettings.getBOOL( "CookiesEnabled" );
media_source->cookies_enabled( cookies_enabled || clean_browser);
- // collect 'plugins enabled' setting from prefs and send to embedded browser
- bool plugins_enabled = gSavedSettings.getBOOL( "BrowserPluginsEnabled" );
- media_source->setPluginsEnabled( plugins_enabled || clean_browser);
-
// collect 'javascript enabled' setting from prefs and send to embedded browser
bool javascript_enabled = gSavedSettings.getBOOL( "BrowserJavascriptEnabled" );
media_source->setJavascriptEnabled( javascript_enabled || clean_browser);
+ // As of SL-15559 PDF files do not load in CEF v91 we enable plugins
+ // but explicitly disable Flash (PDF support in CEF is now treated as a plugin)
+ media_source->setPluginsEnabled(true);
+
bool media_plugin_debugging_enabled = gSavedSettings.getBOOL("MediaPluginDebugging");
media_source->enableMediaPluginDebugging( media_plugin_debugging_enabled || clean_browser);
diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp
index fbf057603e..ad81cb07c1 100644
--- a/indra/newview/llviewermenu.cpp
+++ b/indra/newview/llviewermenu.cpp
@@ -291,6 +291,8 @@ void force_error_bad_memory_access(void *);
void force_error_infinite_loop(void *);
void force_error_software_exception(void *);
void force_error_driver_crash(void *);
+void force_error_coroutine_crash(void *);
+void force_error_thread_crash(void *);
void handle_force_delete(void*);
void print_object_info(void*);
@@ -2361,6 +2363,24 @@ class LLAdvancedForceErrorDriverCrash : public view_listener_t
}
};
+class LLAdvancedForceErrorCoroutineCrash : public view_listener_t
+{
+ bool handleEvent(const LLSD& userdata)
+ {
+ force_error_coroutine_crash(NULL);
+ return true;
+ }
+};
+
+class LLAdvancedForceErrorThreadCrash : public view_listener_t
+{
+ bool handleEvent(const LLSD& userdata)
+ {
+ force_error_thread_crash(NULL);
+ return true;
+ }
+};
+
class LLAdvancedForceErrorDisconnectViewer : public view_listener_t
{
bool handleEvent(const LLSD& userdata)
@@ -4135,25 +4155,31 @@ void near_sit_down_point(BOOL success, void *)
class LLLandSit : public view_listener_t
{
- bool handleEvent(const LLSD& userdata)
- {
- gAgent.standUp();
- LLViewerParcelMgr::getInstance()->deselectLand();
+ bool handleEvent(const LLSD& userdata)
+ {
+ LLVector3d posGlobal = LLToolPie::getInstance()->getPick().mPosGlobal;
- LLVector3d posGlobal = LLToolPie::getInstance()->getPick().mPosGlobal;
-
- LLQuaternion target_rot;
- if (isAgentAvatarValid())
- {
- target_rot = gAgentAvatarp->getRotation();
- }
- else
- {
- target_rot = gAgent.getFrameAgent().getQuaternion();
- }
- gAgent.startAutoPilotGlobal(posGlobal, "Sit", &target_rot, near_sit_down_point, NULL, 0.7f);
- return true;
- }
+ LLQuaternion target_rot;
+ if (isAgentAvatarValid())
+ {
+ target_rot = gAgentAvatarp->getRotation();
+ }
+ else
+ {
+ target_rot = gAgent.getFrameAgent().getQuaternion();
+ }
+ gAgent.startAutoPilotGlobal(posGlobal, "Sit", &target_rot, near_sit_down_point, NULL, 0.7f);
+ return true;
+ }
+};
+
+class LLLandCanSit : public view_listener_t
+{
+ bool handleEvent(const LLSD& userdata)
+ {
+ LLVector3d posGlobal = LLToolPie::getInstance()->getPick().mPosGlobal;
+ return !posGlobal.isExactlyZero(); // valid position, not beyond draw distance
+ }
};
//-------------------------------------------------------------------
@@ -8068,6 +8094,16 @@ void force_error_driver_crash(void *)
LLAppViewer::instance()->forceErrorDriverCrash();
}
+void force_error_coroutine_crash(void *)
+{
+ LLAppViewer::instance()->forceErrorCoroutineCrash();
+}
+
+void force_error_thread_crash(void *)
+{
+ LLAppViewer::instance()->forceErrorThreadCrash();
+}
+
class LLToolsUseSelectionForGrid : public view_listener_t
{
bool handleEvent(const LLSD& userdata)
@@ -9240,6 +9276,8 @@ void initialize_menus()
view_listener_t::addMenu(new LLAdvancedForceErrorInfiniteLoop(), "Advanced.ForceErrorInfiniteLoop");
view_listener_t::addMenu(new LLAdvancedForceErrorSoftwareException(), "Advanced.ForceErrorSoftwareException");
view_listener_t::addMenu(new LLAdvancedForceErrorDriverCrash(), "Advanced.ForceErrorDriverCrash");
+ view_listener_t::addMenu(new LLAdvancedForceErrorCoroutineCrash(), "Advanced.ForceErrorCoroutineCrash");
+ view_listener_t::addMenu(new LLAdvancedForceErrorThreadCrash(), "Advanced.ForceErrorThreadCrash");
view_listener_t::addMenu(new LLAdvancedForceErrorDisconnectViewer(), "Advanced.ForceErrorDisconnectViewer");
// Advanced (toplevel)
@@ -9371,6 +9409,7 @@ void initialize_menus()
// Land pie menu
view_listener_t::addMenu(new LLLandBuild(), "Land.Build");
view_listener_t::addMenu(new LLLandSit(), "Land.Sit");
+ view_listener_t::addMenu(new LLLandCanSit(), "Land.CanSit");
view_listener_t::addMenu(new LLLandBuyPass(), "Land.BuyPass");
view_listener_t::addMenu(new LLLandEdit(), "Land.Edit");
diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp
index 2fde4fe49c..7628a6c7ef 100644
--- a/indra/newview/llviewerregion.cpp
+++ b/indra/newview/llviewerregion.cpp
@@ -82,6 +82,8 @@
#include "llcallstack.h"
#include "llsettingsdaycycle.h"
+#include <boost/regex.hpp>
+
#ifdef LL_WINDOWS
#pragma warning(disable:4355)
#endif
@@ -143,15 +145,22 @@ public:
// build a secondlife://{PLACE} SLurl from this SLapp
std::string url = "secondlife://";
+ boost::regex name_rx("[A-Za-z0-9()_%]+");
+ boost::regex coord_rx("[0-9]+");
for (int i = 0; i < num_params; i++)
{
if (i > 0)
{
url += "/";
}
+ if (!boost::regex_match(params[i].asString(), i > 0 ? coord_rx : name_rx))
+ {
+ return false;
+ }
+
url += params[i].asString();
}
-
+
// Process the SLapp as if it was a secondlife://{PLACE} SLurl
LLURLDispatcher::dispatch(url, "clicked", web, true);
return true;
@@ -2241,7 +2250,7 @@ void LLViewerRegion::setSimulatorFeaturesReceived(bool received)
mSimulatorFeaturesReceived = received;
if (received)
{
- mSimulatorFeaturesReceivedSignal(getRegionID());
+ mSimulatorFeaturesReceivedSignal(getRegionID(), this);
mSimulatorFeaturesReceivedSignal.disconnect_all_slots();
}
}
@@ -3183,7 +3192,7 @@ void LLViewerRegion::setCapabilitiesReceived(bool received)
// so that they can safely use getCapability().
if (received)
{
- mCapabilitiesReceivedSignal(getRegionID());
+ mCapabilitiesReceivedSignal(getRegionID(), this);
LLFloaterPermsDefault::sendInitialPerms();
diff --git a/indra/newview/llviewerregion.h b/indra/newview/llviewerregion.h
index dfd8c64f76..fcbf56c81f 100644
--- a/indra/newview/llviewerregion.h
+++ b/indra/newview/llviewerregion.h
@@ -94,7 +94,7 @@ public:
NUM_PARTITIONS
} eObjectPartitions;
- typedef boost::signals2::signal<void(const LLUUID& region_id)> caps_received_signal_t;
+ typedef boost::signals2::signal<void(const LLUUID& region_id, LLViewerRegion* regionp)> caps_received_signal_t;
LLViewerRegion(const U64 &handle,
const LLHost &host,
diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp
index 21985d5a8a..1d13a306ef 100644
--- a/indra/newview/llviewerwindow.cpp
+++ b/indra/newview/llviewerwindow.cpp
@@ -1928,7 +1928,8 @@ LLViewerWindow::LLViewerWindow(const Params& p)
if (!LLAppViewer::instance()->restoreErrorTrap())
{
- LL_WARNS("Window") << " Someone took over my signal/exception handler (post createWindow)!" << LL_ENDL;
+ // this always happens, so downgrading it to INFO
+ LL_INFOS("Window") << " Someone took over my signal/exception handler (post createWindow; normal)" << LL_ENDL;
}
const bool do_not_enforce = false;
@@ -2700,7 +2701,7 @@ void LLViewerWindow::draw()
if (!gSavedSettings.getBOOL("RenderUIBuffer"))
{
- LLUI::getInstance()->mDirtyRect = getWindowRectScaled();
+ LLView::sDirtyRect = getWindowRectScaled();
}
// HACK for timecode debugging
diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp
index f69b9b3861..e085a945a8 100644
--- a/indra/newview/llvoavatar.cpp
+++ b/indra/newview/llvoavatar.cpp
@@ -10584,7 +10584,8 @@ void LLVOAvatar::accountRenderComplexityForObject(
LL_DEBUGS("ARCdetail") << "Attachment costs " << attached_object->getAttachmentItemID()
<< " total: " << attachment_total_cost
<< ", volume: " << attachment_volume_cost
- << ", textures: " << attachment_texture_cost
+ << ", " << textures.size()
+ << " textures: " << attachment_texture_cost
<< ", " << volume->numChildren()
<< " children: " << attachment_children_cost
<< LL_ENDL;
@@ -10684,10 +10685,23 @@ void LLVOAvatar::calculateUpdateRenderComplexity()
ETextureIndex tex_index = baked_dict->mTextureIndex;
if ((tex_index != TEX_SKIRT_BAKED) || (isWearingWearableType(LLWearableType::WT_SKIRT)))
{
- if (isTextureVisible(tex_index))
- {
- cost +=COMPLEXITY_BODY_PART_COST;
- }
+ // Same as isTextureVisible(), but doesn't account for isSelf to ensure identical numbers for all avatars
+ if (isIndexLocalTexture(tex_index))
+ {
+ if (isTextureDefined(tex_index, 0))
+ {
+ cost += COMPLEXITY_BODY_PART_COST;
+ }
+ }
+ else
+ {
+ // baked textures can use TE images directly
+ if (isTextureDefined(tex_index)
+ && (getTEImage(tex_index)->getID() != IMG_INVISIBLE || LLDrawPoolAlpha::sShowDebugAlpha))
+ {
+ cost += COMPLEXITY_BODY_PART_COST;
+ }
+ }
}
}
LL_DEBUGS("ARCdetail") << "Avatar body parts complexity: " << cost << LL_ENDL;
@@ -10728,8 +10742,7 @@ void LLVOAvatar::calculateUpdateRenderComplexity()
// Diagnostic output to identify all avatar-related textures.
// Does not affect rendering cost calculation.
- // Could be wrapped in a debug option if output becomes problematic.
- if (isSelf())
+ if (isSelf() && debugLoggingEnabled("ARCdetail"))
{
// print any attachment textures we didn't already know about.
for (LLVOVolume::texture_cost_t::iterator it = textures.begin(); it != textures.end(); ++it)
diff --git a/indra/newview/llvocache.cpp b/indra/newview/llvocache.cpp
index 689eeee0e3..5ebc65405f 100644
--- a/indra/newview/llvocache.cpp
+++ b/indra/newview/llvocache.cpp
@@ -44,6 +44,9 @@ F32 LLVOCacheEntry::sFrontPixelThreshold = 1.0f;
F32 LLVOCacheEntry::sRearPixelThreshold = 1.0f;
BOOL LLVOCachePartition::sNeedsOcclusionCheck = FALSE;
+const S32 ENTRY_HEADER_SIZE = 6 * sizeof(S32);
+const S32 MAX_ENTRY_BODY_SIZE = 10000;
+
BOOL check_read(LLAPRFile* apr_file, void* src, S32 n_bytes)
{
return apr_file->read(src, n_bytes) == n_bytes ;
@@ -111,32 +114,22 @@ LLVOCacheEntry::LLVOCacheEntry(LLAPRFile* apr_file)
{
S32 size = -1;
BOOL success;
+ static U8 data_buffer[ENTRY_HEADER_SIZE];
mDP.assignBuffer(mBuffer, 0);
-
- success = check_read(apr_file, &mLocalID, sizeof(U32));
- if(success)
- {
- success = check_read(apr_file, &mCRC, sizeof(U32));
- }
- if(success)
- {
- success = check_read(apr_file, &mHitCount, sizeof(S32));
- }
- if(success)
- {
- success = check_read(apr_file, &mDupeCount, sizeof(S32));
- }
- if(success)
- {
- success = check_read(apr_file, &mCRCChangeCount, sizeof(S32));
- }
- if(success)
- {
- success = check_read(apr_file, &size, sizeof(S32));
+
+ success = check_read(apr_file, (void *)data_buffer, ENTRY_HEADER_SIZE);
+ if (success)
+ {
+ memcpy(&mLocalID, data_buffer, sizeof(U32));
+ memcpy(&mCRC, data_buffer + sizeof(U32), sizeof(U32));
+ memcpy(&mHitCount, data_buffer + (2 * sizeof(U32)), sizeof(S32));
+ memcpy(&mDupeCount, data_buffer + (3 * sizeof(U32)), sizeof(S32));
+ memcpy(&mCRCChangeCount, data_buffer + (4 * sizeof(U32)), sizeof(S32));
+ memcpy(&size, data_buffer + (5 * sizeof(U32)), sizeof(S32));
// Corruption in the cache entries
- if ((size > 10000) || (size < 1))
+ if ((size > MAX_ENTRY_BODY_SIZE) || (size < 1))
{
// We've got a bogus size, skip reading it.
// We won't bother seeking, because the rest of this file
@@ -345,26 +338,25 @@ void LLVOCacheEntry::dump() const
<< LL_ENDL;
}
-BOOL LLVOCacheEntry::writeToFile(LLAPRFile* apr_file) const
+S32 LLVOCacheEntry::writeToBuffer(U8 *data_buffer) const
{
- static const S32 data_buffer_size = 6 * sizeof(S32);
- static U8 data_buffer[data_buffer_size];
S32 size = mDP.getBufferSize();
+ if (size > MAX_ENTRY_BODY_SIZE)
+ {
+ LL_WARNS() << "Failed to write entry with size above allowed limit: " << size << LL_ENDL;
+ return 0;
+ }
+
memcpy(data_buffer, &mLocalID, sizeof(U32));
memcpy(data_buffer + sizeof(U32), &mCRC, sizeof(U32));
memcpy(data_buffer + (2 * sizeof(U32)), &mHitCount, sizeof(S32));
memcpy(data_buffer + (3 * sizeof(U32)), &mDupeCount, sizeof(S32));
memcpy(data_buffer + (4 * sizeof(U32)), &mCRCChangeCount, sizeof(S32));
memcpy(data_buffer + (5 * sizeof(U32)), &size, sizeof(S32));
+ memcpy(data_buffer + ENTRY_HEADER_SIZE, (void*)mBuffer, size);
- BOOL success = check_write(apr_file, (void*)data_buffer, data_buffer_size);
- if (success)
- {
- success = check_write(apr_file, (void*)mBuffer, size);
- }
-
- return success;
+ return ENTRY_HEADER_SIZE + size;
}
//static
@@ -1393,11 +1385,11 @@ void LLVOCache::readFromCache(U64 handle, const LLUUID& id, LLVOCacheEntry::voca
bool success = true ;
{
std::string filename;
+ LLUUID cache_id;
getObjectCacheFilename(handle, filename);
LLAPRFile apr_file(filename, APR_READ|APR_BINARY, mLocalAPRFilePoolp);
- LLUUID cache_id ;
- success = check_read(&apr_file, cache_id.mData, UUID_BYTES) ;
+ success = check_read(&apr_file, cache_id.mData, UUID_BYTES);
if(success)
{
@@ -1409,7 +1401,7 @@ void LLVOCache::readFromCache(U64 handle, const LLUUID& id, LLVOCacheEntry::voca
if(success)
{
- S32 num_entries;
+ S32 num_entries; // if removal was enabled during write num_entries might be wrong
success = check_read(&apr_file, &num_entries, sizeof(S32)) ;
if(success)
@@ -1516,28 +1508,57 @@ void LLVOCache::writeToCache(U64 handle, const LLUUID& id, const LLVOCacheEntry:
{
std::string filename;
getObjectCacheFilename(handle, filename);
- LLAPRFile apr_file(filename, APR_CREATE|APR_WRITE|APR_BINARY, mLocalAPRFilePoolp);
+ LLAPRFile apr_file(filename, APR_CREATE|APR_WRITE|APR_BINARY|APR_TRUNCATE, mLocalAPRFilePoolp);
- success = check_write(&apr_file, (void*)id.mData, UUID_BYTES) ;
-
+ success = check_write(&apr_file, (void*)id.mData, UUID_BYTES);
if(success)
{
- S32 num_entries = cache_entry_map.size() ;
+ S32 num_entries = cache_entry_map.size(); // if removal is enabled num_entries might be wrong
success = check_write(&apr_file, &num_entries, sizeof(S32));
-
- // This can have a lot of entries, so might be better to dump them into buffer first and write in one go.
- for (LLVOCacheEntry::vocache_entry_map_t::const_iterator iter = cache_entry_map.begin(); success && iter != cache_entry_map.end(); ++iter)
- {
- if(!removal_enabled || iter->second->isValid())
- {
- success = iter->second->writeToFile(&apr_file) ;
- if(!success)
- {
- break;
- }
- }
- }
+ if (success)
+ {
+ const S32 buffer_size = 32768; //should be large enough for couple MAX_ENTRY_BODY_SIZE
+ U8 data_buffer[buffer_size]; // generaly entries are fairly small, so collect them and drop onto disk in one go
+ S32 size_in_buffer = 0;
+
+ // This can have a lot of entries, so might be better to dump them into buffer first and write in one go.
+ for (LLVOCacheEntry::vocache_entry_map_t::const_iterator iter = cache_entry_map.begin(); success && iter != cache_entry_map.end(); ++iter)
+ {
+ if (!removal_enabled || iter->second->isValid())
+ {
+ S32 size = iter->second->writeToBuffer(data_buffer + size_in_buffer);
+
+ if (size > ENTRY_HEADER_SIZE) // body is minimum of 1
+ {
+ size_in_buffer += size;
+ }
+ else
+ {
+ success = false;
+ break;
+ }
+
+ // Make sure we have space in buffer for next element
+ if (buffer_size - size_in_buffer < MAX_ENTRY_BODY_SIZE + ENTRY_HEADER_SIZE)
+ {
+ success = check_write(&apr_file, (void*)data_buffer, size_in_buffer);
+ size_in_buffer = 0;
+ if (!success)
+ {
+ break;
+ }
+ }
+ }
+ }
+
+ if (success && size_in_buffer > 0)
+ {
+ // final write
+ success = check_write(&apr_file, (void*)data_buffer, size_in_buffer);
+ size_in_buffer = 0;
+ }
+ }
}
}
diff --git a/indra/newview/llvocache.h b/indra/newview/llvocache.h
index 6c95541c11..dd6afd6b85 100644
--- a/indra/newview/llvocache.h
+++ b/indra/newview/llvocache.h
@@ -106,7 +106,7 @@ public:
F32 getSceneContribution() const { return mSceneContrib;}
void dump() const;
- BOOL writeToFile(LLAPRFile* apr_file) const;
+ S32 writeToBuffer(U8 *data_buffer) const;
LLDataPackerBinaryBuffer *getDP();
void recordHit();
void recordDupe() { mDupeCount++; }
diff --git a/indra/newview/llvoicevivox.cpp b/indra/newview/llvoicevivox.cpp
index 7d8aa6fbbd..4d2eac8c09 100644
--- a/indra/newview/llvoicevivox.cpp
+++ b/indra/newview/llvoicevivox.cpp
@@ -652,7 +652,6 @@ void LLVivoxVoiceClient::idle(void* user_data)
{
}
-
//=========================================================================
// the following are methods to support the coroutine implementation of the
// voice connection and processing. They should only be called in the context
@@ -699,12 +698,15 @@ void LLVivoxVoiceClient::voiceControlCoro()
gSavedSettings.getControl("VivoxVadNoiseFloor")->getSignal()->connect(boost::bind(&LLVivoxVoiceClient::onVADSettingsChange, this));
gSavedSettings.getControl("VivoxVadSensitivity")->getSignal()->connect(boost::bind(&LLVivoxVoiceClient::onVADSettingsChange, this));
- if (mTuningMode)
+ if (mTuningMode && !sShuttingDown)
{
performMicTuning();
}
- waitForChannel(); // this doesn't normally return unless relog is needed or shutting down
+ if (!sShuttingDown)
+ {
+ waitForChannel(); // this doesn't normally return unless relog is needed or shutting down
+ }
LL_DEBUGS("Voice") << "lost channel RelogRequested=" << mRelogRequested << LL_ENDL;
endAndDisconnectSession();
@@ -746,7 +748,6 @@ void LLVivoxVoiceClient::voiceControlCoro()
LL_INFOS("Voice") << "exiting" << LL_ENDL;
}
-
bool LLVivoxVoiceClient::startAndConnectSession()
{
bool ok = false;
@@ -1047,7 +1048,14 @@ bool LLVivoxVoiceClient::provisionVoiceAccount()
{
F32 timeout = pow(PROVISION_RETRY_TIMEOUT, static_cast<float>(retryCount));
LL_WARNS("Voice") << "Provision CAP 404. Retrying in " << timeout << " seconds." << LL_ENDL;
- llcoro::suspendUntilTimeout(timeout);
+ if (sShuttingDown)
+ {
+ return false;
+ }
+ else
+ {
+ llcoro::suspendUntilTimeout(timeout);
+ }
}
else if (!status)
{
@@ -1274,8 +1282,13 @@ bool LLVivoxVoiceClient::loginToVivox()
// tell the user there is a problem
LL_WARNS("Voice") << "login " << loginresp << " will retry login in " << timeout << " seconds." << LL_ENDL;
-
- llcoro::suspendUntilTimeout(timeout);
+
+ if (!sShuttingDown)
+ {
+ // Todo: this is way to long, viewer can get stuck waiting during shutdown
+ // either make it listen to pump or split in smaller waits with checks for shutdown
+ llcoro::suspendUntilTimeout(timeout);
+ }
}
else if (loginresp == "failed")
{
@@ -1341,6 +1354,11 @@ void LLVivoxVoiceClient::logoutOfVivox(bool wait)
result = llcoro::suspendUntilEventOnWithTimeout(mVivoxPump, LOGOUT_ATTEMPT_TIMEOUT, timeoutResult);
+ if (sShuttingDown)
+ {
+ break;
+ }
+
LL_DEBUGS("Voice") << "event=" << ll_stream_notation_sd(result) << LL_ENDL;
// Don't get confused by prior queued events -- note that it's
// very important that mVivoxPump is an LLEventMailDrop, which
@@ -1580,6 +1598,12 @@ bool LLVivoxVoiceClient::addAndJoinSession(const sessionStatePtr_t &nextSession)
{
result = llcoro::suspendUntilEventOnWithTimeout(mVivoxPump, SESSION_JOIN_TIMEOUT, timeoutResult);
+ if (sShuttingDown)
+ {
+ mIsJoiningSession = false;
+ return false;
+ }
+
LL_INFOS("Voice") << "event=" << ll_stream_notation_sd(result) << LL_ENDL;
if (result.has("session"))
{
@@ -1774,7 +1798,7 @@ bool LLVivoxVoiceClient::waitForChannel()
if (sShuttingDown)
{
- logoutOfVivox(true);
+ logoutOfVivox(false);
return false;
}
@@ -1818,7 +1842,7 @@ bool LLVivoxVoiceClient::waitForChannel()
// the parcel is changed, or we have no pending audio sessions,
// so try to request the parcel voice info
// if we have the cap, we move to the appropriate state
- requestParcelVoiceInfo();
+ requestParcelVoiceInfo(); //suspends for http reply
}
else if (sessionNeedsRelog(mNextAudioSession))
{
@@ -1830,7 +1854,7 @@ bool LLVivoxVoiceClient::waitForChannel()
{
sessionStatePtr_t joinSession = mNextAudioSession;
mNextAudioSession.reset();
- if (!runSession(joinSession))
+ if (!runSession(joinSession)) //suspends
{
LL_DEBUGS("Voice") << "runSession returned false; leaving inner loop" << LL_ENDL;
break;
@@ -1845,7 +1869,7 @@ bool LLVivoxVoiceClient::waitForChannel()
}
}
- if (!mNextAudioSession)
+ if (!mNextAudioSession && !sShuttingDown)
{
llcoro::suspendUntilTimeout(1.0);
}
@@ -1866,9 +1890,9 @@ bool LLVivoxVoiceClient::waitForChannel()
mIsProcessingChannels = false;
- logoutOfVivox(true);
+ logoutOfVivox(!sShuttingDown /*bool wait*/);
- if (mRelogRequested)
+ if (mRelogRequested && !sShuttingDown)
{
LL_DEBUGS("Voice") << "Relog Requested, restarting provisioning" << LL_ENDL;
if (!provisionVoiceAccount())
@@ -1918,7 +1942,12 @@ bool LLVivoxVoiceClient::runSession(const sessionStatePtr_t &session)
while (mVoiceEnabled && isGatewayRunning() && !mSessionTerminateRequested && !mTuningMode)
{
- sendCaptureAndRenderDevices();
+ sendCaptureAndRenderDevices(); // suspends
+ if (mSessionTerminateRequested)
+ {
+ break;
+ }
+
if (mAudioSession && mAudioSession->mParticipantsChanged)
{
mAudioSession->mParticipantsChanged = false;
@@ -2145,7 +2174,7 @@ bool LLVivoxVoiceClient::performMicTuning()
mIsInTuningMode = true;
llcoro::suspend();
- while (mTuningMode)
+ while (mTuningMode && !sShuttingDown)
{
if (mCaptureDeviceDirty || mRenderDeviceDirty)
@@ -2181,9 +2210,12 @@ bool LLVivoxVoiceClient::performMicTuning()
tuningCaptureStartSendMessage(1); // 1-loop, zero, don't loop
//---------------------------------------------------------------------
- llcoro::suspend();
+ if (!sShuttingDown)
+ {
+ llcoro::suspend();
+ }
- while (mTuningMode && !mCaptureDeviceDirty && !mRenderDeviceDirty)
+ while (mTuningMode && !mCaptureDeviceDirty && !mRenderDeviceDirty && !sShuttingDown)
{
// process mic/speaker volume changes
if (mTuningMicVolumeDirty || mTuningSpeakerVolumeDirty)
@@ -2223,7 +2255,7 @@ bool LLVivoxVoiceClient::performMicTuning()
// transition out of mic tuning
tuningCaptureStopSendMessage();
- if (mCaptureDeviceDirty || mRenderDeviceDirty)
+ if ((mCaptureDeviceDirty || mRenderDeviceDirty) && !sShuttingDown)
{
llcoro::suspendUntilTimeout(UPDATE_THROTTLE_SECONDS);
}
diff --git a/indra/newview/llvoicevivox.h b/indra/newview/llvoicevivox.h
index 746201af04..75ff5429f3 100644
--- a/indra/newview/llvoicevivox.h
+++ b/indra/newview/llvoicevivox.h
@@ -446,7 +446,6 @@ protected:
// local audio updates, mic mute, speaker mute, mic volume and speaker volumes
void sendLocalAudioUpdates();
-
/////////////////////////////
// Response/Event handlers
void connectorCreateResponse(int statusCode, std::string &statusString, std::string &connectorHandle, std::string &versionID);
diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp
index 3bdb8a2981..f063800587 100644
--- a/indra/newview/llvovolume.cpp
+++ b/indra/newview/llvovolume.cpp
@@ -3987,7 +3987,25 @@ U32 LLVOVolume::getRenderCost(texture_cost_t &textures) const
{
if (textures.find(img->getID()) == textures.end())
{
- S32 texture_cost = 256 + (S32)(ARC_TEXTURE_COST * (img->getFullHeight() / 128.f + img->getFullWidth() / 128.f));
+ S32 texture_cost = 0;
+ S8 type = img->getType();
+ if (type == LLViewerTexture::FETCHED_TEXTURE || type == LLViewerTexture::LOD_TEXTURE)
+ {
+ const LLViewerFetchedTexture* fetched_texturep = static_cast<const LLViewerFetchedTexture*>(img);
+ if (fetched_texturep
+ && fetched_texturep->getFTType() == FTT_LOCAL_FILE
+ && (img->getID() == IMG_ALPHA_GRAD_2D || img->getID() == IMG_ALPHA_GRAD)
+ )
+ {
+ // These two textures appear to switch between each other, but are of different sizes (4x256 and 256x256).
+ // Hardcode cost from larger one to not cause random complexity changes
+ texture_cost = 320;
+ }
+ }
+ if (texture_cost == 0)
+ {
+ texture_cost = 256 + (S32)(ARC_TEXTURE_COST * (img->getFullHeight() / 128.f + img->getFullWidth() / 128.f));
+ }
textures.insert(texture_cost_t::value_type(img->getID(), texture_cost));
}
}
@@ -5450,8 +5468,8 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
U32 useage = group->getSpatialPartition()->mBufferUsage;
- LLCachedControl<S32> max_vbo_size(gSavedSettings, "RenderMaxVBOSize", 512);
- LLCachedControl<S32> max_node_size(gSavedSettings, "RenderMaxNodeSize", 65536);
+ static LLCachedControl<S32> max_vbo_size(gSavedSettings, "RenderMaxVBOSize", 512);
+ static LLCachedControl<S32> max_node_size(gSavedSettings, "RenderMaxNodeSize", 65536);
U32 max_vertices = (max_vbo_size * 1024)/LLVertexBuffer::calcVertexSize(group->getSpatialPartition()->mVertexDataMask);
U32 max_total = (max_node_size * 1024) / LLVertexBuffer::calcVertexSize(group->getSpatialPartition()->mVertexDataMask);
max_vertices = llmin(max_vertices, (U32) 65535);
@@ -6217,7 +6235,7 @@ U32 LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace
#endif
//calculate maximum number of vertices to store in a single buffer
- LLCachedControl<S32> max_vbo_size(gSavedSettings, "RenderMaxVBOSize", 512);
+ static LLCachedControl<S32> max_vbo_size(gSavedSettings, "RenderMaxVBOSize", 512);
U32 max_vertices = (max_vbo_size * 1024)/LLVertexBuffer::calcVertexSize(group->getSpatialPartition()->mVertexDataMask);
max_vertices = llmin(max_vertices, (U32) 65535);
diff --git a/indra/newview/llwatchdog.cpp b/indra/newview/llwatchdog.cpp
index 6273f10c69..0aa0280b25 100644
--- a/indra/newview/llwatchdog.cpp
+++ b/indra/newview/llwatchdog.cpp
@@ -31,15 +31,6 @@
const U32 WATCHDOG_SLEEP_TIME_USEC = 1000000;
-void default_killer_callback()
-{
-#ifdef LL_WINDOWS
- RaiseException(0,0,0,0);
-#else
- raise(SIGQUIT);
-#endif
-}
-
// This class runs the watchdog timing thread.
class LLWatchdogTimerThread : public LLThread
{
@@ -158,11 +149,10 @@ void LLWatchdogTimeout::ping(const std::string& state)
}
// LLWatchdog
-LLWatchdog::LLWatchdog() :
- mSuspectsAccessMutex(),
- mTimer(NULL),
- mLastClockCount(0),
- mKillerCallback(&default_killer_callback)
+LLWatchdog::LLWatchdog()
+ :mSuspectsAccessMutex()
+ ,mTimer(NULL)
+ ,mLastClockCount(0)
{
}
@@ -184,9 +174,8 @@ void LLWatchdog::remove(LLWatchdogEntry* e)
unlockThread();
}
-void LLWatchdog::init(killer_event_callback func)
+void LLWatchdog::init()
{
- mKillerCallback = func;
if(!mSuspectsAccessMutex && !mTimer)
{
mSuspectsAccessMutex = new LLMutex();
@@ -253,8 +242,7 @@ void LLWatchdog::run()
mTimer->stop();
}
- LL_INFOS() << "Watchdog detected error:" << LL_ENDL;
- mKillerCallback();
+ LL_ERRS() << "Watchdog timer expired; assuming viewer is hung and crashing" << LL_ENDL;
}
}
diff --git a/indra/newview/llwatchdog.h b/indra/newview/llwatchdog.h
index 9a6624258e..ce5cf748f4 100644
--- a/indra/newview/llwatchdog.h
+++ b/indra/newview/llwatchdog.h
@@ -83,9 +83,7 @@ public:
void add(LLWatchdogEntry* e);
void remove(LLWatchdogEntry* e);
- typedef boost::function<void (void)> killer_event_callback;
-
- void init(killer_event_callback func = NULL);
+ void init();
void run();
void cleanup();
@@ -98,8 +96,6 @@ private:
LLMutex* mSuspectsAccessMutex;
LLWatchdogTimerThread* mTimer;
U64 mLastClockCount;
-
- killer_event_callback mKillerCallback;
};
#endif // LL_LLTHREADWATCHDOG_H
diff --git a/indra/newview/llweb.cpp b/indra/newview/llweb.cpp
index 63257d6543..d019b400e8 100644
--- a/indra/newview/llweb.cpp
+++ b/indra/newview/llweb.cpp
@@ -237,7 +237,7 @@ bool LLWeb::useExternalBrowser(const std::string &url)
up.extractParts();
std::string uri_string = up.host();
- boost::regex pattern = boost::regex("\\b(lindenlab.com|secondlife.com)$", boost::regex::perl|boost::regex::icase);
+ boost::regex pattern = boost::regex("\\b(lindenlab.com|secondlife.com|secondlife.io)$", boost::regex::perl|boost::regex::icase);
boost::match_results<std::string::const_iterator> matches;
return !(boost::regex_search(uri_string, matches, pattern));
}
diff --git a/indra/newview/llwebprofile.cpp b/indra/newview/llwebprofile.cpp
index 569f479a16..ff899fe895 100644
--- a/indra/newview/llwebprofile.cpp
+++ b/indra/newview/llwebprofile.cpp
@@ -113,6 +113,7 @@ void LLWebProfile::uploadImageCoro(LLPointer<LLImageFormatted> image, std::strin
httpOpts->setWantHeaders(true);
httpOpts->setFollowRedirects(false);
+ httpOpts->setSSLVerifyPeer(false); ; // viewer's cert bundle doesn't appear to agree with web certs from "https://my.secondlife.com/"
// Get upload configuration data.
std::string configUrl(getProfileURL(std::string()) + "snapshots/s3_upload_config");
diff --git a/indra/newview/llwlhandlers.cpp b/indra/newview/llwlhandlers.cpp
index 730aa3774f..d55e1b7cd3 100644
--- a/indra/newview/llwlhandlers.cpp
+++ b/indra/newview/llwlhandlers.cpp
@@ -51,7 +51,7 @@ bool LLEnvironmentRequest::initiate(LLEnvironment::environment_apply_fn cb)
if (!cur_region->capabilitiesReceived())
{
LL_INFOS("WindlightCaps") << "Deferring windlight settings request until we've got region caps" << LL_ENDL;
- cur_region->setCapabilitiesReceivedCallback([cb](const LLUUID &region_id) { LLEnvironmentRequest::onRegionCapsReceived(region_id, cb); });
+ cur_region->setCapabilitiesReceivedCallback([cb](const LLUUID &region_id, LLViewerRegion* regionp) { LLEnvironmentRequest::onRegionCapsReceived(region_id, cb); });
return false;
}
diff --git a/indra/newview/skins/default/xui/en/floater_create_landmark.xml b/indra/newview/skins/default/xui/en/floater_create_landmark.xml
index dcedaceaeb..bba30626b2 100644
--- a/indra/newview/skins/default/xui/en/floater_create_landmark.xml
+++ b/indra/newview/skins/default/xui/en/floater_create_landmark.xml
@@ -49,7 +49,7 @@
layout="topleft"
name="folder_label"
top_pad="10"
- value="Landmark location:"
+ value="Save this landmark in:"
width="290" />
<combo_box
follows="bottom|left"
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 3cc99b28c9..7786ba8a1c 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
@@ -626,23 +626,6 @@
top_delta="16"
width="300" />
- <!-- SL-12594, basic shaders always enabled, no fixed-function GL
- <check_box
- control_name="VertexShaderEnable"
- height="16"
- initial_value="true"
- label="Basic shaders"
- layout="topleft"
- left="420"
- name="BasicShaders"
- tool_tip="Disabling this option may prevent some graphics card drivers from crashing"
- top_delta="16"
- width="300">
- <check_box.commit_callback
- function="Pref.VertexShaderEnable" />
- </check_box>
- -->
-
<slider
control_name="RenderTerrainDetail"
follows="left|top"
diff --git a/indra/newview/skins/default/xui/en/floater_url_entry.xml b/indra/newview/skins/default/xui/en/floater_url_entry.xml
index 29fb29fabf..2dfc0fd125 100644
--- a/indra/newview/skins/default/xui/en/floater_url_entry.xml
+++ b/indra/newview/skins/default/xui/en/floater_url_entry.xml
@@ -66,7 +66,7 @@
layout="topleft"
left="152"
name="loading_label"
- visible="true">
+ visible="false">
Loading...
</text>
</floater>
diff --git a/indra/newview/skins/default/xui/en/menu_inventory.xml b/indra/newview/skins/default/xui/en/menu_inventory.xml
index eda9739976..5a35bbf121 100644
--- a/indra/newview/skins/default/xui/en/menu_inventory.xml
+++ b/indra/newview/skins/default/xui/en/menu_inventory.xml
@@ -152,6 +152,14 @@
parameter="category" />
</menu_item_call>
<menu_item_call
+ label="New Outfit"
+ layout="topleft"
+ name="New Outfit">
+ <menu_item_call.on_click
+ function="Inventory.DoCreate"
+ parameter="outfit" />
+ </menu_item_call>
+ <menu_item_call
label="New Script"
layout="topleft"
name="New Script">
diff --git a/indra/newview/skins/default/xui/en/menu_land.xml b/indra/newview/skins/default/xui/en/menu_land.xml
index 2ad5cbbe95..1ce0d65b3e 100644
--- a/indra/newview/skins/default/xui/en/menu_land.xml
+++ b/indra/newview/skins/default/xui/en/menu_land.xml
@@ -18,6 +18,8 @@
<menu_item_call
label="Sit Here"
name="Sit Here">
+ <menu_item_call.on_enable
+ function="Land.CanSit" />
<menu_item_call.on_click
function="Land.Sit" />
</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 c550f69d26..72cce2208f 100644
--- a/indra/newview/skins/default/xui/en/menu_viewer.xml
+++ b/indra/newview/skins/default/xui/en/menu_viewer.xml
@@ -2657,6 +2657,18 @@ function="World.EnvPreset"
function="Advanced.ForceErrorSoftwareException" />
</menu_item_call>
<menu_item_call
+ label="Force a Crash in a Coroutine"
+ name="Force a Crash in a Coroutine">
+ <menu_item_call.on_click
+ function="Advanced.ForceErrorCoroutineCrash" />
+ </menu_item_call>
+ <menu_item_call
+ label="Force a Crash in a Thread"
+ name="Force a Crash in a Thread">
+ <menu_item_call.on_click
+ function="Advanced.ForceErrorThreadCrash" />
+ </menu_item_call>
+ <menu_item_call
label="Force Disconnect Viewer"
name="Force Disconnect Viewer">
<menu_item_call.on_click
diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml
index 4a02b576c2..d4f71fb370 100644
--- a/indra/newview/skins/default/xui/en/notifications.xml
+++ b/indra/newview/skins/default/xui/en/notifications.xml
@@ -10055,6 +10055,15 @@ Removal of the object &lt;nolink&gt;'[OBJ_NAME]'&lt;/nolink&gt; from the simulat
Cannot save your selection because you do not have permission to modify the object &lt;nolink&gt;'[OBJ_NAME]'&lt;/nolink&gt;.
</notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="NoTransNoSaveToContents"
+ type="notify">
+ <tag>fail</tag>
+ Cannot save &lt;nolink&gt;'[OBJ_NAME]'&lt;/nolink&gt; to object contents because you do not have permission to transfer the object's ownership.
+ </notification>
+
<notification
icon="alertmodal.tga"
name="NoCopyNoSaveSelection"
diff --git a/indra/newview/skins/default/xui/en/panel_login_first.xml b/indra/newview/skins/default/xui/en/panel_login_first.xml
index 726e713595..5568ccb792 100644
--- a/indra/newview/skins/default/xui/en/panel_login_first.xml
+++ b/indra/newview/skins/default/xui/en/panel_login_first.xml
@@ -234,32 +234,6 @@
left_pad="32"
name="image_right"
top="0" />
- <text
- follows="left|top"
- font="SansSerifLarge"
- text_color="White"
- height="64"
- name="image_caption_left"
- left="0"
- halign="center"
- top="408"
- word_wrap="true"
- width="400">
- Your first step is Learning Island. Find the exit portal!
- </text>
- <text
- follows="left|top"
- font="SansSerifLarge"
- text_color="White"
- height="64"
- name="image_caption_right"
- left="432"
- halign="center"
- top="408"
- word_wrap="true"
- width="400">
- Then explore Social Island and meet other new residents!
- </text>
</layout_panel>
<layout_panel
height="100"
diff --git a/indra/newview/skins/default/xui/en/panel_navigation_bar.xml b/indra/newview/skins/default/xui/en/panel_navigation_bar.xml
index 2dae2649a9..1c9aa1eb83 100644
--- a/indra/newview/skins/default/xui/en/panel_navigation_bar.xml
+++ b/indra/newview/skins/default/xui/en/panel_navigation_bar.xml
@@ -151,7 +151,7 @@
layout="topleft"
auto_resize="true"
user_resize="true"
- min_width="254"
+ min_width="342"
name="favorites_layout_panel"
width="342">
<icon
@@ -198,8 +198,8 @@
tool_tip="Drag Landmarks here for quick access to your favorite places in Second Life!"
top="13"
valign="bottom"
- width="205">
- Your saved locations will appear here.
+ width="290">
+ Places you save to your favorites bar will appear here.
</label>
<!-- More button actually is a text box. -->
<more_button
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 6732f4ff1c..dff6f6e600 100644
--- a/indra/newview/skins/default/xui/en/panel_preferences_setup.xml
+++ b/indra/newview/skins/default/xui/en/panel_preferences_setup.xml
@@ -148,20 +148,6 @@
</radio_group>
<check_box
- top_delta="2"
- enabled="true"
- follows="left|top"
- height="18"
- initial_value="true"
- control_name="BrowserPluginsEnabled"
- label="Enable plugins"
- left_delta="20"
- mouse_opaque="true"
- name="browser_plugins_enabled"
- radio_style="false"
- width="400"
- top_pad="5"/>
- <check_box
top_delta="4"
enabled="true"
follows="left|top"
@@ -241,24 +227,23 @@
height="10"
layout="topleft"
left="30"
- name="Proxy Settings:"
+ name="Proxy Settings 1"
+ mouse_opaque="false"
+ top_pad="10"
+ width="300">
+ Proxy Settings:
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="10"
+ layout="topleft"
+ left="80"
+ name="Proxy Settings 2"
mouse_opaque="false"
top_pad="5"
width="300">
- Proxy Settings:
+ Your system's existing proxy settings will be used
</text>
- <button
- label="Adjust proxy settings"
- follows="left|top"
- height="23"
- width="140"
- label_selected="Browse"
- layout="topleft"
- left_delta="50"
- name="set_proxy"
- top_pad="5"
- >
- <button.commit_callback
- function="Pref.Proxy" />
- </button>
</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_status_bar.xml b/indra/newview/skins/default/xui/en/panel_status_bar.xml
index ada980cda1..9023d68ea9 100644
--- a/indra/newview/skins/default/xui/en/panel_status_bar.xml
+++ b/indra/newview/skins/default/xui/en/panel_status_bar.xml
@@ -35,7 +35,7 @@
</panel.string>
<panel
height="18"
- left="-458"
+ left="-398"
top="0"
width="120"
follows="right|top"
@@ -75,7 +75,7 @@
</panel>
<panel
height="18"
- left="-458"
+ left="-398"
width="185"
top="1"
follows="right|top"
@@ -142,7 +142,7 @@
left_pad="0"
name="TimeText"
tool_tip="Current time (Pacific)"
- width="145">
+ width="85">
24:00 AM PST
</text>
<icon
diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml
index f604a16b0b..d115e09d5b 100644
--- a/indra/newview/skins/default/xui/en/strings.xml
+++ b/indra/newview/skins/default/xui/en/strings.xml
@@ -2298,7 +2298,7 @@ For AI Character: Get the closest navigable point to the point provided.
<string name="InventoryNoMatchingItems">Didn't find what you're looking for? Try [secondlife:///app/search/all/[SEARCH_TERM] Search].</string>
<string name="InventoryNoMatchingRecentItems">Didn't find what you're looking for? Try [secondlife:///app/inventory/filters Show filters].</string>
<string name="PlacesNoMatchingItems">To add a place to your landmarks, click the star to the right of the location name.</string>
- <string name="FavoritesNoMatchingItems">To add a place to your favorites bar, click the star to the right of the location name.</string>
+ <string name="FavoritesNoMatchingItems">To add a place to your favorites, click the star to the right of the location name, then save the landmark to "Favorites bar".</string>
<string name="MarketplaceNoListing">You have no listings yet.</string>
<string name="MarketplaceNoMatchingItems">No items found. Check the spelling of your search string and try again.</string>
<string name="InventoryNoTexture">You do not have a copy of this texture in your inventory</string>
diff --git a/indra/newview/tests/cppfeatures_test.cpp b/indra/newview/tests/cppfeatures_test.cpp
new file mode 100644
index 0000000000..923bb1e1b2
--- /dev/null
+++ b/indra/newview/tests/cppfeatures_test.cpp
@@ -0,0 +1,386 @@
+/**
+ * @file cppfeatures_test
+ * @author Vir
+ * @date 2021-03
+ * @brief cpp features
+ *
+ * $LicenseInfo:firstyear=2021&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2021, 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$
+ */
+
+// Tests related to newer C++ features, for verifying support across compilers and platforms
+
+#include "linden_common.h"
+#include "../test/lltut.h"
+
+namespace tut
+{
+
+struct cpp_features_test {};
+typedef test_group<cpp_features_test> cpp_features_test_t;
+typedef cpp_features_test_t::object cpp_features_test_object_t;
+tut::cpp_features_test_t tut_cpp_features_test("LLCPPFeatures");
+
+// bracket initializers
+// Can initialize containers or values using curly brackets
+template<> template<>
+void cpp_features_test_object_t::test<1>()
+{
+ S32 explicit_val{3};
+ ensure(explicit_val==3);
+
+ S32 default_val{};
+ ensure(default_val==0);
+
+ std::vector<S32> fibs{1,1,2,3,5};
+ ensure(fibs[4]==5);
+}
+
+// auto
+//
+// https://en.cppreference.com/w/cpp/language/auto
+//
+// Can use auto in place of a more complex type specification, if the compiler can infer the type
+template<> template<>
+void cpp_features_test_object_t::test<2>()
+{
+ std::vector<S32> numbers{3,6,9};
+
+ // auto element
+ auto& aval = numbers[1];
+ ensure("auto element", aval==6);
+
+ // auto iterator (non-const)
+ auto it = numbers.rbegin();
+ *it += 1;
+ S32 val = *it;
+ ensure("auto iterator", val==10);
+}
+
+// range for
+//
+// https://en.cppreference.com/w/cpp/language/range-for
+//
+// Can iterate over containers without explicit iterator
+template<> template<>
+void cpp_features_test_object_t::test<3>()
+{
+
+ // Traditional iterator for with container
+ //
+ // Problems:
+ // * Have to create a new variable for the iterator, which is unrelated to the problem you're trying to solve.
+ // * Redundant and somewhat fragile. Have to make sure begin() and end() are both from the right container.
+ std::vector<S32> numbers{3,6,9};
+ for (auto it = numbers.begin(); it != numbers.end(); ++it)
+ {
+ auto& n = *it;
+ n *= 2;
+ }
+ ensure("iterator for vector", numbers[2]==18);
+
+ // Range for with container
+ //
+ // Under the hood, this is doing the same thing as the traditional
+ // for loop above. Still uses begin() and end() but you don't have
+ // to access them directly.
+ std::vector<S32> numbersb{3,6,9};
+ for (auto& n: numbersb)
+ {
+ n *= 2;
+ }
+ ensure("range for vector", numbersb[2]==18);
+
+ // Range for over a C-style array.
+ //
+ // This is handy because the language determines the range automatically.
+ // Getting this right manually is a little trickier.
+ S32 pows[] = {1,2,4,8,16};
+ S32 sum{};
+ for (const auto& v: pows)
+ {
+ sum += v;
+ }
+ ensure("for C-array", sum==31);
+}
+
+// override specifier
+//
+// https://en.cppreference.com/w/cpp/language/override
+//
+// Specify that a particular class function is an override of a virtual function.
+// Benefits:
+// * Makes code somewhat easier to read by showing intent.
+// * Prevents mistakes where you think something is an override but it doesn't actually match the declaration in the parent class.
+// Drawbacks:
+// * Some compilers require that any class using override must use it consistently for all functions.
+// This makes switching a class to use override a lot more work.
+
+class Foo
+{
+public:
+ virtual bool is_happy() const = 0;
+};
+
+class Bar: public Foo
+{
+public:
+ bool is_happy() const override { return true; }
+ // Override would fail: non-const declaration doesn't match parent
+ // bool is_happy() override { return true; }
+ // Override would fail: wrong name
+ // bool is_happx() override { return true; }
+};
+
+template<> template<>
+void cpp_features_test_object_t::test<4>()
+{
+ Bar b;
+ ensure("override", b.is_happy());
+}
+
+// final
+//
+// https://en.cppreference.com/w/cpp/language/final: "Specifies that a
+// virtual function cannot be overridden in a derived class or that a
+// class cannot be inherited from."
+
+class Vehicle
+{
+public:
+ virtual bool has_wheels() const = 0;
+};
+
+class WheeledVehicle: public Vehicle
+{
+public:
+ virtual bool has_wheels() const final override { return true; }
+};
+
+class Bicycle: public WheeledVehicle
+{
+public:
+ // Error: can't override final version in WheeledVehicle
+ // virtual bool has_wheels() override const { return true; }
+};
+
+template<> template<>
+void cpp_features_test_object_t::test<5>()
+{
+ Bicycle bi;
+ ensure("final", bi.has_wheels());
+}
+
+// deleted function declaration
+//
+// https://en.cppreference.com/w/cpp/language/function#Deleted_functions
+//
+// Typical case: copy constructor doesn't make sense for a particular class, so you want to make
+// sure the no one tries to copy-construct an instance of the class, and that the
+// compiler won't generate a copy constructor for you automatically.
+// Traditional fix is to declare a
+// copy constructor but never implement it, giving you a link-time error if anyone tries to use it.
+// Now you can explicitly declare a function to be deleted, which has at least two advantages over
+// the old way:
+// * Makes the intention clear
+// * Creates an error sooner, at compile time
+
+class DoNotCopy
+{
+public:
+ DoNotCopy() {}
+ DoNotCopy(const DoNotCopy& ref) = delete;
+};
+
+template<> template<>
+void cpp_features_test_object_t::test<6>()
+{
+ DoNotCopy nc; // OK, default constructor
+ //DoNotCopy nc2(nc); // No, can't copy
+ //DoNotCopy nc3 = nc; // No, this also calls copy constructor (even though it looks like an assignment)
+}
+
+// defaulted function declaration
+//
+// https://en.cppreference.com/w/cpp/language/function#Function_definition
+//
+// What about the complementary case to the deleted function declaration, where you want a copy constructor
+// and are happy with the default implementation the compiler will make (memberwise copy).
+// Now you can explicitly declare that too.
+// Usage: I guess it makes the intent clearer, but otherwise not obviously useful.
+class DefaultCopyOK
+{
+public:
+ DefaultCopyOK(): mVal(123) {}
+ DefaultCopyOK(const DefaultCopyOK&) = default;
+ S32 val() const { return mVal; }
+private:
+ S32 mVal;
+};
+
+template<> template<>
+void cpp_features_test_object_t::test<7>()
+{
+ DefaultCopyOK d; // OK
+ DefaultCopyOK d2(d); // OK
+ DefaultCopyOK d3 = d; // OK
+ ensure("default copy d", d.val()==123);
+ ensure("default copy d2", d.val()==d2.val());
+ ensure("default copy d3", d.val()==d3.val());
+}
+
+// initialize class members inline
+//
+// https://en.cppreference.com/w/cpp/language/data_members#Member_initialization
+//
+// Default class member values can be set where they are declared, using either brackets or =
+
+// It is preferred to skip creating a constructor if all the work can be done by inline initialization:
+// http://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines.html#c45-dont-define-a-default-constructor-that-only-initializes-data-members-use-in-class-member-initializers-instead
+//
+class InitInline
+{
+public:
+ S32 mFoo{10};
+};
+
+class InitInlineWithConstructor
+{
+public:
+ // Here mFoo is not specified, so you will get the default value of 10.
+ // mBar is specified, so 25 will override the default value.
+ InitInlineWithConstructor():
+ mBar(25)
+ {}
+
+ // Default values set using two different styles, same effect.
+ S32 mFoo{10};
+ S32 mBar = 20;
+};
+
+template<> template<>
+void cpp_features_test_object_t::test<8>()
+{
+ InitInline ii;
+ ensure("init member inline 1", ii.mFoo==10);
+
+ InitInlineWithConstructor iici;
+ ensure("init member inline 2", iici.mFoo=10);
+ ensure("init member inline 3", iici.mBar==25);
+}
+
+// constexpr
+//
+// https://en.cppreference.com/w/cpp/language/constexpr
+//
+// Various things can be computed at compile time, and flagged as constexpr.
+constexpr S32 compute2() { return 2; }
+
+constexpr S32 ce_factorial(S32 n)
+{
+ if (n<=0)
+ {
+ return 1;
+ }
+ else
+ {
+ return n*ce_factorial(n-1);
+ }
+}
+
+template<> template<>
+void cpp_features_test_object_t::test<9>()
+{
+ S32 val = compute2();
+ ensure("constexpr 1", val==2);
+
+ // Compile-time factorial. You used to need complex templates to do something this useless.
+ S32 fac5 = ce_factorial(5);
+ ensure("constexpr 2", fac5==120);
+}
+
+// static assert
+//
+// https://en.cppreference.com/w/cpp/language/static_assert
+//
+// You can add asserts to be checked at compile time. The thing to be checked must be a constexpr.
+// There are two forms:
+// * static_assert(expr);
+// * static_assert(expr, message);
+//
+// Currently only the 2-parameter form works on windows. The 1-parameter form needs a flag we don't set.
+
+template<> template<>
+void cpp_features_test_object_t::test<10>()
+{
+ // static_assert(ce_factorial(6)==720); No, needs a flag we don't currently set.
+ static_assert(ce_factorial(6)==720, "bad factorial"); // OK
+}
+
+// type aliases
+//
+// https://en.cppreference.com/w/cpp/language/type_alias
+//
+// You can use the "using" statement to create simpler templates that
+// are aliases for more complex ones. "Template typedef"
+
+// This makes stringmap<T> an alias for std::map<std::string, T>
+template<typename T>
+using stringmap = std::map<std::string, T>;
+
+template<> template<>
+void cpp_features_test_object_t::test<11>()
+{
+ stringmap<S32> name_counts{ {"alice", 3}, {"bob", 2} };
+ ensure("type alias", name_counts["bob"]==2);
+}
+
+// Other possibilities:
+
+// nullptr
+
+// class enums
+
+// std::unique_ptr and make_unique
+
+// std::shared_ptr and make_shared
+
+// lambdas
+
+// perfect forwarding
+
+// variadic templates
+
+// std::thread
+
+// std::mutex
+
+// thread_local
+
+// rvalue reference &&
+
+// move semantics
+
+// std::move
+
+// string_view
+
+} // namespace tut
diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py
index c0a0a7ec46..ce7df2ccb5 100755
--- a/indra/newview/viewer_manifest.py
+++ b/indra/newview/viewer_manifest.py
@@ -620,11 +620,9 @@ class WindowsManifest(ViewerManifest):
# CEF files common to all configurations
with self.prefix(src=os.path.join(pkgdir, 'resources')):
- self.path("cef.pak")
- self.path("cef_100_percent.pak")
- self.path("cef_200_percent.pak")
- self.path("cef_extensions.pak")
- self.path("devtools_resources.pak")
+ self.path("chrome_100_percent.pak")
+ self.path("chrome_200_percent.pak")
+ self.path("resources.pak")
self.path("icudtl.dat")
with self.prefix(src=os.path.join(pkgdir, 'resources', 'locales'), dst='locales'):