diff options
386 files changed, 6597 insertions, 6562 deletions
diff --git a/.gitignore b/.gitignore index 839d14bc0d..80eca667df 100755 --- a/.gitignore +++ b/.gitignore @@ -20,11 +20,8 @@ indra/.distcc build-vc80/ build-vc100/ build-vc120/ -build-vc120-32/ -build-vc120-64/ -build-vc150-32/ -build-vc150-64/ -build-vc160-64/ +build-vc*-32/ +build-vc*-64/ indra/CMakeFiles indra/build-vc[0-9]* indra/lib/mono/1.0/*.dll diff --git a/autobuild.xml b/autobuild.xml index d4d5e08bcb..54a5699c53 100644 --- a/autobuild.xml +++ b/autobuild.xml @@ -52,9 +52,9 @@ <key>archive</key> <map> <key>hash</key> - <string>b6357ef3a0ec37877a5831820f25094e</string> + <string>178b16ee9ff67986c8c14413ee68218e</string> <key>url</key> - <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/80557/759704/apr_suite-1.4.5.558565-darwin64-558565.tar.bz2</string> + <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/107593/938535/apr_suite-1.4.5.576669-darwin64-576669.tar.bz2</string> </map> <key>name</key> <string>darwin64</string> @@ -76,9 +76,9 @@ <key>archive</key> <map> <key>hash</key> - <string>cb48ac069440f6dcd564cfa9fd02a4c2</string> + <string>d2997cad03dbd0d70a060276b5671480</string> <key>url</key> - <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/80556/759710/apr_suite-1.4.5.558565-windows-558565.tar.bz2</string> + <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/107594/938548/apr_suite-1.4.5.576669-windows-576669.tar.bz2</string> </map> <key>name</key> <string>windows</string> @@ -88,16 +88,16 @@ <key>archive</key> <map> <key>hash</key> - <string>646dc3828d9c39fb1e77c4eec44ed739</string> + <string>ec24f5945faa8f13807b83eeaeb994f8</string> <key>url</key> - <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/80555/759709/apr_suite-1.4.5.558565-windows64-558565.tar.bz2</string> + <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/107592/938547/apr_suite-1.4.5.576669-windows64-576669.tar.bz2</string> </map> <key>name</key> <string>windows64</string> </map> </map> <key>version</key> - <string>1.4.5.558565</string> + <string>1.4.5.576669</string> </map> <key>boost</key> <map> @@ -236,9 +236,9 @@ <key>archive</key> <map> <key>hash</key> - <string>4699b8389dfb754da0393ddb5d325722</string> + <string>a880dfc15fcb330baf548a85324cd88a</string> <key>url</key> - <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/95882/856117/colladadom-2.3.569219-darwin64-569219.tar.bz2</string> + <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/104133/913090/colladadom-2.3.574693-darwin64-574693.tar.bz2</string> </map> <key>name</key> <string>darwin64</string> @@ -260,9 +260,9 @@ <key>archive</key> <map> <key>hash</key> - <string>343e46ea49a08ad6596d3dc702d5b812</string> + <string>7e84441d9c7cf019a7bdc7b818b16c27</string> <key>url</key> - <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/95883/856128/colladadom-2.3.569219-windows-569219.tar.bz2</string> + <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/104112/912957/colladadom-2.3.574693-windows-574693.tar.bz2</string> </map> <key>name</key> <string>windows</string> @@ -272,16 +272,16 @@ <key>archive</key> <map> <key>hash</key> - <string>de5bdfb61b31db56c5fe7d0962ad11e2</string> + <string>2eaffbb8a93b03a732d3c47055a8efcb</string> <key>url</key> - <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/95884/856129/colladadom-2.3.569219-windows64-569219.tar.bz2</string> + <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/104135/913103/colladadom-2.3.574693-windows64-574693.tar.bz2</string> </map> <key>name</key> <string>windows64</string> </map> </map> <key>version</key> - <string>2.3.569219</string> + <string>2.3.574693</string> </map> <key>cubemaptoequirectangular</key> <map> @@ -331,6 +331,16 @@ <key>name</key> <string>windows64</string> </map> + <key>linux64</key> + <map> + <key>archive</key> + <map> + <key>hash</key> + <string>ac54672e0b38f52726f5c99047c913e4</string> + <key>url</key> + <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/89306/815431/cubemaptoequirectangular-1.1.0-windows64-564841.tar.bz2</string> + </map> + </map> </map> <key>version</key> <string>1.1.0</string> @@ -1077,6 +1087,16 @@ <key>name</key> <string>windows64</string> </map> + <key>linux64</key> + <map> + <key>archive</key> + <map> + <key>hash</key> + <string>e70898903475d8ac2e81ff33278fc987</string> + <key>url</key> + <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/89309/815433/jpegencoderbasic-1.0-windows64-564842.tar.bz2</string> + </map> + </map> </map> <key>version</key> <string>1.0</string> @@ -1418,9 +1438,9 @@ <key>archive</key> <map> <key>hash</key> - <string>c1c9e32e21f3c34d91ed045b2ca91f24</string> + <string>7a0059748d0b8733f2f9ce434cf604b8</string> <key>url</key> - <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/87781/805801/libpng-1.6.8.563850-darwin64-563850.tar.bz2</string> + <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/107514/937867/libpng-1.6.38.576621-darwin64-576621.tar.bz2</string> </map> <key>name</key> <string>darwin64</string> @@ -1442,9 +1462,9 @@ <key>archive</key> <map> <key>hash</key> - <string>642e9cf95c8ccd0eb34f6d7a40df585a</string> + <string>3112013186ad60b0fc270a398d4dd499</string> <key>url</key> - <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/87782/805831/libpng-1.6.8.563850-windows-563850.tar.bz2</string> + <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/107513/937823/libpng-1.6.38.576621-windows-576621.tar.bz2</string> </map> <key>name</key> <string>windows</string> @@ -1454,16 +1474,16 @@ <key>archive</key> <map> <key>hash</key> - <string>ce46aa0f171d97626c4a3940347cecd7</string> + <string>7c6bfcdb0d6162587cdbc436f595dd02</string> <key>url</key> - <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/87780/805832/libpng-1.6.8.563850-windows64-563850.tar.bz2</string> + <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/107512/937822/libpng-1.6.38.576621-windows64-576621.tar.bz2</string> </map> <key>name</key> <string>windows64</string> </map> </map> <key>version</key> - <string>1.6.8.563850</string> + <string>1.6.38.576621</string> </map> <key>libuuid</key> <map> @@ -1639,9 +1659,9 @@ <key>archive</key> <map> <key>hash</key> - <string>da57838d80cf332f4a3026713a13f086</string> + <string>e51c6f5dfd76eb148348a44ff57e66c2</string> <key>url</key> - <string>https://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/90708/824484/llphysicsextensions_source-1.0.565754-darwin64-565754.tar.bz2</string> + <string>https://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/104810/918016/llphysicsextensions_source-1.0.575107-darwin64-575107.tar.bz2</string> </map> <key>name</key> <string>darwin64</string> @@ -1663,9 +1683,9 @@ <key>archive</key> <map> <key>hash</key> - <string>28ad884012aa0bb70cf4101853af2f9a</string> + <string>dbbe4cc568ac149d862e421cdda4dd48</string> <key>url</key> - <string>https://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/90733/824570/llphysicsextensions_source-1.0.565768-windows-565768.tar.bz2</string> + <string>https://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/104809/918011/llphysicsextensions_source-1.0.575107-windows-575107.tar.bz2</string> </map> <key>name</key> <string>windows</string> @@ -2195,9 +2215,9 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string> <key>archive</key> <map> <key>hash</key> - <string>5abf2d9c0b250821c59cc60cd94fd8af</string> + <string>8114c6a7e499ea20d325db0de08ce30a</string> <key>url</key> - <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/54840/510064/openjpeg-1.5.1.538970-darwin64-538970.tar.bz2</string> + <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/105469/923024/openjpeg-2.5.0.575496-darwin64-575496.tar.bz2</string> </map> <key>name</key> <string>darwin64</string> @@ -2219,9 +2239,9 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string> <key>archive</key> <map> <key>hash</key> - <string>222a406ecb4071a9cc9635353afa337e</string> + <string>edc9388870d951632a6d595792293e05</string> <key>url</key> - <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/54977/511775/openjpeg-1.5.1.538970-windows-538970.tar.bz2</string> + <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/105472/923036/openjpeg-2.5.0.575496-windows-575496.tar.bz2</string> </map> <key>name</key> <string>windows</string> @@ -2231,16 +2251,16 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string> <key>archive</key> <map> <key>hash</key> - <string>5b5c80807fa8161f3480be3d89fe9516</string> + <string>b95f0732f2388ebb0ddf33d4a30e0ff1</string> <key>url</key> - <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/54974/511767/openjpeg-1.5.1.538970-windows64-538970.tar.bz2</string> + <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/105471/923037/openjpeg-2.5.0.575496-windows64-575496.tar.bz2</string> </map> <key>name</key> <string>windows64</string> </map> </map> <key>version</key> - <string>1.5.1.538970</string> + <string>2.5.0.575496</string> </map> <key>openssl</key> <map> @@ -2488,6 +2508,16 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string> <key>name</key> <string>windows64</string> </map> + <key>linux64</key> + <map> + <key>archive</key> + <map> + <key>hash</key> + <string>46edf0f55417f8ef0d33a5c007bc3644</string> + <key>url</key> + <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/89310/815451/threejs-0.132.2-windows64-564843.tar.bz2</string> + </map> + </map> </map> <key>version</key> <string>0.132.2</string> @@ -2671,9 +2701,9 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string> <key>archive</key> <map> <key>hash</key> - <string>2e8d817e7837dd6f4284b13fa3f5c15e</string> + <string>9e1b5515ab59b4e9cfeef6626d65d03d</string> <key>url</key> - <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/104765/917714/viewer_manager-3.0.575083-darwin64-575083.tar.bz2</string> + <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/108609/945996/viewer_manager-3.0.577252-darwin64-577252.tar.bz2</string> </map> <key>name</key> <string>darwin64</string> @@ -2683,9 +2713,9 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string> <key>archive</key> <map> <key>hash</key> - <string>3efa80faaf537e39a77218cd6efa9409</string> + <string>a3c599595ecc8fb987a5499fca42520a</string> <key>url</key> - <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/104766/917721/viewer_manager-3.0.575083-windows-575083.tar.bz2</string> + <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/108610/946003/viewer_manager-3.0.577252-windows-577252.tar.bz2</string> </map> <key>name</key> <string>windows</string> @@ -2696,7 +2726,7 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string> <key>source_type</key> <string>hg</string> <key>version</key> - <string>3.0.575083</string> + <string>3.0.577252</string> </map> <key>vlc-bin</key> <map> @@ -3021,6 +3051,68 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string> <key>name</key> <string>common</string> </map> + <key>linux64</key> + <map> + <key>build_directory</key> + <string>build-linux-x86_64</string> + <key>configurations</key> + <map> + <key>Release</key> + <map> + <key>build</key> + <map> + <key>command</key> + <string>ninja</string> + </map> + <key>configure</key> + <map> + <key>arguments</key> + <array> + <string>../indra</string> + </array> + <key>options</key> + <array> + <string>-G</string> + <string>Ninja</string> + <string>-DLL_TESTS=Off</string> + </array> + </map> + <key>default</key> + <string>True</string> + <key>name</key> + <string>Release</string> + </map> + <key>ReleaseOS</key> + <map> + <key>build</key> + <map> + <key>command</key> + <string>ninja</string> + </map> + <key>configure</key> + <map> + <key>options</key> + <array> + <string>-G</string> + <string>Ninja</string> + <string>-DLL_TESTS=Off</string> + </array> + </map> + <key>name</key> + <string>ReleaseOS</string> + </map> + <key>default</key> + <map> + <key>build</key> + <map> + </map> + <key>name</key> + <string>default</string> + </map> + </map> + <key>name</key> + <string>linux64</string> + </map> <key>darwin64</key> <map> <key>build_directory</key> @@ -3144,7 +3236,7 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string> <key>windows</key> <map> <key>build_directory</key> - <string>build-vc${AUTOBUILD_VSVER|150}-$AUTOBUILD_ADDRSIZE</string> + <string>build-vc${AUTOBUILD_VSVER|170}-$AUTOBUILD_ADDRSIZE</string> <key>configurations</key> <map> <key>RelWithDebInfo</key> @@ -3173,6 +3265,8 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string> <array> <string>-G</string> <string>${AUTOBUILD_WIN_CMAKE_GEN|NOTWIN}</string> + <string>-A</string> + <string>${AUTOBUILD_WIN_VSPLATFORM|NOTWIN}</string> </array> </map> <key>default</key> @@ -3211,9 +3305,11 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string> <array> <string>-G</string> <string>${AUTOBUILD_WIN_CMAKE_GEN|NOTWIN}</string> + <string>-A</string> + <string>${AUTOBUILD_WIN_VSPLATFORM|NOTWIN}</string> <string>-DINSTALL_PROPRIETARY=FALSE</string> <string>-DUSE_KDU=FALSE</string> - <string>-DOPENAL:BOOL=ON</string> + <string>-DUSE_OPENAL:BOOL=ON</string> </array> </map> <key>name</key> @@ -3245,6 +3341,8 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string> <array> <string>-G</string> <string>${AUTOBUILD_WIN_CMAKE_GEN|NOTWIN}</string> + <string>-A</string> + <string>${AUTOBUILD_WIN_VSPLATFORM|NOTWIN}</string> </array> </map> <key>name</key> @@ -3281,10 +3379,12 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string> <array> <string>-G</string> <string>${AUTOBUILD_WIN_CMAKE_GEN|NOTWIN}</string> + <string>-A</string> + <string>${AUTOBUILD_WIN_VSPLATFORM|NOTWIN}</string> <string>-DUNATTENDED:BOOL=ON</string> <string>-DINSTALL_PROPRIETARY=FALSE</string> <string>-DUSE_KDU=FALSE</string> - <string>-DOPENAL:BOOL=ON</string> + <string>-DUSE_OPENAL:BOOL=ON</string> </array> </map> <key>name</key> diff --git a/doc/contributions.txt b/doc/contributions.txt index babcd4b61d..8dbf2c8b12 100755 --- a/doc/contributions.txt +++ b/doc/contributions.txt @@ -282,6 +282,7 @@ Beq Janus SL-11300 SL-15709 SL-16021 + SL-18592 SL-18637 Beth Walcher Bezilon Kasei @@ -373,6 +374,7 @@ Charlie Sazaland Chaser Zaks BUG-225599 BUG-227485 + SL-16874 Cherry Cheevers ChickyBabes Zuzu Chorazin Allen @@ -1130,6 +1132,7 @@ Nicky Dasmijn SL-14541 SL-16438 SL-17218 + SL-17238 SL-17585 Nicky Perian OPEN-1 @@ -1391,6 +1394,7 @@ Sovereign Engineer OPEN-343 SL-11625 BUG-229030 + SL-14696 SL-14705 SL-14706 SL-14707 @@ -1398,6 +1402,12 @@ Sovereign Engineer SL-14732 SL-15096 SL-16127 + SL-18249 + SL-18394 + SL-18412 + SL-18497 + SL-18525 + SL-18534 SpacedOut Frye VWR-34 VWR-45 @@ -1660,6 +1670,8 @@ Zi Ree VWR-25588 STORM-1790 STORM-1842 + SL-18348 + SL-18593 Zipherius Turas VWR-76 VWR-77 diff --git a/indra/CMakeLists.txt b/indra/CMakeLists.txt index 68f6e962ef..205ce402a0 100644 --- a/indra/CMakeLists.txt +++ b/indra/CMakeLists.txt @@ -4,22 +4,43 @@ # other commands to guarantee full compatibility # with the version specified ## 3.8 added VS_DEBUGGER_WORKING_DIRECTORY support -cmake_minimum_required(VERSION 3.8.0 FATAL_ERROR) +## 3.13/12 is needed for add_link_options/add_compile_definitions +## 3.14 added FILE CREATE_LINK +## 3.16 is needed for target_precompile_headers +## Nicky: Ideally we want at least 3.21 for good preset support +## We're not there yet, but once done, there is a kludge in Linking.cmake +# "if(${CMAKE_VERSION} VERSION_LESS "3.20.0")" that can also be removed +cmake_minimum_required(VERSION 3.16.0 FATAL_ERROR) set(ROOT_PROJECT_NAME "SecondLife" CACHE STRING "The root project/makefile/solution name. Defaults to SecondLife.") project(${ROOT_PROJECT_NAME}) -set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake") +set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake" "${CMAKE_CURRENT_BINARY_DIR}") + +include(conanbuildinfo OPTIONAL RESULT_VARIABLE USE_CONAN ) +if( USE_CONAN ) + set( USE_CONAN ON ) + set( USE_AUTOBUILD_3P OFF ) + conan_basic_setup(TARGETS NO_OUTPUT_DIRS) + add_compile_definitions(LL_USESYSTEMLIBS USE_CONAN NO_AUTOBUILD_3P) +else() + set( USE_CONAN OFF ) + set( USE_AUTOBUILD_3P ON ) +endif() + +# The viewer code base can now be successfully compiled with -std=c++14. But +# turning that on in the generic viewer-build-variables/variables file would +# potentially require tweaking each of our ~50 third-party library builds. +# Until we decide to set -std=c++14 in viewer-build-variables/variables, set +# it locally here: we want to at least prevent inadvertently reintroducing +# viewer code that would fail with C++14. +set(CMAKE_CXX_STANDARD 17) +set(CMAKE_CXX_STANDARD_REQUIRED ON) include(Variables) include(BuildVersion) -set(LEGACY_STDIO_LIBS) -if (WINDOWS) - set(LEGACY_STDIO_LIBS legacy_stdio_definitions) -endif (WINDOWS) - if (NOT CMAKE_BUILD_TYPE) set(CMAKE_BUILD_TYPE RelWithDebInfo CACHE STRING "Build type. One of: Debug Release RelWithDebInfo" FORCE) @@ -59,8 +80,10 @@ add_subdirectory(${LIBS_OPEN_PREFIX}llplugin) add_subdirectory(${LIBS_OPEN_PREFIX}llui) add_subdirectory(${LIBS_OPEN_PREFIX}viewer_components) +if( LL_TESTS ) # Legacy C++ tests. Build always, run if LL_TESTS is true. add_subdirectory(${VIEWER_PREFIX}test) +endif() if (ENABLE_MEDIA_PLUGINS) # viewer media plugins @@ -72,7 +95,6 @@ if (LINUX) include(LLAppearanceUtility) add_subdirectory(${LLAPPEARANCEUTILITY_SRC_DIR} ${LLAPPEARANCEUTILITY_BIN_DIR}) endif (INSTALL_PROPRIETARY) - add_dependencies(viewer linux-crash-logger-strip-target) elseif (WINDOWS) # cmake EXISTS requires an absolute path, see indra/cmake/Variables.cmake if (EXISTS ${VIEWER_DIR}win_setup) @@ -87,12 +109,6 @@ if (WINDOWS) endif (EXISTS ${VIEWER_DIR}win_setup) endif (WINDOWS) -# sets the 'startup project' for debugging from visual studio. -set_property( - DIRECTORY ${VIEWER_PREFIX} - PROPERTY VS_STARTUP_PROJECT secondlife-bin - ) - if (USE_BUGSPLAT) if (BUGSPLAT_DB) message(STATUS "Building with BugSplat; database '${BUGSPLAT_DB}'") @@ -108,6 +124,12 @@ add_dependencies(viewer secondlife-bin) add_subdirectory(${VIEWER_PREFIX}doxygen EXCLUDE_FROM_ALL) +# sets the 'startup project' for debugging from visual studio. +set_property( + DIRECTORY ${VIEWER_PREFIX} + PROPERTY VS_STARTUP_PROJECT ${VIEWER_BINARY_NAME} + ) + if (LL_TESTS) # Define after the custom targets are created so # individual apps can add themselves as dependencies diff --git a/indra/cmake/00-Common.cmake b/indra/cmake/00-Common.cmake index 572422d080..c848d00710 100644 --- a/indra/cmake/00-Common.cmake +++ b/indra/cmake/00-Common.cmake @@ -12,9 +12,7 @@ # Also realize that CMAKE_CXX_FLAGS may already be partially populated on # entry to this file. #***************************************************************************** - -if(NOT DEFINED ${CMAKE_CURRENT_LIST_FILE}_INCLUDED) -set(${CMAKE_CURRENT_LIST_FILE}_INCLUDED "YES") +include_guard() include(Variables) @@ -27,25 +25,22 @@ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} $ENV{LL_BUILD}") # as well? # Portable compilation flags. -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DADDRESS_SIZE=${ADDRESS_SIZE}") +add_compile_definitions( ADDRESS_SIZE=${ADDRESS_SIZE}) # Configure crash reporting set(RELEASE_CRASH_REPORTING OFF CACHE BOOL "Enable use of crash reporting in release builds") set(NON_RELEASE_CRASH_REPORTING OFF CACHE BOOL "Enable use of crash reporting in developer builds") if(RELEASE_CRASH_REPORTING) - set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -DLL_SEND_CRASH_REPORTS=1") + add_compile_definitions( LL_SEND_CRASH_REPORTS=1) endif() if(NON_RELEASE_CRASH_REPORTING) - set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} -DLL_SEND_CRASH_REPORTS=1") - set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DLL_SEND_CRASH_REPORTS=1") -endif() - -# Don't bother with MinSizeRel or Debug builds. -set(CMAKE_CONFIGURATION_TYPES "RelWithDebInfo;Release" CACHE STRING - "Supported build types." FORCE) + add_compile_definitions( LL_SEND_CRASH_REPORTS=1) +endif() +# Don't bother with a MinSizeRel or Debug builds. +set(CMAKE_CONFIGURATION_TYPES "RelWithDebInfo;Release" CACHE STRING "Supported build types." FORCE) # Platform-specific compilation flags. @@ -66,98 +61,94 @@ if (WINDOWS) # CP changed to only append the flag for 32bit builds - on 64bit builds, # locally at least, the build output is spammed with 1000s of 'D9002' # warnings about this switch being ignored. - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /MP") if( ADDRESS_SIZE EQUAL 32 ) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /p:PreferredToolArchitecture=x64") endif() - # Preserve first-pass-through versions (ie no FORCE overwrite). Prevents recursive addition of /Zo (04/2021) - set(OG_CMAKE_CXX_FLAGS_RELEASE ${CMAKE_CXX_FLAGS_RELEASE} CACHE STRING "OG_CXX_FLAGS_RELEASE") - set(OG_CMAKE_CXX_FLAGS_RELWITHDEBINFO ${CMAKE_CXX_FLAGS_RELWITHDEBINFO} CACHE STRING "OG_CXX_FLAGS_RELWITHDEBINFO") - - set(CMAKE_CXX_FLAGS_RELWITHDEBINFO - "${OG_CMAKE_CXX_FLAGS_RELWITHDEBINFO} /Zo" - CACHE STRING "C++ compiler release-with-debug options" FORCE) - set(CMAKE_CXX_FLAGS_RELEASE - "${OG_CMAKE_CXX_FLAGS_RELEASE} ${LL_CXX_FLAGS} /Zo" - CACHE STRING "C++ compiler release options" FORCE) - # zlib has assembly-language object files incompatible with SAFESEH - set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /LARGEADDRESSAWARE /SAFESEH:NO /NODEFAULTLIB:LIBCMT /IGNORE:4099") - - set(CMAKE_CXX_STANDARD_LIBRARIES "") - set(CMAKE_C_STANDARD_LIBRARIES "") + add_link_options(/LARGEADDRESSAWARE + /SAFESEH:NO + /NODEFAULTLIB:LIBCMT + /IGNORE:4099) add_definitions( - /DNOMINMAX + -DNOMINMAX # /DDOM_DYNAMIC # For shared library colladadom ) add_compile_options( - /GS - /TP - /W3 - /c - /Zc:forScope - /nologo - /Oy- -# /arch:SSE2 - /fp:fast + /Zo + /GS + /TP + /W3 + /c + /Zc:forScope + /nologo + /Oy- + /fp:fast + /MP ) # Nicky: x64 implies SSE2 if( ADDRESS_SIZE EQUAL 32 ) - add_definitions( /arch:SSE2 ) + add_compile_options( /arch:SSE2 ) endif() # Are we using the crummy Visual Studio KDU build workaround? if (NOT VS_DISABLE_FATAL_WARNINGS) - add_definitions(/WX) + add_compile_options(/WX) endif (NOT VS_DISABLE_FATAL_WARNINGS) + + #ND: When using something like buildcache (https://github.com/mbitsnbites/buildcache) + # to make those wrappers work /Zi must be changed to /Z7, as /Zi due to it's nature is not compatible with caching + if( ${CMAKE_CXX_COMPILER_LAUNCHER} MATCHES ".*cache.*") + add_compile_options( /Z7 ) + string(REPLACE "/Zi" "/Z7" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}") + string(REPLACE "/Zi" "/Z7" CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE}") + string(REPLACE "/Zi" "/Z7" CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE}") + string(REPLACE "/Zi" "/Z7" CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELWITHDEBINFO}") + string(REPLACE "/Zi" "/Z7" CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO}") + endif() endif (WINDOWS) if (LINUX) set(CMAKE_SKIP_RPATH TRUE) - add_definitions(-D_FORTIFY_SOURCE=2) - - set(CMAKE_CXX_FLAGS "-Wno-deprecated -Wno-unused-but-set-variable -Wno-unused-variable ${CMAKE_CXX_FLAGS}") - - # gcc 4.3 and above don't like the LL boost and also - # cause warnings due to our use of deprecated headers - add_definitions(-Wno-parentheses) - - add_definitions( - -D_REENTRANT - ) + # EXTERNAL_TOS + # force this platform to accept TOS via external browser + + # LL_IGNORE_SIGCHLD + # don't catch SIGCHLD in our base application class for the viewer - some of + # our 3rd party libs may need their *own* SIGCHLD handler to work. Sigh! The + # viewer doesn't need to catch SIGCHLD anyway. + + add_compile_definitions( + _REENTRANT + _FORTIFY_SOURCE=2 + EXTERNAL_TOS + APPID=secondlife + LL_IGNORE_SIGCHLD + ) add_compile_options( - -fexceptions - -fno-math-errno - -fno-strict-aliasing - -fsigned-char - -msse2 - -mfpmath=sse - -pthread - ) - - # force this platform to accept TOS via external browser - add_definitions(-DEXTERNAL_TOS) + -fexceptions + -fno-math-errno + -fno-strict-aliasing + -fsigned-char + -msse2 + -mfpmath=sse + -pthread + -Wno-parentheses + -Wno-deprecated + -fvisibility=hidden + ) - add_definitions(-DAPPID=secondlife) - add_compile_options(-fvisibility=hidden) - # don't catch SIGCHLD in our base application class for the viewer - some of - # our 3rd party libs may need their *own* SIGCHLD handler to work. Sigh! The - # viewer doesn't need to catch SIGCHLD anyway. - add_definitions(-DLL_IGNORE_SIGCHLD) if (ADDRESS_SIZE EQUAL 32) add_compile_options(-march=pentium4) endif (ADDRESS_SIZE EQUAL 32) - #add_compile_options(-ftree-vectorize) # THIS CRASHES GCC 3.1-3.2 - if (NOT USESYSTEMLIBS) - # this stops us requiring a really recent glibc at runtime - add_compile_options(-fno-stack-protector) - # linking can be very memory-hungry, especially the final viewer link - set(CMAKE_CXX_LINK_FLAGS "-Wl,--no-keep-memory") - endif (NOT USESYSTEMLIBS) + + # this stops us requiring a really recent glibc at runtime + add_compile_options(-fno-stack-protector) + # linking can be very memory-hungry, especially the final viewer link + set(CMAKE_CXX_LINK_FLAGS "-Wl,--no-keep-memory") set(CMAKE_CXX_FLAGS_DEBUG "-fno-inline ${CMAKE_CXX_FLAGS_DEBUG}") endif (LINUX) @@ -173,13 +164,7 @@ if (DARWIN) # see Variables.cmake. string(REPLACE "-gdwarf-2" "-g${CMAKE_XCODE_ATTRIBUTE_DEBUG_INFORMATION_FORMAT}" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}") - # The viewer code base can now be successfully compiled with -std=c++14. But - # turning that on in the generic viewer-build-variables/variables file would - # potentially require tweaking each of our ~50 third-party library builds. - # Until we decide to set -std=c++14 in viewer-build-variables/variables, set - # it locally here: we want to at least prevent inadvertently reintroducing - # viewer code that would fail with C++14. - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${DARWIN_extra_cstar_flags} -std=c++14") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${DARWIN_extra_cstar_flags}") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${DARWIN_extra_cstar_flags}") # NOTE: it's critical that the optimization flag is put in front. # NOTE: it's critical to have both CXX_FLAGS and C_FLAGS covered. @@ -188,47 +173,17 @@ if (DARWIN) ##set(SIGNING_IDENTITY "Developer ID Application: Linden Research, Inc.") endif (DARWIN) - if (LINUX OR DARWIN) - if (CMAKE_CXX_COMPILER MATCHES ".*clang") - set(CMAKE_COMPILER_IS_CLANGXX 1) - endif (CMAKE_CXX_COMPILER MATCHES ".*clang") - - if (CMAKE_COMPILER_IS_GNUCXX) - set(GCC_WARNINGS "-Wall -Wno-sign-compare -Wno-trigraphs") - elseif (CMAKE_COMPILER_IS_CLANGXX) - set(GCC_WARNINGS "-Wall -Wno-sign-compare -Wno-trigraphs") - endif() + set(GCC_WARNINGS -Wall -Wno-sign-compare -Wno-trigraphs) if (NOT GCC_DISABLE_FATAL_WARNINGS) - set(GCC_WARNINGS "${GCC_WARNINGS} -Werror") + list(APPEND GCC_WARNINGS -Werror) endif (NOT GCC_DISABLE_FATAL_WARNINGS) - set(GCC_CXX_WARNINGS "${GCC_WARNINGS} -Wno-reorder -Wno-non-virtual-dtor") + list(APPEND GCC_WARNINGS -Wno-reorder -Wno-non-virtual-dtor ) - set(CMAKE_C_FLAGS "${GCC_WARNINGS} ${CMAKE_C_FLAGS}") - set(CMAKE_CXX_FLAGS "${GCC_CXX_WARNINGS} ${CMAKE_CXX_FLAGS}") - - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -m${ADDRESS_SIZE}") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -m${ADDRESS_SIZE}") + add_compile_options(${GCC_WARNINGS}) + add_compile_options(-m${ADDRESS_SIZE}) endif (LINUX OR DARWIN) -if (USESYSTEMLIBS) - add_definitions(-DLL_USESYSTEMLIBS=1) - - if (LINUX AND ADDRESS_SIZE EQUAL 32) - add_definitions(-march=pentiumpro) - endif (LINUX AND ADDRESS_SIZE EQUAL 32) - -else (USESYSTEMLIBS) - set(${ARCH}_linux_INCLUDES - atk-1.0 - glib-2.0 - gstreamer-0.10 - gtk-2.0 - pango-1.0 - ) -endif (USESYSTEMLIBS) - -endif(NOT DEFINED ${CMAKE_CURRENT_LIST_FILE}_INCLUDED) diff --git a/indra/cmake/APR.cmake b/indra/cmake/APR.cmake index 9b64bc6160..8a0939c92c 100644 --- a/indra/cmake/APR.cmake +++ b/indra/cmake/APR.cmake @@ -1,54 +1,45 @@ include(Linking) include(Prebuilt) -set(APR_FIND_QUIETLY ON) -set(APR_FIND_REQUIRED ON) +include_guard() -set(APRUTIL_FIND_QUIETLY ON) -set(APRUTIL_FIND_REQUIRED ON) +add_library( ll::apr INTERFACE IMPORTED ) -if (USESYSTEMLIBS) - include(FindAPR) -else (USESYSTEMLIBS) - use_prebuilt_binary(apr_suite) - if (WINDOWS) - if (LLCOMMON_LINK_SHARED) - set(APR_selector "lib") - else (LLCOMMON_LINK_SHARED) - set(APR_selector "") - endif (LLCOMMON_LINK_SHARED) - set(APR_LIBRARIES - debug ${ARCH_PREBUILT_DIRS_DEBUG}/${APR_selector}apr-1.lib - optimized ${ARCH_PREBUILT_DIRS_RELEASE}/${APR_selector}apr-1.lib - ) - set(APRICONV_LIBRARIES - debug ${ARCH_PREBUILT_DIRS_DEBUG}/${APR_selector}apriconv-1.lib - optimized ${ARCH_PREBUILT_DIRS_RELEASE}/${APR_selector}apriconv-1.lib - ) - set(APRUTIL_LIBRARIES - debug ${ARCH_PREBUILT_DIRS_DEBUG}/${APR_selector}aprutil-1.lib ${APRICONV_LIBRARIES} - optimized ${ARCH_PREBUILT_DIRS_RELEASE}/${APR_selector}aprutil-1.lib ${APRICONV_LIBRARIES} - ) - elseif (DARWIN) - if (LLCOMMON_LINK_SHARED) - set(APR_selector "0.dylib") - set(APRUTIL_selector "0.dylib") - else (LLCOMMON_LINK_SHARED) - set(APR_selector "a") - set(APRUTIL_selector "a") - endif (LLCOMMON_LINK_SHARED) - set(APR_LIBRARIES libapr-1.${APR_selector}) - set(APRUTIL_LIBRARIES libaprutil-1.${APRUTIL_selector}) - set(APRICONV_LIBRARIES iconv) - else (WINDOWS) - set(APR_LIBRARIES apr-1) - set(APRUTIL_LIBRARIES aprutil-1) - set(APRICONV_LIBRARIES iconv) - endif (WINDOWS) - set(APR_INCLUDE_DIR ${LIBS_PREBUILT_DIR}/include/apr-1) +use_system_binary( apr apr-util ) +use_prebuilt_binary(apr_suite) - if (LINUX) - list(APPEND APRUTIL_LIBRARIES uuid) - list(APPEND APRUTIL_LIBRARIES rt) - endif (LINUX) -endif (USESYSTEMLIBS) +if (WINDOWS) + if (LLCOMMON_LINK_SHARED) + set(APR_selector "lib") + else (LLCOMMON_LINK_SHARED) + set(APR_selector "") + endif (LLCOMMON_LINK_SHARED) + target_link_libraries( ll::apr INTERFACE + ${ARCH_PREBUILT_DIRS_RELEASE}/${APR_selector}apr-1.lib + ${ARCH_PREBUILT_DIRS_RELEASE}/${APR_selector}apriconv-1.lib + ${ARCH_PREBUILT_DIRS_RELEASE}/${APR_selector}aprutil-1.lib + ) +elseif (DARWIN) + if (LLCOMMON_LINK_SHARED) + set(APR_selector "0.dylib") + set(APRUTIL_selector "0.dylib") + else (LLCOMMON_LINK_SHARED) + set(APR_selector "a") + set(APRUTIL_selector "a") + endif (LLCOMMON_LINK_SHARED) + + target_link_libraries( ll::apr INTERFACE + libapr-1.${APR_selector} + libaprutil-1.${APRUTIL_selector} + iconv + ) +else (WINDOWS) + target_link_libraries( ll::apr INTERFACE + apr-1 + aprutil-1 + iconv + uuid + rt + ) +endif (WINDOWS) +target_include_directories( ll::apr SYSTEM INTERFACE ${LIBS_PREBUILT_DIR}/include/apr-1 ) diff --git a/indra/cmake/Atmosphere.cmake b/indra/cmake/Atmosphere.cmake deleted file mode 100644 index 9c14df2a11..0000000000 --- a/indra/cmake/Atmosphere.cmake +++ /dev/null @@ -1,5 +0,0 @@ -# -*- cmake -*- -include(Prebuilt) -use_prebuilt_binary(libatmosphere) -set(LIBATMOSPHERE_LIBRARIES atmosphere) -set(LIBATMOSPHERE_INCLUDE_DIR ${LIBS_PREBUILT_DIR}/include/atmosphere) diff --git a/indra/cmake/Audio.cmake b/indra/cmake/Audio.cmake index f95439245a..38547bb017 100644 --- a/indra/cmake/Audio.cmake +++ b/indra/cmake/Audio.cmake @@ -1,42 +1,16 @@ # -*- cmake -*- include(Prebuilt) -if (USESYSTEMLIBS) - include(FindPkgConfig) - pkg_check_modules(OGG REQUIRED ogg) - pkg_check_modules(VORBIS REQUIRED vorbis) - pkg_check_modules(VORBISENC REQUIRED vorbisenc) - pkg_check_modules(VORBISFILE REQUIRED vorbisfile) -else (USESYSTEMLIBS) - use_prebuilt_binary(ogg_vorbis) - set(VORBIS_INCLUDE_DIRS ${LIBS_PREBUILT_DIR}/include) - set(VORBISENC_INCLUDE_DIRS ${VORBIS_INCLUDE_DIRS}) - set(VORBISFILE_INCLUDE_DIRS ${VORBIS_INCLUDE_DIRS}) +include_guard() +add_library( ll::vorbis INTERFACE IMPORTED ) - if (WINDOWS) - set(OGG_LIBRARIES - optimized ogg_static - debug ogg_static_d) - set(VORBIS_LIBRARIES - optimized vorbis_static - debug vorbis_static_d) - set(VORBISENC_LIBRARIES - optimized vorbisenc_static - debug vorbisenc_static_d) - set(VORBISFILE_LIBRARIES - optimized vorbisfile_static - debug vorbisfile_static_d) - else (WINDOWS) - set(OGG_LIBRARIES ogg) - set(VORBIS_LIBRARIES vorbis) - set(VORBISENC_LIBRARIES vorbisenc) - set(VORBISFILE_LIBRARIES vorbisfile) - endif (WINDOWS) -endif (USESYSTEMLIBS) +use_system_binary(vorbis) +use_prebuilt_binary(ogg_vorbis) +target_include_directories( ll::vorbis SYSTEM INTERFACE ${LIBS_PREBUILT_DIR}/include ) + +if (WINDOWS) + target_link_libraries(ll::vorbis INTERFACE ogg_static vorbis_static vorbisenc_static vorbisfile_static ) +else (WINDOWS) + target_link_libraries(ll::vorbis INTERFACE ogg vorbis vorbisenc vorbisfile ) +endif (WINDOWS) -link_directories( - ${VORBIS_LIBRARY_DIRS} - ${VORBISENC_LIBRARY_DIRS} - ${VORBISFILE_LIBRARY_DIRS} - ${OGG_LIBRARY_DIRS} - ) diff --git a/indra/cmake/Boost.cmake b/indra/cmake/Boost.cmake index e79dc33245..601a23a86d 100644 --- a/indra/cmake/Boost.cmake +++ b/indra/cmake/Boost.cmake @@ -1,105 +1,50 @@ # -*- cmake -*- include(Prebuilt) -set(Boost_FIND_QUIETLY ON) -set(Boost_FIND_REQUIRED ON) +include_guard() -if (USESYSTEMLIBS) - include(FindBoost) +add_library( ll::boost INTERFACE IMPORTED ) +if( USE_CONAN ) + target_link_libraries( ll::boost INTERFACE CONAN_PKG::boost ) + target_compile_definitions( ll::boost INTERFACE BOOST_ALLOW_DEPRECATED_HEADERS BOOST_BIND_GLOBAL_PLACEHOLDERS ) + return() +endif() - set(BOOST_CONTEXT_LIBRARY boost_context-mt) - set(BOOST_FIBER_LIBRARY boost_fiber-mt) - set(BOOST_FILESYSTEM_LIBRARY boost_filesystem-mt) - set(BOOST_PROGRAM_OPTIONS_LIBRARY boost_program_options-mt) - set(BOOST_REGEX_LIBRARY boost_regex-mt) - set(BOOST_SIGNALS_LIBRARY boost_signals-mt) - set(BOOST_SYSTEM_LIBRARY boost_system-mt) - set(BOOST_THREAD_LIBRARY boost_thread-mt) -else (USESYSTEMLIBS) - use_prebuilt_binary(boost) - set(Boost_INCLUDE_DIRS ${LIBS_PREBUILT_DIR}/include) +use_prebuilt_binary(boost) - # As of sometime between Boost 1.67 and 1.72, Boost libraries are suffixed - # with the address size. - set(addrsfx "-x${ADDRESS_SIZE}") +# As of sometime between Boost 1.67 and 1.72, Boost libraries are suffixed +# with the address size. +set(addrsfx "-x${ADDRESS_SIZE}") - if (WINDOWS) - set(BOOST_CONTEXT_LIBRARY - optimized libboost_context-mt${addrsfx} - debug libboost_context-mt${addrsfx}-gd) - set(BOOST_FIBER_LIBRARY - optimized libboost_fiber-mt${addrsfx} - debug libboost_fiber-mt${addrsfx}-gd) - set(BOOST_FILESYSTEM_LIBRARY - optimized libboost_filesystem-mt${addrsfx} - debug libboost_filesystem-mt${addrsfx}-gd) - set(BOOST_PROGRAM_OPTIONS_LIBRARY - optimized libboost_program_options-mt${addrsfx} - debug libboost_program_options-mt${addrsfx}-gd) - set(BOOST_REGEX_LIBRARY - optimized libboost_regex-mt${addrsfx} - debug libboost_regex-mt${addrsfx}-gd) - set(BOOST_SIGNALS_LIBRARY - optimized libboost_signals-mt${addrsfx} - debug libboost_signals-mt${addrsfx}-gd) - set(BOOST_SYSTEM_LIBRARY - optimized libboost_system-mt${addrsfx} - debug libboost_system-mt${addrsfx}-gd) - set(BOOST_THREAD_LIBRARY - optimized libboost_thread-mt${addrsfx} - debug libboost_thread-mt${addrsfx}-gd) - elseif (LINUX) - set(BOOST_CONTEXT_LIBRARY - optimized boost_context-mt${addrsfx} - debug boost_context-mt${addrsfx}-d) - set(BOOST_FIBER_LIBRARY - optimized boost_fiber-mt${addrsfx} - debug boost_fiber-mt${addrsfx}-d) - set(BOOST_FILESYSTEM_LIBRARY - optimized boost_filesystem-mt${addrsfx} - debug boost_filesystem-mt${addrsfx}-d) - set(BOOST_PROGRAM_OPTIONS_LIBRARY - optimized boost_program_options-mt${addrsfx} - debug boost_program_options-mt${addrsfx}-d) - set(BOOST_REGEX_LIBRARY - optimized boost_regex-mt${addrsfx} - debug boost_regex-mt${addrsfx}-d) - set(BOOST_SIGNALS_LIBRARY - optimized boost_signals-mt${addrsfx} - debug boost_signals-mt${addrsfx}-d) - set(BOOST_SYSTEM_LIBRARY - optimized boost_system-mt${addrsfx} - debug boost_system-mt${addrsfx}-d) - set(BOOST_THREAD_LIBRARY - optimized boost_thread-mt${addrsfx} - debug boost_thread-mt${addrsfx}-d) - elseif (DARWIN) - set(BOOST_CONTEXT_LIBRARY - optimized boost_context-mt${addrsfx} - debug boost_context-mt${addrsfx}) - set(BOOST_FIBER_LIBRARY - optimized boost_fiber-mt${addrsfx} - debug boost_fiber-mt${addrsfx}) - set(BOOST_FILESYSTEM_LIBRARY - optimized boost_filesystem-mt${addrsfx} - debug boost_filesystem-mt${addrsfx}) - set(BOOST_PROGRAM_OPTIONS_LIBRARY - optimized boost_program_options-mt${addrsfx} - debug boost_program_options-mt${addrsfx}) - set(BOOST_REGEX_LIBRARY - optimized boost_regex-mt${addrsfx} - debug boost_regex-mt${addrsfx}) - set(BOOST_SIGNALS_LIBRARY - optimized boost_signals-mt${addrsfx} - debug boost_signals-mt${addrsfx}) - set(BOOST_SYSTEM_LIBRARY - optimized boost_system-mt${addrsfx} - debug boost_system-mt${addrsfx}) - set(BOOST_THREAD_LIBRARY - optimized boost_thread-mt${addrsfx} - debug boost_thread-mt${addrsfx}) - endif (WINDOWS) -endif (USESYSTEMLIBS) +if (WINDOWS) + target_link_libraries( ll::boost INTERFACE + libboost_context-mt${addrsfx} + libboost_fiber-mt${addrsfx} + libboost_filesystem-mt${addrsfx} + libboost_program_options-mt${addrsfx} + libboost_regex-mt${addrsfx} + libboost_system-mt${addrsfx} + libboost_thread-mt${addrsfx}) +elseif (LINUX) + target_link_libraries( ll::boost INTERFACE + boost_context-mt${addrsfx} + boost_fiber-mt${addrsfx} + boost_filesystem-mt${addrsfx} + boost_program_options-mt${addrsfx} + boost_regex-mt${addrsfx} + boost_signals-mt${addrsfx} + boost_system-mt${addrsfx} + boost_thread-mt${addrsfx}) +elseif (DARWIN) + target_link_libraries( ll::boost INTERFACE + boost_context-mt${addrsfx} + boost_fiber-mt${addrsfx} + boost_filesystem-mt${addrsfx} + boost_program_options-mt${addrsfx} + boost_regex-mt${addrsfx} + boost_system-mt${addrsfx} + boost_thread-mt${addrsfx}) +endif (WINDOWS) if (LINUX) set(BOOST_SYSTEM_LIBRARY ${BOOST_SYSTEM_LIBRARY} rt) diff --git a/indra/cmake/BuildPackagesInfo.cmake b/indra/cmake/BuildPackagesInfo.cmake index 8f8b6b2330..659ba9d579 100644 --- a/indra/cmake/BuildPackagesInfo.cmake +++ b/indra/cmake/BuildPackagesInfo.cmake @@ -16,5 +16,5 @@ add_custom_command(OUTPUT packages-info.txt COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_SOURCE_DIR}/cmake/run_build_test.py -DAUTOBUILD_ADDRSIZE=${ADDRESS_SIZE} -DAUTOBUILD=${AUTOBUILD_EXECUTABLE} ${PYTHON_EXECUTABLE} - ${CMAKE_SOURCE_DIR}/../scripts/packages-formatter.py "${VIEWER_CHANNEL}" "${VIEWER_SHORT_VERSION}.${VIEWER_VERSION_REVISION}" > packages-info.txt + ${CMAKE_SOURCE_DIR}/../scripts/packages-formatter.py "${VIEWER_CHANNEL}" "${VIEWER_SHORT_VERSION}.${VIEWER_VERSION_REVISION}" "${AUTOBUILD_INSTALL_DIR}" > packages-info.txt ) diff --git a/indra/cmake/BuildVersion.cmake b/indra/cmake/BuildVersion.cmake index 157fdd07e4..b531f29ee2 100644 --- a/indra/cmake/BuildVersion.cmake +++ b/indra/cmake/BuildVersion.cmake @@ -19,33 +19,23 @@ if (NOT DEFINED VIEWER_SHORT_VERSION) # will be true in indra/, false in indra/n message(STATUS "Revision (from autobuild environment): ${VIEWER_VERSION_REVISION}") else (DEFINED ENV{revision}) - find_program(MERCURIAL - NAMES hg - PATHS [HKEY_LOCAL_MACHINE\\Software\\TortoiseHG] - PATH_SUFFIXES Mercurial) - mark_as_advanced(MERCURIAL) - if (MERCURIAL) - execute_process(COMMAND ${MERCURIAL} identify --num --rev tip - WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} - RESULT_VARIABLE hg_id_result - ERROR_VARIABLE hg_id_error - OUTPUT_VARIABLE VIEWER_VERSION_REVISION - OUTPUT_STRIP_TRAILING_WHITESPACE) - if (NOT ${hg_id_result} EQUAL 0) - message(SEND_ERROR "Revision number generation failed with output:\n${hg_id_error}") - else (NOT ${hg_id_result} EQUAL 0) - string(REGEX REPLACE "[^0-9a-f]" "" VIEWER_VERSION_REVISION ${VIEWER_VERSION_REVISION}) - endif (NOT ${hg_id_result} EQUAL 0) - if ("${VIEWER_VERSION_REVISION}" MATCHES "^[0-9]+$") - message(STATUS "Revision (from hg) ${VIEWER_VERSION_REVISION}") - else ("${VIEWER_VERSION_REVISION}" MATCHES "^[0-9]+$") - message(STATUS "Revision not set (repository not found?); using 0") - set(VIEWER_VERSION_REVISION 0 ) - endif ("${VIEWER_VERSION_REVISION}" MATCHES "^[0-9]+$") - else (MERCURIAL) - message(STATUS "Revision not set: mercurial not found; using 0") - set(VIEWER_VERSION_REVISION 0) - endif (MERCURIAL) + find_program(GIT git) + if (DEFINED GIT ) + execute_process( + COMMAND ${GIT} rev-list --count HEAD + OUTPUT_VARIABLE VIEWER_VERSION_REVISION + OUTPUT_STRIP_TRAILING_WHITESPACE + ) + if ("${VIEWER_VERSION_REVISION}" MATCHES "^[0-9]+$") + message(STATUS "Revision (from git) ${VIEWER_VERSION_REVISION}") + else ("${VIEWER_VERSION_REVISION}" MATCHES "^[0-9]+$") + message(STATUS "Revision not set (repository not found?); using 0") + set(VIEWER_VERSION_REVISION 0 ) + endif ("${VIEWER_VERSION_REVISION}" MATCHES "^[0-9]+$") + else (DEFINED GIT ) + message(STATUS "Revision not set: 'git' found; using 0") + set(VIEWER_VERSION_REVISION 0) + endif (DEFINED GIT) endif (DEFINED ENV{revision}) message(STATUS "Building '${VIEWER_CHANNEL}' Version ${VIEWER_SHORT_VERSION}.${VIEWER_VERSION_REVISION}") else ( EXISTS ${VIEWER_VERSION_BASE_FILE} ) diff --git a/indra/cmake/CEFPlugin.cmake b/indra/cmake/CEFPlugin.cmake index 7d8bfb1b0f..9b77becf29 100644 --- a/indra/cmake/CEFPlugin.cmake +++ b/indra/cmake/CEFPlugin.cmake @@ -2,18 +2,14 @@ include(Linking) include(Prebuilt) -if (USESYSTEMLIBS) - set(CEFPLUGIN OFF CACHE BOOL - "CEFPLUGIN support for the llplugin/llmedia test apps.") -else (USESYSTEMLIBS) - use_prebuilt_binary(dullahan) - set(CEFPLUGIN ON CACHE BOOL - "CEFPLUGIN support for the llplugin/llmedia test apps.") - set(CEF_INCLUDE_DIR ${LIBS_PREBUILT_DIR}/include/cef) -endif (USESYSTEMLIBS) +include_guard() +add_library( ll::cef INTERFACE IMPORTED ) + +use_prebuilt_binary(dullahan) +target_include_directories( ll::cef SYSTEM INTERFACE ${LIBS_PREBUILT_DIR}/include/cef) if (WINDOWS) - set(CEF_PLUGIN_LIBRARIES + target_link_libraries( ll::cef INTERFACE libcef.lib libcef_dll_wrapper.lib dullahan.lib @@ -29,7 +25,7 @@ elseif (DARWIN) message(FATAL_ERROR "CEF not found") endif() - set(CEF_PLUGIN_LIBRARIES + target_link_libraries( ll::cef INTERFACE ${ARCH_PREBUILT_DIRS_RELEASE}/libcef_dll_wrapper.a ${ARCH_PREBUILT_DIRS_RELEASE}/libdullahan.a ${APPKIT_LIBRARY} diff --git a/indra/cmake/CMakeLists.txt b/indra/cmake/CMakeLists.txt index fb3c7216c7..f0b35c08f3 100644 --- a/indra/cmake/CMakeLists.txt +++ b/indra/cmake/CMakeLists.txt @@ -5,109 +5,78 @@ include(00-Common) project(cmake) set(cmake_SOURCE_FILES - CMakeLists.txt - - 00-Common.cmake - APR.cmake - Audio.cmake - Boost.cmake - bugsplat.cmake - BuildVersion.cmake - CEFPlugin.cmake - CEFPlugin.cmake - CMakeCopyIfDifferent.cmake - ConfigurePkgConfig.cmake - CURL.cmake - Copy3rdPartyLibs.cmake - DBusGlib.cmake - DeploySharedLibs.cmake - DragDrop.cmake - EXPAT.cmake - FindAPR.cmake - FindAutobuild.cmake - FindGLH.cmake - FindHUNSPELL.cmake - FindJsonCpp.cmake - FindNDOF.cmake - FindOpenJPEG.cmake - FindSCP.cmake - FindURIPARSER.cmake - FindXmlRpcEpi.cmake - FindZLIBNG.cmake - FMODSTUDIO.cmake - FreeType.cmake - GLEXT.cmake - GLH.cmake -## GStreamer010Plugin.cmake - GoogleMock.cmake - Havok.cmake - Hunspell.cmake - JPEG.cmake - JsonCpp.cmake - LLAddBuildTest.cmake - LLAppearance.cmake - LLAudio.cmake - LLCharacter.cmake - LLCommon.cmake - LLCrashLogger.cmake - LLImage.cmake - LLImageJ2COJ.cmake - LLInventory.cmake - LLKDU.cmake - LLLogin.cmake - LLMath.cmake - LLMeshOptimizer.cmake - LLMessage.cmake - LLPhysicsExtensions.cmake - LLPlugin.cmake - LLPrimitive.cmake - LLRender.cmake - LLSharedLibs.cmake - LLTestCommand.cmake - LLUI.cmake - LLFileSystem.cmake - LLWindow.cmake - LLXML.cmake - Linking.cmake - MediaPluginBase.cmake - MESHOPTIMIZER.cmake - NDOF.cmake - OPENAL.cmake - OpenGL.cmake - OpenJPEG.cmake - OpenSSL.cmake - PNG.cmake - PluginAPI.cmake - Prebuilt.cmake - PulseAudio.cmake - Python.cmake - TemplateCheck.cmake - Tut.cmake - UI.cmake - UnixInstall.cmake - URIPARSER.cmake - Variables.cmake - ViewerMiscLibs.cmake - VisualLeakDetector.cmake - LibVLCPlugin.cmake - XmlRpcEpi.cmake - xxHash.cmake - ZLIBNG.cmake - ) + CMakeLists.txt + 00-Common.cmake + APR.cmake + Audio.cmake + Boost.cmake + bugsplat.cmake + BuildVersion.cmake + CEFPlugin.cmake + CEFPlugin.cmake + CMakeCopyIfDifferent.cmake + ConfigurePkgConfig.cmake + CURL.cmake + Copy3rdPartyLibs.cmake + DBusGlib.cmake + DeploySharedLibs.cmake + DragDrop.cmake + EXPAT.cmake + FindAutobuild.cmake + FMODSTUDIO.cmake + FreeType.cmake + GLEXT.cmake + GLH.cmake + GoogleMock.cmake + Havok.cmake + Hunspell.cmake + JsonCpp.cmake + LLAddBuildTest.cmake + LLAppearance.cmake + LLAudio.cmake + LLCommon.cmake + LLImage.cmake + LLKDU.cmake + LLPhysicsExtensions.cmake + LLPrimitive.cmake + LLSharedLibs.cmake + LLTestCommand.cmake + LLWindow.cmake + Linking.cmake + Meshoptimizer.cmake + NDOF.cmake + OPENAL.cmake + OpenGL.cmake + OpenJPEG.cmake + OpenSSL.cmake + PNG.cmake + PluginAPI.cmake + Prebuilt.cmake + PulseAudio.cmake + Python.cmake + TemplateCheck.cmake + Tut.cmake + UI.cmake + UnixInstall.cmake + URIPARSER.cmake + Variables.cmake + ViewerMiscLibs.cmake + VisualLeakDetector.cmake + LibVLCPlugin.cmake + XmlRpcEpi.cmake + ZLIBNG.cmake + ) source_group("Shared Rules" FILES ${cmake_SOURCE_FILES}) set(master_SOURCE_FILES - ../CMakeLists.txt - ) + ../CMakeLists.txt + ) source_group("Master Rules" FILES ${master_SOURCE_FILES}) -set_source_files_properties(${cmake_SOURCE_FILES} ${master_SOURCE_FILES} - PROPERTIES HEADER_FILE_ONLY TRUE) - add_library(cmake - cmake_dummy.cpp - ${cmake_SOURCE_FILES} - ${master_SOURCE_FILES} - ) + cmake_dummy.cpp + ${cmake_SOURCE_FILES} + ${master_SOURCE_FILES} + ) diff --git a/indra/cmake/CURL.cmake b/indra/cmake/CURL.cmake index 04afae594d..b9f685f37b 100644 --- a/indra/cmake/CURL.cmake +++ b/indra/cmake/CURL.cmake @@ -1,19 +1,14 @@ # -*- cmake -*- include(Prebuilt) -set(CURL_FIND_QUIETLY ON) -set(CURL_FIND_REQUIRED ON) +include_guard() +add_library( ll::libcurl INTERFACE IMPORTED ) -if (USESYSTEMLIBS) - include(FindCURL) -else (USESYSTEMLIBS) - use_prebuilt_binary(curl) - if (WINDOWS) - set(CURL_LIBRARIES - debug libcurld.lib - optimized libcurl.lib) - else (WINDOWS) - set(CURL_LIBRARIES libcurl.a) - endif (WINDOWS) - set(CURL_INCLUDE_DIRS ${LIBS_PREBUILT_DIR}/include) -endif (USESYSTEMLIBS) +use_system_binary(libcurl) +use_prebuilt_binary(curl) +if (WINDOWS) + target_link_libraries(ll::libcurl INTERFACE libcurl.lib) +else (WINDOWS) + target_link_libraries(ll::libcurl INTERFACE libcurl.a) +endif (WINDOWS) +target_include_directories( ll::libcurl SYSTEM INTERFACE ${LIBS_PREBUILT_DIR}/include) diff --git a/indra/cmake/Copy3rdPartyLibs.cmake b/indra/cmake/Copy3rdPartyLibs.cmake index ff705101de..1ee2a621f2 100644 --- a/indra/cmake/Copy3rdPartyLibs.cmake +++ b/indra/cmake/Copy3rdPartyLibs.cmake @@ -6,6 +6,8 @@ include(CMakeCopyIfDifferent) include(Linking) +include(OPENAL) +include(FMODSTUDIO) # When we copy our dependent libraries, we almost always want to copy them to # both the Release and the RelWithDebInfo staging directories. This has @@ -13,27 +15,27 @@ include(Linking) # copy_if_different commands. Encapsulate that usage. # Pass FROM_DIR, TARGETS and the files to copy. TO_DIR is implicit. # to_staging_dirs diverges from copy_if_different in that it appends to TARGETS. -MACRO(to_staging_dirs from_dir targets) - foreach(staging_dir - "${SHARED_LIB_STAGING_DIR_RELEASE}" - "${SHARED_LIB_STAGING_DIR_RELWITHDEBINFO}") - copy_if_different("${from_dir}" "${staging_dir}" out_targets ${ARGN}) +macro(to_staging_dirs from_dir targets) + set( targetDir "${SHARED_LIB_STAGING_DIR}") + copy_if_different("${from_dir}" "${targetDir}" out_targets ${ARGN}) + list(APPEND "${targets}" "${out_targets}") - endforeach() -ENDMACRO(to_staging_dirs from_dir to_dir targets) +endmacro() ################################################################### # set up platform specific lists of files that need to be copied ################################################################### if(WINDOWS) - set(SHARED_LIB_STAGING_DIR_DEBUG "${SHARED_LIB_STAGING_DIR}/Debug") - set(SHARED_LIB_STAGING_DIR_RELWITHDEBINFO "${SHARED_LIB_STAGING_DIR}/RelWithDebInfo") - set(SHARED_LIB_STAGING_DIR_RELEASE "${SHARED_LIB_STAGING_DIR}/Release") - #******************************* # VIVOX - *NOTE: no debug version set(vivox_lib_dir "${ARCH_PREBUILT_DIRS_RELEASE}") - set(slvoice_src_dir "${ARCH_PREBUILT_BIN_RELEASE}") + + # ND, it seems there is no such thing defined. At least when building a viewer + # Does this maybe matter on some LL buildserver? Otherwise this and the snippet using slvoice_src_dir + # can all go + if( ARCH_PREBUILT_BIN_RELEASE ) + set(slvoice_src_dir "${ARCH_PREBUILT_BIN_RELEASE}") + endif() set(slvoice_files SLVoice.exe ) if (ADDRESS_SIZE EQUAL 64) list(APPEND vivox_libs @@ -52,7 +54,7 @@ if(WINDOWS) set(release_src_dir "${ARCH_PREBUILT_DIRS_RELEASE}") set(release_files - openjpeg.dll + openjp2.dll libapr-1.dll libaprutil-1.dll libapriconv-1.dll @@ -84,14 +86,14 @@ if(WINDOWS) endif(ADDRESS_SIZE EQUAL 32) endif (USE_BUGSPLAT) - if (FMODSTUDIO) + if (TARGET ll::fmodstudio) set(debug_files ${debug_files} fmodL.dll) set(release_files ${release_files} fmod.dll) - endif (FMODSTUDIO) + endif () - if (OPENAL) + if (TARGET ll::openal) list(APPEND release_files openal32.dll alut.dll) - endif (OPENAL) + endif () #******************************* # Copy MS C runtime dlls, required for packaging. @@ -105,6 +107,8 @@ if(WINDOWS) set(MSVC_VER 140) elseif (MSVC_VERSION GREATER_EQUAL 1920 AND MSVC_VERSION LESS 1930) # Visual Studio 2019 set(MSVC_VER 140) + elseif (MSVC_VERSION GREATER_EQUAL 1930 AND MSVC_VERSION LESS 1940) # Visual Studio 2022 + set(MSVC_VER 140) else (MSVC80) MESSAGE(WARNING "New MSVC_VERSION ${MSVC_VERSION} of MSVC: adapt Copy3rdPartyLibs.cmake") endif (MSVC80) @@ -148,10 +152,6 @@ if(WINDOWS) endforeach() elseif(DARWIN) - set(SHARED_LIB_STAGING_DIR_DEBUG "${SHARED_LIB_STAGING_DIR}/Debug/Resources") - set(SHARED_LIB_STAGING_DIR_RELWITHDEBINFO "${SHARED_LIB_STAGING_DIR}/RelWithDebInfo/Resources") - set(SHARED_LIB_STAGING_DIR_RELEASE "${SHARED_LIB_STAGING_DIR}/Release/Resources") - set(vivox_lib_dir "${ARCH_PREBUILT_DIRS_RELEASE}") set(slvoice_files SLVoice) set(vivox_libs @@ -178,10 +178,10 @@ elseif(DARWIN) liburiparser.1.0.27.dylib ) - if (FMODSTUDIO) + if (TARGET ll::fmodstudio) set(debug_files ${debug_files} libfmodL.dylib) set(release_files ${release_files} libfmod.dylib) - endif (FMODSTUDIO) + endif () elseif(LINUX) # linux is weird, multiple side by side configurations aren't supported @@ -209,28 +209,30 @@ elseif(LINUX) set(release_src_dir "${ARCH_PREBUILT_DIRS_RELEASE}") # *FIX - figure out what to do with duplicate libalut.so here -brad set(release_files - libapr-1.so.0 - libaprutil-1.so.0 - libatk-1.0.so - libdb-5.1.so - ${EXPAT_COPY} - libfreetype.so.6.6.2 - libfreetype.so.6 - libgmodule-2.0.so - libgobject-2.0.so - libhunspell-1.3.so.0.0.0 - libopenal.so - libopenjpeg.so - libuuid.so.16 - libuuid.so.16.0.22 - libfontconfig.so.1.8.0 - libfontconfig.so.1 - ) + ${EXPAT_COPY} + ) + + if( USE_AUTOBUILD_3P ) + list( APPEND release_files + libapr-1.so.0 + libaprutil-1.so.0 + libatk-1.0.so + libfreetype.so.6.6.2 + libfreetype.so.6 + libhunspell-1.3.so.0.0.0 + libuuid.so.16 + libuuid.so.16.0.22 + libfontconfig.so.1.8.0 + libfontconfig.so.1 + libgmodule-2.0.so + libgobject-2.0.so + ) + endif() - if (FMODSTUDIO) + if (TARGET ll::fmodstudio) set(debug_files ${debug_files} "libfmodL.so") set(release_files ${release_files} "libfmod.so") - endif (FMODSTUDIO) + endif () else(WINDOWS) message(STATUS "WARNING: unrecognized platform for staging 3rd party libs, skipping...") @@ -260,13 +262,16 @@ endif(WINDOWS) # Curiously, slvoice_files are only copied to SHARED_LIB_STAGING_DIR_RELEASE. # It's unclear whether this is oversight or intentional, but anyway leave the # single copy_if_different command rather than using to_staging_dirs. -copy_if_different( - ${slvoice_src_dir} - "${SHARED_LIB_STAGING_DIR_RELEASE}" - out_targets - ${slvoice_files} + +if( slvoice_src_dir ) + copy_if_different( + ${slvoice_src_dir} + "${SHARED_LIB_STAGING_DIR_RELEASE}" + out_targets + ${slvoice_files} ) -list(APPEND third_party_targets ${out_targets}) + list(APPEND third_party_targets ${out_targets}) +endif() to_staging_dirs( ${vivox_lib_dir} @@ -280,9 +285,16 @@ to_staging_dirs( ${release_files} ) -if(NOT USESYSTEMLIBS) - add_custom_target( - stage_third_party_libs ALL - DEPENDS ${third_party_targets} - ) -endif(NOT USESYSTEMLIBS) +add_custom_target( + stage_third_party_libs ALL + DEPENDS ${third_party_targets} +) + +if(DARWIN) + # Support our "@executable_path/../Resources" load path for executables + # that end up in any of the above SHARED_LIB_STAGING_DIR_MUMBLE + # directories. + add_custom_command( TARGET stage_third_party_libs POST_BUILD + COMMAND cmake -E create_symlink ${SHARED_LIB_STAGING_DIR} ${CMAKE_BINARY_DIR}/sharedlibs/Resources + ) +endif() diff --git a/indra/cmake/DBusGlib.cmake b/indra/cmake/DBusGlib.cmake index 5e46b6711a..c9b727ca9d 100644 --- a/indra/cmake/DBusGlib.cmake +++ b/indra/cmake/DBusGlib.cmake @@ -1,29 +1,14 @@ # -*- cmake -*- include(Prebuilt) -if (USESYSTEMLIBS) - include(FindPkgConfig) +add_library( ll::dbus INTERFACE IMPORTED) - pkg_check_modules(DBUSGLIB REQUIRED dbus-glib-1) +if( LINUX ) + # Only define this when not using the prebuild 3ps, lls prebuild is broken + if( NOT USE_AUTOBUILD_3P ) + target_compile_definitions( ll::dbus INTERFACE LL_DBUS_ENABLED ) + endif() + use_system_binary(dbus) -elseif (LINUX) use_prebuilt_binary(dbus_glib) - set(DBUSGLIB_FOUND ON FORCE BOOL) - set(DBUSGLIB_INCLUDE_DIRS - ${LIBS_PREBUILT_DIR}/include/dbus - ) - # We don't need to explicitly link against dbus-glib itself, because - # the viewer probes for the system's copy at runtime. - set(DBUSGLIB_LIBRARIES - gobject-2.0 - glib-2.0 - ) -endif (USESYSTEMLIBS) - -if (DBUSGLIB_FOUND) - set(DBUSGLIB ON CACHE BOOL "Build with dbus-glib message bus support.") -endif (DBUSGLIB_FOUND) - -if (DBUSGLIB) - add_definitions(-DLL_DBUS_ENABLED=1) -endif (DBUSGLIB) +endif() diff --git a/indra/cmake/DragDrop.cmake b/indra/cmake/DragDrop.cmake index 73ef59b18f..26e7828830 100644 --- a/indra/cmake/DragDrop.cmake +++ b/indra/cmake/DragDrop.cmake @@ -1,20 +1,16 @@ # -*- cmake -*- - set(OS_DRAG_DROP ON CACHE BOOL "Build the viewer with OS level drag and drop turned on or off") - - if (OS_DRAG_DROP) +set(OS_DRAG_DROP ON CACHE BOOL "Build the viewer with OS level drag and drop turned on or off") +if (OS_DRAG_DROP) if (WINDOWS) - add_definitions(-DLL_OS_DRAGDROP_ENABLED=1) + add_definitions(-DLL_OS_DRAGDROP_ENABLED=1) endif (WINDOWS) - if (DARWIN) - add_definitions(-DLL_OS_DRAGDROP_ENABLED=1) + add_definitions(-DLL_OS_DRAGDROP_ENABLED=1) endif (DARWIN) - if (LINUX) - add_definitions(-DLL_OS_DRAGDROP_ENABLED=0) + add_definitions(-DLL_OS_DRAGDROP_ENABLED=1) endif (LINUX) - - endif (OS_DRAG_DROP) +endif (OS_DRAG_DROP) diff --git a/indra/cmake/EXPAT.cmake b/indra/cmake/EXPAT.cmake index cddc71b227..327fe8aa72 100644 --- a/indra/cmake/EXPAT.cmake +++ b/indra/cmake/EXPAT.cmake @@ -1,23 +1,20 @@ # -*- cmake -*- include(Prebuilt) -set(EXPAT_FIND_QUIETLY ON) -set(EXPAT_FIND_REQUIRED ON) +include_guard() +add_library( ll::expat INTERFACE IMPORTED ) -if (USESYSTEMLIBS) - include(FindEXPAT) -else (USESYSTEMLIBS) - use_prebuilt_binary(expat) - if (WINDOWS) - set(EXPAT_LIBRARIES libexpatMT) - set(EXPAT_COPY libexpatMT.dll) - else (WINDOWS) - set(EXPAT_LIBRARIES expat) - if (DARWIN) - set(EXPAT_COPY libexpat.1.dylib libexpat.dylib) - else () - set(EXPAT_COPY libexpat.so.1 libexpat.so) - endif () - endif (WINDOWS) - set(EXPAT_INCLUDE_DIRS ${LIBS_PREBUILT_DIR}/include) -endif (USESYSTEMLIBS) +use_system_binary(expat) +use_prebuilt_binary(expat) +if (WINDOWS) + target_link_libraries( ll::expat INTERFACE libexpatMT ) + set(EXPAT_COPY libexpatMT.dll) +else (WINDOWS) + target_link_libraries( ll::expat INTERFACE expat ) + if (DARWIN) + set(EXPAT_COPY libexpat.1.dylib libexpat.dylib) + else () + set(EXPAT_COPY libexpat.so.1 libexpat.so) + endif () +endif (WINDOWS) +target_include_directories( ll::expat SYSTEM INTERFACE ${LIBS_PREBUILT_DIR}/include ) diff --git a/indra/cmake/ExamplePlugin.cmake b/indra/cmake/ExamplePlugin.cmake index 5d826c1f66..6234035474 100644 --- a/indra/cmake/ExamplePlugin.cmake +++ b/indra/cmake/ExamplePlugin.cmake @@ -2,15 +2,5 @@ include(Linking) include(Prebuilt) -if (USESYSTEMLIBS) - set(EXAMPLEPLUGIN OFF CACHE BOOL +set(EXAMPLEPLUGIN ON CACHE BOOL "EXAMPLEPLUGIN support for the llplugin/llmedia test apps.") -else (USESYSTEMLIBS) - set(EXAMPLEPLUGIN ON CACHE BOOL - "EXAMPLEPLUGIN support for the llplugin/llmedia test apps.") -endif (USESYSTEMLIBS) - -if (WINDOWS) -elseif (DARWIN) -elseif (LINUX) -endif (WINDOWS) diff --git a/indra/cmake/FMODSTUDIO.cmake b/indra/cmake/FMODSTUDIO.cmake index 8840354ac6..c5b21ac4e5 100644 --- a/indra/cmake/FMODSTUDIO.cmake +++ b/indra/cmake/FMODSTUDIO.cmake @@ -1,16 +1,30 @@ # -*- cmake -*- +include_guard() + # FMODSTUDIO can be set when launching the make using the argument -DFMODSTUDIO:BOOL=ON # When building using proprietary binaries though (i.e. having access to LL private servers), # we always build with FMODSTUDIO. if (INSTALL_PROPRIETARY) - set(FMODSTUDIO ON CACHE BOOL "Using FMODSTUDIO sound library.") + set(USE_FMODSTUDIO ON CACHE BOOL "Using FMODSTUDIO sound library.") endif (INSTALL_PROPRIETARY) -if (FMODSTUDIO) +# ND: To streamline arguments passed, switch from FMODSTUDIO to USE_FMODSTUDIO +# To not break all old build scripts convert old arguments but warn about it +if(FMODSTUDIO) + message( WARNING "Use of the FMODSTUDIO argument is deprecated, please switch to USE_FMODSTUDIO") + set(USE_FMODSTUDIO ${FMODSTUDIO}) +endif() + +if (USE_FMODSTUDIO) + add_library( ll::fmodstudio INTERFACE IMPORTED ) + target_compile_definitions( ll::fmodstudio INTERFACE LL_FMODSTUDIO=1) + if (FMODSTUDIO_LIBRARY AND FMODSTUDIO_INCLUDE_DIR) # If the path have been specified in the arguments, use that - set(FMODSTUDIO_LIBRARIES ${FMODSTUDIO_LIBRARY}) + + target_link_libraries(ll::fmodstudio INTERFACE ${FMODSTUDIO_LIBRARY}) + target_include_directories( ll::fmodstudio SYSTEM INTERFACE ${FMODSTUDIO_INCLUDE_DIR}) else (FMODSTUDIO_LIBRARY AND FMODSTUDIO_INCLUDE_DIR) # If not, we're going to try to get the package listed in autobuild.xml # Note: if you're not using INSTALL_PROPRIETARY, the package URL should be local (file:/// URL) @@ -18,21 +32,17 @@ if (FMODSTUDIO) include(Prebuilt) use_prebuilt_binary(fmodstudio) if (WINDOWS) - set(FMODSTUDIO_LIBRARY - debug fmodL_vc - optimized fmod_vc) + target_link_libraries( ll::fmodstudio INTERFACE fmod_vc) elseif (DARWIN) #despite files being called libfmod.dylib, we are searching for fmod - set(FMODSTUDIO_LIBRARY - debug fmodL - optimized fmod) + target_link_libraries( ll::fmodstudio INTERFACE fmod) elseif (LINUX) - set(FMODSTUDIO_LIBRARY - debug fmodL - optimized fmod) + target_link_libraries( ll::fmodstudio INTERFACE fmod) endif (WINDOWS) - set(FMODSTUDIO_LIBRARIES ${FMODSTUDIO_LIBRARY}) - set(FMODSTUDIO_INCLUDE_DIR ${LIBS_PREBUILT_DIR}/include/fmodstudio) + + target_include_directories( ll::fmodstudio SYSTEM INTERFACE ${LIBS_PREBUILT_DIR}/include/fmodstudio) endif (FMODSTUDIO_LIBRARY AND FMODSTUDIO_INCLUDE_DIR) -endif (FMODSTUDIO) +else() + set( USE_FMODSTUDIO "OFF") +endif () diff --git a/indra/cmake/FindAPR.cmake b/indra/cmake/FindAPR.cmake deleted file mode 100644 index 906b6c9452..0000000000 --- a/indra/cmake/FindAPR.cmake +++ /dev/null @@ -1,94 +0,0 @@ -# -*- cmake -*- - -# - Find Apache Portable Runtime -# Find the APR includes and libraries -# This module defines -# APR_INCLUDE_DIR and APRUTIL_INCLUDE_DIR, where to find apr.h, etc. -# APR_LIBRARIES and APRUTIL_LIBRARIES, the libraries needed to use APR. -# APR_FOUND and APRUTIL_FOUND, If false, do not try to use APR. -# also defined, but not for general use are -# APR_LIBRARY and APRUTIL_LIBRARY, where to find the APR library. - -# APR first. - -FIND_PATH(APR_INCLUDE_DIR apr.h -/usr/local/include/apr-1 -/usr/local/include/apr-1.0 -/usr/include/apr-1 -/usr/include/apr-1.0 -) - -SET(APR_NAMES ${APR_NAMES} apr-1) -FIND_LIBRARY(APR_LIBRARY - NAMES ${APR_NAMES} - PATHS /usr/lib /usr/local/lib - ) - -IF (APR_LIBRARY AND APR_INCLUDE_DIR) - SET(APR_LIBRARIES ${APR_LIBRARY}) - SET(APR_FOUND "YES") -ELSE (APR_LIBRARY AND APR_INCLUDE_DIR) - SET(APR_FOUND "NO") -ENDIF (APR_LIBRARY AND APR_INCLUDE_DIR) - - -IF (APR_FOUND) - IF (NOT APR_FIND_QUIETLY) - MESSAGE(STATUS "Found APR: ${APR_LIBRARIES}") - ENDIF (NOT APR_FIND_QUIETLY) -ELSE (APR_FOUND) - IF (APR_FIND_REQUIRED) - MESSAGE(FATAL_ERROR "Could not find APR library") - ENDIF (APR_FIND_REQUIRED) -ENDIF (APR_FOUND) - -# Deprecated declarations. -SET (NATIVE_APR_INCLUDE_PATH ${APR_INCLUDE_DIR} ) -GET_FILENAME_COMPONENT (NATIVE_APR_LIB_PATH ${APR_LIBRARY} PATH) - -MARK_AS_ADVANCED( - APR_LIBRARY - APR_INCLUDE_DIR - ) - -# Next, APRUTIL. - -FIND_PATH(APRUTIL_INCLUDE_DIR apu.h -/usr/local/include/apr-1 -/usr/local/include/apr-1.0 -/usr/include/apr-1 -/usr/include/apr-1.0 -) - -SET(APRUTIL_NAMES ${APRUTIL_NAMES} aprutil-1) -FIND_LIBRARY(APRUTIL_LIBRARY - NAMES ${APRUTIL_NAMES} - PATHS /usr/lib /usr/local/lib - ) - -IF (APRUTIL_LIBRARY AND APRUTIL_INCLUDE_DIR) - SET(APRUTIL_LIBRARIES ${APRUTIL_LIBRARY}) - SET(APRUTIL_FOUND "YES") -ELSE (APRUTIL_LIBRARY AND APRUTIL_INCLUDE_DIR) - SET(APRUTIL_FOUND "NO") -ENDIF (APRUTIL_LIBRARY AND APRUTIL_INCLUDE_DIR) - - -IF (APRUTIL_FOUND) - IF (NOT APRUTIL_FIND_QUIETLY) - MESSAGE(STATUS "Found APRUTIL: ${APRUTIL_LIBRARIES}") - ENDIF (NOT APRUTIL_FIND_QUIETLY) -ELSE (APRUTIL_FOUND) - IF (APRUTIL_FIND_REQUIRED) - MESSAGE(FATAL_ERROR "Could not find APRUTIL library") - ENDIF (APRUTIL_FIND_REQUIRED) -ENDIF (APRUTIL_FOUND) - -# Deprecated declarations. -SET (NATIVE_APRUTIL_INCLUDE_PATH ${APRUTIL_INCLUDE_DIR} ) -GET_FILENAME_COMPONENT (NATIVE_APRUTIL_LIB_PATH ${APRUTIL_LIBRARY} PATH) - -MARK_AS_ADVANCED( - APRUTIL_LIBRARY - APRUTIL_INCLUDE_DIR - ) diff --git a/indra/cmake/FindGLH.cmake b/indra/cmake/FindGLH.cmake deleted file mode 100644 index 3d16adaf03..0000000000 --- a/indra/cmake/FindGLH.cmake +++ /dev/null @@ -1,30 +0,0 @@ -# -*- cmake -*- - -# - Find GLH -# Find the Graphic Library Helper includes. -# This module defines -# GLH_INCLUDE_DIR, where to find glh/glh_linear.h. -# GLH_FOUND, If false, do not try to use GLH. - -find_path(GLH_INCLUDE_DIR glh/glh_linear.h - NO_SYSTEM_ENVIRONMENT_PATH - ) - -if (GLH_INCLUDE_DIR) - set(GLH_FOUND "YES") -else (GLH_INCLUDE_DIR) - set(GLH_FOUND "NO") -endif (GLH_INCLUDE_DIR) - -if (GLH_FOUND) - if (NOT GLH_FIND_QUIETLY) - message(STATUS "Found GLH: ${GLH_INCLUDE_DIR}") - set(GLH_FIND_QUIETLY TRUE) # Only alert us the first time - endif (NOT GLH_FIND_QUIETLY) -else (GLH_FOUND) - if (GLH_FIND_REQUIRED) - message(FATAL_ERROR "Could not find GLH") - endif (GLH_FIND_REQUIRED) -endif (GLH_FOUND) - -mark_as_advanced(GLH_INCLUDE_DIR) diff --git a/indra/cmake/FindGooglePerfTools.cmake b/indra/cmake/FindGooglePerfTools.cmake deleted file mode 100644 index bb125d538e..0000000000 --- a/indra/cmake/FindGooglePerfTools.cmake +++ /dev/null @@ -1,66 +0,0 @@ -# -*- cmake -*- - -# - Find Google perftools -# Find the Google perftools includes and libraries -# This module defines -# GOOGLE_PERFTOOLS_INCLUDE_DIR, where to find heap-profiler.h, etc. -# GOOGLE_PERFTOOLS_FOUND, If false, do not try to use Google perftools. -# also defined for general use are -# TCMALLOC_LIBRARIES, where to find the tcmalloc library. -# STACKTRACE_LIBRARIES, where to find the stacktrace library. -# PROFILER_LIBRARIES, where to find the profiler library. - -FIND_PATH(GOOGLE_PERFTOOLS_INCLUDE_DIR google/heap-profiler.h -/usr/local/include -/usr/include -) - -SET(TCMALLOC_NAMES ${TCMALLOC_NAMES} tcmalloc) -FIND_LIBRARY(TCMALLOC_LIBRARY - NAMES ${TCMALLOC_NAMES} - PATHS /usr/lib /usr/local/lib - ) - -IF (TCMALLOC_LIBRARY AND GOOGLE_PERFTOOLS_INCLUDE_DIR) - SET(TCMALLOC_LIBRARIES ${TCMALLOC_LIBRARY}) - SET(GOOGLE_PERFTOOLS_FOUND "YES") -ELSE (TCMALLOC_LIBRARY AND GOOGLE_PERFTOOLS_INCLUDE_DIR) - SET(GOOGLE_PERFTOOLS_FOUND "NO") -ENDIF (TCMALLOC_LIBRARY AND GOOGLE_PERFTOOLS_INCLUDE_DIR) - -SET(STACKTRACE_NAMES ${STACKTRACE_NAMES} stacktrace) -FIND_LIBRARY(STACKTRACE_LIBRARY - NAMES ${STACKTRACE_LIBRARY} - PATHS /usr/lib /usr/local/lib - ) - -IF (STACKTRACE_LIBRARY AND GOOGLE_PERFTOOLS_INCLUDE_DIR) - SET(STACKTRACE_LIBRARIES ${STACKTRACE_LIBRARY}) -ENDIF (STACKTRACE_LIBRARY AND GOOGLE_PERFTOOLS_INCLUDE_DIR) - -SET(PROFILER_NAMES ${PROFILER_NAMES} profiler) -FIND_LIBRARY(PROFILER_LIBRARY - NAMES ${PROFILER_LIBRARY} - PATHS /usr/lib /usr/local/lib - ) - -IF (PROFILER_LIBRARY AND GOOGLE_PERFTOOLS_INCLUDE_DIR) - SET(PROFILER_LIBRARIES ${PROFILER_LIBRARY}) -ENDIF (PROFILER_LIBRARY AND GOOGLE_PERFTOOLS_INCLUDE_DIR) - -IF (GOOGLE_PERFTOOLS_FOUND) - IF (NOT GOOGLE_PERFTOOLS_FIND_QUIETLY) - MESSAGE(STATUS "Found Google perftools: ${GOOGLE_PERFTOOLS_LIBRARIES}") - ENDIF (NOT GOOGLE_PERFTOOLS_FIND_QUIETLY) -ELSE (GOOGLE_PERFTOOLS_FOUND) - IF (GOOGLE_PERFTOOLS_FIND_REQUIRED) - MESSAGE(FATAL_ERROR "Could not find Google perftools library") - ENDIF (GOOGLE_PERFTOOLS_FIND_REQUIRED) -ENDIF (GOOGLE_PERFTOOLS_FOUND) - -MARK_AS_ADVANCED( - TCMALLOC_LIBRARY - STACKTRACE_LIBRARY - PROFILER_LIBRARY - GOOGLE_PERFTOOLS_INCLUDE_DIR - ) diff --git a/indra/cmake/FindHUNSPELL.cmake b/indra/cmake/FindHUNSPELL.cmake deleted file mode 100644 index d411bdb9e5..0000000000 --- a/indra/cmake/FindHUNSPELL.cmake +++ /dev/null @@ -1,38 +0,0 @@ -# -*- cmake -*- - -# - Find HUNSPELL -# This module defines -# HUNSPELL_INCLUDE_DIR, where to find libhunspell.h, etc. -# HUNSPELL_LIBRARY, the library needed to use HUNSPELL. -# HUNSPELL_FOUND, If false, do not try to use HUNSPELL. - -find_path(HUNSPELL_INCLUDE_DIR hunspell.h - PATH_SUFFIXES hunspell - ) - -set(HUNSPELL_NAMES ${HUNSPELL_NAMES} libhunspell-1.3 libhunspell) -find_library(HUNSPELL_LIBRARY - NAMES ${HUNSPELL_NAMES} - ) - -if (HUNSPELL_LIBRARY AND HUNSPELL_INCLUDE_DIR) - set(HUNSPELL_FOUND "YES") -else (HUNSPELL_LIBRARY AND HUNSPELL_INCLUDE_DIR) - set(HUNSPELL_FOUND "NO") -endif (HUNSPELL_LIBRARY AND HUNSPELL_INCLUDE_DIR) - - -if (HUNSPELL_FOUND) - if (NOT HUNSPELL_FIND_QUIETLY) - message(STATUS "Found Hunspell: Library in '${HUNSPELL_LIBRARY}' and header in '${HUNSPELL_INCLUDE_DIR}' ") - endif (NOT HUNSPELL_FIND_QUIETLY) -else (HUNSPELL_FOUND) - if (HUNSPELL_FIND_REQUIRED) - message(FATAL_ERROR " * * *\nCould not find HUNSPELL library! * * *") - endif (HUNSPELL_FIND_REQUIRED) -endif (HUNSPELL_FOUND) - -mark_as_advanced( - HUNSPELL_LIBRARY - HUNSPELL_INCLUDE_DIR - ) diff --git a/indra/cmake/FindJsonCpp.cmake b/indra/cmake/FindJsonCpp.cmake deleted file mode 100644 index 9398779cff..0000000000 --- a/indra/cmake/FindJsonCpp.cmake +++ /dev/null @@ -1,60 +0,0 @@ -# -*- cmake -*- - -# - Find JSONCpp -# Find the JSONCpp includes and library -# This module defines -# JSONCPP_INCLUDE_DIR, where to find json.h, etc. -# JSONCPP_LIBRARIES, the libraries needed to use jsoncpp. -# JSONCPP_FOUND, If false, do not try to use jsoncpp. -# also defined, but not for general use are -# JSONCPP_LIBRARY, where to find the jsoncpp library. - -FIND_PATH(JSONCPP_INCLUDE_DIR jsoncpp/json.h -/usr/local/include -/usr/include -) - -# Get the GCC compiler version -EXEC_PROGRAM(${CMAKE_CXX_COMPILER} - ARGS ${CMAKE_CXX_COMPILER_ARG1} -dumpversion - OUTPUT_VARIABLE _gcc_COMPILER_VERSION - OUTPUT_STRIP_TRAILING_WHITESPACE - ) - -# Try to find a library that was compiled with the same compiler version as we currently use. -SET(JSONCPP_NAMES ${JSONCPP_NAMES} libjson_linux-gcc-${_gcc_COMPILER_VERSION}_libmt.so) -IF (USESYSTEMLIBS) - # On standalone, assume that the system installed library was compiled with the used compiler. - SET(JSONCPP_NAMES ${JSONCPP_NAMES} libjson.so) -ENDIF (USESYSTEMLIBS) -FIND_LIBRARY(JSONCPP_LIBRARY - NAMES ${JSONCPP_NAMES} - PATHS /usr/lib /usr/local/lib - ) - -IF (JSONCPP_LIBRARY AND JSONCPP_INCLUDE_DIR) - SET(JSONCPP_LIBRARIES ${JSONCPP_LIBRARY}) - SET(JSONCPP_FOUND "YES") -ELSE (JSONCPP_LIBRARY AND JSONCPP_INCLUDE_DIR) - SET(JSONCPP_FOUND "NO") -ENDIF (JSONCPP_LIBRARY AND JSONCPP_INCLUDE_DIR) - - -IF (JSONCPP_FOUND) - IF (NOT JSONCPP_FIND_QUIETLY) - MESSAGE(STATUS "Found JSONCpp: ${JSONCPP_LIBRARIES}") - ENDIF (NOT JSONCPP_FIND_QUIETLY) -ELSE (JSONCPP_FOUND) - IF (JSONCPP_FIND_REQUIRED) - MESSAGE(FATAL_ERROR "Could not find JSONCpp library") - ENDIF (JSONCPP_FIND_REQUIRED) -ENDIF (JSONCPP_FOUND) - -# Deprecated declarations. -SET (NATIVE_JSONCPP_INCLUDE_PATH ${JSONCPP_INCLUDE_DIR} ) -GET_FILENAME_COMPONENT (NATIVE_JSONCPP_LIB_PATH ${JSONCPP_LIBRARY} PATH) - -MARK_AS_ADVANCED( - JSONCPP_LIBRARY - JSONCPP_INCLUDE_DIR - ) diff --git a/indra/cmake/FindNDOF.cmake b/indra/cmake/FindNDOF.cmake deleted file mode 100644 index 6dcf590a53..0000000000 --- a/indra/cmake/FindNDOF.cmake +++ /dev/null @@ -1,39 +0,0 @@ -# -*- cmake -*- - -# - Find NDOF -# Find the NDOF includes and library -# This module defines -# NDOF_INCLUDE_DIR, where to find ndofdev_external.h, etc. -# NDOF_LIBRARY, the library needed to use NDOF. -# NDOF_FOUND, If false, do not try to use NDOF. - -find_path(NDOF_INCLUDE_DIR ndofdev_external.h - PATH_SUFFIXES ndofdev - ) - -set(NDOF_NAMES ${NDOF_NAMES} ndofdev libndofdev) -find_library(NDOF_LIBRARY - NAMES ${NDOF_NAMES} - ) - -if (NDOF_LIBRARY AND NDOF_INCLUDE_DIR) - set(NDOF_FOUND "YES") -else (NDOF_LIBRARY AND NDOF_INCLUDE_DIR) - set(NDOF_FOUND "NO") -endif (NDOF_LIBRARY AND NDOF_INCLUDE_DIR) - - -if (NDOF_FOUND) - if (NOT NDOF_FIND_QUIETLY) - message(STATUS "Found NDOF: Library in '${NDOF_LIBRARY}' and header in '${NDOF_INCLUDE_DIR}' ") - endif (NOT NDOF_FIND_QUIETLY) -else (NDOF_FOUND) - if (NDOF_FIND_REQUIRED) - message(FATAL_ERROR " * * *\nCould not find NDOF library!\nIf you don't need Space Navigator Joystick support you can skip this test by configuring with -DNDOF:BOOL=OFF\n * * *") - endif (NDOF_FIND_REQUIRED) -endif (NDOF_FOUND) - -mark_as_advanced( - NDOF_LIBRARY - NDOF_INCLUDE_DIR - ) diff --git a/indra/cmake/FindOpenJPEG.cmake b/indra/cmake/FindOpenJPEG.cmake deleted file mode 100644 index 949384eec4..0000000000 --- a/indra/cmake/FindOpenJPEG.cmake +++ /dev/null @@ -1,50 +0,0 @@ -# -*- cmake -*- - -# - Find OpenJPEG -# Find the OpenJPEG includes and library -# This module defines -# OPENJPEG_INCLUDE_DIR, where to find openjpeg.h, etc. -# OPENJPEG_LIBRARIES, the libraries needed to use OpenJPEG. -# OPENJPEG_FOUND, If false, do not try to use OpenJPEG. -# also defined, but not for general use are -# OPENJPEG_LIBRARY, where to find the OpenJPEG library. - -FIND_PATH(OPENJPEG_INCLUDE_DIR openjpeg.h -/usr/local/include/openjpeg -/usr/local/include -/usr/include/openjpeg -/usr/include -) - -SET(OPENJPEG_NAMES ${OPENJPEG_NAMES} openjpeg) -FIND_LIBRARY(OPENJPEG_LIBRARY - NAMES ${OPENJPEG_NAMES} - PATHS /usr/lib /usr/local/lib - ) - -IF (OPENJPEG_LIBRARY AND OPENJPEG_INCLUDE_DIR) - SET(OPENJPEG_LIBRARIES ${OPENJPEG_LIBRARY}) - SET(OPENJPEG_FOUND "YES") -ELSE (OPENJPEG_LIBRARY AND OPENJPEG_INCLUDE_DIR) - SET(OPENJPEG_FOUND "NO") -ENDIF (OPENJPEG_LIBRARY AND OPENJPEG_INCLUDE_DIR) - - -IF (OPENJPEG_FOUND) - IF (NOT OPENJPEG_FIND_QUIETLY) - MESSAGE(STATUS "Found OpenJPEG: ${OPENJPEG_LIBRARIES}") - ENDIF (NOT OPENJPEG_FIND_QUIETLY) -ELSE (OPENJPEG_FOUND) - IF (OPENJPEG_FIND_REQUIRED) - MESSAGE(FATAL_ERROR "Could not find OpenJPEG library") - ENDIF (OPENJPEG_FIND_REQUIRED) -ENDIF (OPENJPEG_FOUND) - -# Deprecated declarations. -SET (NATIVE_OPENJPEG_INCLUDE_PATH ${OPENJPEG_INCLUDE_DIR} ) -GET_FILENAME_COMPONENT (NATIVE_OPENJPEG_LIB_PATH ${OPENJPEG_LIBRARY} PATH) - -MARK_AS_ADVANCED( - OPENJPEG_LIBRARY - OPENJPEG_INCLUDE_DIR - ) diff --git a/indra/cmake/FindURIPARSER.cmake b/indra/cmake/FindURIPARSER.cmake deleted file mode 100644 index 8ab9f0f4ed..0000000000 --- a/indra/cmake/FindURIPARSER.cmake +++ /dev/null @@ -1,46 +0,0 @@ -# -*- cmake -*- - -# - Find uriparser -# Find the URIPARSER includes and library -# This module defines -# URIPARSER_INCLUDE_DIRS, where to find uriparser.h, etc. -# URIPARSER_LIBRARIES, the libraries needed to use uriparser. -# URIPARSER_FOUND, If false, do not try to use uriparser. -# -# This FindURIPARSER is about 43 times as fast the one provided with cmake (2.8.x), -# because it doesn't look up the version of uriparser, resulting in a dramatic -# speed up for configure (from 4 minutes 22 seconds to 6 seconds). -# -# Note: Since this file is only used for standalone, the windows -# specific parts were left out. - -FIND_PATH(URIPARSER_INCLUDE_DIR uriparser/uri.h - NO_SYSTEM_ENVIRONMENT_PATH - ) - -FIND_LIBRARY(URIPARSER_LIBRARY uriparser) - -if (URIPARSER_LIBRARY AND URIPARSER_INCLUDE_DIR) - SET(URIPARSER_INCLUDE_DIRS ${URIPARSER_INCLUDE_DIR}) - SET(URIPARSER_LIBRARIES ${URIPARSER_LIBRARY}) - SET(URIPARSER_FOUND "YES") -else (URIPARSER_LIBRARY AND URIPARSER_INCLUDE_DIR) - SET(URIPARSER_FOUND "NO") -endif (URIPARSER_LIBRARY AND URIPARSER_INCLUDE_DIR) - -if (URIPARSER_FOUND) - if (NOT URIPARSER_FIND_QUIETLY) - message(STATUS "Found URIPARSER: ${URIPARSER_LIBRARIES}") - SET(URIPARSER_FIND_QUIETLY TRUE) - endif (NOT URIPARSER_FIND_QUIETLY) -else (URIPARSER_FOUND) - if (URIPARSER_FIND_REQUIRED) - message(FATAL_ERROR "Could not find URIPARSER library") - endif (URIPARSER_FIND_REQUIRED) -endif (URIPARSER_FOUND) - -mark_as_advanced( - URIPARSER_LIBRARY - URIPARSER_INCLUDE_DIR - ) - diff --git a/indra/cmake/FindXmlRpcEpi.cmake b/indra/cmake/FindXmlRpcEpi.cmake deleted file mode 100644 index ba217e7467..0000000000 --- a/indra/cmake/FindXmlRpcEpi.cmake +++ /dev/null @@ -1,48 +0,0 @@ -# -*- cmake -*- - -# - Find XMLRPC-EPI -# Find the XMLRPC-EPI includes and library -# This module defines -# XMLRPCEPI_INCLUDE_DIR, where to find jpeglib.h, etc. -# XMLRPCEPI_LIBRARIES, the libraries needed to use XMLRPC-EPI. -# XMLRPCEPI_FOUND, If false, do not try to use XMLRPC-EPI. -# also defined, but not for general use are -# XMLRPCEPI_LIBRARY, where to find the XMLRPC-EPI library. - -FIND_PATH(XMLRPCEPI_INCLUDE_DIR xmlrpc-epi/xmlrpc.h -/usr/local/include -/usr/include -) - -SET(XMLRPCEPI_NAMES ${XMLRPCEPI_NAMES} xmlrpc-epi) -FIND_LIBRARY(XMLRPCEPI_LIBRARY - NAMES ${XMLRPCEPI_NAMES} - PATHS /usr/lib /usr/local/lib - ) - -IF (XMLRPCEPI_LIBRARY AND XMLRPCEPI_INCLUDE_DIR) - SET(XMLRPCEPI_LIBRARIES ${XMLRPCEPI_LIBRARY}) - SET(XMLRPCEPI_FOUND "YES") -ELSE (XMLRPCEPI_LIBRARY AND XMLRPCEPI_INCLUDE_DIR) - SET(XMLRPCEPI_FOUND "NO") -ENDIF (XMLRPCEPI_LIBRARY AND XMLRPCEPI_INCLUDE_DIR) - - -IF (XMLRPCEPI_FOUND) - IF (NOT XMLRPCEPI_FIND_QUIETLY) - MESSAGE(STATUS "Found XMLRPC-EPI: ${XMLRPCEPI_LIBRARIES}") - ENDIF (NOT XMLRPCEPI_FIND_QUIETLY) -ELSE (XMLRPCEPI_FOUND) - IF (XMLRPCEPI_FIND_REQUIRED) - MESSAGE(FATAL_ERROR "Could not find XMLRPC-EPI library") - ENDIF (XMLRPCEPI_FIND_REQUIRED) -ENDIF (XMLRPCEPI_FOUND) - -# Deprecated declarations. -SET (NATIVE_XMLRPCEPI_INCLUDE_PATH ${XMLRPCEPI_INCLUDE_DIR} ) -GET_FILENAME_COMPONENT (NATIVE_XMLRPCEPI_LIB_PATH ${XMLRPCEPI_LIBRARY} PATH) - -MARK_AS_ADVANCED( - XMLRPCEPI_LIBRARY - XMLRPCEPI_INCLUDE_DIR - ) diff --git a/indra/cmake/FindZLIBNG.cmake b/indra/cmake/FindZLIBNG.cmake deleted file mode 100644 index 6e3c8cdddb..0000000000 --- a/indra/cmake/FindZLIBNG.cmake +++ /dev/null @@ -1,46 +0,0 @@ -# -*- cmake -*- - -# - Find zlib-ng -# Find the ZLIB includes and library -# This module defines -# ZLIBNG_INCLUDE_DIRS, where to find zlib.h, etc. -# ZLIBNG_LIBRARIES, the libraries needed to use zlib. -# ZLIBNG_FOUND, If false, do not try to use zlib. -# -# This FindZLIBNG is about 43 times as fast the one provided with cmake (2.8.x), -# because it doesn't look up the version of zlib, resulting in a dramatic -# speed up for configure (from 4 minutes 22 seconds to 6 seconds). -# -# Note: Since this file is only used for standalone, the windows -# specific parts were left out. - -FIND_PATH(ZLIBNG_INCLUDE_DIR zlib.h - NO_SYSTEM_ENVIRONMENT_PATH - ) - -FIND_LIBRARY(ZLIBNG_LIBRARY z) - -if (ZLIBNG_LIBRARY AND ZLIBNG_INCLUDE_DIR) - SET(ZLIBNG_INCLUDE_DIRS ${ZLIBNG_INCLUDE_DIR}) - SET(ZLIBNG_LIBRARIES ${ZLIBNG_LIBRARY}) - SET(ZLIBNG_FOUND "YES") -else (ZLIBNG_LIBRARY AND ZLIBNG_INCLUDE_DIR) - SET(ZLIBNG_FOUND "NO") -endif (ZLINGB_LIBRARY AND ZLIBNG_INCLUDE_DIR) - -if (ZLIBNG_FOUND) - if (NOT ZLIBNG_FIND_QUIETLY) - message(STATUS "Found ZLIBNG: ${ZLIBNG_LIBRARIES}") - SET(ZLIBNG_FIND_QUIETLY TRUE) - endif (NOT ZLIBNG_FIND_QUIETLY) -else (ZLIBNG_FOUND) - if (ZLIBNG_FIND_REQUIRED) - message(FATAL_ERROR "Could not find ZLIBNG library") - endif (ZLIBNG_FIND_REQUIRED) -endif (ZLIBNG_FOUND) - -mark_as_advanced( - ZLIBNG_LIBRARY - ZLIBNG_INCLUDE_DIR - ) - diff --git a/indra/cmake/FreeType.cmake b/indra/cmake/FreeType.cmake index a36485f6d0..77140af641 100644 --- a/indra/cmake/FreeType.cmake +++ b/indra/cmake/FreeType.cmake @@ -1,14 +1,11 @@ # -*- cmake -*- include(Prebuilt) -if (USESYSTEMLIBS) - include(FindPkgConfig) +include_guard() +add_library( ll::freetype INTERFACE IMPORTED ) - pkg_check_modules(FREETYPE REQUIRED freetype2) -else (USESYSTEMLIBS) - use_prebuilt_binary(freetype) - set(FREETYPE_INCLUDE_DIRS ${LIBS_PREBUILT_DIR}/include/freetype2/) - set(FREETYPE_LIBRARIES freetype) -endif (USESYSTEMLIBS) +use_system_binary(freetype) +use_prebuilt_binary(freetype) +target_include_directories( ll::freetype SYSTEM INTERFACE ${LIBS_PREBUILT_DIR}/include/freetype2/) +target_link_libraries( ll::freetype INTERFACE freetype ) -link_directories(${FREETYPE_LIBRARY_DIRS}) diff --git a/indra/cmake/GLEXT.cmake b/indra/cmake/GLEXT.cmake index 9fd3923bfd..434b6f0ee8 100644 --- a/indra/cmake/GLEXT.cmake +++ b/indra/cmake/GLEXT.cmake @@ -1,10 +1,11 @@ # -*- cmake -*- include(Prebuilt) +include(GLH) + +add_library( ll::glext INTERFACE IMPORTED ) +if (WINDOWS OR LINUX) + use_system_binary(glext) + use_prebuilt_binary(glext) +endif (WINDOWS OR LINUX) + -if (NOT USESYSTEMLIBS) - if (WINDOWS OR LINUX) - use_prebuilt_binary(glext) - endif (WINDOWS OR LINUX) - use_prebuilt_binary(glh_linear) - set(GLEXT_INCLUDE_DIR ${LIBS_PREBUILT_DIR}/include) -endif (NOT USESYSTEMLIBS) diff --git a/indra/cmake/GLH.cmake b/indra/cmake/GLH.cmake index d5262f2efa..0cefc3543a 100644 --- a/indra/cmake/GLH.cmake +++ b/indra/cmake/GLH.cmake @@ -1,11 +1,7 @@ # -*- cmake -*- include(Prebuilt) -set(GLH_FIND_REQUIRED TRUE) -set(GLH_FIND_QUIETLY TRUE) +add_library( ll::glh_linear INTERFACE IMPORTED ) -if (USESYSTEMLIBS) - include(FindGLH) -else (USESYSTEMLIBS) - use_prebuilt_binary(glh_linear) -endif (USESYSTEMLIBS) +use_system_binary( glh_linear ) +use_prebuilt_binary(glh_linear) diff --git a/indra/cmake/GStreamer010Plugin.cmake b/indra/cmake/GStreamer010Plugin.cmake index 3fbc40ef8f..61f6f74033 100644 --- a/indra/cmake/GStreamer010Plugin.cmake +++ b/indra/cmake/GStreamer010Plugin.cmake @@ -1,38 +1,12 @@ # -*- cmake -*- include(Prebuilt) +if (NOT LINUX) + return() +endif() -if (USESYSTEMLIBS) - include(FindPkgConfig) +add_library( ll::gstreamer INTERFACE IMPORTED ) +target_compile_definitions( ll::gstreamer INTERFACE LL_GSTREAMER010_ENABLED=1) +use_system_binary(gstreamer) - pkg_check_modules(GSTREAMER010 REQUIRED gstreamer-0.10) - pkg_check_modules(GSTREAMER010_PLUGINS_BASE REQUIRED gstreamer-plugins-base-0.10) -elseif (LINUX) - use_prebuilt_binary(gstreamer) - # possible libxml2 should have its own .cmake file instead - use_prebuilt_binary(libxml2) - set(GSTREAMER010_FOUND ON FORCE BOOL) - set(GSTREAMER010_PLUGINS_BASE_FOUND ON FORCE BOOL) - set(GSTREAMER010_INCLUDE_DIRS - ${LIBS_PREBUILT_DIR}/include/gstreamer-0.10 - ${LIBS_PREBUILT_DIR}/include/glib-2.0 - ${LIBS_PREBUILT_DIR}/include/libxml2 - ) - # We don't need to explicitly link against gstreamer itself, because - # LLMediaImplGStreamer probes for the system's copy at runtime. - set(GSTREAMER010_LIBRARIES - gobject-2.0 - gmodule-2.0 - dl - gthread-2.0 - glib-2.0 - ) -endif (USESYSTEMLIBS) - -if (GSTREAMER010_FOUND AND GSTREAMER010_PLUGINS_BASE_FOUND) - set(GSTREAMER010 ON CACHE BOOL "Build with GStreamer-0.10 streaming media support.") -endif (GSTREAMER010_FOUND AND GSTREAMER010_PLUGINS_BASE_FOUND) - -if (GSTREAMER010) - add_definitions(-DLL_GSTREAMER010_ENABLED=1) -endif (GSTREAMER010) +use_prebuilt_binary(gstreamer) diff --git a/indra/cmake/GoogleMock.cmake b/indra/cmake/GoogleMock.cmake index 5a00546927..e4520fe96e 100644 --- a/indra/cmake/GoogleMock.cmake +++ b/indra/cmake/GoogleMock.cmake @@ -2,27 +2,31 @@ include(Prebuilt) include(Linking) +include_guard() + +add_library( ll::googlemock INTERFACE IMPORTED ) +if(USE_CONAN) + target_link_libraries( ll::googlemock INTERFACE CONAN_PKG::gtest ) + + #Not very nice, but for the moment we need this for tut.hpp + target_include_directories( ll::googlemock SYSTEM INTERFACE ${LIBS_PREBUILT_DIR}/include ) + return() +endif() + use_prebuilt_binary(googlemock) -set(GOOGLEMOCK_INCLUDE_DIRS - ${LIBS_PREBUILT_DIR}/include) +target_include_directories( ll::googlemock SYSTEM INTERFACE ${LIBS_PREBUILT_DIR}/include ) if (LINUX) # VWR-24366: gmock is underlinked, it needs gtest. - set(GOOGLEMOCK_LIBRARIES - gmock -Wl,--no-as-needed - gtest -Wl,--as-needed) + target_link_libraries( ll::googlemock INTERFACE gmock gtest) elseif(WINDOWS) - set(GOOGLEMOCK_LIBRARIES - gmock) - set(GOOGLEMOCK_INCLUDE_DIRS - ${LIBS_PREBUILT_DIR}/include - ${LIBS_PREBUILT_DIR}/include/gmock - ${LIBS_PREBUILT_DIR}/include/gmock/boost/tr1/tr1) + target_link_libraries( ll::googlemock INTERFACE gmock) + target_include_directories( ll::googlemock SYSTEM INTERFACE + ${LIBS_PREBUILT_DIR}/include + ${LIBS_PREBUILT_DIR}/include/gmock) elseif(DARWIN) - set(GOOGLEMOCK_LIBRARIES - gmock - gtest) + target_link_libraries( ll::googlemock INTERFACE gmock gtest) endif(LINUX) diff --git a/indra/cmake/Havok.cmake b/indra/cmake/Havok.cmake index 811a126b8f..652760e626 100644 --- a/indra/cmake/Havok.cmake +++ b/indra/cmake/Havok.cmake @@ -1,7 +1,6 @@ # -*- cmake -*- include(Prebuilt) -if(NOT DEFINED ${CMAKE_CURRENT_LIST_FILE}_INCLUDED) -set(${CMAKE_CURRENT_LIST_FILE}_INCLUDED "YES") +include_guard() use_prebuilt_binary(havok-source) @@ -124,4 +123,3 @@ foreach(HAVOK_LIB ${HAVOK_LIBS}) endif (LINUX) endforeach(HAVOK_LIB) -endif(NOT DEFINED ${CMAKE_CURRENT_LIST_FILE}_INCLUDED) diff --git a/indra/cmake/Hunspell.cmake b/indra/cmake/Hunspell.cmake index 06227b3fe2..bb037c0237 100644 --- a/indra/cmake/Hunspell.cmake +++ b/indra/cmake/Hunspell.cmake @@ -1,22 +1,17 @@ # -*- cmake -*- include(Prebuilt) -set(HUNSPELL_FIND_QUIETLY ON) -set(HUNSPELL_FIND_REQUIRED ON) +include_guard() +use_prebuilt_binary(dictionaries) -if (USESYSTEMLIBS) - include(FindHUNSPELL) -else (USESYSTEMLIBS) - use_prebuilt_binary(libhunspell) - if (WINDOWS) - set(HUNSPELL_LIBRARY libhunspell) - elseif(DARWIN) - set(HUNSPELL_LIBRARY hunspell-1.3) - elseif(LINUX) - set(HUNSPELL_LIBRARY hunspell-1.3) - else() - message(FATAL_ERROR "Invalid platform") - endif() - set(HUNSPELL_INCLUDE_DIRS ${LIBS_PREBUILT_DIR}/include/hunspell) - use_prebuilt_binary(dictionaries) -endif (USESYSTEMLIBS) +add_library( ll::hunspell INTERFACE IMPORTED ) +use_system_binary(hunspell) +use_prebuilt_binary(libhunspell) +if (WINDOWS) + target_link_libraries( ll::hunspell INTERFACE libhunspell) +elseif(DARWIN) + target_link_libraries( ll::hunspell INTERFACE hunspell-1.3) +elseif(LINUX) + target_link_libraries( ll::hunspell INTERFACE hunspell-1.3) +endif() +target_include_directories( ll::hunspell SYSTEM INTERFACE ${LIBS_PREBUILT_DIR}/include/hunspell) diff --git a/indra/cmake/JPEG.cmake b/indra/cmake/JPEG.cmake index d6da22aecc..252d7852d4 100644 --- a/indra/cmake/JPEG.cmake +++ b/indra/cmake/JPEG.cmake @@ -2,19 +2,17 @@ include(Prebuilt) include(Linking) -set(JPEG_FIND_QUIETLY ON) -set(JPEG_FIND_REQUIRED ON) -if (USESYSTEMLIBS) - include(FindJPEG) -else (USESYSTEMLIBS) - use_prebuilt_binary(jpeglib) - if (LINUX) - set(JPEG_LIBRARIES jpeg) - elseif (DARWIN) - set(JPEG_LIBRARIES jpeg) - elseif (WINDOWS) - set(JPEG_LIBRARIES jpeglib) - endif (LINUX) - set(JPEG_INCLUDE_DIRS ${LIBS_PREBUILT_DIR}/include) -endif (USESYSTEMLIBS) +include_guard() +add_library( ll::libjpeg INTERFACE IMPORTED ) + +use_system_binary(libjpeg) +use_prebuilt_binary(jpeglib) +if (LINUX) + target_link_libraries( ll::libjpeg INTERFACE jpeg) +elseif (DARWIN) + target_link_libraries( ll::libjpeg INTERFACE jpeg) +elseif (WINDOWS) + target_link_libraries( ll::libjpeg INTERFACE jpeglib) +endif (LINUX) +target_include_directories( ll::libjpeg SYSTEM INTERFACE ${LIBS_PREBUILT_DIR}/include) diff --git a/indra/cmake/JsonCpp.cmake b/indra/cmake/JsonCpp.cmake index 079619adf8..17f8e47a97 100644 --- a/indra/cmake/JsonCpp.cmake +++ b/indra/cmake/JsonCpp.cmake @@ -1,22 +1,17 @@ # -*- cmake -*- include(Prebuilt) +include_guard() +add_library( ll::jsoncpp INTERFACE IMPORTED ) -set(JSONCPP_FIND_QUIETLY ON) -set(JSONCPP_FIND_REQUIRED ON) +use_system_binary(jsoncpp) -if (USESYSTEMLIBS) - include(FindJsonCpp) -else (USESYSTEMLIBS) - use_prebuilt_binary(jsoncpp) - if (WINDOWS) - set(JSONCPP_LIBRARIES - debug json_libmdd.lib - optimized json_libmd.lib) - elseif (DARWIN) - set(JSONCPP_LIBRARIES libjson_darwin_libmt.a) - elseif (LINUX) - set(JSONCPP_LIBRARIES libjson_linux-gcc-4.1.3_libmt.a) - endif (WINDOWS) - set(JSONCPP_INCLUDE_DIR "${LIBS_PREBUILT_DIR}/include/jsoncpp" "${LIBS_PREBUILT_DIR}/include/json") -endif (USESYSTEMLIBS) +use_prebuilt_binary(jsoncpp) +if (WINDOWS) + target_link_libraries( ll::jsoncpp INTERFACE json_libmd.lib ) +elseif (DARWIN) + target_link_libraries( ll::jsoncpp INTERFACE libjson_darwin_libmt.a ) +elseif (LINUX) + target_link_libraries( ll::jsoncpp INTERFACE libjson_linux-gcc-4.1.3_libmt.a ) +endif (WINDOWS) +target_include_directories( ll::jsoncpp SYSTEM INTERFACE ${LIBS_PREBUILT_DIR}/include) diff --git a/indra/cmake/LLAddBuildTest.cmake b/indra/cmake/LLAddBuildTest.cmake index 4937c2a9d7..bf569e5d99 100644 --- a/indra/cmake/LLAddBuildTest.cmake +++ b/indra/cmake/LLAddBuildTest.cmake @@ -18,100 +18,86 @@ MACRO(LL_ADD_PROJECT_UNIT_TESTS project sources) # * properties for each sourcefile passed in indicate what libs to link that file with (MAKE NO ASSUMPTIONS ASIDE FROM TUT) # # More info and examples at: https://wiki.secondlife.com/wiki/How_to_add_unit_tests_to_indra_code - # - # WARNING: do NOT modify this code without working with poppy - - # there is another branch that will conflict heavily with any changes here. -INCLUDE(GoogleMock) - IF(LL_TEST_VERBOSE) - MESSAGE("LL_ADD_PROJECT_UNIT_TESTS UNITTEST_PROJECT_${project} sources: ${sources}") - ENDIF(LL_TEST_VERBOSE) + # This here looks weird, but is needed. It will inject GoogleMock into projects that forgot to include `this` (LLAddBuildTest.cmake) + # But through some other means have access to this macro + include(GoogleMock) + + if(LL_TEST_VERBOSE) + message("LL_ADD_PROJECT_UNIT_TESTS UNITTEST_PROJECT_${project} sources: ${sources}") + endif() # Start with the header and project-wide setup before making targets #project(UNITTEST_PROJECT_${project}) # Setup includes, paths, etc - SET(alltest_SOURCE_FILES - ${CMAKE_SOURCE_DIR}/test/test.cpp - ${CMAKE_SOURCE_DIR}/test/lltut.cpp - ) - SET(alltest_DEP_TARGETS - # needed by the test harness itself - ${APRUTIL_LIBRARIES} - ${APR_LIBRARIES} - llcommon - ) - IF(NOT "${project}" STREQUAL "llmath") + set(alltest_SOURCE_FILES + ${CMAKE_SOURCE_DIR}/test/test.cpp + ${CMAKE_SOURCE_DIR}/test/lltut.cpp + ) + set(alltest_DEP_TARGETS + # needed by the test harness itself + llcommon + ) + + set(alltest_LIBRARIES + llcommon + ll::googlemock + ) + if(NOT "${project}" STREQUAL "llmath") # add llmath as a dep unless the tested module *is* llmath! - LIST(APPEND alltest_DEP_TARGETS - llmath - ) - ENDIF(NOT "${project}" STREQUAL "llmath") - SET(alltest_INCLUDE_DIRS - ${LLMATH_INCLUDE_DIRS} - ${LLCOMMON_INCLUDE_DIRS} - ${LIBS_OPEN_DIR}/test - ${GOOGLEMOCK_INCLUDE_DIRS} - ) - SET(alltest_LIBRARIES - ${BOOST_FIBER_LIBRARY} - ${BOOST_CONTEXT_LIBRARY} - ${BOOST_SYSTEM_LIBRARY} - ${GOOGLEMOCK_LIBRARIES} - ${PTHREAD_LIBRARY} - ${WINDOWS_LIBRARIES} - ) + list(APPEND alltest_DEP_TARGETS llmath) + list(APPEND alltest_LIBRARIES llmath ) + endif() + # Headers, for convenience in targets. - SET(alltest_HEADER_FILES - ${CMAKE_SOURCE_DIR}/test/test.h - ) + set(alltest_HEADER_FILES ${CMAKE_SOURCE_DIR}/test/test.h) # start the source test executable definitions - SET(${project}_TEST_OUTPUT "") - FOREACH (source ${sources}) - STRING( REGEX REPLACE "(.*)\\.[^.]+$" "\\1" name ${source} ) - STRING( REGEX REPLACE ".*\\.([^.]+)$" "\\1" extension ${source} ) - IF(LL_TEST_VERBOSE) - MESSAGE("LL_ADD_PROJECT_UNIT_TESTS UNITTEST_PROJECT_${project} individual source: ${source} (${name}.${extension})") - ENDIF(LL_TEST_VERBOSE) + set(${project}_TEST_OUTPUT "") + foreach (source ${sources}) + string( REGEX REPLACE "(.*)\\.[^.]+$" "\\1" name ${source} ) + string( REGEX REPLACE ".*\\.([^.]+)$" "\\1" extension ${source} ) + if(LL_TEST_VERBOSE) + message("LL_ADD_PROJECT_UNIT_TESTS UNITTEST_PROJECT_${project} individual source: ${source} (${name}.${extension})") + endif() # # Per-codefile additional / external source, header, and include dir property extraction # # Source GET_OPT_SOURCE_FILE_PROPERTY(${name}_test_additional_SOURCE_FILES ${source} LL_TEST_ADDITIONAL_SOURCE_FILES) - SET(${name}_test_SOURCE_FILES - ${source} - tests/${name}_test.${extension} - ${alltest_SOURCE_FILES} - ${${name}_test_additional_SOURCE_FILES} ) - IF(LL_TEST_VERBOSE) - MESSAGE("LL_ADD_PROJECT_UNIT_TESTS ${name}_test_SOURCE_FILES ${${name}_test_SOURCE_FILES}") - ENDIF(LL_TEST_VERBOSE) - - if (USE_BUGSPLAT) - SET_PROPERTY(SOURCE ${${name}_test_SOURCE_FILES} - APPEND PROPERTY COMPILE_DEFINITIONS "${BUGSPLAT_DEFINE}") - endif (USE_BUGSPLAT) + set(${name}_test_SOURCE_FILES + ${source} + tests/${name}_test.${extension} + ${alltest_SOURCE_FILES} + ${${name}_test_additional_SOURCE_FILES} ) + if(LL_TEST_VERBOSE) + message("LL_ADD_PROJECT_UNIT_TESTS ${name}_test_SOURCE_FILES ${${name}_test_SOURCE_FILES}") + endif() # Headers GET_OPT_SOURCE_FILE_PROPERTY(${name}_test_additional_HEADER_FILES ${source} LL_TEST_ADDITIONAL_HEADER_FILES) - SET(${name}_test_HEADER_FILES ${name}.h ${${name}_test_additional_HEADER_FILES}) - set_source_files_properties(${${name}_test_HEADER_FILES} PROPERTIES HEADER_FILE_ONLY TRUE) - LIST(APPEND ${name}_test_SOURCE_FILES ${${name}_test_HEADER_FILES}) - IF(LL_TEST_VERBOSE) - MESSAGE("LL_ADD_PROJECT_UNIT_TESTS ${name}_test_HEADER_FILES ${${name}_test_HEADER_FILES}") - ENDIF(LL_TEST_VERBOSE) - # Include dirs + set(${name}_test_HEADER_FILES ${name}.h ${${name}_test_additional_HEADER_FILES}) + list(APPEND ${name}_test_SOURCE_FILES ${${name}_test_HEADER_FILES}) + if(LL_TEST_VERBOSE) + message("LL_ADD_PROJECT_UNIT_TESTS ${name}_test_HEADER_FILES ${${name}_test_HEADER_FILES}") + endif() + + # Setup target + add_executable(PROJECT_${project}_TEST_${name} ${${name}_test_SOURCE_FILES}) + + # Cannot declare a dependency on ${project} because the executable create above will later declare + # add_dependencies( ${project} ${project}_tests) + # as such grab ${project}'s interface include dirs and inject them here + get_property( ${name}_test_additional_INCLUDE_DIRS TARGET ${project} PROPERTY INTERFACE_INCLUDE_DIRECTORIES ) + target_include_directories (PROJECT_${project}_TEST_${name} PRIVATE ${${name}_test_additional_INCLUDE_DIRS} ) + GET_OPT_SOURCE_FILE_PROPERTY(${name}_test_additional_INCLUDE_DIRS ${source} LL_TEST_ADDITIONAL_INCLUDE_DIRS) - INCLUDE_DIRECTORIES(${alltest_INCLUDE_DIRS} ${${name}_test_additional_INCLUDE_DIRS} ) - IF(LL_TEST_VERBOSE) - MESSAGE("LL_ADD_PROJECT_UNIT_TESTS ${name}_test_additional_INCLUDE_DIRS ${${name}_test_additional_INCLUDE_DIRS}") - ENDIF(LL_TEST_VERBOSE) + target_include_directories (PROJECT_${project}_TEST_${name} PRIVATE ${${name}_test_additional_INCLUDE_DIRS} ) + target_include_directories (PROJECT_${project}_TEST_${name} PRIVATE ${LIBS_OPEN_DIR}/test ) - # Setup target - ADD_EXECUTABLE(PROJECT_${project}_TEST_${name} ${${name}_test_SOURCE_FILES}) - SET_TARGET_PROPERTIES(PROJECT_${project}_TEST_${name} PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${EXE_STAGING_DIR}") + set_target_properties(PROJECT_${project}_TEST_${name} PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${EXE_STAGING_DIR}") # # Per-codefile additional / external project dep and lib dep property extraction @@ -121,142 +107,133 @@ INCLUDE(GoogleMock) GET_OPT_SOURCE_FILE_PROPERTY(${name}_test_additional_PROJECTS ${source} LL_TEST_ADDITIONAL_PROJECTS) # Libraries GET_OPT_SOURCE_FILE_PROPERTY(${name}_test_additional_LIBRARIES ${source} LL_TEST_ADDITIONAL_LIBRARIES) - IF(LL_TEST_VERBOSE) - MESSAGE("LL_ADD_PROJECT_UNIT_TESTS ${name}_test_additional_PROJECTS ${${name}_test_additional_PROJECTS}") - MESSAGE("LL_ADD_PROJECT_UNIT_TESTS ${name}_test_additional_LIBRARIES ${${name}_test_additional_LIBRARIES}") - ENDIF(LL_TEST_VERBOSE) + + if(LL_TEST_VERBOSE) + message("LL_ADD_PROJECT_UNIT_TESTS ${name}_test_additional_PROJECTS ${${name}_test_additional_PROJECTS}") + message("LL_ADD_PROJECT_UNIT_TESTS ${name}_test_additional_LIBRARIES ${${name}_test_additional_LIBRARIES}") + endif() + # Add to project - TARGET_LINK_LIBRARIES(PROJECT_${project}_TEST_${name} ${alltest_LIBRARIES} ${alltest_DEP_TARGETS} ${${name}_test_additional_PROJECTS} ${${name}_test_additional_LIBRARIES} ) + target_link_libraries(PROJECT_${project}_TEST_${name} ${alltest_LIBRARIES} ${${name}_test_additional_PROJECTS} ${${name}_test_additional_LIBRARIES} ) + add_dependencies( PROJECT_${project}_TEST_${name} ${alltest_DEP_TARGETS}) # Compile-time Definitions GET_OPT_SOURCE_FILE_PROPERTY(${name}_test_additional_CFLAGS ${source} LL_TEST_ADDITIONAL_CFLAGS) - SET_TARGET_PROPERTIES(PROJECT_${project}_TEST_${name} - PROPERTIES - COMPILE_FLAGS "${${name}_test_additional_CFLAGS}" - COMPILE_DEFINITIONS "LL_TEST=${name};LL_TEST_${name}") - IF(LL_TEST_VERBOSE) - MESSAGE("LL_ADD_PROJECT_UNIT_TESTS ${name}_test_additional_CFLAGS ${${name}_test_additional_CFLAGS}") - ENDIF(LL_TEST_VERBOSE) - + set_target_properties(PROJECT_${project}_TEST_${name} + PROPERTIES + COMPILE_FLAGS "${${name}_test_additional_CFLAGS}" + COMPILE_DEFINITIONS "LL_TEST=${name};LL_TEST_${name}") + if(LL_TEST_VERBOSE) + message("LL_ADD_PROJECT_UNIT_TESTS ${name}_test_additional_CFLAGS ${${name}_test_additional_CFLAGS}") + endif() + # # Setup test targets # - SET(TEST_EXE $<TARGET_FILE:PROJECT_${project}_TEST_${name}>) - SET(TEST_OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/PROJECT_${project}_TEST_${name}_ok.txt) - SET(TEST_CMD ${TEST_EXE} --touch=${TEST_OUTPUT} --sourcedir=${CMAKE_CURRENT_SOURCE_DIR}) + set(TEST_EXE $<TARGET_FILE:PROJECT_${project}_TEST_${name}>) + set(TEST_OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/PROJECT_${project}_TEST_${name}_ok.txt) + set(TEST_CMD ${TEST_EXE} --touch=${TEST_OUTPUT} --sourcedir=${CMAKE_CURRENT_SOURCE_DIR}) # daveh - what configuration does this use? Debug? it's cmake-time, not build time. + poppy 2009-04-19 - IF(LL_TEST_VERBOSE) - MESSAGE(STATUS "LL_ADD_PROJECT_UNIT_TESTS ${name} test_cmd = ${TEST_CMD}") - ENDIF(LL_TEST_VERBOSE) + if(LL_TEST_VERBOSE) + message(STATUS "LL_ADD_PROJECT_UNIT_TESTS ${name} test_cmd = ${TEST_CMD}") + endif() SET_TEST_PATH(LD_LIBRARY_PATH) LL_TEST_COMMAND(TEST_SCRIPT_CMD "${LD_LIBRARY_PATH}" ${TEST_CMD}) - IF(LL_TEST_VERBOSE) - MESSAGE(STATUS "LL_ADD_PROJECT_UNIT_TESTS ${name} test_script = ${TEST_SCRIPT_CMD}") - ENDIF(LL_TEST_VERBOSE) - # Add test - ADD_CUSTOM_COMMAND( - OUTPUT ${TEST_OUTPUT} - COMMAND ${TEST_SCRIPT_CMD} - DEPENDS PROJECT_${project}_TEST_${name} - WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} - ) + if(LL_TEST_VERBOSE) + message(STATUS "LL_ADD_PROJECT_UNIT_TESTS ${name} test_script = ${TEST_SCRIPT_CMD}") + endif() + + # Add test + add_custom_command( + OUTPUT ${TEST_OUTPUT} + COMMAND ${TEST_SCRIPT_CMD} + DEPENDS PROJECT_${project}_TEST_${name} + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} + ) # Why not add custom target and add POST_BUILD command? # Slightly less uncertain behavior # (OUTPUT commands run non-deterministically AFAIK) + poppy 2009-04-19 - # > I did not use a post build step as I could not make it notify of a + # > I did not use a post build step as I could not make it notify of a # > failure after the first time you build and fail a test. - daveh 2009-04-20 - LIST(APPEND ${project}_TEST_OUTPUT ${TEST_OUTPUT}) - ENDFOREACH (source) + list(APPEND ${project}_TEST_OUTPUT ${TEST_OUTPUT}) + endforeach (source) # Add the test runner target per-project # (replaces old _test_ok targets all over the place) - ADD_CUSTOM_TARGET(${project}_tests ALL DEPENDS ${${project}_TEST_OUTPUT}) - ADD_DEPENDENCIES(${project} ${project}_tests) + add_custom_target(${project}_tests ALL DEPENDS ${${project}_TEST_OUTPUT}) + add_dependencies(${project} ${project}_tests) ENDMACRO(LL_ADD_PROJECT_UNIT_TESTS) #***************************************************************************** # GET_OPT_SOURCE_FILE_PROPERTY #***************************************************************************** MACRO(GET_OPT_SOURCE_FILE_PROPERTY var filename property) - GET_SOURCE_FILE_PROPERTY(${var} "${filename}" "${property}") - IF("${${var}}" MATCHES NOTFOUND) - SET(${var} "") - ENDIF("${${var}}" MATCHES NOTFOUND) + get_source_file_property(${var} "${filename}" "${property}") + if("${${var}}" MATCHES NOTFOUND) + set(${var} "") + endif() ENDMACRO(GET_OPT_SOURCE_FILE_PROPERTY) #***************************************************************************** # LL_ADD_INTEGRATION_TEST #***************************************************************************** -FUNCTION(LL_ADD_INTEGRATION_TEST - testname - additional_source_files - library_dependencies -# variable args - ) +FUNCTION(LL_ADD_INTEGRATION_TEST + testname + additional_source_files + library_dependencies + # variable args + ) if(TEST_DEBUG) message(STATUS "Adding INTEGRATION_TEST_${testname} - debug output is on") - endif(TEST_DEBUG) + endif() - SET(source_files - tests/${testname}_test.cpp - ${CMAKE_SOURCE_DIR}/test/test.cpp - ${CMAKE_SOURCE_DIR}/test/lltut.cpp - ${additional_source_files} - ) + set(source_files + tests/${testname}_test.cpp + ${CMAKE_SOURCE_DIR}/test/test.cpp + ${CMAKE_SOURCE_DIR}/test/lltut.cpp + ${additional_source_files} + ) - SET(libraries - ${LEGACY_STDIO_LIBS} - ${library_dependencies} - ${BOOST_FIBER_LIBRARY} - ${BOOST_CONTEXT_LIBRARY} - ${BOOST_SYSTEM_LIBRARY} - ${GOOGLEMOCK_LIBRARIES} - ${PTHREAD_LIBRARY} - ) + set(libraries + ${library_dependencies} + ll::googlemock + ) # Add test executable build target if(TEST_DEBUG) message(STATUS "ADD_EXECUTABLE(INTEGRATION_TEST_${testname} ${source_files})") - endif(TEST_DEBUG) - ADD_EXECUTABLE(INTEGRATION_TEST_${testname} ${source_files}) - SET_TARGET_PROPERTIES(INTEGRATION_TEST_${testname} - PROPERTIES - RUNTIME_OUTPUT_DIRECTORY "${EXE_STAGING_DIR}" - COMPILE_DEFINITIONS "LL_TEST=${testname};LL_TEST_${testname}" - ) - - if(USESYSTEMLIBS) - SET_TARGET_PROPERTIES(INTEGRATION_TEST_${testname} PROPERTIES COMPILE_FLAGS -I"${TUT_INCLUDE_DIR}") - endif(USESYSTEMLIBS) + endif() - if (USE_BUGSPLAT) - SET_PROPERTY(SOURCE ${source_files} - APPEND PROPERTY COMPILE_DEFINITIONS "${BUGSPLAT_DEFINE}") - endif (USE_BUGSPLAT) + add_executable(INTEGRATION_TEST_${testname} ${source_files}) + set_target_properties(INTEGRATION_TEST_${testname} + PROPERTIES + RUNTIME_OUTPUT_DIRECTORY "${EXE_STAGING_DIR}" + COMPILE_DEFINITIONS "LL_TEST=${testname};LL_TEST_${testname}" + ) - # The following was copied to llcorehttp/CMakeLists.txt's texture_load target. + # The following was copied to llcorehttp/CMakeLists.txt's texture_load target. # Any changes made here should be replicated there. if (WINDOWS) - SET_TARGET_PROPERTIES(INTEGRATION_TEST_${testname} - PROPERTIES - LINK_FLAGS "/debug /NODEFAULTLIB:LIBCMT /SUBSYSTEM:CONSOLE" - LINK_FLAGS_DEBUG "/NODEFAULTLIB:\"LIBCMT;LIBCMTD;MSVCRT\" /INCREMENTAL:NO" - LINK_FLAGS_RELEASE "" - ) - endif (WINDOWS) + set_target_properties(INTEGRATION_TEST_${testname} + PROPERTIES + LINK_FLAGS "/debug /NODEFAULTLIB:LIBCMT /SUBSYSTEM:CONSOLE" + ) + endif () # Add link deps to the executable if(TEST_DEBUG) message(STATUS "TARGET_LINK_LIBRARIES(INTEGRATION_TEST_${testname} ${libraries})") - endif(TEST_DEBUG) - TARGET_LINK_LIBRARIES(INTEGRATION_TEST_${testname} ${libraries}) + endif() + + target_link_libraries(INTEGRATION_TEST_${testname} ${libraries}) + target_include_directories (INTEGRATION_TEST_${testname} PRIVATE ${LIBS_OPEN_DIR}/test ) # Create the test running command - SET(test_command ${ARGN}) - SET(TEST_EXE $<TARGET_FILE:INTEGRATION_TEST_${testname}>) - LIST(FIND test_command "{}" test_exe_pos) - IF(test_exe_pos LESS 0) + set(test_command ${ARGN}) + set(TEST_EXE $<TARGET_FILE:INTEGRATION_TEST_${testname}>) + list(FIND test_command "{}" test_exe_pos) + if(test_exe_pos LESS 0) # The {} marker means "the full pathname of the test executable." # test_exe_pos -1 means we didn't find it -- so append the test executable # name to $ARGN, the variable part of the arg list. This is convenient @@ -265,26 +242,26 @@ FUNCTION(LL_ADD_INTEGRATION_TEST # pathname of the test program as the last of its args. You need specify # {} only if the test program's pathname isn't the last argument in the # desired command line. - LIST(APPEND test_command "${TEST_EXE}") - ELSE (test_exe_pos LESS 0) + list(APPEND test_command "${TEST_EXE}") + else (test_exe_pos LESS 0) # Found {} marker at test_exe_pos. Remove the {}... - LIST(REMOVE_AT test_command test_exe_pos) + list(REMOVE_AT test_command test_exe_pos) # ...and replace it with the actual name of the test executable. - LIST(INSERT test_command test_exe_pos "${TEST_EXE}") - ENDIF (test_exe_pos LESS 0) + list(INSERT test_command test_exe_pos "${TEST_EXE}") + endif() SET_TEST_PATH(LD_LIBRARY_PATH) LL_TEST_COMMAND(TEST_SCRIPT_CMD "${LD_LIBRARY_PATH}" ${test_command}) if(TEST_DEBUG) message(STATUS "TEST_SCRIPT_CMD: ${TEST_SCRIPT_CMD}") - endif(TEST_DEBUG) + endif() - ADD_CUSTOM_COMMAND( - TARGET INTEGRATION_TEST_${testname} - POST_BUILD - COMMAND ${TEST_SCRIPT_CMD} - ) + add_custom_command( + TARGET INTEGRATION_TEST_${testname} + POST_BUILD + COMMAND ${TEST_SCRIPT_CMD} + ) # Use CTEST? Not sure how to yet... # ADD_TEST(INTEGRATION_TEST_RUNNER_${testname} ${TEST_SCRIPT_CMD}) @@ -299,18 +276,14 @@ MACRO(SET_TEST_PATH LISTVAR) # We typically build/package only Release variants of third-party # libraries, so append the Release staging dir in case the library being # sought doesn't have a debug variant. - set(${LISTVAR} ${SHARED_LIB_STAGING_DIR}/${CMAKE_CFG_INTDIR} ${SHARED_LIB_STAGING_DIR}/Release) + set(${LISTVAR} ${SHARED_LIB_STAGING_DIR} ${SHARED_LIB_STAGING_DIR}/Release) ELSEIF(DARWIN) # We typically build/package only Release variants of third-party # libraries, so append the Release staging dir in case the library being # sought doesn't have a debug variant. - set(${LISTVAR} ${SHARED_LIB_STAGING_DIR}/${CMAKE_CFG_INTDIR}/Resources ${SHARED_LIB_STAGING_DIR}/Release/Resources /usr/lib) + set(${LISTVAR} ${SHARED_LIB_STAGING_DIR} ${SHARED_LIB_STAGING_DIR}/Release/Resources /usr/lib) ELSE(WINDOWS) # Linux uses a single staging directory anyway. - IF (USESYSTEMLIBS) - set(${LISTVAR} ${CMAKE_BINARY_DIR}/llcommon /usr/lib /usr/local/lib) - ELSE (USESYSTEMLIBS) - set(${LISTVAR} ${SHARED_LIB_STAGING_DIR} /usr/lib) - ENDIF (USESYSTEMLIBS) + set(${LISTVAR} ${SHARED_LIB_STAGING_DIR} /usr/lib) ENDIF(WINDOWS) ENDMACRO(SET_TEST_PATH) diff --git a/indra/cmake/LLAppearance.cmake b/indra/cmake/LLAppearance.cmake index 675330ec72..bf34b13714 100644 --- a/indra/cmake/LLAppearance.cmake +++ b/indra/cmake/LLAppearance.cmake @@ -2,26 +2,9 @@ include(Variables) include(Boost) -include(LLMessage) include(LLCoreHttp) -set(LLAPPEARANCE_INCLUDE_DIRS - ${LIBS_OPEN_DIR}/llappearance - ) -if (BUILD_HEADLESS) - set(LLAPPEARANCE_HEADLESS_LIBRARIES - llappearanceheadless - ) -endif (BUILD_HEADLESS) - -set(LLAPPEARANCE_LIBRARIES llappearance - llmessage - llcorehttp - ${BOOST_FIBER_LIBRARY} - ${BOOST_CONTEXT_LIBRARY} - ${BOOST_SYSTEM_LIBRARY} - ) diff --git a/indra/cmake/LLAudio.cmake b/indra/cmake/LLAudio.cmake index 7c248dfc72..c842c69bfe 100644 --- a/indra/cmake/LLAudio.cmake +++ b/indra/cmake/LLAudio.cmake @@ -1,10 +1,3 @@ # -*- cmake -*- include(Audio) - -set(LLAUDIO_INCLUDE_DIRS - ${LIBS_OPEN_DIR}/llaudio - ) - -# be exhaustive here -set(LLAUDIO_LIBRARIES llaudio ${VORBISFILE_LIBRARIES} ${VORBIS_LIBRARIES} ${VORBISENC_LIBRARIES} ${OGG_LIBRARIES} ${OPENAL_LIBRARIES}) diff --git a/indra/cmake/LLCharacter.cmake b/indra/cmake/LLCharacter.cmake deleted file mode 100644 index 9b2f5c4956..0000000000 --- a/indra/cmake/LLCharacter.cmake +++ /dev/null @@ -1,7 +0,0 @@ -# -*- cmake -*- - -set(LLCHARACTER_INCLUDE_DIRS - ${LIBS_OPEN_DIR}/llcharacter - ) - -set(LLCHARACTER_LIBRARIES llcharacter) diff --git a/indra/cmake/LLCommon.cmake b/indra/cmake/LLCommon.cmake index 528b43c3fc..869d5805f2 100644 --- a/indra/cmake/LLCommon.cmake +++ b/indra/cmake/LLCommon.cmake @@ -6,38 +6,6 @@ include(EXPAT) include(Tracy) include(xxHash) include(ZLIBNG) +include(JsonCpp) -set(LLCOMMON_INCLUDE_DIRS - ${LIBS_OPEN_DIR}/llcommon - ${APRUTIL_INCLUDE_DIR} - ${APR_INCLUDE_DIR} - ${TRACY_INCLUDE_DIR} - ) -set(LLCOMMON_SYSTEM_INCLUDE_DIRS - ${Boost_INCLUDE_DIRS} - ) - -if (LINUX) - # In order to support using ld.gold on linux, we need to explicitely - # specify all libraries that llcommon uses. - # llcommon uses `clock_gettime' which is provided by librt on linux. - set(LLCOMMON_LIBRARIES llcommon - ${BOOST_FIBER_LIBRARY} - ${BOOST_CONTEXT_LIBRARY} - ${BOOST_THREAD_LIBRARY} - ${BOOST_SYSTEM_LIBRARY} - rt - ) -else (LINUX) - set(LLCOMMON_LIBRARIES llcommon - ${BOOST_FIBER_LIBRARY} - ${BOOST_CONTEXT_LIBRARY} - ${BOOST_THREAD_LIBRARY} - ${BOOST_SYSTEM_LIBRARY} - ) -endif (LINUX) - -set(LLCOMMON_LINK_SHARED OFF CACHE BOOL "Build the llcommon target as a static library.") -if(LLCOMMON_LINK_SHARED) - add_definitions(-DLL_COMMON_LINK_SHARED=1) -endif(LLCOMMON_LINK_SHARED) +include(XmlRpcEpi) diff --git a/indra/cmake/LLCoreHttp.cmake b/indra/cmake/LLCoreHttp.cmake index 613453ab5d..22ed5fef9c 100644 --- a/indra/cmake/LLCoreHttp.cmake +++ b/indra/cmake/LLCoreHttp.cmake @@ -2,16 +2,4 @@ include(CURL) include(OpenSSL) -include(Boost) - -set(LLCOREHTTP_INCLUDE_DIRS - ${LIBS_OPEN_DIR}/llcorehttp - ${CURL_INCLUDE_DIRS} - ${OPENSSL_INCLUDE_DIRS} - ${BOOST_INCLUDE_DIRS} - ) - -set(LLCOREHTTP_LIBRARIES llcorehttp - ${BOOST_FIBER_LIBRARY} - ${BOOST_CONTEXT_LIBRARY} - ${BOOST_SYSTEM_LIBRARY}) +include(NGHTTP2) diff --git a/indra/cmake/LLCrashLogger.cmake b/indra/cmake/LLCrashLogger.cmake deleted file mode 100644 index f2cb83eb8b..0000000000 --- a/indra/cmake/LLCrashLogger.cmake +++ /dev/null @@ -1,7 +0,0 @@ -# -*- cmake -*- - -set(LLCRASHLOGGER_INCLUDE_DIRS - ${LIBS_OPEN_DIR}/llcrashlogger - ) - -set(LLCRASHLOGGER_LIBRARIES llcrashlogger) diff --git a/indra/cmake/LLFileSystem.cmake b/indra/cmake/LLFileSystem.cmake deleted file mode 100644 index 2e6c42c30c..0000000000 --- a/indra/cmake/LLFileSystem.cmake +++ /dev/null @@ -1,7 +0,0 @@ -# -*- cmake -*- - -set(LLFILESYSTEM_INCLUDE_DIRS - ${LIBS_OPEN_DIR}/llfilesystem - ) - -set(LLFILESYSTEM_LIBRARIES llfilesystem) diff --git a/indra/cmake/LLImage.cmake b/indra/cmake/LLImage.cmake index ec3da89081..8e0b44dfe4 100644 --- a/indra/cmake/LLImage.cmake +++ b/indra/cmake/LLImage.cmake @@ -1,11 +1,4 @@ # -*- cmake -*- -include(JPEG) +#include(JPEG) include(PNG) - -set(LLIMAGE_INCLUDE_DIRS - ${LIBS_OPEN_DIR}/llimage - ${JPEG_INCLUDE_DIRS} - ) - -set(LLIMAGE_LIBRARIES llimage) diff --git a/indra/cmake/LLImageJ2COJ.cmake b/indra/cmake/LLImageJ2COJ.cmake deleted file mode 100644 index 1bcf205f2d..0000000000 --- a/indra/cmake/LLImageJ2COJ.cmake +++ /dev/null @@ -1,5 +0,0 @@ -# -*- cmake -*- - -include(OpenJPEG) - -set(LLIMAGEJ2COJ_LIBRARIES llimagej2coj) diff --git a/indra/cmake/LLInventory.cmake b/indra/cmake/LLInventory.cmake deleted file mode 100644 index c3dc077a2b..0000000000 --- a/indra/cmake/LLInventory.cmake +++ /dev/null @@ -1,7 +0,0 @@ -# -*- cmake -*- - -set(LLINVENTORY_INCLUDE_DIRS - ${LIBS_OPEN_DIR}/llinventory - ) - -set(LLINVENTORY_LIBRARIES llinventory) diff --git a/indra/cmake/LLKDU.cmake b/indra/cmake/LLKDU.cmake index e478b01f84..fda25610da 100644 --- a/indra/cmake/LLKDU.cmake +++ b/indra/cmake/LLKDU.cmake @@ -7,15 +7,20 @@ if (INSTALL_PROPRIETARY) set(USE_KDU ON CACHE BOOL "Use Kakadu library.") endif (INSTALL_PROPRIETARY) +include_guard() +add_library( ll::kdu INTERFACE IMPORTED ) + if (USE_KDU) include(Prebuilt) use_prebuilt_binary(kdu) if (WINDOWS) - set(KDU_LIBRARY kdu.lib) + target_link_libraries( ll::kdu INTERFACE kdu.lib) else (WINDOWS) - set(KDU_LIBRARY libkdu.a) + target_link_libraries( ll::kdu INTERFACE libkdu.a) endif (WINDOWS) - set(KDU_INCLUDE_DIR ${AUTOBUILD_INSTALL_DIR}/include/kdu) - set(LLKDU_INCLUDE_DIRS ${LIBS_OPEN_DIR}/llkdu) - set(LLKDU_LIBRARIES llkdu) + + target_include_directories( ll::kdu SYSTEM INTERFACE + ${AUTOBUILD_INSTALL_DIR}/include/kdu + ${LIBS_OPEN_DIR}/llkdu + ) endif (USE_KDU) diff --git a/indra/cmake/LLLogin.cmake b/indra/cmake/LLLogin.cmake deleted file mode 100644 index 47d171876a..0000000000 --- a/indra/cmake/LLLogin.cmake +++ /dev/null @@ -1,7 +0,0 @@ -# -*- cmake -*- - -set(LLLOGIN_INCLUDE_DIRS - ${LIBS_OPEN_DIR}/viewer_components/login - ) - -set(LLLOGIN_LIBRARIES lllogin) diff --git a/indra/cmake/LLMath.cmake b/indra/cmake/LLMath.cmake index 893920ae6f..a707c75bc4 100644 --- a/indra/cmake/LLMath.cmake +++ b/indra/cmake/LLMath.cmake @@ -1,7 +1,2 @@ # -*- cmake -*- -set(LLMATH_INCLUDE_DIRS - ${LIBS_OPEN_DIR}/llmath - ) - -set(LLMATH_LIBRARIES llmath) diff --git a/indra/cmake/LLMeshOptimizer.cmake b/indra/cmake/LLMeshOptimizer.cmake deleted file mode 100644 index b79944f618..0000000000 --- a/indra/cmake/LLMeshOptimizer.cmake +++ /dev/null @@ -1,7 +0,0 @@ -# -*- cmake -*- - -set(LLMESHOPTIMIZER_INCLUDE_DIRS - ${LIBS_OPEN_DIR}/llmeshoptimizer - ) - -set(LLMESHOPTIMIZER_LIBRARIES llmeshoptimizer) diff --git a/indra/cmake/LLMessage.cmake b/indra/cmake/LLMessage.cmake deleted file mode 100644 index 7be53ec0ec..0000000000 --- a/indra/cmake/LLMessage.cmake +++ /dev/null @@ -1,13 +0,0 @@ -# -*- cmake -*- - -include(CURL) -include(OpenSSL) -include(XmlRpcEpi) - -set(LLMESSAGE_INCLUDE_DIRS - ${LIBS_OPEN_DIR}/llmessage - ${CURL_INCLUDE_DIRS} - ${OPENSSL_INCLUDE_DIRS} - ) - -set(LLMESSAGE_LIBRARIES llmessage) diff --git a/indra/cmake/LLPhysicsExtensions.cmake b/indra/cmake/LLPhysicsExtensions.cmake index e6afee762e..36821447c9 100644 --- a/indra/cmake/LLPhysicsExtensions.cmake +++ b/indra/cmake/LLPhysicsExtensions.cmake @@ -10,6 +10,9 @@ if (INSTALL_PROPRIETARY) set(HAVOK ON CACHE BOOL "Use Havok physics library") endif (INSTALL_PROPRIETARY) +include_guard() +add_library( llphysicsextensions_impl INTERFACE IMPORTED ) + # Note that the use_prebuilt_binary macros below do not in fact include binaries; # the llphysicsextensions_* packages are source only and are built here. @@ -19,17 +22,14 @@ if (HAVOK) include(Havok) use_prebuilt_binary(llphysicsextensions_source) set(LLPHYSICSEXTENSIONS_SRC_DIR ${LIBS_PREBUILT_DIR}/llphysicsextensions/src) - set(LLPHYSICSEXTENSIONS_LIBRARIES llphysicsextensions) - + target_link_libraries( llphysicsextensions_impl INTERFACE llphysicsextensions) elseif (HAVOK_TPV) use_prebuilt_binary(llphysicsextensions_tpv) - set(LLPHYSICSEXTENSIONS_LIBRARIES llphysicsextensions_tpv) - + target_link_libraries( llphysicsextensions_impl INTERFACE llphysicsextensions_tpv) else (HAVOK) use_prebuilt_binary(llphysicsextensions_stub) set(LLPHYSICSEXTENSIONS_SRC_DIR ${LIBS_PREBUILT_DIR}/llphysicsextensions/stub) - set(LLPHYSICSEXTENSIONS_LIBRARIES llphysicsextensionsstub) - + target_link_libraries( llphysicsextensions_impl INTERFACE llphysicsextensionsstub) endif (HAVOK) -set(LLPHYSICSEXTENSIONS_INCLUDE_DIRS ${LIBS_PREBUILT_DIR}/include/llphysicsextensions) +target_include_directories( llphysicsextensions_impl INTERFACE ${LIBS_PREBUILT_DIR}/include/llphysicsextensions) diff --git a/indra/cmake/LLPlugin.cmake b/indra/cmake/LLPlugin.cmake deleted file mode 100644 index 399cb332dd..0000000000 --- a/indra/cmake/LLPlugin.cmake +++ /dev/null @@ -1,14 +0,0 @@ -# -*- cmake -*- - - -set(LLPLUGIN_INCLUDE_DIRS - ${LIBS_OPEN_DIR}/llplugin - ) - -if (LINUX) - # In order to support using ld.gold on linux, we need to explicitely - # specify all libraries that llplugin uses. - set(LLPLUGIN_LIBRARIES llplugin pthread) -else (LINUX) - set(LLPLUGIN_LIBRARIES llplugin) -endif (LINUX) diff --git a/indra/cmake/LLPrimitive.cmake b/indra/cmake/LLPrimitive.cmake index 4e34951215..3d8499cbc3 100644 --- a/indra/cmake/LLPrimitive.cmake +++ b/indra/cmake/LLPrimitive.cmake @@ -4,49 +4,49 @@ include(Prebuilt) include(Boost) +include_guard() + +add_library( ll::pcre INTERFACE IMPORTED ) +add_library( ll::minizip-ng INTERFACE IMPORTED ) +add_library( ll::libxml INTERFACE IMPORTED ) +add_library( ll::colladadom INTERFACE IMPORTED ) + +# ND, needs fixup in collada conan pkg +if( USE_CONAN ) + target_include_directories( ll::colladadom SYSTEM INTERFACE + "${CONAN_INCLUDE_DIRS_COLLADADOM}/collada-dom/" + "${CONAN_INCLUDE_DIRS_COLLADADOM}/collada-dom/1.4/" ) +endif() + +use_system_binary( colladadom ) + use_prebuilt_binary(colladadom) use_prebuilt_binary(minizip-ng) # needed for colladadom use_prebuilt_binary(pcre) use_prebuilt_binary(libxml2) -set(LLPRIMITIVE_INCLUDE_DIRS - ${LIBS_OPEN_DIR}/llprimitive - ) +target_link_libraries( ll::pcre INTERFACE pcrecpp pcre ) + +if (WINDOWS) + target_link_libraries( ll::minizip-ng INTERFACE libminizip ) +else() + target_link_libraries( ll::minizip-ng INTERFACE minizip ) +endif() + if (WINDOWS) - set(LLPRIMITIVE_LIBRARIES - debug llprimitive - optimized llprimitive - debug libcollada14dom23-sd - optimized libcollada14dom23-s - libxml2_a - debug pcrecppd - optimized pcrecpp - debug pcred - optimized pcre - debug libminizip - optimized libminizip - ${BOOST_SYSTEM_LIBRARIES} + target_link_libraries( ll::libxml INTERFACE libxml2_a) +else() + target_link_libraries( ll::libxml INTERFACE xml2) +endif() + +target_include_directories( ll::colladadom SYSTEM INTERFACE + ${LIBS_PREBUILT_DIR}/include/collada + ${LIBS_PREBUILT_DIR}/include/collada/1.4 ) +if (WINDOWS) + target_link_libraries(ll::colladadom INTERFACE libcollada14dom23-s ll::libxml ll::minizip-ng ) elseif (DARWIN) - set(LLPRIMITIVE_LIBRARIES - llprimitive - debug collada14dom-d - optimized collada14dom - minizip # for collada libminizip.a - xml2 - pcrecpp - pcre - iconv # Required by libxml2 - ) + target_link_libraries(ll::colladadom INTERFACE collada14dom ll::libxml ll::minizip-ng) elseif (LINUX) - set(LLPRIMITIVE_LIBRARIES - llprimitive - debug collada14dom-d - optimized collada14dom - minizip - xml2 - pcrecpp - pcre - ) -endif (WINDOWS) - + target_link_libraries(ll::colladadom INTERFACE collada14dom ll::libxml ll::minizip-ng) +endif() diff --git a/indra/cmake/LLRender.cmake b/indra/cmake/LLRender.cmake deleted file mode 100644 index 868922451f..0000000000 --- a/indra/cmake/LLRender.cmake +++ /dev/null @@ -1,20 +0,0 @@ -# -*- cmake -*- - -include(Variables) -include(FreeType) -include(GLH) - -set(LLRENDER_INCLUDE_DIRS - ${LIBS_OPEN_DIR}/llrender - ${GLH_INCLUDE_DIR} - ) - -if (BUILD_HEADLESS) - set(LLRENDER_HEADLESS_LIBRARIES - llrenderheadless - ) -endif (BUILD_HEADLESS) -set(LLRENDER_LIBRARIES - llrender - ) - diff --git a/indra/cmake/LLSharedLibs.cmake b/indra/cmake/LLSharedLibs.cmake index f69b45cd92..e3e2a3b0c6 100644 --- a/indra/cmake/LLSharedLibs.cmake +++ b/indra/cmake/LLSharedLibs.cmake @@ -37,40 +37,3 @@ macro(ll_deploy_sharedlibs_command target_exe) endif(NOT DARWIN) endmacro(ll_deploy_sharedlibs_command) - -# ll_stage_sharedlib -# Performs config and adds a copy command for a sharedlib target. -macro(ll_stage_sharedlib DSO_TARGET) - # target gets written to the DLL staging directory. - # Also this directory is shared with RunBuildTest.cmake, y'know, for the tests. - set_target_properties(${DSO_TARGET} PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${SHARED_LIB_STAGING_DIR}) - if(NOT WINDOWS) - get_target_property(DSO_PATH ${DSO_TARGET} LOCATION) - get_filename_component(DSO_FILE ${DSO_PATH} NAME) - if(DARWIN) - set(SHARED_LIB_STAGING_DIR_CONFIG ${SHARED_LIB_STAGING_DIR}/${CMAKE_CFG_INTDIR}/Resources) - else(DARWIN) - set(SHARED_LIB_STAGING_DIR_CONFIG ${SHARED_LIB_STAGING_DIR}/${CMAKE_CFG_INTDIR}) - endif(DARWIN) - - # *TODO - maybe make this a symbolic link? -brad - add_custom_command( - TARGET ${DSO_TARGET} POST_BUILD - COMMAND ${CMAKE_COMMAND} - ARGS - -E - copy_if_different - ${DSO_PATH} - ${SHARED_LIB_STAGING_DIR_CONFIG}/${DSO_FILE} - COMMENT "Copying llcommon to the staging folder." - ) - endif(NOT WINDOWS) - - if (DARWIN) - set_target_properties(${DSO_TARGET} PROPERTIES - BUILD_WITH_INSTALL_RPATH 1 - INSTALL_NAME_DIR "@executable_path/../Resources" - ) - endif(DARWIN) - -endmacro(ll_stage_sharedlib) diff --git a/indra/cmake/LLUI.cmake b/indra/cmake/LLUI.cmake deleted file mode 100644 index 34de57108b..0000000000 --- a/indra/cmake/LLUI.cmake +++ /dev/null @@ -1,7 +0,0 @@ -# -*- cmake -*- - -set(LLUI_INCLUDE_DIRS - ${LIBS_OPEN_DIR}/llui - ) - -set(LLUI_LIBRARIES llui) diff --git a/indra/cmake/LLWindow.cmake b/indra/cmake/LLWindow.cmake index 80af7ff2ab..b36e970560 100644 --- a/indra/cmake/LLWindow.cmake +++ b/indra/cmake/LLWindow.cmake @@ -4,39 +4,19 @@ include(Variables) include(GLEXT) include(Prebuilt) -if (USESYSTEMLIBS) - include(FindSDL) +include_guard() +add_library( ll::SDL INTERFACE IMPORTED ) - # This should be done by FindSDL. Sigh. - mark_as_advanced( - SDLMAIN_LIBRARY - SDL_INCLUDE_DIR - SDL_LIBRARY - ) -else (USESYSTEMLIBS) - if (LINUX) - use_prebuilt_binary(SDL) - set (SDL_FOUND TRUE) - set (SDL_INCLUDE_DIR ${LIBS_PREBUILT_DIR}/i686-linux) - set (SDL_LIBRARY SDL directfb fusion direct X11) - endif (LINUX) -endif (USESYSTEMLIBS) -if (SDL_FOUND) - include_directories(${SDL_INCLUDE_DIR}) -endif (SDL_FOUND) +if (LINUX) + #Must come first as use_system_binary can exit this file early + target_compile_definitions( ll::SDL INTERFACE LL_SDL=1) -set(LLWINDOW_INCLUDE_DIRS - ${GLEXT_INCLUDE_DIR} - ${LIBS_OPEN_DIR}/llwindow - ) + use_system_binary(SDL) + use_prebuilt_binary(SDL) + + target_include_directories( ll::SDL SYSTEM INTERFACE ${LIBS_PREBUILT_DIR}/include) + target_link_libraries( ll::SDL INTERFACE SDL directfb fusion direct X11) +endif (LINUX) -if (BUILD_HEADLESS) - set(LLWINDOW_HEADLESS_LIBRARIES - llwindowheadless - ) -endif (BUILD_HEADLESS) - set(LLWINDOW_LIBRARIES - llwindow - ) diff --git a/indra/cmake/LLXML.cmake b/indra/cmake/LLXML.cmake deleted file mode 100644 index b093c76297..0000000000 --- a/indra/cmake/LLXML.cmake +++ /dev/null @@ -1,14 +0,0 @@ -# -*- cmake -*- - -include(Boost) -include(EXPAT) - -set(LLXML_INCLUDE_DIRS - ${LIBS_OPEN_DIR}/llxml - ${EXPAT_INCLUDE_DIRS} - ) -set(LLXML_SYSTEM_INCLUDE_DIRS - ${Boost_INCLUDE_DIRS} - ) - -set(LLXML_LIBRARIES llxml) diff --git a/indra/cmake/LibVLCPlugin.cmake b/indra/cmake/LibVLCPlugin.cmake index df829b615a..599ce02844 100644 --- a/indra/cmake/LibVLCPlugin.cmake +++ b/indra/cmake/LibVLCPlugin.cmake @@ -2,29 +2,26 @@ include(Linking) include(Prebuilt) -if (USESYSTEMLIBS) - set(LIBVLCPLUGIN OFF CACHE BOOL - "LIBVLCPLUGIN support for the llplugin/llmedia test apps.") -else (USESYSTEMLIBS) - use_prebuilt_binary(vlc-bin) - set(LIBVLCPLUGIN ON CACHE BOOL +include_guard() +add_library( ll::libvlc INTERFACE IMPORTED ) + +use_prebuilt_binary(vlc-bin) +set(LIBVLCPLUGIN ON CACHE BOOL "LIBVLCPLUGIN support for the llplugin/llmedia test apps.") - set(VLC_INCLUDE_DIR ${LIBS_PREBUILT_DIR}/include/vlc) -endif (USESYSTEMLIBS) if (WINDOWS) - set(VLC_PLUGIN_LIBRARIES - libvlc.lib - libvlccore.lib + target_link_libraries( ll::libvlc INTERFACE + libvlc.lib + libvlccore.lib ) elseif (DARWIN) - set(VLC_PLUGIN_LIBRARIES - libvlc.dylib - libvlccore.dylib + target_link_libraries( ll::libvlc INTERFACE + libvlc.dylib + libvlccore.dylib ) elseif (LINUX) # Specify a full path to make sure we get a static link - set(VLC_PLUGIN_LIBRARIES + target_link_libraries( ll::libvlc INTERFACE ${LIBS_PREBUILT_DIR}/lib/libvlc.a ${LIBS_PREBUILT_DIR}/lib/libvlccore.a ) diff --git a/indra/cmake/Linking.cmake b/indra/cmake/Linking.cmake index 3cb235a9d5..4a501f420b 100644 --- a/indra/cmake/Linking.cmake +++ b/indra/cmake/Linking.cmake @@ -1,24 +1,34 @@ # -*- cmake -*- -if(NOT DEFINED ${CMAKE_CURRENT_LIST_FILE}_INCLUDED) -set(${CMAKE_CURRENT_LIST_FILE}_INCLUDED "YES") - +include_guard() include(Variables) set(ARCH_PREBUILT_DIRS ${AUTOBUILD_INSTALL_DIR}/lib) set(ARCH_PREBUILT_DIRS_PLUGINS ${AUTOBUILD_INSTALL_DIR}/plugins) set(ARCH_PREBUILT_DIRS_RELEASE ${AUTOBUILD_INSTALL_DIR}/lib/release) set(ARCH_PREBUILT_DIRS_DEBUG ${AUTOBUILD_INSTALL_DIR}/lib/debug) -if (WINDOWS) - set(SHARED_LIB_STAGING_DIR ${CMAKE_BINARY_DIR}/sharedlibs) - set(EXE_STAGING_DIR ${CMAKE_BINARY_DIR}/sharedlibs) +if (WINDOWS OR DARWIN ) + # Kludge for older cmake versions, 3.20+ is needed to use a genex in add_custom_command( OUTPUT <var> ... ) + # Using this will work okay-ish, as Debug is not supported anyway. But for property multi config and also + # ninja support the genex version is preferred. + if(${CMAKE_VERSION} VERSION_LESS "3.20.0") + if(CMAKE_BUILD_TYPE MATCHES Release) + set(SHARED_LIB_STAGING_DIR ${CMAKE_BINARY_DIR}/sharedlibs/Release) + elseif (CMAKE_BUILD_TYPE MATCHES RelWithDebInfo) + set(SHARED_LIB_STAGING_DIR ${CMAKE_BINARY_DIR}/sharedlibs/RelWithDebInfo) + endif() + else() + set(SHARED_LIB_STAGING_DIR ${CMAKE_BINARY_DIR}/sharedlibs/$<IF:$<BOOL:${LL_GENERATOR_IS_MULTI_CONFIG}>,$<CONFIG>,>) + endif() + + if( DARWIN ) + set( SHARED_LIB_STAGING_DIR ${SHARED_LIB_STAGING_DIR}/Resources) + endif() + set(EXE_STAGING_DIR ${CMAKE_BINARY_DIR}/sharedlibs/$<IF:$<BOOL:${LL_GENERATOR_IS_MULTI_CONFIG}>,$<CONFIG>,>) elseif (LINUX) set(SHARED_LIB_STAGING_DIR ${CMAKE_BINARY_DIR}/sharedlibs/lib) set(EXE_STAGING_DIR ${CMAKE_BINARY_DIR}/sharedlibs/bin) -elseif (DARWIN) - set(SHARED_LIB_STAGING_DIR ${CMAKE_BINARY_DIR}/sharedlibs) - set(EXE_STAGING_DIR "${CMAKE_BINARY_DIR}/sharedlibs") -endif (WINDOWS) +endif () # Autobuild packages must provide 'release' versions of libraries, but may provide versions for # specific build types. AUTOBUILD_LIBS_INSTALL_DIRS lists first the build type directory and then @@ -27,52 +37,54 @@ endif (WINDOWS) # windows) and CMAKE_BUILD_TYPE on Makefile based generators (like linux). The reason for this is # that CMAKE_BUILD_TYPE is essentially meaningless at configuration time for IDE generators and # CMAKE_CFG_INTDIR is meaningless at build time for Makefile generators -if(WINDOWS OR DARWIN) - # the cmake xcode and VS generators implicitly append ${CMAKE_CFG_INTDIR} to the library paths for us - # fortunately both windows and darwin are case insensitive filesystems so this works. - set(AUTOBUILD_LIBS_INSTALL_DIRS "${AUTOBUILD_INSTALL_DIR}/lib/") -else(WINDOWS OR DARWIN) - # else block is for linux and any other makefile based generators - string(TOLOWER ${CMAKE_BUILD_TYPE} CMAKE_BUILD_TYPE_LOWER) - set(AUTOBUILD_LIBS_INSTALL_DIRS ${AUTOBUILD_INSTALL_DIR}/lib/${CMAKE_BUILD_TYPE_LOWER}) -endif(WINDOWS OR DARWIN) -if (NOT "${CMAKE_BUILD_TYPE}" STREQUAL "Release") - # When we're building something other than Release, append the - # packages/lib/release directory to deal with autobuild packages that don't - # provide (e.g.) lib/debug libraries. - list(APPEND AUTOBUILD_LIBS_INSTALL_DIRS ${ARCH_PREBUILT_DIRS_RELEASE}) -endif (NOT "${CMAKE_BUILD_TYPE}" STREQUAL "Release") +link_directories(${AUTOBUILD_INSTALL_DIR}/lib/$<LOWER_CASE:$<CONFIG>>) +link_directories(${AUTOBUILD_INSTALL_DIR}/lib/release) -link_directories(${AUTOBUILD_LIBS_INSTALL_DIRS}) +add_library( ll::oslibraries INTERFACE IMPORTED ) if (LINUX) - set(DL_LIBRARY dl) - set(PTHREAD_LIBRARY pthread) -else (LINUX) - set(DL_LIBRARY "") - set(PTHREAD_LIBRARY "") -endif (LINUX) + target_link_libraries( ll::oslibraries INTERFACE + dl + pthread + rt) +elseif (WINDOWS) + target_link_libraries( ll::oslibraries INTERFACE + advapi32 + shell32 + ws2_32 + mswsock + psapi + winmm + netapi32 + wldap32 + gdi32 + user32 + ole32 + dbghelp + legacy_stdio_definitions + ) +else() + include(CMakeFindFrameworks) + find_library(COREFOUNDATION_LIBRARY CoreFoundation) + find_library(CARBON_LIBRARY Carbon) + find_library(COCOA_LIBRARY Cocoa) + find_library(IOKIT_LIBRARY IOKit) + + find_library(AGL_LIBRARY AGL) + find_library(APPKIT_LIBRARY AppKit) + find_library(COREAUDIO_LIBRARY CoreAudio) + + target_link_libraries( ll::oslibraries INTERFACE + ${COCOA_LIBRARY} + ${IOKIT_LIBRARY} + ${COREFOUNDATION_LIBRARY} + ${CARBON_LIBRARY} + ${AGL_LIBRARY} + ${APPKIT_LIBRARY} + ${COREAUDIO_LIBRARY} + ) +endif() + -if (WINDOWS) - set(WINDOWS_LIBRARIES - advapi32 - shell32 - ws2_32 - mswsock - psapi - winmm - netapi32 - wldap32 - gdi32 - user32 - ole32 - dbghelp - ) -else (WINDOWS) - set(WINDOWS_LIBRARIES "") -endif (WINDOWS) - -mark_as_advanced(DL_LIBRARY PTHREAD_LIBRARY WINDOWS_LIBRARIES) -endif(NOT DEFINED ${CMAKE_CURRENT_LIST_FILE}_INCLUDED) diff --git a/indra/cmake/MESHOPTIMIZER.cmake b/indra/cmake/MESHOPTIMIZER.cmake deleted file mode 100644 index 1c5b47b9bd..0000000000 --- a/indra/cmake/MESHOPTIMIZER.cmake +++ /dev/null @@ -1,16 +0,0 @@ -# -*- cmake -*- - -include(Linking) -include(Prebuilt) - -use_prebuilt_binary(meshoptimizer) - -if (WINDOWS) - set(MESHOPTIMIZER_LIBRARIES meshoptimizer.lib) -elseif (LINUX) - set(MESHOPTIMIZER_LIBRARIES meshoptimizer.o) -elseif (DARWIN) - set(MESHOPTIMIZER_LIBRARIES libmeshoptimizer.a) -endif (WINDOWS) - -set(MESHOPTIMIZER_INCLUDE_DIRS ${LIBS_PREBUILT_DIR}/include/meshoptimizer) diff --git a/indra/cmake/MediaPluginBase.cmake b/indra/cmake/MediaPluginBase.cmake deleted file mode 100644 index 2be035b641..0000000000 --- a/indra/cmake/MediaPluginBase.cmake +++ /dev/null @@ -1,8 +0,0 @@ -# -*- cmake -*- - - -set(MEDIA_PLUGIN_BASE_INCLUDE_DIRS - ${LIBS_OPEN_DIR}/media_plugins/base/ - ) - -set(MEDIA_PLUGIN_BASE_LIBRARIES media_plugin_base) diff --git a/indra/cmake/Meshoptimizer.cmake b/indra/cmake/Meshoptimizer.cmake new file mode 100644 index 0000000000..fd144d2b97 --- /dev/null +++ b/indra/cmake/Meshoptimizer.cmake @@ -0,0 +1,20 @@ +# -*- cmake -*- + +include(Linking) +include(Prebuilt) + +include_guard() +add_library( ll::meshoptimizer INTERFACE IMPORTED ) + +use_system_binary(meshoptimizer) +use_prebuilt_binary(meshoptimizer) + +if (WINDOWS) + target_link_libraries( ll::meshoptimizer INTERFACE meshoptimizer.lib) +elseif (LINUX) + target_link_libraries( ll::meshoptimizer INTERFACE meshoptimizer.o) +elseif (DARWIN) + target_link_libraries( ll::meshoptimizer INTERFACE libmeshoptimizer.a) +endif (WINDOWS) + +target_include_directories( ll::meshoptimizer SYSTEM INTERFACE ${LIBS_PREBUILT_DIR}/include/meshoptimizer) diff --git a/indra/cmake/NDOF.cmake b/indra/cmake/NDOF.cmake index 388df16a52..b88fbccf2a 100644 --- a/indra/cmake/NDOF.cmake +++ b/indra/cmake/NDOF.cmake @@ -3,34 +3,22 @@ include(Prebuilt) set(NDOF ON CACHE BOOL "Use NDOF space navigator joystick library.") -if (NDOF) - if (USESYSTEMLIBS) - set(NDOF_FIND_REQUIRED ON) - include(FindNDOF) - else (USESYSTEMLIBS) - if (WINDOWS OR DARWIN) - use_prebuilt_binary(libndofdev) - elseif (LINUX) - use_prebuilt_binary(open-libndofdev) - endif (WINDOWS OR DARWIN) +include_guard() +add_library( ll::ndof INTERFACE IMPORTED ) - if (WINDOWS) - set(NDOF_LIBRARY libndofdev) - elseif (DARWIN OR LINUX) - set(NDOF_LIBRARY ndofdev) - endif (WINDOWS) +if (NDOF) + if (WINDOWS OR DARWIN) + use_prebuilt_binary(libndofdev) + elseif (LINUX) + use_prebuilt_binary(open-libndofdev) + endif (WINDOWS OR DARWIN) - set(NDOF_INCLUDE_DIR ${ARCH_PREBUILT_DIRS}/include/ndofdev) - set(NDOF_FOUND 1) - endif (USESYSTEMLIBS) + if (WINDOWS) + target_link_libraries( ll::ndof INTERFACE libndofdev) + elseif (DARWIN OR LINUX) + target_link_libraries( ll::ndof INTERFACE ndofdev) + endif (WINDOWS) + target_compile_definitions( ll::ndof INTERFACE LIB_NDOF=1) endif (NDOF) -if (NDOF_FOUND) - add_definitions(-DLIB_NDOF=1) - include_directories(${NDOF_INCLUDE_DIR}) -else (NDOF_FOUND) - message(STATUS "Building without N-DoF joystick support") - set(NDOF_INCLUDE_DIR "") - set(NDOF_LIBRARY "") -endif (NDOF_FOUND) diff --git a/indra/cmake/NGHTTP2.cmake b/indra/cmake/NGHTTP2.cmake index df191ff3c1..6396a5bd01 100644 --- a/indra/cmake/NGHTTP2.cmake +++ b/indra/cmake/NGHTTP2.cmake @@ -1,20 +1,16 @@ +include(Linking) include(Prebuilt) -set(NGHTTP2_FIND_QUIETLY ON) -set(NGHTTP2_FIND_REQUIRED ON) +include_guard() +add_library( ll::nghttp2 INTERFACE IMPORTED ) -if (USESYSTEMLIBS) - include(FindNGHTTP2) -else (USESYSTEMLIBS) - use_prebuilt_binary(nghttp2) - if (WINDOWS) - set(NGHTTP2_LIBRARIES - ${ARCH_PREBUILT_DIRS_RELEASE}/nghttp2.lib - ) - elseif (DARWIN) - set(NGHTTP2_LIBRARIES libnghttp2.dylib) - else (WINDOWS) - set(NGHTTP2_LIBRARIES libnghttp2.a) - endif (WINDOWS) - set(NGHTTP2_INCLUDE_DIR ${LIBS_PREBUILT_DIR}/include/nghttp2) -endif (USESYSTEMLIBS) +use_system_binary(nghttp2) +use_prebuilt_binary(nghttp2) +if (WINDOWS) + target_link_libraries( ll::nghttp2 INTERFACE ${ARCH_PREBUILT_DIRS_RELEASE}/nghttp2.lib) +elseif (DARWIN) + target_link_libraries( ll::nghttp2 INTERFACE libnghttp2.dylib) +else (WINDOWS) + target_link_libraries( ll::nghttp2 INTERFACE libnghttp2.a ) +endif (WINDOWS) +target_include_directories( ll::nghttp2 SYSTEM INTERFACE ${LIBS_PREBUILT_DIR}/include/nghttp2) diff --git a/indra/cmake/NVAPI.cmake b/indra/cmake/NVAPI.cmake index 105f442a30..ff5a5428e0 100644 --- a/indra/cmake/NVAPI.cmake +++ b/indra/cmake/NVAPI.cmake @@ -5,12 +5,9 @@ set(NVAPI ON CACHE BOOL "Use NVAPI.") if (NVAPI) if (WINDOWS) + add_library( ll::nvapi INTERFACE IMPORTED ) + target_link_libraries( ll::nvapi INTERFACE nvapi) use_prebuilt_binary(nvapi) - set(NVAPI_LIBRARY nvapi) - else (WINDOWS) - set(NVAPI_LIBRARY "") endif (WINDOWS) -else (NVAPI) - set(NVAPI_LIBRARY "") endif (NVAPI) diff --git a/indra/cmake/OPENAL.cmake b/indra/cmake/OPENAL.cmake index 1bbfff6f98..0b6a7c2853 100644 --- a/indra/cmake/OPENAL.cmake +++ b/indra/cmake/OPENAL.cmake @@ -2,31 +2,37 @@ include(Linking) include(Prebuilt) -if (LINUX) - set(OPENAL ON CACHE BOOL "Enable OpenAL") -else (LINUX) - set(OPENAL OFF CACHE BOOL "Enable OpenAL") -endif (LINUX) +include_guard() + +# ND: Turn this off by default, the openal code in the viewer isn't very well maintained, seems +# to have memory leaks, has no option to play music streams +# It probably makes sense to to completely remove it + +set(USE_OPENAL OFF CACHE BOOL "Enable OpenAL") +# ND: To streamline arguments passed, switch from OPENAL to USE_OPENAL +# To not break all old build scripts convert old arguments but warn about it +if(OPENAL) + message( WARNING "Use of the OPENAL argument is deprecated, please switch to USE_OPENAL") + set(USE_OPENAL ${OPENAL}) +endif() + +if (USE_OPENAL) + add_library( ll::openal INTERFACE IMPORTED ) + target_include_directories( ll::openal SYSTEM INTERFACE "${LIBS_PREBUILT_DIR}/include/AL") + target_compile_definitions( ll::openal INTERFACE LL_OPENAL=1) + use_prebuilt_binary(openal) -if (OPENAL) - set(OPENAL_LIB_INCLUDE_DIRS "${LIBS_PREBUILT_DIR}/include/AL") - if (USESYSTEMLIBS) - include(FindPkgConfig) - include(FindOpenAL) - pkg_check_modules(OPENAL_LIB REQUIRED openal) - pkg_check_modules(FREEALUT_LIB REQUIRED freealut) - else (USESYSTEMLIBS) - use_prebuilt_binary(openal) - endif (USESYSTEMLIBS) if(WINDOWS) - set(OPENAL_LIBRARIES - OpenAL32 - alut - ) + target_link_libraries( ll::openal INTERFACE + OpenAL32 + alut + ) + elseif(LINUX) + target_link_libraries( ll::openal INTERFACE + openal + alut + ) else() - set(OPENAL_LIBRARIES - openal - alut - ) + message(FATAL_ERROR "OpenAL is not available for this platform") endif() -endif (OPENAL) +endif () diff --git a/indra/cmake/OpenGL.cmake b/indra/cmake/OpenGL.cmake index 2259c99293..bf7cd8366a 100644 --- a/indra/cmake/OpenGL.cmake +++ b/indra/cmake/OpenGL.cmake @@ -2,11 +2,5 @@ include(Variables) include(Prebuilt) - -if (BUILD_HEADLESS) - SET(OPENGL_glu_LIBRARY GLU) - SET(OPENGL_HEADLESS_LIBRARIES OSMesa16 dl GLU) -endif (BUILD_HEADLESS) - include(FindOpenGL) diff --git a/indra/cmake/OpenJPEG.cmake b/indra/cmake/OpenJPEG.cmake index bf0bde2ba7..c4aab2e9e5 100644 --- a/indra/cmake/OpenJPEG.cmake +++ b/indra/cmake/OpenJPEG.cmake @@ -1,22 +1,11 @@ # -*- cmake -*- include(Prebuilt) -set(OPENJPEG_FIND_QUIETLY ON) -set(OPENJPEG_FIND_REQUIRED ON) +include_guard() +add_library( ll::openjpeg INTERFACE IMPORTED ) -if (USESYSTEMLIBS) - include(FindOpenJPEG) -else (USESYSTEMLIBS) - use_prebuilt_binary(openjpeg) - - if(WINDOWS) - # Windows has differently named release and debug openjpeg(d) libs. - set(OPENJPEG_LIBRARIES - debug openjpegd - optimized openjpeg) - else(WINDOWS) - set(OPENJPEG_LIBRARIES openjpeg) - endif(WINDOWS) - - set(OPENJPEG_INCLUDE_DIR ${LIBS_PREBUILT_DIR}/include/openjpeg) -endif (USESYSTEMLIBS) +use_system_binary(openjpeg) +use_prebuilt_binary(openjpeg) + +target_link_libraries(ll::openjpeg INTERFACE openjp2 ) +target_include_directories( ll::openjpeg SYSTEM INTERFACE ${LIBS_PREBUILT_DIR}/include/openjpeg) diff --git a/indra/cmake/OpenSSL.cmake b/indra/cmake/OpenSSL.cmake index 32400f5e4e..3387c74f45 100644 --- a/indra/cmake/OpenSSL.cmake +++ b/indra/cmake/OpenSSL.cmake @@ -1,23 +1,17 @@ # -*- cmake -*- include(Prebuilt) -set(OpenSSL_FIND_QUIETLY ON) -set(OpenSSL_FIND_REQUIRED ON) +include_guard() +add_library( ll::openssl INTERFACE IMPORTED ) -if (USESYSTEMLIBS) - include(FindOpenSSL) -else (USESYSTEMLIBS) - use_prebuilt_binary(openssl) - if (WINDOWS) - set(OPENSSL_LIBRARIES libssl libcrypto) - else (WINDOWS) - set(OPENSSL_LIBRARIES ssl crypto) - endif (WINDOWS) - set(OPENSSL_INCLUDE_DIRS ${LIBS_PREBUILT_DIR}/include) -endif (USESYSTEMLIBS) +use_system_binary(openssl) +use_prebuilt_binary(openssl) +if (WINDOWS) + target_link_libraries(ll::openssl INTERFACE libssl libcrypto) +elseif (LINUX) + target_link_libraries(ll::openssl INTERFACE ssl crypto dl) +else() + target_link_libraries(ll::openssl INTERFACE ssl crypto) +endif (WINDOWS) +target_include_directories( ll::openssl SYSTEM INTERFACE ${LIBS_PREBUILT_DIR}/include) -if (LINUX) - set(CRYPTO_LIBRARIES crypto dl) -elseif (DARWIN) - set(CRYPTO_LIBRARIES crypto) -endif (LINUX) diff --git a/indra/cmake/PNG.cmake b/indra/cmake/PNG.cmake index 248a875a19..044262bc8d 100644 --- a/indra/cmake/PNG.cmake +++ b/indra/cmake/PNG.cmake @@ -1,34 +1,14 @@ # -*- cmake -*- include(Prebuilt) -set(PNG_FIND_QUIETLY ON) -set(PNG_FIND_REQUIRED ON) +include_guard() +add_library( ll::libpng INTERFACE IMPORTED ) -if (USESYSTEMLIBS) - include(FindPNG) -else (USESYSTEMLIBS) - use_prebuilt_binary(libpng) - if (WINDOWS) - set(PNG_LIBRARIES libpng16) - set(PNG_INCLUDE_DIRS ${LIBS_PREBUILT_DIR}/include/libpng16) - elseif(DARWIN) - set(PNG_LIBRARIES png16) - set(PNG_INCLUDE_DIRS ${LIBS_PREBUILT_DIR}/include/libpng16) - else() - # - # When we have updated static libraries in competition with older - # shared libraries and we want the former to win, we need to do some - # extra work. The *_PRELOAD_ARCHIVES settings are invoked early - # and will pull in the entire archive to the binary giving it - # priority in symbol resolution. Beware of cmake moving the - # achive load itself to another place on the link command line. If - # that happens, you can try something like -Wl,-lpng16 here to hide - # the archive. Also be aware that the linker will not tolerate a - # second whole-archive load of the archive. See viewer's - # CMakeLists.txt for more information. - # - set(PNG_PRELOAD_ARCHIVES -Wl,--whole-archive png16 -Wl,--no-whole-archive) - set(PNG_LIBRARIES png16) - set(PNG_INCLUDE_DIRS ${LIBS_PREBUILT_DIR}/include/libpng16) - endif() -endif (USESYSTEMLIBS) +use_system_binary(libpng) +use_prebuilt_binary(libpng) +if (WINDOWS) + target_link_libraries(ll::libpng INTERFACE libpng16) +else() + target_link_libraries(ll::libpng INTERFACE png16 ) +endif() +target_include_directories( ll::libpng SYSTEM INTERFACE ${LIBS_PREBUILT_DIR}/include/libpng16) diff --git a/indra/cmake/PluginAPI.cmake b/indra/cmake/PluginAPI.cmake index d1649e8248..114415e514 100644 --- a/indra/cmake/PluginAPI.cmake +++ b/indra/cmake/PluginAPI.cmake @@ -1,7 +1,9 @@ # -*- cmake -*- +add_library( ll::pluginlibraries INTERFACE IMPORTED ) + if (WINDOWS) - set(PLUGIN_API_WINDOWS_LIBRARIES + target_link_libraries( ll::pluginlibraries INTERFACE wsock32 ws2_32 psapi @@ -9,8 +11,6 @@ if (WINDOWS) advapi32 user32 ) -else (WINDOWS) - set(PLUGIN_API_WINDOWS_LIBRARIES "") endif (WINDOWS) diff --git a/indra/cmake/Prebuilt.cmake b/indra/cmake/Prebuilt.cmake index 33a6d76916..634cc15c21 100644 --- a/indra/cmake/Prebuilt.cmake +++ b/indra/cmake/Prebuilt.cmake @@ -1,7 +1,5 @@ # -*- cmake -*- - -if(NOT DEFINED ${CMAKE_CURRENT_LIST_FILE}_INCLUDED) -set(${CMAKE_CURRENT_LIST_FILE}_INCLUDED "YES") +include_guard() include(FindAutobuild) if(INSTALL_PROPRIETARY) @@ -25,40 +23,50 @@ endif ("${CMAKE_SOURCE_DIR}/../autobuild.xml" IS_NEWER_THAN "${PREBUILD_TRACKING # of previous attempts is serialized in the file # ${PREBUILD_TRACKING_DIR}/${_binary}_installed) macro (use_prebuilt_binary _binary) - if (NOT DEFINED USESYSTEMLIBS_${_binary}) - set(USESYSTEMLIBS_${_binary} ${USESYSTEMLIBS}) - endif (NOT DEFINED USESYSTEMLIBS_${_binary}) + if( NOT DEFINED ${_binary}_installed ) + set( ${_binary}_installed "") + endif() - if (NOT USESYSTEMLIBS_${_binary}) if("${${_binary}_installed}" STREQUAL "" AND EXISTS "${PREBUILD_TRACKING_DIR}/${_binary}_installed") - file(READ ${PREBUILD_TRACKING_DIR}/${_binary}_installed "${_binary}_installed") - if(DEBUG_PREBUILT) - message(STATUS "${_binary}_installed: \"${${_binary}_installed}\"") - endif(DEBUG_PREBUILT) + file(READ ${PREBUILD_TRACKING_DIR}/${_binary}_installed "${_binary}_installed") + if(DEBUG_PREBUILT) + message(STATUS "${_binary}_installed: \"${${_binary}_installed}\"") + endif(DEBUG_PREBUILT) endif("${${_binary}_installed}" STREQUAL "" AND EXISTS "${PREBUILD_TRACKING_DIR}/${_binary}_installed") if(${PREBUILD_TRACKING_DIR}/sentinel_installed IS_NEWER_THAN ${PREBUILD_TRACKING_DIR}/${_binary}_installed OR NOT ${${_binary}_installed} EQUAL 0) - if(DEBUG_PREBUILT) - message(STATUS "cd ${CMAKE_SOURCE_DIR} && ${AUTOBUILD_EXECUTABLE} install + if(DEBUG_PREBUILT) + message(STATUS "cd ${CMAKE_SOURCE_DIR} && ${AUTOBUILD_EXECUTABLE} install --install-dir=${AUTOBUILD_INSTALL_DIR} ${_binary} ") - endif(DEBUG_PREBUILT) - execute_process(COMMAND "${AUTOBUILD_EXECUTABLE}" - install - --install-dir=${AUTOBUILD_INSTALL_DIR} - ${_binary} - WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}" - RESULT_VARIABLE ${_binary}_installed - ) - file(WRITE ${PREBUILD_TRACKING_DIR}/${_binary}_installed "${${_binary}_installed}") + endif(DEBUG_PREBUILT) + execute_process(COMMAND "${AUTOBUILD_EXECUTABLE}" + install + --install-dir=${AUTOBUILD_INSTALL_DIR} + ${_binary} + WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}" + RESULT_VARIABLE ${_binary}_installed + ) + file(WRITE ${PREBUILD_TRACKING_DIR}/${_binary}_installed "${${_binary}_installed}") endif(${PREBUILD_TRACKING_DIR}/sentinel_installed IS_NEWER_THAN ${PREBUILD_TRACKING_DIR}/${_binary}_installed OR NOT ${${_binary}_installed} EQUAL 0) if(NOT ${_binary}_installed EQUAL 0) - message(FATAL_ERROR - "Failed to download or unpack prebuilt '${_binary}'." - " Process returned ${${_binary}_installed}.") + message(FATAL_ERROR + "Failed to download or unpack prebuilt '${_binary}'." + " Process returned ${${_binary}_installed}.") endif (NOT ${_binary}_installed EQUAL 0) - endif (NOT USESYSTEMLIBS_${_binary}) endmacro (use_prebuilt_binary _binary) -endif(NOT DEFINED ${CMAKE_CURRENT_LIST_FILE}_INCLUDED) +#Sadly we need a macro here, otherwise the return() will not properly work +macro ( use_system_binary package ) + if( USE_CONAN ) + target_link_libraries( ll::${package} INTERFACE CONAN_PKG::${package} ) + foreach( extra_pkg "${ARGN}" ) + if( extra_pkg ) + target_link_libraries( ll::${package} INTERFACE CONAN_PKG::${extra_pkg} ) + endif() + endforeach() + return() + endif() +endmacro() + diff --git a/indra/cmake/PulseAudio.cmake b/indra/cmake/PulseAudio.cmake index cce27f1bdd..303db97db6 100644 --- a/indra/cmake/PulseAudio.cmake +++ b/indra/cmake/PulseAudio.cmake @@ -1,28 +1,4 @@ # -*- cmake -*- include(Prebuilt) -set(PULSEAUDIO OFF CACHE BOOL "Build with PulseAudio support, if available.") - -if (PULSEAUDIO) - if (USESYSTEMLIBS) - include(FindPkgConfig) - - pkg_check_modules(PULSEAUDIO libpulse) - - elseif (LINUX) - use_prebuilt_binary(pulseaudio) - set(PULSEAUDIO_FOUND ON FORCE BOOL) - set(PULSEAUDIO_INCLUDE_DIRS - ${LIBS_PREBUILT_DIR}/include - ) - # We don't need to explicitly link against pulseaudio itself, because - # the viewer probes for the system's copy at runtime. - set(PULSEAUDIO_LIBRARIES - # none needed! - ) - endif (USESYSTEMLIBS) -endif (PULSEAUDIO) - -if (PULSEAUDIO_FOUND) - add_definitions(-DLL_PULSEAUDIO_ENABLED=1) -endif (PULSEAUDIO_FOUND) +message( FATAL_ERROR "Pulseaudio cmake file is broken" ) diff --git a/indra/cmake/Python.cmake b/indra/cmake/Python.cmake index ed595f6966..dbf5033ce5 100644 --- a/indra/cmake/Python.cmake +++ b/indra/cmake/Python.cmake @@ -5,32 +5,49 @@ set(PYTHONINTERP_FOUND) if (WINDOWS) # On Windows, explicitly avoid Cygwin Python. - find_program(PYTHON_EXECUTABLE - NAMES python.exe + # if the user has their own version of Python installed, prefer that + foreach(hive HKEY_CURRENT_USER HKEY_LOCAL_MACHINE) + # prefer more recent Python versions to older ones, if multiple versions + # are installed + foreach(pyver 3.11 3.10 3.9 3.8 3.7) + list(APPEND regpaths "[${hive}\\SOFTWARE\\Python\\PythonCore\\${pyver}\\InstallPath]") + endforeach() + endforeach() + + # TODO: This logic has the disadvantage that if you have multiple versions + # of Python installed, the selected path won't necessarily be the newest - + # e.g. this GLOB will prefer Python310 to Python311. But since pymaybe is + # checked AFTER the registry entries, this will only surface as a problem if + # no installed Python appears in the registry. + file(GLOB pymaybe + "$ENV{PROGRAMFILES}/Python*" +## "$ENV{PROGRAMFILES(X86)}/Python*" + # The Windows environment variable is in fact as shown above, but CMake + # disallows querying an environment variable containing parentheses - + # thanks, Windows. Fudge by just appending " (x86)" to $PROGRAMFILES and + # hoping for the best. + "$ENV{PROGRAMFILES} (x86)/Python*" + "c:/Python*") + + find_program(python + NAMES python3.exe python.exe NO_DEFAULT_PATH # added so that cmake does not find cygwin python PATHS - [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\3.7\\InstallPath] - [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\3.8\\InstallPath] - [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\3.9\\InstallPath] - [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\3.10\\InstallPath] - [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\3.11\\InstallPath] - [HKEY_CURRENT_USER\\SOFTWARE\\Python\\PythonCore\\3.7\\InstallPath] - [HKEY_CURRENT_USER\\SOFTWARE\\Python\\PythonCore\\3.8\\InstallPath] - [HKEY_CURRENT_USER\\SOFTWARE\\Python\\PythonCore\\3.9\\InstallPath] - [HKEY_CURRENT_USER\\SOFTWARE\\Python\\PythonCore\\3.10\\InstallPath] - [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\3.11\\InstallPath] + ${regpaths} + ${pymaybe} ) include(FindPythonInterp) else() - find_program(PYTHON_EXECUTABLE python3) + find_program(python python3) - if (PYTHON_EXECUTABLE) + if (python) set(PYTHONINTERP_FOUND ON) - endif (PYTHON_EXECUTABLE) + endif (python) endif (WINDOWS) -if (NOT PYTHON_EXECUTABLE) +if (NOT python) message(FATAL_ERROR "No Python interpreter found") -endif (NOT PYTHON_EXECUTABLE) +endif (NOT python) +set(PYTHON_EXECUTABLE "${python}" CACHE FILEPATH "Python interpreter for builds") mark_as_advanced(PYTHON_EXECUTABLE) diff --git a/indra/cmake/Tracy.cmake b/indra/cmake/Tracy.cmake index cfff956bcf..b3de06a876 100644 --- a/indra/cmake/Tracy.cmake +++ b/indra/cmake/Tracy.cmake @@ -1,29 +1,18 @@ # -*- cmake -*- include(Prebuilt) +include_guard() +add_library( ll::tracy INTERFACE IMPORTED ) + set(USE_TRACY OFF CACHE BOOL "Use Tracy profiler.") if (USE_TRACY) - set(TRACY_INCLUDE_DIR ${LIBS_PREBUILT_DIR}/include/tracy) - -# See: indra/llcommon/llprofiler.h - add_definitions(-DLL_PROFILER_CONFIGURATION=3) + use_system_binary(tracy) use_prebuilt_binary(tracy) - if (WINDOWS) - MESSAGE(STATUS "Including Tracy for Windows: '${TRACY_INCLUDE_DIR}'") - endif (WINDOWS) + target_include_directories( ll::tracy SYSTEM INTERFACE ${LIBS_PREBUILT_DIR}/include/tracy) - if (DARWIN) - MESSAGE(STATUS "Including Tracy for Darwin: '${TRACY_INCLUDE_DIR}'") - endif (DARWIN) - - if (LINUX) - MESSAGE(STATUS "Including Tracy for Linux: '${TRACY_INCLUDE_DIR}'") - endif (LINUX) -else (USE_TRACY) - # Tracy.cmake should not set LLCOMMON_INCLUDE_DIRS, let LLCommon.cmake do that - set(TRACY_INCLUDE_DIR "") - set(TRACY_LIBRARY "") +# See: indra/llcommon/llprofiler.h + target_compile_definitions(ll::tracy INTERFACE LL_PROFILER_CONFIGURATION=3 ) endif (USE_TRACY) diff --git a/indra/cmake/Tut.cmake b/indra/cmake/Tut.cmake index e11a3c3314..ad93830803 100644 --- a/indra/cmake/Tut.cmake +++ b/indra/cmake/Tut.cmake @@ -1,6 +1,4 @@ # -*- cmake -*- include(Prebuilt) -if (NOT USESYSTEMLIBS) - use_prebuilt_binary(tut) -endif(NOT USESYSTEMLIBS) +use_prebuilt_binary(tut) diff --git a/indra/cmake/UI.cmake b/indra/cmake/UI.cmake index 77fd505df3..8b70192efc 100644 --- a/indra/cmake/UI.cmake +++ b/indra/cmake/UI.cmake @@ -2,68 +2,53 @@ include(Prebuilt) include(FreeType) -if (USESYSTEMLIBS) - include(FindPkgConfig) - - if (LINUX) - set(PKGCONFIG_PACKAGES - atk - cairo - gdk-2.0 - gdk-pixbuf-2.0 - glib-2.0 - gmodule-2.0 - gtk+-2.0 - gthread-2.0 - libpng - pango - pangoft2 - pangox - pangoxft - sdl - ) - endif (LINUX) +add_library( ll::uilibraries INTERFACE IMPORTED ) - foreach(pkg ${PKGCONFIG_PACKAGES}) - pkg_check_modules(${pkg} REQUIRED ${pkg}) - include_directories(${${pkg}_INCLUDE_DIRS}) - link_directories(${${pkg}_LIBRARY_DIRS}) - list(APPEND UI_LIBRARIES ${${pkg}_LIBRARIES}) - add_definitions(${${pkg}_CFLAGS_OTHERS}) - endforeach(pkg) -else (USESYSTEMLIBS) - if (LINUX) - use_prebuilt_binary(gtk-atk-pango-glib) - endif (LINUX) +if (LINUX) + target_compile_definitions(ll::uilibraries INTERFACE LL_GTK=1 LL_X11=1 ) - if (LINUX) - set(UI_LIBRARIES - atk-1.0 - gdk-x11-2.0 - gdk_pixbuf-2.0 - Xinerama - glib-2.0 - gmodule-2.0 - gobject-2.0 - gthread-2.0 - gtk-x11-2.0 - pango-1.0 - pangoft2-1.0 - pangox-1.0 - pangoxft-1.0 - ${FREETYPE_LIBRARIES} - ) - endif (LINUX) + if( USE_CONAN ) + target_link_libraries( ll::uilibraries INTERFACE CONAN_PKG::gtk ) + return() + endif() + use_prebuilt_binary(gtk-atk-pango-glib) + + target_link_libraries( ll::uilibraries INTERFACE + atk-1.0 + gdk-x11-2.0 + gdk_pixbuf-2.0 + Xinerama + glib-2.0 + gmodule-2.0 + gobject-2.0 + gthread-2.0 + gtk-x11-2.0 + pango-1.0 + pangoft2-1.0 + pangox-1.0 + pangoxft-1.0 + Xinerama + ll::freetype + ) +endif (LINUX) +if( WINDOWS ) + target_link_libraries( ll::uilibraries INTERFACE + opengl32 + comdlg32 + dxguid + kernel32 + odbc32 + odbccp32 + oleaut32 + shell32 + Vfw32 + wer + winspool + imm32 + ) +endif() - include_directories ( - ${LIBS_PREBUILT_DIR}/include - ${LIBS_PREBUILT_DIR}/include - ) - foreach(include ${${LL_ARCH}_INCLUDES}) - include_directories(${LIBS_PREBUILT_DIR}/include/${include}) - endforeach(include) -endif (USESYSTEMLIBS) +target_include_directories( ll::uilibraries SYSTEM INTERFACE + ${LIBS_PREBUILT_DIR}/include + ) -if (LINUX) - add_definitions(-DLL_GTK=1 -DLL_X11=1) -endif (LINUX) diff --git a/indra/cmake/URIPARSER.cmake b/indra/cmake/URIPARSER.cmake index ecc5b74ef1..6c33ff70e1 100644 --- a/indra/cmake/URIPARSER.cmake +++ b/indra/cmake/URIPARSER.cmake @@ -1,35 +1,19 @@ # -*- cmake -*- -set(URIPARSER_FIND_QUIETLY ON) -set(URIPARSER_FIND_REQUIRED ON) +include_guard() include(Prebuilt) -if (USESYSTEMLIBS) - include(FindURIPARSER) -else (USESYSTEMLIBS) - use_prebuilt_binary(uriparser) - if (WINDOWS) - set(URIPARSER_LIBRARIES - debug uriparserd - optimized uriparser) - elseif (LINUX) - # - # When we have updated static libraries in competition with older - # shared libraries and we want the former to win, we need to do some - # extra work. The *_PRELOAD_ARCHIVES settings are invoked early - # and will pull in the entire archive to the binary giving it. - # priority in symbol resolution. Beware of cmake moving the - # achive load itself to another place on the link command line. If - # that happens, you can try something like -Wl,-luriparser here to hide - # the archive. Also be aware that the linker will not tolerate a - # second whole-archive load of the archive. See viewer's - # CMakeLists.txt for more information. - # - set(URIPARSER_PRELOAD_ARCHIVES -Wl,--whole-archive uriparser -Wl,--no-whole-archive) - set(URIPARSER_LIBRARIES uriparser) - elseif (DARWIN) - set(URIPARSER_LIBRARIES liburiparser.dylib) - endif (WINDOWS) - set(URIPARSER_INCLUDE_DIRS ${LIBS_PREBUILT_DIR}/include/uriparser) -endif (USESYSTEMLIBS) +add_library( ll::uriparser INTERFACE IMPORTED ) + +use_system_binary( uriparser ) + +use_prebuilt_binary(uriparser) +if (WINDOWS) + target_link_libraries( ll::uriparser INTERFACE uriparser) +elseif (LINUX) + target_link_libraries( ll::uriparser INTERFACE uriparser) +elseif (DARWIN) + target_link_libraries( ll::uriparser INTERFACE liburiparser.dylib) +endif (WINDOWS) +target_include_directories( ll::uriparser SYSTEM INTERFACE ${LIBS_PREBUILT_DIR}/include/uriparser) diff --git a/indra/cmake/Variables.cmake b/indra/cmake/Variables.cmake index 3c87e69e5f..e6285ab48b 100644 --- a/indra/cmake/Variables.cmake +++ b/indra/cmake/Variables.cmake @@ -12,15 +12,18 @@ # Switches set here and in 00-Common.cmake must agree with # https://bitbucket.org/lindenlab/viewer-build-variables/src/tip/variables # Reading $LL_BUILD is an attempt to directly use those switches. -if ("$ENV{LL_BUILD}" STREQUAL "") +if ("$ENV{LL_BUILD}" STREQUAL "" AND "${LL_BUILD_ENV}" STREQUAL "" ) message(FATAL_ERROR "Environment variable LL_BUILD must be set") +elseif("$ENV{LL_BUILD}" STREQUAL "") + set( ENV{LL_BUILD} "${LL_BUILD_ENV}" ) + message( "Setting ENV{LL_BUILD} to cached variable ${LL_BUILD_ENV}" ) +else() + set( LL_BUILD_ENV "$ENV{LL_BUILD}" CACHE STRING "Save environment" FORCE ) endif () +include_guard() # Relative and absolute paths to subtrees. -if(NOT DEFINED ${CMAKE_CURRENT_LIST_FILE}_INCLUDED) -set(${CMAKE_CURRENT_LIST_FILE}_INCLUDED "YES") - if(NOT DEFINED COMMON_CMAKE_DIR) set(COMMON_CMAKE_DIR "${CMAKE_SOURCE_DIR}/cmake") endif(NOT DEFINED COMMON_CMAKE_DIR) @@ -70,39 +73,36 @@ endif (NOT CMAKE_BUILD_TYPE) # If someone has specified an address size, use that to determine the # architecture. Otherwise, let the architecture specify the address size. if (ADDRESS_SIZE EQUAL 32) - #message(STATUS "ADDRESS_SIZE is 32") set(ARCH i686) elseif (ADDRESS_SIZE EQUAL 64) - #message(STATUS "ADDRESS_SIZE is 64") set(ARCH x86_64) else (ADDRESS_SIZE EQUAL 32) - #message(STATUS "ADDRESS_SIZE is UNRECOGNIZED: '${ADDRESS_SIZE}'") - # Use Python's platform.machine() since uname -m isn't available everywhere. - # Even if you can assume cygwin uname -m, the answer depends on whether - # you're running 32-bit cygwin or 64-bit cygwin! But even 32-bit Python will - # report a 64-bit processor. - execute_process(COMMAND - "${PYTHON_EXECUTABLE}" "-c" - "import platform; print platform.machine()" - OUTPUT_VARIABLE ARCH OUTPUT_STRIP_TRAILING_WHITESPACE) - # We expect values of the form i386, i686, x86_64, AMD64. - # In CMake, expressing ARCH.endswith('64') is awkward: - string(LENGTH "${ARCH}" ARCH_LENGTH) - math(EXPR ARCH_LEN_2 "${ARCH_LENGTH} - 2") - string(SUBSTRING "${ARCH}" ${ARCH_LEN_2} 2 ARCH_LAST_2) - if (ARCH_LAST_2 STREQUAL 64) - #message(STATUS "ARCH is detected as 64; ARCH is ${ARCH}") + # Note we cannot use if(DARWIN) here, this variable is set way lower + if( ${CMAKE_SYSTEM_NAME} MATCHES "Darwin" ) set(ADDRESS_SIZE 64) - else () - #message(STATUS "ARCH is detected as 32; ARCH is ${ARCH}") - set(ADDRESS_SIZE 32) - endif () + set(ARCH x86_64) + else() + # Use Python's platform.machine() since uname -m isn't available everywhere. + # Even if you can assume cygwin uname -m, the answer depends on whether + # you're running 32-bit cygwin or 64-bit cygwin! But even 32-bit Python will + # report a 64-bit processor. + execute_process(COMMAND + "${PYTHON_EXECUTABLE}" "-c" + "import platform; print( platform.machine() )" + OUTPUT_VARIABLE ARCH OUTPUT_STRIP_TRAILING_WHITESPACE) + string( REGEX MATCH ".*(64)$" RE_MATCH "${ARCH}" ) + if( RE_MATCH AND ${CMAKE_MATCH_1} STREQUAL "64" ) + set(ADDRESS_SIZE 64) + set(ARCH x86_64) + else() + set(ADDRESS_SIZE 32) + set(ARCH i686) + endif() + endif() endif (ADDRESS_SIZE EQUAL 32) if (${CMAKE_SYSTEM_NAME} MATCHES "Windows") set(WINDOWS ON BOOL FORCE) - set(LL_ARCH ${ARCH}_win32) - set(LL_ARCH_DIR ${ARCH}-win32) endif (${CMAKE_SYSTEM_NAME} MATCHES "Windows") if (${CMAKE_SYSTEM_NAME} MATCHES "Linux") @@ -129,9 +129,6 @@ if (${CMAKE_SYSTEM_NAME} MATCHES "Linux") include(ConfigurePkgConfig) - set(LL_ARCH ${ARCH}_linux) - set(LL_ARCH_DIR ${ARCH}-linux) - if (INSTALL_PROPRIETARY) # Only turn on headless if we can find osmesa libraries. include(FindPkgConfig) @@ -206,9 +203,6 @@ if (${CMAKE_SYSTEM_NAME} MATCHES "Darwin") set(CMAKE_OSX_ARCHITECTURES "${ARCH}") string(REPLACE "i686" "i386" CMAKE_OSX_ARCHITECTURES "${CMAKE_OSX_ARCHITECTURES}") string(REPLACE "AMD64" "x86_64" CMAKE_OSX_ARCHITECTURES "${CMAKE_OSX_ARCHITECTURES}") - - set(LL_ARCH ${ARCH}_darwin) - set(LL_ARCH_DIR universal-darwin) endif (${CMAKE_SYSTEM_NAME} MATCHES "Darwin") # Default deploy grid @@ -220,10 +214,10 @@ set(ENABLE_SIGNING OFF CACHE BOOL "Enable signing the viewer") set(SIGNING_IDENTITY "" CACHE STRING "Specifies the signing identity to use, if necessary.") set(VERSION_BUILD "0" CACHE STRING "Revision number passed in from the outside") -set(USESYSTEMLIBS OFF CACHE BOOL "Use libraries from your system rather than Linden-supplied prebuilt libraries.") set(USE_PRECOMPILED_HEADERS ON CACHE BOOL "Enable use of precompiled header directives where supported.") source_group("CMake Rules" FILES CMakeLists.txt) -endif(NOT DEFINED ${CMAKE_CURRENT_LIST_FILE}_INCLUDED) +get_property(LL_GENERATOR_IS_MULTI_CONFIG GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG) + diff --git a/indra/cmake/ViewerMiscLibs.cmake b/indra/cmake/ViewerMiscLibs.cmake index fc5bdedb5a..00f8b77106 100644 --- a/indra/cmake/ViewerMiscLibs.cmake +++ b/indra/cmake/ViewerMiscLibs.cmake @@ -1,12 +1,20 @@ # -*- cmake -*- include(Prebuilt) -if (NOT USESYSTEMLIBS) - if (LINUX) - use_prebuilt_binary(libuuid) +if (LINUX) + #use_prebuilt_binary(libuuid) + add_library( ll::fontconfig INTERFACE IMPORTED ) + + if( NOT USE_CONAN ) use_prebuilt_binary(fontconfig) - endif (LINUX) + else() + target_link_libraries( ll::fontconfig INTERFACE CONAN_PKG::fontconfig ) + endif() +endif (LINUX) + +if( NOT USE_CONAN ) use_prebuilt_binary(libhunspell) - use_prebuilt_binary(slvoice) -endif(NOT USESYSTEMLIBS) +endif() + +use_prebuilt_binary(slvoice) diff --git a/indra/cmake/XmlRpcEpi.cmake b/indra/cmake/XmlRpcEpi.cmake index 8c3790ea89..6409f9d6e2 100644 --- a/indra/cmake/XmlRpcEpi.cmake +++ b/indra/cmake/XmlRpcEpi.cmake @@ -1,20 +1,11 @@ # -*- cmake -*- include(Prebuilt) -set(XMLRPCEPI_FIND_QUIETLY ON) -set(XMLRPCEPI_FIND_REQUIRED ON) +include_guard() +add_library( ll::xmlrpc-epi INTERFACE IMPORTED ) -if (USESYSTEMLIBS) - include(FindXmlRpcEpi) -else (USESYSTEMLIBS) - use_prebuilt_binary(xmlrpc-epi) - if (WINDOWS) - set(XMLRPCEPI_LIBRARIES - debug xmlrpc-epid - optimized xmlrpc-epi - ) - else (WINDOWS) - set(XMLRPCEPI_LIBRARIES xmlrpc-epi) - endif (WINDOWS) - set(XMLRPCEPI_INCLUDE_DIRS ${LIBS_PREBUILT_DIR}/include) -endif (USESYSTEMLIBS) +use_system_binary( xmlrpc-epi ) + +use_prebuilt_binary(xmlrpc-epi) +target_link_libraries(ll::xmlrpc-epi INTERFACE xmlrpc-epi ) +target_include_directories( ll::xmlrpc-epi SYSTEM INTERFACE ${LIBS_PREBUILT_DIR}/include) diff --git a/indra/cmake/ZLIBNG.cmake b/indra/cmake/ZLIBNG.cmake index 1f46a23d92..5d99cd9709 100644 --- a/indra/cmake/ZLIBNG.cmake +++ b/indra/cmake/ZLIBNG.cmake @@ -1,35 +1,22 @@ # -*- cmake -*- -set(ZLIBNG_FIND_QUIETLY ON) -set(ZLIBNG_FIND_REQUIRED ON) - include(Prebuilt) -if (USESYSTEMLIBS) - include(FindZLIBNG) -else (USESYSTEMLIBS) - use_prebuilt_binary(zlib-ng) - if (WINDOWS) - set(ZLIBNG_LIBRARIES - debug zlib - optimized zlib) - elseif (LINUX) - # - # When we have updated static libraries in competition with older - # shared libraries and we want the former to win, we need to do some - # extra work. The *_PRELOAD_ARCHIVES settings are invoked early - # and will pull in the entire archive to the binary giving it - # priority in symbol resolution. Beware of cmake moving the - # achive load itself to another place on the link command line. If - # that happens, you can try something like -Wl,-lz here to hide - # the archive. Also be aware that the linker will not tolerate a - # second whole-archive load of the archive. See viewer's - # CMakeLists.txt for more information. - # - set(ZLIBNG_PRELOAD_ARCHIVES -Wl,--whole-archive z -Wl,--no-whole-archive) - set(ZLIBNG_LIBRARIES z) - elseif (DARWIN) - set(ZLIBNG_LIBRARIES z) - endif (WINDOWS) - set(ZLIBNG_INCLUDE_DIRS ${LIBS_PREBUILT_DIR}/include/zlib-ng) -endif (USESYSTEMLIBS) +include_guard() +add_library( ll::zlib-ng INTERFACE IMPORTED ) + +if(USE_CONAN ) + target_link_libraries( ll::zlib-ng INTERFACE CONAN_PKG::zlib ) + return() +endif() + +use_prebuilt_binary(zlib-ng) +if (WINDOWS) + target_link_libraries( ll::zlib-ng INTERFACE zlib ) +else() + target_link_libraries( ll::zlib-ng INTERFACE z ) +endif (WINDOWS) + +if( NOT LINUX ) + target_include_directories( ll::zlib-ng SYSTEM INTERFACE ${LIBS_PREBUILT_DIR}/include/zlib-ng) +endif() diff --git a/indra/cmake/bugsplat.cmake b/indra/cmake/bugsplat.cmake index 4edc4c59cd..509981d72c 100644 --- a/indra/cmake/bugsplat.cmake +++ b/indra/cmake/bugsplat.cmake @@ -9,29 +9,33 @@ else (INSTALL_PROPRIETARY) set(USE_BUGSPLAT OFF CACHE BOOL "Use the BugSplat crash reporting system") endif (INSTALL_PROPRIETARY) +include_guard() +add_library( ll::bugsplat INTERFACE IMPORTED ) + if (USE_BUGSPLAT) - if (NOT USESYSTEMLIBS) - include(Prebuilt) - use_prebuilt_binary(bugsplat) - if (WINDOWS) - set(BUGSPLAT_LIBRARIES + include(Prebuilt) + use_prebuilt_binary(bugsplat) + if (WINDOWS) + target_link_libraries( ll::bugsplat INTERFACE ${ARCH_PREBUILT_DIRS_RELEASE}/bugsplat.lib ) - elseif (DARWIN) - find_library(BUGSPLAT_LIBRARIES BugsplatMac REQUIRED + target_include_directories( ll::bugsplat SYSTEM INTERFACE ${LIBS_PREBUILT_DIR}/include/bugsplat) + elseif (DARWIN) + find_library(BUGSPLAT_LIBRARIES BugsplatMac REQUIRED NO_DEFAULT_PATH PATHS "${ARCH_PREBUILT_DIRS_RELEASE}") - else (WINDOWS) - message(FATAL_ERROR "BugSplat is not supported; add -DUSE_BUGSPLAT=OFF") - endif (WINDOWS) - else (NOT USESYSTEMLIBS) - set(BUGSPLAT_FIND_QUIETLY ON) - set(BUGSPLAT_FIND_REQUIRED ON) - include(FindBUGSPLAT) - endif (NOT USESYSTEMLIBS) + target_link_libraries( ll::bugsplat INTERFACE + ${BUGSPLAT_LIBRARIES} + ) + else (WINDOWS) + message(FATAL_ERROR "BugSplat is not supported; add -DUSE_BUGSPLAT=OFF") + endif (WINDOWS) - set(BUGSPLAT_DB "" CACHE STRING "BugSplat crash database name") + if( NOT BUGSPLAT_DB ) + message( FATAL_ERROR "You need to set BUGSPLAT_DB when setting USE_BUGSPLAT" ) + endif() - set(BUGSPLAT_INCLUDE_DIR ${LIBS_PREBUILT_DIR}/include/bugsplat) - set(BUGSPLAT_DEFINE "LL_BUGSPLAT") + set_property( TARGET ll::bugsplat APPEND PROPERTY INTERFACE_COMPILE_DEFINITIONS LL_BUGSPLAT) +else() + set(BUGSPLAT_DB "" CACHE STRING "BugSplat crash database name") endif (USE_BUGSPLAT) diff --git a/indra/cmake/run_build_test.py b/indra/cmake/run_build_test.py index 1e92868ae7..1f040bded5 100755 --- a/indra/cmake/run_build_test.py +++ b/indra/cmake/run_build_test.py @@ -73,7 +73,7 @@ def main(command, arguments=[], libpath=[], vars={}): if sys.platform == "win32": lpvars = ["PATH"] elif sys.platform == "darwin": - lpvars = ["LD_LIBRARY_PATH", "DYLD_LIBRARY_PATH"] + lpvars = ["LD_LIBRARY_PATH"] # , "DYLD_LIBRARY_PATH"] elif sys.platform.startswith("linux"): lpvars = ["LD_LIBRARY_PATH"] else: diff --git a/indra/integration_tests/llimage_libtest/CMakeLists.txt b/indra/integration_tests/llimage_libtest/CMakeLists.txt index bd59f57e49..ee2890778b 100644 --- a/indra/integration_tests/llimage_libtest/CMakeLists.txt +++ b/indra/integration_tests/llimage_libtest/CMakeLists.txt @@ -12,16 +12,6 @@ include(LLImageJ2COJ) include(LLKDU) include(LLFileSystem) -include_directories( - ${LLCOMMON_INCLUDE_DIRS} - ${LLFILESYSTEM_INCLUDE_DIRS} - ${LLIMAGE_INCLUDE_DIRS} - ${LLMATH_INCLUDE_DIRS} - ) -include_directories(SYSTEM - ${LLCOMMON_SYSTEM_INCLUDE_DIRS} - ) - set(llimage_libtest_SOURCE_FILES llimage_libtest.cpp ) @@ -31,9 +21,6 @@ set(llimage_libtest_HEADER_FILES llimage_libtest.h ) -set_source_files_properties(${llimage_libtest_HEADER_FILES} - PROPERTIES HEADER_FILE_ONLY TRUE) - list(APPEND llimage_libtest_SOURCE_FILES ${llimage_libtest_HEADER_FILES}) add_executable(llimage_libtest @@ -48,37 +35,21 @@ set_target_properties(llimage_libtest FALSE ) -# OS-specific libraries -if (DARWIN) - include(CMakeFindFrameworks) - find_library(COREFOUNDATION_LIBRARY CoreFoundation) - set(OS_LIBRARIES ${COREFOUNDATION_LIBRARY}) -elseif (WINDOWS) - set(OS_LIBRARIES) -elseif (LINUX) - set(OS_LIBRARIES) -else (DARWIN) - message(FATAL_ERROR "Unknown platform") -endif (DARWIN) - # Libraries on which this application depends on # Sort by high-level to low-level target_link_libraries(llimage_libtest - ${LEGACY_STDIO_LIBS} - ${LLCOMMON_LIBRARIES} - ${LLFILESYSTEM_LIBRARIES} - ${LLMATH_LIBRARIES} - ${LLIMAGE_LIBRARIES} - ${LLKDU_LIBRARIES} - ${KDU_LIBRARY} - ${LLIMAGEJ2COJ_LIBRARIES} - ${OS_LIBRARIES} - ) + llcommon + llfilesystem + llmath + llimage + llkdu + llimagej2coj + ) if (DARWIN) # Path inside the app bundle where we'll need to copy libraries set(LLIMAGE_LIBTEST_DESTINATION_DIR - ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/llimage_libtest.app/Contents/Resources + ${CMAKE_CURRENT_BINARY_DIR}/$<IF:$<BOOL:${LL_GENERATOR_IS_MULTI_CONFIG}>,$<CONFIG>,>/llimage_libtest.app/Contents/Resources ) # Create the Contents/Resources directory add_custom_command( diff --git a/indra/integration_tests/llui_libtest/CMakeLists.txt b/indra/integration_tests/llui_libtest/CMakeLists.txt index d7706e73b2..d603e57aab 100644 --- a/indra/integration_tests/llui_libtest/CMakeLists.txt +++ b/indra/integration_tests/llui_libtest/CMakeLists.txt @@ -22,23 +22,6 @@ include(Hunspell) include(Linking) # include(Tut) -include_directories( - ${FREETYPE_INCLUDE_DIRS} - ${LLCOMMON_INCLUDE_DIRS} - ${LLIMAGE_INCLUDE_DIRS} - ${LLMATH_INCLUDE_DIRS} - ${LLRENDER_INCLUDE_DIRS} - ${LLUI_INCLUDE_DIRS} - ${LLFILESYSTEM_INCLUDE_DIRS} - ${LLWINDOW_INCLUDE_DIRS} - ${LLXML_INCLUDE_DIRS} - ${LIBS_PREBUILD_DIR}/include/hunspell - ) -include_directories(SYSTEM - ${LLCOMMON_SYSTEM_INCLUDE_DIRS} - ${LLXML_SYSTEM_INCLUDE_DIRS} - ) - set(llui_libtest_SOURCE_FILES llui_libtest.cpp llwidgetreg.cpp @@ -50,63 +33,39 @@ set(llui_libtest_HEADER_FILES llwidgetreg.h ) -set_source_files_properties(${llui_libtest_HEADER_FILES} - PROPERTIES HEADER_FILE_ONLY TRUE) - list(APPEND llui_libtest_SOURCE_FILES ${llui_libtest_HEADER_FILES}) add_executable(llui_libtest ${llui_libtest_SOURCE_FILES}) -# Link with OS-specific libraries for LLWindow dependency -if (DARWIN) - find_library(COCOA_LIBRARY Cocoa) - find_library(IOKIT_LIBRARY IOKit) - set(OS_LIBRARIES ${COCOA_LIBRARY} ${IOKIT_LIBRARY}) -elseif (WINDOWS) - #ll_stack_trace needs this now... - list(APPEND WINDOWS_LIBRARIES dbghelp) - set(OS_LIBRARIES ${WINDOWS_LIBRARIES}) -elseif (LINUX) - set(OS_LIBRARIES) -else (DARWIN) - message(FATAL_ERROR "unknown platform") -endif (DARWIN) - # Libraries on which this library depends, needed for Linux builds # Sort by high-level to low-level target_link_libraries(llui_libtest - ${LEGACY_STDIO_LIBS} - llui - llinventory - llmessage - ${LLRENDER_LIBRARIES} - ${LLIMAGE_LIBRARIES} - ${LLKDU_LIBRARIES} - ${KDU_LIBRARY} - ${LLIMAGEJ2COJ_LIBRARIES} - ${OS_LIBRARIES} - ${GOOGLE_PERFTOOLS_LIBRARIES} - ${HUNSPELL_LIBRARY} - ) + llui + llinventory + llmessage + llrender + llimage + llkdu + llimagej2coj + ) if (WINDOWS) set_target_properties(llui_libtest PROPERTIES LINK_FLAGS "/NODEFAULTLIB:LIBCMT" - LINK_FLAGS_DEBUG "/NODEFAULTLIB:MSVCRT /NODEFAULTLIB:LIBCMTD" ) # Copy over OpenJPEG.dll # *NOTE: On Windows with VS2005, only the first comment prints set(OPENJPEG_RELEASE - "${ARCH_PREBUILT_DIRS_RELEASE}/openjpeg.dll") + "${ARCH_PREBUILT_DIRS_RELEASE}/openjp2.dll") add_custom_command( TARGET llui_libtest POST_BUILD - COMMAND ${CMAKE_COMMAND} -E copy_if_different + COMMAND ${CMAKE_COMMAND} -E copy_if_different ${OPENJPEG_RELEASE} ${CMAKE_CURRENT_BINARY_DIR} COMMENT "Copying OpenJPEG DLLs to binary directory" ) set(OPENJPEG_DEBUG - "${ARCH_PREBUILT_DIRS_DEBUG}/openjpegd.dll") + "${ARCH_PREBUILT_DIRS_DEBUG}/openjp2.dll") add_custom_command( TARGET llui_libtest POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy_if_different ${OPENJPEG_DEBUG} ${CMAKE_CURRENT_BINARY_DIR} diff --git a/indra/lib/python/indra/util/llmanifest.py b/indra/lib/python/indra/util/llmanifest.py index 5b277846b7..820f356dae 100755 --- a/indra/lib/python/indra/util/llmanifest.py +++ b/indra/lib/python/indra/util/llmanifest.py @@ -125,7 +125,7 @@ BASE_ARGUMENTS=[ but not application name (used internally)""", default=None), dict(name='configuration', - description="""The build configuration used.""", + description="""The build configurations sub directory used.""", default="Release"), dict(name='dest', description='Destination directory.', default=DEFAULT_SRCTREE), dict(name='grid', diff --git a/indra/linux_crash_logger/CMakeLists.txt b/indra/linux_crash_logger/CMakeLists.txt index aa82ed12cc..1793aa82b9 100644 --- a/indra/linux_crash_logger/CMakeLists.txt +++ b/indra/linux_crash_logger/CMakeLists.txt @@ -45,9 +45,6 @@ set(linux_crash_logger_HEADER_FILES llcrashloggerlinux.h ) -set_source_files_properties(${linux_crash_logger_HEADER_FILES} - PROPERTIES HEADER_FILE_ONLY TRUE) - list(APPEND linux_crash_logger_SOURCE_FILES ${linux_crash_logger_HEADER_FILES} ) @@ -61,19 +58,14 @@ set(LIBRT_LIBRARY rt) target_link_libraries(linux-crash-logger - ${LLCRASHLOGGER_LIBRARIES} - ${LLFILESYSTEM_LIBRARIES} - ${LLXML_LIBRARIES} - ${LLMESSAGE_LIBRARIES} - ${LLMATH_LIBRARIES} - ${LLCOREHTTP_LIBRARIES} - ${LLCOMMON_LIBRARIES} - ${BOOST_FIBER_LIBRARY} - ${BOOST_CONTEXT_LIBRARY} - ${UI_LIBRARIES} - ${DB_LIBRARIES} - ${FREETYPE_LIBRARIES} - ${LIBRT_LIBRARY} + llcrashlogger + llfilesystem + llxml + llmessage + llmath + llcorehttp + llcommon + ll::uilibraries ) add_custom_target(linux-crash-logger-target ALL diff --git a/indra/llappearance/CMakeLists.txt b/indra/llappearance/CMakeLists.txt index 268849ad74..75c0e276eb 100644 --- a/indra/llappearance/CMakeLists.txt +++ b/indra/llappearance/CMakeLists.txt @@ -4,30 +4,11 @@ project(llappearance) include(00-Common) include(LLCommon) -include(LLCharacter) include(LLImage) -include(LLInventory) -include(LLMath) -include(LLMessage) include(LLCoreHttp) -include(LLRender) -include(LLFileSystem) include(LLWindow) -include(LLXML) include(Linking) -include_directories( - ${LLCOMMON_INCLUDE_DIRS} - ${LLCHARACTER_INCLUDE_DIRS} - ${LLIMAGE_INCLUDE_DIRS} - ${LLINVENTORY_INCLUDE_DIRS} - ${LLMATH_INCLUDE_DIRS} - ${LLRENDER_INCLUDE_DIRS} - ${LLFILESYSTEM_INCLUDE_DIRS} - ${LLWINDOW_INCLUDE_DIRS} - ${LLXML_INCLUDE_DIRS} - ) - set(llappearance_SOURCE_FILES llavatarappearance.cpp llavatarjoint.cpp @@ -71,41 +52,37 @@ set(llappearance_HEADER_FILES llavatarappearancedefines.h ) -set_source_files_properties(${llappearance_HEADER_FILES} - PROPERTIES HEADER_FILE_ONLY TRUE) - list(APPEND llappearance_SOURCE_FILES ${llappearance_HEADER_FILES}) add_library (llappearance ${llappearance_SOURCE_FILES}) target_link_libraries(llappearance - ${LLCHARACTER_LIBRARIES} - ${LLINVENTORY_LIBRARIES} - ${LLIMAGE_LIBRARIES} - ${LLRENDER_LIBRARIES} - ${LLFILESYSTEM_LIBRARIES} - ${LLMATH_LIBRARIES} - ${LLXML_LIBRARIES} - ${LLMATH_LIBRARIES} - ${LLMESSAGE_LIBRARIES} - ${LLCOREHTTP_LIBRARIES} - ${LLCOMMON_LIBRARIES} + llcharacter + llinventory + llimage + llrender + llfilesystem + llmath + llxml + llmessage + llcorehttp + llcommon ) +target_include_directories( llappearance INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}) if (BUILD_HEADLESS) add_library (llappearanceheadless ${llappearance_SOURCE_FILES}) - + target_include_directories( llappearanceheadless INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}) + target_link_libraries(llappearanceheadless - ${LLCHARACTER_LIBRARIES} - ${LLINVENTORY_LIBRARIES} - ${LLIMAGE_LIBRARIES} - ${LLRENDERHEADLESS_LIBRARIES} - ${LLFILESYSTEM_LIBRARIES} - ${LLMATH_LIBRARIES} - ${LLXML_LIBRARIES} - ${LLMATH_LIBRARIES} - ${LLMESSAGE_LIBRARIES} - ${LLCOREHTTP_LIBRARIES} - ${LLCOMMON_LIBRARIES} + llcharacter + llinventory + llimage + llfilesystem + llmath + llxml + llmessage + llcorehttp + llcommon ) endif (BUILD_HEADLESS) diff --git a/indra/llappearance/llavatarappearance.cpp b/indra/llappearance/llavatarappearance.cpp index 2f0980ac76..7946a3e705 100644 --- a/indra/llappearance/llavatarappearance.cpp +++ b/indra/llappearance/llavatarappearance.cpp @@ -296,7 +296,12 @@ LLAvatarAppearance::~LLAvatarAppearance() } } - if (mRoot) mRoot->removeAllChildren(); + if (mRoot) + { + mRoot->removeAllChildren(); + delete mRoot; + mRoot = nullptr; + } mJointMap.clear(); clearSkeleton(); diff --git a/indra/llappearance/lllocaltextureobject.cpp b/indra/llappearance/lllocaltextureobject.cpp index ac8a1abb2d..ab50db3a5a 100644 --- a/indra/llappearance/lllocaltextureobject.cpp +++ b/indra/llappearance/lllocaltextureobject.cpp @@ -76,6 +76,7 @@ LLLocalTextureObject::LLLocalTextureObject(const LLLocalTextureObject& lto) : LLLocalTextureObject::~LLLocalTextureObject() { + delete_and_clear(mTexLayers); } LLGLTexture* LLLocalTextureObject::getImage() const diff --git a/indra/llaudio/CMakeLists.txt b/indra/llaudio/CMakeLists.txt index 92a5cfe22f..4f469b9bb5 100644 --- a/indra/llaudio/CMakeLists.txt +++ b/indra/llaudio/CMakeLists.txt @@ -7,23 +7,6 @@ include(LLAudio) include(FMODSTUDIO) include(OPENAL) include(LLCommon) -include(LLMath) -include(LLMessage) -include(LLFileSystem) - -include_directories( - ${LLAUDIO_INCLUDE_DIRS} - ${LLCOMMON_INCLUDE_DIRS} - ${LLMATH_INCLUDE_DIRS} - ${LLMESSAGE_INCLUDE_DIRS} - ${LLFILESYSTEM_INCLUDE_DIRS} - ${OGG_INCLUDE_DIRS} - ${VORBISENC_INCLUDE_DIRS} - ${VORBISFILE_INCLUDE_DIRS} - ${VORBIS_INCLUDE_DIRS} - ${OPENAL_LIB_INCLUDE_DIRS} - ${FREEAULT_LIB_INCLUDE_DIRS} - ) set(llaudio_SOURCE_FILES llaudioengine.cpp @@ -42,10 +25,7 @@ set(llaudio_HEADER_FILES llwindgen.h ) -if (FMODSTUDIO) - include_directories( - ${FMODSTUDIO_INCLUDE_DIR} - ) +if (TARGET ll::fmodstudio) list(APPEND llaudio_SOURCE_FILES llaudioengine_fmodstudio.cpp lllistener_fmodstudio.cpp @@ -57,13 +37,9 @@ if (FMODSTUDIO) lllistener_fmodstudio.h llstreamingaudio_fmodstudio.h ) -endif (FMODSTUDIO) - -if (OPENAL) - include_directories( - ${OPENAL_LIBRARIES} - ) +endif () +if (TARGET ll::openal) list(APPEND llaudio_SOURCE_FILES llaudioengine_openal.cpp lllistener_openal.cpp @@ -73,22 +49,23 @@ if (OPENAL) llaudioengine_openal.h lllistener_openal.h ) -endif (OPENAL) - -set_source_files_properties(${llaudio_HEADER_FILES} - PROPERTIES HEADER_FILE_ONLY TRUE) +endif () list(APPEND llaudio_SOURCE_FILES ${llaudio_HEADER_FILES}) add_library (llaudio ${llaudio_SOURCE_FILES}) -target_link_libraries( - llaudio - ${LLCOMMON_LIBRARIES} - ${LLMATH_LIBRARIES} - ${LLMESSAGE_LIBRARIES} - ${LLFILESYSTEM_LIBRARIES} - ${VORBISENC_LIBRARIES} - ${VORBISFILE_LIBRARIES} - ${VORBIS_LIBRARIES} - ${OGG_LIBRARIES} +target_include_directories( llaudio INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}) +target_link_libraries( llaudio + llcommon + llmath + llmessage + llfilesystem + ll::vorbis ) + +if( TARGET ll::openal ) + target_link_libraries( llaudio ll::openal ) +endif() +if( TARGET ll::fmodstudio ) + target_link_libraries( llaudio ll::fmodstudio ) +endif() diff --git a/indra/llcharacter/CMakeLists.txt b/indra/llcharacter/CMakeLists.txt index d90ffb5543..bc45eb474a 100644 --- a/indra/llcharacter/CMakeLists.txt +++ b/indra/llcharacter/CMakeLists.txt @@ -4,22 +4,6 @@ project(llcharacter) include(00-Common) include(LLCommon) -include(LLMath) -include(LLMessage) -include(LLFileSystem) -include(LLXML) - -include_directories( - ${LLCOMMON_INCLUDE_DIRS} - ${LLMATH_INCLUDE_DIRS} - ${LLMESSAGE_INCLUDE_DIRS} - ${LLFILESYSTEM_INCLUDE_DIRS} - ${LLXML_INCLUDE_DIRS} - ) -include_directories(SYSTEM - ${LLCOMMON_SYSTEM_INCLUDE_DIRS} - ${LLXML_SYSTEM_INCLUDE_DIRS} - ) set(llcharacter_SOURCE_FILES llanimationstates.cpp @@ -73,18 +57,16 @@ set(llcharacter_HEADER_FILES llvisualparam.h ) -set_source_files_properties(${llcharacter_HEADER_FILES} - PROPERTIES HEADER_FILE_ONLY TRUE) - list(APPEND llcharacter_SOURCE_FILES ${llcharacter_HEADER_FILES}) add_library (llcharacter ${llcharacter_SOURCE_FILES}) +target_include_directories( llcharacter INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}) target_link_libraries( - llcharacter - ${LLCOMMON_LIBRARIES} - ${LLMATH_LIBRARIES} - ${LLMESSAGE_LIBRARIES} - ${LLFILESYSTEM_LIBRARIES} - ${LLXML_LIBRARIES} + llcharacter + llcommon + llmath + llmessage + llfilesystem + llxml ) diff --git a/indra/llcharacter/llkeyframemotion.cpp b/indra/llcharacter/llkeyframemotion.cpp index d82ce23b4b..6720f902bd 100644 --- a/indra/llcharacter/llkeyframemotion.cpp +++ b/indra/llcharacter/llkeyframemotion.cpp @@ -1221,7 +1221,7 @@ void LLKeyframeMotion::applyConstraint(JointConstraint* constraint, F32 time, U8 BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, bool allow_invalid_joints) { BOOL old_version = FALSE; - mJointMotionList = new LLKeyframeMotion::JointMotionList; + std::unique_ptr<LLKeyframeMotion::JointMotionList> joint_motion_list(new LLKeyframeMotion::JointMotionList); //------------------------------------------------------------------------- // get base priority @@ -1264,16 +1264,16 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, boo << " for animation " << asset_id << LL_ENDL; return FALSE; } - mJointMotionList->mBasePriority = (LLJoint::JointPriority) temp_priority; + joint_motion_list->mBasePriority = (LLJoint::JointPriority) temp_priority; - if (mJointMotionList->mBasePriority >= LLJoint::ADDITIVE_PRIORITY) + if (joint_motion_list->mBasePriority >= LLJoint::ADDITIVE_PRIORITY) { - mJointMotionList->mBasePriority = (LLJoint::JointPriority)((S32)LLJoint::ADDITIVE_PRIORITY-1); - mJointMotionList->mMaxPriority = mJointMotionList->mBasePriority; + joint_motion_list->mBasePriority = (LLJoint::JointPriority)((S32)LLJoint::ADDITIVE_PRIORITY-1); + joint_motion_list->mMaxPriority = joint_motion_list->mBasePriority; } - else if (mJointMotionList->mBasePriority < LLJoint::USE_MOTION_PRIORITY) + else if (joint_motion_list->mBasePriority < LLJoint::USE_MOTION_PRIORITY) { - LL_WARNS() << "bad animation base_priority " << mJointMotionList->mBasePriority + LL_WARNS() << "bad animation base_priority " << joint_motion_list->mBasePriority << " for animation " << asset_id << LL_ENDL; return FALSE; } @@ -1281,15 +1281,15 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, boo //------------------------------------------------------------------------- // get duration //------------------------------------------------------------------------- - if (!dp.unpackF32(mJointMotionList->mDuration, "duration")) + if (!dp.unpackF32(joint_motion_list->mDuration, "duration")) { LL_WARNS() << "can't read duration" << " for animation " << asset_id << LL_ENDL; return FALSE; } - if (mJointMotionList->mDuration > MAX_ANIM_DURATION || - !llfinite(mJointMotionList->mDuration)) + if (joint_motion_list->mDuration > MAX_ANIM_DURATION || + !llfinite(joint_motion_list->mDuration)) { LL_WARNS() << "invalid animation duration" << " for animation " << asset_id << LL_ENDL; @@ -1299,14 +1299,14 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, boo //------------------------------------------------------------------------- // get emote (optional) //------------------------------------------------------------------------- - if (!dp.unpackString(mJointMotionList->mEmoteName, "emote_name")) + if (!dp.unpackString(joint_motion_list->mEmoteName, "emote_name")) { LL_WARNS() << "can't read optional_emote_animation" << " for animation " << asset_id << LL_ENDL; return FALSE; } - if(mJointMotionList->mEmoteName==mID.asString()) + if(joint_motion_list->mEmoteName==mID.asString()) { LL_WARNS() << "Malformed animation mEmoteName==mID" << " for animation " << asset_id << LL_ENDL; @@ -1316,23 +1316,23 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, boo //------------------------------------------------------------------------- // get loop //------------------------------------------------------------------------- - if (!dp.unpackF32(mJointMotionList->mLoopInPoint, "loop_in_point") || - !llfinite(mJointMotionList->mLoopInPoint)) + if (!dp.unpackF32(joint_motion_list->mLoopInPoint, "loop_in_point") || + !llfinite(joint_motion_list->mLoopInPoint)) { LL_WARNS() << "can't read loop point" << " for animation " << asset_id << LL_ENDL; return FALSE; } - if (!dp.unpackF32(mJointMotionList->mLoopOutPoint, "loop_out_point") || - !llfinite(mJointMotionList->mLoopOutPoint)) + if (!dp.unpackF32(joint_motion_list->mLoopOutPoint, "loop_out_point") || + !llfinite(joint_motion_list->mLoopOutPoint)) { LL_WARNS() << "can't read loop point" << " for animation " << asset_id << LL_ENDL; return FALSE; } - if (!dp.unpackS32(mJointMotionList->mLoop, "loop")) + if (!dp.unpackS32(joint_motion_list->mLoop, "loop")) { LL_WARNS() << "can't read loop" << " for animation " << asset_id << LL_ENDL; @@ -1345,22 +1345,22 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, boo if (female_land_anim == asset_id || formal_female_land_anim == asset_id) { LL_WARNS() << "Animation(" << asset_id << ") won't be looped." << LL_ENDL; - mJointMotionList->mLoop = FALSE; + joint_motion_list->mLoop = FALSE; } //------------------------------------------------------------------------- // get easeIn and easeOut //------------------------------------------------------------------------- - if (!dp.unpackF32(mJointMotionList->mEaseInDuration, "ease_in_duration") || - !llfinite(mJointMotionList->mEaseInDuration)) + if (!dp.unpackF32(joint_motion_list->mEaseInDuration, "ease_in_duration") || + !llfinite(joint_motion_list->mEaseInDuration)) { LL_WARNS() << "can't read easeIn" << " for animation " << asset_id << LL_ENDL; return FALSE; } - if (!dp.unpackF32(mJointMotionList->mEaseOutDuration, "ease_out_duration") || - !llfinite(mJointMotionList->mEaseOutDuration)) + if (!dp.unpackF32(joint_motion_list->mEaseOutDuration, "ease_out_duration") || + !llfinite(joint_motion_list->mEaseOutDuration)) { LL_WARNS() << "can't read easeOut" << " for animation " << asset_id << LL_ENDL; @@ -1385,7 +1385,7 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, boo return FALSE; } - mJointMotionList->mHandPose = (LLHandMotion::eHandPose)word; + joint_motion_list->mHandPose = (LLHandMotion::eHandPose)word; //------------------------------------------------------------------------- // get number of joint motions @@ -1411,8 +1411,8 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, boo return FALSE; } - mJointMotionList->mJointMotionArray.clear(); - mJointMotionList->mJointMotionArray.reserve(num_motions); + joint_motion_list->mJointMotionArray.clear(); + joint_motion_list->mJointMotionArray.reserve(num_motions); mJointStates.clear(); mJointStates.reserve(num_motions); @@ -1423,7 +1423,7 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, boo for(U32 i=0; i<num_motions; ++i) { JointMotion* joint_motion = new JointMotion; - mJointMotionList->mJointMotionArray.push_back(joint_motion); + joint_motion_list->mJointMotionArray.push_back(joint_motion); std::string joint_name; if (!dp.unpackString(joint_name, "joint_name")) @@ -1495,9 +1495,9 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, boo joint_motion->mPriority = (LLJoint::JointPriority)joint_priority; if (joint_priority != LLJoint::USE_MOTION_PRIORITY && - joint_priority > mJointMotionList->mMaxPriority) + joint_priority > joint_motion_list->mMaxPriority) { - mJointMotionList->mMaxPriority = (LLJoint::JointPriority)joint_priority; + joint_motion_list->mMaxPriority = (LLJoint::JointPriority)joint_priority; } joint_state->setPriority((LLJoint::JointPriority)joint_priority); @@ -1548,9 +1548,9 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, boo return FALSE; } - time = U16_to_F32(time_short, 0.f, mJointMotionList->mDuration); + time = U16_to_F32(time_short, 0.f, joint_motion_list->mDuration); - if (time < 0 || time > mJointMotionList->mDuration) + if (time < 0 || time > joint_motion_list->mDuration) { LL_WARNS() << "invalid frame time" << " for animation " << asset_id << LL_ENDL; @@ -1563,38 +1563,57 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, boo LLVector3 rot_angles; U16 x, y, z; - BOOL success = TRUE; - if (old_version) { - success = dp.unpackVector3(rot_angles, "rot_angles") && rot_angles.isFinite(); + if (!dp.unpackVector3(rot_angles, "rot_angles")) + { + LL_WARNS() << "can't read rot_angles in rotation key (" << k << ")" << LL_ENDL; + return FALSE; + } + if (!rot_angles.isFinite()) + { + LL_WARNS() << "non-finite angle in rotation key (" << k << ")" << LL_ENDL; + return FALSE; + } LLQuaternion::Order ro = StringToOrder("ZYX"); rot_key.mRotation = mayaQ(rot_angles.mV[VX], rot_angles.mV[VY], rot_angles.mV[VZ], ro); } else { - success &= dp.unpackU16(x, "rot_angle_x"); - success &= dp.unpackU16(y, "rot_angle_y"); - success &= dp.unpackU16(z, "rot_angle_z"); + if (!dp.unpackU16(x, "rot_angle_x")) + { + LL_WARNS() << "can't read rot_angle_x in rotation key (" << k << ")" << LL_ENDL; + return FALSE; + } + if (!dp.unpackU16(y, "rot_angle_y")) + { + LL_WARNS() << "can't read rot_angle_y in rotation key (" << k << ")" << LL_ENDL; + return FALSE; + } + if (!dp.unpackU16(z, "rot_angle_z")) + { + LL_WARNS() << "can't read rot_angle_z in rotation key (" << k << ")" << LL_ENDL; + return FALSE; + } LLVector3 rot_vec; rot_vec.mV[VX] = U16_to_F32(x, -1.f, 1.f); rot_vec.mV[VY] = U16_to_F32(y, -1.f, 1.f); rot_vec.mV[VZ] = U16_to_F32(z, -1.f, 1.f); + + if(!rot_vec.isFinite()) + { + LL_WARNS() << "non-finite angle in rotation key (" << k << ")" + << " for animation " << asset_id << LL_ENDL; + return FALSE; + } rot_key.mRotation.unpackFromVector3(rot_vec); } - if( !(rot_key.mRotation.isFinite()) ) - { - LL_WARNS() << "non-finite angle in rotation key" - << " for animation " << asset_id << LL_ENDL; - success = FALSE; - } - - if (!success) + if(!rot_key.mRotation.isFinite()) { - LL_WARNS() << "can't read rotation key (" << k << ")" + LL_WARNS() << "non-finite angle in rotation key (" << k << ")" << " for animation " << asset_id << LL_ENDL; return FALSE; } @@ -1647,14 +1666,16 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, boo return FALSE; } - pos_key.mTime = U16_to_F32(time_short, 0.f, mJointMotionList->mDuration); + pos_key.mTime = U16_to_F32(time_short, 0.f, joint_motion_list->mDuration); } - BOOL success = TRUE; - if (old_version) { - success = dp.unpackVector3(pos_key.mPosition, "pos"); + if (!dp.unpackVector3(pos_key.mPosition, "pos")) + { + LL_WARNS() << "can't read pos in position key (" << k << ")" << LL_ENDL; + return FALSE; + } //MAINT-6162 pos_key.mPosition.mV[VX] = llclamp( pos_key.mPosition.mV[VX], -LL_MAX_PELVIS_OFFSET, LL_MAX_PELVIS_OFFSET); @@ -1666,26 +1687,31 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, boo { U16 x, y, z; - success &= dp.unpackU16(x, "pos_x"); - success &= dp.unpackU16(y, "pos_y"); - success &= dp.unpackU16(z, "pos_z"); + if (!dp.unpackU16(x, "pos_x")) + { + LL_WARNS() << "can't read pos_x in position key (" << k << ")" << LL_ENDL; + return FALSE; + } + if (!dp.unpackU16(y, "pos_y")) + { + LL_WARNS() << "can't read pos_y in position key (" << k << ")" << LL_ENDL; + return FALSE; + } + if (!dp.unpackU16(z, "pos_z")) + { + LL_WARNS() << "can't read pos_z in position key (" << k << ")" << LL_ENDL; + return FALSE; + } pos_key.mPosition.mV[VX] = U16_to_F32(x, -LL_MAX_PELVIS_OFFSET, LL_MAX_PELVIS_OFFSET); pos_key.mPosition.mV[VY] = U16_to_F32(y, -LL_MAX_PELVIS_OFFSET, LL_MAX_PELVIS_OFFSET); pos_key.mPosition.mV[VZ] = U16_to_F32(z, -LL_MAX_PELVIS_OFFSET, LL_MAX_PELVIS_OFFSET); } - if( !(pos_key.mPosition.isFinite()) ) + if(!pos_key.mPosition.isFinite()) { LL_WARNS() << "non-finite position in key" << " for animation " << asset_id << LL_ENDL; - success = FALSE; - } - - if (!success) - { - LL_WARNS() << "can't read position key (" << k << ")" - << " for animation " << asset_id << LL_ENDL; return FALSE; } @@ -1693,7 +1719,7 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, boo if (is_pelvis) { - mJointMotionList->mPelvisBBox.addPoint(pos_key.mPosition); + joint_motion_list->mPelvisBBox.addPoint(pos_key.mPosition); } } @@ -1725,23 +1751,21 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, boo for(S32 i = 0; i < num_constraints; ++i) { // read in constraint data - JointConstraintSharedData* constraintp = new JointConstraintSharedData; + std::unique_ptr<JointConstraintSharedData> constraintp(new JointConstraintSharedData); U8 byte = 0; if (!dp.unpackU8(byte, "chain_length")) { LL_WARNS() << "can't read constraint chain length" << " for animation " << asset_id << LL_ENDL; - delete constraintp; return FALSE; } constraintp->mChainLength = (S32) byte; - if((U32)constraintp->mChainLength > mJointMotionList->getNumJointMotions()) + if((U32)constraintp->mChainLength > joint_motion_list->getNumJointMotions()) { LL_WARNS() << "invalid constraint chain length" << " for animation " << asset_id << LL_ENDL; - delete constraintp; return FALSE; } @@ -1749,7 +1773,6 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, boo { LL_WARNS() << "can't read constraint type" << " for animation " << asset_id << LL_ENDL; - delete constraintp; return FALSE; } @@ -1757,7 +1780,6 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, boo { LL_WARNS() << "invalid constraint type" << " for animation " << asset_id << LL_ENDL; - delete constraintp; return FALSE; } constraintp->mConstraintType = (EConstraintType)byte; @@ -1768,7 +1790,6 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, boo { LL_WARNS() << "can't read source volume name" << " for animation " << asset_id << LL_ENDL; - delete constraintp; return FALSE; } @@ -1779,7 +1800,6 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, boo { LL_WARNS() << "not a valid source constraint volume " << str << " for animation " << asset_id << LL_ENDL; - delete constraintp; return FALSE; } @@ -1787,7 +1807,6 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, boo { LL_WARNS() << "can't read constraint source offset" << " for animation " << asset_id << LL_ENDL; - delete constraintp; return FALSE; } @@ -1795,7 +1814,6 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, boo { LL_WARNS() << "non-finite constraint source offset" << " for animation " << asset_id << LL_ENDL; - delete constraintp; return FALSE; } @@ -1803,7 +1821,6 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, boo { LL_WARNS() << "can't read target volume name" << " for animation " << asset_id << LL_ENDL; - delete constraintp; return FALSE; } @@ -1822,7 +1839,6 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, boo { LL_WARNS() << "not a valid target constraint volume " << str << " for animation " << asset_id << LL_ENDL; - delete constraintp; return FALSE; } } @@ -1831,7 +1847,6 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, boo { LL_WARNS() << "can't read constraint target offset" << " for animation " << asset_id << LL_ENDL; - delete constraintp; return FALSE; } @@ -1839,7 +1854,6 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, boo { LL_WARNS() << "non-finite constraint target offset" << " for animation " << asset_id << LL_ENDL; - delete constraintp; return FALSE; } @@ -1847,7 +1861,6 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, boo { LL_WARNS() << "can't read constraint target direction" << " for animation " << asset_id << LL_ENDL; - delete constraintp; return FALSE; } @@ -1855,7 +1868,6 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, boo { LL_WARNS() << "non-finite constraint target direction" << " for animation " << asset_id << LL_ENDL; - delete constraintp; return FALSE; } @@ -1869,7 +1881,6 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, boo { LL_WARNS() << "can't read constraint ease in start time" << " for animation " << asset_id << LL_ENDL; - delete constraintp; return FALSE; } @@ -1877,7 +1888,6 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, boo { LL_WARNS() << "can't read constraint ease in stop time" << " for animation " << asset_id << LL_ENDL; - delete constraintp; return FALSE; } @@ -1885,7 +1895,6 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, boo { LL_WARNS() << "can't read constraint ease out start time" << " for animation " << asset_id << LL_ENDL; - delete constraintp; return FALSE; } @@ -1893,33 +1902,31 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, boo { LL_WARNS() << "can't read constraint ease out stop time" << " for animation " << asset_id << LL_ENDL; - delete constraintp; return FALSE; } - mJointMotionList->mConstraints.push_front(constraintp); - - constraintp->mJointStateIndices = new S32[constraintp->mChainLength + 1]; // note: mChainLength is size-limited - comes from a byte - LLJoint* joint = mCharacter->findCollisionVolume(constraintp->mSourceConstraintVolume); // get joint to which this collision volume is attached if (!joint) { return FALSE; } + + constraintp->mJointStateIndices = new S32[constraintp->mChainLength + 1]; // note: mChainLength is size-limited - comes from a byte + for (S32 i = 0; i < constraintp->mChainLength + 1; i++) { LLJoint* parent = joint->getParent(); if (!parent) { LL_WARNS() << "Joint with no parent: " << joint->getName() - << " Emote: " << mJointMotionList->mEmoteName + << " Emote: " << joint_motion_list->mEmoteName << " for animation " << asset_id << LL_ENDL; return FALSE; } joint = parent; constraintp->mJointStateIndices[i] = -1; - for (U32 j = 0; j < mJointMotionList->getNumJointMotions(); j++) + for (U32 j = 0; j < joint_motion_list->getNumJointMotions(); j++) { LLJoint* constraint_joint = getJoint(j); @@ -1940,14 +1947,16 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, boo { LL_WARNS() << "No joint index for constraint " << i << " for animation " << asset_id << LL_ENDL; - delete constraintp; return FALSE; } } + + joint_motion_list->mConstraints.push_front(constraintp.release()); } } // *FIX: support cleanup of old keyframe data + mJointMotionList = joint_motion_list.release(); // release from unique_ptr to member; LLKeyframeDataCache::addKeyframeData(getID(), mJointMotionList); mAssetStatus = ASSET_LOADED; diff --git a/indra/llcommon/CMakeLists.txt b/indra/llcommon/CMakeLists.txt index 54b025b74f..54020a4231 100644 --- a/indra/llcommon/CMakeLists.txt +++ b/indra/llcommon/CMakeLists.txt @@ -14,19 +14,6 @@ include(ZLIBNG) include(URIPARSER) include(Tracy) -include_directories( - ${EXPAT_INCLUDE_DIRS} - ${LLCOMMON_INCLUDE_DIRS} - ${JSONCPP_INCLUDE_DIR} - ${ZLIBNG_INCLUDE_DIRS} - ${URIPARSER_INCLUDE_DIRS} - ${TRACY_INCLUDE_DIR} - ) - -# add_executable(lltreeiterators lltreeiterators.cpp) -# -# target_link_libraries(lltreeiterators -# ${LLCOMMON_LIBRARIES}) set(llcommon_SOURCE_FILES indra_constants.cpp @@ -273,52 +260,25 @@ if (DARWIN) list(APPEND llcommon_SOURCE_FILES llsys_objc.mm) endif (DARWIN) -set_source_files_properties(${llcommon_HEADER_FILES} - PROPERTIES HEADER_FILE_ONLY TRUE) - -if (USE_BUGSPLAT) - set_source_files_properties(${llcommon_SOURCE_FILES} - PROPERTIES COMPILE_DEFINITIONS "${BUGSPLAT_DEFINE}") -endif (USE_BUGSPLAT) - list(APPEND llcommon_SOURCE_FILES ${llcommon_HEADER_FILES}) -if(LLCOMMON_LINK_SHARED) - add_library (llcommon SHARED ${llcommon_SOURCE_FILES}) - if(NOT ADDRESS_SIZE EQUAL 32) - if(WINDOWS) - ##add_definitions(/FIXED:NO) - else(WINDOWS) # not windows therefore gcc LINUX and DARWIN - add_definitions(-fPIC) - endif(WINDOWS) - endif(NOT ADDRESS_SIZE EQUAL 32) - if(WINDOWS) - # always generate llcommon.pdb, even for "Release" builds - set_target_properties(llcommon PROPERTIES LINK_FLAGS "/DEBUG") - endif(WINDOWS) - ll_stage_sharedlib(llcommon) -else(LLCOMMON_LINK_SHARED) - add_library (llcommon ${llcommon_SOURCE_FILES}) -endif(LLCOMMON_LINK_SHARED) +add_library (llcommon ${llcommon_SOURCE_FILES}) target_link_libraries( - llcommon - ${APRUTIL_LIBRARIES} - ${APR_LIBRARIES} - ${EXPAT_LIBRARIES} - ${JSONCPP_LIBRARIES} - ${ZLIBNG_LIBRARIES} - ${WINDOWS_LIBRARIES} - ${BOOST_FIBER_LIBRARY} - ${BOOST_CONTEXT_LIBRARY} - ${BOOST_PROGRAM_OPTIONS_LIBRARY} - ${BOOST_REGEX_LIBRARY} - ${BOOST_SYSTEM_LIBRARY} - ${GOOGLE_PERFTOOLS_LIBRARIES} - ${URIPARSER_LIBRARIES} - ${TRACY_LIBRARY} + llcommon + ll::apr + ll::expat + ll::jsoncpp + ll::zlib-ng + ll::boost + ll::uriparser + ll::oslibraries + ll::tracy ) +target_include_directories(llcommon INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}) +target_include_directories(llcommon PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}) + add_dependencies(llcommon stage_third_party_libs) if (LL_TESTS) @@ -329,14 +289,7 @@ if (LL_TESTS) LL_ADD_PROJECT_UNIT_TESTS(llcommon "${llcommon_TEST_SOURCE_FILES}") #set(TEST_DEBUG on) - set(test_libs llcommon - ${LLCOMMON_LIBRARIES} - ${WINDOWS_LIBRARIES} - ${GOOGLEMOCK_LIBRARIES} - ${BOOST_FIBER_LIBRARY} - ${BOOST_CONTEXT_LIBRARY} - ${BOOST_THREAD_LIBRARY} - ${BOOST_SYSTEM_LIBRARY}) + set(test_libs llcommon) LL_ADD_INTEGRATION_TEST(bitpack "" "${test_libs}") LL_ADD_INTEGRATION_TEST(classic_callback "" "${test_libs}") LL_ADD_INTEGRATION_TEST(commonmisc "" "${test_libs}") diff --git a/indra/llcommon/apply.h b/indra/llcommon/apply.h new file mode 100644 index 0000000000..7c58d63bc0 --- /dev/null +++ b/indra/llcommon/apply.h @@ -0,0 +1,115 @@ +/** + * @file apply.h + * @author Nat Goodspeed + * @date 2022-06-18 + * @brief C++14 version of std::apply() + * + * $LicenseInfo:firstyear=2022&license=viewerlgpl$ + * Copyright (c) 2022, Linden Research, Inc. + * $/LicenseInfo$ + */ + +#if ! defined(LL_APPLY_H) +#define LL_APPLY_H + +#include <boost/type_traits/function_traits.hpp> +#include <tuple> + +namespace LL +{ + +/** + * USAGE NOTE: + * https://stackoverflow.com/a/40523474/5533635 + * + * If you're trying to pass apply() a variadic function, the compiler + * complains that it can't deduce the callable type, presumably because it + * doesn't know which arity to reify to pass. + * + * But it works to wrap the variadic function in a generic lambda, e.g.: + * + * @CODE + * LL::apply( + * [](auto&&... args) + * { + * return variadic(std::forward<decltype(args)>(args)...); + * }, + * args); + * @ENDCODE + * + * Presumably this is because there's only one instance of the generic lambda + * @em type, with a variadic <tt>operator()()</tt>. + * + * It's pointless to provide a wrapper @em function that implicitly supplies + * the generic lambda. You couldn't pass your variadic function to our wrapper + * function, for the same original reason! + * + * Instead we provide a wrapper @em macro. Sorry, Dr. Stroustrup. + */ +#define VAPPLY(FUNC, ARGS) \ + LL::apply( \ + [](auto&&... args) \ + { \ + return (FUNC)(std::forward<decltype(args)>(args)...); \ + }, \ + (ARGS)) + +#if __cplusplus >= 201703L + +// C++17 implementation +using std::apply; + +#else // C++14 + +// Derived from https://stackoverflow.com/a/20441189 +// and https://en.cppreference.com/w/cpp/utility/apply +template <typename CALLABLE, typename TUPLE, std::size_t... I> +auto apply_impl(CALLABLE&& func, TUPLE&& args, std::index_sequence<I...>) +{ + // call func(unpacked args) + return std::forward<CALLABLE>(func)(std::move(std::get<I>(args))...); +} + +template <typename CALLABLE, typename... ARGS> +auto apply(CALLABLE&& func, const std::tuple<ARGS...>& args) +{ + // std::index_sequence_for is the magic sauce here, generating an argument + // pack of indexes for each entry in args. apply_impl() can then pass + // those to std::get() to unpack args into individual arguments. + return apply_impl(std::forward<CALLABLE>(func), + args, + std::index_sequence_for<ARGS...>{}); +} + +// per https://stackoverflow.com/a/57510428/5533635 +template <typename CALLABLE, typename T, size_t SIZE> +auto apply(CALLABLE&& func, const std::array<T, SIZE>& args) +{ + return apply(std::forward<CALLABLE>(func), std::tuple_cat(args)); +} + +// per https://stackoverflow.com/a/28411055/5533635 +template <typename CALLABLE, typename T, std::size_t... I> +auto apply_impl(CALLABLE&& func, const std::vector<T>& args, std::index_sequence<I...>) +{ + return apply_impl(std::forward<CALLABLE>(func), + std::make_tuple(std::forward<T>(args[I])...), + I...); +} + +// this goes beyond C++17 std::apply() +template <typename CALLABLE, typename T> +auto apply(CALLABLE&& func, const std::vector<T>& args) +{ + constexpr auto arity = boost::function_traits<CALLABLE>::arity; + assert(args.size() == arity); + return apply_impl(std::forward<CALLABLE>(func), + args, + std::make_index_sequence<arity>()); +} + +#endif // C++14 + +} // namespace LL + +#endif /* ! defined(LL_APPLY_H) */ diff --git a/indra/llcommon/llapp.cpp b/indra/llcommon/llapp.cpp index c658075a31..d839b19c99 100644 --- a/indra/llcommon/llapp.cpp +++ b/indra/llcommon/llapp.cpp @@ -68,10 +68,6 @@ void setup_signals(); void default_unix_signal_handler(int signum, siginfo_t *info, void *); #if LL_LINUX -#include "google_breakpad/minidump_descriptor.h" -static bool unix_minidump_callback(const google_breakpad::MinidumpDescriptor& minidump_desc, - void* context, - bool succeeded); #else // Called by breakpad exception handler after the minidump has been generated. bool unix_post_minidump_callback(const char *dump_dir, @@ -856,47 +852,8 @@ void default_unix_signal_handler(int signum, siginfo_t *info, void *) } #if LL_LINUX -bool unix_minidump_callback(const google_breakpad::MinidumpDescriptor& minidump_desc, void* context, bool succeeded) -{ - // Copy minidump file path into fixed buffer in the app instance to avoid - // heap allocations in a crash handler. - - // path format: <dump_dir>/<minidump_id>.dmp - - //HACK: *path points to the buffer in getMiniDumpFilename which has already allocated space - //to avoid doing allocation during crash. - char * path = LLApp::instance()->getMiniDumpFilename(); - int dir_path_len = strlen(path); - - // The path must not be truncated. - S32 remaining = LLApp::MAX_MINDUMP_PATH_LENGTH - dir_path_len; - - llassert( (remaining - strlen(minidump_desc.path())) > 5); - - path += dir_path_len; - - if (dir_path_len > 0 && path[-1] != '/') - { - *path++ = '/'; - --remaining; - } - - strncpy(path, minidump_desc.path(), remaining); - - LL_INFOS("CRASHREPORT") << "generated minidump: " << LLApp::instance()->getMiniDumpFilename() << LL_ENDL; - LLApp::runErrorHandler(); - -#ifndef LL_RELEASE_FOR_DOWNLOAD - clear_signals(); - return false; -#else - return true; #endif -} -#endif - - bool unix_post_minidump_callback(const char *dump_dir, const char *minidump_id, void *context, bool succeeded) diff --git a/indra/llcommon/llcoros.cpp b/indra/llcommon/llcoros.cpp index 14bfb98629..70d8dfc8b9 100644 --- a/indra/llcommon/llcoros.cpp +++ b/indra/llcommon/llcoros.cpp @@ -288,25 +288,15 @@ std::string LLCoros::launch(const std::string& prefix, const callable_t& callabl return name; } +namespace +{ + #if LL_WINDOWS static const U32 STATUS_MSC_EXCEPTION = 0xE06D7363; // compiler specific -U32 cpp_exception_filter(U32 code, struct _EXCEPTION_POINTERS *exception_infop, const std::string& name) +U32 exception_filter(U32 code, struct _EXCEPTION_POINTERS *exception_infop) { - // C++ exceptions were logged in toplevelTryWrapper, but not SEH - // log SEH exceptions here, to make sure it gets into bugsplat's - // report and because __try won't allow std::string operations - if (code != STATUS_MSC_EXCEPTION) - { - LL_WARNS() << "SEH crash in " << name << ", code: " << code << LL_ENDL; - } - // Handle bugsplat here, since GetExceptionInformation() can only be - // called from within filter for __except(filter), not from __except's {} - // Bugsplat should get all exceptions, C++ and SEH - LLApp::instance()->reportCrashToBugsplat(exception_infop); - - // Only convert non C++ exceptions. if (code == STATUS_MSC_EXCEPTION) { // C++ exception, go on @@ -319,28 +309,38 @@ U32 cpp_exception_filter(U32 code, struct _EXCEPTION_POINTERS *exception_infop, } } -void LLCoros::sehHandle(const std::string& name, const LLCoros::callable_t& callable) +void sehandle(const LLCoros::callable_t& callable) { __try { - LLCoros::toplevelTryWrapper(name, callable); + callable(); } - __except (cpp_exception_filter(GetExceptionCode(), GetExceptionInformation(), name)) + __except (exception_filter(GetExceptionCode(), GetExceptionInformation())) { - // convert to C++ styled exception for handlers other than bugsplat + // convert to C++ styled exception // Note: it might be better to use _se_set_translator // if you want exception to inherit full callstack - // - // in case of bugsplat this will get to exceptionTerminateHandler and - // looks like fiber will terminate application after that char integer_string[512]; - sprintf(integer_string, "SEH crash in %s, code: %lu\n", name.c_str(), GetExceptionCode()); + sprintf(integer_string, "SEH, code: %lu\n", GetExceptionCode()); throw std::exception(integer_string); } } -#endif -void LLCoros::toplevelTryWrapper(const std::string& name, const callable_t& callable) +#else // ! LL_WINDOWS + +inline void sehandle(const LLCoros::callable_t& callable) +{ + callable(); +} + +#endif // ! LL_WINDOWS + +} // anonymous namespace + +// Top-level wrapper around caller's coroutine callable. +// Normally we like to pass strings and such by const reference -- but in this +// case, we WANT to copy both the name and the callable to our local stack! +void LLCoros::toplevel(std::string name, callable_t callable) { // keep the CoroData on this top-level function's stack frame CoroData corodata(name); @@ -350,12 +350,12 @@ void LLCoros::toplevelTryWrapper(const std::string& name, const callable_t& call // run the code the caller actually wants in the coroutine try { - callable(); + sehandle(callable); } catch (const Stop& exc) { LL_INFOS("LLCoros") << "coroutine " << name << " terminating because " - << exc.what() << LL_ENDL; + << exc.what() << LL_ENDL; } catch (const LLContinueError&) { @@ -366,36 +366,14 @@ void LLCoros::toplevelTryWrapper(const std::string& name, const callable_t& call } catch (...) { -#if LL_WINDOWS - // Any OTHER kind of uncaught exception will cause the viewer to - // crash, SEH handling should catch it and report to bugsplat. - LOG_UNHANDLED_EXCEPTION(STRINGIZE("coroutine " << name)); - // to not modify callstack - throw; -#else // Stash any OTHER kind of uncaught exception in the rethrow() queue // to be rethrown by the main fiber. LL_WARNS("LLCoros") << "Capturing uncaught exception in coroutine " << name << LL_ENDL; LLCoros::instance().saveException(name, std::current_exception()); -#endif } } -// Top-level wrapper around caller's coroutine callable. -// Normally we like to pass strings and such by const reference -- but in this -// case, we WANT to copy both the name and the callable to our local stack! -void LLCoros::toplevel(std::string name, callable_t callable) -{ -#if LL_WINDOWS - // Because SEH can's have unwinding, need to call a wrapper - // 'try' is inside SEH handling to not catch LLContinue - sehHandle(name, callable); -#else - toplevelTryWrapper(name, callable); -#endif -} - //static void LLCoros::checkStop() { diff --git a/indra/llcommon/llcoros.h b/indra/llcommon/llcoros.h index dbff921f16..966ce03296 100644 --- a/indra/llcommon/llcoros.h +++ b/indra/llcommon/llcoros.h @@ -307,11 +307,7 @@ public: private: std::string generateDistinctName(const std::string& prefix) const; - void toplevelTryWrapper(const std::string& name, const callable_t& callable); -#if LL_WINDOWS - void sehHandle(const std::string& name, const callable_t& callable); // calls toplevelTryWrapper -#endif - void toplevel(std::string name, callable_t callable); // calls sehHandle or toplevelTryWrapper + void toplevel(std::string name, callable_t callable); struct CoroData; static CoroData& get_CoroData(const std::string& caller); void saveException(const std::string& name, std::exception_ptr exc); diff --git a/indra/llcommon/llerror.cpp b/indra/llcommon/llerror.cpp index 310da2c9f0..02cb186275 100644 --- a/indra/llcommon/llerror.cpp +++ b/indra/llcommon/llerror.cpp @@ -941,7 +941,7 @@ namespace LLError for (a = sets.beginArray(), end = sets.endArray(); a != end; ++a) { const LLSD& entry = *a; - if (entry.isMap() && !entry.emptyMap()) + if (entry.isMap() && entry.size() != 0) { ELevel level = decodeLevel(entry["level"]); diff --git a/indra/llcommon/llprocess.cpp b/indra/llcommon/llprocess.cpp index 23936f0526..97a38ea992 100644 --- a/indra/llcommon/llprocess.cpp +++ b/indra/llcommon/llprocess.cpp @@ -272,6 +272,14 @@ public: boost::bind(&ReadPipeImpl::tick, this, _1)); } + ~ReadPipeImpl() + { + if (mConnection.connected()) + { + mConnection.disconnect(); + } + } + // Much of the implementation is simply connecting the abstract virtual // methods with implementation data concealed from the base class. virtual std::istream& get_istream() { return mStream; } diff --git a/indra/llcommon/llsd.h b/indra/llcommon/llsd.h index c1406cf73f..4e9fcc77ee 100644 --- a/indra/llcommon/llsd.h +++ b/indra/llcommon/llsd.h @@ -447,42 +447,42 @@ public: static std::string typeString(Type type); // Return human-readable type as a string }; -struct llsd_select_bool : public std::unary_function<LLSD, LLSD::Boolean> +struct llsd_select_bool { LLSD::Boolean operator()(const LLSD& sd) const { return sd.asBoolean(); } }; -struct llsd_select_integer : public std::unary_function<LLSD, LLSD::Integer> +struct llsd_select_integer { LLSD::Integer operator()(const LLSD& sd) const { return sd.asInteger(); } }; -struct llsd_select_real : public std::unary_function<LLSD, LLSD::Real> +struct llsd_select_real { LLSD::Real operator()(const LLSD& sd) const { return sd.asReal(); } }; -struct llsd_select_float : public std::unary_function<LLSD, F32> +struct llsd_select_float { F32 operator()(const LLSD& sd) const { return (F32)sd.asReal(); } }; -struct llsd_select_uuid : public std::unary_function<LLSD, LLSD::UUID> +struct llsd_select_uuid { LLSD::UUID operator()(const LLSD& sd) const { return sd.asUUID(); } }; -struct llsd_select_string : public std::unary_function<LLSD, LLSD::String> +struct llsd_select_string { LLSD::String operator()(const LLSD& sd) const { diff --git a/indra/llcommon/llsdjson.h b/indra/llcommon/llsdjson.h index 2be7112404..e56cf03b45 100644 --- a/indra/llcommon/llsdjson.h +++ b/indra/llcommon/llsdjson.h @@ -34,7 +34,7 @@ #include "stdtypes.h" #include "llsd.h" -#include "value.h" +#include "json/value.h" /// Convert a parsed JSON structure into LLSD maintaining member names and /// array indexes. diff --git a/indra/llcommon/llsdserialize.cpp b/indra/llcommon/llsdserialize.cpp index 046523dbb1..e7482b601d 100644 --- a/indra/llcommon/llsdserialize.cpp +++ b/indra/llcommon/llsdserialize.cpp @@ -34,6 +34,9 @@ #include <iostream> #include "apr_base64.h" +#include <boost/iostreams/device/array.hpp> +#include <boost/iostreams/stream.hpp> + #ifdef LL_USESYSTEMLIBS # include <zlib.h> #else @@ -2177,7 +2180,9 @@ std::string zip_llsd(LLSD& data) { //copy result into output if (strm.avail_out >= CHUNK) { - free(output); + deflateEnd(&strm); + if(output) + free(output); LL_WARNS() << "Failed to compress LLSD block." << LL_ENDL; return std::string(); } @@ -2200,7 +2205,9 @@ std::string zip_llsd(LLSD& data) } else { - free(output); + deflateEnd(&strm); + if(output) + free(output); LL_WARNS() << "Failed to compress LLSD block." << LL_ENDL; return std::string(); } @@ -2211,7 +2218,8 @@ std::string zip_llsd(LLSD& data) std::string result((char*) output, size); deflateEnd(&strm); - free(output); + if(output) + free(output); return result; } @@ -2221,53 +2229,66 @@ std::string zip_llsd(LLSD& data) // and deserializes from that copy using LLSDSerialize LLUZipHelper::EZipRresult LLUZipHelper::unzip_llsd(LLSD& data, std::istream& is, S32 size) { + std::unique_ptr<U8[]> in = std::unique_ptr<U8[]>(new(std::nothrow) U8[size]); + if (!in) + { + return ZR_MEM_ERROR; + } + is.read((char*) in.get(), size); + + return unzip_llsd(data, in.get(), size); +} + +LLUZipHelper::EZipRresult LLUZipHelper::unzip_llsd(LLSD& data, const U8* in, S32 size) +{ U8* result = NULL; - llssize cur_size = 0; + U32 cur_size = 0; z_stream strm; - const U32 CHUNK = 65536; + constexpr U32 CHUNK = 1024 * 512; - U8 *in = new(std::nothrow) U8[size]; - if (!in) + static thread_local std::unique_ptr<U8[]> out; + if (!out) { - return ZR_MEM_ERROR; + out = std::unique_ptr<U8[]>(new(std::nothrow) U8[CHUNK]); } - is.read((char*) in, size); - - U8 out[CHUNK]; strm.zalloc = Z_NULL; strm.zfree = Z_NULL; strm.opaque = Z_NULL; strm.avail_in = size; - strm.next_in = in; + strm.next_in = const_cast<U8*>(in); S32 ret = inflateInit(&strm); do { strm.avail_out = CHUNK; - strm.next_out = out; + strm.next_out = out.get(); ret = inflate(&strm, Z_NO_FLUSH); - if (ret == Z_STREAM_ERROR) + switch (ret) + { + case Z_NEED_DICT: + case Z_DATA_ERROR: { inflateEnd(&strm); free(result); - delete [] in; return ZR_DATA_ERROR; } - - switch (ret) + case Z_STREAM_ERROR: + case Z_BUF_ERROR: { - case Z_NEED_DICT: - ret = Z_DATA_ERROR; - case Z_DATA_ERROR: + inflateEnd(&strm); + free(result); + return ZR_BUFFER_ERROR; + } + case Z_MEM_ERROR: + { inflateEnd(&strm); free(result); - delete [] in; return ZR_MEM_ERROR; - break; + } } U32 have = CHUNK-strm.avail_out; @@ -2280,17 +2301,15 @@ LLUZipHelper::EZipRresult LLUZipHelper::unzip_llsd(LLSD& data, std::istream& is, { free(result); } - delete[] in; return ZR_MEM_ERROR; } result = new_result; - memcpy(result+cur_size, out, have); + memcpy(result+cur_size, out.get(), have); cur_size += have; - } while (ret == Z_OK); + } while (ret == Z_OK && ret != Z_STREAM_END); inflateEnd(&strm); - delete [] in; if (ret != Z_STREAM_END) { @@ -2300,37 +2319,11 @@ LLUZipHelper::EZipRresult LLUZipHelper::unzip_llsd(LLSD& data, std::istream& is, //result now points to the decompressed LLSD block { - std::istringstream istr; - // Since we are using this for meshes, data we are dealing with tend to be large. - // So string can potentially fail to allocate, make sure this won't cause problems - try - { - std::string res_str((char*)result, cur_size); - - std::string deprecated_header("<? LLSD/Binary ?>"); - - if (res_str.substr(0, deprecated_header.size()) == deprecated_header) - { - res_str = res_str.substr(deprecated_header.size() + 1, cur_size); - } - cur_size = res_str.size(); - - istr.str(res_str); - } -#ifdef LL_WINDOWS - catch (std::length_error) - { - free(result); - return ZR_SIZE_ERROR; - } -#endif - catch (std::bad_alloc&) - { - free(result); - return ZR_MEM_ERROR; - } + char* result_ptr = strip_deprecated_header((char*)result, cur_size); - if (!LLSDSerialize::fromBinary(data, istr, cur_size, UNZIP_LLSD_MAX_DEPTH)) + boost::iostreams::stream<boost::iostreams::array_source> istrm(result_ptr, cur_size); + + if (!LLSDSerialize::fromBinary(data, istrm, cur_size, UNZIP_LLSD_MAX_DEPTH)) { free(result); return ZR_PARSE_ERROR; @@ -2443,3 +2436,23 @@ U8* unzip_llsdNavMesh( bool& valid, size_t& outsize, std::istream& is, S32 size return result; } + +char* strip_deprecated_header(char* in, U32& cur_size, U32* header_size) +{ + const char* deprecated_header = "<? LLSD/Binary ?>"; + constexpr size_t deprecated_header_size = 17; + + if (cur_size > deprecated_header_size + && memcmp(in, deprecated_header, deprecated_header_size) == 0) + { + in = in + deprecated_header_size; + cur_size = cur_size - deprecated_header_size; + if (header_size) + { + *header_size = deprecated_header_size + 1; + } + } + + return in; +} + diff --git a/indra/llcommon/llsdserialize.h b/indra/llcommon/llsdserialize.h index bd5ef668c0..cf6c1ab73a 100644 --- a/indra/llcommon/llsdserialize.h +++ b/indra/llcommon/llsdserialize.h @@ -858,14 +858,20 @@ public: ZR_SIZE_ERROR, ZR_DATA_ERROR, ZR_PARSE_ERROR, + ZR_BUFFER_ERROR, + ZR_VERSION_ERROR } EZipRresult; // return OK or reason for failure static EZipRresult unzip_llsd(LLSD& data, std::istream& is, S32 size); + static EZipRresult unzip_llsd(LLSD& data, const U8* in, S32 size); }; //dirty little zip functions -- yell at davep LL_COMMON_API std::string zip_llsd(LLSD& data); -LL_COMMON_API U8* unzip_llsdNavMesh( bool& valid, size_t& outsize,std::istream& is, S32 size); +LL_COMMON_API U8* unzip_llsdNavMesh( bool& valid, unsigned int& outsize,std::istream& is, S32 size); + +// returns a pointer to the array or past the array if the deprecated header exists +LL_COMMON_API char* strip_deprecated_header(char* in, U32& cur_size, U32* header_size = nullptr); #endif // LL_LLSDSERIALIZE_H diff --git a/indra/llcommon/llstl.h b/indra/llcommon/llstl.h index a90c2c7e08..25131291f9 100644 --- a/indra/llcommon/llstl.h +++ b/indra/llcommon/llstl.h @@ -142,7 +142,7 @@ struct DeletePairedPointerArray // llselect2nd<map_type::value_type>())); template<typename T> -struct DeletePointerFunctor : public std::unary_function<T*, bool> +struct DeletePointerFunctor { bool operator()(T* ptr) const { @@ -153,7 +153,7 @@ struct DeletePointerFunctor : public std::unary_function<T*, bool> // See notes about DeleteArray for why you should consider avoiding this. template<typename T> -struct DeleteArrayFunctor : public std::unary_function<T*, bool> +struct DeleteArrayFunctor { bool operator()(T* ptr) const { @@ -395,16 +395,17 @@ OutputIter ll_transform_n( // select... with the stl. Look up usage on the sgi website. template <class _Pair> -struct _LLSelect1st : public std::unary_function<_Pair, typename _Pair::first_type> { - const typename _Pair::first_type& operator()(const _Pair& __x) const { +struct _LLSelect1st +{ + const auto& operator()(const _Pair& __x) const { return __x.first; } }; template <class _Pair> -struct _LLSelect2nd : public std::unary_function<_Pair, typename _Pair::second_type> +struct _LLSelect2nd { - const typename _Pair::second_type& operator()(const _Pair& __x) const { + const auto& operator()(const _Pair& __x) const { return __x.second; } }; @@ -416,9 +417,7 @@ template <class _Pair> struct llselect2nd : public _LLSelect2nd<_Pair> {}; // compose... with the stl. Look up usage on the sgi website. template <class _Operation1, class _Operation2> -class ll_unary_compose : - public std::unary_function<typename _Operation2::argument_type, - typename _Operation1::result_type> +class ll_unary_compose { protected: _Operation1 __op1; @@ -426,8 +425,9 @@ protected: public: ll_unary_compose(const _Operation1& __x, const _Operation2& __y) : __op1(__x), __op2(__y) {} - typename _Operation1::result_type - operator()(const typename _Operation2::argument_type& __x) const { + template <typename _Op2Arg> + auto + operator()(const _Op2Arg& __x) const { return __op1(__op2(__x)); } }; @@ -441,8 +441,7 @@ llcompose1(const _Operation1& __op1, const _Operation2& __op2) template <class _Operation1, class _Operation2, class _Operation3> class ll_binary_compose - : public std::unary_function<typename _Operation2::argument_type, - typename _Operation1::result_type> { +{ protected: _Operation1 _M_op1; _Operation2 _M_op2; @@ -451,8 +450,9 @@ public: ll_binary_compose(const _Operation1& __x, const _Operation2& __y, const _Operation3& __z) : _M_op1(__x), _M_op2(__y), _M_op3(__z) { } - typename _Operation1::result_type - operator()(const typename _Operation2::argument_type& __x) const { + template<typename OP2ARG> + auto + operator()(const OP2ARG& __x) const { return _M_op1(_M_op2(__x), _M_op3(__x)); } }; @@ -468,54 +468,51 @@ llcompose2(const _Operation1& __op1, const _Operation2& __op2, // helpers to deal with the fact that MSDev does not package // bind... with the stl. Again, this is from sgi. -template <class _Operation> -class llbinder1st : - public std::unary_function<typename _Operation::second_argument_type, - typename _Operation::result_type> { +template <class _Operation, typename _Arg1> +class llbinder1st +{ protected: _Operation op; - typename _Operation::first_argument_type value; + _Arg1 value; public: - llbinder1st(const _Operation& __x, - const typename _Operation::first_argument_type& __y) + llbinder1st(const _Operation& __x, const _Arg1& __y) : op(__x), value(__y) {} - typename _Operation::result_type - operator()(const typename _Operation::second_argument_type& __x) const { - return op(value, __x); - } + template <typename _Arg2> + auto + operator()(const _Arg2& __x) const { + return op(value, __x); + } }; template <class _Operation, class _Tp> -inline llbinder1st<_Operation> +inline auto llbind1st(const _Operation& __oper, const _Tp& __x) { - typedef typename _Operation::first_argument_type _Arg1_type; - return llbinder1st<_Operation>(__oper, _Arg1_type(__x)); + return llbinder1st<_Operation, _Tp>(__oper, __x); } -template <class _Operation> +template <class _Operation, typename _Arg2> class llbinder2nd - : public std::unary_function<typename _Operation::first_argument_type, - typename _Operation::result_type> { +{ protected: _Operation op; - typename _Operation::second_argument_type value; + _Arg2 value; public: llbinder2nd(const _Operation& __x, - const typename _Operation::second_argument_type& __y) + const _Arg2& __y) : op(__x), value(__y) {} - typename _Operation::result_type - operator()(const typename _Operation::first_argument_type& __x) const { + template <typename _Arg1> + auto + operator()(const _Arg1& __x) const { return op(__x, value); } }; template <class _Operation, class _Tp> -inline llbinder2nd<_Operation> +inline auto llbind2nd(const _Operation& __oper, const _Tp& __x) { - typedef typename _Operation::second_argument_type _Arg2_type; - return llbinder2nd<_Operation>(__oper, _Arg2_type(__x)); + return llbinder2nd<_Operation, _Tp>(__oper, __x); } /** @@ -548,8 +545,7 @@ bool before(const std::type_info* lhs, const std::type_info* rhs) namespace std { template <> - struct less<const std::type_info*>: - public std::binary_function<const std::type_info*, const std::type_info*, bool> + struct less<const std::type_info*> { bool operator()(const std::type_info* lhs, const std::type_info* rhs) const { @@ -558,8 +554,7 @@ namespace std }; template <> - struct less<std::type_info*>: - public std::binary_function<std::type_info*, std::type_info*, bool> + struct less<std::type_info*> { bool operator()(std::type_info* lhs, std::type_info* rhs) const { diff --git a/indra/llcommon/lluuid.cpp b/indra/llcommon/lluuid.cpp index adf31b2d28..5655e8e2f2 100644 --- a/indra/llcommon/lluuid.cpp +++ b/indra/llcommon/lluuid.cpp @@ -1003,36 +1003,6 @@ LLUUID::LLUUID() return !(word[0] | word[1] | word[2] | word[3]); } -// Copy constructor - LLUUID::LLUUID(const LLUUID& rhs) -{ - U32 *tmp = (U32 *)mData; - U32 *rhstmp = (U32 *)rhs.mData; - tmp[0] = rhstmp[0]; - tmp[1] = rhstmp[1]; - tmp[2] = rhstmp[2]; - tmp[3] = rhstmp[3]; -} - - LLUUID::~LLUUID() -{ -} - -// Assignment - LLUUID& LLUUID::operator=(const LLUUID& rhs) -{ - // No need to check the case where this==&rhs. The branch is slower than the write. - U32 *tmp = (U32 *)mData; - U32 *rhstmp = (U32 *)rhs.mData; - tmp[0] = rhstmp[0]; - tmp[1] = rhstmp[1]; - tmp[2] = rhstmp[2]; - tmp[3] = rhstmp[3]; - - return *this; -} - - LLUUID::LLUUID(const char *in_string) { if (!in_string || in_string[0] == 0) diff --git a/indra/llcommon/lluuid.h b/indra/llcommon/lluuid.h index 0d4896ee97..80597fa186 100644 --- a/indra/llcommon/lluuid.h +++ b/indra/llcommon/lluuid.h @@ -55,10 +55,7 @@ public: LLUUID(); explicit LLUUID(const char *in_string); // Convert from string. explicit LLUUID(const std::string& in_string); // Convert from string. - LLUUID(const LLUUID &in); - LLUUID &operator=(const LLUUID &rhs); - - ~LLUUID(); + ~LLUUID() = default; // // MANIPULATORS @@ -139,6 +136,9 @@ public: U8 mData[UUID_BYTES]; }; +static_assert(std::is_trivially_copyable<LLUUID>::value, "LLUUID must be trivial copy"); +static_assert(std::is_trivially_move_assignable<LLUUID>::value, "LLUUID must be trivial move"); +static_assert(std::is_standard_layout<LLUUID>::value, "LLUUID must be a standard layout type"); typedef std::vector<LLUUID> uuid_vec_t; typedef std::set<LLUUID> uuid_set_t; diff --git a/indra/llcommon/stringize.h b/indra/llcommon/stringize.h index 12df693910..c0b13135f9 100644 --- a/indra/llcommon/stringize.h +++ b/indra/llcommon/stringize.h @@ -30,7 +30,7 @@ #define LL_STRINGIZE_H #include <sstream> -#include <llstring.h> +#include "llstring.h" #include <boost/call_traits.hpp> /** diff --git a/indra/llcommon/tests/llleap_test.cpp b/indra/llcommon/tests/llleap_test.cpp index 6c799b7993..3ae48a2532 100644 --- a/indra/llcommon/tests/llleap_test.cpp +++ b/indra/llcommon/tests/llleap_test.cpp @@ -15,10 +15,10 @@ #include "llleap.h" // STL headers // std headers +#include <functional> // external library headers #include <boost/assign/list_of.hpp> #include <boost/phoenix/core/argument.hpp> -#include <boost/foreach.hpp> // other Linden headers #include "../test/lltut.h" #include "../test/namedtempfile.h" @@ -29,7 +29,6 @@ #include "llstring.h" #include "stringize.h" #include "StringVec.h" -#include <functional> using boost::assign::list_of; @@ -241,9 +240,9 @@ namespace tut "import sys\n" "sys.stderr.write('''Hello from Python!\n" "note partial line''')\n"); + StringVec vcommand{ PYTHON, script.getName() }; CaptureLog log(LLError::LEVEL_INFO); - waitfor(LLLeap::create(get_test_name(), - sv(list_of(PYTHON)(script.getName())))); + waitfor(LLLeap::create(get_test_name(), vcommand)); log.messageWith("Hello from Python!"); log.messageWith("note partial line"); } @@ -531,7 +530,7 @@ namespace tut result.ensure(); } - struct TestLargeMessage: public std::binary_function<size_t, size_t, bool> + struct TestLargeMessage { TestLargeMessage(const std::string& PYTHON_, const std::string& reader_module_, const std::string& test_name_): diff --git a/indra/llcommon/threadsafeschedule.h b/indra/llcommon/threadsafeschedule.h index 2d82d6a15e..92bc7da940 100644 --- a/indra/llcommon/threadsafeschedule.h +++ b/indra/llcommon/threadsafeschedule.h @@ -248,7 +248,7 @@ namespace LL TimePoint until = TimePoint::clock::now() + std::chrono::hours(24); pop_result popped = tryPopUntil_(lock, until, tt); if (popped == POPPED) - return std::move(tt); + return tt; // DONE: throw, just as super::pop() does if (popped == DONE) diff --git a/indra/llcorehttp/CMakeLists.txt b/indra/llcorehttp/CMakeLists.txt index c591680250..87796abd3c 100644 --- a/indra/llcorehttp/CMakeLists.txt +++ b/indra/llcorehttp/CMakeLists.txt @@ -10,19 +10,10 @@ include(NGHTTP2) include(ZLIBNG) include(LLCoreHttp) include(LLAddBuildTest) -include(LLMessage) include(LLCommon) include(Tut) include(bugsplat) -include_directories (${CMAKE_CURRENT_SOURCE_DIR}) - -include_directories( - ${LLMESSAGE_INCLUDE_DIRS} - ${LLCOMMON_INCLUDE_DIRS} - ${LLCOREHTTP_INCLUDE_DIRS} - ) - set(llcorehttp_SOURCE_FILES bufferarray.cpp bufferstream.cpp @@ -80,8 +71,6 @@ set(llcorehttp_HEADER_FILES _thread.h ) -set_source_files_properties(${llcorehttp_HEADER_FILES} - PROPERTIES HEADER_FILE_ONLY TRUE) if (DARWIN OR LINUX) # Boost headers define unused members in condition_variable so... set_source_files_properties(${llcorehttp_SOURCE_FILES} @@ -92,14 +81,17 @@ list(APPEND llcorehttp_SOURCE_FILES ${llcorehttp_HEADER_FILES}) add_library (llcorehttp ${llcorehttp_SOURCE_FILES}) target_link_libraries( - llcorehttp - ${CURL_LIBRARIES} - ${OPENSSL_LIBRARIES} - ${CRYPTO_LIBRARIES} - ${NGHTTP2_LIBRARIES} - ${BOOST_THREAD_LIBRARY} - ${BOOST_SYSTEM_LIBRARY} + llcorehttp + llcommon + ll::libcurl + ll::openssl + ll::nghttp2 ) +target_include_directories( llcorehttp INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}) +# llmessage depends on llcorehttp, yet llcorehttp also depends on llmessage (at least for includes). +# Cannot/Should not use target_link_libraries here to add llmessage to the dependencies, as that would +# lead to circular dependencies (or in case of cmake, the first project declaring it's dependencies wins) +target_include_directories( llcorehttp PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/../llmessage) # tests set(LLCOREHTTP_TESTS ON CACHE BOOL @@ -119,26 +111,15 @@ if (LL_TESTS AND LLCOREHTTP_TESTS) tests/test_bufferstream.hpp ) - set_source_files_properties(${llcorehttp_TEST_HEADER_FILES} - PROPERTIES HEADER_FILE_ONLY TRUE) - list(APPEND llcorehttp_TEST_SOURCE_FILES ${llcorehttp_TEST_HEADER_FILES}) # LL_ADD_PROJECT_UNIT_TESTS(llcorehttp "${llcorehttp_TEST_SOURCE_FILES}") # set(TEST_DEBUG on) set(test_libs - ${LLCOREHTTP_LIBRARIES} - ${WINDOWS_LIBRARIES} - ${LLMESSAGE_LIBRARIES} - ${LLCOMMON_LIBRARIES} - ${GOOGLEMOCK_LIBRARIES} - ${CURL_LIBRARIES} - ${OPENSSL_LIBRARIES} - ${CRYPTO_LIBRARIES} - ${NGHTTP2_LIBRARIES} - ${BOOST_THREAD_LIBRARY} - ${BOOST_SYSTEM_LIBRARY} + llcorehttp + llmessage + llcommon ) # If http_proxy is in the current environment (e.g. to fetch s3-proxy @@ -155,7 +136,7 @@ if (LL_TESTS AND LLCOREHTTP_TESTS) if (DARWIN) # Path inside the app bundle where we'll need to copy libraries set(LL_TEST_DESTINATION_DIR - ${CMAKE_BINARY_DIR}/sharedlibs/Resources + ${CMAKE_BINARY_DIR}/sharedlibs/$<IF:$<BOOL:${LL_GENERATOR_IS_MULTI_CONFIG}>,,../>Resources ) # Create the Contents/Resources directory @@ -200,18 +181,9 @@ endif (DARWIN) ) set(example_libs - ${LEGACY_STDIO_LIBS} - ${LLCOREHTTP_LIBRARIES} - ${WINDOWS_LIBRARIES} - ${LLMESSAGE_LIBRARIES} - ${LLCOMMON_LIBRARIES} - ${GOOGLEMOCK_LIBRARIES} - ${CURL_LIBRARIES} - ${OPENSSL_LIBRARIES} - ${CRYPTO_LIBRARIES} - ${NGHTTP2_LIBRARIES} - ${BOOST_THREAD_LIBRARY} - ${BOOST_SYSTEM_LIBRARY} + llcorehttp + llmessage + llcommon ) add_executable(http_texture_load diff --git a/indra/llcorehttp/tests/test_llcorehttp_peer.py b/indra/llcorehttp/tests/test_llcorehttp_peer.py index 778de90962..185e8e25c6 100755 --- a/indra/llcorehttp/tests/test_llcorehttp_peer.py +++ b/indra/llcorehttp/tests/test_llcorehttp_peer.py @@ -38,7 +38,6 @@ from io import StringIO from http.server import HTTPServer, BaseHTTPRequestHandler -from llbase.fastest_elementtree import parse as xml_parse from llbase import llsd # we're in llcorehttp/tests ; testrunner.py is found in llmessage/tests diff --git a/indra/llcrashlogger/CMakeLists.txt b/indra/llcrashlogger/CMakeLists.txt index d70a1e0fb0..6ac73c0d32 100644 --- a/indra/llcrashlogger/CMakeLists.txt +++ b/indra/llcrashlogger/CMakeLists.txt @@ -5,23 +5,6 @@ project(llcrashlogger) include(00-Common) include(LLCoreHttp) include(LLCommon) -include(LLMath) -include(LLMessage) -include(LLFileSystem) -include(LLXML) - -include_directories( - ${LLCOREHTTP_INCLUDE_DIRS} - ${LLCOMMON_INCLUDE_DIRS} - ${LLMATH_INCLUDE_DIRS} - ${LLMESSAGE_INCLUDE_DIRS} - ${LLFILESYSTEM_INCLUDE_DIRS} - ${LLXML_INCLUDE_DIRS} - ) -include_directories(SYSTEM - ${LLCOMMON_SYSTEM_INCLUDE_DIRS} - ${LLXML_SYSTEM_INCLUDE_DIRS} - ) set(llcrashlogger_SOURCE_FILES llcrashlogger.cpp @@ -30,14 +13,11 @@ set(llcrashlogger_SOURCE_FILES set(llcrashlogger_HEADER_FILES CMakeLists.txt - llcrashlogger.h llcrashlock.h ) -set_source_files_properties(${llcrashlogger_HEADER_FILES} - PROPERTIES HEADER_FILE_ONLY TRUE) - list(APPEND llcrashlogger_SOURCE_FILES ${llcrashlogger_HEADER_FILES}) add_library(llcrashlogger ${llcrashlogger_SOURCE_FILES}) +target_link_libraries( llcrashlogger llcommon llmessage llcorehttp llxml llfilesystem ) diff --git a/indra/llfilesystem/CMakeLists.txt b/indra/llfilesystem/CMakeLists.txt index 09c4c33ebf..9f24f75eab 100644 --- a/indra/llfilesystem/CMakeLists.txt +++ b/indra/llfilesystem/CMakeLists.txt @@ -4,12 +4,6 @@ project(llfilesystem) include(00-Common) include(LLCommon) -include(UnixInstall) - -include_directories( - ${LLCOMMON_INCLUDE_DIRS} - ${LLCOMMON_SYSTEM_INCLUDE_DIRS} - ) set(llfilesystem_SOURCE_FILES lldir.cpp @@ -53,29 +47,14 @@ if (WINDOWS) LIST(APPEND llfilesystem_HEADER_FILES lldir_win32.h) endif (WINDOWS) -set_source_files_properties(${llfilesystem_HEADER_FILES} - PROPERTIES HEADER_FILE_ONLY TRUE) - list(APPEND llfilesystem_SOURCE_FILES ${llfilesystem_HEADER_FILES}) add_library (llfilesystem ${llfilesystem_SOURCE_FILES}) -set(cache_BOOST_LIBRARIES - ${BOOST_FILESYSTEM_LIBRARY} - ${BOOST_SYSTEM_LIBRARY} - ) - target_link_libraries(llfilesystem - ${LLCOMMON_LIBRARIES} - ${cache_BOOST_LIBRARIES} + llcommon ) - -if (DARWIN) - include(CMakeFindFrameworks) - find_library(COCOA_LIBRARY Cocoa) - target_link_libraries(llfilesystem ${COCOA_LIBRARY}) -endif (DARWIN) - +target_include_directories( llfilesystem INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}) # Add tests if (LL_TESTS) @@ -85,14 +64,10 @@ if (LL_TESTS) lldiriterator.cpp ) - set_source_files_properties(lldiriterator.cpp - PROPERTIES - LL_TEST_ADDITIONAL_LIBRARIES "${cache_BOOST_LIBRARIES}" - ) LL_ADD_PROJECT_UNIT_TESTS(llfilesystem "${llfilesystem_TEST_SOURCE_FILES}") # INTEGRATION TESTS - set(test_libs llmath llcommon llfilesystem ${LLCOMMON_LIBRARIES} ${WINDOWS_LIBRARIES}) + set(test_libs llmath llcommon llfilesystem ) # TODO: Some of these need refactoring to be proper Unit tests rather than Integration tests. LL_ADD_INTEGRATION_TEST(lldir "" "${test_libs}") diff --git a/indra/llfilesystem/lldir_mac.cpp b/indra/llfilesystem/lldir_mac.cpp index 3bc4ee844e..9ad8e274b6 100644 --- a/indra/llfilesystem/lldir_mac.cpp +++ b/indra/llfilesystem/lldir_mac.cpp @@ -66,16 +66,16 @@ LLDir_Mac::LLDir_Mac() const std::string secondLifeString = "SecondLife"; - std::string *executablepathstr = getSystemExecutableFolder(); + std::string executablepathstr = getSystemExecutableFolder(); //NOTE: LLINFOS/LLERRS will not output to log here. The streams are not initialized. - if (executablepathstr) + if (!executablepathstr.empty()) { // mExecutablePathAndName - mExecutablePathAndName = *executablepathstr; + mExecutablePathAndName = executablepathstr; - boost::filesystem::path executablepath(*executablepathstr); + boost::filesystem::path executablepath(executablepathstr); # ifndef BOOST_SYSTEM_NO_DEPRECATED #endif @@ -83,8 +83,8 @@ LLDir_Mac::LLDir_Mac() mExecutableDir = executablepath.parent_path().string(); // mAppRODataDir - std::string *resourcepath = getSystemResourceFolder(); - mAppRODataDir = *resourcepath; + std::string resourcepath = getSystemResourceFolder(); + mAppRODataDir = resourcepath; // *NOTE: When running in a dev tree, use the copy of // skins in indra/newview/ rather than in the application bundle. This @@ -110,11 +110,11 @@ LLDir_Mac::LLDir_Mac() } // mOSUserDir - std::string *appdir = getSystemApplicationSupportFolder(); + std::string appdir = getSystemApplicationSupportFolder(); std::string rootdir; //Create root directory - if (CreateDirectory(*appdir, secondLifeString, &rootdir)) + if (CreateDirectory(appdir, secondLifeString, &rootdir)) { // Save the full path to the folder @@ -128,12 +128,10 @@ LLDir_Mac::LLDir_Mac() } //mOSCacheDir - std::string *cachedir = getSystemCacheFolder(); - - if (cachedir) - + std::string cachedir = getSystemCacheFolder(); + if (!cachedir.empty()) { - mOSCacheDir = *cachedir; + mOSCacheDir = cachedir; //TODO: This changes from ~/Library/Cache/Secondlife to ~/Library/Cache/com.app.secondlife/Secondlife. Last dir level could go away. CreateDirectory(mOSCacheDir, secondLifeString, NULL); } @@ -143,12 +141,10 @@ LLDir_Mac::LLDir_Mac() // mTempDir //Aura 120920 boost::filesystem::temp_directory_path() not yet implemented on mac. :( - std::string *tmpdir = getSystemTempFolder(); - if (tmpdir) + std::string tmpdir = getSystemTempFolder(); + if (!tmpdir.empty()) { - - CreateDirectory(*tmpdir, secondLifeString, &mTempDir); - if (tmpdir) delete tmpdir; + CreateDirectory(tmpdir, secondLifeString, &mTempDir); } mWorkingDir = getCurPath(); diff --git a/indra/llfilesystem/lldir_utils_objc.h b/indra/llfilesystem/lldir_utils_objc.h index 12019c4284..59dbeb4aec 100644 --- a/indra/llfilesystem/lldir_utils_objc.h +++ b/indra/llfilesystem/lldir_utils_objc.h @@ -33,11 +33,11 @@ #include <iostream> -std::string* getSystemTempFolder(); -std::string* getSystemCacheFolder(); -std::string* getSystemApplicationSupportFolder(); -std::string* getSystemResourceFolder(); -std::string* getSystemExecutableFolder(); +std::string getSystemTempFolder(); +std::string getSystemCacheFolder(); +std::string getSystemApplicationSupportFolder(); +std::string getSystemResourceFolder(); +std::string getSystemExecutableFolder(); #endif // LL_LLDIR_UTILS_OBJC_H diff --git a/indra/llfilesystem/lldir_utils_objc.mm b/indra/llfilesystem/lldir_utils_objc.mm index da55a2f897..20540fb93c 100644 --- a/indra/llfilesystem/lldir_utils_objc.mm +++ b/indra/llfilesystem/lldir_utils_objc.mm @@ -30,75 +30,75 @@ #include "lldir_utils_objc.h" #import <Cocoa/Cocoa.h> -std::string* getSystemTempFolder() +std::string getSystemTempFolder() { - NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; - NSString * tempDir = NSTemporaryDirectory(); - if (tempDir == nil) - tempDir = @"/tmp"; - std::string *result = ( new std::string([tempDir UTF8String]) ); - [pool release]; + std::string result; + @autoreleasepool { + NSString * tempDir = NSTemporaryDirectory(); + if (tempDir == nil) + tempDir = @"/tmp"; + result = std::string([tempDir UTF8String]); + } return result; } //findSystemDirectory scoped exclusively to this file. -std::string* findSystemDirectory(NSSearchPathDirectory searchPathDirectory, +std::string findSystemDirectory(NSSearchPathDirectory searchPathDirectory, NSSearchPathDomainMask domainMask) { - NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; - - std::string *result = nil; - NSString *path = nil; - - // Search for the path - NSArray* paths = NSSearchPathForDirectoriesInDomains(searchPathDirectory, - domainMask, - YES); - if ([paths count]) - { - path = [paths objectAtIndex:0]; - //HACK: Always attempt to create directory, ignore errors. - NSError *error = nil; - - [[NSFileManager defaultManager] createDirectoryAtPath:path withIntermediateDirectories:YES attributes:nil error:&error]; - + std::string result; + @autoreleasepool { + NSString *path = nil; - result = new std::string([path UTF8String]); + // Search for the path + NSArray* paths = NSSearchPathForDirectoriesInDomains(searchPathDirectory, + domainMask, + YES); + if ([paths count]) + { + path = [paths objectAtIndex:0]; + //HACK: Always attempt to create directory, ignore errors. + NSError *error = nil; + + [[NSFileManager defaultManager] createDirectoryAtPath:path withIntermediateDirectories:YES attributes:nil error:&error]; + + + result = std::string([path UTF8String]); + } } - [pool release]; return result; } -std::string* getSystemExecutableFolder() +std::string getSystemExecutableFolder() { - NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; - - NSString *bundlePath = [[NSBundle mainBundle] executablePath]; - std::string *result = (new std::string([bundlePath UTF8String])); - [pool release]; + std::string result; + @autoreleasepool { + NSString *bundlePath = [[NSBundle mainBundle] executablePath]; + result = std::string([bundlePath UTF8String]); + } return result; } -std::string* getSystemResourceFolder() +std::string getSystemResourceFolder() { - NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; - - NSString *bundlePath = [[NSBundle mainBundle] resourcePath]; - std::string *result = (new std::string([bundlePath UTF8String])); - [pool release]; + std::string result; + @autoreleasepool { + NSString *bundlePath = [[NSBundle mainBundle] resourcePath]; + result = std::string([bundlePath UTF8String]); + } return result; } -std::string* getSystemCacheFolder() +std::string getSystemCacheFolder() { return findSystemDirectory (NSCachesDirectory, NSUserDomainMask); } -std::string* getSystemApplicationSupportFolder() +std::string getSystemApplicationSupportFolder() { return findSystemDirectory (NSApplicationSupportDirectory, NSUserDomainMask); diff --git a/indra/llfilesystem/lldiskcache.cpp b/indra/llfilesystem/lldiskcache.cpp index 6de99dfbff..4b7363c8e5 100644 --- a/indra/llfilesystem/lldiskcache.cpp +++ b/indra/llfilesystem/lldiskcache.cpp @@ -35,7 +35,6 @@ #include "llassettype.h" #include "lldir.h" #include <boost/filesystem.hpp> -#include <boost/range/iterator_range.hpp> #include <chrono> #include "lldiskcache.h" @@ -100,19 +99,20 @@ void LLDiskCache::purge() #endif if (boost::filesystem::is_directory(cache_path, ec) && !ec.failed()) { - for (auto& entry : boost::make_iterator_range(boost::filesystem::directory_iterator(cache_path, ec), {})) + boost::filesystem::directory_iterator iter(cache_path, ec); + while (iter != boost::filesystem::directory_iterator() && !ec.failed()) { - if (boost::filesystem::is_regular_file(entry, ec) && !ec.failed()) + if (boost::filesystem::is_regular_file(*iter, ec) && !ec.failed()) { - if (entry.path().string().find(mCacheFilenamePrefix) != std::string::npos) + if ((*iter).path().string().find(mCacheFilenamePrefix) != std::string::npos) { - uintmax_t file_size = boost::filesystem::file_size(entry, ec); + uintmax_t file_size = boost::filesystem::file_size(*iter, ec); if (ec.failed()) { continue; } - const std::string file_path = entry.path().string(); - const std::time_t file_time = boost::filesystem::last_write_time(entry, ec); + const std::string file_path = (*iter).path().string(); + const std::time_t file_time = boost::filesystem::last_write_time(*iter, ec); if (ec.failed()) { continue; @@ -121,6 +121,7 @@ void LLDiskCache::purge() file_info.push_back(file_info_t(file_time, { file_size, file_path })); } } + iter.increment(ec); } } @@ -348,19 +349,21 @@ void LLDiskCache::clearCache() #endif if (boost::filesystem::is_directory(cache_path, ec) && !ec.failed()) { - for (auto& entry : boost::make_iterator_range(boost::filesystem::directory_iterator(cache_path, ec), {})) + boost::filesystem::directory_iterator iter(cache_path, ec); + while (iter != boost::filesystem::directory_iterator() && !ec.failed()) { - if (boost::filesystem::is_regular_file(entry, ec) && !ec.failed()) + if (boost::filesystem::is_regular_file(*iter, ec) && !ec.failed()) { - if (entry.path().string().find(mCacheFilenamePrefix) != std::string::npos) + if ((*iter).path().string().find(mCacheFilenamePrefix) != std::string::npos) { - boost::filesystem::remove(entry, ec); + boost::filesystem::remove(*iter, ec); if (ec.failed()) { - LL_WARNS() << "Failed to delete cache file " << entry << ": " << ec.message() << LL_ENDL; + LL_WARNS() << "Failed to delete cache file " << *iter << ": " << ec.message() << LL_ENDL; } } } + iter.increment(ec); } } } @@ -379,20 +382,22 @@ void LLDiskCache::removeOldVFSFiles() #endif if (boost::filesystem::is_directory(cache_path, ec) && !ec.failed()) { - for (auto& entry : boost::make_iterator_range(boost::filesystem::directory_iterator(cache_path, ec), {})) + boost::filesystem::directory_iterator iter(cache_path, ec); + while (iter != boost::filesystem::directory_iterator() && !ec.failed()) { - if (boost::filesystem::is_regular_file(entry, ec) && !ec.failed()) + if (boost::filesystem::is_regular_file(*iter, ec) && !ec.failed()) { - if ((entry.path().string().find(CACHE_FORMAT) != std::string::npos) || - (entry.path().string().find(DB_FORMAT) != std::string::npos)) + if (((*iter).path().string().find(CACHE_FORMAT) != std::string::npos) || + ((*iter).path().string().find(DB_FORMAT) != std::string::npos)) { - boost::filesystem::remove(entry, ec); + boost::filesystem::remove(*iter, ec); if (ec.failed()) { - LL_WARNS() << "Failed to delete cache file " << entry << ": " << ec.message() << LL_ENDL; + LL_WARNS() << "Failed to delete cache file " << *iter << ": " << ec.message() << LL_ENDL; } } } + iter.increment(ec); } } } @@ -418,19 +423,21 @@ uintmax_t LLDiskCache::dirFileSize(const std::string dir) #endif if (boost::filesystem::is_directory(dir_path, ec) && !ec.failed()) { - for (auto& entry : boost::make_iterator_range(boost::filesystem::directory_iterator(dir_path, ec), {})) + boost::filesystem::directory_iterator iter(dir_path, ec); + while (iter != boost::filesystem::directory_iterator() && !ec.failed()) { - if (boost::filesystem::is_regular_file(entry, ec) && !ec.failed()) + if (boost::filesystem::is_regular_file(*iter, ec) && !ec.failed()) { - if (entry.path().string().find(mCacheFilenamePrefix) != std::string::npos) + if ((*iter).path().string().find(mCacheFilenamePrefix) != std::string::npos) { - uintmax_t file_size = boost::filesystem::file_size(entry, ec); + uintmax_t file_size = boost::filesystem::file_size(*iter, ec); if (!ec.failed()) { total_file_size += file_size; } } } + iter.increment(ec); } } diff --git a/indra/llimage/CMakeLists.txt b/indra/llimage/CMakeLists.txt index 436b8dd1a2..cc75c463bc 100644 --- a/indra/llimage/CMakeLists.txt +++ b/indra/llimage/CMakeLists.txt @@ -5,24 +5,13 @@ project(llimage) include(00-Common) include(LLCommon) include(LLImage) -include(LLMath) -include(LLFileSystem) +include(JPEG) include(LLKDU) -include(LLImageJ2COJ) include(ZLIBNG) include(LLAddBuildTest) include(bugsplat) include(Tut) -include_directories( - ${LLCOMMON_INCLUDE_DIRS} - ${LLCOMMON_SYSTEM_INCLUDE_DIRS} - ${LLMATH_INCLUDE_DIRS} - ${LLFILESYSTEM_INCLUDE_DIRS} - ${PNG_INCLUDE_DIRS} - ${ZLIBNG_INCLUDE_DIRS} - ) - set(llimage_SOURCE_FILES llimagebmp.cpp llimage.cpp @@ -54,27 +43,24 @@ set(llimage_HEADER_FILES llpngwrapper.h ) -set_source_files_properties(${llimage_HEADER_FILES} - PROPERTIES HEADER_FILE_ONLY TRUE) - list(APPEND llimage_SOURCE_FILES ${llimage_HEADER_FILES}) add_library (llimage ${llimage_SOURCE_FILES}) +target_include_directories( llimage INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}) # Libraries on which this library depends, needed for Linux builds # Sort by high-level to low-level if (USE_KDU) - target_link_libraries(llimage ${LLKDU_LIBRARIES}) + target_link_libraries(llimage llkdu) else (USE_KDU) - target_link_libraries(llimage ${LLIMAGEJ2COJ_LIBRARIES}) + target_link_libraries(llimage llimagej2coj) endif (USE_KDU) target_link_libraries(llimage - ${LLFILESYSTEM_LIBRARIES} - ${LLMATH_LIBRARIES} - ${LLCOMMON_LIBRARIES} - ${JPEG_LIBRARIES} - ${PNG_LIBRARIES} - ${ZLIBNG_LIBRARIES} + llfilesystem + llmath + llcommon + ll::libpng + ll::libjpeg ) # Add tests diff --git a/indra/llimage/llpngwrapper.cpp b/indra/llimage/llpngwrapper.cpp index f7dc6272cf..cad7c00042 100644 --- a/indra/llimage/llpngwrapper.cpp +++ b/indra/llimage/llpngwrapper.cpp @@ -257,12 +257,7 @@ void LLPngWrapper::normalizeImage() png_set_strip_16(mReadPngPtr); } -#if LL_DARWIN - const F64 SCREEN_GAMMA = 1.8; -#else const F64 SCREEN_GAMMA = 2.2; -#endif - if (png_get_gAMA(mReadPngPtr, mReadInfoPtr, &mGamma)) { png_set_gamma(mReadPngPtr, SCREEN_GAMMA, mGamma); diff --git a/indra/llimagej2coj/CMakeLists.txt b/indra/llimagej2coj/CMakeLists.txt index c9423d50dd..93e85668dd 100644 --- a/indra/llimagej2coj/CMakeLists.txt +++ b/indra/llimagej2coj/CMakeLists.txt @@ -7,12 +7,6 @@ include(LLCommon) include(LLImage) include(OpenJPEG) -include_directories( - ${LLCOMMON_INCLUDE_DIRS} - ${LLIMAGE_INCLUDE_DIRS} - ${OPENJPEG_INCLUDE_DIR} - ) - set(llimagej2coj_SOURCE_FILES llimagej2coj.cpp ) @@ -23,15 +17,13 @@ set(llimagej2coj_HEADER_FILES llimagej2coj.h ) -set_source_files_properties(${llimagej2coj_HEADER_FILES} - PROPERTIES HEADER_FILE_ONLY TRUE) - list(APPEND llimagej2coj_SOURCE_FILES ${llimagej2coj_HEADER_FILES}) add_library (llimagej2coj ${llimagej2coj_SOURCE_FILES}) -target_link_libraries( - llimagej2coj - ${OPENJPEG_LIBRARIES} +target_link_libraries( llimagej2coj + llcommon + llimage + ll::openjpeg ) diff --git a/indra/llimagej2coj/llimagej2coj.cpp b/indra/llimagej2coj/llimagej2coj.cpp index 925da5674b..12985c3c7f 100644 --- a/indra/llimagej2coj/llimagej2coj.cpp +++ b/indra/llimagej2coj/llimagej2coj.cpp @@ -29,40 +29,41 @@ // this is defined so that we get static linking. #include "openjpeg.h" +#include "event.h" +#include "cio.h" -#include "lltimer.h" -//#include "llmemory.h" +#define MAX_ENCODED_DISCARD_LEVELS 5 // Factory function: see declaration in llimagej2c.cpp LLImageJ2CImpl* fallbackCreateLLImageJ2CImpl() { - return new LLImageJ2COJ(); + return new LLImageJ2COJ(); } std::string LLImageJ2COJ::getEngineInfo() const { #ifdef OPENJPEG_VERSION - return std::string("OpenJPEG: " OPENJPEG_VERSION ", Runtime: ") - + opj_version(); + return std::string("OpenJPEG: " OPENJPEG_VERSION ", Runtime: ") + + opj_version(); #else - return std::string("OpenJPEG runtime: ") + opj_version(); + return std::string("OpenJPEG runtime: ") + opj_version(); #endif } // Return string from message, eliminating final \n if present static std::string chomp(const char* msg) { - // stomp trailing \n - std::string message = msg; - if (!message.empty()) - { - size_t last = message.size() - 1; - if (message[last] == '\n') - { - message.resize( last ); - } - } - return message; + // stomp trailing \n + std::string message = msg; + if (!message.empty()) + { + size_t last = message.size() - 1; + if (message[last] == '\n') + { + message.resize(last); + } +} + return message; } /** @@ -70,419 +71,770 @@ sample error callback expecting a LLFILE* client object */ void error_callback(const char* msg, void*) { - LL_DEBUGS() << "LLImageJ2COJ: " << chomp(msg) << LL_ENDL; + LL_DEBUGS() << "LLImageJ2COJ: " << chomp(msg) << LL_ENDL; } /** sample warning callback expecting a LLFILE* client object */ void warning_callback(const char* msg, void*) { - LL_DEBUGS() << "LLImageJ2COJ: " << chomp(msg) << LL_ENDL; + LL_DEBUGS() << "LLImageJ2COJ: " << chomp(msg) << LL_ENDL; } /** sample debug callback expecting no client object */ void info_callback(const char* msg, void*) { - LL_DEBUGS() << "LLImageJ2COJ: " << chomp(msg) << LL_ENDL; + LL_DEBUGS() << "LLImageJ2COJ: " << chomp(msg) << LL_ENDL; } // Divide a by 2 to the power of b and round upwards int ceildivpow2(int a, int b) { - return (a + (1 << b) - 1) >> b; + return (a + (1 << b) - 1) >> b; } - -LLImageJ2COJ::LLImageJ2COJ() - : LLImageJ2CImpl() +class JPEG2KBase { -} +public: + JPEG2KBase() {} + U8* buffer = nullptr; + OPJ_SIZE_T size = 0; + OPJ_OFF_T offset = 0; +}; -LLImageJ2COJ::~LLImageJ2COJ() +#define WANT_VERBOSE_OPJ_SPAM LL_DEBUG + +static void opj_info(const char* msg, void* user_data) { + llassert(user_data); +#if WANT_VERBOSE_OPJ_SPAM + LL_INFOS("OpenJPEG") << msg << LL_ENDL; +#endif } -bool LLImageJ2COJ::initDecode(LLImageJ2C &base, LLImageRaw &raw_image, int discard_level, int* region) +static void opj_warn(const char* msg, void* user_data) { - // No specific implementation for this method in the OpenJpeg case - return false; + llassert(user_data); +#if WANT_VERBOSE_OPJ_SPAM + LL_WARNS("OpenJPEG") << msg << LL_ENDL; +#endif } -bool LLImageJ2COJ::initEncode(LLImageJ2C &base, LLImageRaw &raw_image, int blocks_size, int precincts_size, int levels) +static void opj_error(const char* msg, void* user_data) { - // No specific implementation for this method in the OpenJpeg case - return false; + llassert(user_data); +#if WANT_VERBOSE_OPJ_SPAM + LL_WARNS("OpenJPEG") << msg << LL_ENDL; +#endif } -bool LLImageJ2COJ::decodeImpl(LLImageJ2C &base, LLImageRaw &raw_image, F32 decode_time, S32 first_channel, S32 max_channel_count) +static OPJ_SIZE_T opj_read(void * buffer, OPJ_SIZE_T bytes, void* user_data) { - // - // FIXME: Get the comment field out of the texture - // - - LLTimer decode_timer; - - opj_dparameters_t parameters; /* decompression parameters */ - opj_event_mgr_t event_mgr; /* event manager */ - opj_image_t *image = NULL; - - opj_dinfo_t* dinfo = NULL; /* handle to a decompressor */ - opj_cio_t *cio = NULL; - - - /* configure the event callbacks (not required) */ - memset(&event_mgr, 0, sizeof(opj_event_mgr_t)); - event_mgr.error_handler = error_callback; - event_mgr.warning_handler = warning_callback; - event_mgr.info_handler = info_callback; - - /* set decoding parameters to default values */ - opj_set_default_decoder_parameters(¶meters); - - parameters.cp_reduce = base.getRawDiscardLevel(); - - /* decode the code-stream */ - /* ---------------------- */ - - /* JPEG-2000 codestream */ - - /* get a decoder handle */ - dinfo = opj_create_decompress(CODEC_J2K); - - /* catch events using our callbacks and give a local context */ - opj_set_event_mgr((opj_common_ptr)dinfo, &event_mgr, stderr); - - /* setup the decoder decoding parameters using user parameters */ - opj_setup_decoder(dinfo, ¶meters); - - /* open a byte stream */ - cio = opj_cio_open((opj_common_ptr)dinfo, base.getData(), base.getDataSize()); - - /* decode the stream and fill the image structure */ - image = opj_decode(dinfo, cio); - - /* close the byte stream */ - opj_cio_close(cio); - - /* free remaining structures */ - if(dinfo) - { - opj_destroy_decompress(dinfo); - } - - // The image decode failed if the return was NULL or the component - // count was zero. The latter is just a sanity check before we - // dereference the array. - if(!image || !image->numcomps) - { - LL_DEBUGS("Texture") << "ERROR -> decodeImpl: failed to decode image!" << LL_ENDL; - if (image) - { - opj_image_destroy(image); - } - - return true; // done - } - - // sometimes we get bad data out of the cache - check to see if the decode succeeded - for (S32 i = 0; i < image->numcomps; i++) - { - if (image->comps[i].factor != base.getRawDiscardLevel()) - { - // if we didn't get the discard level we're expecting, fail - opj_image_destroy(image); - base.mDecoding = false; - return true; - } - } - - if(image->numcomps <= first_channel) - { - LL_WARNS() << "trying to decode more channels than are present in image: numcomps: " << image->numcomps << " first_channel: " << first_channel << LL_ENDL; - if (image) - { - opj_image_destroy(image); - } - - return true; - } - - // Copy image data into our raw image format (instead of the separate channel format - - S32 img_components = image->numcomps; - S32 channels = img_components - first_channel; - if( channels > max_channel_count ) - channels = max_channel_count; - - // Component buffers are allocated in an image width by height buffer. - // The image placed in that buffer is ceil(width/2^factor) by - // ceil(height/2^factor) and if the factor isn't zero it will be at the - // top left of the buffer with black filled in the rest of the pixels. - // It is integer math so the formula is written in ceildivpo2. - // (Assuming all the components have the same width, height and - // factor.) - S32 comp_width = image->comps[0].w; - S32 f=image->comps[0].factor; - S32 width = ceildivpow2(image->x1 - image->x0, f); - S32 height = ceildivpow2(image->y1 - image->y0, f); - raw_image.resize(width, height, channels); - U8 *rawp = raw_image.getData(); - - // first_channel is what channel to start copying from - // dest is what channel to copy to. first_channel comes from the - // argument, dest always starts writing at channel zero. - for (S32 comp = first_channel, dest=0; comp < first_channel + channels; - comp++, dest++) - { - if (image->comps[comp].data) - { - S32 offset = dest; - for (S32 y = (height - 1); y >= 0; y--) - { - for (S32 x = 0; x < width; x++) - { - rawp[offset] = image->comps[comp].data[y*comp_width + x]; - offset += channels; - } - } - } - else // Some rare OpenJPEG versions have this bug. - { - LL_DEBUGS("Texture") << "ERROR -> decodeImpl: failed to decode image! (NULL comp data - OpenJPEG bug)" << LL_ENDL; - opj_image_destroy(image); - - return true; // done - } - } - - /* free image data structure */ - opj_image_destroy(image); - - return true; // done + llassert(user_data); + JPEG2KBase* jpeg_codec = static_cast<JPEG2KBase*>(user_data); + OPJ_SIZE_T remainder = (jpeg_codec->size - jpeg_codec->offset); + if (remainder <= 0) + { + jpeg_codec->offset = jpeg_codec->size; + // Indicate end of stream (hacky?) + return (OPJ_OFF_T)-1; + } + OPJ_SIZE_T to_read = llclamp(U32(bytes), U32(0), U32(remainder)); + memcpy(buffer, jpeg_codec->buffer + jpeg_codec->offset, to_read); + jpeg_codec->offset += to_read; + return to_read; } - -bool LLImageJ2COJ::encodeImpl(LLImageJ2C &base, const LLImageRaw &raw_image, const char* comment_text, F32 encode_time, bool reversible) +static OPJ_SIZE_T opj_write(void * buffer, OPJ_SIZE_T bytes, void* user_data) { - const S32 MAX_COMPS = 5; - opj_cparameters_t parameters; /* compression parameters */ - opj_event_mgr_t event_mgr; /* event manager */ - - - /* - configure the event callbacks (not required) - setting of each callback is optional - */ - memset(&event_mgr, 0, sizeof(opj_event_mgr_t)); - event_mgr.error_handler = error_callback; - event_mgr.warning_handler = warning_callback; - event_mgr.info_handler = info_callback; - - /* set encoding parameters to default values */ - opj_set_default_encoder_parameters(¶meters); - parameters.cod_format = 0; - parameters.cp_disto_alloc = 1; - - if (reversible) - { - parameters.tcp_numlayers = 1; - parameters.tcp_rates[0] = 0.0f; - } - else - { - parameters.tcp_numlayers = 5; - parameters.tcp_rates[0] = 1920.0f; - parameters.tcp_rates[1] = 480.0f; - parameters.tcp_rates[2] = 120.0f; - parameters.tcp_rates[3] = 30.0f; - parameters.tcp_rates[4] = 10.0f; - parameters.irreversible = 1; - if (raw_image.getComponents() >= 3) - { - parameters.tcp_mct = 1; - } - } - - if (!comment_text) - { - parameters.cp_comment = (char *) ""; - } - else - { - // Awful hacky cast, too lazy to copy right now. - parameters.cp_comment = (char *) comment_text; - } - - // - // Fill in the source image from our raw image - // - OPJ_COLOR_SPACE color_space = CLRSPC_SRGB; - opj_image_cmptparm_t cmptparm[MAX_COMPS]; - opj_image_t * image = NULL; - S32 numcomps = raw_image.getComponents(); - S32 width = raw_image.getWidth(); - S32 height = raw_image.getHeight(); - - memset(&cmptparm[0], 0, MAX_COMPS * sizeof(opj_image_cmptparm_t)); - for(S32 c = 0; c < numcomps; c++) { - cmptparm[c].prec = 8; - cmptparm[c].bpp = 8; - cmptparm[c].sgnd = 0; - cmptparm[c].dx = parameters.subsampling_dx; - cmptparm[c].dy = parameters.subsampling_dy; - cmptparm[c].w = width; - cmptparm[c].h = height; - } - - /* create the image */ - image = opj_image_create(numcomps, &cmptparm[0], color_space); - - image->x1 = width; - image->y1 = height; - - S32 i = 0; - const U8 *src_datap = raw_image.getData(); - for (S32 y = height - 1; y >= 0; y--) - { - for (S32 x = 0; x < width; x++) - { - const U8 *pixel = src_datap + (y*width + x) * numcomps; - for (S32 c = 0; c < numcomps; c++) - { - image->comps[c].data[i] = *pixel; - pixel++; - } - i++; - } - } - - - - /* encode the destination image */ - /* ---------------------------- */ - - int codestream_length; - opj_cio_t *cio = NULL; - - /* get a J2K compressor handle */ - opj_cinfo_t* cinfo = opj_create_compress(CODEC_J2K); - - /* catch events using our callbacks and give a local context */ - opj_set_event_mgr((opj_common_ptr)cinfo, &event_mgr, stderr); - - /* setup the encoder parameters using the current image and using user parameters */ - opj_setup_encoder(cinfo, ¶meters, image); - - /* open a byte stream for writing */ - /* allocate memory for all tiles */ - cio = opj_cio_open((opj_common_ptr)cinfo, NULL, 0); - - /* encode the image */ - bool bSuccess = opj_encode(cinfo, cio, image, NULL); - if (!bSuccess) - { - opj_cio_close(cio); - LL_DEBUGS("Texture") << "Failed to encode image." << LL_ENDL; - return false; - } - codestream_length = cio_tell(cio); - - base.copyData(cio->buffer, codestream_length); - base.updateData(); // set width, height - - /* close and free the byte stream */ - opj_cio_close(cio); - - /* free remaining compression structures */ - opj_destroy_compress(cinfo); - - - /* free user parameters structure */ - if(parameters.cp_matrice) free(parameters.cp_matrice); - - /* free image data */ - opj_image_destroy(image); - return true; + llassert(user_data); + JPEG2KBase* jpeg_codec = static_cast<JPEG2KBase*>(user_data); + OPJ_SIZE_T remainder = jpeg_codec->size - jpeg_codec->offset; + if (remainder < bytes) + { + OPJ_SIZE_T new_size = jpeg_codec->size + (bytes - remainder); + U8* new_buffer = (U8*)ll_aligned_malloc_16(new_size); + memcpy(new_buffer, jpeg_codec->buffer, jpeg_codec->offset); + U8* old_buffer = jpeg_codec->buffer; + jpeg_codec->buffer = new_buffer; + ll_aligned_free_16(old_buffer); + jpeg_codec->size = new_size; + } + memcpy(jpeg_codec->buffer + jpeg_codec->offset, buffer, bytes); + jpeg_codec->offset += bytes; + return bytes; } -bool LLImageJ2COJ::getMetadata(LLImageJ2C &base) +static OPJ_OFF_T opj_skip(OPJ_OFF_T bytes, void* user_data) { - // - // FIXME: We get metadata by decoding the ENTIRE image. - // - - // Update the raw discard level - base.updateRawDiscardLevel(); - - opj_dparameters_t parameters; /* decompression parameters */ - opj_event_mgr_t event_mgr; /* event manager */ - opj_image_t *image = NULL; - - opj_dinfo_t* dinfo = NULL; /* handle to a decompressor */ - opj_cio_t *cio = NULL; - - - /* configure the event callbacks (not required) */ - memset(&event_mgr, 0, sizeof(opj_event_mgr_t)); - event_mgr.error_handler = error_callback; - event_mgr.warning_handler = warning_callback; - event_mgr.info_handler = info_callback; - - /* set decoding parameters to default values */ - opj_set_default_decoder_parameters(¶meters); - - // Only decode what's required to get the size data. - parameters.cp_limit_decoding=LIMIT_TO_MAIN_HEADER; + JPEG2KBase* jpeg_codec = static_cast<JPEG2KBase*>(user_data); + jpeg_codec->offset += bytes; + + if (jpeg_codec->offset > jpeg_codec->size) + { + jpeg_codec->offset = jpeg_codec->size; + // Indicate end of stream + return (OPJ_OFF_T)-1; + } + + if (jpeg_codec->offset < 0) + { + // Shouldn't be possible? + jpeg_codec->offset = 0; + return (OPJ_OFF_T)-1; + } + + return bytes; +} - //parameters.cp_reduce = mRawDiscardLevel; +static OPJ_BOOL opj_seek(OPJ_OFF_T bytes, void * user_data) +{ + JPEG2KBase* jpeg_codec = static_cast<JPEG2KBase*>(user_data); + jpeg_codec->offset = bytes; + jpeg_codec->offset = llclamp(U32(jpeg_codec->offset), U32(0), U32(jpeg_codec->size)); + return OPJ_TRUE; +} - /* decode the code-stream */ - /* ---------------------- */ +static void opj_free_user_data(void * user_data) +{ + JPEG2KBase* jpeg_codec = static_cast<JPEG2KBase*>(user_data); + // Don't free, data is managed externally + jpeg_codec->buffer = nullptr; + jpeg_codec->size = 0; + jpeg_codec->offset = 0; +} - /* JPEG-2000 codestream */ +static void opj_free_user_data_write(void * user_data) +{ + JPEG2KBase* jpeg_codec = static_cast<JPEG2KBase*>(user_data); + // Free, data was allocated here + ll_aligned_free_16(jpeg_codec->buffer); + jpeg_codec->buffer = nullptr; + jpeg_codec->size = 0; + jpeg_codec->offset = 0; +} - /* get a decoder handle */ - dinfo = opj_create_decompress(CODEC_J2K); +class JPEG2KDecode : public JPEG2KBase +{ +public: + + JPEG2KDecode(S8 discardLevel) + { + memset(&event_mgr, 0, sizeof(opj_event_mgr_t)); + memset(¶meters, 0, sizeof(opj_dparameters_t)); + event_mgr.error_handler = error_callback; + event_mgr.warning_handler = warning_callback; + event_mgr.info_handler = info_callback; + opj_set_default_decoder_parameters(¶meters); + parameters.cp_reduce = discardLevel; + } + + ~JPEG2KDecode() + { + if (decoder) + { + opj_destroy_codec(decoder); + } + decoder = nullptr; + + if (image) + { + opj_image_destroy(image); + } + image = nullptr; + + if (stream) + { + opj_stream_destroy(stream); + } + stream = nullptr; + + if (codestream_info) + { + opj_destroy_cstr_info(&codestream_info); + } + codestream_info = nullptr; + } + + bool readHeader( + U8* data, + U32 dataSize, + S32& widthOut, + S32& heightOut, + S32& components, + S32& discard_level) + { + parameters.flags |= OPJ_DPARAMETERS_DUMP_FLAG; + + decoder = opj_create_decompress(OPJ_CODEC_J2K); + + if (!opj_setup_decoder(decoder, ¶meters)) + { + return false; + } + + if (stream) + { + opj_stream_destroy(stream); + } + + stream = opj_stream_create(dataSize, true); + if (!stream) + { + return false; + } + + opj_stream_set_user_data(stream, this, opj_free_user_data); + opj_stream_set_user_data_length(stream, dataSize); + opj_stream_set_read_function(stream, opj_read); + opj_stream_set_write_function(stream, opj_write); + opj_stream_set_skip_function(stream, opj_skip); + opj_stream_set_seek_function(stream, opj_seek); + + buffer = data; + size = dataSize; + offset = 0; + + // enable decoding partially loaded images + opj_decoder_set_strict_mode(decoder, OPJ_FALSE); + + /* Read the main header of the codestream and if necessary the JP2 boxes*/ + if (!opj_read_header((opj_stream_t*)stream, decoder, &image)) + { + return false; + } + + codestream_info = opj_get_cstr_info(decoder); + + if (!codestream_info) + { + return false; + } + + U32 tileDimX = codestream_info->tdx; + U32 tileDimY = codestream_info->tdy; + U32 tilesW = codestream_info->tw; + U32 tilesH = codestream_info->th; + + widthOut = S32(tilesW * tileDimX); + heightOut = S32(tilesH * tileDimY); + components = codestream_info->nbcomps; + + discard_level = 0; + while (tilesW > 1 && tilesH > 1 && discard_level < MAX_DISCARD_LEVEL) + { + discard_level++; + tilesW >>= 1; + tilesH >>= 1; + } + + return true; + } + + bool decode(U8* data, U32 dataSize, U32* channels, U8 discard_level) + { + parameters.flags &= ~OPJ_DPARAMETERS_DUMP_FLAG; + + decoder = opj_create_decompress(OPJ_CODEC_J2K); + opj_setup_decoder(decoder, ¶meters); + + opj_set_info_handler(decoder, opj_info, this); + opj_set_warning_handler(decoder, opj_warn, this); + opj_set_error_handler(decoder, opj_error, this); + + if (stream) + { + opj_stream_destroy(stream); + } + + stream = opj_stream_create(dataSize, true); + if (!stream) + { + return false; + } + + opj_stream_set_user_data(stream, this, opj_free_user_data); + opj_stream_set_user_data_length(stream, dataSize); + opj_stream_set_read_function(stream, opj_read); + opj_stream_set_write_function(stream, opj_write); + opj_stream_set_skip_function(stream, opj_skip); + opj_stream_set_seek_function(stream, opj_seek); + + buffer = data; + size = dataSize; + offset = 0; + + if (image) + { + opj_image_destroy(image); + image = nullptr; + } + + // needs to happen before opj_read_header and opj_decode... + opj_set_decoded_resolution_factor(decoder, discard_level); + + // enable decoding partially loaded images + opj_decoder_set_strict_mode(decoder, OPJ_FALSE); + + if (!opj_read_header(stream, decoder, &image)) + { + return false; + } + + // needs to happen before decode which may fail + if (channels) + { + *channels = image->numcomps; + } + + OPJ_BOOL decoded = opj_decode(decoder, stream, image); + + // count was zero. The latter is just a sanity check before we + // dereference the array. + if (!decoded || !image || !image->numcomps) + { + opj_end_decompress(decoder, stream); + return false; + } + + opj_end_decompress(decoder, stream); + + return true; + } + + opj_image_t* getImage() { return image; } + +private: + opj_dparameters_t parameters; + opj_event_mgr_t event_mgr; + opj_image_t* image = nullptr; + opj_codec_t* decoder = nullptr; + opj_stream_t* stream = nullptr; + opj_codestream_info_v2_t* codestream_info = nullptr; +}; + +class JPEG2KEncode : public JPEG2KBase +{ +public: + const OPJ_UINT32 TILE_SIZE = 64 * 64 * 3; + + JPEG2KEncode(const char* comment_text_in, bool reversible) + { + memset(¶meters, 0, sizeof(opj_cparameters_t)); + memset(&event_mgr, 0, sizeof(opj_event_mgr_t)); + event_mgr.error_handler = error_callback; + event_mgr.warning_handler = warning_callback; + event_mgr.info_handler = info_callback; + + opj_set_default_encoder_parameters(¶meters); + parameters.cod_format = OPJ_CODEC_J2K; + parameters.cp_disto_alloc = 1; + parameters.max_cs_size = (1 << 15); + + if (reversible) + { + parameters.tcp_numlayers = 1; + parameters.tcp_rates[0] = 1.0f; + } + else + { + parameters.tcp_numlayers = 5; + parameters.tcp_rates[0] = 1920.0f; + parameters.tcp_rates[1] = 960.0f; + parameters.tcp_rates[2] = 480.0f; + parameters.tcp_rates[3] = 120.0f; + parameters.tcp_rates[4] = 30.0f; + parameters.irreversible = 1; + parameters.tcp_mct = 1; + } + + if (comment_text) + { + free(comment_text); + } + comment_text = comment_text_in ? strdup(comment_text_in) : nullptr; + + parameters.cp_comment = comment_text ? comment_text : (char*)"no comment"; + llassert(parameters.cp_comment); + } + + ~JPEG2KEncode() + { + if (encoder) + { + opj_destroy_codec(encoder); + } + encoder = nullptr; + + if (image) + { + opj_image_destroy(image); + } + image = nullptr; + + if (stream) + { + opj_stream_destroy(stream); + } + stream = nullptr; + + if (comment_text) + { + free(comment_text); + } + comment_text = nullptr; + } + + bool encode(const LLImageRaw& rawImageIn, LLImageJ2C &compressedImageOut) + { + setImage(rawImageIn); + + encoder = opj_create_compress(OPJ_CODEC_J2K); + + parameters.tcp_mct = (image->numcomps >= 3) ? 1 : 0; + parameters.cod_format = OPJ_CODEC_J2K; + parameters.prog_order = OPJ_RLCP; + parameters.cp_disto_alloc = 1; + + if (!opj_setup_encoder(encoder, ¶meters, image)) + { + return false; + } + + opj_set_info_handler(encoder, opj_info, this); + opj_set_warning_handler(encoder, opj_warn, this); + opj_set_error_handler(encoder, opj_error, this); + + U32 tile_count = (rawImageIn.getWidth() >> 6) * (rawImageIn.getHeight() >> 6); + U32 data_size_guess = tile_count * TILE_SIZE; + + // will be freed in opj_free_user_data_write + buffer = (U8*)ll_aligned_malloc_16(data_size_guess); + size = data_size_guess; + offset = 0; + + memset(buffer, 0, data_size_guess); + + if (stream) + { + opj_stream_destroy(stream); + } + + stream = opj_stream_create(data_size_guess, false); + if (!stream) + { + return false; + } + + opj_stream_set_user_data(stream, this, opj_free_user_data_write); + opj_stream_set_user_data_length(stream, data_size_guess); + opj_stream_set_read_function(stream, opj_read); + opj_stream_set_write_function(stream, opj_write); + opj_stream_set_skip_function(stream, opj_skip); + opj_stream_set_seek_function(stream, opj_seek); + + OPJ_BOOL started = opj_start_compress(encoder, image, stream); + + if (!started) + { + return false; + } + + if (!opj_encode(encoder, stream)) + { + return false; + } + + OPJ_BOOL encoded = opj_end_compress(encoder, stream); + + // if we successfully encoded, then stream out the compressed data... + if (encoded) + { + // "append" (set) the data we "streamed" (memcopied) for writing to the formatted image + // with side-effect of setting the actually encoded size to same + compressedImageOut.allocateData(offset); + memcpy(compressedImageOut.getData(), buffer, offset); + compressedImageOut.updateData(); // update width, height etc from header + } + return encoded; + } + + void setImage(const LLImageRaw& raw) + { + opj_image_cmptparm_t cmptparm[MAX_ENCODED_DISCARD_LEVELS]; + memset(&cmptparm[0], 0, MAX_ENCODED_DISCARD_LEVELS * sizeof(opj_image_cmptparm_t)); + + S32 numcomps = raw.getComponents(); + S32 width = raw.getWidth(); + S32 height = raw.getHeight(); + + for (S32 c = 0; c < numcomps; c++) + { + cmptparm[c].prec = 8; + cmptparm[c].bpp = 8; + cmptparm[c].sgnd = 0; + cmptparm[c].dx = parameters.subsampling_dx; + cmptparm[c].dy = parameters.subsampling_dy; + cmptparm[c].w = width; + cmptparm[c].h = height; + } + + image = opj_image_create(numcomps, &cmptparm[0], OPJ_CLRSPC_SRGB); + + image->x1 = width; + image->y1 = height; + + const U8 *src_datap = raw.getData(); + + S32 i = 0; + for (S32 y = height - 1; y >= 0; y--) + { + for (S32 x = 0; x < width; x++) + { + const U8 *pixel = src_datap + (y*width + x) * numcomps; + for (S32 c = 0; c < numcomps; c++) + { + image->comps[c].data[i] = *pixel; + pixel++; + } + i++; + } + } + + // This likely works, but there seems to be an issue openjpeg side + // check over after gixing that. + + // De-interleave to component plane data + /* + switch (numcomps) + { + case 0: + default: + break; + + case 1: + { + U32 rBitDepth = image->comps[0].bpp; + U32 bytesPerPixel = rBitDepth >> 3; + memcpy(image->comps[0].data, src, width * height * bytesPerPixel); + } + break; + + case 2: + { + U32 rBitDepth = image->comps[0].bpp; + U32 gBitDepth = image->comps[1].bpp; + U32 totalBitDepth = rBitDepth + gBitDepth; + U32 bytesPerPixel = totalBitDepth >> 3; + U32 stride = width * bytesPerPixel; + U32 offset = 0; + for (S32 y = height - 1; y >= 0; y--) + { + const U8* component = src + (y * stride); + for (S32 x = 0; x < width; x++) + { + image->comps[0].data[offset] = *component++; + image->comps[1].data[offset] = *component++; + offset++; + } + } + } + break; + + case 3: + { + U32 rBitDepth = image->comps[0].bpp; + U32 gBitDepth = image->comps[1].bpp; + U32 bBitDepth = image->comps[2].bpp; + U32 totalBitDepth = rBitDepth + gBitDepth + bBitDepth; + U32 bytesPerPixel = totalBitDepth >> 3; + U32 stride = width * bytesPerPixel; + U32 offset = 0; + for (S32 y = height - 1; y >= 0; y--) + { + const U8* component = src + (y * stride); + for (S32 x = 0; x < width; x++) + { + image->comps[0].data[offset] = *component++; + image->comps[1].data[offset] = *component++; + image->comps[2].data[offset] = *component++; + offset++; + } + } + } + break; + + + case 4: + { + U32 rBitDepth = image->comps[0].bpp; + U32 gBitDepth = image->comps[1].bpp; + U32 bBitDepth = image->comps[2].bpp; + U32 aBitDepth = image->comps[3].bpp; + + U32 totalBitDepth = rBitDepth + gBitDepth + bBitDepth + aBitDepth; + U32 bytesPerPixel = totalBitDepth >> 3; + + U32 stride = width * bytesPerPixel; + U32 offset = 0; + for (S32 y = height - 1; y >= 0; y--) + { + const U8* component = src + (y * stride); + for (S32 x = 0; x < width; x++) + { + image->comps[0].data[offset] = *component++; + image->comps[1].data[offset] = *component++; + image->comps[2].data[offset] = *component++; + image->comps[3].data[offset] = *component++; + offset++; + } + } + } + break; + }*/ + } + + opj_image_t* getImage() { return image; } + +private: + opj_cparameters_t parameters; + opj_event_mgr_t event_mgr; + opj_image_t* image = nullptr; + opj_codec_t* encoder = nullptr; + opj_stream_t* stream = nullptr; + char* comment_text = nullptr; +}; - /* catch events using our callbacks and give a local context */ - opj_set_event_mgr((opj_common_ptr)dinfo, &event_mgr, stderr); - /* setup the decoder decoding parameters using user parameters */ - opj_setup_decoder(dinfo, ¶meters); +LLImageJ2COJ::LLImageJ2COJ() + : LLImageJ2CImpl() +{ +} - /* open a byte stream */ - cio = opj_cio_open((opj_common_ptr)dinfo, base.getData(), base.getDataSize()); - /* decode the stream and fill the image structure */ - image = opj_decode(dinfo, cio); +LLImageJ2COJ::~LLImageJ2COJ() +{ +} - /* close the byte stream */ - opj_cio_close(cio); +bool LLImageJ2COJ::initDecode(LLImageJ2C &base, LLImageRaw &raw_image, int discard_level, int* region) +{ + base.mDiscardLevel = discard_level; + return false; +} - /* free remaining structures */ - if(dinfo) - { - opj_destroy_decompress(dinfo); - } +bool LLImageJ2COJ::initEncode(LLImageJ2C &base, LLImageRaw &raw_image, int blocks_size, int precincts_size, int levels) +{ + // No specific implementation for this method in the OpenJpeg case + return false; +} - if(!image) - { - LL_WARNS() << "ERROR -> getMetadata: failed to decode image!" << LL_ENDL; - return false; - } +bool LLImageJ2COJ::decodeImpl(LLImageJ2C &base, LLImageRaw &raw_image, F32 decode_time, S32 first_channel, S32 max_channel_count) +{ + JPEG2KDecode decoder(0); + + U32 image_channels = 0; + S32 data_size = base.getDataSize(); + S32 max_bytes = (base.getMaxBytes() ? base.getMaxBytes() : data_size); + bool decoded = decoder.decode(base.getData(), max_bytes, &image_channels, base.mDiscardLevel); + + // set correct channel count early so failed decodes don't miss it... + S32 channels = (S32)image_channels - first_channel; + channels = llmin(channels, max_channel_count); + + if (!decoded) + { + // reset the channel count if necessary + if (raw_image.getComponents() != channels) + { + raw_image.resize(raw_image.getWidth(), raw_image.getHeight(), S8(channels)); + } + + LL_DEBUGS("Texture") << "ERROR -> decodeImpl: failed to decode image!" << LL_ENDL; + return true; // done + } + + opj_image_t *image = decoder.getImage(); + + // Component buffers are allocated in an image width by height buffer. + // The image placed in that buffer is ceil(width/2^factor) by + // ceil(height/2^factor) and if the factor isn't zero it will be at the + // top left of the buffer with black filled in the rest of the pixels. + // It is integer math so the formula is written in ceildivpo2. + // (Assuming all the components have the same width, height and + // factor.) + U32 comp_width = image->comps[0].w; // leave this unshifted by 'f' discard factor, the strides are always for the full buffer width + U32 f = image->comps[0].factor; + + // do size the texture to the mem we'll acrually use... + U32 width = image->comps[0].w; + U32 height = image->comps[0].h; + + raw_image.resize(U16(width), U16(height), S8(channels)); + + U8 *rawp = raw_image.getData(); + + // first_channel is what channel to start copying from + // dest is what channel to copy to. first_channel comes from the + // argument, dest always starts writing at channel zero. + for (S32 comp = first_channel, dest = 0; comp < first_channel + channels; comp++, dest++) + { + llassert(image->comps[comp].data); + if (image->comps[comp].data) + { + S32 offset = dest; + for (S32 y = (height - 1); y >= 0; y--) + { + for (S32 x = 0; x < width; x++) + { + rawp[offset] = image->comps[comp].data[y*comp_width + x]; + offset += channels; + } + } + } + else // Some rare OpenJPEG versions have this bug. + { + LL_DEBUGS("Texture") << "ERROR -> decodeImpl: failed! (OpenJPEG bug)" << LL_ENDL; + } + } + + base.setDiscardLevel(f); + + return true; // done +} - // Copy image data into our raw image format (instead of the separate channel format - S32 width = 0; - S32 height = 0; - S32 img_components = image->numcomps; - width = image->x1 - image->x0; - height = image->y1 - image->y0; - base.setSize(width, height, img_components); +bool LLImageJ2COJ::encodeImpl(LLImageJ2C &base, const LLImageRaw &raw_image, const char* comment_text, F32 encode_time, bool reversible) +{ + JPEG2KEncode encode(comment_text, reversible); + bool encoded = encode.encode(raw_image, base); + if (encoded) + { + LL_WARNS() << "Openjpeg encoding implementation isn't complete, returning false" << LL_ENDL; + } + return encoded; + //return false; +} - /* free image data structure */ - opj_image_destroy(image); - return true; +bool LLImageJ2COJ::getMetadata(LLImageJ2C &base) +{ + JPEG2KDecode decode(0); + + S32 width = 0; + S32 height = 0; + S32 components = 0; + S32 discard_level = 0; + + U32 dataSize = base.getDataSize(); + U8* data = base.getData(); + bool header_read = decode.readHeader(data, dataSize, width, height, components, discard_level); + if (!header_read) + { + return false; + } + + base.mDiscardLevel = discard_level; + base.setSize(width, height, components); + return true; } diff --git a/indra/llinventory/CMakeLists.txt b/indra/llinventory/CMakeLists.txt index 04975940aa..93a586759f 100644 --- a/indra/llinventory/CMakeLists.txt +++ b/indra/llinventory/CMakeLists.txt @@ -5,17 +5,6 @@ project(llinventory) include(00-Common) include(LLCommon) include(LLCoreHttp) -include(LLMath) -include(LLMessage) -include(LLFileSystem) -include(LLXML) - -include_directories( - ${LLCOMMON_INCLUDE_DIRS} - ${LLMATH_INCLUDE_DIRS} - ${LLMESSAGE_INCLUDE_DIRS} - ${LLXML_INCLUDE_DIRS} - ) set(llinventory_SOURCE_FILES llcategory.cpp @@ -63,14 +52,12 @@ set(llinventory_HEADER_FILES lluserrelations.h ) -set_source_files_properties(${llinventory_HEADER_FILES} - PROPERTIES HEADER_FILE_ONLY TRUE) - list(APPEND llinventory_SOURCE_FILES ${llinventory_HEADER_FILES}) add_library (llinventory ${llinventory_SOURCE_FILES}) - +target_link_libraries( llinventory llcommon llmath llmessage llxml ) +target_include_directories( llinventory INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}) #add unit tests if (LL_TESTS) @@ -81,7 +68,7 @@ if (LL_TESTS) LL_ADD_PROJECT_UNIT_TESTS(llinventory "${llinventory_TEST_SOURCE_FILES}") #set(TEST_DEBUG on) - set(test_libs llinventory ${LLMESSAGE_LIBRARIES} ${LLFILESYSTEM_LIBRARIES} ${LLCOREHTTP_LIBRARIES} ${LLMATH_LIBRARIES} ${LLCOMMON_LIBRARIES} ${WINDOWS_LIBRARIES}) + set(test_libs llinventory llmath llcorehttp llfilesystem ) LL_ADD_INTEGRATION_TEST(inventorymisc "" "${test_libs}") LL_ADD_INTEGRATION_TEST(llparcel "" "${test_libs}") endif (LL_TESTS) diff --git a/indra/llinventory/llparcel.cpp b/indra/llinventory/llparcel.cpp index 134e783053..bba2e2505d 100644 --- a/indra/llinventory/llparcel.cpp +++ b/indra/llinventory/llparcel.cpp @@ -1271,5 +1271,5 @@ U32 LLParcel::countExperienceKeyType( U32 type ) return std::count_if( boost::begin(mExperienceKeys | boost::adaptors::map_values), boost::end(mExperienceKeys | boost::adaptors::map_values), - std::bind2nd(std::equal_to<U32>(), type)); + [type](U32 key){ return (key == type); }); } diff --git a/indra/llkdu/CMakeLists.txt b/indra/llkdu/CMakeLists.txt index cb0e204e91..7cd9f5eb24 100644 --- a/indra/llkdu/CMakeLists.txt +++ b/indra/llkdu/CMakeLists.txt @@ -13,15 +13,6 @@ include(00-Common) include(LLCommon) include(LLImage) include(LLKDU) -include(LLMath) - -include_directories( - ${LLCOMMON_INCLUDE_DIRS} - ${LLIMAGE_INCLUDE_DIRS} - ${KDU_INCLUDE_DIR} - ${LLKDU_INCLUDE_DIRS} - ${LLMATH_INCLUDE_DIRS} - ) set(llkdu_SOURCE_FILES llimagej2ckdu.cpp @@ -30,14 +21,10 @@ set(llkdu_SOURCE_FILES set(llkdu_HEADER_FILES CMakeLists.txt - llimagej2ckdu.h llkdumem.h ) -set_source_files_properties(${llkdu_HEADER_FILES} - PROPERTIES HEADER_FILE_ONLY TRUE) - list(APPEND llkdu_SOURCE_FILES ${llkdu_HEADER_FILES}) # Our KDU package is built with KDU_X86_INTRINSICS in its .vcxproj file. @@ -51,11 +38,14 @@ set_source_files_properties(${llkdu_SOURCE_FILES} if (USE_KDU) add_library (llkdu ${llkdu_SOURCE_FILES}) - target_link_libraries(llkdu - ${KDU_LIBRARY}) - + target_link_libraries(llkdu ll::kdu llimage llcommon) + target_include_directories( llkdu INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}) + # Add tests - if (LL_TESTS) + # ND: llkdu tests are very strange as they include stubs for KDU classes/methods + # if not having access to the right KDU version this test will fail to compile, incidentally I do not + # have access to a matching version of KDU and thus cannot get this tests to compile + if (LL_TESTS_KDU) include(LLAddBuildTest) include(Tut) SET(llkdu_TEST_SOURCE_FILES @@ -66,11 +56,12 @@ if (USE_KDU) llkdumem.h lltut.h ) - SET(llkdu_test_additional_INCLUDE_DIRS - ${KDU_INCLUDE_DIR} - ${LLKDU_INCLUDE_DIRS} - ) + + get_property( llimage_include_dir TARGET llimage PROPERTY INTERFACE_INCLUDE_DIRECTORIES ) + set_property( SOURCE ${llkdu_TEST_SOURCE_FILES} PROPERTY LL_TEST_ADDITIONAL_LIBRARIES ll::kdu llcommon) + set_property( SOURCE ${llkdu_TEST_SOURCE_FILES} PROPERTY LL_TEST_ADDITIONAL_INCLUDE_DIRS ${llimage_include_dir}) + LL_ADD_PROJECT_UNIT_TESTS(llkdu "${llkdu_TEST_SOURCE_FILES}") - endif (LL_TESTS) + endif (LL_TESTS_KDU) endif (USE_KDU) diff --git a/indra/llmath/CMakeLists.txt b/indra/llmath/CMakeLists.txt index 4617309606..eb29df245a 100644 --- a/indra/llmath/CMakeLists.txt +++ b/indra/llmath/CMakeLists.txt @@ -4,16 +4,9 @@ project(llmath) include(00-Common) include(LLCommon) -include(LLMeshOptimizer) include(bugsplat) include(Boost) -include_directories( - ${LLCOMMON_INCLUDE_DIRS} - ${LLCOMMON_SYSTEM_INCLUDE_DIRS} - ${LLMESHOPTIMIZER_INCLUDE_DIRS} - ) - set(llmath_SOURCE_FILES llbbox.cpp llbboxlocal.cpp @@ -102,17 +95,12 @@ set(llmath_HEADER_FILES xform.h ) -set_source_files_properties(${llmath_HEADER_FILES} - PROPERTIES HEADER_FILE_ONLY TRUE) - list(APPEND llmath_SOURCE_FILES ${llmath_HEADER_FILES}) add_library (llmath ${llmath_SOURCE_FILES}) -target_link_libraries(llmath - ${LLCOMMON_LIBRARIES} - ${LLMESHOPTIMIZER_LIBRARIES} - ) +target_link_libraries(llmath llcommon llmeshoptimizer) +target_include_directories( llmath INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}) # Add tests if (LL_TESTS) @@ -127,15 +115,11 @@ if (LL_TESTS) v4color.cpp v4coloru.cpp ) - set_source_files_properties( - ${llmath_TEST_SOURCE_FILES} - PROPERTIES - LL_TEST_ADDITIONAL_LIBRARIES "${BOOST_THREAD_LIBRARY}" - ) + LL_ADD_PROJECT_UNIT_TESTS(llmath "${llmath_TEST_SOURCE_FILES}") # INTEGRATION TESTS - set(test_libs llmath llcommon ${LLCOMMON_LIBRARIES} ${WINDOWS_LIBRARIES}) + set(test_libs llmath llcommon) # TODO: Some of these need refactoring to be proper Unit tests rather than Integration tests. LL_ADD_INTEGRATION_TEST(alignment "" "${test_libs}") LL_ADD_INTEGRATION_TEST(llbbox llbbox.cpp "${test_libs}") diff --git a/indra/llmath/llcalcparser.h b/indra/llmath/llcalcparser.h index e2388d6702..dff5bf3af3 100644 --- a/indra/llmath/llcalcparser.h +++ b/indra/llmath/llcalcparser.h @@ -81,28 +81,28 @@ struct LLCalcParser : grammar<LLCalcParser> ; unary_func = - ((str_p("SIN") >> '(' >> expression[unary_func.value = bind(&LLCalcParser::_sin)(self,arg1)]) | - (str_p("COS") >> '(' >> expression[unary_func.value = bind(&LLCalcParser::_cos)(self,arg1)]) | - (str_p("TAN") >> '(' >> expression[unary_func.value = bind(&LLCalcParser::_tan)(self,arg1)]) | - (str_p("ASIN") >> '(' >> expression[unary_func.value = bind(&LLCalcParser::_asin)(self,arg1)]) | - (str_p("ACOS") >> '(' >> expression[unary_func.value = bind(&LLCalcParser::_acos)(self,arg1)]) | - (str_p("ATAN") >> '(' >> expression[unary_func.value = bind(&LLCalcParser::_atan)(self,arg1)]) | - (str_p("SQRT") >> '(' >> expression[unary_func.value = bind(&LLCalcParser::_sqrt)(self,arg1)]) | - (str_p("LOG") >> '(' >> expression[unary_func.value = bind(&LLCalcParser::_log)(self,arg1)]) | - (str_p("EXP") >> '(' >> expression[unary_func.value = bind(&LLCalcParser::_exp)(self,arg1)]) | - (str_p("ABS") >> '(' >> expression[unary_func.value = bind(&LLCalcParser::_fabs)(self,arg1)]) | - (str_p("FLR") >> '(' >> expression[unary_func.value = bind(&LLCalcParser::_floor)(self,arg1)]) | - (str_p("CEIL") >> '(' >> expression[unary_func.value = bind(&LLCalcParser::_ceil)(self,arg1)]) + ((str_p("SIN") >> '(' >> expression[unary_func.value = phoenix::bind(&LLCalcParser::_sin)(self,arg1)]) | + (str_p("COS") >> '(' >> expression[unary_func.value = phoenix::bind(&LLCalcParser::_cos)(self,arg1)]) | + (str_p("TAN") >> '(' >> expression[unary_func.value = phoenix::bind(&LLCalcParser::_tan)(self,arg1)]) | + (str_p("ASIN") >> '(' >> expression[unary_func.value = phoenix::bind(&LLCalcParser::_asin)(self,arg1)]) | + (str_p("ACOS") >> '(' >> expression[unary_func.value = phoenix::bind(&LLCalcParser::_acos)(self,arg1)]) | + (str_p("ATAN") >> '(' >> expression[unary_func.value = phoenix::bind(&LLCalcParser::_atan)(self,arg1)]) | + (str_p("SQRT") >> '(' >> expression[unary_func.value = phoenix::bind(&LLCalcParser::_sqrt)(self,arg1)]) | + (str_p("LOG") >> '(' >> expression[unary_func.value = phoenix::bind(&LLCalcParser::_log)(self,arg1)]) | + (str_p("EXP") >> '(' >> expression[unary_func.value = phoenix::bind(&LLCalcParser::_exp)(self,arg1)]) | + (str_p("ABS") >> '(' >> expression[unary_func.value = phoenix::bind(&LLCalcParser::_fabs)(self,arg1)]) | + (str_p("FLR") >> '(' >> expression[unary_func.value = phoenix::bind(&LLCalcParser::_floor)(self,arg1)]) | + (str_p("CEIL") >> '(' >> expression[unary_func.value = phoenix::bind(&LLCalcParser::_ceil)(self,arg1)]) ) >> assert_syntax(ch_p(')')) ; binary_func = ((str_p("ATAN2") >> '(' >> expression[binary_func.value = arg1] >> ',' >> - expression[binary_func.value = bind(&LLCalcParser::_atan2)(self, binary_func.value, arg1)]) | + expression[binary_func.value = phoenix::bind(&LLCalcParser::_atan2)(self, binary_func.value, arg1)]) | (str_p("MIN") >> '(' >> expression[binary_func.value = arg1] >> ',' >> - expression[binary_func.value = bind(&LLCalcParser::_min)(self, binary_func.value, arg1)]) | + expression[binary_func.value = phoenix::bind(&LLCalcParser::_min)(self, binary_func.value, arg1)]) | (str_p("MAX") >> '(' >> expression[binary_func.value = arg1] >> ',' >> - expression[binary_func.value = bind(&LLCalcParser::_max)(self, binary_func.value, arg1)]) + expression[binary_func.value = phoenix::bind(&LLCalcParser::_max)(self, binary_func.value, arg1)]) ) >> assert_syntax(ch_p(')')) ; @@ -118,10 +118,10 @@ struct LLCalcParser : grammar<LLCalcParser> // Lookup throws an Unknown Symbol error if it is unknown, while this works fine, // would be "neater" to handle symbol lookup from here with an assertive parser. // constants_p[factor.value = arg1]| - identifier[factor.value = bind(&LLCalcParser::lookup)(self, arg1, arg2)] + identifier[factor.value = phoenix::bind(&LLCalcParser::lookup)(self, arg1, arg2)] ) >> // Detect and throw math errors. - assert_domain(eps_p(bind(&LLCalcParser::checkNaN)(self, factor.value))) + assert_domain(eps_p(phoenix::bind(&LLCalcParser::checkNaN)(self, factor.value))) ; unary_expr = @@ -131,14 +131,14 @@ struct LLCalcParser : grammar<LLCalcParser> power = unary_expr[power.value = arg1] >> - *('^' >> assert_syntax(unary_expr[power.value = bind(&powf)(power.value, arg1)])) + *('^' >> assert_syntax(unary_expr[power.value = phoenix::bind(&powf)(power.value, arg1)])) ; term = power[term.value = arg1] >> *(('*' >> assert_syntax(power[term.value *= arg1])) | ('/' >> assert_syntax(power[term.value /= arg1])) | - ('%' >> assert_syntax(power[term.value = bind(&fmodf)(term.value, arg1)])) + ('%' >> assert_syntax(power[term.value = phoenix::bind(&fmodf)(term.value, arg1)])) ) ; diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp index ed5334d31b..40f7b1e9fb 100644 --- a/indra/llmath/llvolume.cpp +++ b/indra/llmath/llvolume.cpp @@ -2386,7 +2386,25 @@ bool LLVolume::unpackVolumeFaces(std::istream& is, S32 size) LL_DEBUGS("MeshStreaming") << "Failed to unzip LLSD blob for LoD with code " << uzip_result << " , will probably fetch from sim again." << LL_ENDL; return false; } - + return unpackVolumeFacesInternal(mdl); +} + +bool LLVolume::unpackVolumeFaces(U8* in_data, S32 size) +{ + //input data is now pointing at a zlib compressed block of LLSD + //decompress block + LLSD mdl; + U32 uzip_result = LLUZipHelper::unzip_llsd(mdl, in_data, size); + if (uzip_result != LLUZipHelper::ZR_OK) + { + LL_DEBUGS("MeshStreaming") << "Failed to unzip LLSD blob for LoD with code " << uzip_result << " , will probably fetch from sim again." << LL_ENDL; + return false; + } + return unpackVolumeFacesInternal(mdl); +} + +bool LLVolume::unpackVolumeFacesInternal(const LLSD& mdl) +{ { U32 face_count = mdl.size(); diff --git a/indra/llmath/llvolume.h b/indra/llmath/llvolume.h index 3ccaed47f1..1509241623 100644 --- a/indra/llmath/llvolume.h +++ b/indra/llmath/llvolume.h @@ -1101,8 +1101,12 @@ protected: BOOL generate(); void createVolumeFaces(); public: - virtual bool unpackVolumeFaces(std::istream& is, S32 size); + bool unpackVolumeFaces(std::istream& is, S32 size); + bool unpackVolumeFaces(U8* in_data, S32 size); +private: + bool unpackVolumeFacesInternal(const LLSD& mdl); +public: virtual void setMeshAssetLoaded(BOOL loaded); virtual BOOL isMeshAssetLoaded(); diff --git a/indra/llmeshoptimizer/CMakeLists.txt b/indra/llmeshoptimizer/CMakeLists.txt index 016794cfad..dfac44c296 100644 --- a/indra/llmeshoptimizer/CMakeLists.txt +++ b/indra/llmeshoptimizer/CMakeLists.txt @@ -2,43 +2,33 @@ project(llmeshoptimizer) -include(MESHOPTIMIZER) +include(Meshoptimizer) include(00-Common) include(LLCommon) include(LLMath) -include_directories( - ${LLCOMMON_INCLUDE_DIRS} - ${LLMATH_INCLUDE_DIRS} - ${LLMESHOPTIMIZER_INCLUDE_DIR} - ${MESHOPTIMIZER_INCLUDE_DIRS} - ${LIBS_PREBUILT_DIR}/include #access to boost headers, needed for LLError - ) - set(llmeshoptimizer_SOURCE_FILES - llmeshoptimizer.cpp - ) + llmeshoptimizer.cpp + ) set(llmeshoptimizer_HEADER_FILES - CMakeLists.txt - - llmeshoptimizer.h - ) + CMakeLists.txt + llmeshoptimizer.h + ) set_source_files_properties(${llmeshoptimizer_HEADER_FILES} - PROPERTIES HEADER_FILE_ONLY TRUE) + PROPERTIES HEADER_FILE_ONLY TRUE) list(APPEND llmeshoptimizer_SOURCE_FILES ${llmeshoptimizer_HEADER_FILES}) -#if (USE_MESHOPT) - add_library (llmeshoptimizer ${llmeshoptimizer_SOURCE_FILES}) +add_library (llmeshoptimizer ${llmeshoptimizer_SOURCE_FILES}) +target_include_directories( llmeshoptimizer INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}) + +target_link_libraries(llmeshoptimizer + llcommon + llmath + ll::meshoptimizer) - target_link_libraries(llmeshoptimizer - ${LLCOMMON_LIBRARIES} - ${LLMATH_LIBRARIES} - ${MESHOPTIMIZER_LIBRARIES}) - - # Add tests +# Add tests -#endif (USE_MESHOPT) diff --git a/indra/llmessage/CMakeLists.txt b/indra/llmessage/CMakeLists.txt index f0a1dfe940..4786956e85 100644 --- a/indra/llmessage/CMakeLists.txt +++ b/indra/llmessage/CMakeLists.txt @@ -7,26 +7,12 @@ include(GoogleMock) include(LLAddBuildTest) include(LLCommon) include(LLCoreHttp) -include(LLMath) -include(LLMessage) -include(LLFileSystem) include(LLAddBuildTest) include(Python) include(Tut) include(Python) include(JsonCpp) -include_directories (${CMAKE_CURRENT_SOURCE_DIR}) - -include_directories( - ${LLCOMMON_INCLUDE_DIRS} - ${LLCOREHTTP_INCLUDE_DIRS} - ${LLMATH_INCLUDE_DIRS} - ${LLMESSAGE_INCLUDE_DIRS} - ${LLFILESYSTEM_INCLUDE_DIRS} - ${JSONCPP_INCLUDE_DIR} - ) - set(llmessage_SOURCE_FILES llassetstorage.cpp llavatarname.cpp @@ -197,49 +183,19 @@ set(llmessage_HEADER_FILES sound_ids.h ) -set_source_files_properties(${llmessage_HEADER_FILES} - PROPERTIES HEADER_FILE_ONLY TRUE) - list(APPEND llmessage_SOURCE_FILES ${llmessage_HEADER_FILES}) add_library (llmessage ${llmessage_SOURCE_FILES}) -if (LINUX) -target_link_libraries( - llmessage - ${CURL_LIBRARIES} - ${LLCOMMON_LIBRARIES} - ${LLFILESYSTEM_LIBRARIES} - ${LLMATH_LIBRARIES} - ${JSONCPP_LIBRARIES} - ${OPENSSL_LIBRARIES} - ${CRYPTO_LIBRARIES} - ${NGHTTP2_LIBRARIES} - ${XMLRPCEPI_LIBRARIES} - ${LLCOREHTTP_LIBRARIES} - ${BOOST_FIBER_LIBRARY} - ${BOOST_CONTEXT_LIBRARY} - ${BOOST_SYSTEM_LIBRARY} - rt - ) -else (LINUX) target_link_libraries( - llmessage - ${CURL_LIBRARIES} - ${LLCOMMON_LIBRARIES} - ${LLFILESYSTEM_LIBRARIES} - ${LLMATH_LIBRARIES} - ${JSONCPP_LIBRARIES} - ${OPENSSL_LIBRARIES} - ${CRYPTO_LIBRARIES} - ${NGHTTP2_LIBRARIES} - ${XMLRPCEPI_LIBRARIES} - ${LLCOREHTTP_LIBRARIES} - ${BOOST_FIBER_LIBRARY} - ${BOOST_CONTEXT_LIBRARY} - ${BOOST_SYSTEM_LIBRARY} - ) -endif(LINUX) + llmessage + llcommon + llfilesystem + llmath + llcorehttp + ll::xmlrpc-epi +) +target_include_directories( llmessage INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}) # tests if (LL_TESTS) @@ -249,43 +205,18 @@ if (LL_TESTS) lltrustedmessageservice.cpp lltemplatemessagedispatcher.cpp ) + set_property( SOURCE ${llmessage_TEST_SOURCE_FILES} PROPERTY LL_TEST_ADDITIONAL_LIBRARIES llmath llcorehttp) LL_ADD_PROJECT_UNIT_TESTS(llmessage "${llmessage_TEST_SOURCE_FILES}") - # set(TEST_DEBUG on) - -if (LINUX) - set(test_libs - ${WINDOWS_LIBRARIES} - ${LLFILESYSTEM_LIBRARIES} - ${LLMATH_LIBRARIES} - ${CURL_LIBRARIES} - ${NGHTTP2_LIBRARIES} - ${LLCOMMON_LIBRARIES} - ${LLMESSAGE_LIBRARIES} - ${LLCOREHTTP_LIBRARIES} - ${JSONCPP_LIBRARIES} - ${BOOST_FIBER_LIBRARY} - ${BOOST_CONTEXT_LIBRARY} - rt - ${GOOGLEMOCK_LIBRARIES} - ) -else (LINUX) + set(test_libs - ${WINDOWS_LIBRARIES} - ${LLFILESYSTEM_LIBRARIES} - ${LLMATH_LIBRARIES} - ${CURL_LIBRARIES} - ${NGHTTP2_LIBRARIES} - ${LLCOMMON_LIBRARIES} - ${LLMESSAGE_LIBRARIES} - ${LLCOREHTTP_LIBRARIES} - ${JSONCPP_LIBRARIES} - ${BOOST_FIBER_LIBRARY} - ${BOOST_CONTEXT_LIBRARY} - ${GOOGLEMOCK_LIBRARIES} - ) -endif(LINUX) + llfilesystem + llmath + llcorehttp + llmessage + llcommon + ) #LL_ADD_INTEGRATION_TEST(llavatarnamecache "" "${test_libs}") LL_ADD_INTEGRATION_TEST(llhost "" "${test_libs}") diff --git a/indra/llmessage/llcorehttputil.cpp b/indra/llmessage/llcorehttputil.cpp index 7031f1aa8c..c8c9280029 100644 --- a/indra/llmessage/llcorehttputil.cpp +++ b/indra/llmessage/llcorehttputil.cpp @@ -35,8 +35,8 @@ #include "llsd.h" #include "llsdjson.h" #include "llsdserialize.h" -#include "reader.h" // JSON -#include "writer.h" // JSON +#include "json/reader.h" // JSON +#include "json/writer.h" // JSON #include "llfilesystem.h" #include "message.h" // for getting the port diff --git a/indra/llmessage/lldatapacker.cpp b/indra/llmessage/lldatapacker.cpp index b6adc102d2..9f7768f78e 100644 --- a/indra/llmessage/lldatapacker.cpp +++ b/indra/llmessage/lldatapacker.cpp @@ -116,9 +116,8 @@ BOOL LLDataPacker::packFixed(const F32 value, const char *name, BOOL LLDataPacker::unpackFixed(F32 &value, const char *name, const BOOL is_signed, const U32 int_bits, const U32 frac_bits) { - //BOOL success = TRUE; + BOOL success = TRUE; //LL_INFOS() << "unpackFixed:" << name << " int:" << int_bits << " frac:" << frac_bits << LL_ENDL; - BOOL ok = FALSE; S32 unsigned_bits = int_bits + frac_bits; S32 total_bits = unsigned_bits; @@ -134,19 +133,19 @@ BOOL LLDataPacker::unpackFixed(F32 &value, const char *name, if (total_bits <= 8) { U8 fixed_8; - ok = unpackU8(fixed_8, name); + success = unpackU8(fixed_8, name); fixed_val = (F32)fixed_8; } else if (total_bits <= 16) { U16 fixed_16; - ok = unpackU16(fixed_16, name); + success = unpackU16(fixed_16, name); fixed_val = (F32)fixed_16; } else if (total_bits <= 31) { U32 fixed_32; - ok = unpackU32(fixed_32, name); + success = unpackU32(fixed_32, name); fixed_val = (F32)fixed_32; } else @@ -164,7 +163,7 @@ BOOL LLDataPacker::unpackFixed(F32 &value, const char *name, } value = fixed_val; //LL_INFOS() << "Value: " << value << LL_ENDL; - return ok; + return success; } BOOL LLDataPacker::unpackU16s(U16 *values, S32 count, const char *name) @@ -238,37 +237,43 @@ BOOL LLDataPacker::unpackUUIDs(LLUUID *values, S32 count, const char *name) BOOL LLDataPackerBinaryBuffer::packString(const std::string& value, const char *name) { - BOOL success = TRUE; S32 length = value.length()+1; - success &= verifyLength(length, name); + if (!verifyLength(length, name)) + { + return FALSE; + } if (mWriteEnabled) { htolememcpy(mCurBufferp, value.c_str(), MVT_VARIABLE, length); } mCurBufferp += length; - return success; + return TRUE; } BOOL LLDataPackerBinaryBuffer::unpackString(std::string& value, const char *name) { - BOOL success = TRUE; S32 length = (S32)strlen((char *)mCurBufferp) + 1; /*Flawfinder: ignore*/ - success &= verifyLength(length, name); + if (!verifyLength(length, name)) + { + return FALSE; + } value = std::string((char*)mCurBufferp); // We already assume NULL termination calling strlen() mCurBufferp += length; - return success; + return TRUE; } BOOL LLDataPackerBinaryBuffer::packBinaryData(const U8 *value, S32 size, const char *name) { - BOOL success = TRUE; - success &= verifyLength(size + 4, name); + if (!verifyLength(size + 4, name)) + { + return FALSE; + } if (mWriteEnabled) { @@ -280,102 +285,117 @@ BOOL LLDataPackerBinaryBuffer::packBinaryData(const U8 *value, S32 size, const c htolememcpy(mCurBufferp, value, MVT_VARIABLE, size); } mCurBufferp += size; - return success; + return TRUE; } BOOL LLDataPackerBinaryBuffer::unpackBinaryData(U8 *value, S32 &size, const char *name) { - BOOL success = TRUE; - success &= verifyLength(4, name); - htolememcpy(&size, mCurBufferp, MVT_S32, 4); - mCurBufferp += 4; - success &= verifyLength(size, name); - if (success) + if (!verifyLength(4, name)) { - htolememcpy(value, mCurBufferp, MVT_VARIABLE, size); - mCurBufferp += size; + LL_WARNS() << "LLDataPackerBinaryBuffer::unpackBinaryData would unpack invalid data, aborting!" << LL_ENDL; + return FALSE; } - else + + htolememcpy(&size, mCurBufferp, MVT_S32, 4); + mCurBufferp += 4; + + if (!verifyLength(size, name)) { LL_WARNS() << "LLDataPackerBinaryBuffer::unpackBinaryData would unpack invalid data, aborting!" << LL_ENDL; - success = FALSE; + return FALSE; } - return success; + + htolememcpy(value, mCurBufferp, MVT_VARIABLE, size); + mCurBufferp += size; + + return TRUE; } BOOL LLDataPackerBinaryBuffer::packBinaryDataFixed(const U8 *value, S32 size, const char *name) { - BOOL success = TRUE; - success &= verifyLength(size, name); + if (!verifyLength(size, name)) + { + return FALSE; + } if (mWriteEnabled) { htolememcpy(mCurBufferp, value, MVT_VARIABLE, size); } mCurBufferp += size; - return success; + return TRUE; } BOOL LLDataPackerBinaryBuffer::unpackBinaryDataFixed(U8 *value, S32 size, const char *name) { - BOOL success = TRUE; - success &= verifyLength(size, name); + if (!verifyLength(size, name)) + { + return FALSE; + } htolememcpy(value, mCurBufferp, MVT_VARIABLE, size); mCurBufferp += size; - return success; + return TRUE; } BOOL LLDataPackerBinaryBuffer::packU8(const U8 value, const char *name) { - BOOL success = TRUE; - success &= verifyLength(sizeof(U8), name); + if (!verifyLength(sizeof(U8), name)) + { + return FALSE; + } if (mWriteEnabled) { *mCurBufferp = value; } mCurBufferp++; - return success; + return TRUE; } BOOL LLDataPackerBinaryBuffer::unpackU8(U8 &value, const char *name) { - BOOL success = TRUE; - success &= verifyLength(sizeof(U8), name); + if (!verifyLength(sizeof(U8), name)) + { + return FALSE; + } value = *mCurBufferp; mCurBufferp++; - return success; + return TRUE; } BOOL LLDataPackerBinaryBuffer::packU16(const U16 value, const char *name) { - BOOL success = TRUE; - success &= verifyLength(sizeof(U16), name); + if (!verifyLength(sizeof(U16), name)) + { + return FALSE; + } if (mWriteEnabled) { htolememcpy(mCurBufferp, &value, MVT_U16, 2); } mCurBufferp += 2; - return success; + return TRUE; } BOOL LLDataPackerBinaryBuffer::unpackU16(U16 &value, const char *name) { - BOOL success = TRUE; - success &= verifyLength(sizeof(U16), name); + if (!verifyLength(sizeof(U16), name)) + { + return FALSE; + } htolememcpy(&value, mCurBufferp, MVT_U16, 2); mCurBufferp += 2; - return success; + return TRUE; } BOOL LLDataPackerBinaryBuffer::packS16(const S16 value, const char *name) @@ -404,134 +424,156 @@ BOOL LLDataPackerBinaryBuffer::unpackS16(S16 &value, const char *name) BOOL LLDataPackerBinaryBuffer::packU32(const U32 value, const char *name) { - BOOL success = TRUE; - success &= verifyLength(sizeof(U32), name); + if (!verifyLength(sizeof(U32), name)) + { + return FALSE; + } if (mWriteEnabled) { htolememcpy(mCurBufferp, &value, MVT_U32, 4); } mCurBufferp += 4; - return success; + return TRUE; } BOOL LLDataPackerBinaryBuffer::unpackU32(U32 &value, const char *name) { - BOOL success = TRUE; - success &= verifyLength(sizeof(U32), name); + if (!verifyLength(sizeof(U32), name)) + { + return FALSE; + } htolememcpy(&value, mCurBufferp, MVT_U32, 4); mCurBufferp += 4; - return success; + return TRUE; } BOOL LLDataPackerBinaryBuffer::packS32(const S32 value, const char *name) { - BOOL success = TRUE; - success &= verifyLength(sizeof(S32), name); + if (!verifyLength(sizeof(S32), name)) + { + return FALSE; + } if (mWriteEnabled) { htolememcpy(mCurBufferp, &value, MVT_S32, 4); } mCurBufferp += 4; - return success; + return TRUE; } BOOL LLDataPackerBinaryBuffer::unpackS32(S32 &value, const char *name) { - BOOL success = TRUE; - success &= verifyLength(sizeof(S32), name); + if(!verifyLength(sizeof(S32), name)) + { + return FALSE; + } htolememcpy(&value, mCurBufferp, MVT_S32, 4); mCurBufferp += 4; - return success; + return TRUE; } BOOL LLDataPackerBinaryBuffer::packF32(const F32 value, const char *name) { - BOOL success = TRUE; - success &= verifyLength(sizeof(F32), name); + if (!verifyLength(sizeof(F32), name)) + { + return FALSE; + } if (mWriteEnabled) { htolememcpy(mCurBufferp, &value, MVT_F32, 4); } mCurBufferp += 4; - return success; + return TRUE; } BOOL LLDataPackerBinaryBuffer::unpackF32(F32 &value, const char *name) { - BOOL success = TRUE; - success &= verifyLength(sizeof(F32), name); + if (!verifyLength(sizeof(F32), name)) + { + return FALSE; + } htolememcpy(&value, mCurBufferp, MVT_F32, 4); mCurBufferp += 4; - return success; + return TRUE; } BOOL LLDataPackerBinaryBuffer::packColor4(const LLColor4 &value, const char *name) { - BOOL success = TRUE; - success &= verifyLength(16, name); + if (!verifyLength(16, name)) + { + return FALSE; + } if (mWriteEnabled) { htolememcpy(mCurBufferp, value.mV, MVT_LLVector4, 16); } mCurBufferp += 16; - return success; + return TRUE; } BOOL LLDataPackerBinaryBuffer::unpackColor4(LLColor4 &value, const char *name) { - BOOL success = TRUE; - success &= verifyLength(16, name); + if (!verifyLength(16, name)) + { + return FALSE; + } htolememcpy(value.mV, mCurBufferp, MVT_LLVector4, 16); mCurBufferp += 16; - return success; + return TRUE; } BOOL LLDataPackerBinaryBuffer::packColor4U(const LLColor4U &value, const char *name) { - BOOL success = TRUE; - success &= verifyLength(4, name); + if (!verifyLength(4, name)) + { + return FALSE; + } if (mWriteEnabled) { htolememcpy(mCurBufferp, value.mV, MVT_VARIABLE, 4); } mCurBufferp += 4; - return success; + return TRUE; } BOOL LLDataPackerBinaryBuffer::unpackColor4U(LLColor4U &value, const char *name) { - BOOL success = TRUE; - success &= verifyLength(4, name); + if (!verifyLength(4, name)) + { + return FALSE; + } htolememcpy(value.mV, mCurBufferp, MVT_VARIABLE, 4); mCurBufferp += 4; - return success; + return TRUE; } BOOL LLDataPackerBinaryBuffer::packVector2(const LLVector2 &value, const char *name) { - BOOL success = TRUE; - success &= verifyLength(8, name); + if (!verifyLength(8, name)) + { + return FALSE; + } if (mWriteEnabled) { @@ -539,92 +581,106 @@ BOOL LLDataPackerBinaryBuffer::packVector2(const LLVector2 &value, const char *n htolememcpy(mCurBufferp+4, &value.mV[1], MVT_F32, 4); } mCurBufferp += 8; - return success; + return TRUE; } BOOL LLDataPackerBinaryBuffer::unpackVector2(LLVector2 &value, const char *name) { - BOOL success = TRUE; - success &= verifyLength(8, name); + if (!verifyLength(8, name)) + { + return FALSE; + } htolememcpy(&value.mV[0], mCurBufferp, MVT_F32, 4); htolememcpy(&value.mV[1], mCurBufferp+4, MVT_F32, 4); mCurBufferp += 8; - return success; + return TRUE; } BOOL LLDataPackerBinaryBuffer::packVector3(const LLVector3 &value, const char *name) { - BOOL success = TRUE; - success &= verifyLength(12, name); + if (!verifyLength(12, name)) + { + return FALSE; + } if (mWriteEnabled) { htolememcpy(mCurBufferp, value.mV, MVT_LLVector3, 12); } mCurBufferp += 12; - return success; + return TRUE; } BOOL LLDataPackerBinaryBuffer::unpackVector3(LLVector3 &value, const char *name) { - BOOL success = TRUE; - success &= verifyLength(12, name); + if (!verifyLength(12, name)) + { + return FALSE; + } htolememcpy(value.mV, mCurBufferp, MVT_LLVector3, 12); mCurBufferp += 12; - return success; + return TRUE; } BOOL LLDataPackerBinaryBuffer::packVector4(const LLVector4 &value, const char *name) { - BOOL success = TRUE; - success &= verifyLength(16, name); + if (!verifyLength(16, name)) + { + return FALSE; + } if (mWriteEnabled) { htolememcpy(mCurBufferp, value.mV, MVT_LLVector4, 16); } mCurBufferp += 16; - return success; + return TRUE; } BOOL LLDataPackerBinaryBuffer::unpackVector4(LLVector4 &value, const char *name) { - BOOL success = TRUE; - success &= verifyLength(16, name); + if (!verifyLength(16, name)) + { + return FALSE; + } htolememcpy(value.mV, mCurBufferp, MVT_LLVector4, 16); mCurBufferp += 16; - return success; + return TRUE; } BOOL LLDataPackerBinaryBuffer::packUUID(const LLUUID &value, const char *name) { - BOOL success = TRUE; - success &= verifyLength(16, name); + if (!verifyLength(16, name)) + { + return FALSE; + } if (mWriteEnabled) { htolememcpy(mCurBufferp, value.mData, MVT_LLUUID, 16); } mCurBufferp += 16; - return success; + return TRUE; } BOOL LLDataPackerBinaryBuffer::unpackUUID(LLUUID &value, const char *name) { - BOOL success = TRUE; - success &= verifyLength(16, name); + if (!verifyLength(16, name)) + { + return FALSE; + } htolememcpy(value.mData, mCurBufferp, MVT_LLUUID, 16); mCurBufferp += 16; - return success; + return TRUE; } const LLDataPackerBinaryBuffer& LLDataPackerBinaryBuffer::operator=(const LLDataPackerBinaryBuffer &a) @@ -698,15 +754,13 @@ BOOL LLDataPackerAsciiBuffer::packString(const std::string& value, const char *n BOOL LLDataPackerAsciiBuffer::unpackString(std::string& value, const char *name) { - BOOL success = TRUE; char valuestr[DP_BUFSIZE]; /*Flawfinder: ignore*/ - BOOL res = getValueStr(name, valuestr, DP_BUFSIZE); // NULL terminated - if (!res) // + if (!getValueStr(name, valuestr, DP_BUFSIZE)) // NULL terminated { return FALSE; } value = valuestr; - return success; + return TRUE; } diff --git a/indra/llmessage/llfiltersd2xmlrpc.cpp b/indra/llmessage/llfiltersd2xmlrpc.cpp index 0abdafbdfc..c63ce5f441 100644 --- a/indra/llmessage/llfiltersd2xmlrpc.cpp +++ b/indra/llmessage/llfiltersd2xmlrpc.cpp @@ -75,7 +75,13 @@ #include <sstream> #include <iterator> + +#ifdef LL_USESYSTEMLIBS +#include <xmlrpc.h> +#else #include <xmlrpc-epi/xmlrpc.h> +#endif + #include "apr_base64.h" #include "llbuffer.h" diff --git a/indra/llmessage/llioutil.h b/indra/llmessage/llioutil.h index e8d245f530..c404a98bed 100644 --- a/indra/llmessage/llioutil.h +++ b/indra/llmessage/llioutil.h @@ -147,7 +147,7 @@ protected: * } * </code> */ -class LLChangeChannel //: public unary_function<T, void> +class LLChangeChannel { public: /** diff --git a/indra/llmessage/llmessagethrottle.cpp b/indra/llmessage/llmessagethrottle.cpp index 579d6d7187..14582aaf32 100644 --- a/indra/llmessage/llmessagethrottle.cpp +++ b/indra/llmessage/llmessagethrottle.cpp @@ -32,18 +32,8 @@ #include "llframetimer.h" // This is used for the stl search_n function. -#if _MSC_VER >= 1500 // VC9 has a bug in search_n -struct eq_message_throttle_entry : public std::binary_function< LLMessageThrottleEntry, LLMessageThrottleEntry, bool > -{ - bool operator()(const LLMessageThrottleEntry& a, const LLMessageThrottleEntry& b) const - { - return a.getHash() == b.getHash(); - } -}; -#else bool eq_message_throttle_entry(LLMessageThrottleEntry a, LLMessageThrottleEntry b) { return a.getHash() == b.getHash(); } -#endif const U64 SEC_TO_USEC = 1000000; @@ -118,14 +108,8 @@ BOOL LLMessageThrottle::addViewerAlert(const LLUUID& to, const std::string& mesg LLMessageThrottleEntry entry(hash, LLFrameTimer::getTotalTime()); // Check if this message is already in the list. -#if _MSC_VER >= 1500 // VC9 has a bug in search_n - // SJB: This *should* work but has not been tested yet *TODO: Test! - message_list_iterator_t found = std::find_if(message_list->begin(), message_list->end(), - std::bind2nd(eq_message_throttle_entry(), entry)); -#else message_list_iterator_t found = std::search_n(message_list->begin(), message_list->end(), 1, entry, eq_message_throttle_entry); -#endif if (found == message_list->end()) { // This message was not found. Add it to the list. @@ -152,15 +136,8 @@ BOOL LLMessageThrottle::addAgentAlert(const LLUUID& agent, const LLUUID& task, c LLMessageThrottleEntry entry(hash, LLFrameTimer::getTotalTime()); // Check if this message is already in the list. -#if _MSC_VER >= 1500 // VC9 has a bug in search_n - // SJB: This *should* work but has not been tested yet *TODO: Test! - message_list_iterator_t found = std::find_if(message_list->begin(), message_list->end(), - std::bind2nd(eq_message_throttle_entry(), entry)); -#else message_list_iterator_t found = std::search_n(message_list->begin(), message_list->end(), 1, entry, eq_message_throttle_entry); -#endif - if (found == message_list->end()) { // This message was not found. Add it to the list. diff --git a/indra/llmessage/llregionflags.h b/indra/llmessage/llregionflags.h index c13f39df9b..8548ed51e7 100644 --- a/indra/llmessage/llregionflags.h +++ b/indra/llmessage/llregionflags.h @@ -89,6 +89,8 @@ const U64 REGION_FLAGS_ALLOW_VOICE = (1 << 28); const U64 REGION_FLAGS_BLOCK_PARCEL_SEARCH = (1 << 29); const U64 REGION_FLAGS_DENY_AGEUNVERIFIED = (1 << 30); +const U64 REGION_FLAGS_DENY_BOTS = (1 << 31); + const U64 REGION_FLAGS_DEFAULT = REGION_FLAGS_ALLOW_LANDMARK | REGION_FLAGS_ALLOW_SET_HOME | REGION_FLAGS_ALLOW_PARCEL_CHANGES | diff --git a/indra/llmessage/llthrottle.cpp b/indra/llmessage/llthrottle.cpp index 935af2aa5a..e659414e8c 100644 --- a/indra/llmessage/llthrottle.cpp +++ b/indra/llmessage/llthrottle.cpp @@ -435,12 +435,6 @@ BOOL LLThrottleGroup::dynamicAdjust() { channel_over_nominal[i] = FALSE; } - - //if (total) - //{ - // LL_INFOS() << i << ": B" << channel_busy[i] << " I" << channel_idle[i] << " N" << channel_over_nominal[i]; - // LL_CONT << " Nom: " << mNominalBPS[i] << " Cur: " << mCurrentBPS[i] << " BS: " << mBitsSentHistory[i] << LL_ENDL; - //} } if (channels_busy) diff --git a/indra/llmessage/tests/llcoproceduremanager_test.cpp b/indra/llmessage/tests/llcoproceduremanager_test.cpp index 6424117ef3..a1a4ce0520 100644 --- a/indra/llmessage/tests/llcoproceduremanager_test.cpp +++ b/indra/llmessage/tests/llcoproceduremanager_test.cpp @@ -92,7 +92,7 @@ namespace tut Sync sync; int foo = 0; LLCoprocedureManager::instance().initializePool("PoolName"); - LLUUID queueId = LLCoprocedureManager::instance().enqueueCoprocedure("PoolName", "ProcName", + LLCoprocedureManager::instance().enqueueCoprocedure("PoolName", "ProcName", [&foo, &sync] (LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t & ptr, const LLUUID & id) { sync.bump(); foo = 1; diff --git a/indra/llplugin/CMakeLists.txt b/indra/llplugin/CMakeLists.txt index 5cc129a267..14a69afe6e 100644 --- a/indra/llplugin/CMakeLists.txt +++ b/indra/llplugin/CMakeLists.txt @@ -6,26 +6,7 @@ include(00-Common) include(CURL) include(LLCommon) include(LLImage) -include(LLMath) -include(LLMessage) -include(LLRender) -include(LLXML) include(LLWindow) -include(Boost) - -include_directories( - ${LLCOMMON_INCLUDE_DIRS} - ${LLIMAGE_INCLUDE_DIRS} - ${LLMATH_INCLUDE_DIRS} - ${LLMESSAGE_INCLUDE_DIRS} - ${LLRENDER_INCLUDE_DIRS} - ${LLXML_INCLUDE_DIRS} - ${LLWINDOW_INCLUDE_DIRS} - ) -include_directories(SYSTEM - ${LLCOMMON_SYSTEM_INCLUDE_DIRS} - ${LLXML_SYSTEM_INCLUDE_DIRS} - ) set(llplugin_SOURCE_FILES llpluginclassmedia.cpp @@ -39,7 +20,6 @@ set(llplugin_SOURCE_FILES set(llplugin_HEADER_FILES CMakeLists.txt - llpluginclassmedia.h llpluginclassmediaowner.h llplugininstance.h @@ -51,9 +31,6 @@ set(llplugin_HEADER_FILES llpluginsharedmemory.h ) -set_source_files_properties(${llplugin_HEADER_FILES} - PROPERTIES HEADER_FILE_ONLY TRUE) - if(NOT ADDRESS_SIZE EQUAL 32) if(WINDOWS) ##add_definitions(/FIXED:NO) @@ -65,6 +42,7 @@ endif(NOT ADDRESS_SIZE EQUAL 32) list(APPEND llplugin_SOURCE_FILES ${llplugin_HEADER_FILES}) add_library (llplugin ${llplugin_SOURCE_FILES}) - +target_include_directories( llplugin INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}) +target_link_libraries( llplugin llcommon llmath llrender llmessage ) add_subdirectory(slplugin) diff --git a/indra/llplugin/llpluginprocessparent.cpp b/indra/llplugin/llpluginprocessparent.cpp index 1fbbad06d4..756d0b5db8 100644 --- a/indra/llplugin/llpluginprocessparent.cpp +++ b/indra/llplugin/llpluginprocessparent.cpp @@ -162,6 +162,11 @@ LLPluginProcessParent::~LLPluginProcessParent() { // If we are quitting, the network sockets will already have been destroyed. killSockets(); } + + if (mPolling.connected()) + { + mPolling.disconnect(); + } } /*static*/ diff --git a/indra/llplugin/slplugin/CMakeLists.txt b/indra/llplugin/slplugin/CMakeLists.txt index e4f64448c5..0ea6495eac 100644 --- a/indra/llplugin/slplugin/CMakeLists.txt +++ b/indra/llplugin/slplugin/CMakeLists.txt @@ -2,25 +2,8 @@ project(SLPlugin) include(00-Common) include(LLCommon) -include(LLPlugin) include(Linking) include(PluginAPI) -include(LLMessage) - -include_directories( - ${LLPLUGIN_INCLUDE_DIRS} - ${LLMESSAGE_INCLUDE_DIRS} - ${LLCOMMON_INCLUDE_DIRS} -) -include_directories(SYSTEM - ${LLCOMMON_SYSTEM_INCLUDE_DIRS} - ) - -if (DARWIN) - include(CMakeFindFrameworks) - find_library(COCOA_LIBRARY Cocoa) -endif (DARWIN) - ### SLPlugin @@ -37,9 +20,6 @@ if (DARWIN) ) endif (DARWIN) -set_source_files_properties(${SLPlugin_HEADER_FILES} - PROPERTIES HEADER_FILE_ONLY TRUE) - if (SLPlugin_HEADER_FILES) list(APPEND SLPlugin_SOURCE_FILES ${SLPlugin_HEADER_FILES}) endif (SLPlugin_HEADER_FILES) @@ -63,23 +43,20 @@ set_target_properties(SLPlugin endif () target_link_libraries(SLPlugin - ${LEGACY_STDIO_LIBS} - ${LLPLUGIN_LIBRARIES} - ${LLMESSAGE_LIBRARIES} - ${LLCOMMON_LIBRARIES} - ${PLUGIN_API_WINDOWS_LIBRARIES} -) + llplugin + llmessage + llcommon + ll::pluginlibraries + ) if (DARWIN) - # Mac version needs to link against Carbon - target_link_libraries(SLPlugin ${COCOA_LIBRARY}) # Make sure the app bundle has a Resources directory (it will get populated by viewer-manifest.py later) add_custom_command( TARGET SLPlugin POST_BUILD COMMAND mkdir ARGS -p - ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/SLPlugin.app/Contents/Resources + ${CMAKE_CURRENT_BINARY_DIR}/$<IF:$<BOOL:${LL_GENERATOR_IS_MULTI_CONFIG}>,$<CONFIG>,>/SLPlugin.app/Contents/Resources ) endif (DARWIN) diff --git a/indra/llprimitive/CMakeLists.txt b/indra/llprimitive/CMakeLists.txt index 7b6d04b096..d69cd958a0 100644 --- a/indra/llprimitive/CMakeLists.txt +++ b/indra/llprimitive/CMakeLists.txt @@ -4,27 +4,10 @@ project(llprimitive) include(00-Common) include(LLCommon) -include(LLMath) -include(LLMessage) include(LLCoreHttp) -include(LLXML) include(LLPhysicsExtensions) -include(LLCharacter) - -include_directories( - ${LLCOMMON_INCLUDE_DIRS} - ${LLMATH_INCLUDE_DIRS} - ${LLMESSAGE_INCLUDE_DIRS} - ${LLXML_INCLUDE_DIRS} - ${LIBS_PREBUILT_DIR}/include/collada - ${LIBS_PREBUILT_DIR}/include/collada/1.4 - ${LLCHARACTER_INCLUDE_DIRS} - ) -include_directories(SYSTEM - ${LLCOMMON_SYSTEM_INCLUDE_DIRS} - ${LLXML_SYSTEM_INCLUDE_DIRS} - ${LLPHYSICSEXTENSIONS_INCLUDE_DIRS} - ) +include(LLPrimitive) +include(GLH) set(llprimitive_SOURCE_FILES lldaeloader.cpp @@ -64,26 +47,24 @@ set(llprimitive_HEADER_FILES material_codes.h object_flags.h ) - -set_source_files_properties(${llprimitive_HEADER_FILES} - PROPERTIES HEADER_FILE_ONLY TRUE) list(APPEND llprimitive_SOURCE_FILES ${llprimitive_HEADER_FILES}) add_library (llprimitive ${llprimitive_SOURCE_FILES}) +target_include_directories( llprimitive INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}) target_link_libraries(llprimitive - ${LLCOMMON_LIBRARIES} - ${LLMATH_LIBRARIES} - ${LLMESSAGE_LIBRARIES} - ${LLCOREHTTP_LIBRARIES} - ${LLXML_LIBRARIES} - ${LLPHYSICSEXTENSIONS_LIBRARIES} - ${LLCHARACTER_LIBRARIES} - ${BOOST_FIBER_LIBRARY} - ${BOOST_CONTEXT_LIBRARY} - ) - + llcommon + llmath + llmessage + llcorehttp + llxml + llcharacter + llphysicsextensions_impl + ll::colladadom + ll::pcre + ll::glh_linear + ) #add unit tests if (LL_TESTS) diff --git a/indra/llprimitive/llmodel.cpp b/indra/llprimitive/llmodel.cpp index 3921ebfca3..fbd97b3de7 100644 --- a/indra/llprimitive/llmodel.cpp +++ b/indra/llprimitive/llmodel.cpp @@ -1402,6 +1402,16 @@ LLMeshSkinInfo::LLMeshSkinInfo(LLSD& skin): fromLLSD(skin); } +LLMeshSkinInfo::LLMeshSkinInfo(const LLUUID& mesh_id, LLSD& skin) : + mMeshID(mesh_id), + mPelvisOffset(0.0), + mLockScaleIfJointPosition(false), + mInvalidJointsScrubbed(false), + mJointNumsInitialized(false) +{ + fromLLSD(skin); +} + void LLMeshSkinInfo::fromLLSD(LLSD& skin) { if (skin.has("joint_names")) diff --git a/indra/llprimitive/llmodel.h b/indra/llprimitive/llmodel.h index 2aaaa4e8c1..4505d6b3b9 100644 --- a/indra/llprimitive/llmodel.h +++ b/indra/llprimitive/llmodel.h @@ -41,12 +41,13 @@ class domMesh; #define MAX_MODEL_FACES 8 LL_ALIGN_PREFIX(16) -class LLMeshSkinInfo +class LLMeshSkinInfo : public LLRefCount { LL_ALIGN_NEW public: LLMeshSkinInfo(); LLMeshSkinInfo(LLSD& data); + LLMeshSkinInfo(const LLUUID& mesh_id, LLSD& data); void fromLLSD(LLSD& data); LLSD asLLSD(bool include_joints, bool lock_scale_if_joint_position) const; void updateHash(); diff --git a/indra/llrender/CMakeLists.txt b/indra/llrender/CMakeLists.txt index baab09a104..c5cf1100d5 100644 --- a/indra/llrender/CMakeLists.txt +++ b/indra/llrender/CMakeLists.txt @@ -7,26 +7,7 @@ include(OpenGL) include(FreeType) include(LLCommon) include(LLImage) -include(LLMath) -include(LLRender) include(LLWindow) -include(LLXML) -include(LLFileSystem) - -include_directories( - ${FREETYPE_INCLUDE_DIRS} - ${LLCOMMON_INCLUDE_DIRS} - ${LLIMAGE_INCLUDE_DIRS} - ${LLMATH_INCLUDE_DIRS} - ${LLRENDER_INCLUDE_DIRS} - ${LLFILESYSTEM_INCLUDE_DIRS} - ${LLWINDOW_INCLUDE_DIRS} - ${LLXML_INCLUDE_DIRS} - ) -include_directories(SYSTEM - ${LLCOMMON_SYSTEM_INCLUDE_DIRS} - ${LLXML_SYSTEM_INCLUDE_DIRS} - ) set(llrender_SOURCE_FILES llatmosphere.cpp @@ -83,9 +64,6 @@ set(llrender_HEADER_FILES llglcommonfunc.h ) -set_source_files_properties(${llrender_HEADER_FILES} - PROPERTIES HEADER_FILE_ONLY TRUE) - list(APPEND llrender_SOURCE_FILES ${llrender_HEADER_FILES}) if (BUILD_HEADLESS) @@ -98,34 +76,29 @@ if (BUILD_HEADLESS) ) target_link_libraries(llrenderheadless - ${LLCOMMON_LIBRARIES} - ${LLIMAGE_LIBRARIES} - ${LLMATH_LIBRARIES} - ${LLRENDER_HEADLESS_LIBRARIES} - ${LLXML_LIBRARIES} - ${LLFILESYSTEM_LIBRARIES} - ${LLWINDOW_HEADLESS_LIBRARIES} - ${OPENGL_HEADLESS_LIBRARIES}) - + llcommon + llimage + llmath + llrender + llxml + llfilesystem + ) endif (BUILD_HEADLESS) add_library (llrender ${llrender_SOURCE_FILES}) - -if (SDL_FOUND) - set_property(TARGET llrender - PROPERTY COMPILE_DEFINITIONS LL_SDL=1 - ) -endif (SDL_FOUND) +target_include_directories( llrender INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}) # Libraries on which this library depends, needed for Linux builds # Sort by high-level to low-level -target_link_libraries(llrender - ${LLCOMMON_LIBRARIES} - ${LLIMAGE_LIBRARIES} - ${LLMATH_LIBRARIES} - ${LLFILESYSTEM_LIBRARIES} - ${LLXML_LIBRARIES} - ${LLWINDOW_LIBRARIES} - ${FREETYPE_LIBRARIES} - ${OPENGL_LIBRARIES}) +target_link_libraries(llrender + llcommon + llimage + llmath + llfilesystem + llxml + llwindow + ll::freetype + OpenGL::GL + OpenGL::GLU + ) diff --git a/indra/llrender/llfontregistry.cpp b/indra/llrender/llfontregistry.cpp index bc1a2f8887..9750bd4fa1 100644 --- a/indra/llrender/llfontregistry.cpp +++ b/indra/llrender/llfontregistry.cpp @@ -239,7 +239,7 @@ std::string currentOsName() return "Windows"; #elif LL_DARWIN return "Mac"; -#elif LL_SDL || LL_MESA_HEADLESS +#elif LL_LINUX return "Linux"; #else return ""; diff --git a/indra/llrender/llglheaders.h b/indra/llrender/llglheaders.h index 3d93cc0762..e1ecc6a6ca 100644 --- a/indra/llrender/llglheaders.h +++ b/indra/llrender/llglheaders.h @@ -59,11 +59,6 @@ # include "GL/glh_extensions.h" # undef __APPLE__ -/* Although SDL very likely ends up calling glXGetProcAddress() itself, - if we use SDL_GL_GetProcAddress() then we get bogus addresses back on - some systems. Weird. */ -/*# include "SDL/SDL.h" - # define GLH_EXT_GET_PROC_ADDRESS(p) SDL_GL_GetProcAddress(p) */ #define GLX_GLXEXT_PROTOTYPES 1 # include "GL/glx.h" # include "GL/glxext.h" diff --git a/indra/llrender/llglslshader.cpp b/indra/llrender/llglslshader.cpp index 185c1450c8..da24d999b0 100644 --- a/indra/llrender/llglslshader.cpp +++ b/indra/llrender/llglslshader.cpp @@ -278,10 +278,10 @@ void LLGLSLShader::readProfileQuery(U32 count, U32 mode) glEndQueryARB(GL_TIME_ELAPSED); glEndQueryARB(GL_SAMPLES_PASSED); - U64 time_elapsed = 0; + GLuint64 time_elapsed = 0; glGetQueryObjectui64v(mTimerQuery, GL_QUERY_RESULT, &time_elapsed); - U64 samples_passed = 0; + GLuint64 samples_passed = 0; glGetQueryObjectui64v(mSamplesQuery, GL_QUERY_RESULT, &samples_passed); sTotalTimeElapsed += time_elapsed; diff --git a/indra/llui/CMakeLists.txt b/indra/llui/CMakeLists.txt index e0579352d3..9108c6143c 100644 --- a/indra/llui/CMakeLists.txt +++ b/indra/llui/CMakeLists.txt @@ -6,33 +6,9 @@ include(00-Common) include(Hunspell) include(LLCommon) include(LLImage) -include(LLInventory) -include(LLMath) -include(LLMessage) include(LLCoreHttp) -include(LLRender) include(LLWindow) include(LLCoreHttp) -include(LLFileSystem) -include(LLXML) - -include_directories( - ${LLCOMMON_INCLUDE_DIRS} - ${LLCOREHTTP_INCLUDE_DIRS} - ${LLIMAGE_INCLUDE_DIRS} - ${LLINVENTORY_INCLUDE_DIRS} - ${LLMATH_INCLUDE_DIRS} - ${LLMESSAGE_INCLUDE_DIRS} - ${LLRENDER_INCLUDE_DIRS} - ${LLWINDOW_INCLUDE_DIRS} - ${LLFILESYSTEM_INCLUDE_DIRS} - ${LLXML_INCLUDE_DIRS} - ${LIBS_PREBUILD_DIR}/include/hunspell - ) -include_directories(SYSTEM - ${LLCOMMON_SYSTEM_INCLUDE_DIRS} - ${LLXML_SYSTEM_INCLUDE_DIRS} - ) set(llui_SOURCE_FILES llaccordionctrl.cpp @@ -260,9 +236,6 @@ set(llui_HEADER_FILES llxyvector.h ) -set_source_files_properties(${llui_HEADER_FILES} - PROPERTIES HEADER_FILE_ONLY TRUE) - SET(llurlentry_TEST_DEPENDENCIES llurlmatch.cpp llurlregistry.cpp @@ -276,42 +249,37 @@ set_source_files_properties(llurlentry.cpp list(APPEND llui_SOURCE_FILES ${llui_HEADER_FILES}) add_library (llui ${llui_SOURCE_FILES}) +target_include_directories( llui INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}) # Libraries on which this library depends, needed for Linux builds # Sort by high-level to low-level target_link_libraries(llui - ${LLRENDER_LIBRARIES} - ${LLWINDOW_LIBRARIES} - ${LLIMAGE_LIBRARIES} - ${LLINVENTORY_LIBRARIES} - ${LLMESSAGE_LIBRARIES} - ${LLCOREHTTP_LIBRARIES} - ${LLFILESYSTEM_LIBRARIES} - ${LLXUIXML_LIBRARIES} - ${LLXML_LIBRARIES} - ${LLMATH_LIBRARIES} - ${HUNSPELL_LIBRARY} - ${LLMESSAGE_LIBRARIES} - ${LLCOMMON_LIBRARIES} # must be after llimage, llwindow, llrender + llrender + llwindow + llimage + llinventory + llmessage + llcorehttp + llfilesystem + llxml + llmath + ll::hunspell + llcommon ) # Add tests if(LL_TESTS) include(LLAddBuildTest) + set(test_libs llmessage llcorehttp llxml llrender llcommon ll::hunspell) + SET(llui_TEST_SOURCE_FILES llurlmatch.cpp ) + set_property( SOURCE ${llui_TEST_SOURCE_FILES} PROPERTY LL_TEST_ADDITIONAL_LIBRARIES ${test_libs}) LL_ADD_PROJECT_UNIT_TESTS(llui "${llui_TEST_SOURCE_FILES}") # INTEGRATION TESTS - set(test_libs llui llmessage llcorehttp llcommon - ${HUNSPELL_LIBRARY} - ${LLCOMMON_LIBRARIES} - ${BOOST_FIBER_LIBRARY} ${BOOST_CONTEXT_LIBRARY} ${BOOST_SYSTEM_LIBRARY} - ${WINDOWS_LIBRARIES}) + if(NOT LINUX) - if(WINDOWS) - LL_ADD_INTEGRATION_TEST(llurlentry llurlentry.cpp "imm32;${test_libs}") - else(WINDOWS) - LL_ADD_INTEGRATION_TEST(llurlentry llurlentry.cpp "${test_libs}") - endif(WINDOWS) + set(test_libs llui llmessage llcorehttp llxml llrender llcommon ll::hunspell ) + LL_ADD_INTEGRATION_TEST(llurlentry llurlentry.cpp "${test_libs}") endif(NOT LINUX) endif(LL_TESTS) diff --git a/indra/llui/lldockablefloater.h b/indra/llui/lldockablefloater.h index 89c9852f4a..5d90b3ef4e 100644 --- a/indra/llui/lldockablefloater.h +++ b/indra/llui/lldockablefloater.h @@ -30,6 +30,7 @@ #include "llerror.h" #include "llfloater.h" #include "lldockcontrol.h" +#include <memory> /** * Represents floater that can dock. @@ -131,7 +132,7 @@ protected: boost::function<BOOL ()> mIsDockedStateForcedCallback; private: - std::auto_ptr<LLDockControl> mDockControl; + std::unique_ptr<LLDockControl> mDockControl; LLUIImagePtr mDockTongue; static LLHandle<LLFloater> sInstanceHandle; /** diff --git a/indra/llui/llflatlistview.cpp b/indra/llui/llflatlistview.cpp index 5e00bf7f45..b13e7389cc 100644 --- a/indra/llui/llflatlistview.cpp +++ b/indra/llui/llflatlistview.cpp @@ -505,6 +505,17 @@ LLFlatListView::LLFlatListView(const LLFlatListView::Params& p) } }; +LLFlatListView::~LLFlatListView() +{ + for (pairs_iterator_t it = mItemPairs.begin(); it != mItemPairs.end(); ++it) + { + mItemsPanel->removeChild((*it)->first); + (*it)->first->die(); + delete *it; + } + mItemPairs.clear(); +} + // virtual void LLFlatListView::draw() { diff --git a/indra/llui/llflatlistview.h b/indra/llui/llflatlistview.h index 230ea200d8..d47c1cf333 100644 --- a/indra/llui/llflatlistview.h +++ b/indra/llui/llflatlistview.h @@ -299,6 +299,7 @@ public: virtual S32 notify(const LLSD& info) ; + virtual ~LLFlatListView(); protected: /** Pairs LLpanel representing a single item LLPanel and LLSD associated with it */ diff --git a/indra/llui/llfloater.cpp b/indra/llui/llfloater.cpp index d413fab270..2303cd24b7 100644 --- a/indra/llui/llfloater.cpp +++ b/indra/llui/llfloater.cpp @@ -759,11 +759,13 @@ void LLFloater::closeFloater(bool app_quitting) } // now close dependent floater - for(handle_set_iter_t dependent_it = mDependents.begin(); - dependent_it != mDependents.end(); ) + while(mDependents.size() > 0) { + handle_set_iter_t dependent_it = mDependents.begin(); LLFloater* floaterp = dependent_it->get(); - dependent_it = mDependents.erase(dependent_it); + // normally removeDependentFloater will do this, but in + // case floaterp is somehow invalid or orphaned, erase now + mDependents.erase(dependent_it); if (floaterp) { floaterp->mDependeeHandle = LLHandle<LLFloater>(); diff --git a/indra/llui/llfolderview.cpp b/indra/llui/llfolderview.cpp index ea2ca68e47..e1869e8125 100644 --- a/indra/llui/llfolderview.cpp +++ b/indra/llui/llfolderview.cpp @@ -163,6 +163,7 @@ LLFolderView::LLFolderView(const Params& p) : LLFolderViewFolder(p), mScrollContainer( NULL ), mPopupMenuHandle(), + mMenuFileName(p.options_menu), mAllowMultiSelect(p.allow_multiselect), mAllowDrag(p.allow_drag), mShowEmptyMessage(p.show_empty_message), @@ -182,6 +183,7 @@ LLFolderView::LLFolderView(const Params& p) mMinWidth(0), mDragAndDropThisFrame(FALSE), mCallbackRegistrar(NULL), + mEnableRegistrar(NULL), mUseEllipses(p.use_ellipses), mDraggingOverItem(NULL), mStatusTextBox(NULL), @@ -244,17 +246,6 @@ LLFolderView::LLFolderView(const Params& p) mStatusTextBox->setFollowsTop(); addChild(mStatusTextBox); - - // make the popup menu available - llassert(LLMenuGL::sMenuContainer != NULL); - LLMenuGL* menu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>(p.options_menu, LLMenuGL::sMenuContainer, LLMenuHolderGL::child_registry_t::instance()); - if (!menu) - { - menu = LLUICtrlFactory::getDefaultWidget<LLMenuGL>("inventory_menu"); - } - menu->setBackgroundColor(LLUIColorTable::instance().getColor("MenuPopupBgColor")); - mPopupMenuHandle = menu->getHandle(); - mViewModelItem->openItem(); mAreChildrenInited = true; // root folder is a special case due to not being loaded normally, assume that it's inited. @@ -276,6 +267,7 @@ LLFolderView::~LLFolderView( void ) mStatusTextBox = NULL; if (mPopupMenuHandle.get()) mPopupMenuHandle.get()->die(); + mPopupMenuHandle.markDead(); mAutoOpenItems.removeAllNodes(); clearSelection(); @@ -1438,22 +1430,56 @@ BOOL LLFolderView::handleRightMouseDown( S32 x, S32 y, MASK mask ) BOOL handled = childrenHandleRightMouseDown(x, y, mask) != NULL; S32 count = mSelectedItems.size(); - LLMenuGL* menu = (LLMenuGL*)mPopupMenuHandle.get(); + LLMenuGL* menu = static_cast<LLMenuGL*>(mPopupMenuHandle.get()); + if (!menu) + { + if (mCallbackRegistrar) + { + mCallbackRegistrar->pushScope(); + } + if (mEnableRegistrar) + { + mEnableRegistrar->pushScope(); + } + llassert(LLMenuGL::sMenuContainer != NULL); + menu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>(mMenuFileName, LLMenuGL::sMenuContainer, LLMenuHolderGL::child_registry_t::instance()); + if (!menu) + { + menu = LLUICtrlFactory::getDefaultWidget<LLMenuGL>("inventory_menu"); + } + menu->setBackgroundColor(LLUIColorTable::instance().getColor("MenuPopupBgColor")); + mPopupMenuHandle = menu->getHandle(); + if (mEnableRegistrar) + { + mEnableRegistrar->popScope(); + } + if (mCallbackRegistrar) + { + mCallbackRegistrar->popScope(); + } + } bool hide_folder_menu = mSuppressFolderMenu && isFolderSelected(); - if ((handled - && ( count > 0 && (hasVisibleChildren()) ) // show menu only if selected items are visible - && menu ) && + if (menu && (handled + && ( count > 0 && (hasVisibleChildren()) )) && // show menu only if selected items are visible !hide_folder_menu) { if (mCallbackRegistrar) { mCallbackRegistrar->pushScope(); } + if (mEnableRegistrar) + { + mEnableRegistrar->pushScope(); + } updateMenuOptions(menu); menu->updateParent(LLMenuGL::sMenuContainer); LLMenuGL::showPopup(this, menu, x, y); + if (mEnableRegistrar) + { + mEnableRegistrar->popScope(); + } if (mCallbackRegistrar) { mCallbackRegistrar->popScope(); @@ -1531,7 +1557,7 @@ void LLFolderView::deleteAllChildren() { closeRenamer(); if (mPopupMenuHandle.get()) mPopupMenuHandle.get()->die(); - mPopupMenuHandle = LLHandle<LLView>(); + mPopupMenuHandle.markDead(); mScrollContainer = NULL; mRenameItem = NULL; mRenamer = NULL; diff --git a/indra/llui/llfolderview.h b/indra/llui/llfolderview.h index 6bb5e6c02e..7dfa04828a 100644 --- a/indra/llui/llfolderview.h +++ b/indra/llui/llfolderview.h @@ -235,6 +235,7 @@ public: bool showItemLinkOverlays() { return mShowItemLinkOverlays; } void setCallbackRegistrar(LLUICtrl::CommitCallbackRegistry::ScopedRegistrar* registrar) { mCallbackRegistrar = registrar; } + void setEnableRegistrar(LLUICtrl::EnableCallbackRegistry::ScopedRegistrar* registrar) { mEnableRegistrar = registrar; } LLPanel* getParentPanel() { return mParentPanel.get(); } // DEBUG only @@ -272,6 +273,7 @@ protected: protected: LLHandle<LLView> mPopupMenuHandle; + std::string mMenuFileName; selected_items_t mSelectedItems; bool mKeyboardSelection, @@ -327,6 +329,7 @@ protected: LLFolderViewItem* mDraggingOverItem; // See EXT-719 LLUICtrl::CommitCallbackRegistry::ScopedRegistrar* mCallbackRegistrar; + LLUICtrl::EnableCallbackRegistry::ScopedRegistrar* mEnableRegistrar; public: static F32 sAutoOpenTime; diff --git a/indra/llui/llfolderviewmodel.h b/indra/llui/llfolderviewmodel.h index 618169a8fe..c5e027d314 100644 --- a/indra/llui/llfolderviewmodel.h +++ b/indra/llui/llfolderviewmodel.h @@ -419,21 +419,15 @@ public: mFilter(filter) {} - virtual ~LLFolderViewModel() - { - delete mSorter; - mSorter = NULL; - delete mFilter; - mFilter = NULL; - } + virtual ~LLFolderViewModel() {} virtual SortType& getSorter() { return *mSorter; } virtual const SortType& getSorter() const { return *mSorter; } - virtual void setSorter(const SortType& sorter) { mSorter = new SortType(sorter); requestSortAll(); } + virtual void setSorter(const SortType& sorter) { mSorter.reset(new SortType(sorter)); requestSortAll(); } virtual FilterType& getFilter() { return *mFilter; } virtual const FilterType& getFilter() const { return *mFilter; } - virtual void setFilter(const FilterType& filter) { mFilter = new FilterType(filter); } + virtual void setFilter(const FilterType& filter) { mFilter.reset(new FilterType(filter)); } // By default, we assume the content is available. If a network fetch mechanism is implemented for the model, // this method needs to be overloaded and return the relevant fetch status. @@ -471,8 +465,8 @@ public: } protected: - SortType* mSorter; - FilterType* mFilter; + std::unique_ptr<SortType> mSorter; + std::unique_ptr<FilterType> mFilter; }; #endif // LLFOLDERVIEWMODEL_H diff --git a/indra/llui/lllineeditor.cpp b/indra/llui/lllineeditor.cpp index 33037b5001..940cf398c0 100644 --- a/indra/llui/lllineeditor.cpp +++ b/indra/llui/lllineeditor.cpp @@ -209,13 +209,6 @@ LLLineEditor::LLLineEditor(const LLLineEditor::Params& p) setPrevalidateInput(p.prevalidate_input_callback()); setPrevalidate(p.prevalidate_callback()); - - llassert(LLMenuGL::sMenuContainer != NULL); - LLContextMenu* menu = LLUICtrlFactory::instance().createFromFile<LLContextMenu> - ("menu_text_editor.xml", - LLMenuGL::sMenuContainer, - LLMenuHolderGL::child_registry_t::instance()); - setContextMenu(menu); } LLLineEditor::~LLLineEditor() @@ -1567,7 +1560,7 @@ BOOL LLLineEditor::handleKeyHere(KEY key, MASK mask ) KEY_SHIFT != key && KEY_CONTROL != key && KEY_ALT != key && - KEY_CAPSLOCK ) + KEY_CAPSLOCK != key) { deselect(); } @@ -2637,6 +2630,15 @@ LLWString LLLineEditor::getConvertedText() const void LLLineEditor::showContextMenu(S32 x, S32 y) { LLContextMenu* menu = static_cast<LLContextMenu*>(mContextMenuHandle.get()); + if (!menu) + { + llassert(LLMenuGL::sMenuContainer != NULL); + menu = LLUICtrlFactory::createFromFile<LLContextMenu> + ("menu_text_editor.xml", + LLMenuGL::sMenuContainer, + LLMenuHolderGL::child_registry_t::instance()); + setContextMenu(menu); + } if (menu) { diff --git a/indra/llui/llmenugl.cpp b/indra/llui/llmenugl.cpp index 4264028338..5cb840fd61 100644 --- a/indra/llui/llmenugl.cpp +++ b/indra/llui/llmenugl.cpp @@ -4087,25 +4087,39 @@ void LLTearOffMenu::closeTearOff() } LLContextMenuBranch::LLContextMenuBranch(const LLContextMenuBranch::Params& p) -: LLMenuItemGL(p), - mBranch( p.branch()->getHandle() ) +: LLMenuItemGL(p) { - mBranch.get()->hide(); - mBranch.get()->setParentMenuItem(this); + LLContextMenu* branch = static_cast<LLContextMenu*>(p.branch); + if (branch) + { + mBranch = branch->getHandle(); + branch->hide(); + branch->setParentMenuItem(this); + } +} + +LLContextMenuBranch::~LLContextMenuBranch() +{ + if (mBranch.get()) + { + mBranch.get()->die(); + } } // called to rebuild the draw label void LLContextMenuBranch::buildDrawLabel( void ) { + auto menu = getBranch(); + if (menu) { // default enablement is this -- if any of the subitems are // enabled, this item is enabled. JC - U32 sub_count = mBranch.get()->getItemCount(); + U32 sub_count = menu->getItemCount(); U32 i; BOOL any_enabled = FALSE; for (i = 0; i < sub_count; i++) { - LLMenuItemGL* item = mBranch.get()->getItem(i); + LLMenuItemGL* item = menu->getItem(i); item->buildDrawLabel(); if (item->getEnabled() && !item->getDrawTextDisabled() ) { @@ -4127,13 +4141,17 @@ void LLContextMenuBranch::buildDrawLabel( void ) void LLContextMenuBranch::showSubMenu() { - LLMenuItemGL* menu_item = mBranch.get()->getParentMenuItem(); - if (menu_item != NULL && menu_item->getVisible()) + auto menu = getBranch(); + if(menu) { - S32 center_x; - S32 center_y; - localPointToScreen(getRect().getWidth(), getRect().getHeight() , ¢er_x, ¢er_y); - mBranch.get()->show(center_x, center_y); + LLMenuItemGL* menu_item = menu->getParentMenuItem(); + if (menu_item != NULL && menu_item->getVisible()) + { + S32 center_x; + S32 center_y; + localPointToScreen(getRect().getWidth(), getRect().getHeight(), ¢er_x, ¢er_y); + menu->show(center_x, center_y); + } } } @@ -4147,13 +4165,17 @@ void LLContextMenuBranch::setHighlight( BOOL highlight ) { if (highlight == getHighlight()) return; LLMenuItemGL::setHighlight(highlight); - if( highlight ) - { - showSubMenu(); - } - else + auto menu = getBranch(); + if (menu) { - mBranch.get()->hide(); + if (highlight) + { + showSubMenu(); + } + else + { + menu->hide(); + } } } diff --git a/indra/llui/llmenugl.h b/indra/llui/llmenugl.h index abbfd9a24a..f84c4d41eb 100644 --- a/indra/llui/llmenugl.h +++ b/indra/llui/llmenugl.h @@ -745,8 +745,7 @@ public: LLContextMenuBranch(const Params&); - virtual ~LLContextMenuBranch() - {} + virtual ~LLContextMenuBranch(); // called to rebuild the draw label virtual void buildDrawLabel( void ); diff --git a/indra/llui/llmultislider.cpp b/indra/llui/llmultislider.cpp index f89064d59a..604d246f12 100644 --- a/indra/llui/llmultislider.cpp +++ b/indra/llui/llmultislider.cpp @@ -92,7 +92,7 @@ LLMultiSlider::LLMultiSlider(const LLMultiSlider::Params& p) mMouseDownSignal(NULL), mMouseUpSignal(NULL) { - mValue.emptyMap(); + mValue = LLSD::emptyMap(); mCurSlider = LLStringUtil::null; if (mOrientation == HORIZONTAL) diff --git a/indra/llui/llscrolllistctrl.cpp b/indra/llui/llscrolllistctrl.cpp index 88c1bdc0d5..219667f766 100644 --- a/indra/llui/llscrolllistctrl.cpp +++ b/indra/llui/llscrolllistctrl.cpp @@ -196,7 +196,6 @@ LLScrollListCtrl::LLScrollListCtrl(const LLScrollListCtrl::Params& p) mHighlightedItem(-1), mBorder(NULL), mSortCallback(NULL), - mPopupMenu(NULL), mCommentTextView(NULL), mNumDynamicWidthColumns(0), mTotalStaticColumnWidth(0), @@ -348,6 +347,13 @@ LLScrollListCtrl::~LLScrollListCtrl() mItemList.clear(); clearColumns(); //clears columns and deletes headers delete mIsFriendSignal; + + auto menu = mPopupMenuHandle.get(); + if (menu) + { + menu->die(); + mPopupMenuHandle.markDead(); + } } @@ -1307,14 +1313,14 @@ LLScrollListItem* LLScrollListCtrl::getItemByLabel(const std::string& label, BOO } -BOOL LLScrollListCtrl::selectItemByPrefix(const std::string& target, BOOL case_sensitive) +BOOL LLScrollListCtrl::selectItemByPrefix(const std::string& target, BOOL case_sensitive, S32 column) { - return selectItemByPrefix(utf8str_to_wstring(target), case_sensitive); + return selectItemByPrefix(utf8str_to_wstring(target), case_sensitive, column); } // Selects first enabled item that has a name where the name's first part matched the target string. // Returns false if item not found. -BOOL LLScrollListCtrl::selectItemByPrefix(const LLWString& target, BOOL case_sensitive) +BOOL LLScrollListCtrl::selectItemByPrefix(const LLWString& target, BOOL case_sensitive, S32 column) { BOOL found = FALSE; @@ -1329,7 +1335,7 @@ BOOL LLScrollListCtrl::selectItemByPrefix(const LLWString& target, BOOL case_sen { LLScrollListItem* item = *iter; // Only select enabled items with matching names - LLScrollListCell* cellp = item->getColumn(getSearchColumn()); + LLScrollListCell* cellp = item->getColumn(column == -1 ? getSearchColumn() : column); BOOL select = cellp ? item->getEnabled() && ('\0' == cellp->getValue().asString()[0]) : FALSE; if (select) { @@ -1352,7 +1358,7 @@ BOOL LLScrollListCtrl::selectItemByPrefix(const LLWString& target, BOOL case_sen LLScrollListItem* item = *iter; // Only select enabled items with matching names - LLScrollListCell* cellp = item->getColumn(getSearchColumn()); + LLScrollListCell* cellp = item->getColumn(column == -1 ? getSearchColumn() : column); if (!cellp) { continue; @@ -1997,17 +2003,23 @@ BOOL LLScrollListCtrl::handleRightMouseDown(S32 x, S32 y, MASK mask) // create the context menu from the XUI file and display it std::string menu_name = is_group ? "menu_url_group.xml" : "menu_url_agent.xml"; - delete mPopupMenu; + auto menu = mPopupMenuHandle.get(); + if (menu) + { + menu->die(); + mPopupMenuHandle.markDead(); + } llassert(LLMenuGL::sMenuContainer != NULL); - mPopupMenu = LLUICtrlFactory::getInstance()->createFromFile<LLContextMenu>( + menu = LLUICtrlFactory::getInstance()->createFromFile<LLContextMenu>( menu_name, LLMenuGL::sMenuContainer, LLMenuHolderGL::child_registry_t::instance()); - if (mPopupMenu) + if (menu) { + mPopupMenuHandle = menu->getHandle(); if (mIsFriendSignal) { bool isFriend = *(*mIsFriendSignal)(uuid); - LLView* addFriendButton = mPopupMenu->getChild<LLView>("add_friend"); - LLView* removeFriendButton = mPopupMenu->getChild<LLView>("remove_friend"); + LLView* addFriendButton = menu->getChild<LLView>("add_friend"); + LLView* removeFriendButton = menu->getChild<LLView>("remove_friend"); if (addFriendButton && removeFriendButton) { @@ -2016,8 +2028,8 @@ BOOL LLScrollListCtrl::handleRightMouseDown(S32 x, S32 y, MASK mask) } } - mPopupMenu->show(x, y); - LLMenuGL::showPopup(this, mPopupMenu, x, y); + menu->show(x, y); + LLMenuGL::showPopup(this, menu, x, y); return TRUE; } } diff --git a/indra/llui/llscrolllistctrl.h b/indra/llui/llscrolllistctrl.h index 11ee012185..73b4fb036a 100644 --- a/indra/llui/llscrolllistctrl.h +++ b/indra/llui/llscrolllistctrl.h @@ -261,8 +261,8 @@ public: virtual LLScrollListItem* addSimpleElement(const std::string& value, EAddPosition pos = ADD_BOTTOM, const LLSD& id = LLSD()); BOOL selectItemByLabel( const std::string& item, BOOL case_sensitive = TRUE, S32 column = 0 ); // FALSE if item not found - BOOL selectItemByPrefix(const std::string& target, BOOL case_sensitive = TRUE); - BOOL selectItemByPrefix(const LLWString& target, BOOL case_sensitive = TRUE); + BOOL selectItemByPrefix(const std::string& target, BOOL case_sensitive = TRUE, S32 column = -1); + BOOL selectItemByPrefix(const LLWString& target, BOOL case_sensitive = TRUE, S32 column = -1); LLScrollListItem* getItemByLabel( const std::string& item, BOOL case_sensitive = TRUE, S32 column = 0 ); const std::string getSelectedItemLabel(S32 column = 0) const; LLSD getSelectedValue(); @@ -528,7 +528,7 @@ private: S32 mHighlightedItem; class LLViewBorder* mBorder; - LLContextMenu *mPopupMenu; + LLHandle<LLContextMenu> mPopupMenuHandle; LLView *mCommentTextView; diff --git a/indra/llui/lltabcontainer.cpp b/indra/llui/lltabcontainer.cpp index 0aa7a2d217..8c841540a5 100644 --- a/indra/llui/lltabcontainer.cpp +++ b/indra/llui/lltabcontainer.cpp @@ -1442,6 +1442,11 @@ void LLTabContainer::selectLastTab() void LLTabContainer::selectNextTab() { + if (mTabList.size() == 0) + { + return; + } + BOOL tab_has_focus = FALSE; if (mCurrentTabIdx >= 0 && mTabList[mCurrentTabIdx]->mButton->hasFocus()) { diff --git a/indra/llui/lltextbase.cpp b/indra/llui/lltextbase.cpp index 8effd866e0..82a3c01c6d 100644 --- a/indra/llui/lltextbase.cpp +++ b/indra/llui/lltextbase.cpp @@ -273,6 +273,12 @@ LLTextBase::LLTextBase(const LLTextBase::Params &p) LLTextBase::~LLTextBase() { mSegments.clear(); + LLContextMenu* menu = static_cast<LLContextMenu*>(mPopupMenuHandle.get()); + if (menu) + { + menu->die(); + mPopupMenuHandle.markDead(); + } delete mURLClickSignal; delete mIsFriendSignal; delete mIsObjectBlockedSignal; diff --git a/indra/llui/lltexteditor.cpp b/indra/llui/lltexteditor.cpp index b1f8b00cab..3d2a426913 100644 --- a/indra/llui/lltexteditor.cpp +++ b/indra/llui/lltexteditor.cpp @@ -257,7 +257,6 @@ LLTextEditor::LLTextEditor(const LLTextEditor::Params& p) : mMouseDownY(0), mTabsToNextField(p.ignore_tab), mPrevalidateFunc(p.prevalidate_callback()), - mContextMenu(NULL), mShowContextMenu(p.show_context_menu), mEnableTooltipPaste(p.enable_tooltip_paste), mPassDelete(FALSE), @@ -301,8 +300,13 @@ LLTextEditor::~LLTextEditor() // Scrollbar is deleted by LLView std::for_each(mUndoStack.begin(), mUndoStack.end(), DeletePointer()); mUndoStack.clear(); - // context menu is owned by menu holder, not us - //delete mContextMenu; + // Mark the menu as dead or its retained in memory till shutdown. + LLContextMenu* menu = static_cast<LLContextMenu*>(mContextMenuHandle.get()); + if(menu) + { + menu->die(); + mContextMenuHandle.markDead(); + } } //////////////////////////////////////////////////////////// @@ -2051,12 +2055,19 @@ void LLTextEditor::setEnabled(BOOL enabled) void LLTextEditor::showContextMenu(S32 x, S32 y) { - if (!mContextMenu) + LLContextMenu* menu = static_cast<LLContextMenu*>(mContextMenuHandle.get()); + if (!menu) { llassert(LLMenuGL::sMenuContainer != NULL); - mContextMenu = LLUICtrlFactory::instance().createFromFile<LLContextMenu>("menu_text_editor.xml", + menu = LLUICtrlFactory::createFromFile<LLContextMenu>("menu_text_editor.xml", LLMenuGL::sMenuContainer, LLMenuHolderGL::child_registry_t::instance()); + if(!menu) + { + LL_WARNS() << "Failed to create menu for LLTextEditor: " << getName() << LL_ENDL; + return; + } + mContextMenuHandle = menu->getHandle(); } // Route menu to this class @@ -2102,11 +2113,11 @@ void LLTextEditor::showContextMenu(S32 x, S32 y) } } - mContextMenu->setItemVisible("Suggestion Separator", (use_spellcheck) && (!mSuggestionList.empty())); - mContextMenu->setItemVisible("Add to Dictionary", (use_spellcheck) && (is_misspelled)); - mContextMenu->setItemVisible("Add to Ignore", (use_spellcheck) && (is_misspelled)); - mContextMenu->setItemVisible("Spellcheck Separator", (use_spellcheck) && (is_misspelled)); - mContextMenu->show(screen_x, screen_y, this); + menu->setItemVisible("Suggestion Separator", (use_spellcheck) && (!mSuggestionList.empty())); + menu->setItemVisible("Add to Dictionary", (use_spellcheck) && (is_misspelled)); + menu->setItemVisible("Add to Ignore", (use_spellcheck) && (is_misspelled)); + menu->setItemVisible("Spellcheck Separator", (use_spellcheck) && (is_misspelled)); + menu->show(screen_x, screen_y, this); } diff --git a/indra/llui/lltexteditor.h b/indra/llui/lltexteditor.h index 1a10d2fd1e..f3939248c2 100644 --- a/indra/llui/lltexteditor.h +++ b/indra/llui/lltexteditor.h @@ -329,7 +329,7 @@ private: keystroke_signal_t mKeystrokeSignal; LLTextValidate::validate_func_t mPrevalidateFunc; - LLContextMenu* mContextMenu; + LLHandle<LLContextMenu> mContextMenuHandle; }; // end class LLTextEditor // Build time optimization, generate once in .cpp file diff --git a/indra/llui/lltoolbar.cpp b/indra/llui/lltoolbar.cpp index 5150df25f2..2707f7a15c 100644 --- a/indra/llui/lltoolbar.cpp +++ b/indra/llui/lltoolbar.cpp @@ -127,7 +127,12 @@ LLToolBar::LLToolBar(const LLToolBar::Params& p) LLToolBar::~LLToolBar() { - delete mPopupMenuHandle.get(); + auto menu = mPopupMenuHandle.get(); + if (menu) + { + menu->die(); + mPopupMenuHandle.markDead(); + } delete mButtonAddSignal; delete mButtonEnterSignal; delete mButtonLeaveSignal; diff --git a/indra/llui/llurlentry.cpp b/indra/llui/llurlentry.cpp index 1547a4ba5c..6a9070634c 100644 --- a/indra/llui/llurlentry.cpp +++ b/indra/llui/llurlentry.cpp @@ -206,6 +206,7 @@ bool LLUrlEntryBase::isWikiLinkCorrect(const std::string &labeled_url) const { return (chr == L'\u02D0') // "Modifier Letter Colon" || (chr == L'\uFF1A') // "Fullwidth Colon" + || (chr == L'\u2236') // "Ratio" || (chr == L'\uFE55'); // "Small Colon" }, L'\u003A'); // Colon diff --git a/indra/llui/llurlregistry.cpp b/indra/llui/llurlregistry.cpp index c9d7013a11..23f3dca3fb 100644 --- a/indra/llui/llurlregistry.cpp +++ b/indra/llui/llurlregistry.cpp @@ -169,7 +169,7 @@ bool LLUrlRegistry::findUrl(const std::string &text, LLUrlMatch &match, const LL for (it = mUrlEntry.begin(); it != mUrlEntry.end(); ++it) { //Skip for url entry icon if content is not trusted - if(!is_content_trusted && (mUrlEntryIcon == *it)) + if((mUrlEntryIcon == *it) && ((text.find("Hand") != std::string::npos) || !is_content_trusted)) { continue; } diff --git a/indra/llwindow/CMakeLists.txt b/indra/llwindow/CMakeLists.txt index 55befaef51..ca08e38f77 100644 --- a/indra/llwindow/CMakeLists.txt +++ b/indra/llwindow/CMakeLists.txt @@ -14,26 +14,9 @@ include(00-Common) include(DragDrop) include(LLCommon) include(LLImage) -include(LLMath) -include(LLRender) -include(LLFileSystem) include(LLWindow) -include(LLXML) include(UI) - -include_directories( - ${LLCOMMON_INCLUDE_DIRS} - ${LLIMAGE_INCLUDE_DIRS} - ${LLMATH_INCLUDE_DIRS} - ${LLRENDER_INCLUDE_DIRS} - ${LLFILESYSTEM_INCLUDE_DIRS} - ${LLWINDOW_INCLUDE_DIRS} - ${LLXML_INCLUDE_DIRS} - ) -include_directories(SYSTEM - ${LLCOMMON_SYSTEM_INCLUDE_DIRS} - ${LLXML_SYSTEM_INCLUDE_DIRS} - ) +include(ViewerMiscLibs) set(llwindow_SOURCE_FILES llcursortypes.cpp @@ -64,22 +47,21 @@ set(viewer_HEADER_FILES llmousehandler.h ) +set(llwindow_LINK_LIBRARIES + llcommon + llimage + llmath + llrender + llfilesystem + llxml + ll::glh_linear + ll::glext + ll::uilibraries + ll::SDL + ) # Libraries on which this library depends, needed for Linux builds # Sort by high-level to low-level if (LINUX) - set(llwindow_LINK_LIBRARIES - ${LLCOMMON_LIBRARIES} - ${LLIMAGE_LIBRARIES} - ${LLMATH_LIBRARIES} - ${LLRENDER_LIBRARIES} - ${LLFILESYSTEM_LIBRARIES} - ${LLWINDOW_LIBRARIES} - ${LLXML_LIBRARIES} - ${UI_LIBRARIES} # for GTK - ${SDL_LIBRARY} - fontconfig # For FCInit and other FC* functions. - ) - list(APPEND viewer_SOURCE_FILES llkeyboardsdl.cpp llwindowsdl.cpp @@ -157,9 +139,6 @@ if (SOLARIS) ) endif (SOLARIS) -set_source_files_properties(${llwindow_HEADER_FILES} - PROPERTIES HEADER_FILE_ONLY TRUE) - if (BUILD_HEADLESS) set(llwindowheadless_SOURCE_FILES llwindowmesaheadless.cpp @@ -197,10 +176,10 @@ if (SDL_FOUND) endif (SDL_FOUND) target_link_libraries (llwindow ${llwindow_LINK_LIBRARIES}) + target_include_directories(llwindow INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}) if (DARWIN) include(CMakeFindFrameworks) find_library(CARBON_LIBRARY Carbon) target_link_libraries(llwindow ${CARBON_LIBRARY}) endif (DARWIN) - diff --git a/indra/llwindow/lldxhardware.cpp b/indra/llwindow/lldxhardware.cpp index 81e938edbe..391a377280 100644 --- a/indra/llwindow/lldxhardware.cpp +++ b/indra/llwindow/lldxhardware.cpp @@ -1098,7 +1098,7 @@ LLSD LLDXHardware::getDisplayInfo() } LCleanup: - if (ret.emptyMap()) + if (!ret.isMap() || (ret.size() == 0)) { LL_INFOS() << "Failed to get data, cleaning up" << LL_ENDL; } diff --git a/indra/llwindow/llwindowmacosx-objc.h b/indra/llwindow/llwindowmacosx-objc.h index 43edc0110d..77024d3a9c 100644 --- a/indra/llwindow/llwindowmacosx-objc.h +++ b/indra/llwindow/llwindowmacosx-objc.h @@ -83,7 +83,7 @@ int createNSApp(int argc, const char **argv); void setupCocoa(); bool pasteBoardAvailable(); bool copyToPBoard(const unsigned short *str, unsigned int len); -const unsigned short *copyFromPBoard(); +unsigned short *copyFromPBoard(); CursorRef createImageCursor(const char *fullpath, int hotspotX, int hotspotY); short releaseImageCursor(CursorRef ref); short setImageCursor(CursorRef ref); diff --git a/indra/llwindow/llwindowmacosx-objc.mm b/indra/llwindow/llwindowmacosx-objc.mm index 5ec9b017cf..690fe058db 100644 --- a/indra/llwindow/llwindowmacosx-objc.mm +++ b/indra/llwindow/llwindowmacosx-objc.mm @@ -49,14 +49,12 @@ void setupCocoa() if(!inited) { - NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; - - // The following prevents the Cocoa command line parser from trying to open 'unknown' arguements as documents. - // ie. running './secondlife -set Language fr' would cause a pop-up saying can't open document 'fr' - // when init'ing the Cocoa App window. - [[NSUserDefaults standardUserDefaults] setObject:@"NO" forKey:@"NSTreatUnknownArgumentsAsOpen"]; - - [pool release]; + @autoreleasepool { + // The following prevents the Cocoa command line parser from trying to open 'unknown' arguements as documents. + // ie. running './secondlife -set Language fr' would cause a pop-up saying can't open document 'fr' + // when init'ing the Cocoa App window. + [[NSUserDefaults standardUserDefaults] setObject:@"NO" forKey:@"NSTreatUnknownArgumentsAsOpen"]; + } inited = true; } @@ -64,13 +62,13 @@ void setupCocoa() bool copyToPBoard(const unsigned short *str, unsigned int len) { - NSAutoreleasePool *pool = [[NSAutoreleasePool alloc]init]; - NSPasteboard *pboard = [NSPasteboard generalPasteboard]; - [pboard clearContents]; - - NSArray *contentsToPaste = [[NSArray alloc] initWithObjects:[NSString stringWithCharacters:str length:len], nil]; - [pool release]; - return [pboard writeObjects:contentsToPaste]; + @autoreleasepool { + NSPasteboard *pboard = [NSPasteboard generalPasteboard]; + [pboard clearContents]; + + NSArray *contentsToPaste = [[[NSArray alloc] initWithObjects:[NSString stringWithCharacters:str length:len], nil] autorelease]; + return [pboard writeObjects:contentsToPaste]; + } } bool pasteBoardAvailable() @@ -79,39 +77,39 @@ bool pasteBoardAvailable() return [[NSPasteboard generalPasteboard] canReadObjectForClasses:classArray options:[NSDictionary dictionary]]; } -const unsigned short *copyFromPBoard() +unsigned short *copyFromPBoard() { - NSAutoreleasePool *pool = [[NSAutoreleasePool alloc]init]; - NSPasteboard *pboard = [NSPasteboard generalPasteboard]; - NSArray *classArray = [NSArray arrayWithObject:[NSString class]]; - NSString *str = NULL; - BOOL ok = [pboard canReadObjectForClasses:classArray options:[NSDictionary dictionary]]; - if (ok) - { - NSArray *objToPaste = [pboard readObjectsForClasses:classArray options:[NSDictionary dictionary]]; - str = [objToPaste objectAtIndex:0]; - } - unichar* temp = (unichar*)calloc([str length]+1, sizeof(unichar)); - [str getCharacters:temp]; - [pool release]; - return temp; + @autoreleasepool { + NSPasteboard *pboard = [NSPasteboard generalPasteboard]; + NSArray *classArray = [NSArray arrayWithObject:[NSString class]]; + NSString *str = NULL; + BOOL ok = [pboard canReadObjectForClasses:classArray options:[NSDictionary dictionary]]; + if (ok) + { + NSArray *objToPaste = [pboard readObjectsForClasses:classArray options:[NSDictionary dictionary]]; + str = [objToPaste objectAtIndex:0]; + } + NSUInteger str_len = [str length]; + unichar* temp = (unichar*)calloc(str_len+1, sizeof(unichar)); + [str getCharacters:temp range:NSMakeRange(0, str_len)]; + return temp; + } } CursorRef createImageCursor(const char *fullpath, int hotspotX, int hotspotY) { - NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; - - // extra retain on the NSCursor since we want it to live for the lifetime of the app. - NSCursor *cursor = - [[[NSCursor alloc] - initWithImage: - [[[NSImage alloc] initWithContentsOfFile: - [NSString stringWithUTF8String:fullpath] - ]autorelease] - hotSpot:NSMakePoint(hotspotX, hotspotY) - ]retain]; - - [pool release]; + NSCursor *cursor = nil; + @autoreleasepool { + // extra retain on the NSCursor since we want it to live for the lifetime of the app. + cursor = + [[[NSCursor alloc] + initWithImage: + [[[NSImage alloc] initWithContentsOfFile: + [NSString stringWithUTF8String:fullpath] + ] autorelease] + hotSpot:NSMakePoint(hotspotX, hotspotY) + ] retain]; + } return (CursorRef)cursor; } @@ -178,10 +176,10 @@ OSErr releaseImageCursor(CursorRef ref) { if( ref != NULL ) { - NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; - NSCursor *cursor = (NSCursor*)ref; - [cursor release]; - [pool release]; + @autoreleasepool { + NSCursor *cursor = (NSCursor*)ref; + [cursor autorelease]; + } } else { @@ -195,10 +193,10 @@ OSErr setImageCursor(CursorRef ref) { if( ref != NULL ) { - NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; - NSCursor *cursor = (NSCursor*)ref; - [cursor set]; - [pool release]; + @autoreleasepool { + NSCursor *cursor = (NSCursor*)ref; + [cursor set]; + } } else { @@ -217,6 +215,7 @@ NSWindowRef createNSWindow(int x, int y, int width, int height) styleMask:NSTitledWindowMask | NSResizableWindowMask | NSClosableWindowMask | NSMiniaturizableWindowMask | NSTexturedBackgroundWindowMask backing:NSBackingStoreBuffered defer:NO]; [window makeKeyAndOrderFront:nil]; [window setAcceptsMouseMovedEvents:TRUE]; + [window setRestorable:FALSE]; // Viewer manages state from own settings return window; } @@ -419,24 +418,26 @@ void requestUserAttention() long showAlert(std::string text, std::string title, int type) { - NSAlert *alert = [[NSAlert alloc] init]; - - [alert setMessageText:[NSString stringWithCString:title.c_str() encoding:[NSString defaultCStringEncoding]]]; - [alert setInformativeText:[NSString stringWithCString:text.c_str() encoding:[NSString defaultCStringEncoding]]]; - if (type == 0) - { - [alert addButtonWithTitle:@"Okay"]; - } else if (type == 1) - { - [alert addButtonWithTitle:@"Okay"]; - [alert addButtonWithTitle:@"Cancel"]; - } else if (type == 2) - { - [alert addButtonWithTitle:@"Yes"]; - [alert addButtonWithTitle:@"No"]; + long ret = 0; + @autoreleasepool { + NSAlert *alert = [[[NSAlert alloc] init] autorelease]; + + [alert setMessageText:[NSString stringWithCString:title.c_str() encoding:[NSString defaultCStringEncoding]]]; + [alert setInformativeText:[NSString stringWithCString:text.c_str() encoding:[NSString defaultCStringEncoding]]]; + if (type == 0) + { + [alert addButtonWithTitle:@"Okay"]; + } else if (type == 1) + { + [alert addButtonWithTitle:@"Okay"]; + [alert addButtonWithTitle:@"Cancel"]; + } else if (type == 2) + { + [alert addButtonWithTitle:@"Yes"]; + [alert addButtonWithTitle:@"No"]; + } + ret = [alert runModal]; } - long ret = [alert runModal]; - [alert dealloc]; if (ret == NSAlertFirstButtonReturn) { diff --git a/indra/llwindow/llwindowmacosx.cpp b/indra/llwindow/llwindowmacosx.cpp index c29131d60b..a0fc91399b 100644 --- a/indra/llwindow/llwindowmacosx.cpp +++ b/indra/llwindow/llwindowmacosx.cpp @@ -634,7 +634,6 @@ BOOL LLWindowMacOSX::createContext(int x, int y, int width, int height, int bits // Get the view instead. mGLView = createOpenGLView(mWindow, mFSAASamples, enable_vsync); mContext = getCGLContextObj(mGLView); - gGLManager.mVRAM = getVramSize(mGLView); } @@ -668,11 +667,11 @@ BOOL LLWindowMacOSX::createContext(int x, int y, int width, int height, int bits if (cgl_err != kCGLNoError ) { - LL_DEBUGS("GLInit") << "Multi-threaded OpenGL not available." << LL_ENDL; + LL_INFOS("GLInit") << "Multi-threaded OpenGL not available." << LL_ENDL; } else { - LL_DEBUGS("GLInit") << "Multi-threaded OpenGL enabled." << LL_ENDL; + LL_INFOS("GLInit") << "Multi-threaded OpenGL enabled." << LL_ENDL; } } makeFirstResponder(mWindow, mGLView); @@ -1246,8 +1245,11 @@ BOOL LLWindowMacOSX::isClipboardTextAvailable() } BOOL LLWindowMacOSX::pasteTextFromClipboard(LLWString &dst) -{ - llutf16string str(copyFromPBoard()); +{ + unsigned short* pboard_data = copyFromPBoard(); // must free returned data + llutf16string str(pboard_data); + free(pboard_data); + dst = utf16str_to_wstring(str); if (dst != L"") { @@ -1280,7 +1282,7 @@ LLWindow::LLWindowResolution* LLWindowMacOSX::getSupportedResolutions(S32 &num_r { if (!mSupportedResolutions) { - CFArrayRef modes = CGDisplayAvailableModes(mDisplay); + CFArrayRef modes = CGDisplayCopyAllDisplayModes(mDisplay, nullptr); if(modes != NULL) { @@ -1319,6 +1321,7 @@ LLWindow::LLWindowResolution* LLWindowMacOSX::getSupportedResolutions(S32 &num_r } } } + CFRelease(modes); } } diff --git a/indra/llwindow/llwindowmacosx.h b/indra/llwindow/llwindowmacosx.h index b0f339e1db..851c860017 100644 --- a/indra/llwindow/llwindowmacosx.h +++ b/indra/llwindow/llwindowmacosx.h @@ -228,6 +228,7 @@ protected: BOOL mLanguageTextInputAllowed; LLPreeditor* mPreeditor; +public: static BOOL sUseMultGL; friend class LLWindowManager; diff --git a/indra/llwindow/llwindowwin32.cpp b/indra/llwindow/llwindowwin32.cpp index 41f3042ace..6f67b131d1 100644 --- a/indra/llwindow/llwindowwin32.cpp +++ b/indra/llwindow/llwindowwin32.cpp @@ -3904,42 +3904,48 @@ void LLWindowWin32::allowLanguageTextInput(LLPreeditor *preeditor, BOOL b) sLanguageTextInputAllowed = b; - if ( sLanguageTextInputAllowed ) - { - // Allowing: Restore the previous IME status, so that the user has a feeling that the previous - // text input continues naturally. Be careful, however, the IME status is meaningful only during the user keeps - // using same Input Locale (aka Keyboard Layout). - if (sWinIMEOpened && GetKeyboardLayout(0) == sWinInputLocale) - { - HIMC himc = LLWinImm::getContext(mWindowHandle); - LLWinImm::setOpenStatus(himc, TRUE); - LLWinImm::setConversionStatus(himc, sWinIMEConversionMode, sWinIMESentenceMode); - LLWinImm::releaseContext(mWindowHandle, himc); - } - } - else - { - // Disallowing: Turn off the IME so that succeeding key events bypass IME and come to us directly. - // However, do it after saving the current IME status. We need to restore the status when - // allowing language text input again. - sWinInputLocale = GetKeyboardLayout(0); - sWinIMEOpened = LLWinImm::isIME(sWinInputLocale); - if (sWinIMEOpened) - { - HIMC himc = LLWinImm::getContext(mWindowHandle); - sWinIMEOpened = LLWinImm::getOpenStatus(himc); - if (sWinIMEOpened) - { - LLWinImm::getConversionStatus(himc, &sWinIMEConversionMode, &sWinIMESentenceMode); + if (sLanguageTextInputAllowed) + { + mWindowThread->post([=]() + { + // Allowing: Restore the previous IME status, so that the user has a feeling that the previous + // text input continues naturally. Be careful, however, the IME status is meaningful only during the user keeps + // using same Input Locale (aka Keyboard Layout). + if (sWinIMEOpened && GetKeyboardLayout(0) == sWinInputLocale) + { + HIMC himc = LLWinImm::getContext(mWindowHandle); + LLWinImm::setOpenStatus(himc, TRUE); + LLWinImm::setConversionStatus(himc, sWinIMEConversionMode, sWinIMESentenceMode); + LLWinImm::releaseContext(mWindowHandle, himc); + } + }); + } + else + { + mWindowThread->post([=]() + { + // Disallowing: Turn off the IME so that succeeding key events bypass IME and come to us directly. + // However, do it after saving the current IME status. We need to restore the status when + // allowing language text input again. + sWinInputLocale = GetKeyboardLayout(0); + sWinIMEOpened = LLWinImm::isIME(sWinInputLocale); + if (sWinIMEOpened) + { + HIMC himc = LLWinImm::getContext(mWindowHandle); + sWinIMEOpened = LLWinImm::getOpenStatus(himc); + if (sWinIMEOpened) + { + LLWinImm::getConversionStatus(himc, &sWinIMEConversionMode, &sWinIMESentenceMode); - // We need both ImmSetConversionStatus and ImmSetOpenStatus here to surely disable IME's - // keyboard hooking, because Some IME reacts only on the former and some other on the latter... - LLWinImm::setConversionStatus(himc, IME_CMODE_NOCONVERSION, sWinIMESentenceMode); - LLWinImm::setOpenStatus(himc, FALSE); - } - LLWinImm::releaseContext(mWindowHandle, himc); - } - } + // We need both ImmSetConversionStatus and ImmSetOpenStatus here to surely disable IME's + // keyboard hooking, because Some IME reacts only on the former and some other on the latter... + LLWinImm::setConversionStatus(himc, IME_CMODE_NOCONVERSION, sWinIMESentenceMode); + LLWinImm::setOpenStatus(himc, FALSE); + } + LLWinImm::releaseContext(mWindowHandle, himc); + } + }); + } } void LLWindowWin32::fillCandidateForm(const LLCoordGL& caret, const LLRect& bounds, @@ -4136,6 +4142,10 @@ void LLWindowWin32::handleStartCompositionMessage() void LLWindowWin32::handleCompositionMessage(const U32 indexes) { + if (!mPreeditor) + { + return; + } BOOL needs_update = FALSE; LLWString result_string; LLWString preedit_string; @@ -4434,7 +4444,7 @@ BOOL LLWindowWin32::handleImeRequests(WPARAM request, LPARAM param, LRESULT *res LLWString context = find_context(wtext, preedit, preedit_length, &context_offset); preedit -= context_offset; preedit_length = llmin(preedit_length, (S32)context.length() - preedit); - if (preedit_length && preedit >= 0) + if (preedit_length > 0 && preedit >= 0) { // IMR_DOCUMENTFEED may be called when we have an active preedit. // We should pass the context string *excluding* the preedit string. diff --git a/indra/llxml/CMakeLists.txt b/indra/llxml/CMakeLists.txt index 3a7a54e51d..508c2b919b 100644 --- a/indra/llxml/CMakeLists.txt +++ b/indra/llxml/CMakeLists.txt @@ -4,18 +4,6 @@ project(llxml) include(00-Common) include(LLCommon) -include(LLMath) -include(LLFileSystem) -include(LLXML) - -include_directories( - ${LLCOMMON_INCLUDE_DIRS} - ${LLMATH_INCLUDE_DIRS} - ${LLFILESYSTEM_INCLUDE_DIRS} - ) -include_directories( - ${LLCOMMON_SYSTEM_INCLUDE_DIRS} - ) set(llxml_SOURCE_FILES llcontrol.cpp @@ -33,20 +21,19 @@ set(llxml_HEADER_FILES llxmltree.h ) -set_source_files_properties(${llxml_HEADER_FILES} - PROPERTIES HEADER_FILE_ONLY TRUE) - list(APPEND llxml_SOURCE_FILES ${llxml_HEADER_FILES}) add_library (llxml ${llxml_SOURCE_FILES}) # Libraries on which this library depends, needed for Linux builds # Sort by high-level to low-level target_link_libraries( llxml - ${LLFILESYSTEM_LIBRARIES} - ${LLMATH_LIBRARIES} - ${LLCOMMON_LIBRARIES} - ${EXPAT_LIBRARIES} + llfilesystem + llmath + llcommon + ll::expat ) +target_include_directories( llxml INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}) + # tests @@ -62,11 +49,10 @@ if (LL_TESTS) # set(TEST_DEBUG on) set(test_libs - ${LLXML_LIBRARIES} - ${WINDOWS_LIBRARIES} - ${LLMATH_LIBRARIES} - ${LLCOMMON_LIBRARIES} - ) + llxml + llmath + llcommon + ) LL_ADD_INTEGRATION_TEST(llcontrol "" "${test_libs}") endif (LL_TESTS) diff --git a/indra/media_plugins/CMakeLists.txt b/indra/media_plugins/CMakeLists.txt index 1a5cc8ec9a..972bb7dd2d 100644 --- a/indra/media_plugins/CMakeLists.txt +++ b/indra/media_plugins/CMakeLists.txt @@ -3,8 +3,7 @@ add_subdirectory(base) if (LINUX) - add_subdirectory(gstreamer010) - add_subdirectory(libvlc) + #add_subdirectory(gstreamer010) add_subdirectory(example) endif (LINUX) diff --git a/indra/media_plugins/base/CMakeLists.txt b/indra/media_plugins/base/CMakeLists.txt index 7f2b82ffdd..64b6a4228d 100644 --- a/indra/media_plugins/base/CMakeLists.txt +++ b/indra/media_plugins/base/CMakeLists.txt @@ -5,25 +5,9 @@ project(media_plugin_base) include(00-Common) include(LLCommon) include(LLImage) -include(LLPlugin) -include(LLMath) -include(LLRender) include(LLWindow) include(Linking) include(PluginAPI) -include(OpenGL) - -include_directories( - ${LLPLUGIN_INCLUDE_DIRS} - ${LLCOMMON_INCLUDE_DIRS} - ${LLMATH_INCLUDE_DIRS} - ${LLIMAGE_INCLUDE_DIRS} - ${LLRENDER_INCLUDE_DIRS} - ${LLWINDOW_INCLUDE_DIRS} -) -include_directories(SYSTEM - ${LLCOMMON_SYSTEM_INCLUDE_DIRS} - ) ### media_plugin_base @@ -48,5 +32,7 @@ set(media_plugin_base_HEADER_FILES add_library(media_plugin_base ${media_plugin_base_SOURCE_FILES} - ) + ) +target_link_libraries( media_plugin_base llplugin ) +target_include_directories( media_plugin_base INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}) diff --git a/indra/media_plugins/cef/CMakeLists.txt b/indra/media_plugins/cef/CMakeLists.txt index 2acce03d08..410778114d 100644 --- a/indra/media_plugins/cef/CMakeLists.txt +++ b/indra/media_plugins/cef/CMakeLists.txt @@ -5,29 +5,12 @@ project(media_plugin_cef) include(Boost) include(00-Common) include(LLCommon) -include(LLPlugin) -include(LLMath) -include(LLRender) include(LLWindow) include(Linking) include(PluginAPI) -include(MediaPluginBase) include(CEFPlugin) -include_directories( - ${LLPLUGIN_INCLUDE_DIRS} - ${MEDIA_PLUGIN_BASE_INCLUDE_DIRS} - ${LLCOMMON_INCLUDE_DIRS} - ${LLMATH_INCLUDE_DIRS} - ${LLRENDER_INCLUDE_DIRS} - ${LLWINDOW_INCLUDE_DIRS} - ${CEF_INCLUDE_DIR} -) -include_directories(SYSTEM - ${LLCOMMON_SYSTEM_INCLUDE_DIRS} - ) - ### media_plugin_cef @@ -47,13 +30,6 @@ set(media_plugin_cef_HEADER_FILES volume_catcher.h ) -set (media_plugin_cef_LINK_LIBRARIES - ${LLPLUGIN_LIBRARIES} - ${MEDIA_PLUGIN_BASE_LIBRARIES} - ${CEF_PLUGIN_LIBRARIES} - ${LLCOMMON_LIBRARIES} - ${PLUGIN_API_WINDOWS_LIBRARIES}) - # Select which VolumeCatcher implementation to use if (LINUX) message(FATAL_ERROR "CEF plugin has been enabled for a Linux compile.\n" @@ -62,7 +38,7 @@ elseif (DARWIN) list(APPEND media_plugin_cef_SOURCE_FILES mac_volume_catcher_null.cpp) find_library(CORESERVICES_LIBRARY CoreServices) find_library(AUDIOUNIT_LIBRARY AudioUnit) - list(APPEND media_plugin_cef_LINK_LIBRARIES + set( media_plugin_cef_LINK_LIBRARIES ${CORESERVICES_LIBRARY} # for Component Manager calls ${AUDIOUNIT_LIBRARY} # for AudioUnit calls ) @@ -70,9 +46,6 @@ elseif (WINDOWS) list(APPEND media_plugin_cef_SOURCE_FILES windows_volume_catcher.cpp) endif (LINUX) -set_source_files_properties(${media_plugin_cef_HEADER_FILES} - PROPERTIES HEADER_FILE_ONLY TRUE) - list(APPEND media_plugin_cef_SOURCE_FILES ${media_plugin_cef_HEADER_FILES}) add_library(media_plugin_cef @@ -85,7 +58,8 @@ add_library(media_plugin_cef #) target_link_libraries(media_plugin_cef - ${media_plugin_cef_LINK_LIBRARIES} + media_plugin_base + ll::cef ) if (WINDOWS) @@ -93,7 +67,6 @@ if (WINDOWS) media_plugin_cef PROPERTIES LINK_FLAGS "/MANIFEST:NO /SAFESEH:NO /NODEFAULTLIB:LIBCMT /IGNORE:4099" - LINK_FLAGS_DEBUG "/MANIFEST:NO /SAFESEH:NO /NODEFAULTLIB:LIBCMTD /IGNORE:4099" ) endif (WINDOWS) diff --git a/indra/media_plugins/example/CMakeLists.txt b/indra/media_plugins/example/CMakeLists.txt index eb067a7f6e..7d3e7f663b 100644 --- a/indra/media_plugins/example/CMakeLists.txt +++ b/indra/media_plugins/example/CMakeLists.txt @@ -5,31 +5,12 @@ project(media_plugin_example) include(00-Common) include(LLCommon) include(LLImage) -include(LLPlugin) -include(LLMath) -include(LLRender) include(LLWindow) include(Linking) include(PluginAPI) -include(MediaPluginBase) -include(OpenGL) include(ExamplePlugin) -include_directories( - ${LLPLUGIN_INCLUDE_DIRS} - ${MEDIA_PLUGIN_BASE_INCLUDE_DIRS} - ${LLCOMMON_INCLUDE_DIRS} - ${LLMATH_INCLUDE_DIRS} - ${LLIMAGE_INCLUDE_DIRS} - ${LLRENDER_INCLUDE_DIRS} - ${LLWINDOW_INCLUDE_DIRS} -) -include_directories(SYSTEM - ${LLCOMMON_SYSTEM_INCLUDE_DIRS} - ) - - ### media_plugin_example if(NOT ADDRESS_SIZE EQUAL 32) @@ -49,21 +30,7 @@ add_library(media_plugin_example ${media_plugin_example_SOURCE_FILES} ) -target_link_libraries(media_plugin_example - ${LLPLUGIN_LIBRARIES} - ${MEDIA_PLUGIN_BASE_LIBRARIES} - ${LLCOMMON_LIBRARIES} - ${EXAMPLE_PLUGIN_LIBRARIES} - ${PLUGIN_API_WINDOWS_LIBRARIES} -) - -add_dependencies(media_plugin_example - ${LLPLUGIN_LIBRARIES} - ${MEDIA_PLUGIN_BASE_LIBRARIES} - # Using ${LLCOMMON_LIBRARIES} here drags in a whole bunch of Boost stuff - # that only produces CMake warnings about nonexistent dependencies. - llcommon -) +target_link_libraries(media_plugin_example media_plugin_base ) if (WINDOWS) set_target_properties( diff --git a/indra/media_plugins/gstreamer010/CMakeLists.txt b/indra/media_plugins/gstreamer010/CMakeLists.txt index 571eb57b24..38fc8201bf 100644 --- a/indra/media_plugins/gstreamer010/CMakeLists.txt +++ b/indra/media_plugins/gstreamer010/CMakeLists.txt @@ -5,32 +5,14 @@ project(media_plugin_gstreamer010) include(00-Common) include(LLCommon) include(LLImage) -include(LLPlugin) include(LLMath) -include(LLRender) include(LLWindow) include(Linking) include(PluginAPI) -include(MediaPluginBase) include(OpenGL) include(GStreamer010Plugin) -include_directories( - ${LLPLUGIN_INCLUDE_DIRS} - ${MEDIA_PLUGIN_BASE_INCLUDE_DIRS} - ${LLCOMMON_INCLUDE_DIRS} - ${LLMATH_INCLUDE_DIRS} - ${LLIMAGE_INCLUDE_DIRS} - ${LLRENDER_INCLUDE_DIRS} - ${LLWINDOW_INCLUDE_DIRS} - ${GSTREAMER010_INCLUDE_DIRS} - ${GSTREAMER010_PLUGINS_BASE_INCLUDE_DIRS} -) -include_directories(SYSTEM - ${LLCOMMON_SYSTEM_INCLUDE_DIRS} - ) - ### media_plugin_gstreamer010 if(NOT ADDRESS_SIZE EQUAL 32) @@ -59,17 +41,6 @@ add_library(media_plugin_gstreamer010 ) target_link_libraries(media_plugin_gstreamer010 - ${LLPLUGIN_LIBRARIES} - ${MEDIA_PLUGIN_BASE_LIBRARIES} - ${LLCOMMON_LIBRARIES} - ${PLUGIN_API_WINDOWS_LIBRARIES} - ${GSTREAMER010_LIBRARIES} -) - -add_dependencies(media_plugin_gstreamer010 - ${LLPLUGIN_LIBRARIES} - ${MEDIA_PLUGIN_BASE_LIBRARIES} - ${LLCOMMON_LIBRARIES} -) - - + media_plugin_base + ll::gstreamer + ) diff --git a/indra/media_plugins/libvlc/CMakeLists.txt b/indra/media_plugins/libvlc/CMakeLists.txt index 97392bbe08..a3c1c4ef99 100644 --- a/indra/media_plugins/libvlc/CMakeLists.txt +++ b/indra/media_plugins/libvlc/CMakeLists.txt @@ -5,32 +5,12 @@ project(media_plugin_libvlc) include(00-Common) include(LLCommon) include(LLImage) -include(LLPlugin) -include(LLMath) -include(LLRender) include(LLWindow) include(Linking) include(PluginAPI) -include(MediaPluginBase) -include(OpenGL) include(LibVLCPlugin) -include_directories( - ${LLPLUGIN_INCLUDE_DIRS} - ${MEDIA_PLUGIN_BASE_INCLUDE_DIRS} - ${LLCOMMON_INCLUDE_DIRS} - ${LLMATH_INCLUDE_DIRS} - ${LLIMAGE_INCLUDE_DIRS} - ${LLRENDER_INCLUDE_DIRS} - ${LLWINDOW_INCLUDE_DIRS} - ${VLC_INCLUDE_DIR} -) -include_directories(SYSTEM - ${LLCOMMON_SYSTEM_INCLUDE_DIRS} - ) - - ### media_plugin_libvlc if(NOT ADDRESS_SIZE EQUAL 32) @@ -51,27 +31,8 @@ add_library(media_plugin_libvlc ) target_link_libraries(media_plugin_libvlc - ${LLPLUGIN_LIBRARIES} - ${MEDIA_PLUGIN_BASE_LIBRARIES} - ${LLCOMMON_LIBRARIES} - ${VLC_PLUGIN_LIBRARIES} - ${PLUGIN_API_WINDOWS_LIBRARIES} -) - -add_dependencies(media_plugin_libvlc - ${LLPLUGIN_LIBRARIES} - ${MEDIA_PLUGIN_BASE_LIBRARIES} -##${LLCOMMON_LIBRARIES} - # Just say 'llcommon' here. LLCOMMON_LIBRARIES is specified for use in - # target_link_libraries: it includes several Boost libraries, which are - # absolutely NOT dependencies in the sense intended here. Those Boost - # library macros, in turn, specify 'debug' and 'optimized' and a different - # library name for each, producing several wordy errors: - # Policy CMP0046 is not set: Error on non-existent dependency in - # add_dependencies. - # Really, the only dependency we should mention from LLCOMMON_LIBRARIES is - # llcommon itself. - llcommon + media_plugin_base + ll::libvlc ) if (WINDOWS) diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index 9eee5338ec..361718a13e 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -23,25 +23,13 @@ include(JsonCpp) include(LLAppearance) include(LLAudio) include(LLCA) -include(LLCharacter) include(LLCommon) include(LLCoreHttp) include(LLImage) -include(LLImageJ2COJ) -include(LLInventory) include(LLKDU) -include(LLLogin) -include(LLMath) -include(LLMeshOptimizer) -include(LLMessage) include(LLPhysicsExtensions) -include(LLPlugin) include(LLPrimitive) -include(LLRender) -include(LLUI) -include(LLFileSystem) include(LLWindow) -include(LLXML) include(NDOF) include(NVAPI) include(OPENAL) @@ -52,64 +40,36 @@ include(TemplateCheck) include(ThreeJS) include(Tracy) include(UI) -include(UnixInstall) include(ViewerMiscLibs) include(ViewerManager) include(VisualLeakDetector) include(ZLIBNG) include(URIPARSER) +include(LLPrimitive) if (NOT HAVOK_TPV) # When using HAVOK_TPV, the library is precompiled, so no need for this - add_subdirectory(${LLPHYSICSEXTENSIONS_SRC_DIR} llphysicsextensions) -endif (NOT HAVOK_TPV) -if(FMODSTUDIO) - include_directories(${FMODSTUDIO_INCLUDE_DIR}) -endif(FMODSTUDIO) - -include_directories( - ${DBUSGLIB_INCLUDE_DIRS} - ${JSONCPP_INCLUDE_DIR} - ${LLAUDIO_INCLUDE_DIRS} - ${LLCHARACTER_INCLUDE_DIRS} - ${LLCOMMON_INCLUDE_DIRS} - ${LLCOREHTTP_INCLUDE_DIRS} - ${LLPHYSICS_INCLUDE_DIRS} - ${LLIMAGE_INCLUDE_DIRS} - ${LLKDU_INCLUDE_DIRS} - ${LLINVENTORY_INCLUDE_DIRS} - ${LLMATH_INCLUDE_DIRS} - ${LLMESHOPTIMIZER_INCLUDE_DIRS} - ${LLMESSAGE_INCLUDE_DIRS} - ${LLPLUGIN_INCLUDE_DIRS} - ${LLPRIMITIVE_INCLUDE_DIRS} - ${LLRENDER_INCLUDE_DIRS} - ${LLUI_INCLUDE_DIRS} - ${LLFILESYSTEM_INCLUDE_DIRS} - ${LLWINDOW_INCLUDE_DIRS} - ${LLXML_INCLUDE_DIRS} - ${LLLOGIN_INCLUDE_DIRS} - ${LIBS_PREBUILT_DIR}/include/collada - ${LIBS_PREBUILD_DIR}/include/hunspell - ${OPENAL_LIB_INCLUDE_DIRS} - ${LIBS_PREBUILT_DIR}/include/collada/1.4 - ${LLAPPEARANCE_INCLUDE_DIRS} - ${CMAKE_CURRENT_SOURCE_DIR} - ${TRACY_INCLUDE_DIR} - ) + # Stub and probably havok lib itself is a hack, autobuild loads a 3p that really is a source tarball + # which includes a CMakeList.txt and then this whole source tree gets pushed into out build ... :/ + # To make matters worse there is a internal assumption about the structure of the viewers CMake layout, + # which means we need to duct tape this togther ... -include_directories(SYSTEM - ${LLCOMMON_SYSTEM_INCLUDE_DIRS} - ${LLXML_SYSTEM_INCLUDE_DIRS} - ${LLPHYSICSEXTENSIONS_INCLUDE_DIRS} - ) + add_subdirectory(${LLPHYSICSEXTENSIONS_SRC_DIR} llphysicsextensions) + + # Another hack that works with newer cmake versions: + cmake_policy( SET CMP0079 NEW) + if( TARGET llphysicsextensionsstub ) + target_link_libraries(llphysicsextensionsstub llcommon llmath) + endif() + if( TARGET llphysicsextensions ) + target_link_libraries(llphysicsextensions llrender ) + if (DARWIN) + target_compile_options( llphysicsextensions PRIVATE -Wno-unused-local-typedef) + endif (DARWIN) + endif() +endif (NOT HAVOK_TPV) -if (USE_BUGSPLAT) - include_directories(AFTER - ${BUGSPLAT_INCLUDE_DIR} - ) -endif (USE_BUGSPLAT) set(viewer_SOURCE_FILES groupchatlistener.cpp @@ -1414,25 +1374,6 @@ if (DARWIN) COMPILE_FLAGS "-fmodules -fcxx-modules -Wno-nullability-completeness" ) - find_library(AGL_LIBRARY AGL) - find_library(APPKIT_LIBRARY AppKit) - find_library(COCOA_LIBRARY Cocoa) - find_library(IOKIT_LIBRARY IOKit) - find_library(COREAUDIO_LIBRARY CoreAudio) - - set(viewer_LIBRARIES - ${COCOA_LIBRARY} - ${AGL_LIBRARY} - ${IOKIT_LIBRARY} - ${COREAUDIO_LIBRARY} - ) - - if (USE_BUGSPLAT) - list(APPEND viewer_LIBRARIES - ${BUGSPLAT_LIBRARIES} - ) - endif (USE_BUGSPLAT) - # Add resource files to the project. set(viewer_RESOURCE_FILES secondlife.icns @@ -1446,12 +1387,7 @@ if (DARWIN) Japanese.lproj/language.txt Korean.lproj/language.txt ) - set_source_files_properties( - ${viewer_RESOURCE_FILES} - PROPERTIES - HEADER_FILE_ONLY TRUE - #MACOSX_PACKAGE_LOCATION Resources #don't do this! this tells cmake to copy the files. - ) + SOURCE_GROUP("Resources" FILES ${viewer_RESOURCE_FILES}) list(APPEND viewer_SOURCE_FILES ${viewer_RESOURCE_FILES}) endif (DARWIN) @@ -1466,12 +1402,6 @@ if (LINUX) LIST(APPEND viewer_SOURCE_FILES llappviewerlinux_api_dbus.cpp) SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--as-needed") - set(viewer_LIBRARIES - Xinerama - ) - if (OPENAL) - LIST(APPEND viewer_LIBRARIES ${OPENAL_LIBRARIES}) - endif (OPENAL) endif (LINUX) if (WINDOWS) @@ -1490,19 +1420,6 @@ if (WINDOWS) llwindebug.h ) - # precompiled header configuration - # llviewerprecompiledheaders.cpp generates - # the .pch file. - # All sources added to viewer_SOURCE_FILES - # at this point use it. - if(USE_PRECOMPILED_HEADERS) - set_source_files_properties(llviewerprecompiledheaders.cpp - PROPERTIES - COMPILE_FLAGS "/Ycllviewerprecompiledheaders.h" - ) - set(viewer_SOURCE_FILES "${viewer_SOURCE_FILES}" llviewerprecompiledheaders.cpp) - endif(USE_PRECOMPILED_HEADERS) - # Replace the icons with the appropriate ones for the channel # ('test' is the default) set(ICON_PATH "test") @@ -1599,26 +1516,7 @@ if (WINDOWS) SOURCE_GROUP("Resource Files" FILES ${viewer_RESOURCE_FILES}) - if (NOT USESYSTEMLIBS) - list(APPEND viewer_SOURCE_FILES ${viewer_RESOURCE_FILES}) - endif (NOT USESYSTEMLIBS) - -# see EXP-1765 - theory is opengl32.lib needs to be included before gdi32.lib (windows libs) - set(viewer_LIBRARIES - opengl32 - ${WINDOWS_LIBRARIES} - comdlg32 - dxguid - imm32 - kernel32 - odbc32 - odbccp32 - oleaut32 - shell32 - Vfw32 - wer - winspool - ) + list(APPEND viewer_SOURCE_FILES ${viewer_RESOURCE_FILES}) find_library(INTEL_MEMOPS_LIBRARY NAMES ll_intel_memops @@ -1628,8 +1526,10 @@ if (WINDOWS) ) mark_as_advanced(INTEL_MEMOPS_LIBRARY) + if (INTEL_MEMOPS_LIBRARY) - list(APPEND viewer_LIBRARIES ${INTEL_MEMOPS_LIBRARY}) + add_library( ll::intel_memops INTERFACE IMPORTED ) + target_link_libraries( ll::intel_memops ${INTEL_MEMOPS_LIBRARY} ) endif (INTEL_MEMOPS_LIBRARY) if (ADDRESS_SIZE EQUAL 64) @@ -1641,9 +1541,6 @@ if (WINDOWS) LIST(APPEND viewer_SOURCE_FILES windows.manifest) endif (ADDRESS_SIZE EQUAL 64) - if (OPENAL) - LIST(APPEND viewer_LIBRARIES ${OPENAL_LIBRARIES}) - endif (OPENAL) endif (WINDOWS) # Add the xui files. This is handy for searching for xui elements @@ -1722,9 +1619,7 @@ source_group("Character File" FILES ${viewer_CHARACTER_FILES}) set_source_files_properties(${viewer_CHARACTER_FILES} PROPERTIES HEADER_FILE_ONLY TRUE) -if (NOT USESYSTEMLIBS) - list(APPEND viewer_SOURCE_FILES ${viewer_CHARACTER_FILES}) -endif (NOT USESYSTEMLIBS) +list(APPEND viewer_SOURCE_FILES ${viewer_CHARACTER_FILES}) if (WINDOWS) file(GLOB viewer_INSTALLER_FILES installers/windows/*.nsi) @@ -1737,28 +1632,18 @@ if (WINDOWS) list(APPEND viewer_SOURCE_FILES ${viewer_INSTALLER_FILES}) endif (WINDOWS) -if (OPENAL) - set(LLSTARTUP_COMPILE_FLAGS "${LLSTARTUP_COMPILE_FLAGS} -DLL_OPENAL") -endif (OPENAL) - -if (FMODSTUDIO) - set(LLSTARTUP_COMPILE_FLAGS "${LLSTARTUP_COMPILE_FLAGS} -DLL_FMODSTUDIO") - set(FMODWRAPPER_LIBRARY ${FMODSTUDIO_LIBRARY}) -endif (FMODSTUDIO) - -set_source_files_properties(llstartup.cpp PROPERTIES COMPILE_FLAGS "${LLSTARTUP_COMPILE_FLAGS}") - if (HAVOK OR HAVOK_TPV) set(LLSTARTUP_COMPILE_FLAGS "${LLSTARTUP_COMPILE_FLAGS} -DLL_HAVOK") endif (HAVOK OR HAVOK_TPV) -# progress view disables/enables icons based on available packages -set_source_files_properties(llprogressview.cpp PROPERTIES COMPILE_FLAGS "${LLSTARTUP_COMPILE_FLAGS}") +if( DEFINED LLSTARTUP_COMPILE_FLAGS ) + # progress view disables/enables icons based on available packages + set_source_files_properties(llprogressview.cpp PROPERTIES COMPILE_FLAGS "${LLSTARTUP_COMPILE_FLAGS}") -list(APPEND viewer_SOURCE_FILES ${viewer_HEADER_FILES}) + set_source_files_properties(llstartup.cpp PROPERTIES COMPILE_FLAGS "${LLSTARTUP_COMPILE_FLAGS}") +endif() -set_source_files_properties(${viewer_HEADER_FILES} - PROPERTIES HEADER_FILE_ONLY TRUE) +list(APPEND viewer_SOURCE_FILES ${viewer_HEADER_FILES}) add_executable(${VIEWER_BINARY_NAME} WIN32 @@ -1766,17 +1651,6 @@ add_executable(${VIEWER_BINARY_NAME} ${viewer_SOURCE_FILES} ) -if (SDL_FOUND) - set_property(TARGET ${VIEWER_BINARY_NAME} - PROPERTY COMPILE_DEFINITIONS LL_SDL=1 - ) -endif (SDL_FOUND) - -if (USE_BUGSPLAT) - set_property(TARGET ${VIEWER_BINARY_NAME} - PROPERTY COMPILE_DEFINITIONS "${BUGSPLAT_DEFINE}") -endif (USE_BUGSPLAT) - # add package files file(GLOB EVENT_HOST_SCRIPT_GLOB_LIST ${CMAKE_CURRENT_SOURCE_DIR}/../viewer_components/*.py) @@ -1795,11 +1669,7 @@ if (WINDOWS) ) if(USE_PRECOMPILED_HEADERS) - set_target_properties( - ${VIEWER_BINARY_NAME} - PROPERTIES - COMPILE_FLAGS "/Yullviewerprecompiledheaders.h" - ) + target_precompile_headers( ${VIEWER_BINARY_NAME} PRIVATE llviewerprecompiledheaders.h ) endif(USE_PRECOMPILED_HEADERS) # If adding a file to viewer_manifest.py in the WindowsManifest.construct() method, be sure to add the dependency @@ -1818,67 +1688,51 @@ if (WINDOWS) # The following commented dependencies are determined at variably at build time. Can't do this here. ${CMAKE_SOURCE_DIR}/../etc/message.xml ${CMAKE_SOURCE_DIR}/../scripts/messages/message_template.msg - ${SHARED_LIB_STAGING_DIR}/${CMAKE_CFG_INTDIR}/llcommon.dll - ${SHARED_LIB_STAGING_DIR}/${CMAKE_CFG_INTDIR}/libapr-1.dll - ${SHARED_LIB_STAGING_DIR}/${CMAKE_CFG_INTDIR}/libaprutil-1.dll - ${SHARED_LIB_STAGING_DIR}/${CMAKE_CFG_INTDIR}/libapriconv-1.dll - ${SHARED_LIB_STAGING_DIR}/Release/libcollada14dom22.dll - ${SHARED_LIB_STAGING_DIR}/RelWithDebInfo/libcollada14dom22.dll - ${SHARED_LIB_STAGING_DIR}/Debug/libcollada14dom22-d.dll - ${SHARED_LIB_STAGING_DIR}/Release/openjpeg.dll - ${SHARED_LIB_STAGING_DIR}/RelWithDebInfo/openjpeg.dll - ${SHARED_LIB_STAGING_DIR}/Debug/openjpegd.dll - ${SHARED_LIB_STAGING_DIR}/Release/libhunspell.dll - ${SHARED_LIB_STAGING_DIR}/RelWithDebInfo/libhunspell.dll - ${SHARED_LIB_STAGING_DIR}/Debug/libhunspell.dll - ${SHARED_LIB_STAGING_DIR}/Release/uriparser.dll - ${SHARED_LIB_STAGING_DIR}/RelWithDebInfo/uriparser.dll - ${SHARED_LIB_STAGING_DIR}/${CMAKE_CFG_INTDIR}/SLVoice.exe - ${SHARED_LIB_STAGING_DIR}/${CMAKE_CFG_INTDIR}/libsndfile-1.dll - ${SHARED_LIB_STAGING_DIR}/${CMAKE_CFG_INTDIR}/vivoxoal.dll - ${SHARED_LIB_STAGING_DIR}/${CMAKE_CFG_INTDIR}/ca-bundle.crt - ${GOOGLE_PERF_TOOLS_SOURCE} + ${SHARED_LIB_STAGING_DIR}/openjp2.dll + ${SHARED_LIB_STAGING_DIR}/libhunspell.dll + ${SHARED_LIB_STAGING_DIR}/uriparser.dll + #${SHARED_LIB_STAGING_DIR}/${LL_INTDIR}/SLVoice.exe + #${SHARED_LIB_STAGING_DIR}/${LL_INTDIR}/libsndfile-1.dll + #${SHARED_LIB_STAGING_DIR}/${LL_INTDIR}/vivoxoal.dll + ${AUTOBUILD_INSTALL_DIR}/ca-bundle.crt ${CMAKE_CURRENT_SOURCE_DIR}/licenses-win32.txt ${CMAKE_CURRENT_SOURCE_DIR}/featuretable.txt - ${CMAKE_CURRENT_SOURCE_DIR}/featuretable_xp.txt ${viewer_APPSETTINGS_FILES} SLPlugin media_plugin_cef media_plugin_libvlc media_plugin_example - winmm_shim ) if (ADDRESS_SIZE EQUAL 64) - list(APPEND COPY_INPUT_DEPENDENCIES - ${SHARED_LIB_STAGING_DIR}/${CMAKE_CFG_INTDIR}/vivoxsdk_x64.dll - ${SHARED_LIB_STAGING_DIR}/${CMAKE_CFG_INTDIR}/ortp_x64.dll - ${ARCH_PREBUILT_DIRS_RELEASE}/libcrypto-1_1-x64.dll - ${ARCH_PREBUILT_DIRS_RELEASE}/libssl-1_1-x64.dll - ) + list(APPEND COPY_INPUT_DEPENDENCIES + ${SHARED_LIB_STAGING_DIR}/vivoxsdk_x64.dll + ${SHARED_LIB_STAGING_DIR}/ortp_x64.dll + ${ARCH_PREBUILT_DIRS_RELEASE}/libcrypto-1_1-x64.dll + ${ARCH_PREBUILT_DIRS_RELEASE}/libssl-1_1-x64.dll + ) else (ADDRESS_SIZE EQUAL 64) - list(APPEND COPY_INPUT_DEPENDENCIES - ${SHARED_LIB_STAGING_DIR}/${CMAKE_CFG_INTDIR}/vivoxsdk.dll - ${SHARED_LIB_STAGING_DIR}/${CMAKE_CFG_INTDIR}/ortp.dll - ${ARCH_PREBUILT_DIRS_RELEASE}/libcrypto-1_1.dll - ${ARCH_PREBUILT_DIRS_RELEASE}/libssl-1_1.dll - ) + list(APPEND COPY_INPUT_DEPENDENCIES + ${SHARED_LIB_STAGING_DIR}/vivoxsdk.dll + ${SHARED_LIB_STAGING_DIR}/ortp.dll + ${ARCH_PREBUILT_DIRS_RELEASE}/libcrypto-1_1.dll + ${ARCH_PREBUILT_DIRS_RELEASE}/libssl-1_1.dll + ) endif (ADDRESS_SIZE EQUAL 64) - if (FMODSTUDIO) + if (TARGET ll::fmodstudio) list(APPEND COPY_INPUT_DEPENDENCIES - ${SHARED_LIB_STAGING_DIR}/Release/fmod.dll - ${SHARED_LIB_STAGING_DIR}/RelWithDebInfo/fmod.dll + ${SHARED_LIB_STAGING_DIR}/fmod.dll ${SHARED_LIB_STAGING_DIR}/Debug/fmodL.dll ) - endif (FMODSTUDIO) + endif () - if (OPENAL) + if (TARGET ll::openal) list(APPEND COPY_INPUT_DEPENDENCIES - ${SHARED_LIB_STAGING_DIR}/${CMAKE_CFG_INTDIR}/OpenAL32.dll - ${SHARED_LIB_STAGING_DIR}/${CMAKE_CFG_INTDIR}/alut.dll + ${SHARED_LIB_STAGING_DIR}/OpenAL32.dll + ${SHARED_LIB_STAGING_DIR}/alut.dll ) - endif (OPENAL) + endif () add_custom_command( OUTPUT ${CMAKE_CFG_INTDIR}/copy_touched.bat @@ -1889,16 +1743,16 @@ if (WINDOWS) --arch=${ARCH} --artwork=${ARTWORK_DIR} "--bugsplat=${BUGSPLAT_DB}" - "--fmodstudio=${FMODSTUDIO}" - "--openal=${OPENAL}" + "--fmodstudio=${USE_FMODSTUDIO}" + "--openal=${USE_OPENAL}" --build=${CMAKE_CURRENT_BINARY_DIR} - --buildtype=${CMAKE_BUILD_TYPE} + --buildtype=$<CONFIG> "--channel=${VIEWER_CHANNEL}" --configuration=${CMAKE_CFG_INTDIR} - --dest=${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR} + --dest=${CMAKE_CURRENT_BINARY_DIR}/$<IF:$<BOOL:${LL_GENERATOR_IS_MULTI_CONFIG}>,$<CONFIG>,> --grid=${GRID} --source=${CMAKE_CURRENT_SOURCE_DIR} - --touch=${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/copy_touched.bat + --touch=${CMAKE_CURRENT_BINARY_DIR}/$<IF:$<BOOL:${LL_GENERATOR_IS_MULTI_CONFIG}>,$<CONFIG>,>/copy_touched.bat --versionfile=${CMAKE_CURRENT_BINARY_DIR}/viewer_version.txt DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/viewer_manifest.py @@ -1945,21 +1799,21 @@ if (WINDOWS) OUTPUT ${CMAKE_CFG_INTDIR}/touched.bat COMMAND ${PYTHON_EXECUTABLE} ARGS - ${CMAKE_CURRENT_SOURCE_DIR}/viewer_manifest.py - --arch=${ARCH} - --artwork=${ARTWORK_DIR} - "--bugsplat=${BUGSPLAT_DB}" - "--fmodstudio=${FMODSTUDIO}" - "--openal=${OPENAL}" - --build=${CMAKE_CURRENT_BINARY_DIR} - --buildtype=${CMAKE_BUILD_TYPE} - "--channel=${VIEWER_CHANNEL}" - --configuration=${CMAKE_CFG_INTDIR} - --dest=${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR} - --grid=${GRID} - --source=${CMAKE_CURRENT_SOURCE_DIR} - --touch=${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/touched.bat - --versionfile=${CMAKE_CURRENT_BINARY_DIR}/viewer_version.txt + ${CMAKE_CURRENT_SOURCE_DIR}/viewer_manifest.py + --arch=${ARCH} + --artwork=${ARTWORK_DIR} + "--bugsplat=${BUGSPLAT_DB}" + "--fmodstudio=${USE_FMODSTUDIO}" + "--openal=${USE_OPENAL}" + --build=${CMAKE_CURRENT_BINARY_DIR} + --buildtype=$<CONFIG> + "--channel=${VIEWER_CHANNEL}" + --configuration=${CMAKE_CFG_INTDIR} + --dest=${CMAKE_CURRENT_BINARY_DIR}/$<IF:$<BOOL:${LL_GENERATOR_IS_MULTI_CONFIG}>,$<CONFIG>,> + --grid=${GRID} + --source=${CMAKE_CURRENT_SOURCE_DIR} + --touch=${CMAKE_CURRENT_BINARY_DIR}/$<IF:$<BOOL:${LL_GENERATOR_IS_MULTI_CONFIG}>,$<CONFIG>,>/touched.bat + --versionfile=${CMAKE_CURRENT_BINARY_DIR}/viewer_version.txt DEPENDS ${VIEWER_BINARY_NAME} ${CMAKE_CURRENT_SOURCE_DIR}/viewer_manifest.py @@ -1968,8 +1822,7 @@ if (WINDOWS) ) add_custom_target(llpackage ALL DEPENDS - ${CMAKE_CFG_INTDIR}/touched.bat - windows-setup-build-all + ${CMAKE_CFG_INTDIR}/touched.bat ) # temporarily disable packaging of event_host until hg subrepos get # sorted out on the parabuild cluster... @@ -2018,61 +1871,38 @@ endif (WINDOWS) # modern version. target_link_libraries(${VIEWER_BINARY_NAME} - ${LEGACY_STDIO_LIBS} - ${PNG_PRELOAD_ARCHIVES} - ${ZLIBNG_PRELOAD_ARCHIVES} - ${URIPARSER_PRELOAD_ARCHIVES} - ${GOOGLE_PERFTOOLS_LIBRARIES} - ${LLAUDIO_LIBRARIES} - ${LLCHARACTER_LIBRARIES} - ${LLIMAGE_LIBRARIES} - ${LLINVENTORY_LIBRARIES} - ${LLMESHOPTIMIZER_LIBRARIES} - ${LLMESSAGE_LIBRARIES} - ${LLPLUGIN_LIBRARIES} - ${LLPRIMITIVE_LIBRARIES} - ${LLRENDER_LIBRARIES} - ${FREETYPE_LIBRARIES} - ${LLUI_LIBRARIES} - ${LLFILESYSTEM_LIBRARIES} - ${LLWINDOW_LIBRARIES} - ${LLXML_LIBRARIES} - ${LLMATH_LIBRARIES} - ${LLCOREHTTP_LIBRARIES} - ${LLCOMMON_LIBRARIES} - ${NDOF_LIBRARY} - ${NVAPI_LIBRARY} - ${HUNSPELL_LIBRARY} - ${viewer_LIBRARIES} - ${BOOST_PROGRAM_OPTIONS_LIBRARY} - ${BOOST_REGEX_LIBRARY} - ${BOOST_FIBER_LIBRARY} - ${BOOST_CONTEXT_LIBRARY} - ${DBUSGLIB_LIBRARIES} - ${OPENGL_LIBRARIES} - ${FMODWRAPPER_LIBRARY} # must come after LLAudio - ${OPENGL_LIBRARIES} - ${JSONCPP_LIBRARIES} - ${SDL_LIBRARY} - ${SMARTHEAP_LIBRARY} - ${UI_LIBRARIES} - ${WINDOWS_LIBRARIES} - ${EXPAT_LIBRARIES} - ${XMLRPCEPI_LIBRARIES} - ${OPENSSL_LIBRARIES} - ${CRYPTO_LIBRARIES} - ${LLLOGIN_LIBRARIES} - ${LLPHYSICS_LIBRARIES} - ${LLPHYSICSEXTENSIONS_LIBRARIES} - ${LLAPPEARANCE_LIBRARIES} - ${TRACY_LIBRARY} - ) + llaudio + llcharacter + llimage + llinventory + llmessage + llplugin + llprimitive + llrender + llui + llfilesystem + llwindow + llxml + llmath + llcorehttp + llcommon + llmeshoptimizer + ll::ndof + lllogin + llprimitive + llappearance + ${LLPHYSICSEXTENSIONS_LIBRARIES} + ll::bugsplat + ll::tracy + ) -if (USE_BUGSPLAT) - target_link_libraries(${VIEWER_BINARY_NAME} - ${BUGSPLAT_LIBRARIES} - ) -endif (USE_BUGSPLAT) +if( TARGET ll::intel_memops ) + target_link_libraries(${VIEWER_BINARY_NAME} ll::intel_memops ) +endif() + +if( TARGET ll::nvapi ) + target_link_libraries(${VIEWER_BINARY_NAME} ll::nvapi ) +endif() set(ARTWORK_DIR ${CMAKE_CURRENT_SOURCE_DIR} CACHE PATH "Path to artwork files.") @@ -2084,14 +1914,13 @@ if (LINUX) set(COPY_INPUT_DEPENDENCIES ${VIEWER_BINARY_NAME} SLPlugin - media_plugin_gstreamer010 - media_plugin_libvlc + #media_plugin_gstreamer010 llcommon ) - if (NOT USE_BUGSPLAT) - LIST(APPEND COPY_INPUT_DEPENDENCIES linux-crash-logger) - endif (NOT USE_BUGSPLAT) + #if (NOT USE_BUGSPLAT) + # LIST(APPEND COPY_INPUT_DEPENDENCIES linux-crash-logger) + #endif (NOT USE_BUGSPLAT) add_custom_command( OUTPUT ${product}.tar.bz2 @@ -2101,8 +1930,8 @@ if (LINUX) --arch=${ARCH} --artwork=${ARTWORK_DIR} "--bugsplat=${BUGSPLAT_DB}" - "--fmodstudio=${FMODSTUDIO}" - "--openal=${OPENAL}" + "--fmodstudio=${USE_FMODSTUDIO}" + "--openal=${USE_OPENAL}" --build=${CMAKE_CURRENT_BINARY_DIR} --buildtype=${CMAKE_BUILD_TYPE} "--channel=${VIEWER_CHANNEL}" @@ -2129,8 +1958,8 @@ if (LINUX) --arch=${ARCH} --artwork=${ARTWORK_DIR} "--bugsplat=${BUGSPLAT_DB}" - "--fmodstudio=${FMODSTUDIO}" - "--openal=${OPENAL}" + "--fmodstudio=${USE_FMODSTUDIO}" + "--openal=${USE_OPENAL}" --build=${CMAKE_CURRENT_BINARY_DIR} --buildtype=${CMAKE_BUILD_TYPE} "--channel=${VIEWER_CHANNEL}" @@ -2188,7 +2017,7 @@ if (DARWIN) XCODE_ATTRIBUTE_PRODUCT_BUNDLE_IDENTIFIER "${MACOSX_BUNDLE_GUI_IDENTIFIER}" ) - set(VIEWER_APP_BUNDLE "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/${product}.app") + set(VIEWER_APP_BUNDLE "${CMAKE_CURRENT_BINARY_DIR}/$<IF:$<BOOL:${LL_GENERATOR_IS_MULTI_CONFIG}>,$<CONFIG>,>/${product}.app") set(VIEWER_APP_EXE "${VIEWER_APP_BUNDLE}/Contents/MacOS/${product}") set(VIEWER_APP_DSYM "${VIEWER_APP_EXE}.dSYM") set(VIEWER_APP_XCARCHIVE "${VIEWER_APP_BUNDLE}/../${product}.xcarchive.zip") @@ -2207,10 +2036,10 @@ if (DARWIN) --arch=${ARCH} --artwork=${ARTWORK_DIR} "--bugsplat=${BUGSPLAT_DB}" - "--fmodstudio=${FMODSTUDIO}" - "--openal=${OPENAL}" + "--fmodstudio=${USE_FMODSTUDIO}" + "--openal=${USE_OPENAL}" --build=${CMAKE_CURRENT_BINARY_DIR} - --buildtype=${CMAKE_BUILD_TYPE} + --buildtype=$<CONFIG> --bundleid=${MACOSX_BUNDLE_GUI_IDENTIFIER} "--channel=${VIEWER_CHANNEL}" --configuration=${CMAKE_CFG_INTDIR} @@ -2238,22 +2067,22 @@ if (DARWIN) TARGET llpackage POST_BUILD COMMAND ${PYTHON_EXECUTABLE} ARGS - ${CMAKE_CURRENT_SOURCE_DIR}/viewer_manifest.py - --arch=${ARCH} - --artwork=${ARTWORK_DIR} - "--bugsplat=${BUGSPLAT_DB}" - "--fmodstudio=${FMODSTUDIO}" - "--openal=${OPENAL}" - --build=${CMAKE_CURRENT_BINARY_DIR} - --buildtype=${CMAKE_BUILD_TYPE} - "--channel=${VIEWER_CHANNEL}" - --configuration=${CMAKE_CFG_INTDIR} - --dest=${VIEWER_APP_BUNDLE} - --grid=${GRID} - --source=${CMAKE_CURRENT_SOURCE_DIR} - --touch=${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/.${product}.touched - --versionfile=${CMAKE_CURRENT_BINARY_DIR}/viewer_version.txt - ${SIGNING_SETTING} + ${CMAKE_CURRENT_SOURCE_DIR}/viewer_manifest.py + --arch=${ARCH} + --artwork=${ARTWORK_DIR} + "--bugsplat=${BUGSPLAT_DB}" + "--fmodstudio=${USE_FMODSTUDIO}" + "--openal=${USE_OPENAL}" + --build=${CMAKE_CURRENT_BINARY_DIR} + --buildtype=$<CONFIG> + "--channel=${VIEWER_CHANNEL}" + --configuration=${CMAKE_CFG_INTDIR} + --dest=${VIEWER_APP_BUNDLE} + --grid=${GRID} + --source=${CMAKE_CURRENT_SOURCE_DIR} + --touch=${CMAKE_CURRENT_BINARY_DIR}/$<IF:$<BOOL:${LL_GENERATOR_IS_MULTI_CONFIG}>,$<CONFIG>,>/.${product}.bat + --versionfile=${CMAKE_CURRENT_BINARY_DIR}/viewer_version.txt + ${SIGNING_SETTING} DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/viewer_manifest.py ) @@ -2382,10 +2211,15 @@ if (LL_TESTS) ) set(test_libs - ${LLCOMMON_LIBRARIES} - ${JSONCPP_LIBRARIES} - ${CURL_LIBRARIES} - ${NGHTTP2_LIBRARIES} + llcommon + llfilesystem + llxml + llmessage + llcharacter + llui + lllogin + llplugin + llappearance ) set_source_files_properties( @@ -2394,17 +2228,6 @@ if (LL_TESTS) LL_TEST_ADDITIONAL_LIBRARIES "${test_libs}" ) - set_source_files_properties( - llviewerhelputil.cpp - PROPERTIES - LL_TEST_ADDITIONAL_LIBRARIES "${BOOST_SYSTEM_LIBRARY}" - ) - - set_source_files_properties( - llremoteparcelrequest.cpp - PROPERTIES - LL_TEST_ADDITIONAL_LIBRARIES "${BOOST_SYSTEM_LIBRARY}" - ) set_source_files_properties( llworldmap.cpp @@ -2412,83 +2235,49 @@ if (LL_TESTS) PROPERTIES LL_TEST_ADDITIONAL_SOURCE_FILES tests/llviewertexture_stub.cpp - #llviewertexturelist.cpp - LL_TEST_ADDITIONAL_LIBRARIES "${BOOST_SYSTEM_LIBRARY}" ) set_source_files_properties( llmediadataclient.cpp PROPERTIES - LL_TEST_ADDITIONAL_LIBRARIES "${LLPRIMITIVE_LIBRARIES}" - ) - - set_source_files_properties( - llagentaccess.cpp - PROPERTIES - LL_TEST_ADDITIONAL_LIBRARIES "${BOOST_SYSTEM_LIBRARY}" + LL_TEST_ADDITIONAL_LIBRARIES llprimitive ) set_source_files_properties( lllogininstance.cpp PROPERTIES LL_TEST_ADDITIONAL_SOURCE_FILES llversioninfo.cpp - LL_TEST_ADDITIONAL_LIBRARIES "${BOOST_SYSTEM_LIBRARY}" + ) + set_property( SOURCE + ${viewer_TEST_SOURCE_FILES} + PROPERTY + LL_TEST_ADDITIONAL_LIBRARIES ${test_libs} ) - ################################################## - # DISABLING PRECOMPILED HEADERS USAGE FOR TESTS - ################################################## - # if(USE_PRECOMPILED_HEADERS) - # set_source_files_properties( - # ${viewer_TEST_SOURCE_FILES} - # PROPERTIES - # LL_TEST_ADDITIONAL_SOURCE_FILES llviewerprecompiledheaders.cpp - # ) - # endif(USE_PRECOMPILED_HEADERS) LL_ADD_PROJECT_UNIT_TESTS(${VIEWER_BINARY_NAME} "${viewer_TEST_SOURCE_FILES}") #set(TEST_DEBUG on) - ################################################## - # DISABLING PRECOMPILED HEADERS USAGE FOR TESTS - ################################################## - # if(USE_PRECOMPILED_HEADERS) - # set(test_sources "${test_sources}" llviewerprecompiledheaders.cpp) - # endif(USE_PRECOMPILED_HEADERS) - set(test_libs - ${LLMESSAGE_LIBRARIES} - ${WINDOWS_LIBRARIES} - ${LLFILESYSTEM_LIBRARIES} - ${LLMATH_LIBRARIES} - ${LLCOMMON_LIBRARIES} - ${GOOGLEMOCK_LIBRARIES} - ) - - if (LINUX) - # llcommon uses `clock_gettime' which is provided by librt on linux. - set(LIBRT_LIBRARY - rt - ) - endif (LINUX) set(test_libs - ${WINDOWS_LIBRARIES} - ${LLFILESYSTEM_LIBRARIES} - ${LLMATH_LIBRARIES} - ${LLCOMMON_LIBRARIES} - ${LLMESSAGE_LIBRARIES} - ${LLCOREHTTP_LIBRARIES} - ${GOOGLEMOCK_LIBRARIES} - ${OPENSSL_LIBRARIES} - ${CRYPTO_LIBRARIES} - ${LIBRT_LIBRARY} - ${BOOST_FIBER_LIBRARY} - ${BOOST_CONTEXT_LIBRARY} - ) + llfilesystem + llmath + llcommon + llmessage + llcorehttp + llxml + llui + llplugin + llappearance + lllogin + llprimitive + lllogin + ) LL_ADD_INTEGRATION_TEST(cppfeatures "" "${test_libs}" ) + LL_ADD_INTEGRATION_TEST(llsechandler_basic llsechandler_basic.cpp "${test_libs}" @@ -2504,7 +2293,6 @@ if (LL_TESTS) llviewernetwork.cpp ) - LL_ADD_INTEGRATION_TEST(llslurl "${llslurl_test_sources}" "${test_libs}" @@ -2527,15 +2315,6 @@ if (LL_TESTS) #ADD_VIEWER_BUILD_TEST(lltextureinfo viewer) #ADD_VIEWER_BUILD_TEST(lltextureinfodetails viewer) -include(LLAddBuildTest) -SET(viewer_TEST_SOURCE_FILES - llagentaccess.cpp - ) -set_source_files_properties( - ${viewer_TEST_SOURCE_FILES} - PROPERTIES - LL_TEST_ADDITIONAL_SOURCE_FILES llviewerprecompiledheaders.cpp - ) endif (LL_TESTS) diff --git a/indra/newview/VIEWER_VERSION.txt b/indra/newview/VIEWER_VERSION.txt index f5199477c5..8a68577213 100644 --- a/indra/newview/VIEWER_VERSION.txt +++ b/indra/newview/VIEWER_VERSION.txt @@ -1 +1 @@ -6.6.9 +6.6.11 diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 2f5bf7d148..3f6adfe13d 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -16876,5 +16876,16 @@ <key>Value</key> <string></string> </map> + <key>DebugSettingsHideDefault</key> + <map> + <key>Comment</key> + <string>Show non-default settings only in Debug Settings list</string> + <key>Persist</key> + <integer>0</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>0</integer> + </map> </map> </llsd> diff --git a/indra/newview/app_settings/settings_per_account.xml b/indra/newview/app_settings/settings_per_account.xml index 537744b44c..e89d1cbda4 100644 --- a/indra/newview/app_settings/settings_per_account.xml +++ b/indra/newview/app_settings/settings_per_account.xml @@ -220,6 +220,17 @@ <key>Value</key> <integer>1</integer> </map> + <key>FetchGroupChatHistory</key> + <map> + <key>Comment</key> + <string>Fetch recent messages from group chat servers when a group window opens</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>1</integer> + </map> <key>VoiceCallsFriendsOnly</key> <map> <key>Comment</key> diff --git a/indra/newview/app_settings/shaders/class1/deferred/skyF.glsl b/indra/newview/app_settings/shaders/class1/deferred/skyF.glsl index 331249dc33..de22312d3c 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/skyF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/skyF.glsl @@ -25,6 +25,17 @@ /*[EXTRA_CODE_HERE]*/ +// Inputs +VARYING vec4 vary_HazeColor; +VARYING float vary_LightNormPosDot; + +uniform sampler2D rainbow_map; +uniform sampler2D halo_map; + +uniform float moisture_level; +uniform float droplet_radius; +uniform float ice_level; + #ifdef DEFINE_GL_FRAGCOLOR out vec4 frag_data[3]; #else @@ -35,11 +46,34 @@ out vec4 frag_data[3]; // The fragment shader for the sky ///////////////////////////////////////////////////////////////////////// -VARYING vec4 vary_HazeColor; +vec3 rainbow(float d) +{ + // 'Interesting' values of d are -0.75 .. -0.825, i.e. when view vec nearly opposite of sun vec + // Rainbox tex is mapped with REPEAT, so -.75 as tex coord is same as 0.25. -0.825 -> 0.175. etc. + // SL-13629 + // Unfortunately the texture is inverted, so we need to invert the y coord, but keep the 'interesting' + // part within the same 0.175..0.250 range, i.e. d = (1 - d) - 1.575 + d = clamp(-0.575 - d, 0.0, 1.0); + + // With the colors in the lower 1/4 of the texture, inverting the coords leaves most of it inaccessible. + // So, we can stretch the texcoord above the colors (ie > 0.25) to fill the entire remaining coordinate + // space. This improves gradation, reduces banding within the rainbow interior. (1-0.25) / (0.425/0.25) = 4.2857 + float interior_coord = max(0.0, d - 0.25) * 4.2857; + d = clamp(d, 0.0, 0.25) + interior_coord; + + float rad = (droplet_radius - 5.0f) / 1024.0f; + return pow(texture2D(rainbow_map, vec2(rad+0.5, d)).rgb, vec3(1.8)) * moisture_level; +} + +vec3 halo22(float d) +{ + d = clamp(d, 0.1, 1.0); + float v = sqrt(clamp(1 - (d * d), 0, 1)); + return texture2D(halo_map, vec2(0, v)).rgb * ice_level; +} /// Soft clips the light with a gamma correction vec3 scaleSoftClip(vec3 light); -vec3 srgb_to_linear(vec3 c); void main() { @@ -48,14 +82,18 @@ void main() // the fragment) if the sky wouldn't show up because the clouds // are fully opaque. - vec4 color; - color = vary_HazeColor; + vec4 color = vary_HazeColor; + float rel_pos_lightnorm = vary_LightNormPosDot; + float optic_d = rel_pos_lightnorm; + vec3 halo_22 = halo22(optic_d); + color.rgb += rainbow(optic_d); + color.rgb += halo_22; color.rgb *= 2.; color.rgb = scaleSoftClip(color.rgb); - /// Gamma correct for WL (soft clip effect). - frag_data[0] = vec4(color.rgb, 0.0); + // Gamma correct for WL (soft clip effect). + frag_data[0] = vec4(color.rgb, 1.0); frag_data[1] = vec4(0.0,0.0,0.0,0.0); frag_data[2] = vec4(0.0,0.0,0.0,1.0); //1.0 in norm.w masks off fog diff --git a/indra/newview/app_settings/shaders/class1/deferred/skyV.glsl b/indra/newview/app_settings/shaders/class1/deferred/skyV.glsl index 28a1faf24f..6db4690bff 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/skyV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/skyV.glsl @@ -33,6 +33,7 @@ ATTRIBUTE vec3 position; // Output parameters VARYING vec4 vary_HazeColor; +VARYING float vary_LightNormPosDot; // Inputs uniform vec3 camPosLocal; @@ -72,27 +73,29 @@ void main() vec3 rel_pos = position.xyz - camPosLocal.xyz + vec3(0, 50, 0); // Adj position vector to clamp altitude - if (rel_pos.y > 0) + if (rel_pos.y > 0.) { rel_pos *= (max_y / rel_pos.y); } - if (rel_pos.y < 0) + if (rel_pos.y < 0.) { rel_pos *= (-32000. / rel_pos.y); } - // Can normalize then - vec3 rel_pos_norm = normalize(rel_pos); + // Normalized + vec3 rel_pos_norm = normalize(rel_pos); + float rel_pos_len = length(rel_pos); - float rel_pos_len = length(rel_pos); + // Grab this value and pass to frag shader for rainbows + float rel_pos_lightnorm_dot = dot(rel_pos_norm, lightnorm.xyz); + vary_LightNormPosDot = rel_pos_lightnorm_dot; // Initialize temp variables vec4 sunlight = (sun_up_factor == 1) ? sunlight_color : moonlight_color; - vec4 light_atten; // Sunlight attenuation effect (hue and brightness) due to atmosphere // this is used later for sunlight modulation at various altitudes - light_atten = (blue_density + vec4(haze_density * 0.25)) * (density_multiplier * max_y); + vec4 light_atten = (blue_density + vec4(haze_density * 0.25)) * (density_multiplier * max_y); // Calculate relative weights vec4 combined_haze = abs(blue_density) + vec4(abs(haze_density)); @@ -112,7 +115,7 @@ void main() combined_haze = exp(-combined_haze * density_dist); // Compute haze glow - float haze_glow = 1.0 - dot(rel_pos_norm, lightnorm.xyz); + float haze_glow = 1.0 - rel_pos_lightnorm_dot; // haze_glow is 0 at the sun and increases away from sun haze_glow = max(haze_glow, .001); // Set a minimum "angle" (smaller glow.y allows tighter, brighter hotspot) @@ -123,30 +126,30 @@ void main() // Add "minimum anti-solar illumination" // For sun, add to glow. For moon, remove glow entirely. SL-13768 - haze_glow = (sun_moon_glow_factor < 1.0) ? 0.0 : (haze_glow + 0.25); + haze_glow = (sun_moon_glow_factor < 1.0) ? 0.0 : (sun_moon_glow_factor * (haze_glow + 0.25)); - vec4 color = - (blue_horizon * blue_weight * (sunlight + ambient_color) + (haze_horizon * haze_weight) * (sunlight * haze_glow + ambient_color)); + // Haze color above cloud + vec4 color = (blue_horizon * blue_weight * (sunlight + ambient_color) + + (haze_horizon * haze_weight) * (sunlight * haze_glow + ambient_color)); // Final atmosphere additive color *= (1. - combined_haze); // Increase ambient when there are more clouds - vec4 tmpAmbient = ambient_color; - tmpAmbient += max(vec4(0), (1. - ambient_color)) * cloud_shadow * 0.5; + vec4 ambient = ambient_color + max(vec4(0), (1. - ambient_color)) * cloud_shadow * 0.5; // Dim sunlight by cloud shadow percentage sunlight *= max(0.0, (1. - cloud_shadow)); // Haze color below cloud - vec4 additiveColorBelowCloud = - (blue_horizon * blue_weight * (sunlight + tmpAmbient) + (haze_horizon * haze_weight) * (sunlight * haze_glow + tmpAmbient)); + vec4 add_below_cloud = (blue_horizon * blue_weight * (sunlight + ambient) + + (haze_horizon * haze_weight) * (sunlight * haze_glow + ambient)); // Attenuate cloud color by atmosphere combined_haze = sqrt(combined_haze); // less atmos opacity (more transparency) below clouds // At horizon, blend high altitude sky color towards the darker color below the clouds - color += (additiveColorBelowCloud - color) * (1. - sqrt(combined_haze)); + color += (add_below_cloud - color) * (1. - sqrt(combined_haze)); // Haze color above cloud vary_HazeColor = color; diff --git a/indra/newview/app_settings/shaders/class2/deferred/skyF.glsl b/indra/newview/app_settings/shaders/class2/deferred/skyF.glsl deleted file mode 100644 index 6841a8194f..0000000000 --- a/indra/newview/app_settings/shaders/class2/deferred/skyF.glsl +++ /dev/null @@ -1,199 +0,0 @@ -/** - * @file class2/deferred/skyF.glsl - * - * $LicenseInfo:firstyear=2005&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2005, Linden Research, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; - * version 2.1 of the License only. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA - * $/LicenseInfo$ - */ - -uniform mat4 modelview_projection_matrix; - -// SKY //////////////////////////////////////////////////////////////////////// -// The vertex shader for creating the atmospheric sky -/////////////////////////////////////////////////////////////////////////////// - -// Inputs -uniform vec3 camPosLocal; - -uniform vec4 lightnorm; -uniform vec4 sunlight_color; -uniform vec4 moonlight_color; -uniform int sun_up_factor; -uniform vec4 ambient_color; -uniform vec4 blue_horizon; -uniform vec4 blue_density; -uniform float haze_horizon; -uniform float haze_density; - -uniform float cloud_shadow; -uniform float density_multiplier; -uniform float distance_multiplier; -uniform float max_y; - -uniform vec4 glow; -uniform float sun_moon_glow_factor; - -uniform vec4 cloud_color; - -#ifdef DEFINE_GL_FRAGCOLOR -out vec4 frag_data[3]; -#else -#define frag_data gl_FragData -#endif - -VARYING vec3 pos; - -///////////////////////////////////////////////////////////////////////// -// The fragment shader for the sky -///////////////////////////////////////////////////////////////////////// - -uniform sampler2D rainbow_map; -uniform sampler2D halo_map; - -uniform float moisture_level; -uniform float droplet_radius; -uniform float ice_level; - -vec3 rainbow(float d) -{ - // d is the dot product of view and sun directions, so ranging -1.0..1.0 - // 'interesting' values of d are the range -0.75..-0.825, when view is nearly opposite of sun vec - // Rainbox texture mode is GL_REPEAT, so tc of -.75 is equiv to 0.25, -0.825 equiv to 0.175. - - // SL-13629 Rainbow texture has colors within the correct .175...250 range, but order is inverted. - // Rather than replace the texture, we mirror and translate the y tc to keep the colors within the - // interesting range, but in reversed order: i.e. d = (1 - d) - 1.575 - d = clamp(-0.575 - d, 0.0, 1.0); - - // With the colors in the lower 1/4 of the texture, inverting the coords leaves most of it inaccessible. - // So, we can stretch the texcoord above the colors (ie > 0.25) to fill the entire remaining coordinate - // space. This improves gradation, reduces banding within the rainbow interior. (1-0.25) / (0.425/0.25) = 4.2857 - float interior_coord = max(0.0, d - 0.25) * 4.2857; - d = clamp(d, 0.0, 0.25) + interior_coord; - - float rad = (droplet_radius - 5.0f) / 1024.0f; - return pow(texture2D(rainbow_map, vec2(rad, d)).rgb, vec3(1.8)) * moisture_level; -} - -vec3 halo22(float d) -{ - d = clamp(d, 0.1, 1.0); - float v = sqrt(clamp(1 - (d * d), 0, 1)); - return texture2D(halo_map, vec2(0, v)).rgb * ice_level; -} - -/// Soft clips the light with a gamma correction -vec3 scaleSoftClip(vec3 light); - -void main() -{ - // World / view / projection - // Get relative position (offset why?) - vec3 rel_pos = pos.xyz - camPosLocal.xyz + vec3(0, 50, 0); - - // Adj position vector to clamp altitude - if (rel_pos.y > 0.) - { - rel_pos *= (max_y / rel_pos.y); - } - if (rel_pos.y < 0.) - { - rel_pos *= (-32000. / rel_pos.y); - } - - // Normalized - vec3 rel_pos_norm = normalize(rel_pos); - float rel_pos_len = length(rel_pos); - - // Initialize temp variables - vec4 sunlight = (sun_up_factor == 1) ? sunlight_color : moonlight_color; - - // Sunlight attenuation effect (hue and brightness) due to atmosphere - // this is used later for sunlight modulation at various altitudes - vec4 light_atten = (blue_density + vec4(haze_density * 0.25)) * (density_multiplier * max_y); - - // Calculate relative weights - vec4 combined_haze = abs(blue_density) + vec4(abs(haze_density)); - vec4 blue_weight = blue_density / combined_haze; - vec4 haze_weight = haze_density / combined_haze; - - // Compute sunlight from rel_pos & lightnorm (for long rays like sky) - float off_axis = 1.0 / max(1e-6, max(0, rel_pos_norm.y) + lightnorm.y); - sunlight *= exp(-light_atten * off_axis); - - // Distance - float density_dist = rel_pos_len * density_multiplier; - - // Transparency (-> combined_haze) - // ATI Bugfix -- can't store combined_haze*density_dist in a variable because the ati - // compiler gets confused. - combined_haze = exp(-combined_haze * density_dist); - - // Compute haze glow - float haze_glow = dot(rel_pos_norm, lightnorm.xyz); - haze_glow = 1. - haze_glow; - // haze_glow is 0 at the sun and increases away from sun - haze_glow = max(haze_glow, .001); - // Set a minimum "angle" (smaller glow.y allows tighter, brighter hotspot) - haze_glow *= glow.x; - // Higher glow.x gives dimmer glow (because next step is 1 / "angle") - haze_glow = pow(haze_glow, glow.z); - // glow.z should be negative, so we're doing a sort of (1 / "angle") function - - // Add "minimum anti-solar illumination" - // For sun, add to glow. For moon, remove glow entirely. SL-13768 - haze_glow = (sun_moon_glow_factor < 1.0) ? 0.0 : (sun_moon_glow_factor * (haze_glow + 0.25)); - - // Haze color above cloud - vec4 color = blue_horizon * blue_weight * (sunlight + ambient_color) - + haze_horizon * haze_weight * (sunlight * haze_glow + ambient_color); - - // Final atmosphere additive - color *= (1. - combined_haze); - - // Increase ambient when there are more clouds - // TODO 9/20: DJH what does this do? max(0,(1-ambient)) will change the color - vec4 ambient = ambient_color + max(vec4(0), (1. - ambient_color)) * cloud_shadow * 0.5; - - // Dim sunlight by cloud shadow percentage - sunlight *= max(0.0, (1. - cloud_shadow)); - - // Haze color below cloud - vec4 add_below_cloud = blue_horizon * blue_weight * (sunlight + ambient) - + haze_horizon * haze_weight * (sunlight * haze_glow + ambient); - - // Attenuate cloud color by atmosphere - combined_haze = sqrt(combined_haze); // less atmos opacity (more transparency) below clouds - - // At horizon, blend high altitude sky color towards the darker color below the clouds - color += (add_below_cloud - color) * (1. - sqrt(combined_haze)); - - float optic_d = dot(rel_pos_norm, lightnorm.xyz); - vec3 halo_22 = halo22(optic_d); - color.rgb += rainbow(optic_d); - color.rgb += halo_22; - color.rgb *= 2.; - color.rgb = scaleSoftClip(color.rgb); - - // Gamma correct for WL (soft clip effect). - frag_data[0] = vec4(color.rgb, 1.0); - frag_data[1] = vec4(0.0, 0.0, 0.0, 0.0); - frag_data[2] = vec4(0.0, 0.0, 0.0, 1.0); // 1.0 in norm.w masks off fog -} diff --git a/indra/newview/app_settings/shaders/class2/deferred/skyV.glsl b/indra/newview/app_settings/shaders/class2/deferred/skyV.glsl deleted file mode 100644 index bcf775577a..0000000000 --- a/indra/newview/app_settings/shaders/class2/deferred/skyV.glsl +++ /dev/null @@ -1,42 +0,0 @@ -/** - * @file WLSkyV.glsl - * - * $LicenseInfo:firstyear=2005&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2005, Linden Research, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; - * version 2.1 of the License only. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA - * $/LicenseInfo$ - */ - -uniform mat4 modelview_projection_matrix; - -ATTRIBUTE vec3 position; - -// SKY //////////////////////////////////////////////////////////////////////// -// The vertex shader for creating the atmospheric sky -/////////////////////////////////////////////////////////////////////////////// - -VARYING vec3 pos; - -void main() -{ - - // World / view / projection - pos = position.xyz; - gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0); -} diff --git a/indra/newview/llaccountingcostmanager.cpp b/indra/newview/llaccountingcostmanager.cpp index e09527a34b..d3f988d715 100644 --- a/indra/newview/llaccountingcostmanager.cpp +++ b/indra/newview/llaccountingcostmanager.cpp @@ -96,11 +96,7 @@ void LLAccountingCostManager::accountingCostCoro(std::string url, LLSD dataToPost = LLSD::emptyMap(); dataToPost[keystr.c_str()] = objectList; - LLAccountingCostObserver* observer = observerHandle.get(); - LLUUID transactionId = observer->getTransactionID(); - observer = NULL; - - + LLAccountingCostObserver* observer = NULL; LLSD results = httpAdapter->postAndSuspend(httpRequest, url, dataToPost); diff --git a/indra/newview/llagentcamera.cpp b/indra/newview/llagentcamera.cpp index 8d2e3905d1..77131efd75 100644 --- a/indra/newview/llagentcamera.cpp +++ b/indra/newview/llagentcamera.cpp @@ -133,7 +133,6 @@ LLAgentCamera::LLAgentCamera() : mCameraFOVZoomFactor(0.f), mCameraCurrentFOVZoomFactor(0.f), mCameraFocusOffset(), - mCameraFOVDefault(DEFAULT_FIELD_OF_VIEW), mCameraCollidePlane(), @@ -155,7 +154,6 @@ LLAgentCamera::LLAgentCamera() : mFocusObject(NULL), mFocusObjectDist(0.f), mFocusObjectOffset(), - mFocusDotRadius( 0.1f ), // meters mTrackFocusObject(TRUE), mAtKey(0), // Either 1, 0, or -1... indicates that movement-key is pressed @@ -2361,6 +2359,11 @@ void LLAgentCamera::changeCameraToCustomizeAvatar() gAgent.standUp(); // force stand up gViewerWindow->getWindow()->resetBusyCount(); + if (LLSelectMgr::getInstance()->getSelection()->isAttachment()) + { + LLSelectMgr::getInstance()->deselectAll(); + } + if (gFaceEditToolset) { LLToolMgr::getInstance()->setCurrentToolset(gFaceEditToolset); diff --git a/indra/newview/llagentcamera.h b/indra/newview/llagentcamera.h index 89680f95dc..d27cdb0c5c 100644 --- a/indra/newview/llagentcamera.h +++ b/indra/newview/llagentcamera.h @@ -152,7 +152,6 @@ private: F32 mTargetCameraDistance; // Target camera offset from avatar F32 mCameraFOVZoomFactor; // Amount of fov zoom applied to camera when zeroing in on an object F32 mCameraCurrentFOVZoomFactor; // Interpolated fov zoom - F32 mCameraFOVDefault; // Default field of view that is basis for FOV zoom effect LLVector4 mCameraCollidePlane; // Colliding plane for camera F32 mCameraZoomFraction; // Mousewheel driven fraction of zoom LLVector3 mCameraPositionAgent; // Camera position in agent coordinates @@ -167,7 +166,6 @@ private: // Follow //-------------------------------------------------------------------- public: - void setUsingFollowCam(bool using_follow_cam); bool isfollowCamLocked(); private: LLFollowCam mFollowCam; // Ventrella @@ -233,7 +231,6 @@ private: LLPointer<LLViewerObject> mFocusObject; F32 mFocusObjectDist; LLVector3 mFocusObjectOffset; - F32 mFocusDotRadius; // Meters BOOL mTrackFocusObject; //-------------------------------------------------------------------- diff --git a/indra/newview/llagentui.cpp b/indra/newview/llagentui.cpp index 3410a37890..c19ad2ae6f 100644 --- a/indra/newview/llagentui.cpp +++ b/indra/newview/llagentui.cpp @@ -53,7 +53,16 @@ void LLAgentUI::buildSLURL(LLSLURL& slurl, const bool escaped /*= true*/) LLViewerRegion *regionp = gAgent.getRegion(); if (regionp) { - return_slurl = LLSLURL(regionp->getName(), gAgent.getPositionGlobal()); + // Make sure coordinates are within current region + LLVector3d global_pos = gAgent.getPositionGlobal(); + LLVector3d region_origin = regionp->getOriginGlobal(); + // -1 otherwise slurl will fmod 256 to 0. + // And valid slurl range is supposed to be 0..255 + F64 max_val = REGION_WIDTH_METERS - 1; + global_pos.mdV[VX] = llclamp(global_pos[VX], region_origin[VX], region_origin[VX] + max_val); + global_pos.mdV[VY] = llclamp(global_pos[VY], region_origin[VY], region_origin[VY] + max_val); + + return_slurl = LLSLURL(regionp->getName(), global_pos); } slurl = return_slurl; } diff --git a/indra/newview/llappdelegate-objc.mm b/indra/newview/llappdelegate-objc.mm index 5214f4b838..1090888c1c 100644 --- a/indra/newview/llappdelegate-objc.mm +++ b/indra/newview/llappdelegate-objc.mm @@ -46,6 +46,7 @@ - (void)dealloc { + [currentInputLanguage release]; [super dealloc]; } @@ -199,12 +200,14 @@ - (bool) romanScript { - // How to add support for new languages with the input window: - // Simply append this array with the language code (ja for japanese, ko for korean, zh for chinese, etc.) - NSArray *nonRomanScript = [[NSArray alloc] initWithObjects:@"ja", @"ko", @"zh-Hant", @"zh-Hans", nil]; - if ([nonRomanScript containsObject:currentInputLanguage]) - { - return false; + @autoreleasepool { + // How to add support for new languages with the input window: + // Simply append this array with the language code (ja for japanese, ko for korean, zh for chinese, etc.) + NSArray* nonRomanScript = @[@"ja", @"ko", @"zh-Hant", @"zh-Hans"]; + if ([nonRomanScript containsObject:currentInputLanguage]) + { + return false; + } } return true; diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp index eff69df087..07d6efd2fa 100644 --- a/indra/newview/llappearancemgr.cpp +++ b/indra/newview/llappearancemgr.cpp @@ -3989,7 +3989,7 @@ void LLAppearanceMgr::makeNewOutfitLinks(const std::string& new_folder_name, boo // existence of AIS as an indicator the fix is present. Does // not actually use AIS to create the category. inventory_func_type func = boost::bind(&LLAppearanceMgr::onOutfitFolderCreated,this,_1,show_panel); - LLUUID folder_id = gInventory.createNewCategory( + gInventory.createNewCategory( parent_id, LLFolderType::FT_OUTFIT, new_folder_name, diff --git a/indra/newview/llappearancemgr.h b/indra/newview/llappearancemgr.h index 8a55a848db..cf953d21ac 100644 --- a/indra/newview/llappearancemgr.h +++ b/indra/newview/llappearancemgr.h @@ -35,6 +35,7 @@ #include "llinventoryobserver.h" #include "llviewerinventory.h" #include "llcorehttputil.h" +#include <memory> class LLWearableHoldingPattern; class LLInventoryCallback; @@ -276,7 +277,7 @@ private: LLUUID mCOFImageID; - std::auto_ptr<LLOutfitUnLockTimer> mUnlockOutfitTimer; + std::unique_ptr<LLOutfitUnLockTimer> mUnlockOutfitTimer; // Set of temp attachment UUIDs that should be removed typedef std::set<LLUUID> doomed_temp_attachments_t; diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 8af5fdfc93..9e06fc3ac0 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -135,6 +135,10 @@ #include "vlc/libvlc_version.h" #endif // LL_LINUX +#if LL_DARWIN +#include "llwindowmacosx.h" +#endif + // Third party library includes #include <boost/bind.hpp> #include <boost/foreach.hpp> @@ -303,7 +307,7 @@ S32 gLastExecDuration = -1; // (<0 indicates unknown) # define LL_PLATFORM_KEY "mac" #elif LL_LINUX # define LL_PLATFORM_KEY "lnx" -else +#else # error "Unknown Platform" #endif const char* gPlatform = LL_PLATFORM_KEY; @@ -560,6 +564,7 @@ static void settings_to_globals() LLWorldMapView::setScaleSetting(gSavedSettings.getF32("MapScale")); #if LL_DARWIN + LLWindowMacOSX::sUseMultGL = gSavedSettings.getBOOL("RenderAppleUseMultGL"); gHiDPISupport = gSavedSettings.getBOOL("RenderHiDPI"); #endif } @@ -1185,12 +1190,8 @@ bool LLAppViewer::init() { LL_WARNS("InitInfo") << "Skipping updater check." << LL_ENDL; } +#endif //LL_RELEASE_FOR_DOWNLOAD - if (mUpdaterNotFound) - { - LL_WARNS("InitInfo") << "Failed to launch updater. Skipping Leap commands." << LL_ENDL; - } - else { // Iterate over --leap command-line options. But this is a bit tricky: if // there's only one, it won't be an array at all. @@ -1223,7 +1224,6 @@ bool LLAppViewer::init() << "lleventhost no longer supported as a dynamic library" << LL_ENDL; } -#endif //LL_RELEASE_FOR_DOWNLOAD LLTextUtil::TextHelpers::iconCallbackCreationFunction = create_text_segment_icon_from_url_match; @@ -1724,7 +1724,8 @@ bool LLAppViewer::cleanup() { if (!isSecondInstance()) { - LLSceneMonitor::instance().dumpToFile(gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "scene_monitor_results.csv")); + std::string dump_path = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "scene_monitor_results.csv"); + LLSceneMonitor::instance().dumpToFile(dump_path); } LLSceneMonitor::deleteSingleton(); } @@ -5474,7 +5475,8 @@ void LLAppViewer::disconnectViewer() { gInventory.cache(gInventory.getRootFolderID(), gAgent.getID()); if (gInventory.getLibraryRootFolderID().notNull() - && gInventory.getLibraryOwnerID().notNull()) + && gInventory.getLibraryOwnerID().notNull() + && !mSecondInstance) // agent is unique, library isn't { gInventory.cache( gInventory.getLibraryRootFolderID(), diff --git a/indra/newview/llappviewerwin32.cpp b/indra/newview/llappviewerwin32.cpp index a39ec7f51b..6457c13ef3 100644 --- a/indra/newview/llappviewerwin32.cpp +++ b/indra/newview/llappviewerwin32.cpp @@ -75,7 +75,7 @@ // Bugsplat (http://bugsplat.com) crash reporting tool #ifdef LL_BUGSPLAT #include "BugSplat.h" -#include "reader.h" // JsonCpp +#include "json/reader.h" // JsonCpp #include "llagent.h" // for agent location #include "llviewerregion.h" #include "llvoavatarself.h" // for agent name diff --git a/indra/newview/llavatarrenderinfoaccountant.cpp b/indra/newview/llavatarrenderinfoaccountant.cpp index 275f17b02a..293c9d60a1 100644 --- a/indra/newview/llavatarrenderinfoaccountant.cpp +++ b/indra/newview/llavatarrenderinfoaccountant.cpp @@ -364,11 +364,10 @@ void LLAvatarRenderInfoAccountant::getRenderInfoFromRegion(LLViewerRegion * regi } } -// static // Called every frame - send render weight requests to every region void LLAvatarRenderInfoAccountant::idle() { - if (mRenderInfoScanTimer.hasExpired()) + if (mRenderInfoScanTimer.hasExpired() && !LLApp::isExiting()) { LL_DEBUGS("AvatarRenderInfo") << "Scanning regions for render info updates" << LL_ENDL; diff --git a/indra/newview/llbuycurrencyhtml.cpp b/indra/newview/llbuycurrencyhtml.cpp index 1c69dadb12..7ad06f8eaa 100644 --- a/indra/newview/llbuycurrencyhtml.cpp +++ b/indra/newview/llbuycurrencyhtml.cpp @@ -41,7 +41,7 @@ class LLBuyCurrencyHTMLHandler : { public: // requests will be throttled from a non-trusted browser - LLBuyCurrencyHTMLHandler() : LLCommandHandler( "buycurrencyhtml", UNTRUSTED_ALLOW ) {} + LLBuyCurrencyHTMLHandler() : LLCommandHandler( "buycurrencyhtml", UNTRUSTED_THROTTLE) {} bool handle(const LLSD& params, const LLSD& query_map, LLMediaCtrl* web) { diff --git a/indra/newview/llcallingcard.cpp b/indra/newview/llcallingcard.cpp index 1ad2157df0..df79043b00 100644 --- a/indra/newview/llcallingcard.cpp +++ b/indra/newview/llcallingcard.cpp @@ -650,8 +650,7 @@ void LLAvatarTracker::processChange(LLMessageSystem* msg) { if(mBuddyInfo.find(agent_id) != mBuddyInfo.end()) { - if (((mBuddyInfo[agent_id]->getRightsGrantedFrom() ^ new_rights) & LLRelationship::GRANT_MODIFY_OBJECTS) - && !gAgent.isDoNotDisturb()) + if (((mBuddyInfo[agent_id]->getRightsGrantedFrom() ^ new_rights) & LLRelationship::GRANT_MODIFY_OBJECTS)) { LLSD args; args["NAME"] = LLSLURL("agent", agent_id, "displayname").getSLURLString(); @@ -719,11 +718,12 @@ void LLAvatarTracker::processNotify(LLMessageSystem* msg, bool online) // we were tracking someone who went offline deleteTrackingData(); } - } - if(chat_notify) - { - // Look up the name of this agent for the notification - LLAvatarNameCache::get(agent_id,boost::bind(&on_avatar_name_cache_notify,_1, _2, online, payload)); + + if(chat_notify) + { + // Look up the name of this agent for the notification + LLAvatarNameCache::get(agent_id,boost::bind(&on_avatar_name_cache_notify,_1, _2, online, payload)); + } } mModifyMask |= LLFriendObserver::ONLINE; diff --git a/indra/newview/llchathistory.cpp b/indra/newview/llchathistory.cpp index 7188b9136c..9a608fba8e 100644 --- a/indra/newview/llchathistory.cpp +++ b/indra/newview/llchathistory.cpp @@ -141,6 +141,18 @@ public: { mAvatarNameCacheConnection.disconnect(); } + auto menu = mPopupMenuHandleAvatar.get(); + if (menu) + { + menu->die(); + mPopupMenuHandleAvatar.markDead(); + } + menu = mPopupMenuHandleObject.get(); + if (menu) + { + menu->die(); + mPopupMenuHandleObject.markDead(); + } } BOOL handleMouseUp(S32 x, S32 y, MASK mask) @@ -567,36 +579,6 @@ public: BOOL postBuild() { - LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar; - LLUICtrl::EnableCallbackRegistry::ScopedRegistrar registrar_enable; - - registrar.add("AvatarIcon.Action", boost::bind(&LLChatHistoryHeader::onAvatarIconContextMenuItemClicked, this, _2)); - registrar_enable.add("AvatarIcon.Check", boost::bind(&LLChatHistoryHeader::onAvatarIconContextMenuItemChecked, this, _2)); - registrar_enable.add("AvatarIcon.Enable", boost::bind(&LLChatHistoryHeader::onAvatarIconContextMenuItemEnabled, this, _2)); - registrar_enable.add("AvatarIcon.Visible", boost::bind(&LLChatHistoryHeader::onAvatarIconContextMenuItemVisible, this, _2)); - registrar.add("ObjectIcon.Action", boost::bind(&LLChatHistoryHeader::onObjectIconContextMenuItemClicked, this, _2)); - registrar_enable.add("ObjectIcon.Visible", boost::bind(&LLChatHistoryHeader::onObjectIconContextMenuItemVisible, this, _2)); - - LLMenuGL* menu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>("menu_avatar_icon.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); - if (menu) - { - mPopupMenuHandleAvatar = menu->getHandle(); - } - else - { - LL_WARNS() << " Failed to create menu_avatar_icon.xml" << LL_ENDL; - } - - menu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>("menu_object_icon.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); - if (menu) - { - mPopupMenuHandleObject = menu->getHandle(); - } - else - { - LL_WARNS() << " Failed to create menu_object_icon.xml" << LL_ENDL; - } - setDoubleClickCallback(boost::bind(&LLChatHistoryHeader::showInspector, this)); setMouseEnterCallback(boost::bind(&LLChatHistoryHeader::showInfoCtrl, this)); @@ -884,13 +866,53 @@ protected: void showObjectContextMenu(S32 x,S32 y) { LLMenuGL* menu = (LLMenuGL*)mPopupMenuHandleObject.get(); - if(menu) + if (!menu) + { + LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar; + LLUICtrl::EnableCallbackRegistry::ScopedRegistrar registrar_enable; + registrar.add("ObjectIcon.Action", boost::bind(&LLChatHistoryHeader::onObjectIconContextMenuItemClicked, this, _2)); + registrar_enable.add("ObjectIcon.Visible", boost::bind(&LLChatHistoryHeader::onObjectIconContextMenuItemVisible, this, _2)); + + menu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>("menu_object_icon.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); + if (menu) + { + mPopupMenuHandleObject = menu->getHandle(); + menu->updateParent(LLMenuGL::sMenuContainer); + LLMenuGL::showPopup(this, menu, x, y); + } + else + { + LL_WARNS() << " Failed to create menu_object_icon.xml" << LL_ENDL; + } + } + else + { LLMenuGL::showPopup(this, menu, x, y); + } } void showAvatarContextMenu(S32 x,S32 y) { LLMenuGL* menu = (LLMenuGL*)mPopupMenuHandleAvatar.get(); + if (!menu) + { + LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar; + LLUICtrl::EnableCallbackRegistry::ScopedRegistrar registrar_enable; + registrar.add("AvatarIcon.Action", boost::bind(&LLChatHistoryHeader::onAvatarIconContextMenuItemClicked, this, _2)); + registrar_enable.add("AvatarIcon.Check", boost::bind(&LLChatHistoryHeader::onAvatarIconContextMenuItemChecked, this, _2)); + registrar_enable.add("AvatarIcon.Enable", boost::bind(&LLChatHistoryHeader::onAvatarIconContextMenuItemEnabled, this, _2)); + registrar_enable.add("AvatarIcon.Visible", boost::bind(&LLChatHistoryHeader::onAvatarIconContextMenuItemVisible, this, _2)); + + menu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>("menu_avatar_icon.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); + if (menu) + { + mPopupMenuHandleAvatar = menu->getHandle(); + } + else + { + LL_WARNS() << " Failed to create menu_avatar_icon.xml" << LL_ENDL; + } + } if(menu) { @@ -1082,10 +1104,7 @@ LLChatHistory::LLChatHistory(const LLChatHistory::Params& p) LLSD LLChatHistory::getValue() const { - LLSD* text=new LLSD(); - text->assign(mEditor->getText()); - return *text; - + return LLSD(mEditor->getText()); } LLChatHistory::~LLChatHistory() diff --git a/indra/newview/llchiclet.cpp b/indra/newview/llchiclet.cpp index 0f187b0ecf..cc4f4536a4 100644 --- a/indra/newview/llchiclet.cpp +++ b/indra/newview/llchiclet.cpp @@ -67,7 +67,6 @@ LLSysWellChiclet::LLSysWellChiclet(const Params& p) , mMaxDisplayedCount(p.max_displayed_count) , mIsNewMessagesState(false) , mFlashToLitTimer(NULL) - , mContextMenu(NULL) { LLButton::Params button_params = p.button; mButton = LLUICtrlFactory::create<LLButton>(button_params); @@ -79,6 +78,12 @@ LLSysWellChiclet::LLSysWellChiclet(const Params& p) LLSysWellChiclet::~LLSysWellChiclet() { mFlashToLitTimer->unset(); + LLContextMenu* menu = static_cast<LLContextMenu*>(mContextMenuHandle.get()); + if (menu) + { + menu->die(); + mContextMenuHandle.markDead(); + } } void LLSysWellChiclet::setCounter(S32 counter) @@ -145,14 +150,16 @@ void LLSysWellChiclet::updateWidget(bool is_window_empty) // virtual BOOL LLSysWellChiclet::handleRightMouseDown(S32 x, S32 y, MASK mask) { - if(!mContextMenu) + LLContextMenu* menu_avatar = mContextMenuHandle.get(); + if(!menu_avatar) { createMenu(); + menu_avatar = mContextMenuHandle.get(); } - if (mContextMenu) + if (menu_avatar) { - mContextMenu->show(x, y); - LLMenuGL::showPopup(this, mContextMenu, x, y); + menu_avatar->show(x, y); + LLMenuGL::showPopup(this, menu_avatar, x, y); } return TRUE; } @@ -192,7 +199,7 @@ bool LLNotificationChiclet::enableMenuItem(const LLSD& user_data) void LLNotificationChiclet::createMenu() { - if(mContextMenu) + if(mContextMenuHandle.get()) { LL_WARNS() << "Menu already exists" << LL_ENDL; return; @@ -207,10 +214,14 @@ void LLNotificationChiclet::createMenu() boost::bind(&LLNotificationChiclet::enableMenuItem, this, _2)); llassert(LLMenuGL::sMenuContainer != NULL); - mContextMenu = LLUICtrlFactory::getInstance()->createFromFile<LLContextMenu> + LLContextMenu* menu = LLUICtrlFactory::getInstance()->createFromFile<LLContextMenu> ("menu_notification_well_button.xml", LLMenuGL::sMenuContainer, LLViewerMenuHolderGL::child_registry_t::instance()); + if (menu) + { + mContextMenuHandle = menu->getHandle(); + } } /*virtual*/ @@ -309,10 +320,19 @@ LLIMChiclet::LLIMChiclet(const LLIMChiclet::Params& p) , mDefaultWidth(p.rect().getWidth()) , mNewMessagesIcon(NULL) , mChicletButton(NULL) -, mPopupMenu(NULL) { } +LLIMChiclet::~LLIMChiclet() +{ + auto menu = mPopupMenuHandle.get(); + if (menu) + { + menu->die(); + mPopupMenuHandle.markDead(); + } +} + /* virtual*/ BOOL LLIMChiclet::postBuild() { @@ -364,16 +384,18 @@ void LLIMChiclet::setToggleState(bool toggle) BOOL LLIMChiclet::handleRightMouseDown(S32 x, S32 y, MASK mask) { - if(!mPopupMenu) + auto menu = static_cast<LLMenuGL*>(mPopupMenuHandle.get()); + if(!menu) { createPopupMenu(); + menu = static_cast<LLMenuGL*>(mPopupMenuHandle.get()); } - if (mPopupMenu) + if (menu) { updateMenuItems(); - mPopupMenu->arrangeAndClear(); - LLMenuGL::showPopup(this, mPopupMenu, x, y); + menu->arrangeAndClear(); + LLMenuGL::showPopup(this, menu, x, y); } return TRUE; @@ -381,15 +403,16 @@ BOOL LLIMChiclet::handleRightMouseDown(S32 x, S32 y, MASK mask) void LLIMChiclet::hidePopupMenu() { - if (mPopupMenu) + auto menu = mPopupMenuHandle.get(); + if (menu) { - mPopupMenu->setVisible(FALSE); + menu->setVisible(FALSE); } } bool LLIMChiclet::canCreateMenu() { - if(mPopupMenu) + if(mPopupMenuHandle.get()) { LL_WARNS() << "Menu already exists" << LL_ENDL; return false; @@ -1107,8 +1130,13 @@ void LLScriptChiclet::createPopupMenu() LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar; registrar.add("ScriptChiclet.Action", boost::bind(&LLScriptChiclet::onMenuItemClicked, this, _2)); - mPopupMenu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL> + LLMenuGL* menu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL> ("menu_script_chiclet.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); + if (menu) + { + mPopupMenuHandle = menu->getHandle(); + } + } ////////////////////////////////////////////////////////////////////////// @@ -1185,8 +1213,12 @@ void LLInvOfferChiclet::createPopupMenu() LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar; registrar.add("InvOfferChiclet.Action", boost::bind(&LLInvOfferChiclet::onMenuItemClicked, this, _2)); - mPopupMenu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL> + LLMenuGL* menu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL> ("menu_inv_offer_chiclet.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); + if (menu) + { + mPopupMenuHandle = menu->getHandle(); + } } // EOF diff --git a/indra/newview/llchiclet.h b/indra/newview/llchiclet.h index aceedda07e..58a797218f 100644 --- a/indra/newview/llchiclet.h +++ b/indra/newview/llchiclet.h @@ -252,7 +252,7 @@ public: {}; - virtual ~LLIMChiclet() {}; + virtual ~LLIMChiclet(); /** * It is used for default setting up of chicklet:click handler, etc. @@ -325,7 +325,7 @@ protected: bool canCreateMenu(); - LLMenuGL* mPopupMenu; + LLHandle<LLUICtrl> mPopupMenuHandle; bool mShowSpeaker; bool mCounterEnabled; @@ -519,7 +519,7 @@ protected: bool mIsNewMessagesState; LLFlashTimer* mFlashToLitTimer; - LLContextMenu* mContextMenu; + LLHandle<LLContextMenu> mContextMenuHandle; }; class LLNotificationChiclet : public LLSysWellChiclet diff --git a/indra/newview/llcommandhandler.cpp b/indra/newview/llcommandhandler.cpp index 23e2271eae..74f37961c7 100644 --- a/indra/newview/llcommandhandler.cpp +++ b/indra/newview/llcommandhandler.cpp @@ -39,6 +39,7 @@ #define THROTTLE_PERIOD 5 // required seconds between throttled commands static LLCommandDispatcherListener sCommandDispatcherListener; +const std::string LLCommandHandler::NAV_TYPE_CLICKED = "clicked"; //--------------------------------------------------------------------------- // Underlying registry for command handlers, not directly accessible. @@ -64,6 +65,9 @@ public: bool trusted_browser); private: + void notifySlurlBlocked(); + void notifySlurlThrottled(); + friend LLSD LLCommandDispatcher::enumerate(); std::map<std::string, LLCommandHandlerInfo> mMap; }; @@ -96,8 +100,6 @@ bool LLCommandHandlerRegistry::dispatch(const std::string& cmd, const std::string& nav_type, bool trusted_browser) { - static bool slurl_blocked = false; - static bool slurl_throttled = false; static F64 last_throttle_time = 0.0; F64 cur_time = 0.0; std::map<std::string, LLCommandHandlerInfo>::iterator it = mMap.find(cmd); @@ -115,44 +117,45 @@ bool LLCommandHandlerRegistry::dispatch(const std::string& cmd, // block request from external browser, but report as // "handled" because it was well formatted. LL_WARNS_ONCE("SLURL") << "Blocked SLURL command from untrusted browser" << LL_ENDL; - if (! slurl_blocked) - { - if (LLStartUp::getStartupState() >= STATE_BROWSER_INIT) - { - // Note: commands can arrive before we initialize everything we need for Notification. - LLNotificationsUtil::add("BlockedSLURL"); - } - slurl_blocked = true; - } + notifySlurlBlocked(); return true; + case LLCommandHandler::UNTRUSTED_CLICK_ONLY: + if (nav_type == LLCommandHandler::NAV_TYPE_CLICKED + && info.mHandler->canHandleUntrusted(params, query_map, web, nav_type)) + { + break; + } + LL_WARNS_ONCE("SLURL") << "Blocked SLURL click-only command " << cmd << " from untrusted browser" << LL_ENDL; + notifySlurlBlocked(); + return true; + case LLCommandHandler::UNTRUSTED_THROTTLE: + //skip initial request from external browser before STATE_BROWSER_INIT + if (LLStartUp::getStartupState() == STATE_FIRST) + { + return true; + } + if (!info.mHandler->canHandleUntrusted(params, query_map, web, nav_type)) + { + LL_WARNS_ONCE("SLURL") << "Blocked SLURL command from untrusted browser" << LL_ENDL; + notifySlurlBlocked(); + return true; + } // if users actually click on a link, we don't need to throttle it // (throttling mechanism is used to prevent an avalanche of clicks via // javascript - if ( nav_type == "clicked" ) + if (nav_type == LLCommandHandler::NAV_TYPE_CLICKED) { break; } - //skip initial request from external browser before STATE_BROWSER_INIT - if (LLStartUp::getStartupState() == STATE_FIRST) - { - return true; - } cur_time = LLTimer::getElapsedSeconds(); if (cur_time < last_throttle_time + THROTTLE_PERIOD) { // block request from external browser if it happened // within THROTTLE_PERIOD seconds of the last command LL_WARNS_ONCE("SLURL") << "Throttled SLURL command from untrusted browser" << LL_ENDL; - if (! slurl_throttled) - { - if (LLStartUp::getStartupState() >= STATE_BROWSER_INIT) - { - LLNotificationsUtil::add("ThrottledSLURL"); - } - slurl_throttled = true; - } + notifySlurlThrottled(); return true; } last_throttle_time = cur_time; @@ -163,6 +166,34 @@ bool LLCommandHandlerRegistry::dispatch(const std::string& cmd, return info.mHandler->handle(params, query_map, web); } +void LLCommandHandlerRegistry::notifySlurlBlocked() +{ + static bool slurl_blocked = false; + if (!slurl_blocked) + { + if (LLStartUp::getStartupState() >= STATE_BROWSER_INIT) + { + // Note: commands can arrive before we initialize everything we need for Notification. + LLNotificationsUtil::add("BlockedSLURL"); + } + slurl_blocked = true; + } +} + +void LLCommandHandlerRegistry::notifySlurlThrottled() +{ + static bool slurl_throttled = false; + if (!slurl_throttled) + { + if (LLStartUp::getStartupState() >= STATE_BROWSER_INIT) + { + // Note: commands can arrive before we initialize everything we need for Notification. + LLNotificationsUtil::add("ThrottledSLURL"); + } + slurl_throttled = true; + } +} + //--------------------------------------------------------------------------- // Automatic registration of commands, runs before main() //--------------------------------------------------------------------------- @@ -230,6 +261,7 @@ symbol_info symbols[] = { ent(LLCommandHandler::UNTRUSTED_ALLOW), // allow commands from untrusted browsers ent(LLCommandHandler::UNTRUSTED_BLOCK), // ignore commands from untrusted browsers + ent(LLCommandHandler::UNTRUSTED_CLICK_ONLY), // allow untrusted, but only if clicked ent(LLCommandHandler::UNTRUSTED_THROTTLE) // allow untrusted, but only a few per min. }; diff --git a/indra/newview/llcommandhandler.h b/indra/newview/llcommandhandler.h index 1e0895565a..763e3ee51f 100644 --- a/indra/newview/llcommandhandler.h +++ b/indra/newview/llcommandhandler.h @@ -65,9 +65,12 @@ public: { UNTRUSTED_ALLOW, // allow commands from untrusted browsers UNTRUSTED_BLOCK, // ignore commands from untrusted browsers + UNTRUSTED_CLICK_ONLY, // allow untrusted, but only if clicked UNTRUSTED_THROTTLE // allow untrusted, but only a few per min. }; + static const std::string NAV_TYPE_CLICKED; + LLCommandHandler(const char* command, EUntrustedAccess untrusted_access); // Automatically registers object to get called when // command is executed. All commands can be processed @@ -76,6 +79,13 @@ public: virtual ~LLCommandHandler(); + virtual bool canHandleUntrusted( + const LLSD& params, + const LLSD& query_map, + LLMediaCtrl* web, + const std::string& nav_type) + { return true; } + virtual bool handle(const LLSD& params, const LLSD& query_map, LLMediaCtrl* web) = 0; diff --git a/indra/newview/llenvironment.cpp b/indra/newview/llenvironment.cpp index 4ef14c20f7..05c7decfbd 100644 --- a/indra/newview/llenvironment.cpp +++ b/indra/newview/llenvironment.cpp @@ -684,7 +684,6 @@ namespace if (!injection->mBlendIn) mix = 1.0 - mix; stringset_t dummy; - LLUUID cloud_noise_id = getCloudNoiseTextureId(); F64 value = this->mSettings[injection->mKeyName].asReal(); if (this->getCloudNoiseTextureId().isNull()) { @@ -3097,7 +3096,7 @@ bool LLEnvironment::loadFromSettings() LL_INFOS("ENVIRONMENT") << "Unable to open previous session environment file " << user_filepath << LL_ENDL; } - if (!env_data.isMap() || env_data.emptyMap()) + if (!env_data.isMap() || (env_data.size() == 0)) { LL_DEBUGS("ENVIRONMENT") << "Empty map loaded from: " << user_filepath << LL_ENDL; return false; diff --git a/indra/newview/llestateinfomodel.cpp b/indra/newview/llestateinfomodel.cpp index 4fdb860592..5be56660d6 100644 --- a/indra/newview/llestateinfomodel.cpp +++ b/indra/newview/llestateinfomodel.cpp @@ -74,6 +74,7 @@ bool LLEstateInfoModel::getDenyAgeUnverified() const { return getFlag(REGION_FL bool LLEstateInfoModel::getAllowVoiceChat() const { return getFlag(REGION_FLAGS_ALLOW_VOICE); } bool LLEstateInfoModel::getAllowAccessOverride() const { return getFlag(REGION_FLAGS_ALLOW_ACCESS_OVERRIDE); } bool LLEstateInfoModel::getAllowEnvironmentOverride() const { return getFlag(REGION_FLAGS_ALLOW_ENVIRONMENT_OVERRIDE); } +bool LLEstateInfoModel::getDenyScriptedAgents() const { return getFlag(REGION_FLAGS_DENY_BOTS); } void LLEstateInfoModel::setUseFixedSun(bool val) { setFlag(REGION_FLAGS_SUN_FIXED, val); } void LLEstateInfoModel::setIsExternallyVisible(bool val) { setFlag(REGION_FLAGS_EXTERNALLY_VISIBLE, val); } @@ -83,6 +84,7 @@ void LLEstateInfoModel::setDenyAgeUnverified(bool val) { setFlag(REGION_FLAGS_D void LLEstateInfoModel::setAllowVoiceChat(bool val) { setFlag(REGION_FLAGS_ALLOW_VOICE, val); } void LLEstateInfoModel::setAllowAccessOverride(bool val) { setFlag(REGION_FLAGS_ALLOW_ACCESS_OVERRIDE, val); } void LLEstateInfoModel::setAllowEnvironmentOverride(bool val) { setFlag(REGION_FLAGS_ALLOW_ENVIRONMENT_OVERRIDE, val); } +void LLEstateInfoModel::setDenyScriptedAgents(bool val) { setFlag(REGION_FLAGS_DENY_BOTS, val); } void LLEstateInfoModel::update(const strings_t& strings) { @@ -148,6 +150,7 @@ void LLEstateInfoModel::commitEstateInfoCapsCoro(std::string url) body["allow_direct_teleport"] = getAllowDirectTeleport(); body["deny_anonymous"] = getDenyAnonymous(); body["deny_age_unverified"] = getDenyAgeUnverified(); + body["block_bots"] = getDenyScriptedAgents(); body["allow_voice_chat"] = getAllowVoiceChat(); body["override_public_access"] = getAllowAccessOverride(); @@ -222,6 +225,7 @@ std::string LLEstateInfoModel::getInfoDump() dump["allow_direct_teleport"] = getAllowDirectTeleport(); dump["deny_anonymous" ] = getDenyAnonymous(); dump["deny_age_unverified" ] = getDenyAgeUnverified(); + dump["block_bots" ] = getDenyScriptedAgents(); dump["allow_voice_chat" ] = getAllowVoiceChat(); dump["override_public_access"] = getAllowAccessOverride(); dump["override_environment"] = getAllowEnvironmentOverride(); diff --git a/indra/newview/llestateinfomodel.h b/indra/newview/llestateinfomodel.h index d6f00c573c..cfe91a2930 100644 --- a/indra/newview/llestateinfomodel.h +++ b/indra/newview/llestateinfomodel.h @@ -57,6 +57,7 @@ public: bool getAllowVoiceChat() const; bool getAllowAccessOverride() const; bool getAllowEnvironmentOverride() const; + bool getDenyScriptedAgents() const; const std::string& getName() const { return mName; } const LLUUID& getOwnerID() const { return mOwnerID; } @@ -72,6 +73,7 @@ public: void setAllowVoiceChat(bool val); void setAllowAccessOverride(bool val); void setAllowEnvironmentOverride(bool val); + void setDenyScriptedAgents(bool val); void setSunHour(F32 sun_hour) { mSunHour = sun_hour; } diff --git a/indra/newview/llfavoritesbar.cpp b/indra/newview/llfavoritesbar.cpp index 70e8437190..cdce6f7156 100644 --- a/indra/newview/llfavoritesbar.cpp +++ b/indra/newview/llfavoritesbar.cpp @@ -878,8 +878,11 @@ void LLFavoritesBarCtrl::updateButtons(bool force_update) if (getChildList()->size() > 0) { //find last visible child to get the rightest button offset - child_list_const_reverse_iter_t last_visible_it = std::find_if(childs->rbegin(), childs->rend(), - std::mem_fun(&LLView::getVisible)); + child_list_const_reverse_iter_t last_visible_it = + std::find_if( + childs->rbegin(), childs->rend(), + [](const child_list_t::value_type& child) + { return child->getVisible(); }); if(last_visible_it != childs->rend()) { last_right_edge = (*last_visible_it)->getRect().mRight; diff --git a/indra/newview/llfilepicker.cpp b/indra/newview/llfilepicker.cpp index e6b6c22cc3..51b2f25f8d 100644 --- a/indra/newview/llfilepicker.cpp +++ b/indra/newview/llfilepicker.cpp @@ -614,9 +614,9 @@ BOOL LLFilePicker::getSaveFileModeless(ESaveFilter filter, #elif LL_DARWIN -std::vector<std::string>* LLFilePicker::navOpenFilterProc(ELoadFilter filter) //(AEDesc *theItem, void *info, void *callBackUD, NavFilterModes filterMode) +std::unique_ptr<std::vector<std::string>> LLFilePicker::navOpenFilterProc(ELoadFilter filter) //(AEDesc *theItem, void *info, void *callBackUD, NavFilterModes filterMode) { - std::vector<std::string> *allowedv = new std::vector< std::string >; + std::unique_ptr<std::vector<std::string>> allowedv(new std::vector< std::string >); switch(filter) { case FFLOAD_ALL: @@ -689,9 +689,9 @@ bool LLFilePicker::doNavChooseDialog(ELoadFilter filter) gViewerWindow->getWindow()->beforeDialog(); - std::vector<std::string> *allowed_types=navOpenFilterProc(filter); + std::unique_ptr<std::vector<std::string>> allowed_types = navOpenFilterProc(filter); - std::vector<std::string> *filev = doLoadDialog(allowed_types, + std::unique_ptr<std::vector<std::string>> filev = doLoadDialog(allowed_types.get(), mPickOptions); gViewerWindow->getWindow()->afterDialog(); @@ -826,7 +826,7 @@ bool LLFilePicker::doNavSaveDialog(ESaveFilter filter, const std::string& filena gViewerWindow->getWindow()->beforeDialog(); // Run the dialog - std::string* filev = doSaveDialog(&namestring, + std::unique_ptr<std::string> filev = doSaveDialog(&namestring, &type, &creator, &extension, @@ -1354,7 +1354,7 @@ static std::string add_save_texture_filter_to_gtkchooser(GtkWindow *picker) return caption; } -BOOL LLFilePicker::getSaveFile( ESaveFilter filter, const std::string& filename ) +BOOL LLFilePicker::getSaveFile( ESaveFilter filter, const std::string& filename, bool blocking ) { BOOL rtn = FALSE; @@ -1571,7 +1571,7 @@ BOOL LLFilePicker::getMultipleOpenFiles( ELoadFilter filter, bool blocking) // Hacky stubs designed to facilitate fake getSaveFile and getOpenFile with // static results, when we don't have a real filepicker. -BOOL LLFilePicker::getSaveFile( ESaveFilter filter, const std::string& filename ) +BOOL LLFilePicker::getSaveFile( ESaveFilter filter, const std::string& filename, bool blocking ) { // if local file browsing is turned off, return without opening dialog // (Even though this is a stub, I think we still should not return anything at all) diff --git a/indra/newview/llfilepicker.h b/indra/newview/llfilepicker.h index 5e2b7f51f2..26649e0940 100644 --- a/indra/newview/llfilepicker.h +++ b/indra/newview/llfilepicker.h @@ -178,7 +178,7 @@ private: void (*callback)(bool, std::vector<std::string>&, void*), void *userdata); bool doNavSaveDialog(ESaveFilter filter, const std::string& filename); - std::vector<std::string>* navOpenFilterProc(ELoadFilter filter); + std::unique_ptr<std::vector<std::string>> navOpenFilterProc(ELoadFilter filter); bool doNavSaveDialogModeless(ESaveFilter filter, const std::string& filename, void (*callback)(bool, std::string&, void*), diff --git a/indra/newview/llfilepicker_mac.h b/indra/newview/llfilepicker_mac.h index 2ec9d0c4e6..c18643f355 100644 --- a/indra/newview/llfilepicker_mac.h +++ b/indra/newview/llfilepicker_mac.h @@ -39,7 +39,7 @@ #include <vector> //void modelessPicker(); -std::vector<std::string>* doLoadDialog(const std::vector<std::string>* allowed_types, +std::unique_ptr<std::vector<std::string>> doLoadDialog(const std::vector<std::string>* allowed_types, unsigned int flags); void doLoadDialogModeless(const std::vector<std::string>* allowed_types, diff --git a/indra/newview/llfilepicker_mac.mm b/indra/newview/llfilepicker_mac.mm index 8f5b3030db..7fd9f37e18 100644 --- a/indra/newview/llfilepicker_mac.mm +++ b/indra/newview/llfilepicker_mac.mm @@ -71,7 +71,7 @@ NSOpenPanel *init_panel(const std::vector<std::string>* allowed_types, unsigned return panel; } -std::vector<std::string>* doLoadDialog(const std::vector<std::string>* allowed_types, +std::unique_ptr<std::vector<std::string>> doLoadDialog(const std::vector<std::string>* allowed_types, unsigned int flags) { int result; diff --git a/indra/newview/llfloater360capture.cpp b/indra/newview/llfloater360capture.cpp index 62a1e0af94..542a1ea39b 100644 --- a/indra/newview/llfloater360capture.cpp +++ b/indra/newview/llfloater360capture.cpp @@ -537,7 +537,8 @@ void LLFloater360Capture::capture360Images() // We need to convert from the angle getYaw() gives us into something // the XMP data field wants (N=0, E=90, S=180, W= 270 etc.) mInitialHeadingDeg = (360 + 90 - (int)(camera->getYaw() * RAD_TO_DEG)) % 360; - LL_INFOS("360Capture") << "Recording a heading of " << (int)(mInitialHeadingDeg) << LL_ENDL; + LL_INFOS("360Capture") << "Recording a heading of " << (int)(mInitialHeadingDeg) + << " Image size: " << (S32)mSourceImageSize << LL_ENDL; // camera constants for the square, cube map capture image camera->setAspect(1.0); // must set aspect ratio first to avoid undesirable clamping of vertical FoV @@ -587,6 +588,9 @@ void LLFloater360Capture::capture360Images() // for each of the 6 directions we shoot... for (int i = 0; i < 6; i++) { + LLAppViewer::instance()->pauseMainloopTimeout(); + LLViewerStats::instance().getRecording().stop(); + // these buffers are where the raw, captured pixels are stored and // the first time we use them, we have to make a new one if (mRawImages[i] == nullptr) @@ -624,8 +628,10 @@ void LLFloater360Capture::capture360Images() auto duration = std::chrono::duration_cast<std::chrono::duration<double>>(t_end - t_start); encode_time_total += duration.count(); - // ping the main loop in case the snapshot process takes a really long - // time and we get disconnected + LLViewerStats::instance().getRecording().resume(); + LLAppViewer::instance()->resumeMainloopTimeout(); + + // update main loop timeout state LLAppViewer::instance()->pingMainloopTimeout("LLFloater360Capture::capture360Images"); } @@ -892,8 +898,10 @@ const std::string LLFloater360Capture::generate_proposed_filename() // this looks complex but it's straightforward - removes all non-alpha chars from a string // which in this case is the SL region name - we use it as a proposed filename but the user is free to change std::string region_name = region->getName(); - std::replace_if(region_name.begin(), region_name.end(), std::not1(std::ptr_fun(isalnum)), '_'); - if (region_name.length() > 0) + std::replace_if(region_name.begin(), region_name.end(), + [](char c){ return ! std::isalnum(c); }, + '_'); + if (! region_name.empty()) { filename << region_name; filename << "_"; diff --git a/indra/newview/llfloateravatar.cpp b/indra/newview/llfloateravatar.cpp index 31adf5b61e..f888d032ae 100644 --- a/indra/newview/llfloateravatar.cpp +++ b/indra/newview/llfloateravatar.cpp @@ -44,17 +44,21 @@ LLFloaterAvatar::LLFloaterAvatar(const LLSD& key) LLFloaterAvatar::~LLFloaterAvatar() { - LLMediaCtrl* avatar_picker = findChild<LLMediaCtrl>("avatar_picker_contents"); - if (avatar_picker) + if (mAvatarPicker) { - avatar_picker->navigateStop(); - avatar_picker->clearCache(); //images are reloading each time already - avatar_picker->unloadMediaSource(); + mAvatarPicker->navigateStop(); + mAvatarPicker->clearCache(); //images are reloading each time already + mAvatarPicker->unloadMediaSource(); } } BOOL LLFloaterAvatar::postBuild() { + mAvatarPicker = findChild<LLMediaCtrl>("avatar_picker_contents"); + if (mAvatarPicker) + { + mAvatarPicker->clearCache(); + } enableResizeCtrls(true, true, false); return TRUE; } diff --git a/indra/newview/llfloateravatar.h b/indra/newview/llfloateravatar.h index cadc5e4028..76e9372709 100644 --- a/indra/newview/llfloateravatar.h +++ b/indra/newview/llfloateravatar.h @@ -29,6 +29,7 @@ #define LL_FLOATER_AVATAR_H #include "llfloater.h" +class LLMediaCtrl; class LLFloaterAvatar: public LLFloater @@ -38,6 +39,8 @@ private: LLFloaterAvatar(const LLSD& key); /*virtual*/ ~LLFloaterAvatar(); /*virtual*/ BOOL postBuild(); + + LLMediaCtrl* mAvatarPicker; }; #endif diff --git a/indra/newview/llfloateravatarpicker.cpp b/indra/newview/llfloateravatarpicker.cpp index 0186c4aebe..2422596f60 100644 --- a/indra/newview/llfloateravatarpicker.cpp +++ b/indra/newview/llfloateravatarpicker.cpp @@ -428,13 +428,18 @@ void LLFloaterAvatarPicker::findCoro(std::string url, LLUUID queryID, std::strin if (status || (status == LLCore::HttpStatus(HTTP_BAD_REQUEST))) { - LLFloaterAvatarPicker* floater = - LLFloaterReg::findTypedInstance<LLFloaterAvatarPicker>("avatar_picker", name); - if (floater) - { - result.erase(LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS); - floater->processResponse(queryID, result); - } + result.erase(LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS); + } + else + { + result["failure_reason"] = status.toString(); + } + + LLFloaterAvatarPicker* floater = + LLFloaterReg::findTypedInstance<LLFloaterAvatarPicker>("avatar_picker", name); + if (floater) + { + floater->processResponse(queryID, result); } } @@ -672,59 +677,67 @@ void LLFloaterAvatarPicker::processResponse(const LLUUID& query_id, const LLSD& { LLScrollListCtrl* search_results = getChild<LLScrollListCtrl>("SearchResults"); - LLSD agents = content["agents"]; - - // clear "Searching" label on first results - search_results->deleteAllItems(); - - LLSD item; - LLSD::array_const_iterator it = agents.beginArray(); - for ( ; it != agents.endArray(); ++it) - { - const LLSD& row = *it; - if (row["id"].asUUID() != gAgent.getID() || !mExcludeAgentFromSearchResults) - { - item["id"] = row["id"]; - LLSD& columns = item["columns"]; - columns[0]["column"] = "name"; - columns[0]["value"] = row["display_name"]; - columns[1]["column"] = "username"; - columns[1]["value"] = row["username"]; - search_results->addElement(item); - - // add the avatar name to our list - LLAvatarName avatar_name; - avatar_name.fromLLSD(row); - sAvatarNameMap[row["id"].asUUID()] = avatar_name; - } - } + // clear "Searching" label on first results + search_results->deleteAllItems(); - if (search_results->isEmpty()) - { - std::string name = "'" + getChild<LLUICtrl>("Edit")->getValue().asString() + "'"; - LLSD item; - item["id"] = LLUUID::null; - item["columns"][0]["column"] = "name"; - item["columns"][0]["value"] = name; - item["columns"][1]["column"] = "username"; - item["columns"][1]["value"] = getString("not_found_text"); - search_results->addElement(item); - search_results->setEnabled(false); - getChildView("ok_btn")->setEnabled(false); - } - else - { - getChildView("ok_btn")->setEnabled(true); - search_results->setEnabled(true); - search_results->sortByColumnIndex(1, TRUE); - std::string text = getChild<LLUICtrl>("Edit")->getValue().asString(); - if (!search_results->selectItemByLabel(text, TRUE, 1)) - { - search_results->selectFirstItem(); - } - onList(); - search_results->setFocus(TRUE); - } + if (content.has("failure_reason")) + { + getChild<LLScrollListCtrl>("SearchResults")->setCommentText(content["failure_reason"].asString()); + getChildView("ok_btn")->setEnabled(false); + } + else + { + LLSD agents = content["agents"]; + + LLSD item; + LLSD::array_const_iterator it = agents.beginArray(); + for (; it != agents.endArray(); ++it) + { + const LLSD& row = *it; + if (row["id"].asUUID() != gAgent.getID() || !mExcludeAgentFromSearchResults) + { + item["id"] = row["id"]; + LLSD& columns = item["columns"]; + columns[0]["column"] = "name"; + columns[0]["value"] = row["display_name"]; + columns[1]["column"] = "username"; + columns[1]["value"] = row["username"]; + search_results->addElement(item); + + // add the avatar name to our list + LLAvatarName avatar_name; + avatar_name.fromLLSD(row); + sAvatarNameMap[row["id"].asUUID()] = avatar_name; + } + } + + if (search_results->isEmpty()) + { + std::string name = "'" + getChild<LLUICtrl>("Edit")->getValue().asString() + "'"; + LLSD item; + item["id"] = LLUUID::null; + item["columns"][0]["column"] = "name"; + item["columns"][0]["value"] = name; + item["columns"][1]["column"] = "username"; + item["columns"][1]["value"] = getString("not_found_text"); + search_results->addElement(item); + search_results->setEnabled(false); + getChildView("ok_btn")->setEnabled(false); + } + else + { + getChildView("ok_btn")->setEnabled(true); + search_results->setEnabled(true); + search_results->sortByColumnIndex(1, TRUE); + std::string text = getChild<LLUICtrl>("Edit")->getValue().asString(); + if (!search_results->selectItemByLabel(text, TRUE, 1)) + { + search_results->selectFirstItem(); + } + onList(); + search_results->setFocus(TRUE); + } + } } } diff --git a/indra/newview/llfloateravatarrendersettings.cpp b/indra/newview/llfloateravatarrendersettings.cpp index b8f854feb3..8b28f6941e 100644 --- a/indra/newview/llfloateravatarrendersettings.cpp +++ b/indra/newview/llfloateravatarrendersettings.cpp @@ -89,6 +89,7 @@ BOOL LLFloaterAvatarRenderSettings::postBuild() LLFloater::postBuild(); mAvatarSettingsList = getChild<LLNameListCtrl>("render_settings_list"); mAvatarSettingsList->setRightMouseDownCallback(boost::bind(&LLFloaterAvatarRenderSettings::onAvatarListRightClick, this, _1, _2, _3)); + mAvatarSettingsList->setAlternateSort(); getChild<LLFilterEditor>("people_filter_input")->setCommitCallback(boost::bind(&LLFloaterAvatarRenderSettings::onFilterEdit, this, _2)); return TRUE; @@ -138,8 +139,8 @@ void LLFloaterAvatarRenderSettings::updateList() item_params.columns.add().value(av_name.getCompleteName()).column("name"); std::string setting = getString(iter->second == 1 ? "av_never_render" : "av_always_render"); item_params.columns.add().value(setting).column("setting"); - std::string timestamp = createTimestamp(LLRenderMuteList::getInstance()->getVisualMuteDate(iter->first)); - item_params.columns.add().value(timestamp).column("timestamp"); + S32 mute_date = LLRenderMuteList::getInstance()->getVisualMuteDate(iter->first); + item_params.columns.add().value(createTimestamp(mute_date)).column("timestamp").alt_value(std::to_string(mute_date)); mAvatarSettingsList->addNameItemRow(item_params); } } diff --git a/indra/newview/llfloaterbump.cpp b/indra/newview/llfloaterbump.cpp index 33e4c7cd5f..307ab8c4d1 100644 --- a/indra/newview/llfloaterbump.cpp +++ b/indra/newview/llfloaterbump.cpp @@ -69,6 +69,12 @@ LLFloaterBump::LLFloaterBump(const LLSD& key) // Destroys the object LLFloaterBump::~LLFloaterBump() { + auto menu = mPopupMenuHandle.get(); + if (menu) + { + menu->die(); + mPopupMenuHandle.markDead(); + } } BOOL LLFloaterBump::postBuild() @@ -77,11 +83,15 @@ BOOL LLFloaterBump::postBuild() mList->setAllowMultipleSelection(false); mList->setRightMouseDownCallback(boost::bind(&LLFloaterBump::onScrollListRightClicked, this, _1, _2, _3)); - mPopupMenu = LLUICtrlFactory::getInstance()->createFromFile<LLContextMenu>("menu_avatar_other.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); - mPopupMenu->setItemVisible(std::string("Normal"), false); - mPopupMenu->setItemVisible(std::string("Always use impostor"), false); - mPopupMenu->setItemVisible(std::string("Never use impostor"), false); - mPopupMenu->setItemVisible(std::string("Impostor seperator"), false); + LLContextMenu* menu = LLUICtrlFactory::getInstance()->createFromFile<LLContextMenu>("menu_avatar_other.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); + if (menu) + { + mPopupMenuHandle = menu->getHandle(); + menu->setItemVisible(std::string("Normal"), false); + menu->setItemVisible(std::string("Always use impostor"), false); + menu->setItemVisible(std::string("Never use impostor"), false); + menu->setItemVisible(std::string("Impostor seperator"), false); + } return TRUE; } @@ -176,18 +186,19 @@ void LLFloaterBump::onScrollListRightClicked(LLUICtrl* ctrl, S32 x, S32 y) if (!gMeanCollisionList.empty()) { LLScrollListItem* item = mList->hitItem(x, y); - if (item && mPopupMenu) + auto menu = mPopupMenuHandle.get(); + if (item && menu) { mItemUUID = item->getUUID(); - mPopupMenu->buildDrawLabels(); - mPopupMenu->updateParent(LLMenuGL::sMenuContainer); + menu->buildDrawLabels(); + menu->updateParent(LLMenuGL::sMenuContainer); std::string mute_msg = (LLMuteList::getInstance()->isMuted(mItemUUID, mNames[mItemUUID])) ? "UnmuteAvatar" : "MuteAvatar"; - mPopupMenu->getChild<LLUICtrl>("Avatar Mute")->setValue(LLTrans::getString(mute_msg)); - mPopupMenu->setItemEnabled(std::string("Zoom In"), bool(gObjectList.findObject(mItemUUID))); + menu->getChild<LLUICtrl>("Avatar Mute")->setValue(LLTrans::getString(mute_msg)); + menu->setItemEnabled(std::string("Zoom In"), bool(gObjectList.findObject(mItemUUID))); - ((LLContextMenu*)mPopupMenu)->show(x, y); - LLMenuGL::showPopup(ctrl, mPopupMenu, x, y); + menu->show(x, y); + LLMenuGL::showPopup(ctrl, menu, x, y); } } } diff --git a/indra/newview/llfloaterbump.h b/indra/newview/llfloaterbump.h index ce52c75255..d2f9fabdd3 100644 --- a/indra/newview/llfloaterbump.h +++ b/indra/newview/llfloaterbump.h @@ -68,7 +68,7 @@ private: virtual ~LLFloaterBump(); LLScrollListCtrl* mList; - LLMenuGL* mPopupMenu; + LLHandle<LLContextMenu> mPopupMenuHandle; LLUUID mItemUUID; typedef std::map<LLUUID, std::string> uuid_map_t; diff --git a/indra/newview/llfloatercreatelandmark.cpp b/indra/newview/llfloatercreatelandmark.cpp index 7def855d83..b82d8a29ba 100644 --- a/indra/newview/llfloatercreatelandmark.cpp +++ b/indra/newview/llfloatercreatelandmark.cpp @@ -316,7 +316,6 @@ void LLFloaterCreateLandmark::onSaveClicked() LLStringUtil::trim(current_title_value); LLStringUtil::trim(current_notes_value); - LLUUID item_id = mItem->getUUID(); LLUUID folder_id = mFolderCombo->getValue().asUUID(); bool change_parent = folder_id != mItem->getParentUUID(); diff --git a/indra/newview/llfloaterdisplayname.cpp b/indra/newview/llfloaterdisplayname.cpp index 3b0c67415a..19bc865d8b 100644 --- a/indra/newview/llfloaterdisplayname.cpp +++ b/indra/newview/llfloaterdisplayname.cpp @@ -47,6 +47,7 @@ public: virtual ~LLFloaterDisplayName() { } /*virtual*/ BOOL postBuild(); void onSave(); + void onReset(); void onCancel(); /*virtual*/ void onOpen(const LLSD& key); @@ -101,6 +102,7 @@ void LLFloaterDisplayName::onOpen(const LLSD& key) BOOL LLFloaterDisplayName::postBuild() { + getChild<LLUICtrl>("reset_btn")->setCommitCallback(boost::bind(&LLFloaterDisplayName::onReset, this)); getChild<LLUICtrl>("cancel_btn")->setCommitCallback(boost::bind(&LLFloaterDisplayName::onCancel, this)); getChild<LLUICtrl>("save_btn")->setCommitCallback(boost::bind(&LLFloaterDisplayName::onSave, this)); @@ -156,6 +158,20 @@ void LLFloaterDisplayName::onCancel() setVisible(false); } +void LLFloaterDisplayName::onReset() +{ + LLAvatarName av_name; + if (!LLAvatarNameCache::get(gAgent.getID(), &av_name)) + { + return; + } + getChild<LLUICtrl>("display_name_editor")->setValue(av_name.getCompleteName()); + + getChild<LLUICtrl>("display_name_confirm")->clear(); + getChild<LLUICtrl>("display_name_confirm")->setFocus(TRUE); +} + + void LLFloaterDisplayName::onSave() { std::string display_name_utf8 = getChild<LLUICtrl>("display_name_editor")->getValue().asString(); diff --git a/indra/newview/llfloaterimcontainer.cpp b/indra/newview/llfloaterimcontainer.cpp index 703b5d0011..2720b7fcf7 100644 --- a/indra/newview/llfloaterimcontainer.cpp +++ b/indra/newview/llfloaterimcontainer.cpp @@ -211,6 +211,7 @@ BOOL LLFloaterIMContainer::postBuild() p.options_menu = "menu_conversation.xml"; mConversationsRoot = LLUICtrlFactory::create<LLFolderView>(p); mConversationsRoot->setCallbackRegistrar(&mCommitCallbackRegistrar); + mConversationsRoot->setEnableRegistrar(&mEnableCallbackRegistrar); // Add listener to conversation model events mConversationsEventStream.listen("ConversationsRefresh", boost::bind(&LLFloaterIMContainer::onConversationModelEvent, this, _1)); diff --git a/indra/newview/llfloaterimsessiontab.cpp b/indra/newview/llfloaterimsessiontab.cpp index 204cd03b09..78271369d2 100644 --- a/indra/newview/llfloaterimsessiontab.cpp +++ b/indra/newview/llfloaterimsessiontab.cpp @@ -316,6 +316,7 @@ BOOL LLFloaterIMSessionTab::postBuild() p.name = "root"; mConversationsRoot = LLUICtrlFactory::create<LLFolderView>(p); mConversationsRoot->setCallbackRegistrar(&mCommitCallbackRegistrar); + mConversationsRoot->setEnableRegistrar(&mEnableCallbackRegistrar); // Attach that root to the scroller mScroller->addChild(mConversationsRoot); mConversationsRoot->setScrollContainer(mScroller); diff --git a/indra/newview/llfloatermodelpreview.cpp b/indra/newview/llfloatermodelpreview.cpp index 66a245b779..6f8f73bca0 100644 --- a/indra/newview/llfloatermodelpreview.cpp +++ b/indra/newview/llfloatermodelpreview.cpp @@ -1740,7 +1740,7 @@ void LLFloaterModelPreview::toggleCalculateButton(bool visible) childSetTextArg("download_weight", "[ST]", tbd); childSetTextArg("server_weight", "[SIM]", tbd); childSetTextArg("physics_weight", "[PH]", tbd); - if (!mModelPhysicsFee.isMap() || mModelPhysicsFee.emptyMap()) + if (!mModelPhysicsFee.isMap() || (mModelPhysicsFee.size() == 0)) { childSetTextArg("upload_fee", "[FEE]", tbd); } diff --git a/indra/newview/llfloateropenobject.cpp b/indra/newview/llfloateropenobject.cpp index 2a1749bd42..a682064dad 100644 --- a/indra/newview/llfloateropenobject.cpp +++ b/indra/newview/llfloateropenobject.cpp @@ -56,8 +56,6 @@ LLFloaterOpenObject::LLFloaterOpenObject(const LLSD& key) mDirty(TRUE) { mCommitCallbackRegistrar.add("OpenObject.MoveToInventory", boost::bind(&LLFloaterOpenObject::onClickMoveToInventory, this)); - mCommitCallbackRegistrar.add("OpenObject.MoveAndWear", boost::bind(&LLFloaterOpenObject::onClickMoveAndWear, this)); - mCommitCallbackRegistrar.add("OpenObject.ReplaceOutfit", boost::bind(&LLFloaterOpenObject::onClickReplace, this)); mCommitCallbackRegistrar.add("OpenObject.Cancel", boost::bind(&LLFloaterOpenObject::onClickCancel, this)); } @@ -243,18 +241,6 @@ void LLFloaterOpenObject::onClickMoveToInventory() closeFloater(); } -void LLFloaterOpenObject::onClickMoveAndWear() -{ - moveToInventory(true, false); - closeFloater(); -} - -void LLFloaterOpenObject::onClickReplace() -{ - moveToInventory(true, true); - closeFloater(); -} - void LLFloaterOpenObject::onClickCancel() { closeFloater(); diff --git a/indra/newview/llfloateropenobject.h b/indra/newview/llfloateropenobject.h index 2e761f99bf..745753316b 100644 --- a/indra/newview/llfloateropenobject.h +++ b/indra/newview/llfloateropenobject.h @@ -63,8 +63,6 @@ protected: void moveToInventory(bool wear, bool replace = false); void onClickMoveToInventory(); - void onClickMoveAndWear(); - void onClickReplace(); void onClickCancel(); static void callbackCreateInventoryCategory(const LLUUID& category_id, LLUUID object_id, bool wear, bool replace = false); static void callbackMoveInventory(S32 result, void* data); diff --git a/indra/newview/llfloateroutfitphotopreview.cpp b/indra/newview/llfloateroutfitphotopreview.cpp index 6c39db730c..ade258aef7 100644 --- a/indra/newview/llfloateroutfitphotopreview.cpp +++ b/indra/newview/llfloateroutfitphotopreview.cpp @@ -234,7 +234,6 @@ void LLFloaterOutfitPhotoPreview::updateImageID() if(item) { mImageID = item->getAssetUUID(); - LLPermissions perm(item->getPermissions()); } else { diff --git a/indra/newview/llfloaterpathfindinglinksets.cpp b/indra/newview/llfloaterpathfindinglinksets.cpp index 1e46d7a402..03aede94c6 100644 --- a/indra/newview/llfloaterpathfindinglinksets.cpp +++ b/indra/newview/llfloaterpathfindinglinksets.cpp @@ -44,6 +44,7 @@ #include "llpathfindinglinkset.h" #include "llpathfindinglinksetlist.h" #include "llpathfindingmanager.h" +#include "llsearcheditor.h" #include "llscrolllistitem.h" #include "llsd.h" #include "lltextbase.h" @@ -114,17 +115,13 @@ BOOL LLFloaterPathfindingLinksets::postBuild() { mBeaconColor = LLUIColorTable::getInstance()->getColor("PathfindingLinksetBeaconColor"); - mFilterByName = findChild<LLLineEditor>("filter_by_name"); - llassert(mFilterByName != NULL); - mFilterByName->setCommitCallback(boost::bind(&LLFloaterPathfindingLinksets::onApplyAllFilters, this)); - mFilterByName->setSelectAllonFocusReceived(true); - mFilterByName->setCommitOnFocusLost(true); - - mFilterByDescription = findChild<LLLineEditor>("filter_by_description"); - llassert(mFilterByDescription != NULL); - mFilterByDescription->setCommitCallback(boost::bind(&LLFloaterPathfindingLinksets::onApplyAllFilters, this)); - mFilterByDescription->setSelectAllonFocusReceived(true); - mFilterByDescription->setCommitOnFocusLost(true); + mFilterByName = getChild<LLSearchEditor>("filter_by_name"); + mFilterByName->setCommitCallback(boost::bind(&LLFloaterPathfindingLinksets::onApplyAllFilters, this)); + mFilterByName->setCommitOnFocusLost(true); + + mFilterByDescription = getChild<LLSearchEditor>("filter_by_description"); + mFilterByDescription->setCommitCallback(boost::bind(&LLFloaterPathfindingLinksets::onApplyAllFilters, this)); + mFilterByDescription->setCommitOnFocusLost(true); mFilterByLinksetUse = findChild<LLComboBox>("filter_by_linkset_use"); llassert(mFilterByLinksetUse != NULL); diff --git a/indra/newview/llfloaterpathfindinglinksets.h b/indra/newview/llfloaterpathfindinglinksets.h index 7149da9215..a954d8a8ec 100644 --- a/indra/newview/llfloaterpathfindinglinksets.h +++ b/indra/newview/llfloaterpathfindinglinksets.h @@ -42,6 +42,7 @@ class LLSD; class LLTextBase; class LLUICtrl; class LLVector3; +class LLSearchEditor; class LLFloaterPathfindingLinksets : public LLFloaterPathfindingObjects { @@ -105,8 +106,8 @@ private: LLPathfindingLinkset::ELinksetUse convertToLinksetUse(LLSD pXuiValue) const; LLSD convertToXuiValue(LLPathfindingLinkset::ELinksetUse pLinksetUse) const; - LLLineEditor *mFilterByName; - LLLineEditor *mFilterByDescription; + LLSearchEditor *mFilterByName; + LLSearchEditor *mFilterByDescription; LLComboBox *mFilterByLinksetUse; LLComboBox *mEditLinksetUse; LLScrollListItem *mEditLinksetUseUnset; diff --git a/indra/newview/llfloaterregioninfo.cpp b/indra/newview/llfloaterregioninfo.cpp index 07d4dcae38..da7a4733c7 100644 --- a/indra/newview/llfloaterregioninfo.cpp +++ b/indra/newview/llfloaterregioninfo.cpp @@ -657,13 +657,11 @@ void LLFloaterRegionInfo::refreshFromRegion(LLViewerRegion* region) } // call refresh from region on all panels - std::for_each( - mInfoPanels.begin(), - mInfoPanels.end(), - llbind2nd( - std::mem_fun(&LLPanelRegionInfo::refreshFromRegion), - region)); - mEnvironmentPanel->refreshFromRegion(region); + for (const auto& infoPanel : mInfoPanels) + { + infoPanel->refreshFromRegion(region); + } + mEnvironmentPanel->refreshFromRegion(region); } // public @@ -1882,6 +1880,7 @@ BOOL LLPanelEstateInfo::postBuild() initCtrl("allow_direct_teleport"); initCtrl("limit_payment"); initCtrl("limit_age_verified"); + initCtrl("limit_bots"); initCtrl("voice_chat_check"); initCtrl("parcel_access_override"); @@ -1905,12 +1904,14 @@ void LLPanelEstateInfo::refresh() getChildView("Only Allow")->setEnabled(public_access); getChildView("limit_payment")->setEnabled(public_access); getChildView("limit_age_verified")->setEnabled(public_access); + getChildView("limit_bots")->setEnabled(public_access); // if this is set to false, then the limit fields are meaningless and should be turned off if (public_access == false) { getChild<LLUICtrl>("limit_payment")->setValue(false); getChild<LLUICtrl>("limit_age_verified")->setValue(false); + getChild<LLUICtrl>("limit_bots")->setValue(false); } } @@ -1927,6 +1928,7 @@ void LLPanelEstateInfo::refreshFromEstate() getChild<LLUICtrl>("limit_payment")->setValue(estate_info.getDenyAnonymous()); getChild<LLUICtrl>("limit_age_verified")->setValue(estate_info.getDenyAgeUnverified()); getChild<LLUICtrl>("parcel_access_override")->setValue(estate_info.getAllowAccessOverride()); + getChild<LLUICtrl>("limit_bots")->setValue(estate_info.getDenyScriptedAgents()); // Ensure appriopriate state of the management UI updateControls(gAgent.getRegion()); @@ -1970,6 +1972,7 @@ bool LLPanelEstateInfo::callbackChangeLindenEstate(const LLSD& notification, con estate_info.setDenyAgeUnverified(getChild<LLUICtrl>("limit_age_verified")->getValue().asBoolean()); estate_info.setAllowVoiceChat(getChild<LLUICtrl>("voice_chat_check")->getValue().asBoolean()); estate_info.setAllowAccessOverride(getChild<LLUICtrl>("parcel_access_override")->getValue().asBoolean()); + estate_info.setDenyScriptedAgents(getChild<LLUICtrl>("limit_bots")->getValue().asBoolean()); // JIGGLYPUFF //estate_info.setAllowAccessOverride(getChild<LLUICtrl>("")->getValue().asBoolean()); // send the update to sim diff --git a/indra/newview/llfloaterscriptlimits.cpp b/indra/newview/llfloaterscriptlimits.cpp index 3746b9b6c2..40fe11b309 100644 --- a/indra/newview/llfloaterscriptlimits.cpp +++ b/indra/newview/llfloaterscriptlimits.cpp @@ -421,7 +421,6 @@ void LLPanelScriptLimitsRegionMemory::setRegionDetails(LLSD content) for(S32 i = 0; i < number_parcels; i++) { std::string parcel_name = content["parcels"][i]["name"].asString(); - LLUUID parcel_id = content["parcels"][i]["id"].asUUID(); S32 number_objects = content["parcels"][i]["objects"].size(); S32 local_id = 0; diff --git a/indra/newview/llfloatersearch.cpp b/indra/newview/llfloatersearch.cpp index bb3ed77772..7e6af45515 100644 --- a/indra/newview/llfloatersearch.cpp +++ b/indra/newview/llfloatersearch.cpp @@ -45,7 +45,7 @@ class LLSearchHandler : public LLCommandHandler { public: // requires trusted browser to trigger - LLSearchHandler() : LLCommandHandler("search", UNTRUSTED_THROTTLE) { } + LLSearchHandler() : LLCommandHandler("search", UNTRUSTED_CLICK_ONLY) { } bool handle(const LLSD& tokens, const LLSD& query_map, LLMediaCtrl* web) { if (!LLUI::getInstance()->mSettingGroups["config"]->getBOOL("EnableSearch")) diff --git a/indra/newview/llfloatersettingsdebug.cpp b/indra/newview/llfloatersettingsdebug.cpp index 186994c857..3c7f341613 100644 --- a/indra/newview/llfloatersettingsdebug.cpp +++ b/indra/newview/llfloatersettingsdebug.cpp @@ -2,9 +2,9 @@ * @file llfloatersettingsdebug.cpp * @brief floater for debugging internal viewer settings * - * $LicenseInfo:firstyear=2001&license=viewerlgpl$ + * $LicenseInfo:firstyear=2022&license=viewerlgpl$ * Second Life Viewer Source Code - * Copyright (C) 2010, Linden Research, Inc. + * Copyright (C) 2022, Linden Research, Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -27,8 +27,8 @@ #include "llviewerprecompiledheaders.h" #include "llfloatersettingsdebug.h" #include "llfloater.h" +#include "llfiltereditor.h" #include "lluictrlfactory.h" -//#include "llfirstuse.h" #include "llcombobox.h" #include "llspinctrl.h" #include "llcolorswatch.h" @@ -37,12 +37,11 @@ LLFloaterSettingsDebug::LLFloaterSettingsDebug(const LLSD& key) -: LLFloater(key) +: LLFloater(key), + mSettingList(NULL) { - mCommitCallbackRegistrar.add("SettingSelect", boost::bind(&LLFloaterSettingsDebug::onSettingSelect, this,_1)); mCommitCallbackRegistrar.add("CommitSettings", boost::bind(&LLFloaterSettingsDebug::onCommitSettings, this)); mCommitCallbackRegistrar.add("ClickDefault", boost::bind(&LLFloaterSettingsDebug::onClickDefault, this)); - } LLFloaterSettingsDebug::~LLFloaterSettingsDebug() @@ -50,59 +49,43 @@ LLFloaterSettingsDebug::~LLFloaterSettingsDebug() BOOL LLFloaterSettingsDebug::postBuild() { - LLComboBox* settings_combo = getChild<LLComboBox>("settings_combo"); + enableResizeCtrls(true, false, true); - struct f : public LLControlGroup::ApplyFunctor - { - LLComboBox* combo; - f(LLComboBox* c) : combo(c) {} - virtual void apply(const std::string& name, LLControlVariable* control) - { - if (!control->isHiddenFromSettingsEditor()) - { - combo->add(name, (void*)control); - } - } - } func(settings_combo); + mComment = getChild<LLTextEditor>("comment_text"); - std::string key = getKey().asString(); - if (key == "all" || key == "base") - { - gSavedSettings.applyToAll(&func); - } - if (key == "all" || key == "account") - { - gSavedPerAccountSettings.applyToAll(&func); - } + getChild<LLFilterEditor>("filter_input")->setCommitCallback(boost::bind(&LLFloaterSettingsDebug::setSearchFilter, this, _2)); + + mSettingList = getChild<LLScrollListCtrl>("setting_list"); + mSettingList->setCommitOnSelectionChange(TRUE); + mSettingList->setCommitCallback(boost::bind(&LLFloaterSettingsDebug::onSettingSelect, this)); + + updateList(); + + gSavedSettings.getControl("DebugSettingsHideDefault")->getCommitSignal()->connect(boost::bind(&LLFloaterSettingsDebug::updateList, this, false)); - settings_combo->sortByName(); - settings_combo->updateSelection(); - mComment = getChild<LLTextEditor>("comment_text"); return TRUE; } void LLFloaterSettingsDebug::draw() { - LLComboBox* settings_combo = getChild<LLComboBox>("settings_combo"); - LLControlVariable* controlp = (LLControlVariable*)settings_combo->getCurrentUserdata(); - updateControl(controlp); + LLScrollListItem* first_selected = mSettingList->getFirstSelected(); + if (first_selected) + { + LLControlVariable* controlp = (LLControlVariable*)first_selected->getUserdata(); + updateControl(controlp); + } LLFloater::draw(); } -//static -void LLFloaterSettingsDebug::onSettingSelect(LLUICtrl* ctrl) -{ - LLComboBox* combo_box = (LLComboBox*)ctrl; - LLControlVariable* controlp = (LLControlVariable*)combo_box->getCurrentUserdata(); - - updateControl(controlp); -} - void LLFloaterSettingsDebug::onCommitSettings() { - LLComboBox* settings_combo = getChild<LLComboBox>("settings_combo"); - LLControlVariable* controlp = (LLControlVariable*)settings_combo->getCurrentUserdata(); + LLScrollListItem* first_selected = mSettingList->getFirstSelected(); + if (!first_selected) + { + return; + } + LLControlVariable* controlp = (LLControlVariable*)first_selected->getUserdata(); if (!controlp) { @@ -176,19 +159,23 @@ void LLFloaterSettingsDebug::onCommitSettings() default: break; } + updateDefaultColumn(controlp); } // static void LLFloaterSettingsDebug::onClickDefault() { - LLComboBox* settings_combo = getChild<LLComboBox>("settings_combo"); - LLControlVariable* controlp = (LLControlVariable*)settings_combo->getCurrentUserdata(); - - if (controlp) - { - controlp->resetToDefault(true); - updateControl(controlp); - } + LLScrollListItem* first_selected = mSettingList->getFirstSelected(); + if (first_selected) + { + LLControlVariable* controlp = (LLControlVariable*)first_selected->getUserdata(); + if (controlp) + { + controlp->resetToDefault(true); + updateDefaultColumn(controlp); + updateControl(controlp); + } + } } // we've switched controls, or doing per-frame update, so update spinners, etc. @@ -207,23 +194,30 @@ void LLFloaterSettingsDebug::updateControl(LLControlVariable* controlp) return; } - spinner1->setVisible(FALSE); - spinner2->setVisible(FALSE); - spinner3->setVisible(FALSE); - spinner4->setVisible(FALSE); - color_swatch->setVisible(FALSE); - getChildView("val_text")->setVisible( FALSE); - mComment->setText(LLStringUtil::null); + hideUIControls(); - if (controlp) + if (controlp && !isSettingHidden(controlp)) { eControlType type = controlp->type(); //hide combo box only for non booleans, otherwise this will result in the combo box closing every frame getChildView("boolean_combo")->setVisible( type == TYPE_BOOLEAN); - + getChildView("default_btn")->setVisible(true); + getChildView("setting_name_txt")->setVisible(true); + getChild<LLTextBox>("setting_name_txt")->setText(controlp->getName()); + getChild<LLTextBox>("setting_name_txt")->setToolTip(controlp->getName()); + mComment->setVisible(true); + + std::string old_text = mComment->getText(); + std::string new_text = controlp->getComment(); + // Don't setText if not nessesary, it will reset scroll + // This is a debug UI that reads from xml, there might + // be use cases where comment changes, but not the name + if (old_text != new_text) + { + mComment->setText(controlp->getComment()); + } - mComment->setText(controlp->getComment()); spinner1->setMaxValue(F32_MAX); spinner2->setMaxValue(F32_MAX); spinner3->setMaxValue(F32_MAX); @@ -479,3 +473,166 @@ void LLFloaterSettingsDebug::updateControl(LLControlVariable* controlp) } } + +void LLFloaterSettingsDebug::updateList(bool skip_selection) +{ + std::string last_selected; + LLScrollListItem* item = mSettingList->getFirstSelected(); + if (item) + { + LLScrollListCell* cell = item->getColumn(1); + if (cell) + { + last_selected = cell->getValue().asString(); + } + } + + mSettingList->deleteAllItems(); + struct f : public LLControlGroup::ApplyFunctor + { + LLScrollListCtrl* setting_list; + LLFloaterSettingsDebug* floater; + std::string selected_setting; + bool skip_selection; + f(LLScrollListCtrl* list, LLFloaterSettingsDebug* floater, std::string setting, bool skip_selection) + : setting_list(list), floater(floater), selected_setting(setting), skip_selection(skip_selection) {} + virtual void apply(const std::string& name, LLControlVariable* control) + { + if (!control->isHiddenFromSettingsEditor() && floater->matchesSearchFilter(name) && !floater->isSettingHidden(control)) + { + LLSD row; + + row["columns"][0]["column"] = "changed_setting"; + row["columns"][0]["value"] = control->isDefault() ? "" : "*"; + + row["columns"][1]["column"] = "setting"; + row["columns"][1]["value"] = name; + + LLScrollListItem* item = setting_list->addElement(row, ADD_BOTTOM, (void*)control); + if (!floater->mSearchFilter.empty() && (selected_setting == name) && !skip_selection) + { + std::string lower_name(name); + LLStringUtil::toLower(lower_name); + if (LLStringUtil::startsWith(lower_name, floater->mSearchFilter)) + { + item->setSelected(true); + } + } + } + } + } func(mSettingList, this, last_selected, skip_selection); + + std::string key = getKey().asString(); + if (key == "all" || key == "base") + { + gSavedSettings.applyToAll(&func); + } + if (key == "all" || key == "account") + { + gSavedPerAccountSettings.applyToAll(&func); + } + + + if (!mSettingList->isEmpty()) + { + if (mSettingList->hasSelectedItem()) + { + mSettingList->scrollToShowSelected(); + } + else if (!mSettingList->hasSelectedItem() && !mSearchFilter.empty() && !skip_selection) + { + if (!mSettingList->selectItemByPrefix(mSearchFilter, false, 1)) + { + mSettingList->selectFirstItem(); + } + mSettingList->scrollToShowSelected(); + } + } + else + { + LLSD row; + + row["columns"][0]["column"] = "changed_setting"; + row["columns"][0]["value"] = ""; + row["columns"][1]["column"] = "setting"; + row["columns"][1]["value"] = "No matching settings."; + + mSettingList->addElement(row); + hideUIControls(); + } +} + +void LLFloaterSettingsDebug::onSettingSelect() +{ + LLScrollListItem* first_selected = mSettingList->getFirstSelected(); + if (first_selected) + { + LLControlVariable* controlp = (LLControlVariable*)first_selected->getUserdata(); + if (controlp) + { + updateControl(controlp); + } + } +} + +void LLFloaterSettingsDebug::setSearchFilter(const std::string& filter) +{ + if(mSearchFilter == filter) + return; + mSearchFilter = filter; + LLStringUtil::toLower(mSearchFilter); + updateList(); +} + +bool LLFloaterSettingsDebug::matchesSearchFilter(std::string setting_name) +{ + // If the search filter is empty, everything passes. + if (mSearchFilter.empty()) return true; + + LLStringUtil::toLower(setting_name); + std::string::size_type match_name = setting_name.find(mSearchFilter); + + return (std::string::npos != match_name); +} + +bool LLFloaterSettingsDebug::isSettingHidden(LLControlVariable* control) +{ + static LLCachedControl<bool> hide_default(gSavedSettings, "DebugSettingsHideDefault", false); + return hide_default && control->isDefault(); +} + +void LLFloaterSettingsDebug::updateDefaultColumn(LLControlVariable* control) +{ + if (isSettingHidden(control)) + { + hideUIControls(); + updateList(true); + return; + } + + LLScrollListItem* item = mSettingList->getFirstSelected(); + if (item) + { + LLScrollListCell* cell = item->getColumn(0); + if (cell) + { + std::string is_default = control->isDefault() ? "" : "*"; + cell->setValue(is_default); + } + } +} + +void LLFloaterSettingsDebug::hideUIControls() +{ + getChildView("val_spinner_1")->setVisible(false); + getChildView("val_spinner_2")->setVisible(false); + getChildView("val_spinner_3")->setVisible(false); + getChildView("val_spinner_4")->setVisible(false); + getChildView("val_color_swatch")->setVisible(false); + getChildView("val_text")->setVisible(false); + getChildView("default_btn")->setVisible(false); + getChildView("boolean_combo")->setVisible(false); + getChildView("setting_name_txt")->setVisible(false); + mComment->setVisible(false); +} + diff --git a/indra/newview/llfloatersettingsdebug.h b/indra/newview/llfloatersettingsdebug.h index f07e0557e3..888eaadcbd 100644 --- a/indra/newview/llfloatersettingsdebug.h +++ b/indra/newview/llfloatersettingsdebug.h @@ -2,9 +2,9 @@ * @file llfloatersettingsdebug.h * @brief floater for debugging internal viewer settings * - * $LicenseInfo:firstyear=2001&license=viewerlgpl$ + * $LicenseInfo:firstyear=2022&license=viewerlgpl$ * Second Life Viewer Source Code - * Copyright (C) 2010, Linden Research, Inc. + * Copyright (C) 2022, Linden Research, Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -30,6 +30,8 @@ #include "llcontrol.h" #include "llfloater.h" +class LLScrollListCtrl; + class LLFloaterSettingsDebug : public LLFloater { @@ -42,18 +44,31 @@ public: void updateControl(LLControlVariable* control); - void onSettingSelect(LLUICtrl* ctrl); void onCommitSettings(); void onClickDefault(); + bool matchesSearchFilter(std::string setting_name); + bool isSettingHidden(LLControlVariable* control); + private: // key - selects which settings to show, one of: // "all", "base", "account", "skin" LLFloaterSettingsDebug(const LLSD& key); virtual ~LLFloaterSettingsDebug(); + + void updateList(bool skip_selection = false); + void onSettingSelect(); + void setSearchFilter(const std::string& filter); + + void updateDefaultColumn(LLControlVariable* control); + void hideUIControls(); + + LLScrollListCtrl* mSettingList; protected: class LLTextEditor* mComment; + + std::string mSearchFilter; }; #endif //LLFLOATERDEBUGSETTINGS_H diff --git a/indra/newview/llfloaterworldmap.cpp b/indra/newview/llfloaterworldmap.cpp index 01bfae8934..704abd269f 100755 --- a/indra/newview/llfloaterworldmap.cpp +++ b/indra/newview/llfloaterworldmap.cpp @@ -122,7 +122,7 @@ class LLWorldMapHandler : public LLCommandHandler { public: // requires trusted browser to trigger - LLWorldMapHandler() : LLCommandHandler("worldmap", UNTRUSTED_THROTTLE ) { } + LLWorldMapHandler() : LLCommandHandler("worldmap", UNTRUSTED_CLICK_ONLY ) { } bool handle(const LLSD& params, const LLSD& query_map, LLMediaCtrl* web) @@ -159,7 +159,7 @@ class LLMapTrackAvatarHandler : public LLCommandHandler { public: // requires trusted browser to trigger - LLMapTrackAvatarHandler() : LLCommandHandler("maptrackavatar", UNTRUSTED_THROTTLE) + LLMapTrackAvatarHandler() : LLCommandHandler("maptrackavatar", UNTRUSTED_CLICK_ONLY) { } diff --git a/indra/newview/llgesturemgr.cpp b/indra/newview/llgesturemgr.cpp index 489d34edca..c0f773968d 100644 --- a/indra/newview/llgesturemgr.cpp +++ b/indra/newview/llgesturemgr.cpp @@ -757,11 +757,11 @@ S32 LLGestureMgr::getPlayingCount() const } -struct IsGesturePlaying : public std::unary_function<LLMultiGesture*, bool> +struct IsGesturePlaying { bool operator()(const LLMultiGesture* gesture) const { - return gesture->mPlaying ? true : false; + return bool(gesture->mPlaying); } }; diff --git a/indra/newview/llgroupactions.cpp b/indra/newview/llgroupactions.cpp index dbeb157323..be52e280e1 100644 --- a/indra/newview/llgroupactions.cpp +++ b/indra/newview/llgroupactions.cpp @@ -52,7 +52,32 @@ class LLGroupHandler : public LLCommandHandler { public: // requires trusted browser to trigger - LLGroupHandler() : LLCommandHandler("group", UNTRUSTED_THROTTLE) { } + LLGroupHandler() : LLCommandHandler("group", UNTRUSTED_CLICK_ONLY) { } + + virtual bool canHandleUntrusted( + const LLSD& params, + const LLSD& query_map, + LLMediaCtrl* web, + const std::string& nav_type) + { + if (params.size() < 1) + { + return true; // don't block, will fail later + } + + if (nav_type == NAV_TYPE_CLICKED) + { + return true; + } + + const std::string verb = params[0].asString(); + if (verb == "create") + { + return false; + } + return true; + } + bool handle(const LLSD& tokens, const LLSD& query_map, LLMediaCtrl* web) { diff --git a/indra/newview/llhudnametag.cpp b/indra/newview/llhudnametag.cpp index 952fbf8e4b..ab6a64157c 100644 --- a/indra/newview/llhudnametag.cpp +++ b/indra/newview/llhudnametag.cpp @@ -56,7 +56,6 @@ const F32 HORIZONTAL_PADDING = 16.f; const F32 VERTICAL_PADDING = 12.f; const F32 LINE_PADDING = 3.f; // aka "leading" const F32 BUFFER_SIZE = 2.f; -const F32 HUD_TEXT_MAX_WIDTH = 190.f; const S32 NUM_OVERLAP_ITERATIONS = 10; const F32 POSITION_DAMPING_TC = 0.2f; const F32 MAX_STABLE_CAMERA_VELOCITY = 0.1f; @@ -67,6 +66,8 @@ const F32 LOD_2_SCREEN_COVERAGE = 0.40f; std::set<LLPointer<LLHUDNameTag> > LLHUDNameTag::sTextObjects; std::vector<LLPointer<LLHUDNameTag> > LLHUDNameTag::sVisibleTextObjects; BOOL LLHUDNameTag::sDisplayText = TRUE ; +const F32 LLHUDNameTag::NAMETAG_MAX_WIDTH = 298.f; +const F32 LLHUDNameTag::HUD_TEXT_MAX_WIDTH = 190.f; bool llhudnametag_further_away::operator()(const LLPointer<LLHUDNameTag>& lhs, const LLPointer<LLHUDNameTag>& rhs) const { @@ -414,7 +415,8 @@ void LLHUDNameTag::addLine(const std::string &text_utf8, const LLColor4& color, const LLFontGL::StyleFlags style, const LLFontGL* font, - const bool use_ellipses) + const bool use_ellipses, + F32 max_pixels) { LLWString wline = utf8str_to_wstring(text_utf8); if (!wline.empty()) @@ -431,7 +433,7 @@ void LLHUDNameTag::addLine(const std::string &text_utf8, tokenizer tokens(wline, sep); tokenizer::iterator iter = tokens.begin(); - const F32 max_pixels = HUD_TEXT_MAX_WIDTH; + max_pixels = llmin(max_pixels, NAMETAG_MAX_WIDTH); while (iter != tokens.end()) { U32 line_length = 0; @@ -488,7 +490,7 @@ void LLHUDNameTag::setLabel(const std::string &label_utf8) addLabel(label_utf8); } -void LLHUDNameTag::addLabel(const std::string& label_utf8) +void LLHUDNameTag::addLabel(const std::string& label_utf8, F32 max_pixels) { LLWString wstr = utf8string_to_wstring(label_utf8); if (!wstr.empty()) @@ -502,13 +504,15 @@ void LLHUDNameTag::addLabel(const std::string& label_utf8) tokenizer tokens(wstr, sep); tokenizer::iterator iter = tokens.begin(); + max_pixels = llmin(max_pixels, NAMETAG_MAX_WIDTH); + while (iter != tokens.end()) { U32 line_length = 0; do { S32 segment_length = mFontp->maxDrawableChars(iter->substr(line_length).c_str(), - HUD_TEXT_MAX_WIDTH, wstr.length(), LLFontGL::WORD_BOUNDARY_IF_POSSIBLE); + max_pixels, wstr.length(), LLFontGL::WORD_BOUNDARY_IF_POSSIBLE); LLHUDTextSegment segment(iter->substr(line_length, segment_length), LLFontGL::NORMAL, mColor, mFontp); mLabelSegments.push_back(segment); line_length += segment_length; @@ -695,7 +699,7 @@ void LLHUDNameTag::updateSize() const LLFontGL* fontp = iter->mFont; height += fontp->getLineHeight(); height += LINE_PADDING; - width = llmax(width, llmin(iter->getWidth(fontp), HUD_TEXT_MAX_WIDTH)); + width = llmax(width, llmin(iter->getWidth(fontp), NAMETAG_MAX_WIDTH)); ++iter; } @@ -709,7 +713,7 @@ void LLHUDNameTag::updateSize() while (iter != mLabelSegments.end()) { height += mFontp->getLineHeight(); - width = llmax(width, llmin(iter->getWidth(mFontp), HUD_TEXT_MAX_WIDTH)); + width = llmax(width, llmin(iter->getWidth(mFontp), NAMETAG_MAX_WIDTH)); ++iter; } diff --git a/indra/newview/llhudnametag.h b/indra/newview/llhudnametag.h index 7577dd5de6..361e4d4f4b 100644 --- a/indra/newview/llhudnametag.h +++ b/indra/newview/llhudnametag.h @@ -85,6 +85,9 @@ public: ALIGN_VERT_CENTER } EVertAlignment; + static const F32 NAMETAG_MAX_WIDTH; // 298px, made to fit 31 M's + static const F32 HUD_TEXT_MAX_WIDTH; // 190px + public: // Set entire string, eliminating existing lines void setString(const std::string& text_utf8); @@ -92,11 +95,17 @@ public: void clearString(); // Add text a line at a time, allowing custom formatting - void addLine(const std::string &text_utf8, const LLColor4& color, const LLFontGL::StyleFlags style = LLFontGL::NORMAL, const LLFontGL* font = NULL, const bool use_ellipses = false); + void addLine( + const std::string &text_utf8, + const LLColor4& color, + const LLFontGL::StyleFlags style = LLFontGL::NORMAL, + const LLFontGL* font = NULL, + const bool use_ellipses = false, + F32 max_pixels = HUD_TEXT_MAX_WIDTH); // For bubble chat, set the part above the chat text void setLabel(const std::string& label_utf8); - void addLabel(const std::string& label_utf8); + void addLabel(const std::string& label_utf8, F32 max_pixels = HUD_TEXT_MAX_WIDTH); // Sets the default font for lines with no font specified void setFont(const LLFontGL* font); diff --git a/indra/newview/llimprocessing.cpp b/indra/newview/llimprocessing.cpp index e6845127e3..3536b83989 100644 --- a/indra/newview/llimprocessing.cpp +++ b/indra/newview/llimprocessing.cpp @@ -453,7 +453,7 @@ void LLIMProcessing::processNewMessage(LLUUID from_id, BOOL is_friend = (LLAvatarTracker::instance().getBuddyInfo(from_id) == NULL) ? false : true; BOOL accept_im_from_only_friend = gSavedPerAccountSettings.getBOOL("VoiceCallsFriendsOnly"); BOOL is_linden = chat.mSourceType != CHAT_SOURCE_OBJECT && - LLMuteList::getInstance()->isLinden(name); + LLMuteList::isLinden(name); chat.mMuted = is_muted; chat.mFromID = from_id; @@ -521,7 +521,9 @@ void LLIMProcessing::processNewMessage(LLUUID from_id, dialog, parent_estate_id, region_id, - position); + position, + false, // is_region_msg + timestamp); if (!gIMMgr->isDNDMessageSend(session_id)) { @@ -592,7 +594,8 @@ void LLIMProcessing::processNewMessage(LLUUID from_id, parent_estate_id, region_id, position, - region_message); + region_message, + timestamp); } else { @@ -1111,7 +1114,9 @@ void LLIMProcessing::processNewMessage(LLUUID from_id, IM_SESSION_INVITE, parent_estate_id, region_id, - position); + position, + false, // is_region_msg + timestamp); } else { @@ -1131,12 +1136,14 @@ void LLIMProcessing::processNewMessage(LLUUID from_id, from_id, name, buffer, - IM_OFFLINE == offline, - ll_safe_string((char*)binary_bucket), + (IM_OFFLINE == offline), + ll_safe_string((char*)binary_bucket), // session name IM_SESSION_INVITE, parent_estate_id, region_id, - position); + position, + false, // is_region_msg + timestamp); } break; @@ -1568,7 +1575,7 @@ void LLIMProcessing::requestOfflineMessagesCoro(std::string url) return; } - if (messages.emptyArray()) + if (messages.size() == 0) { // Nothing to process return; diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp index bf9e226244..6880cf2171 100644 --- a/indra/newview/llimview.cpp +++ b/indra/newview/llimview.cpp @@ -1,25 +1,25 @@ -/** +/** * @file LLIMMgr.cpp * @brief Container for Instant Messaging * * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -41,6 +41,7 @@ #include "llstring.h" #include "lltextutil.h" #include "lltrans.h" +#include "lltranslate.h" #include "lluictrlfactory.h" #include "llfloaterimsessiontab.h" #include "llagent.h" @@ -76,11 +77,17 @@ const static std::string ADHOC_NAME_SUFFIX(" Conference"); const static std::string NEARBY_P2P_BY_OTHER("nearby_P2P_by_other"); const static std::string NEARBY_P2P_BY_AGENT("nearby_P2P_by_agent"); +// Markers inserted around translated part of chat text +const static std::string XL8_START_TAG(" ("); +const static std::string XL8_END_TAG(")"); +const S32 XL8_PADDING = 3; // XL8_START_TAG.size() + XL8_END_TAG.size() + /** Timeout of outgoing session initialization (in seconds) */ const static U32 SESSION_INITIALIZATION_TIMEOUT = 30; void startConfrenceCoro(std::string url, LLUUID tempSessionId, LLUUID creatorId, LLUUID otherParticipantId, LLSD agents); void chatterBoxInvitationCoro(std::string url, LLUUID sessionId, LLIMMgr::EInvitationType invitationType); +void chatterBoxHistoryCoro(std::string url, LLUUID sessionId, std::string from, std::string message, U32 timestamp); void start_deprecated_conference_chat(const LLUUID& temp_session_id, const LLUUID& creator_id, const LLUUID& other_participant_id, const LLSD& agents_to_invite); const LLUUID LLOutgoingCallDialog::OCD_KEY = LLUUID("7CF78E11-0CFE-498D-ADB9-1417BF03DDB4"); @@ -111,7 +118,7 @@ void process_dnd_im(const LLSD& notification) LLUUID sessionID = data["SESSION_ID"].asUUID(); LLUUID fromID = data["FROM_ID"].asUUID(); - //re-create the IM session if needed + //re-create the IM session if needed //(when coming out of DND mode upon app restart) if(!gIMMgr->hasSession(sessionID)) { @@ -122,13 +129,13 @@ void process_dnd_im(const LLSD& notification) { name = av_name.getDisplayName(); } - - - LLIMModel::getInstance()->newSession(sessionID, - name, - IM_NOTHING_SPECIAL, - fromID, - false, + + + LLIMModel::getInstance()->newSession(sessionID, + name, + IM_NOTHING_SPECIAL, + fromID, + false, false); //will need slight refactor to retrieve whether offline message or not (assume online for now) } @@ -311,8 +318,8 @@ void notify_of_message(const LLSD& msg, bool is_dnd_msg) } else { - if (is_dnd_msg && (ON_TOP == conversations_floater_status || - NOT_ON_TOP == conversations_floater_status || + if (is_dnd_msg && (ON_TOP == conversations_floater_status || + NOT_ON_TOP == conversations_floater_status || CLOSED == conversations_floater_status)) { im_box->highlightConversationItemWidget(session_id, true); @@ -371,7 +378,7 @@ void notify_of_message(const LLSD& msg, bool is_dnd_msg) } if (store_dnd_message) { - // If in DND mode, allow notification to be stored so upon DND exit + // If in DND mode, allow notification to be stored so upon DND exit // the user will be notified with some limitations (see 'is_dnd_msg' flag checks) if(session_id.notNull() && participant_id.notNull() @@ -392,7 +399,7 @@ void startConfrenceCoro(std::string url, { LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID); LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t - httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("TwitterConnect", httpPolicy)); + httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("ConferenceChatStart", httpPolicy)); LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest); LLSD postData; @@ -432,7 +439,7 @@ void chatterBoxInvitationCoro(std::string url, LLUUID sessionId, LLIMMgr::EInvit { LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID); LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t - httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("TwitterConnect", httpPolicy)); + httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("ConferenceInviteStart", httpPolicy)); LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest); LLSD postData; @@ -510,8 +517,124 @@ void chatterBoxInvitationCoro(std::string url, LLUUID sessionId, LLIMMgr::EInvit } +void translateSuccess(const LLUUID& session_id, const std::string& from, const LLUUID& from_id, const std::string& utf8_text, + U64 time_n_flags, std::string originalMsg, std::string expectLang, std::string translation, const std::string detected_language) +{ + std::string message_txt(utf8_text); + // filter out non-interesting responses + if (!translation.empty() + && ((detected_language.empty()) || (expectLang != detected_language)) + && (LLStringUtil::compareInsensitive(translation, originalMsg) != 0)) + { // Note - if this format changes, also fix code in addMessagesFromServerHistory() + message_txt += XL8_START_TAG + LLTranslate::removeNoTranslateTags(translation) + XL8_END_TAG; + } -LLIMModel::LLIMModel() + // Extract info packed in time_n_flags + bool log2file = (bool)(time_n_flags & (1LL << 32)); + bool is_region_msg = (bool)(time_n_flags & (1LL << 33)); + U32 time_stamp = (U32)(time_n_flags & 0x00000000ffffffff); + + LLIMModel::getInstance()->processAddingMessage(session_id, from, from_id, message_txt, log2file, is_region_msg, time_stamp); +} + +void translateFailure(const LLUUID& session_id, const std::string& from, const LLUUID& from_id, const std::string& utf8_text, + U64 time_n_flags, int status, const std::string err_msg) +{ + std::string message_txt(utf8_text); + std::string msg = LLTrans::getString("TranslationFailed", LLSD().with("[REASON]", err_msg)); + LLStringUtil::replaceString(msg, "\n", " "); // we want one-line error messages + message_txt += XL8_START_TAG + msg + XL8_END_TAG; + + // Extract info packed in time_n_flags + bool log2file = (bool)(time_n_flags & (1LL << 32)); + bool is_region_msg = (bool)(time_n_flags & (1LL << 33)); + U32 time_stamp = (U32)(time_n_flags & 0x00000000ffffffff); + + LLIMModel::getInstance()->processAddingMessage(session_id, from, from_id, message_txt, log2file, is_region_msg, time_stamp); +} + +void chatterBoxHistoryCoro(std::string url, LLUUID sessionId, std::string from, std::string message, U32 timestamp) +{ // if parameters from, message and timestamp have values, they are a message that opened chat + LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID); + LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t + httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("ChatHistory", httpPolicy)); + LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest); + + LLSD postData; + postData["method"] = "fetch history"; + postData["session-id"] = sessionId; + + LL_DEBUGS("ChatHistory") << sessionId << ": Chat history posting " << postData << " to " << url + << ", from " << from << ", message " << message << ", timestamp " << (S32)timestamp << LL_ENDL; + + LLSD result = httpAdapter->postAndSuspend(httpRequest, url, postData); + + LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS]; + LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults); + + if (!status) + { + LL_WARNS("ChatHistory") << sessionId << ": Bad HTTP response in chatterBoxHistoryCoro" + << ", results: " << httpResults << LL_ENDL; + return; + } + + // Add history to IM session + LLSD history = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS_CONTENT]; + + LL_DEBUGS("ChatHistory") << sessionId << ": Chat server history fetch returned " << history << LL_ENDL; + + try + { + LLIMModel::LLIMSession* session = LLIMModel::getInstance()->findIMSession(sessionId); + if (session && history.isArray()) + { // Result array is sorted oldest to newest + if (history.size() > 0) + { // History from the chat server has an integer 'time' value timestamp. Create 'datetime' string which will match + // what we have from the local history cache + for (LLSD::array_iterator cur_server_hist = history.beginArray(), endLists = history.endArray(); + cur_server_hist != endLists; + cur_server_hist++) + { + if ((*cur_server_hist).isMap()) + { // Take the 'time' value from the server and make the date-time string that will be in local cache log files + // {'from_id':u7aa8c222-8a81-450e-b3d1-9c28491ef717,'message':'Can you hear me now?','from':'Chat Tester','num':i86,'time':r1.66501e+09} + U32 timestamp = (U32)((*cur_server_hist)[LL_IM_TIME].asInteger()); + (*cur_server_hist)[LL_IM_DATE_TIME] = LLLogChat::timestamp2LogString(timestamp, true); + } + } + + session->addMessagesFromServerHistory(history, from, message, timestamp); + + // Display the newly added messages + LLFloaterIMSession* floater = LLFloaterReg::findTypedInstance<LLFloaterIMSession>("impanel", sessionId); + if (floater && floater->isInVisibleChain()) + { + floater->updateMessages(); + } + } + else + { + LL_DEBUGS("ChatHistory") << sessionId << ": Empty history from chat server, nothing to add" << LL_ENDL; + } + } + else if (session && !history.isArray()) + { + LL_WARNS("ChatHistory") << sessionId << ": Bad array data fetching chat history" << LL_ENDL; + } + else + { + LL_WARNS("ChatHistory") << sessionId << ": Unable to find session fetching chat history" << LL_ENDL; + } + } + catch (...) + { + LOG_UNHANDLED_EXCEPTION("chatterBoxHistoryCoro"); + LL_WARNS("ChatHistory") << "chatterBoxHistoryCoro unhandled exception while processing data for session " << sessionId << LL_ENDL; + } +} + +LLIMModel::LLIMModel() { addNewMsgCallback(boost::bind(&LLFloaterIMSession::newIMCallback, _1)); addNewMsgCallback(boost::bind(&on_new_message, _1)); @@ -556,25 +679,25 @@ LLIMModel::LLIMSession::LLIMSession(const LLUUID& session_id, const std::string& else { mSessionType = ADHOC_SESSION; - } + } } if(mVoiceChannel) { mVoiceChannelStateChangeConnection = mVoiceChannel->setStateChangedCallback(boost::bind(&LLIMSession::onVoiceChannelStateChanged, this, _1, _2, _3)); } - + mSpeakers = new LLIMSpeakerMgr(mVoiceChannel); // All participants will be added to the list of people we've recently interacted with. - // we need to add only _active_ speakers...so comment this. + // we need to add only _active_ speakers...so comment this. // may delete this later on cleanup //mSpeakers->addListener(&LLRecentPeople::instance(), "add"); //we need to wait for session initialization for outgoing ad-hoc and group chat session //correct session id for initiated ad-hoc chat will be received from the server - if (!LLIMModel::getInstance()->sendStartSession(mSessionID, mOtherParticipantID, + if (!LLIMModel::getInstance()->sendStartSession(mSessionID, mOtherParticipantID, mInitialTargetIDs, mType)) { //we don't need to wait for any responses @@ -656,7 +779,7 @@ void LLIMModel::LLIMSession::onVoiceChannelStateChanged(const LLVoiceChannel::ES LLStringUtil::format_map_t string_args; string_args["[NAME]"] = other_avatar_name; message = LLTrans::getString("name_started_call", string_args); - LLIMModel::getInstance()->addMessage(mSessionID, SYSTEM_FROM, LLUUID::null, message); + LLIMModel::getInstance()->addMessage(mSessionID, SYSTEM_FROM, LLUUID::null, message); break; } case LLVoiceChannel::STATE_CONNECTED : @@ -760,14 +883,21 @@ void LLIMModel::LLIMSession::sessionInitReplyReceived(const LLUUID& new_session_ } } -void LLIMModel::LLIMSession::addMessage(const std::string& from, const LLUUID& from_id, const std::string& utf8_text, const std::string& time, const bool is_history, bool is_region_msg) +void LLIMModel::LLIMSession::addMessage(const std::string& from, + const LLUUID& from_id, + const std::string& utf8_text, + const std::string& time, + const bool is_history, // comes from a history file or chat server + const bool is_region_msg, + const U32 timestamp) // may be zero { LLSD message; message["from"] = from; message["from_id"] = from_id; message["message"] = utf8_text; - message["time"] = time; - message["index"] = (LLSD::Integer)mMsgs.size(); + message["time"] = time; // string used in display, may be full data YYYY/MM/DD HH:MM or just HH:MM + message["timestamp"] = (S32)timestamp; // use string? LLLogChat::timestamp2LogString(timestamp, true); + message["index"] = (LLSD::Integer)mMsgs.size(); message["is_history"] = is_history; message["is_region_msg"] = is_region_msg; @@ -788,7 +918,7 @@ void LLIMModel::LLIMSession::addMessage(const std::string& from, const LLUUID& f } } - mMsgs.push_front(message); + mMsgs.push_front(message); // Add most recent messages to the front of mMsgs if (mSpeakers && from_id.notNull()) { @@ -797,35 +927,281 @@ void LLIMModel::LLIMSession::addMessage(const std::string& from, const LLUUID& f } } -void LLIMModel::LLIMSession::addMessagesFromHistory(const std::list<LLSD>& history) +void LLIMModel::LLIMSession::addMessagesFromHistoryCache(const chat_message_list_t& history) { - std::list<LLSD>::const_iterator it = history.begin(); - while (it != history.end()) - { - const LLSD& msg = *it; + // Add the messages from the local cached chat history to the session window + for (const auto& msg : history) + { + std::string from = msg[LL_IM_FROM]; + LLUUID from_id; + if (msg[LL_IM_FROM_ID].isDefined()) + { + from_id = msg[LL_IM_FROM_ID].asUUID(); + } + else + { // convert it to a legacy name if we have a complete name + std::string legacy_name = gCacheName->buildLegacyName(from); + from_id = LLAvatarNameCache::getInstance()->findIdByName(legacy_name); + } - std::string from = msg[LL_IM_FROM]; - LLUUID from_id; - if (msg[LL_IM_FROM_ID].isDefined()) - { - from_id = msg[LL_IM_FROM_ID].asUUID(); - } - else - { - // convert it to a legacy name if we have a complete name - std::string legacy_name = gCacheName->buildLegacyName(from); - from_id = LLAvatarNameCache::getInstance()->findIdByName(legacy_name); - } + // Save the last minute of messages so we can merge with the chat server history. + // Really would be nice to have a numeric timestamp in the local cached chat file + const std::string & msg_time_str = msg[LL_IM_DATE_TIME].asString(); + if (mLastHistoryCacheDateTime != msg_time_str) + { + mLastHistoryCacheDateTime = msg_time_str; // Reset to the new time + mLastHistoryCacheMsgs.clear(); + } + mLastHistoryCacheMsgs.push_front(msg); + LL_DEBUGS("ChatHistory") << mSessionID << ": Adding history cache message: " << msg << LL_ENDL; - std::string timestamp = msg[LL_IM_TIME]; - std::string text = msg[LL_IM_TEXT]; + // Add message from history cache to the display + addMessage(from, from_id, msg[LL_IM_TEXT], msg[LL_IM_TIME], true, false, 0); // from history data, not region message, no timestamp + } +} - addMessage(from, from_id, text, timestamp, true); +void LLIMModel::LLIMSession::addMessagesFromServerHistory(const LLSD& history, // Array of chat messages from chat server + const std::string& target_from, // Sender of message that opened chat + const std::string& target_message, // Message text that opened chat + U32 timestamp) // timestamp of message that opened chat +{ // Add messages from history returned by the chat server. + + // The session mMsgs may contain chat messages from the local history cache file, and possibly one or more newly + // arrived chat messages. If the chat window was manually opened, these will be empty and history can + // more easily merged. The history from the server, however, may overlap what is in the file and those must also be merged. + + // At this point, the session mMsgs can have + // no messages + // nothing from history file cache, but one or more very recently arrived messages, + // messages from history file cache, no recent chat + // messages from history file cache, one or more very recent messages + // + // The chat history from server can possibly contain: + // no messages + // messages that start back before anything in the local file (obscure case, but possible) + // messages that match messages from the history file cache + // messages from the last hour, new to the viewer + // one or more messages that match most recently received chat (the one that opened the window) + // In other words: + // messages from chat server may or may not match what we already have in mMsgs + // We can drop anything that is during the time span covered by the local cache file + // To keep things simple, drop any chat data older than the local cache file + + if (!history.isArray()) + { + LL_WARNS("ChatHistory") << mSessionID << ": Unexpected history data not array, type " << (S32)history.type() << LL_ENDL; + return; + } - it++; - } + if (history.size() == 0) + { // If history is empty + LL_DEBUGS("ChatHistory") << mSessionID << ": addMessagesFromServerHistory() has empty history, nothing to merge" << LL_ENDL; + return; + } + + if (history.size() == 1 && // Server chat history has one entry, + target_from.length() > 0 && // and we have a chat message that just arrived + mMsgs.size() > 0) // and we have some data in the window - assume the history message is there. + { // This is the common case where a group chat is silent for a while, and then one message is sent. + LL_DEBUGS("ChatHistory") << mSessionID << ": addMessagesFromServerHistory() only has chat message just received." << LL_ENDL; + return; + } + + LL_DEBUGS("ChatHistory") << mSessionID << ": addMessagesFromServerHistory() starting with mMsg.size() " << mMsgs.size() + << " adding history with " << history.size() << " messages" + << ", target_from: " << target_from + << ", target_message: " << target_message + << ", timestamp: " << (S32)timestamp << LL_ENDL; + + // At start of merging, mMsgs is either empty, has some chat messages read from a local cache file, and may have + // one or more messages that just arrived from the server. + U32 match_timestamp = 0; + chat_message_list_t shift_msgs; + if (mMsgs.size() > 0 && + target_from.length() > 0 + && target_message.length() > 0) + { // Find where to insert the history messages by popping off a few in the session. + // The most common case is one duplciate message, the one that opens a chat session + while (mMsgs.size() > 0) + { + // The "time" value from mMsgs is a string, either just time HH:MM or a full date and time + LLSD cur_msg = mMsgs.front(); // Get most recent message from the chat display (front of mMsgs list) + + if (cur_msg.isMap()) + { + LL_DEBUGS("ChatHistoryCompare") << mSessionID << ": Finding insertion point, looking at cur_msg: " << cur_msg << LL_ENDL; + + match_timestamp = cur_msg["timestamp"].asInteger(); // get timestamp of message in the session, may be zero + if ((S32)timestamp > match_timestamp) + { + LL_DEBUGS("ChatHistory") << mSessionID << ": found older chat message: " << cur_msg + << ", timestamp " << (S32)timestamp + << " vs. match_timestamp " << match_timestamp + << ", shift_msgs size is " << shift_msgs.size() << LL_ENDL; + break; + } + // Have the matching message or one more recent: these need to be at the end + shift_msgs.push_front(cur_msg); // Move chat message to temp list. + mMsgs.pop_front(); // Normally this is just one message + LL_DEBUGS("ChatHistory") << mSessionID << ": shifting chat message " << cur_msg + << " to be inserted at end, shift_msgs size is " << shift_msgs.size() + << ", match_timestamp " << match_timestamp + << ", timestamp " << (S32)timestamp << LL_ENDL; + } + else + { + LL_DEBUGS("ChatHistory") << mSessionID << ": Unexpected non-map entry in session messages: " << cur_msg << LL_ENDL; + return; + } + } + } + + // Now merge messages from server history data into the session display. The history data + // from the local file may overlap with the chat messages from the server. + // Drop any messages from the chat server history that are before the latest one from the local history file. + // Unfortunately, messages from the local file don't have timestamps - just datetime strings + LLSD::array_const_iterator cur_history_iter = history.beginArray(); + while (cur_history_iter != history.endArray()) + { + const LLSD &cur_server_hist = *cur_history_iter; + cur_history_iter++; + + if (cur_server_hist.isMap()) + { // Each server history entry looks like + // { 'from':'Laggy Avatar', 'from_id' : u72345678 - 744f - 43b9 - 98af - b06f1c76ddda, 'index' : i24, 'is_history' : 1, 'message' : 'That was slow', 'time' : '02/13/2023 10:03', 'timestamp' : i1676311419 } + + // If we reach the message that opened our window, stop adding messages + U32 history_msg_timestamp = (U32)cur_server_hist[LL_IM_TIME].asInteger(); + if ((match_timestamp > 0 && match_timestamp <= history_msg_timestamp) || + (timestamp > 0 && timestamp <= history_msg_timestamp)) + { // we found the message we matched, so stop inserting from chat server history + LL_DEBUGS("ChatHistoryCompare") << "Found end of chat history insertion with match_timestamp " << (S32)match_timestamp + << " vs. history_msg_timestamp " << (S32)history_msg_timestamp + << " vs. timestamp " << (S32)timestamp + << LL_ENDL; + break; + } + LL_DEBUGS("ChatHistoryCompare") << "Compared match_timestamp " << (S32)match_timestamp + << " vs. history_msg_timestamp " << (S32)history_msg_timestamp << LL_ENDL; + + bool add_chat_to_conversation = true; + if (!mLastHistoryCacheDateTime.empty()) + { // Skip past the any from server that are older than what we already read from the history file. + std::string history_datetime = cur_server_hist[LL_IM_DATE_TIME].asString(); + if (history_datetime.empty()) + { + history_datetime = cur_server_hist[LL_IM_TIME].asString(); + } + + if (history_datetime < mLastHistoryCacheDateTime) + { + LL_DEBUGS("ChatHistoryCompare") << "Skipping message from chat server history since it's older than messages the session already has." + << history_datetime << " vs " << mLastHistoryCacheDateTime << LL_ENDL; + add_chat_to_conversation = false; + } + else if (history_datetime > mLastHistoryCacheDateTime) + { // The message from the chat server is more recent than the last one from the local cache file. Add it + LL_DEBUGS("ChatHistoryCompare") << "Found message dated " + << history_datetime << " vs " << mLastHistoryCacheDateTime + << ", adding new message from chat server history " << cur_server_hist << LL_ENDL; + } + else // (history_datetime == mLastHistoryCacheDateTime) + { // Messages are in the same minute as the last from the cache log file. + const std::string & history_msg_text = cur_server_hist[LL_IM_TEXT]; + + // Look in the saved messages from the history file that have the same time + for (const auto& scan_msg : mLastHistoryCacheMsgs) + { + LL_DEBUGS("ChatHistoryCompare") << "comparing messages " << scan_msg[LL_IM_TEXT] + << " with " << cur_server_hist << LL_ENDL; + if (scan_msg.size() > 0) + { // Extra work ... the history_msg_text value may have been translated, i.e. "I am confused (je suis confus)" + // while the server history will only have the first part "I am confused" + std::string target_compare(scan_msg[LL_IM_TEXT]); + if (target_compare.size() > history_msg_text.size() + XL8_PADDING && + target_compare.substr(history_msg_text.size(), XL8_START_TAG.size()) == XL8_START_TAG && + target_compare.substr(target_compare.size() - XL8_END_TAG.size()) == XL8_END_TAG) + { // This really looks like a "translated string (cadena traducida)" so just compare the source part + LL_DEBUGS("ChatHistory") << mSessionID << ": Found translated chat " << target_compare + << " when comparing to history " << history_msg_text + << ", will truncate" << LL_ENDL; + target_compare = target_compare.substr(0, history_msg_text.size()); + } + if (history_msg_text == target_compare) + { // Found a match, so don't add a duplicate chat message to the window + LL_DEBUGS("ChatHistory") << mSessionID << ": Found duplicate message text " << history_msg_text + << " : " << (S32)history_msg_timestamp << ", matching datetime " << history_datetime << LL_ENDL; + add_chat_to_conversation = false; + break; + } + } + } + } + } + + LLUUID sender_id = cur_server_hist[LL_IM_FROM_ID].asUUID(); + if (add_chat_to_conversation) + { // Check if they're muted + if (LLMuteList::getInstance()->isMuted(sender_id, LLMute::flagTextChat)) + { + add_chat_to_conversation = false; + LL_DEBUGS("ChatHistory") << mSessionID << ": Skipped adding chat from " << sender_id + << " as muted, message: " << cur_server_hist + << LL_ENDL; + } + } + + if (add_chat_to_conversation) + { // Finally add message to the chat session + std::string chat_time_str = LLConversation::createTimestamp((U64Seconds)history_msg_timestamp); + std::string sender_name = cur_server_hist[LL_IM_FROM].asString(); + + std::string history_msg_text = cur_server_hist[LL_IM_TEXT].asString(); + LLSD message; + message["from"] = sender_name; + message["from_id"] = sender_id; + message["message"] = history_msg_text; + message["time"] = chat_time_str; + message["timestamp"] = (S32)history_msg_timestamp; + message["index"] = (LLSD::Integer)mMsgs.size(); + message["is_history"] = true; + mMsgs.push_front(message); + + LL_DEBUGS("ChatHistory") << mSessionID << ": push_front() adding group chat history message " << message << LL_ENDL; + + // Add chat history messages to the local cache file, only in the case where we opened the chat window + // Need to solve the logic around messages that arrive and open chat - at this point, they've already been added to the + // local history cache file. If we append messages here, it will be out of order. + if (target_from.empty() && target_message.empty()) + { + LLIMModel::getInstance()->logToFile(LLIMModel::getInstance()->getHistoryFileName(mSessionID), + sender_name, sender_id, history_msg_text); + } + } + } + } + + S32 shifted_size = shift_msgs.size(); + while (shift_msgs.size() > 0) + { // Finally add back any new messages, and tweak the index value to be correct. + LLSD newer_message = shift_msgs.front(); + shift_msgs.pop_front(); + S32 old_index = newer_message["index"]; + newer_message["index"] = (LLSD::Integer)mMsgs.size(); // Update the index to match the new position in the conversation + LL_DEBUGS("ChatHistory") << mSessionID << ": Re-adding newest group chat history messages from " << newer_message["from"] + << ", text: " << newer_message["message"] + << " old index " << old_index << ", new index " << newer_message["index"] << LL_ENDL; + mMsgs.push_front(newer_message); + } + + LL_DEBUGS("ChatHistory") << mSessionID << ": addMessagesFromServerHistory() exiting with mMsg.size() " << mMsgs.size() + << ", shifted " << shifted_size << " messages" << LL_ENDL; + + mLastHistoryCacheDateTime.clear(); // Don't need this data + mLastHistoryCacheMsgs.clear(); } + void LLIMModel::LLIMSession::chatFromLogFile(LLLogChat::ELogLineType type, const LLSD& msg, void* userdata) { if (!userdata) return; @@ -834,26 +1210,29 @@ void LLIMModel::LLIMSession::chatFromLogFile(LLLogChat::ELogLineType type, const if (type == LLLogChat::LOG_LINE) { - self->addMessage("", LLSD(), msg["message"].asString(), "", true); + LL_DEBUGS("ChatHistory") << "chatFromLogFile() adding LOG_LINE message from " << msg << LL_ENDL; + self->addMessage("", LLSD(), msg["message"].asString(), "", true, false, 0); // from history data, not region message, no timestamp } else if (type == LLLogChat::LOG_LLSD) { - self->addMessage(msg["from"].asString(), msg["from_id"].asUUID(), msg["message"].asString(), msg["time"].asString(), true); + LL_DEBUGS("ChatHistory") << "chatFromLogFile() adding LOG_LLSD message from " << msg << LL_ENDL; + self->addMessage(msg["from"].asString(), msg["from_id"].asUUID(), msg["message"].asString(), msg["time"].asString(), true, false, 0); // from history data, not region message, no timestamp } } void LLIMModel::LLIMSession::loadHistory() { mMsgs.clear(); + mLastHistoryCacheMsgs.clear(); + mLastHistoryCacheDateTime.clear(); if ( gSavedPerAccountSettings.getBOOL("LogShowHistory") ) { - std::list<LLSD> chat_history; - - //involves parsing of a chat history + // read and parse chat history from local file + chat_message_list_t chat_history; LLLogChat::loadChatHistory(mHistoryFileName, chat_history, LLSD(), isGroupChat()); - addMessagesFromHistory(chat_history); - } + addMessagesFromHistoryCache(chat_history); + } } LLIMModel::LLIMSession* LLIMModel::findIMSession(const LLUUID& session_id) const @@ -873,7 +1252,7 @@ LLIMModel::LLIMSession* LLIMModel::findAdHocIMSession(const uuid_vec_t& ids) for (; it != mId2SessionMap.end(); ++it) { LLIMSession* session = (*it).second; - + if (!session->isAdHoc()) continue; if (session->mInitialTargetIDs.size() != num) continue; @@ -884,8 +1263,8 @@ LLIMModel::LLIMSession* LLIMModel::findAdHocIMSession(const uuid_vec_t& ids) { tmp_list.remove(*iter); ++iter; - - if (tmp_list.empty()) + + if (tmp_list.empty()) { break; } @@ -941,7 +1320,7 @@ void LLIMModel::LLIMSession::buildHistoryFileName() if (isAdHoc()) { /* in case of outgoing ad-hoc sessions we need to make specilized names - * if this naming system is ever changed then the filtering definitions in + * if this naming system is ever changed then the filtering definitions in * lllogchat.cpp need to be change acordingly so that the filtering for the * date stamp code introduced in STORM-102 will work properly and not add * a date stamp to the Ad-hoc conferences. @@ -954,7 +1333,7 @@ void LLIMModel::LLIMSession::buildHistoryFileName() else { //in case of incoming ad-hoc sessions - mHistoryFileName = mName + " " + LLLogChat::timestamp(true) + " " + mSessionID.asString().substr(0, 4); + mHistoryFileName = mName + " " + LLLogChat::timestamp2LogString(0, true) + " " + mSessionID.asString().substr(0, 4); } } else if (isP2P()) // look up username to use as the log name @@ -985,7 +1364,7 @@ void LLIMModel::LLIMSession::buildHistoryFileName() LLUUID LLIMModel::LLIMSession::generateHash(const std::set<LLUUID>& sorted_uuids) { LLMD5 md5_uuid; - + std::set<LLUUID>::const_iterator it = sorted_uuids.begin(); while (it != sorted_uuids.end()) { @@ -1047,7 +1426,7 @@ void LLIMModel::testMessages() S32 rand1 = ll_rand(sizeof firstname)/(sizeof firstname[0]); S32 rand2 = ll_rand(sizeof lastname)/(sizeof lastname[0]); - + from = firstname[rand1] + " " + lastname[rand2]; bot2_id.generate(from); LLUUID bot2_session_id = LLIMMgr::computeSessionID(IM_NOTHING_SPECIAL, bot2_id); @@ -1057,7 +1436,7 @@ void LLIMModel::testMessages() } //session name should not be empty -bool LLIMModel::newSession(const LLUUID& session_id, const std::string& name, const EInstantMessage& type, +bool LLIMModel::newSession(const LLUUID& session_id, const std::string& name, const EInstantMessage& type, const LLUUID& other_participant_id, const uuid_vec_t& ids, bool voice, bool has_offline_msg) { if (name.empty()) @@ -1099,7 +1478,7 @@ bool LLIMModel::clearSession(const LLUUID& session_id) return true; } -void LLIMModel::getMessages(const LLUUID& session_id, std::list<LLSD>& messages, int start_index, const bool sendNoUnreadMsgs) +void LLIMModel::getMessages(const LLUUID& session_id, chat_message_list_t& messages, int start_index, const bool sendNoUnreadMsgs) { getMessagesSilently(session_id, messages, start_index); @@ -1109,7 +1488,7 @@ void LLIMModel::getMessages(const LLUUID& session_id, std::list<LLSD>& messages, } } -void LLIMModel::getMessagesSilently(const LLUUID& session_id, std::list<LLSD>& messages, int start_index) +void LLIMModel::getMessagesSilently(const LLUUID& session_id, chat_message_list_t& messages, int start_index) { LLIMSession* session = findIMSession(session_id); if (!session) @@ -1120,7 +1499,7 @@ void LLIMModel::getMessagesSilently(const LLUUID& session_id, std::list<LLSD>& m int i = session->mMsgs.size() - start_index; - for (std::list<LLSD>::iterator iter = session->mMsgs.begin(); + for (chat_message_list_t::iterator iter = session->mMsgs.begin(); iter != session->mMsgs.end() && i > 0; iter++) { @@ -1142,7 +1521,7 @@ void LLIMModel::sendNoUnreadMessages(const LLUUID& session_id) session->mNumUnread = 0; session->mParticipantUnreadMessageCount = 0; - + LLSD arg; arg["session_id"] = session_id; arg["num_unread"] = 0; @@ -1150,17 +1529,23 @@ void LLIMModel::sendNoUnreadMessages(const LLUUID& session_id) mNoUnreadMsgsSignal(arg); } -bool LLIMModel::addToHistory(const LLUUID& session_id, const std::string& from, const LLUUID& from_id, const std::string& utf8_text, bool is_region_msg) { - +bool LLIMModel::addToHistory(const LLUUID& session_id, + const std::string& from, + const LLUUID& from_id, + const std::string& utf8_text, + bool is_region_msg, + U32 timestamp) +{ LLIMSession* session = findIMSession(session_id); - if (!session) + if (!session) { LL_WARNS() << "session " << session_id << "does not exist " << LL_ENDL; return false; } - session->addMessage(from, from_id, utf8_text, LLLogChat::timestamp(false), false, is_region_msg); //might want to add date separately + // This is where a normal arriving message is added to the session. Note that the time string created here is without the full date + session->addMessage(from, from_id, utf8_text, LLLogChat::timestamp2LogString(timestamp, false), false, is_region_msg, timestamp); return true; } @@ -1168,14 +1553,14 @@ bool LLIMModel::addToHistory(const LLUUID& session_id, const std::string& from, bool LLIMModel::logToFile(const std::string& file_name, const std::string& from, const LLUUID& from_id, const std::string& utf8_text) { if (gSavedPerAccountSettings.getS32("KeepConversationLogTranscripts") > 1) - { + { std::string from_name = from; LLAvatarName av_name; - if (!from_id.isNull() && + if (!from_id.isNull() && LLAvatarNameCache::get(from_id, &av_name) && !av_name.isDisplayNameDefault()) - { + { from_name = av_name.getCompleteName(); } @@ -1189,43 +1574,63 @@ bool LLIMModel::logToFile(const std::string& file_name, const std::string& from, } } -bool LLIMModel::proccessOnlineOfflineNotification( - const LLUUID& session_id, - const std::string& utf8_text) +void LLIMModel::proccessOnlineOfflineNotification( + const LLUUID& session_id, + const std::string& utf8_text) { // Add system message to history - return addMessage(session_id, SYSTEM_FROM, LLUUID::null, utf8_text); + addMessage(session_id, SYSTEM_FROM, LLUUID::null, utf8_text); } -bool LLIMModel::addMessage(const LLUUID& session_id, const std::string& from, const LLUUID& from_id, - const std::string& utf8_text, bool log2file, bool is_region_msg) { +void LLIMModel::addMessage(const LLUUID& session_id, const std::string& from, const LLUUID& from_id, + const std::string& utf8_text, bool log2file /* = true */, bool is_region_msg, /* = false */ U32 time_stamp /* = 0 */) +{ + if (gSavedSettings.getBOOL("TranslateChat") && (from != SYSTEM_FROM)) + { + const std::string from_lang = ""; // leave empty to trigger autodetect + const std::string to_lang = LLTranslate::getTranslateLanguage(); + U64 time_n_flags = ((U64) time_stamp) | (log2file ? (1LL << 32) : 0) | (is_region_msg ? (1LL << 33) : 0); // boost::bind has limited parameters + LLTranslate::translateMessage(from_lang, to_lang, utf8_text, + boost::bind(&translateSuccess, session_id, from, from_id, utf8_text, time_n_flags, utf8_text, from_lang, _1, _2), + boost::bind(&translateFailure, session_id, from, from_id, utf8_text, time_n_flags, _1, _2)); + } + else + { + processAddingMessage(session_id, from, from_id, utf8_text, log2file, is_region_msg, time_stamp); + } +} - LLIMSession* session = addMessageSilently(session_id, from, from_id, utf8_text, log2file, is_region_msg); - if (!session) return false; +void LLIMModel::processAddingMessage(const LLUUID& session_id, const std::string& from, const LLUUID& from_id, + const std::string& utf8_text, bool log2file, bool is_region_msg, U32 time_stamp) +{ + LLIMSession* session = addMessageSilently(session_id, from, from_id, utf8_text, log2file, is_region_msg, time_stamp); + if (!session) + return; - //good place to add some1 to recent list - //other places may be called from message history. - if( !from_id.isNull() && - ( session->isP2PSessionType() || session->isAdHocSessionType() ) ) - LLRecentPeople::instance().add(from_id); + //good place to add some1 to recent list + //other places may be called from message history. + if( !from_id.isNull() && + ( session->isP2PSessionType() || session->isAdHocSessionType() ) ) + LLRecentPeople::instance().add(from_id); - // notify listeners - LLSD arg; - arg["session_id"] = session_id; - arg["num_unread"] = session->mNumUnread; - arg["participant_unread"] = session->mParticipantUnreadMessageCount; - arg["message"] = utf8_text; - arg["from"] = from; - arg["from_id"] = from_id; - arg["time"] = LLLogChat::timestamp(false); - arg["session_type"] = session->mSessionType; - mNewMsgSignal(arg); + // notify listeners + LLSD arg; + arg["session_id"] = session_id; + arg["num_unread"] = session->mNumUnread; + arg["participant_unread"] = session->mParticipantUnreadMessageCount; + arg["message"] = utf8_text; + arg["from"] = from; + arg["from_id"] = from_id; + arg["time"] = LLLogChat::timestamp2LogString(time_stamp, true); + arg["session_type"] = session->mSessionType; + arg["is_region_msg"] = is_region_msg; - return true; + mNewMsgSignal(arg); } -LLIMModel::LLIMSession* LLIMModel::addMessageSilently(const LLUUID& session_id, const std::string& from, const LLUUID& from_id, - const std::string& utf8_text, bool log2file, bool is_region_msg) +LLIMModel::LLIMSession* LLIMModel::addMessageSilently(const LLUUID& session_id, const std::string& from, const LLUUID& from_id, + const std::string& utf8_text, bool log2file /* = true */, bool is_region_msg, /* false */ + U32 timestamp /* = 0 */) { LLIMSession* session = findIMSession(session_id); @@ -1241,12 +1646,12 @@ LLIMModel::LLIMSession* LLIMModel::addMessageSilently(const LLUUID& session_id, from_name = SYSTEM_FROM; } - addToHistory(session_id, from_name, from_id, utf8_text, is_region_msg); + addToHistory(session_id, from_name, from_id, utf8_text, is_region_msg, timestamp); if (log2file) { logToFile(getHistoryFileName(session_id), from_name, from_id, utf8_text); } - + session->mNumUnread++; //update count of unread messages from real participant @@ -1348,7 +1753,7 @@ const std::string& LLIMModel::getHistoryFileName(const LLUUID& session_id) const // TODO get rid of other participant ID -void LLIMModel::sendTypingState(LLUUID session_id, LLUUID other_participant_id, BOOL typing) +void LLIMModel::sendTypingState(LLUUID session_id, LLUUID other_participant_id, BOOL typing) { std::string name; LLAgentUI::buildFullname(name); @@ -1379,7 +1784,7 @@ void LLIMModel::sendLeaveSession(const LLUUID& session_id, const LLUUID& other_p FALSE, gAgent.getSessionID(), other_participant_id, - name, + name, LLStringUtil::null, IM_ONLINE, IM_SESSION_LEAVE, @@ -1400,7 +1805,7 @@ void LLIMModel::sendMessage(const std::string& utf8_text, const LLRelationship* info = NULL; info = LLAvatarTracker::instance().getBuddyInfo(other_participant_id); - + U8 offline = (!info || info->isOnline()) ? IM_ONLINE : IM_OFFLINE; // Old call to send messages to SLim client, no longer supported. //if((offline == IM_OFFLINE) && (LLVoiceClient::getInstance()->isOnlineSIP(other_participant_id))) @@ -1408,7 +1813,7 @@ void LLIMModel::sendMessage(const std::string& utf8_text, // // User is online through the OOW connector, but not with a regular viewer. Try to send the message via SLVoice. // sent = LLVoiceClient::getInstance()->sendTextMessage(other_participant_id, utf8_text); //} - + if(!sent) { // Send message normally. @@ -1465,7 +1870,7 @@ void LLIMModel::sendMessage(const std::string& utf8_text, } } - if((dialog == IM_NOTHING_SPECIAL) && + if((dialog == IM_NOTHING_SPECIAL) && (other_participant_id.notNull())) { // Do we have to replace the /me's here? @@ -1503,7 +1908,7 @@ void LLIMModel::sendMessage(const std::string& utf8_text, // to Recent People to prevent showing of an item with (?? ?)(?? ?), sans the spaces. See EXT-8246. // Concrete participants will be added into this list once they sent message in chat. if (IM_SESSION_INVITE == dialog) return; - + if (IM_SESSION_CONFERENCE_START == dialog) // outgoing ad-hoc session { // Add only online members of conference to recent list (EXT-8658) @@ -1585,7 +1990,7 @@ void start_deprecated_conference_chat( for(S32 i = 0; i < count; ++i) { LLUUID agent_id = agents_to_invite[i].asUUID(); - + memcpy(pos, &agent_id, UUID_BYTES); pos += UUID_BYTES; } @@ -1601,7 +2006,7 @@ void start_deprecated_conference_chat( bucket_size); gAgent.sendReliableMessage(); - + delete[] bucket; } @@ -1822,7 +2227,7 @@ void LLCallDialogManager::onVoiceChannelChangedInt(const LLUUID &session_id) { LLIMModel::LLIMSession* session = LLIMModel::getInstance()->findIMSession(session_id); if(!session) - { + { mPreviousSessionlName = mCurrentSessionlName; mCurrentSessionlName = ""; // Empty string results in "Nearby Voice Chat" after substitution return; @@ -1845,7 +2250,7 @@ void LLCallDialogManager::onVoiceChannelChangedInt(const LLUUID &session_id) if (LLVoiceChannel::getCurrentVoiceChannel()->getState() == LLVoiceChannel::STATE_CALL_STARTED && LLVoiceChannel::getCurrentVoiceChannel()->getCallDirection() == LLVoiceChannel::OUTGOING_CALL) { - + //*TODO get rid of duplicated code LLSD mCallDialogPayload; mCallDialogPayload["session_id"] = mSession->mSessionID; @@ -1860,7 +2265,7 @@ void LLCallDialogManager::onVoiceChannelChangedInt(const LLUUID &session_id) if(ocd) { ocd->show(mCallDialogPayload); - } + } } } @@ -1893,7 +2298,7 @@ void LLCallDialogManager::onVoiceChannelStateChangedInt(const LLVoiceChannel::ES mCallDialogPayload["ended_by_agent"] = ended_by_agent; switch(new_state) - { + { case LLVoiceChannel::STATE_CALL_STARTED : // do not show "Calling to..." if it is incoming call if(direction == LLVoiceChannel::INCOMING_CALL) @@ -1922,7 +2327,7 @@ void LLCallDialogManager::onVoiceChannelStateChangedInt(const LLVoiceChannel::ES if(ocd) { ocd->show(mCallDialogPayload); - } + } } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -1948,9 +2353,9 @@ BOOL LLCallDialog::postBuild() { if (!LLDockableFloater::postBuild() || !gToolBarView) return FALSE; - + dockToToolbarButton("speak"); - + return TRUE; } @@ -1968,20 +2373,20 @@ LLDockControl::DocAt LLCallDialog::getDockControlPos(const std::string& toolbarB { LLCommandId command_id(toolbarButtonName); S32 toolbar_loc = gToolBarView->hasCommand(command_id); - + LLDockControl::DocAt doc_at = LLDockControl::TOP; - + switch (toolbar_loc) { case LLToolBarEnums::TOOLBAR_LEFT: doc_at = LLDockControl::RIGHT; break; - + case LLToolBarEnums::TOOLBAR_RIGHT: doc_at = LLDockControl::LEFT; break; } - + return doc_at; } @@ -1996,7 +2401,7 @@ LLCallDialog(payload) if(instance && instance->getVisible()) { instance->onCancel(instance); - } + } } void LLCallDialog::draw() @@ -2053,7 +2458,7 @@ bool LLCallDialog::lifetimeHasExpired() if (mLifetimeTimer.getStarted()) { F32 elapsed_time = mLifetimeTimer.getElapsedTimeF32(); - if (elapsed_time > mLifetime) + if (elapsed_time > mLifetime) { return true; } @@ -2095,7 +2500,7 @@ void LLOutgoingCallDialog::show(const LLSD& key) } else { - getChild<LLUICtrl>("leaving")->setTextArg("[CURRENT_CHAT]", getString("localchat")); + getChild<LLUICtrl>("leaving")->setTextArg("[CURRENT_CHAT]", getString("localchat")); } if (!mPayload["disconnected_channel_name"].asString().empty()) @@ -2115,13 +2520,11 @@ void LLOutgoingCallDialog::show(const LLSD& key) std::string callee_name = mPayload["session_name"].asString(); - LLUUID session_id = mPayload["session_id"].asUUID(); - if (callee_name == "anonymous") // obsolete? Likely was part of avaline support { callee_name = getString("anonymous"); } - + LLSD callee_id = mPayload["other_user_id"]; // Beautification: Since you know who you called, just show display name std::string title = callee_name; @@ -2177,7 +2580,7 @@ void LLOutgoingCallDialog::show(const LLSD& key) { const std::string& nearby_str = mPayload["ended_by_agent"] ? NEARBY_P2P_BY_AGENT : NEARBY_P2P_BY_OTHER; getChild<LLTextBox>(nearby_str)->setVisible(true); - } + } else { getChild<LLTextBox>("nearby")->setVisible(true); @@ -2211,7 +2614,7 @@ void LLOutgoingCallDialog::onCancel(void* user_data) LLUUID session_id = self->mPayload["session_id"].asUUID(); gIMMgr->endCall(session_id); - + self->closeFloater(); } @@ -2296,7 +2699,7 @@ BOOL LLIncomingCallDialog::postBuild() LL_INFOS("IMVIEW") << "IncomingCall: notify_box_type was not provided" << LL_ENDL; return TRUE; } - + // init notification's lifetime std::istringstream ss( getString("lifetime") ); if (!(ss >> mLifetime)) @@ -2471,7 +2874,7 @@ void LLIncomingCallDialog::processCallResponse(S32 response, const LLSD &payload if (session_name.empty()) { LL_WARNS() << "Received an empty session name from a server" << LL_ENDL; - + switch(type){ case IM_SESSION_CONFERENCE_START: case IM_SESSION_GROUP_START: @@ -2489,18 +2892,18 @@ void LLIncomingCallDialog::processCallResponse(S32 response, const LLSD &payload if (LLAvatarNameCache::get(caller_id, &av_name)) { correct_session_name = av_name.getCompleteName(); - correct_session_name.append(ADHOC_NAME_SUFFIX); + correct_session_name.append(ADHOC_NAME_SUFFIX); } } LL_INFOS("IMVIEW") << "Corrected session name is " << correct_session_name << LL_ENDL; break; - default: + default: LL_WARNS("IMVIEW") << "Received an empty session name from a server and failed to generate a new proper session name" << LL_ENDL; break; } } - - LLUUID new_session_id = gIMMgr->addSession(correct_session_name, type, session_id, true); + + gIMMgr->addSession(correct_session_name, type, session_id, true); std::string url = gAgent.getRegion()->getCapability( "ChatSessionRequest"); @@ -2511,7 +2914,7 @@ void LLIncomingCallDialog::processCallResponse(S32 response, const LLSD &payload boost::bind(&chatterBoxInvitationCoro, url, session_id, inv_type)); - // send notification message to the corresponding chat + // send notification message to the corresponding chat if (payload["notify_box_type"].asString() == "VoiceInviteGroup" || payload["notify_box_type"].asString() == "VoiceInviteAdHoc") { LLStringUtil::format_map_t string_args; @@ -2546,7 +2949,7 @@ void LLIncomingCallDialog::processCallResponse(S32 response, const LLSD &payload data["session-id"] = session_id; LLCoreHttpUtil::HttpCoroutineAdapter::messageHttpPost(url, data, - "Invitation declined", + "Invitation declined", "Invitation decline failed."); } } @@ -2566,7 +2969,7 @@ bool inviteUserResponse(const LLSD& notification, const LLSD& response) EInstantMessage type = (EInstantMessage)payload["type"].asInteger(); LLIMMgr::EInvitationType inv_type = (LLIMMgr::EInvitationType)payload["inv_type"].asInteger(); S32 option = LLNotificationsUtil::getSelectedOption(notification, response); - switch(option) + switch(option) { case 0: // accept { @@ -2586,7 +2989,7 @@ bool inviteUserResponse(const LLSD& notification, const LLSD& response) } else { - LLUUID new_session_id = gIMMgr->addSession( + gIMMgr->addSession( payload["session_name"].asString(), type, session_id, true); @@ -2610,7 +3013,7 @@ bool inviteUserResponse(const LLSD& notification, const LLSD& response) } } /* FALLTHROUGH */ - + case 1: // decline { if (type == IM_SESSION_P2P_INVITE) @@ -2626,8 +3029,8 @@ bool inviteUserResponse(const LLSD& notification, const LLSD& response) LLSD data; data["method"] = "decline invitation"; data["session-id"] = session_id; - LLCoreHttpUtil::HttpCoroutineAdapter::messageHttpPost(url, data, - "Invitation declined.", + LLCoreHttpUtil::HttpCoroutineAdapter::messageHttpPost(url, data, + "Invitation declined.", "Invitation decline failed."); } } @@ -2636,7 +3039,7 @@ bool inviteUserResponse(const LLSD& notification, const LLSD& response) gIMMgr->clearPendingInvitation(session_id); break; } - + return false; } @@ -2650,9 +3053,11 @@ LLIMMgr::LLIMMgr() mPendingAgentListUpdates = LLSD::emptyMap(); LLIMModel::getInstance()->addNewMsgCallback(boost::bind(&LLFloaterIMSession::sRemoveTypingIndicator, _1)); + + gSavedPerAccountSettings.declareBOOL("FetchGroupChatHistory", TRUE, "Fetch recent messages from group chat servers when a group window opens", LLControlVariable::PERSIST_ALWAYS); } -// Add a message to a session. +// Add a message to a session. void LLIMMgr::addMessage( const LLUUID& session_id, const LLUUID& target_id, @@ -2664,7 +3069,8 @@ void LLIMMgr::addMessage( U32 parent_estate_id, const LLUUID& region_id, const LLVector3& position, - bool is_region_msg) + bool is_region_msg, + U32 timestamp) // May be zero { LLUUID other_participant_id = target_id; @@ -2684,7 +3090,7 @@ void LLIMMgr::addMessage( name_is_setted = true; } bool skip_message = false; - bool from_linden = LLMuteList::getInstance()->isLinden(from); + bool from_linden = LLMuteList::isLinden(from); if (gSavedPerAccountSettings.getBOOL("VoiceCallsFriendsOnly") && !from_linden) { // Evaluate if we need to skip this message when that setting is true (default is false) @@ -2751,6 +3157,14 @@ void LLIMMgr::addMessage( return; } + // Fetch group chat history, enabled by default. + if (gSavedPerAccountSettings.getBOOL("FetchGroupChatHistory")) + { + std::string chat_url = gAgent.getRegion()->getCapability("ChatSessionRequest"); + LLCoros::instance().launch("chatterBoxHistoryCoro", + boost::bind(&chatterBoxHistoryCoro, chat_url, session_id, from, msg, timestamp)); + } + //Play sound for new conversations if (!skip_message & !gAgent.isDoNotDisturb() && (gSavedSettings.getBOOL("PlaySoundNewConversation") == TRUE)) { @@ -2766,7 +3180,7 @@ void LLIMMgr::addMessage( if (!LLMuteList::getInstance()->isMuted(other_participant_id, LLMute::flagTextChat) && !skip_message) { - LLIMModel::instance().addMessage(new_session_id, from, other_participant_id, msg, true, is_region_msg); + LLIMModel::instance().addMessage(new_session_id, from, other_participant_id, msg, true, is_region_msg, timestamp); } // Open conversation floater if offline messages are present @@ -2781,7 +3195,7 @@ void LLIMMgr::addMessage( void LLIMMgr::addSystemMessage(const LLUUID& session_id, const std::string& message_name, const LLSD& args) { LLUIString message; - + // null session id means near me (chat history) if (session_id.isNull()) { @@ -2821,7 +3235,7 @@ void LLIMMgr::addSystemMessage(const LLUUID& session_id, const std::string& mess S32 LLIMMgr::getNumberOfUnreadIM() { std::map<LLUUID, LLIMModel::LLIMSession*>::iterator it; - + S32 num = 0; for(it = LLIMModel::getInstance()->mId2SessionMap.begin(); it != LLIMModel::getInstance()->mId2SessionMap.end(); ++it) { @@ -2848,7 +3262,7 @@ void LLIMMgr::autoStartCallOnStartup(const LLUUID& session_id) { LLIMModel::LLIMSession *session = LLIMModel::getInstance()->findIMSession(session_id); if (!session) return; - + if (session->mSessionInitialized) { startCall(session_id); @@ -2856,7 +3270,7 @@ void LLIMMgr::autoStartCallOnStartup(const LLUUID& session_id) else { session->mStartCallOnInitialize = true; - } + } } LLUUID LLIMMgr::addP2PSession(const std::string& name, @@ -2893,7 +3307,7 @@ LLUUID LLIMMgr::addSession( return session_id; } -// Adds a session using the given session_id. If the session already exists +// Adds a session using the given session_id. If the session already exists // the dialog type is assumed correct. Returns the uuid of the session. LLUUID LLIMMgr::addSession( const std::string& name, @@ -2956,9 +3370,9 @@ LLUUID LLIMMgr::addSession( //we don't need to show notes about online/offline, mute/unmute users' statuses for existing sessions if (!new_session) return session_id; - + LL_INFOS("IMVIEW") << "LLIMMgr::addSession, new session added, name = " << name << ", session id = " << session_id << LL_ENDL; - + //Per Plan's suggestion commented "explicit offline status warning" out to make Dessie happier (see EXT-3609) //*TODO After February 2010 remove this commented out line if no one will be missing that warning //noteOfflineUsers(session_id, floater, ids); @@ -2988,7 +3402,7 @@ bool LLIMMgr::leaveSession(const LLUUID& session_id) void LLIMMgr::removeSession(const LLUUID& session_id) { llassert_always(hasSession(session_id)); - + clearPendingInvitation(session_id); clearPendingAgentListUpdates(session_id); @@ -3000,9 +3414,9 @@ void LLIMMgr::removeSession(const LLUUID& session_id) } void LLIMMgr::inviteToSession( - const LLUUID& session_id, - const std::string& session_name, - const LLUUID& caller_id, + const LLUUID& session_id, + const std::string& session_name, + const LLUUID& caller_id, const std::string& caller_name, EInstantMessage type, EInvitationType inv_type, @@ -3014,7 +3428,7 @@ void LLIMMgr::inviteToSession( std::string question_type = "VoiceInviteQuestionDefault"; BOOL voice_invite = FALSE; - bool is_linden = LLMuteList::getInstance()->isLinden(caller_name); + bool is_linden = LLMuteList::isLinden(caller_name); if(type == IM_SESSION_P2P_INVITE) @@ -3119,22 +3533,22 @@ void LLIMMgr::inviteToSession( { if (caller_name.empty()) { - LLAvatarNameCache::get(caller_id, + LLAvatarNameCache::get(caller_id, boost::bind(&LLIMMgr::onInviteNameLookup, payload, _1, _2)); } else { LLFloaterReg::showInstance("incoming_call", payload, FALSE); } - - // Add the caller to the Recent List here (at this point + + // Add the caller to the Recent List here (at this point // "incoming_call" floater is shown and the recipient can // reject the call), because even if a recipient will reject // the call, the caller should be added to the recent list // anyway. STORM-507. if(type == IM_SESSION_P2P_INVITE) LLRecentPeople::instance().add(caller_id); - + mPendingInvitations[session_id.asString()] = LLSD(); } } @@ -3331,7 +3745,7 @@ bool LLIMMgr::startCall(const LLUUID& session_id, LLVoiceChannel::EDirection dir { LLVoiceChannel* voice_channel = LLIMModel::getInstance()->getVoiceChannel(session_id); if (!voice_channel) return false; - + voice_channel->setCallDirection(direction); voice_channel->activate(); return true; @@ -3449,7 +3863,7 @@ void LLIMMgr::noteMutedUsers(const LLUUID& session_id, if(count > 0) { LLIMModel* im_model = LLIMModel::getInstance(); - + for(S32 i = 0; i < count; ++i) { if( ml->isMuted(ids.at(i)) ) @@ -3527,7 +3941,15 @@ public: if ( body.has("session_info") ) { im_floater->processSessionUpdate(body["session_info"]); - } + + // Send request for chat history, if enabled. + if (gSavedPerAccountSettings.getBOOL("FetchGroupChatHistory")) + { + std::string url = gAgent.getRegion()->getCapability("ChatSessionRequest"); + LLCoros::instance().launch("chatterBoxHistoryCoro", + boost::bind(&chatterBoxHistoryCoro, url, session_id, "", "", 0)); + } + } } gIMMgr->clearPendingAgentListUpdates(session_id); @@ -3656,7 +4078,7 @@ public: LLUUID session_id = message_params["id"].asUUID(); std::vector<U8> bin_bucket = message_params["data"]["binary_bucket"].asBinary(); U8 offline = (U8)message_params["offline"].asInteger(); - + time_t timestamp = (time_t) message_params["timestamp"].asInteger(); @@ -3693,7 +4115,9 @@ public: IM_SESSION_INVITE, message_params["parent_estate_id"].asInteger(), message_params["region_id"].asUUID(), - ll_vector3_from_sd(message_params["position"])); + ll_vector3_from_sd(message_params["position"]), + false, // is_region_message + timestamp); if (LLMuteList::getInstance()->isMuted(from_id, name, LLMute::flagTextChat)) { @@ -3719,8 +4143,8 @@ public: } gIMMgr->inviteToSession( - input["body"]["session_id"].asUUID(), - input["body"]["session_name"].asString(), + input["body"]["session_id"].asUUID(), + input["body"]["session_name"].asString(), input["body"]["from_id"].asUUID(), input["body"]["from_name"].asString(), IM_SESSION_INVITE, @@ -3729,8 +4153,8 @@ public: else if ( input["body"].has("immediate") ) { gIMMgr->inviteToSession( - input["body"]["session_id"].asUUID(), - input["body"]["session_name"].asString(), + input["body"]["session_id"].asUUID(), + input["body"]["session_name"].asString(), input["body"]["from_id"].asUUID(), input["body"]["from_name"].asString(), IM_SESSION_INVITE, diff --git a/indra/newview/llimview.h b/indra/newview/llimview.h index 326e8f22e3..946eb02f26 100644 --- a/indra/newview/llimview.h +++ b/indra/newview/llimview.h @@ -42,6 +42,7 @@ class LLAvatarName; class LLFriendObserver; class LLCallDialogManager; class LLIMSpeakerMgr; + /** * Timeout Timer for outgoing Ad-Hoc/Group IM sessions which being initialized by the server */ @@ -63,11 +64,14 @@ private: class LLIMModel : public LLSingleton<LLIMModel> { LLSINGLETON(LLIMModel); + public: - struct LLIMSession : public boost::signals2::trackable + typedef std::list<LLSD> chat_message_list_t; + + struct LLIMSession : public boost::signals2::trackable { - typedef enum e_session_type + typedef enum e_session_type { // for now we have 4 predefined types for a session P2P_SESSION, GROUP_SESSION, @@ -75,15 +79,23 @@ public: NONE_SESSION, } SType; - LLIMSession(const LLUUID& session_id, const std::string& name, + LLIMSession(const LLUUID& session_id, const std::string& name, const EInstantMessage& type, const LLUUID& other_participant_id, const uuid_vec_t& ids, bool voice, bool has_offline_msg); virtual ~LLIMSession(); void sessionInitReplyReceived(const LLUUID& new_session_id); - void addMessagesFromHistory(const std::list<LLSD>& history); - void addMessage(const std::string& from, const LLUUID& from_id, const std::string& utf8_text, const std::string& time, const bool is_history = false, bool is_region_msg = false); - void onVoiceChannelStateChanged(const LLVoiceChannel::EState& old_state, const LLVoiceChannel::EState& new_state, const LLVoiceChannel::EDirection& direction); - + void addMessagesFromHistoryCache(const std::list<LLSD>& history); // From local file + void addMessagesFromServerHistory(const LLSD& history, const std::string& target_from, const std::string& target_message, U32 timestamp); // From chat server + void addMessage(const std::string& from, + const LLUUID& from_id, + const std::string& utf8_text, + const std::string& time, + const bool is_history, + const bool is_region_msg, + U32 timestamp); + + void onVoiceChannelStateChanged(const LLVoiceChannel::EState& old_state, const LLVoiceChannel::EState& new_state, const LLVoiceChannel::EDirection& direction); + /** @deprecated */ static void chatFromLogFile(LLLogChat::ELogLineType type, const LLSD& msg, void* userdata); @@ -112,6 +124,10 @@ public: uuid_vec_t mInitialTargetIDs; std::string mHistoryFileName; + // Saved messages from the last minute of history read from the local group chat cache file + std::string mLastHistoryCacheDateTime; + chat_message_list_t mLastHistoryCacheMsgs; + // connection to voice channel state change signal boost::signals2::connection mVoiceChannelStateChangeConnection; @@ -121,7 +137,7 @@ public: // does include all incoming messages S32 mNumUnread; - std::list<LLSD> mMsgs; + chat_message_list_t mMsgs; LLVoiceChannel* mVoiceChannel; LLIMSpeakerMgr* mSpeakers; @@ -208,29 +224,43 @@ public: * and also saved into a file if log2file is specified. * It sends new message signal for each added message. */ - bool addMessage(const LLUUID& session_id, const std::string& from, const LLUUID& other_participant_id, const std::string& utf8_text, bool log2file = true, bool is_region_msg = false); + void addMessage(const LLUUID& session_id, + const std::string& from, + const LLUUID& other_participant_id, + const std::string& utf8_text, + bool log2file = true, + bool is_region_msg = false, + U32 time_stamp = 0); + + void processAddingMessage(const LLUUID& session_id, + const std::string& from, + const LLUUID& from_id, + const std::string& utf8_text, + bool log2file, + bool is_region_msg, + U32 time_stamp); /** * Similar to addMessage(...) above but won't send a signal about a new message added */ - LLIMModel::LLIMSession* addMessageSilently(const LLUUID& session_id, const std::string& from, const LLUUID& from_id, - const std::string& utf8_text, bool log2file = true, bool is_region_msg = false); + LLIMModel::LLIMSession* addMessageSilently(const LLUUID& session_id, const std::string& from, const LLUUID& from_id, + const std::string& utf8_text, bool log2file = true, bool is_region_msg = false, U32 timestamp = 0); /** * Add a system message to an IM Model */ - bool proccessOnlineOfflineNotification(const LLUUID& session_id, const std::string& utf8_text); + void proccessOnlineOfflineNotification(const LLUUID& session_id, const std::string& utf8_text); /** - * Get a session's name. - * For a P2P chat - it's an avatar's name, + * Get a session's name. + * For a P2P chat - it's an avatar's name, * For a group chat - it's a group's name * For an incoming ad-hoc chat - is received from the server and is in a from of "<Avatar's name> Conference" * It is updated in LLIMModel::LLIMSession's constructor to localize the "Conference". */ const std::string getName(const LLUUID& session_id) const; - /** + /** * Get number of unread messages in a session with session_id * Returns -1 if the session with session_id doesn't exist */ @@ -282,7 +312,7 @@ public: bool logToFile(const std::string& file_name, const std::string& from, const LLUUID& from_id, const std::string& utf8_text); private: - + /** * Populate supplied std::list with messages starting from index specified by start_index without * emitting no unread messages signal. @@ -292,7 +322,7 @@ private: /** * Add message to a list of message associated with session specified by session_id */ - bool addToHistory(const LLUUID& session_id, const std::string& from, const LLUUID& from_id, const std::string& utf8_text, bool is_region_msg = false); + bool addToHistory(const LLUUID& session_id, const std::string& from, const LLUUID& from_id, const std::string& utf8_text, bool is_region_msg, U32 timestamp); }; @@ -334,7 +364,8 @@ public: U32 parent_estate_id = 0, const LLUUID& region_id = LLUUID::null, const LLVector3& position = LLVector3::zero, - bool is_region_msg = false); + bool is_region_msg = false, + U32 timestamp = 0); void addSystemMessage(const LLUUID& session_id, const std::string& message_name, const LLSD& args); diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp index 7793b71f56..db347f7096 100644 --- a/indra/newview/llinventorybridge.cpp +++ b/indra/newview/llinventorybridge.cpp @@ -831,6 +831,12 @@ void LLInvFVBridge::getClipboardEntries(bool show_asset_id, { disabled_items.push_back(std::string("Find Original")); } + + items.push_back(std::string("Cut")); + if (!isItemMovable() || !isItemRemovable()) + { + disabled_items.push_back(std::string("Cut")); + } } else { @@ -2140,6 +2146,7 @@ bool LLItemBridge::isItemCopyable(bool can_copy_as_link) const static LLCachedControl<bool> inventory_linking(gSavedSettings, "InventoryLinking", true); return (can_copy_as_link && inventory_linking) + || (mIsLink && inventory_linking) || item->getPermissions().allowCopyBy(gAgent.getID()); } @@ -2346,6 +2353,12 @@ BOOL LLFolderBridge::isUpToDate() const bool LLFolderBridge::isItemCopyable(bool can_copy_as_link) const { + if (can_copy_as_link && !LLFolderType::lookupIsProtectedType(getPreferredType())) + { + // Can copy and paste unprotected folders as links + return true; + } + // Folders are copyable if items in them are, recursively, copyable. // Get the content of the folder diff --git a/indra/newview/llinventoryfilter.cpp b/indra/newview/llinventoryfilter.cpp index 707ff2b7b6..e3a6b2dc85 100644 --- a/indra/newview/llinventoryfilter.cpp +++ b/indra/newview/llinventoryfilter.cpp @@ -437,7 +437,6 @@ bool LLInventoryFilter::checkAgainstFilterType(const LLFolderViewModelItemInvent bool LLInventoryFilter::checkAgainstFilterType(const LLInventoryItem* item) const { LLInventoryType::EType object_type = item->getInventoryType(); - const LLUUID object_id = item->getUUID(); const U32 filterTypes = mFilterOps.mFilterTypes; diff --git a/indra/newview/llinventoryfunctions.cpp b/indra/newview/llinventoryfunctions.cpp index 5755bc692e..67240ac7e7 100644 --- a/indra/newview/llinventoryfunctions.cpp +++ b/indra/newview/llinventoryfunctions.cpp @@ -529,7 +529,11 @@ BOOL get_is_item_worn(const LLUUID& id) const LLViewerInventoryItem* item = gInventory.getItem(id); if (!item) return FALSE; - + + if (item->getIsLinkType() && !gInventory.getItem(item->getLinkedUUID())) + { + return FALSE; + } // Consider the item as worn if it has links in COF. if (LLAppearanceMgr::instance().isLinkedInCOF(id)) { @@ -787,7 +791,7 @@ void show_item_original(const LLUUID& item_uuid) LLPanelMainInventory* main_inventory = sidepanel_inventory->getMainInventoryPanel(); if (main_inventory) { - main_inventory->resetFilters(); + main_inventory->resetAllItemsFilters(); } reset_inventory_filter(); @@ -795,6 +799,7 @@ void show_item_original(const LLUUID& item_uuid) { LLFloaterReg::toggleInstanceOrBringToFront("inventory"); } + sidepanel_inventory->showInventoryPanel(); const LLUUID inbox_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_INBOX); if (gInventory.isObjectDescendentOf(gInventory.getLinkedItemID(item_uuid), inbox_id)) @@ -1406,9 +1411,6 @@ bool move_item_to_marketplacelistings(LLInventoryItem* inv_item, LLUUID dest_fol LLNotificationsUtil::add("MerchantPasteFailed", subs); return false; } - - // Get the parent folder of the moved item : we may have to update it - LLUUID src_folder = viewer_inv_item->getParentUUID(); if (copy) { @@ -2653,7 +2655,12 @@ void LLInventoryAction::doToSelected(LLInventoryModel* model, LLFolderView* root } else { - std::copy(selected_uuid_set.begin(), selected_uuid_set.end(), std::back_inserter(ids)); + for (std::set<LLFolderViewItem*>::iterator it = selected_items.begin(), end_it = selected_items.end(); + it != end_it; + ++it) + { + ids.push_back(static_cast<LLFolderViewModelItemInventory*>((*it)->getViewModelItem())->getUUID()); + } } // Check for actions that get handled in bulk @@ -2714,7 +2721,7 @@ void LLInventoryAction::doToSelected(LLInventoryModel* model, LLFolderView* root } else if ("ungroup_folder_items" == action) { - if (selected_uuid_set.size() == 1) + if (ids.size() == 1) { LLInventoryCategory* inv_cat = gInventory.getCategory(*ids.begin()); if (!inv_cat || LLFolderType::lookupIsProtectedType(inv_cat->getPreferredType())) diff --git a/indra/newview/llinventorylistitem.h b/indra/newview/llinventorylistitem.h index d4dd212cc3..cf713a6930 100644 --- a/indra/newview/llinventorylistitem.h +++ b/indra/newview/llinventorylistitem.h @@ -197,6 +197,7 @@ protected: virtual BOOL handleToolTip( S32 x, S32 y, MASK mask); const LLUUID mInventoryItemUUID; + bool mHovered; private: @@ -221,7 +222,6 @@ private: LLUIImagePtr mSelectedImage; LLUIImagePtr mSeparatorImage; - bool mHovered; bool mSelected; bool mSeparatorVisible; diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp index e56a0ba414..46e76bc3f8 100644 --- a/indra/newview/llinventorymodel.cpp +++ b/indra/newview/llinventorymodel.cpp @@ -1635,6 +1635,9 @@ void LLInventoryModel::deleteObject(const LLUUID& id, bool fix_broken_links, boo LL_WARNS(LOG_INV) << "Deleting non-existent object [ id: " << id << " ] " << LL_ENDL; return; } + + //collect the links before removing the item from mItemMap + LLInventoryModel::item_array_t links = collectLinksTo(id); LL_DEBUGS(LOG_INV) << "Deleting inventory object " << id << LL_ENDL; mLastItem = NULL; @@ -1690,37 +1693,36 @@ void LLInventoryModel::deleteObject(const LLUUID& id, bool fix_broken_links, boo // Can't have links to links, so there's no need for this update // if the item removed is a link. Can also skip if source of the // update is getting broken link info separately. - obj = NULL; // delete obj if (fix_broken_links && !is_link_type) { - updateLinkedObjectsFromPurge(id); + rebuildLinkItems(links); } + obj = nullptr; // delete obj if (do_notify_observers) { notifyObservers(); } } -void LLInventoryModel::updateLinkedObjectsFromPurge(const LLUUID &baseobj_id) +void LLInventoryModel::rebuildLinkItems(LLInventoryModel::item_array_t& items) { - LLInventoryModel::item_array_t item_array = collectLinksTo(baseobj_id); - - // REBUILD is expensive, so clear the current change list first else - // everything else on the changelist will also get rebuilt. - if (item_array.size() > 0) - { - notifyObservers(); - for (LLInventoryModel::item_array_t::const_iterator iter = item_array.begin(); - iter != item_array.end(); - iter++) - { - const LLViewerInventoryItem *linked_item = (*iter); - const LLUUID &item_id = linked_item->getUUID(); - if (item_id == baseobj_id) continue; - addChangedMask(LLInventoryObserver::REBUILD, item_id); - } - notifyObservers(); - } + // REBUILD is expensive, so clear the current change list first else + // everything else on the changelist will also get rebuilt. + if (items.size() > 0) + { + notifyObservers(); + for (LLInventoryModel::item_array_t::const_iterator iter = items.begin(); + iter != items.end(); + iter++) + { + const LLViewerInventoryItem *linked_item = (*iter); + if (linked_item) + { + addChangedMask(LLInventoryObserver::REBUILD, linked_item->getUUID()); + } + } + notifyObservers(); + } } // Add/remove an observer. If the observer is destroyed, be sure to @@ -1950,18 +1952,20 @@ void LLInventoryModel::cache( items, INCLUDE_TRASH, can_cache); - std::string inventory_filename = getInvCacheAddres(agent_id); - saveToFile(inventory_filename, categories, items); - std::string gzip_filename(inventory_filename); + // Use temporary file to avoid potential conflicts with other + // instances (even a 'read only' instance unzips into a file) + std::string temp_file = gDirUtilp->getTempFilename(); + saveToFile(temp_file, categories, items); + std::string gzip_filename = getInvCacheAddres(agent_id); gzip_filename.append(".gz"); - if(gzip_file(inventory_filename, gzip_filename)) + if(gzip_file(temp_file, gzip_filename)) { - LL_DEBUGS(LOG_INV) << "Successfully compressed " << inventory_filename << LL_ENDL; - LLFile::remove(inventory_filename); + LL_DEBUGS(LOG_INV) << "Successfully compressed " << temp_file << " to " << gzip_filename << LL_ENDL; + LLFile::remove(temp_file); } else { - LL_WARNS(LOG_INV) << "Unable to compress " << inventory_filename << LL_ENDL; + LL_WARNS(LOG_INV) << "Unable to compress " << temp_file << " into " << gzip_filename << LL_ENDL; } } @@ -2714,7 +2718,6 @@ void LLInventoryModel::buildParentChildMap() // some accounts has pbroken inventory root folders std::string name = "My Inventory"; - LLUUID prev_root_id = mRootFolderID; for (parent_cat_map_t::const_iterator it = mParentChildCategoryTree.begin(), it_end = mParentChildCategoryTree.end(); it != it_end; ++it) { @@ -3035,6 +3038,7 @@ bool LLInventoryModel::saveToFile(const std::string& filename, return false; } } + fileXML.flush(); fileXML.close(); @@ -4590,7 +4594,6 @@ void LLInventoryModel::FetchItemHttpHandler::processData(LLSD & content, LLCore: { gInventory.updateItem(*it); } - gInventory.notifyObservers(); gViewerWindow->getWindow()->decBusyCount(); } diff --git a/indra/newview/llinventorymodel.h b/indra/newview/llinventorymodel.h index ef4a7d984d..6c5706f871 100644 --- a/indra/newview/llinventorymodel.h +++ b/indra/newview/llinventorymodel.h @@ -445,7 +445,7 @@ public: void checkTrashOverflow(); protected: - void updateLinkedObjectsFromPurge(const LLUUID& baseobj_id); + void rebuildLinkItems(LLInventoryModel::item_array_t& items); //-------------------------------------------------------------------- // Reorder diff --git a/indra/newview/llinventorymodelbackgroundfetch.cpp b/indra/newview/llinventorymodelbackgroundfetch.cpp index 406c8b89d0..4a9b471a47 100644 --- a/indra/newview/llinventorymodelbackgroundfetch.cpp +++ b/indra/newview/llinventorymodelbackgroundfetch.cpp @@ -363,7 +363,7 @@ void LLInventoryModelBackgroundFetch::bulkFetch() //If there are items in mFetchQueue, we want to check the time since the last bulkFetch was //sent. If it exceeds our retry time, go ahead and fire off another batch. LLViewerRegion * region(gAgent.getRegion()); - if (! region || gDisconnected) + if (! region || gDisconnected || LLApp::isExiting()) { return; } diff --git a/indra/newview/llinventorypanel.cpp b/indra/newview/llinventorypanel.cpp index 6b102c7500..8029486d6f 100644 --- a/indra/newview/llinventorypanel.cpp +++ b/indra/newview/llinventorypanel.cpp @@ -211,7 +211,11 @@ LLFolderView * LLInventoryPanel::createFolderRoot(LLUUID root_id ) p.allow_drop = mParams.allow_drop_on_root; p.options_menu = "menu_inventory.xml"; - return LLUICtrlFactory::create<LLFolderView>(p); + LLFolderView* fv = LLUICtrlFactory::create<LLFolderView>(p); + fv->setCallbackRegistrar(&mCommitCallbackRegistrar); + fv->setEnableRegistrar(&mEnableCallbackRegistrar); + + return fv; } void LLInventoryPanel::clearFolderRoot() @@ -264,6 +268,7 @@ void LLInventoryPanel::initFromParams(const LLInventoryPanel::Params& params) } mCommitCallbackRegistrar.popScope(); mFolderRoot.get()->setCallbackRegistrar(&mCommitCallbackRegistrar); + mFolderRoot.get()->setEnableRegistrar(&mEnableCallbackRegistrar); // Scroller LLRect scroller_view_rect = getRect(); @@ -1622,6 +1627,7 @@ void LLInventoryPanel::purgeSelectedItems() if (inventory_selected.empty()) return; LLSD args; S32 count = inventory_selected.size(); + std::vector<LLUUID> selected_items; for (std::set<LLFolderViewItem*>::const_iterator it = inventory_selected.begin(), end_it = inventory_selected.end(); it != end_it; ++it) @@ -1631,27 +1637,23 @@ void LLInventoryPanel::purgeSelectedItems() LLInventoryModel::item_array_t items; gInventory.collectDescendents(item_id, cats, items, LLInventoryModel::INCLUDE_TRASH); count += items.size() + cats.size(); + selected_items.push_back(item_id); } args["COUNT"] = count; - LLNotificationsUtil::add("PurgeSelectedItems", args, LLSD(), boost::bind(&LLInventoryPanel::callbackPurgeSelectedItems, this, _1, _2)); + LLNotificationsUtil::add("PurgeSelectedItems", args, LLSD(), boost::bind(callbackPurgeSelectedItems, _1, _2, selected_items)); } -void LLInventoryPanel::callbackPurgeSelectedItems(const LLSD& notification, const LLSD& response) +// static +void LLInventoryPanel::callbackPurgeSelectedItems(const LLSD& notification, const LLSD& response, const std::vector<LLUUID> inventory_selected) { - if (!mFolderRoot.get()) return; - S32 option = LLNotificationsUtil::getSelectedOption(notification, response); if (option == 0) { - const std::set<LLFolderViewItem*> inventory_selected = mFolderRoot.get()->getSelectionList(); if (inventory_selected.empty()) return; - std::set<LLFolderViewItem*>::const_iterator it = inventory_selected.begin(); - const std::set<LLFolderViewItem*>::const_iterator it_end = inventory_selected.end(); - for (; it != it_end; ++it) + for (auto it : inventory_selected) { - LLUUID item_id = static_cast<LLFolderViewModelItemInventory*>((*it)->getViewModelItem())->getUUID(); - remove_inventory_object(item_id, NULL); + remove_inventory_object(it, NULL); } } } diff --git a/indra/newview/llinventorypanel.h b/indra/newview/llinventorypanel.h index 552c61b915..2c782a5ea7 100644 --- a/indra/newview/llinventorypanel.h +++ b/indra/newview/llinventorypanel.h @@ -260,7 +260,7 @@ public: // Clean up stuff when the folder root gets deleted void clearFolderRoot(); - void callbackPurgeSelectedItems(const LLSD& notification, const LLSD& response); + static void callbackPurgeSelectedItems(const LLSD& notification, const LLSD& response, const std::vector<LLUUID> inventory_selected); protected: void openStartFolderOrMyInventory(); // open the first level of inventory diff --git a/indra/newview/llkeyconflict.cpp b/indra/newview/llkeyconflict.cpp index d3ba18525b..60f8aca94c 100644 --- a/indra/newview/llkeyconflict.cpp +++ b/indra/newview/llkeyconflict.cpp @@ -171,8 +171,9 @@ bool LLKeyConflictHandler::isReservedByMenu(const KEY &key, const MASK &mask) { return false; } - return (gMenuBarView && gMenuBarView->hasAccelerator(key, mask)) - || (gLoginMenuBarView && gLoginMenuBarView->hasAccelerator(key, mask)); + // At the moment controls are only applicable inworld, + // ignore gLoginMenuBarView + return gMenuBarView && gMenuBarView->hasAccelerator(key, mask); } // static @@ -182,8 +183,7 @@ bool LLKeyConflictHandler::isReservedByMenu(const LLKeyData &data) { return false; } - return (gMenuBarView && gMenuBarView->hasAccelerator(data.mKey, data.mMask)) - || (gLoginMenuBarView && gLoginMenuBarView->hasAccelerator(data.mKey, data.mMask)); + return gMenuBarView && gMenuBarView->hasAccelerator(data.mKey, data.mMask); } bool LLKeyConflictHandler::registerControl(const std::string &control_name, U32 index, EMouseClickType mouse, KEY key, MASK mask, bool ignore_mask) diff --git a/indra/newview/lllegacyatmospherics.cpp b/indra/newview/lllegacyatmospherics.cpp index ce4ec668f1..a34dafb19a 100644 --- a/indra/newview/lllegacyatmospherics.cpp +++ b/indra/newview/lllegacyatmospherics.cpp @@ -482,7 +482,6 @@ void LLAtmospherics::updateFog(const F32 distance, const LLVector3& tosun_in) { LLSettingsWater::ptr_t pwater = LLEnvironment::instance().getCurrentWater(); F32 depth = water_height - camera_height; - LLColor4 water_fog_color(pwater->getWaterFogColor()); // adjust the color based on depth. We're doing linear approximations diff --git a/indra/newview/lllistcontextmenu.cpp b/indra/newview/lllistcontextmenu.cpp index 6bda8b1d0d..77185411c5 100644 --- a/indra/newview/lllistcontextmenu.cpp +++ b/indra/newview/lllistcontextmenu.cpp @@ -51,6 +51,7 @@ LLListContextMenu::~LLListContextMenu() if (!mMenuHandle.isDead()) { mMenuHandle.get()->die(); + mMenuHandle.markDead(); } } @@ -59,13 +60,8 @@ void LLListContextMenu::show(LLView* spawning_view, const uuid_vec_t& uuids, S32 LLContextMenu* menup = mMenuHandle.get(); if (menup) { - //preventing parent (menu holder) from deleting already "dead" context menus on exit - LLView* parent = menup->getParent(); - if (parent) - { - parent->removeChild(menup); - } - delete menup; + menup->die(); + mMenuHandle.markDead(); mUUIDs.clear(); } diff --git a/indra/newview/lllogchat.cpp b/indra/newview/lllogchat.cpp index fb9885b454..ba82ff0b0f 100644 --- a/indra/newview/lllogchat.cpp +++ b/indra/newview/lllogchat.cpp @@ -62,6 +62,7 @@ const S32 LOG_RECALL_SIZE = 2048; const std::string LL_IM_TIME("time"); +const std::string LL_IM_DATE_TIME("datetime"); const std::string LL_IM_TEXT("message"); const std::string LL_IM_FROM("from"); const std::string LL_IM_FROM_ID("from_id"); @@ -133,14 +134,14 @@ void append_to_last_message(std::list<LLSD>& messages, const std::string& line) messages.back()[LL_IM_TEXT] = im_text; } -std::string remove_utf8_bom(const char* buf) +const char* remove_utf8_bom(const char* buf) { - std::string res(buf); - if (res[0] == (char)0xEF && res[1] == (char)0xBB && res[2] == (char)0xBF) - { - res.erase(0, 3); + const char* start = buf; + if (start[0] == (char)0xEF && start[1] == (char)0xBB && start[2] == (char)0xBF) + { // If string starts with the magic bytes, return pointer after it. + start += 3; } - return res; + return start; } class LLLogChatTimeScanner: public LLSingleton<LLLogChatTimeScanner> @@ -315,7 +316,7 @@ std::string LLLogChat::cleanFileName(std::string filename) return filename; } -std::string LLLogChat::timestamp(bool withdate) +std::string LLLogChat::timestamp2LogString(U32 timestamp, bool withdate) { std::string timeStr; if (withdate) @@ -333,7 +334,14 @@ std::string LLLogChat::timestamp(bool withdate) } LLSD substitution; - substitution["datetime"] = (S32)time_corrected(); + if (timestamp == 0) + { + substitution["datetime"] = (S32)time_corrected(); + } + else + { // timestamp is correct utc already + substitution["datetime"] = (S32)timestamp; + } LLStringUtil::format (timeStr, substitution); return timeStr; @@ -355,7 +363,7 @@ void LLLogChat::saveHistory(const std::string& filename, llassert(tmp_filename.size()); return; } - + llofstream file(LLLogChat::makeLogFileName(filename).c_str(), std::ios_base::app); if (!file.is_open()) { @@ -366,7 +374,7 @@ void LLLogChat::saveHistory(const std::string& filename, LLSD item; if (gSavedPerAccountSettings.getBOOL("LogTimestamp")) - item["time"] = LLLogChat::timestamp(gSavedPerAccountSettings.getBOOL("LogTimestampDate")); + item["time"] = LLLogChat::timestamp2LogString(0, gSavedPerAccountSettings.getBOOL("LogTimestampDate")); item["from_id"] = from_id; item["message"] = line; @@ -374,7 +382,7 @@ void LLLogChat::saveHistory(const std::string& filename, //adding "Second Life:" for all system messages to make chat log history parsing more reliable if (from.empty() && from_id.isNull()) { - item["from"] = SYSTEM_FROM; + item["from"] = SYSTEM_FROM; } else { @@ -393,37 +401,60 @@ void LLLogChat::loadChatHistory(const std::string& file_name, std::list<LLSD>& m { if (file_name.empty()) { - LL_WARNS("LLLogChat::loadChatHistory") << "Session name is Empty!" << LL_ENDL; + LL_WARNS("LLLogChat::loadChatHistory") << "Local history file name is empty!" << LL_ENDL; return ; } bool load_all_history = load_params.has("load_all_history") ? load_params["load_all_history"].asBoolean() : false; - LLFILE* fptr = LLFile::fopen(LLLogChat::makeLogFileName(file_name), "r");/*Flawfinder: ignore*/ + // Stat the file to find it and get the last history entry time + llstat stat_data; + + std::string log_file_name = LLLogChat::makeLogFileName(file_name); + LL_DEBUGS("ChatHistory") << "First attempt to stat chat history file " << log_file_name << LL_ENDL; + + S32 no_stat = LLFile::stat(log_file_name, &stat_data); + + if (no_stat) + { + if (is_group) + { + std::string old_name(file_name); + old_name.erase(old_name.size() - GROUP_CHAT_SUFFIX.size()); // trim off " (group)" + log_file_name = LLLogChat::makeLogFileName(old_name); + LL_DEBUGS("ChatHistory") << "Attempting to stat adjusted chat history file " << log_file_name << LL_ENDL; + no_stat = LLFile::stat(log_file_name, &stat_data); + if (!no_stat) + { // Found it without "(group)", copy to new naming style. We already have the mod time in stat_data + log_file_name = LLLogChat::makeLogFileName(file_name); + LL_DEBUGS("ChatHistory") << "Attempt to stat copied history file " << log_file_name << LL_ENDL; + LLFile::copy(LLLogChat::makeLogFileName(old_name), log_file_name); + } + } + if (no_stat) + { + log_file_name = LLLogChat::oldLogFileName(file_name); + LL_DEBUGS("ChatHistory") << "Attempt to stat old history file name " << log_file_name << LL_ENDL; + no_stat = LLFile::stat(log_file_name, &stat_data); + if (no_stat) + { + LL_DEBUGS("ChatHistory") << "No previous conversation log file found for " << file_name << LL_ENDL; + return; //No previous conversation with this name. + } + } + } + + // If we got here, we managed to stat the file. + // Open the file to read + LLFILE* fptr = LLFile::fopen(log_file_name, "r"); /*Flawfinder: ignore*/ if (!fptr) - { - if (is_group) - { - std::string old_name(file_name); - old_name.erase(old_name.size() - GROUP_CHAT_SUFFIX.size()); - fptr = LLFile::fopen(LLLogChat::makeLogFileName(old_name), "r"); - if (fptr) - { - fclose(fptr); - LLFile::copy(LLLogChat::makeLogFileName(old_name), LLLogChat::makeLogFileName(file_name)); - } - fptr = LLFile::fopen(LLLogChat::makeLogFileName(file_name), "r"); - } - if (!fptr) - { - fptr = LLFile::fopen(LLLogChat::oldLogFileName(file_name), "r");/*Flawfinder: ignore*/ - if (!fptr) - { - return; //No previous conversation with this name. - } - } + { // Ok, this is strange but not really tragic in the big picture of things + LL_WARNS("ChatHistory") << "Unable to read file " << log_file_name << " after stat was successful" << LL_ENDL; + return; } + S32 save_num_messages = messages.size(); + char buffer[LOG_RECALL_SIZE]; /*Flawfinder: ignore*/ char *bptr; S32 len; @@ -441,6 +472,7 @@ void LLLogChat::loadChatHistory(const std::string& file_name, std::list<LLSD>& m while (fgets(buffer, LOG_RECALL_SIZE, fptr) && !feof(fptr)) { len = strlen(buffer) - 1; /*Flawfinder: ignore*/ + // backfill any end of line characters with nulls for (bptr = (buffer + len); (*bptr == '\n' || *bptr == '\r') && bptr>buffer; bptr--) *bptr='\0'; if (firstline) @@ -473,6 +505,10 @@ void LLLogChat::loadChatHistory(const std::string& file_name, std::list<LLSD>& m } } fclose(fptr); + + LL_DEBUGS("ChatHistory") << "Read " << (messages.size() - save_num_messages) + << " messages of chat history from " << log_file_name + << " file mod time " << (F64)stat_data.st_mtime << LL_ENDL; } bool LLLogChat::historyThreadsFinished(LLUUID session_id) @@ -837,7 +873,8 @@ bool LLLogChat::isTranscriptFileFound(std::string fullname) { //matching a timestamp boost::match_results<std::string::const_iterator> matches; - if (ll_regex_match(remove_utf8_bom(buffer), matches, TIMESTAMP)) + std::string line(remove_utf8_bom(buffer)); + if (ll_regex_match(line, matches, TIMESTAMP)) { result = true; } @@ -847,7 +884,7 @@ bool LLLogChat::isTranscriptFileFound(std::string fullname) return result; } -//*TODO mark object's names in a special way so that they will be distinguishable form avatar name +//*TODO mark object's names in a special way so that they will be distinguishable form avatar name //which are more strict by its nature (only firstname and secondname) //Example, an object's name can be written like "Object <actual_object's_name>" void LLChatLogFormatter::format(const LLSD& im, std::ostream& ostr) const @@ -865,7 +902,7 @@ void LLChatLogFormatter::format(const LLSD& im, std::ostream& ostr) const ostr << '[' << timestamp << ']' << TWO_SPACES; } - //*TODO mark object's names in a special way so that they will be distinguishable form avatar name + //*TODO mark object's names in a special way so that they will be distinguishable from avatar name //which are more strict by its nature (only firstname and secondname) //Example, an object's name can be written like "Object <actual_object's_name>" if (im[LL_IM_FROM].isDefined()) @@ -928,7 +965,9 @@ bool LLChatLogParser::parse(std::string& raw, LLSD& im, const LLSD& parse_params timestamp.erase(0, 1); timestamp.erase(timestamp.length()-1, 1); - if (cut_off_todays_date) + im[LL_IM_DATE_TIME] = timestamp; // Retain full date-time for merging chat histories + + if (cut_off_todays_date) { LLLogChatTimeScanner::instance().checkAndCutOffDate(timestamp); } @@ -936,9 +975,9 @@ bool LLChatLogParser::parse(std::string& raw, LLSD& im, const LLSD& parse_params im[LL_IM_TIME] = timestamp; } else - { - //timestamp is optional - im[LL_IM_TIME] = ""; + { //timestamp is optional + im[LL_IM_DATE_TIME] = ""; + im[LL_IM_TIME] = ""; } bool has_stuff = matches[IDX_STUFF].matched; diff --git a/indra/newview/lllogchat.h b/indra/newview/lllogchat.h index c4b61ee716..5dce8ab1d2 100644 --- a/indra/newview/lllogchat.h +++ b/indra/newview/lllogchat.h @@ -92,7 +92,7 @@ public: LOG_END }; - static std::string timestamp(bool withdate = false); + static std::string timestamp2LogString(U32 timestamp, bool withdate); static std::string makeLogFileName(std::string(filename)); static void renameLogFile(const std::string& old_filename, const std::string& new_filename); /** @@ -201,6 +201,7 @@ extern const std::string GROUP_CHAT_SUFFIX; // LLSD map lookup constants extern const std::string LL_IM_TIME; //("time"); +extern const std::string LL_IM_DATE_TIME; //("datetime"); extern const std::string LL_IM_TEXT; //("message"); extern const std::string LL_IM_FROM; //("from"); extern const std::string LL_IM_FROM_ID; //("from_id"); diff --git a/indra/newview/llmarketplacefunctions.cpp b/indra/newview/llmarketplacefunctions.cpp index 2d726409c6..6f3d40bb3a 100644 --- a/indra/newview/llmarketplacefunctions.cpp +++ b/indra/newview/llmarketplacefunctions.cpp @@ -42,8 +42,8 @@ #include "llviewermedia.h" #include "llviewernetwork.h" #include "llviewerregion.h" -#include "reader.h" // JSON -#include "writer.h" // JSON +#include "json/reader.h" // JSON +#include "json/writer.h" // JSON #include "lleventcoro.h" #include "llcoros.h" #include "llcorehttputil.h" diff --git a/indra/newview/llmaterialmgr.cpp b/indra/newview/llmaterialmgr.cpp index 11aa607393..a52f7244f3 100644 --- a/indra/newview/llmaterialmgr.cpp +++ b/indra/newview/llmaterialmgr.cpp @@ -429,12 +429,10 @@ void LLMaterialMgr::onGetResponse(bool success, const LLSD& content, const LLUUI llassert(content.has(MATERIALS_CAP_ZIP_FIELD)); llassert(content[MATERIALS_CAP_ZIP_FIELD].isBinary()); - LLSD::Binary content_binary = content[MATERIALS_CAP_ZIP_FIELD].asBinary(); - std::string content_string(reinterpret_cast<const char*>(content_binary.data()), content_binary.size()); - std::istringstream content_stream(content_string); + const LLSD::Binary& content_binary = content[MATERIALS_CAP_ZIP_FIELD].asBinary(); LLSD response_data; - U32 uzip_result = LLUZipHelper::unzip_llsd(response_data, content_stream, content_binary.size()); + U32 uzip_result = LLUZipHelper::unzip_llsd(response_data, content_binary.data(), content_binary.size()); if (uzip_result != LLUZipHelper::ZR_OK) { LL_WARNS("Materials") << "Cannot unzip LLSD binary content: " << uzip_result << LL_ENDL; @@ -472,12 +470,10 @@ void LLMaterialMgr::onGetAllResponse(bool success, const LLSD& content, const LL llassert(content.has(MATERIALS_CAP_ZIP_FIELD)); llassert(content[MATERIALS_CAP_ZIP_FIELD].isBinary()); - LLSD::Binary content_binary = content[MATERIALS_CAP_ZIP_FIELD].asBinary(); - std::string content_string(reinterpret_cast<const char*>(content_binary.data()), content_binary.size()); - std::istringstream content_stream(content_string); + const LLSD::Binary& content_binary = content[MATERIALS_CAP_ZIP_FIELD].asBinary(); LLSD response_data; - U32 uzip_result = LLUZipHelper::unzip_llsd(response_data, content_stream, content_binary.size()); + U32 uzip_result = LLUZipHelper::unzip_llsd(response_data, content_binary.data(), content_binary.size()); if (uzip_result != LLUZipHelper::ZR_OK) { LL_WARNS("Materials") << "Cannot unzip LLSD binary content: " << uzip_result << LL_ENDL; @@ -541,12 +537,10 @@ void LLMaterialMgr::onPutResponse(bool success, const LLSD& content) llassert(content.has(MATERIALS_CAP_ZIP_FIELD)); llassert(content[MATERIALS_CAP_ZIP_FIELD].isBinary()); - LLSD::Binary content_binary = content[MATERIALS_CAP_ZIP_FIELD].asBinary(); - std::string content_string(reinterpret_cast<const char*>(content_binary.data()), content_binary.size()); - std::istringstream content_stream(content_string); + const LLSD::Binary& content_binary = content[MATERIALS_CAP_ZIP_FIELD].asBinary(); LLSD response_data; - U32 uzip_result = LLUZipHelper::unzip_llsd(response_data, content_stream, content_binary.size()); + U32 uzip_result = LLUZipHelper::unzip_llsd(response_data, content_binary.data(), content_binary.size()); if (uzip_result != LLUZipHelper::ZR_OK) { LL_WARNS("Materials") << "Cannot unzip LLSD binary content: " << uzip_result << LL_ENDL; @@ -666,8 +660,8 @@ void LLMaterialMgr::processGetQueue() { material_queue_t::iterator itMaterial = loopMaterial++; materialsData.append((*itMaterial).asLLSD()); - materials.erase(itMaterial); markGetPending(region_id, *itMaterial); + materials.erase(itMaterial); } if (materials.empty()) { diff --git a/indra/newview/llmediactrl.cpp b/indra/newview/llmediactrl.cpp index 9142aadab9..36ac1bdf97 100644 --- a/indra/newview/llmediactrl.cpp +++ b/indra/newview/llmediactrl.cpp @@ -106,7 +106,6 @@ LLMediaCtrl::LLMediaCtrl( const Params& p) : mTrusted(p.trusted_content), mWindowShade(NULL), mHoverTextChanged(false), - mContextMenu(NULL), mAllowFileDownload(false) { { @@ -151,6 +150,13 @@ LLMediaCtrl::LLMediaCtrl( const Params& p) : LLMediaCtrl::~LLMediaCtrl() { + auto menu = mContextMenuHandle.get(); + if (menu) + { + menu->die(); + mContextMenuHandle.markDead(); + } + if (mMediaSource) { mMediaSource->remObserver( this ); @@ -336,15 +342,33 @@ BOOL LLMediaCtrl::handleRightMouseDown( S32 x, S32 y, MASK mask ) setFocus( TRUE ); } - if (mContextMenu) + auto menu = mContextMenuHandle.get(); + if (!menu) + { + LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registar; + registar.add("Open.WebInspector", boost::bind(&LLMediaCtrl::onOpenWebInspector, this)); + + // stinson 05/05/2014 : use this as the parent of the context menu if the static menu + // container has yet to be created + LLPanel* menuParent = (LLMenuGL::sMenuContainer != NULL) ? dynamic_cast<LLPanel*>(LLMenuGL::sMenuContainer) : dynamic_cast<LLPanel*>(this); + llassert(menuParent != NULL); + menu = LLUICtrlFactory::getInstance()->createFromFile<LLContextMenu>( + "menu_media_ctrl.xml", menuParent, LLViewerMenuHolderGL::child_registry_t::instance()); + if (menu) + { + mContextMenuHandle = menu->getHandle(); + } + } + + if (menu) { // hide/show debugging options bool media_plugin_debugging_enabled = gSavedSettings.getBOOL("MediaPluginDebugging"); - mContextMenu->setItemVisible("open_webinspector", media_plugin_debugging_enabled ); - mContextMenu->setItemVisible("debug_separator", media_plugin_debugging_enabled ); + menu->setItemVisible("open_webinspector", media_plugin_debugging_enabled ); + menu->setItemVisible("debug_separator", media_plugin_debugging_enabled ); - mContextMenu->show(x, y); - LLMenuGL::showPopup(this, mContextMenu, x, y); + menu->show(x, y); + LLMenuGL::showPopup(this, menu, x, y); } return TRUE; @@ -409,15 +433,6 @@ void LLMediaCtrl::onFocusLost() // BOOL LLMediaCtrl::postBuild () { - LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registar; - registar.add("Open.WebInspector", boost::bind(&LLMediaCtrl::onOpenWebInspector, this)); - - // stinson 05/05/2014 : use this as the parent of the context menu if the static menu - // container has yet to be created - LLPanel* menuParent = (LLMenuGL::sMenuContainer != NULL) ? dynamic_cast<LLPanel*>(LLMenuGL::sMenuContainer) : dynamic_cast<LLPanel*>(this); - llassert(menuParent != NULL); - mContextMenu = LLUICtrlFactory::getInstance()->createFromFile<LLContextMenu>( - "menu_media_ctrl.xml", menuParent, LLViewerMenuHolderGL::child_registry_t::instance()); setVisibleCallback(boost::bind(&LLMediaCtrl::onVisibilityChanged, this, _2)); return TRUE; @@ -1230,11 +1245,6 @@ void LLMediaCtrl::setTrustedContent(bool trusted) } } -void LLMediaCtrl::updateContextMenuParent(LLView* pNewParent) -{ - mContextMenu->updateParent(pNewParent); -} - bool LLMediaCtrl::wantsKeyUpKeyDown() const { return true; diff --git a/indra/newview/llmediactrl.h b/indra/newview/llmediactrl.h index bc4cbaae68..487c654adc 100644 --- a/indra/newview/llmediactrl.h +++ b/indra/newview/llmediactrl.h @@ -174,8 +174,6 @@ public: LLUUID getTextureID() {return mMediaTextureID;} - void updateContextMenuParent(LLView* pNewParent); - // The Browser windows want keyup and keydown events. Overridden from LLFocusableElement to return true. virtual bool wantsKeyUpKeyDown() const; virtual bool wantsReturnKey() const; @@ -220,7 +218,7 @@ public: mTextureHeight; class LLWindowShade* mWindowShade; - LLContextMenu* mContextMenu; + LLHandle<LLContextMenu> mContextMenuHandle; }; #endif // LL_LLMediaCtrl_H diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp index a15a61429b..f937754368 100644 --- a/indra/newview/llmeshrepository.cpp +++ b/indra/newview/llmeshrepository.cpp @@ -77,6 +77,8 @@ #include "lluploaddialog.h" #include "llfloaterreg.h" +#include "boost/iostreams/device/array.hpp" +#include "boost/iostreams/stream.hpp" #include "boost/lexical_cast.hpp" #ifndef LL_WINDOWS @@ -138,7 +140,7 @@ // data copied // headerReceived() invoked // LLSD parsed -// mMeshHeader, mMeshHeaderSize updated +// mMeshHeader updated // scan mPendingLOD for LOD request // push LODRequest to mLODReqQ // ... @@ -246,7 +248,6 @@ // sActiveLODRequests mMutex rw.any.mMutex, ro.repo.none [1] // sMaxConcurrentRequests mMutex wo.main.none, ro.repo.none, ro.main.mMutex // mMeshHeader mHeaderMutex rw.repo.mHeaderMutex, ro.main.mHeaderMutex, ro.main.none [0] -// mMeshHeaderSize mHeaderMutex rw.repo.mHeaderMutex // mSkinRequests mMutex rw.repo.mMutex, ro.repo.none [5] // mSkinInfoQ mMutex rw.repo.mMutex, rw.main.mMutex [5] (was: [0]) // mDecompositionRequests mMutex rw.repo.mMutex, ro.repo.none [5] @@ -858,6 +859,12 @@ LLMeshRepoThread::~LLMeshRepoThread() mHttpRequestSet.clear(); mHttpHeaders.reset(); + while (!mSkinInfoQ.empty()) + { + delete mSkinInfoQ.front(); + mSkinInfoQ.pop_front(); + } + while (!mDecompositionQ.empty()) { delete mDecompositionQ.front(); @@ -947,7 +954,8 @@ void LLMeshRepoThread::run() else { // too many fails - mUnavailableQ.push(req); + LLMutexLock lock(mMutex); + mUnavailableQ.push_back(req); LL_WARNS() << "Failed to load " << req.mMeshParams << " , skip" << LL_ENDL; } } @@ -1023,37 +1031,42 @@ void LLMeshRepoThread::run() if (!mSkinRequests.empty()) { - std::set<UUIDBasedRequest> incomplete; - while (!mSkinRequests.empty() && mHttpRequestSet.size() < sRequestHighWater) - { - mMutex->lock(); - std::set<UUIDBasedRequest>::iterator iter = mSkinRequests.begin(); - UUIDBasedRequest req = *iter; - mSkinRequests.erase(iter); - mMutex->unlock(); - if (req.isDelayed()) - { - incomplete.insert(req); - } - else if (!fetchMeshSkinInfo(req.mId)) - { - if (req.canRetry()) - { - req.updateTime(); - incomplete.insert(req); - } - else - { - LL_DEBUGS() << "mSkinRequests failed: " << req.mId << LL_ENDL; - } - } - } + std::list<UUIDBasedRequest> incomplete; + while (!mSkinRequests.empty() && mHttpRequestSet.size() < sRequestHighWater) + { - if (!incomplete.empty()) - { - LLMutexLock locker(mMutex); - mSkinRequests.insert(incomplete.begin(), incomplete.end()); - } + mMutex->lock(); + auto req = mSkinRequests.front(); + mSkinRequests.pop_front(); + mMutex->unlock(); + if (req.isDelayed()) + { + incomplete.emplace_back(req); + } + else if (!fetchMeshSkinInfo(req.mId, req.canRetry())) + { + if (req.canRetry()) + { + req.updateTime(); + incomplete.emplace_back(req); + } + else + { + LLMutexLock locker(mMutex); + mSkinUnavailableQ.push_back(req); + LL_DEBUGS() << "mSkinReqQ failed: " << req.mId << LL_ENDL; + } + } + } + + if (!incomplete.empty()) + { + LLMutexLock locker(mMutex); + for (const auto& req : incomplete) + { + mSkinRequests.push_back(req); + } + } } // holding lock, try next list @@ -1152,7 +1165,7 @@ void LLMeshRepoThread::run() // Mutex: LLMeshRepoThread::mMutex must be held on entry void LLMeshRepoThread::loadMeshSkinInfo(const LLUUID& mesh_id) { - mSkinRequests.insert(UUIDBasedRequest(mesh_id)); + mSkinRequests.push_back(UUIDBasedRequest(mesh_id)); } // Mutex: LLMeshRepoThread::mMutex must be held on entry @@ -1178,10 +1191,13 @@ void LLMeshRepoThread::lockAndLoadMeshLOD(const LLVolumeParams& mesh_params, S32 void LLMeshRepoThread::loadMeshLOD(const LLVolumeParams& mesh_params, S32 lod) { //could be called from any thread + const LLUUID& mesh_id = mesh_params.getSculptID(); LLMutexLock lock(mMutex); - mesh_header_map::iterator iter = mMeshHeader.find(mesh_params.getSculptID()); + LLMutexLock header_lock(mHeaderMutex); + mesh_header_map::iterator iter = mMeshHeader.find(mesh_id); if (iter != mMeshHeader.end()) { //if we have the header, request LOD byte range + LODRequest req(mesh_params, lod); { mLODReqQ.push(req); @@ -1191,8 +1207,7 @@ void LLMeshRepoThread::loadMeshLOD(const LLVolumeParams& mesh_params, S32 lod) else { HeaderRequest req(mesh_params); - - pending_lod_map::iterator pending = mPendingLOD.find(mesh_params); + pending_lod_map::iterator pending = mPendingLOD.find(mesh_id); if (pending != mPendingLOD.end()) { //append this lod request to existing header request @@ -1202,7 +1217,7 @@ void LLMeshRepoThread::loadMeshLOD(const LLVolumeParams& mesh_params, S32 lod) else { //if no header request is pending, fetch header mHeaderReqQ.push(req); - mPendingLOD[mesh_params].push_back(lod); + mPendingLOD[mesh_id].push_back(lod); } } } @@ -1307,7 +1322,7 @@ LLCore::HttpHandle LLMeshRepoThread::getByteRange(const std::string & url, } -bool LLMeshRepoThread::fetchMeshSkinInfo(const LLUUID& mesh_id) +bool LLMeshRepoThread::fetchMeshSkinInfo(const LLUUID& mesh_id, bool can_retry) { if (!mHeaderMutex) @@ -1317,7 +1332,8 @@ bool LLMeshRepoThread::fetchMeshSkinInfo(const LLUUID& mesh_id) mHeaderMutex->lock(); - if (mMeshHeader.find(mesh_id) == mMeshHeader.end()) + auto header_it = mMeshHeader.find(mesh_id); + if (header_it == mMeshHeader.end()) { //we have no header info for this mesh, do nothing mHeaderMutex->unlock(); return false; @@ -1325,13 +1341,14 @@ bool LLMeshRepoThread::fetchMeshSkinInfo(const LLUUID& mesh_id) ++LLMeshRepository::sMeshRequestCount; bool ret = true; - U32 header_size = mMeshHeaderSize[mesh_id]; + U32 header_size = header_it->second.first; if (header_size > 0) { - S32 version = mMeshHeader[mesh_id]["version"].asInteger(); - S32 offset = header_size + mMeshHeader[mesh_id]["skin"]["offset"].asInteger(); - S32 size = mMeshHeader[mesh_id]["skin"]["size"].asInteger(); + const LLSD& header = header_it->second.second; + S32 version = header["version"].asInteger(); + S32 offset = header_size + header["skin"]["offset"].asInteger(); + S32 size = header["skin"]["size"].asInteger(); mHeaderMutex->unlock(); @@ -1387,12 +1404,27 @@ bool LLMeshRepoThread::fetchMeshSkinInfo(const LLUUID& mesh_id) << LL_ENDL; ret = false; } - else + else if(can_retry) { handler->mHttpHandle = handle; mHttpRequestSet.insert(handler); } + else + { + LLMutexLock locker(mMutex); + mSkinUnavailableQ.emplace_back(mesh_id); + } } + else + { + LLMutexLock locker(mMutex); + mSkinUnavailableQ.emplace_back(mesh_id); + } + } + else + { + LLMutexLock locker(mMutex); + mSkinUnavailableQ.emplace_back(mesh_id); } } else @@ -1413,21 +1445,23 @@ bool LLMeshRepoThread::fetchMeshDecomposition(const LLUUID& mesh_id) mHeaderMutex->lock(); - if (mMeshHeader.find(mesh_id) == mMeshHeader.end()) + auto header_it = mMeshHeader.find(mesh_id); + if (header_it == mMeshHeader.end()) { //we have no header info for this mesh, do nothing mHeaderMutex->unlock(); return false; } ++LLMeshRepository::sMeshRequestCount; - U32 header_size = mMeshHeaderSize[mesh_id]; + U32 header_size = header_it->second.first; bool ret = true; if (header_size > 0) { - S32 version = mMeshHeader[mesh_id]["version"].asInteger(); - S32 offset = header_size + mMeshHeader[mesh_id]["physics_convex"]["offset"].asInteger(); - S32 size = mMeshHeader[mesh_id]["physics_convex"]["size"].asInteger(); + const auto& header = header_it->second.second; + S32 version = header["version"].asInteger(); + S32 offset = header_size + header["physics_convex"]["offset"].asInteger(); + S32 size = header["physics_convex"]["size"].asInteger(); mHeaderMutex->unlock(); @@ -1510,21 +1544,23 @@ bool LLMeshRepoThread::fetchMeshPhysicsShape(const LLUUID& mesh_id) mHeaderMutex->lock(); - if (mMeshHeader.find(mesh_id) == mMeshHeader.end()) + auto header_it = mMeshHeader.find(mesh_id); + if (header_it == mMeshHeader.end()) { //we have no header info for this mesh, do nothing mHeaderMutex->unlock(); return false; } ++LLMeshRepository::sMeshRequestCount; - U32 header_size = mMeshHeaderSize[mesh_id]; + U32 header_size = header_it->second.first; bool ret = true; if (header_size > 0) { - S32 version = mMeshHeader[mesh_id]["version"].asInteger(); - S32 offset = header_size + mMeshHeader[mesh_id]["physics_mesh"]["offset"].asInteger(); - S32 size = mMeshHeader[mesh_id]["physics_mesh"]["size"].asInteger(); + const auto& header = header_it->second.second; + S32 version = header["version"].asInteger(); + S32 offset = header_size + header["physics_mesh"]["offset"].asInteger(); + S32 size = header["physics_mesh"]["size"].asInteger(); mHeaderMutex->unlock(); @@ -1704,20 +1740,25 @@ bool LLMeshRepoThread::fetchMeshLOD(const LLVolumeParams& mesh_params, S32 lod, return false; } - mHeaderMutex->lock(); + const LLUUID& mesh_id = mesh_params.getSculptID(); + mHeaderMutex->lock(); + auto header_it = mMeshHeader.find(mesh_id); + if (header_it == mMeshHeader.end()) + { //we have no header info for this mesh, do nothing + mHeaderMutex->unlock(); + return false; + } ++LLMeshRepository::sMeshRequestCount; bool retval = true; - - LLUUID mesh_id = mesh_params.getSculptID(); - U32 header_size = mMeshHeaderSize[mesh_id]; - + U32 header_size = header_it->second.first; if (header_size > 0) { - S32 version = mMeshHeader[mesh_id]["version"].asInteger(); - S32 offset = header_size + mMeshHeader[mesh_id][header_lod[lod]]["offset"].asInteger(); - S32 size = mMeshHeader[mesh_id][header_lod[lod]]["size"].asInteger(); + const auto& header = header_it->second.second; + S32 version = header["version"].asInteger(); + S32 offset = header_size + header[header_lod[lod]]["offset"].asInteger(); + S32 size = header[header_lod[lod]]["size"].asInteger(); mHeaderMutex->unlock(); if (version <= MAX_MESH_VERSION && offset >= 0 && size > 0) @@ -1792,17 +1833,20 @@ bool LLMeshRepoThread::fetchMeshLOD(const LLVolumeParams& mesh_params, S32 lod, } else { - mUnavailableQ.push(LODRequest(mesh_params, lod)); + LLMutexLock lock(mMutex); + mUnavailableQ.push_back(LODRequest(mesh_params, lod)); } } else { - mUnavailableQ.push(LODRequest(mesh_params, lod)); + LLMutexLock lock(mMutex); + mUnavailableQ.push_back(LODRequest(mesh_params, lod)); } } else { - mUnavailableQ.push(LODRequest(mesh_params, lod)); + LLMutexLock lock(mMutex); + mUnavailableQ.push_back(LODRequest(mesh_params, lod)); } } else @@ -1821,27 +1865,12 @@ EMeshProcessingResult LLMeshRepoThread::headerReceived(const LLVolumeParams& mes U32 header_size = 0; if (data_size > 0) { - std::istringstream stream; - try - { - std::string res_str((char*)data, data_size); + U32 dsize = data_size; + char* result_ptr = strip_deprecated_header((char*)data, dsize, &header_size); - std::string deprecated_header("<? LLSD/Binary ?>"); + data_size = dsize; - if (res_str.substr(0, deprecated_header.size()) == deprecated_header) - { - res_str = res_str.substr(deprecated_header.size() + 1, data_size); - header_size = deprecated_header.size() + 1; - } - data_size = res_str.size(); - - stream.str(res_str); - } - catch (std::bad_alloc&) - { - // out of memory, we won't be able to process this mesh - return MESH_OUT_OF_MEMORY; - } + boost::iostreams::stream<boost::iostreams::array_source> stream(result_ptr, data_size); if (!LLSDSerialize::fromBinary(header, stream, data_size)) { @@ -1878,8 +1907,7 @@ EMeshProcessingResult LLMeshRepoThread::headerReceived(const LLVolumeParams& mes { LLMutexLock lock(mHeaderMutex); - mMeshHeaderSize[mesh_id] = header_size; - mMeshHeader[mesh_id] = header; + mMeshHeader[mesh_id] = { header_size, header }; LLMeshRepository::sCacheBytesHeaders += header_size; } @@ -1887,7 +1915,7 @@ EMeshProcessingResult LLMeshRepoThread::headerReceived(const LLVolumeParams& mes LLMutexLock lock(mMutex); // make sure only one thread access mPendingLOD at the same time. //check for pending requests - pending_lod_map::iterator iter = mPendingLOD.find(mesh_params); + pending_lod_map::iterator iter = mPendingLOD.find(mesh_id); if (iter != mPendingLOD.end()) { for (U32 i = 0; i < iter->second.size(); ++i) @@ -1911,26 +1939,14 @@ EMeshProcessingResult LLMeshRepoThread::lodReceived(const LLVolumeParams& mesh_p } LLPointer<LLVolume> volume = new LLVolume(mesh_params, LLVolumeLODGroup::getVolumeScaleFromDetail(lod)); - std::istringstream stream; - try - { - std::string mesh_string((char*)data, data_size); - stream.str(mesh_string); - } - catch (std::bad_alloc&) - { - // out of memory, we won't be able to process this mesh - return MESH_OUT_OF_MEMORY; - } - - if (volume->unpackVolumeFaces(stream, data_size)) + if (volume->unpackVolumeFaces(data, data_size)) { if (volume->getNumFaces() > 0) { LoadedMesh mesh(volume, mesh_params, lod); { LLMutexLock lock(mMutex); - mLoadedQ.push(mesh); + mLoadedQ.push_back(mesh); // LLPointer is not thread safe, since we added this pointer into // threaded list, make sure counter gets decreased inside mutex lock // and won't affect mLoadedQ processing @@ -1953,10 +1969,7 @@ bool LLMeshRepoThread::skinInfoReceived(const LLUUID& mesh_id, U8* data, S32 dat { try { - std::string res_str((char*)data, data_size); - std::istringstream stream(res_str); - - U32 uzip_result = LLUZipHelper::unzip_llsd(skin, stream, data_size); + U32 uzip_result = LLUZipHelper::unzip_llsd(skin, data, data_size); if (uzip_result != LLUZipHelper::ZR_OK) { LL_WARNS(LOG_MESH) << "Mesh skin info parse error. Not a valid mesh asset! ID: " << mesh_id @@ -1973,8 +1986,16 @@ bool LLMeshRepoThread::skinInfoReceived(const LLUUID& mesh_id, U8* data, S32 dat } { - LLMeshSkinInfo info(skin); - info.mMeshID = mesh_id; + LLMeshSkinInfo* info = nullptr; + try + { + info = new LLMeshSkinInfo(mesh_id, skin); + } + catch (const std::bad_alloc& ex) + { + LL_WARNS() << "Failed to allocate skin info with exception: " << ex.what() << LL_ENDL; + return false; + } // LL_DEBUGS(LOG_MESH) << "info pelvis offset" << info.mPelvisOffset << LL_ENDL; { @@ -1994,10 +2015,7 @@ bool LLMeshRepoThread::decompositionReceived(const LLUUID& mesh_id, U8* data, S3 { try { - std::string res_str((char*)data, data_size); - std::istringstream stream(res_str); - - U32 uzip_result = LLUZipHelper::unzip_llsd(decomp, stream, data_size); + U32 uzip_result = LLUZipHelper::unzip_llsd(decomp, data, data_size); if (uzip_result != LLUZipHelper::ZR_OK) { LL_WARNS(LOG_MESH) << "Mesh decomposition parse error. Not a valid mesh asset! ID: " << mesh_id @@ -2006,7 +2024,7 @@ bool LLMeshRepoThread::decompositionReceived(const LLUUID& mesh_id, U8* data, S3 return false; } } - catch (std::bad_alloc&) + catch (const std::bad_alloc&) { LL_WARNS(LOG_MESH) << "Out of memory for mesh ID " << mesh_id << " of size: " << data_size << LL_ENDL; return false; @@ -2043,20 +2061,7 @@ EMeshProcessingResult LLMeshRepoThread::physicsShapeReceived(const LLUUID& mesh_ volume_params.setSculptID(mesh_id, LL_SCULPT_TYPE_MESH); LLPointer<LLVolume> volume = new LLVolume(volume_params,0); - std::istringstream stream; - try - { - std::string mesh_string((char*)data, data_size); - stream.str(mesh_string); - } - catch (std::bad_alloc&) - { - // out of memory, we won't be able to process this mesh - delete d; - return MESH_OUT_OF_MEMORY; - } - - if (volume->unpackVolumeFaces(stream, data_size)) + if (volume->unpackVolumeFaces(data, data_size)) { d->mPhysicsShapeMesh.clear(); @@ -2870,58 +2875,72 @@ void LLMeshRepoThread::notifyLoadedMeshes() return; } - while (!mLoadedQ.empty()) + if (!mLoadedQ.empty()) { + std::deque<LoadedMesh> loaded_queue; + mMutex->lock(); - if (mLoadedQ.empty()) + if (!mLoadedQ.empty()) { + loaded_queue.swap(mLoadedQ); mMutex->unlock(); - break; - } - LoadedMesh mesh = mLoadedQ.front(); // make sure nothing else owns volume pointer by this point - mLoadedQ.pop(); - mMutex->unlock(); - - update_metrics = true; - if (mesh.mVolume->getNumVolumeFaces() > 0) - { - gMeshRepo.notifyMeshLoaded(mesh.mMeshParams, mesh.mVolume); - } - else - { - gMeshRepo.notifyMeshUnavailable(mesh.mMeshParams, - LLVolumeLODGroup::getVolumeDetailFromScale(mesh.mVolume->getDetail())); + + update_metrics = true; + + // Process the elements free of the lock + for (const auto& mesh : loaded_queue) + { + if (mesh.mVolume->getNumVolumeFaces() > 0) + { + gMeshRepo.notifyMeshLoaded(mesh.mMeshParams, mesh.mVolume); + } + else + { + gMeshRepo.notifyMeshUnavailable(mesh.mMeshParams, + LLVolumeLODGroup::getVolumeDetailFromScale(mesh.mVolume->getDetail())); + } + } } } - while (!mUnavailableQ.empty()) + if (!mUnavailableQ.empty()) { + std::deque<LODRequest> unavil_queue; + mMutex->lock(); - if (mUnavailableQ.empty()) + if (!mUnavailableQ.empty()) { + unavil_queue.swap(mUnavailableQ); mMutex->unlock(); - break; - } - - LODRequest req = mUnavailableQ.front(); - mUnavailableQ.pop(); - mMutex->unlock(); - update_metrics = true; - gMeshRepo.notifyMeshUnavailable(req.mMeshParams, req.mLOD); + update_metrics = true; + + // Process the elements free of the lock + for (const auto& req : unavil_queue) + { + gMeshRepo.notifyMeshUnavailable(req.mMeshParams, req.mLOD); + } + } } - if (! mSkinInfoQ.empty() || ! mDecompositionQ.empty()) + if (!mSkinInfoQ.empty() || !mSkinUnavailableQ.empty() || ! mDecompositionQ.empty()) { if (mMutex->trylock()) { - std::list<LLMeshSkinInfo> skin_info_q; + std::deque<LLMeshSkinInfo*> skin_info_q; + std::deque<UUIDBasedRequest> skin_info_unavail_q; std::list<LLModel::Decomposition*> decomp_q; if (! mSkinInfoQ.empty()) { skin_info_q.swap(mSkinInfoQ); } + + if (! mSkinUnavailableQ.empty()) + { + skin_info_unavail_q.swap(mSkinUnavailableQ); + } + if (! mDecompositionQ.empty()) { decomp_q.swap(mDecompositionQ); @@ -2935,6 +2954,11 @@ void LLMeshRepoThread::notifyLoadedMeshes() gMeshRepo.notifySkinInfoReceived(skin_info_q.front()); skin_info_q.pop_front(); } + while (! skin_info_unavail_q.empty()) + { + gMeshRepo.notifySkinInfoUnavailable(skin_info_unavail_q.front().mId); + skin_info_unavail_q.pop_front(); + } while (! decomp_q.empty()) { @@ -2959,7 +2983,7 @@ S32 LLMeshRepoThread::getActualMeshLOD(const LLVolumeParams& mesh_params, S32 lo if (iter != mMeshHeader.end()) { - LLSD& header = iter->second; + LLSD& header = iter->second.second; return LLMeshRepository::getActualMeshLOD(header, lod); } @@ -3162,7 +3186,7 @@ void LLMeshHeaderHandler::processFailure(LLCore::HttpStatus status) LLMutexLock lock(gMeshRepo.mThread->mMutex); for (int i(0); i < 4; ++i) { - gMeshRepo.mThread->mUnavailableQ.push(LLMeshRepoThread::LODRequest(mMeshParams, i)); + gMeshRepo.mThread->mUnavailableQ.push_back(LLMeshRepoThread::LODRequest(mMeshParams, i)); } } @@ -3191,7 +3215,7 @@ void LLMeshHeaderHandler::processData(LLCore::BufferArray * /* body */, S32 /* b LLMutexLock lock(gMeshRepo.mThread->mMutex); for (int i(0); i < 4; ++i) { - gMeshRepo.mThread->mUnavailableQ.push(LLMeshRepoThread::LODRequest(mMeshParams, i)); + gMeshRepo.mThread->mUnavailableQ.push_back(LLMeshRepoThread::LODRequest(mMeshParams, i)); } } else if (data && data_size > 0) @@ -3204,8 +3228,8 @@ void LLMeshHeaderHandler::processData(LLCore::BufferArray * /* body */, S32 /* b LLMeshRepoThread::mesh_header_map::iterator iter = gMeshRepo.mThread->mMeshHeader.find(mesh_id); if (iter != gMeshRepo.mThread->mMeshHeader.end()) { - header_bytes = (S32)gMeshRepo.mThread->mMeshHeaderSize[mesh_id]; - header = iter->second; + header_bytes = (S32)iter->second.first; + header = iter->second.second; } if (header_bytes > 0 @@ -3273,7 +3297,7 @@ void LLMeshHeaderHandler::processData(LLCore::BufferArray * /* body */, S32 /* b LLMutexLock lock(gMeshRepo.mThread->mMutex); for (int i(0); i < 4; ++i) { - gMeshRepo.mThread->mUnavailableQ.push(LLMeshRepoThread::LODRequest(mMeshParams, i)); + gMeshRepo.mThread->mUnavailableQ.push_back(LLMeshRepoThread::LODRequest(mMeshParams, i)); } } } @@ -3300,7 +3324,7 @@ void LLMeshLODHandler::processFailure(LLCore::HttpStatus status) << LL_ENDL; LLMutexLock lock(gMeshRepo.mThread->mMutex); - gMeshRepo.mThread->mUnavailableQ.push(LLMeshRepoThread::LODRequest(mMeshParams, mLOD)); + gMeshRepo.mThread->mUnavailableQ.push_back(LLMeshRepoThread::LODRequest(mMeshParams, mLOD)); } void LLMeshLODHandler::processData(LLCore::BufferArray * /* body */, S32 /* body_offset */, @@ -3337,7 +3361,7 @@ void LLMeshLODHandler::processData(LLCore::BufferArray * /* body */, S32 /* body << " Not retrying." << LL_ENDL; LLMutexLock lock(gMeshRepo.mThread->mMutex); - gMeshRepo.mThread->mUnavailableQ.push(LLMeshRepoThread::LODRequest(mMeshParams, mLOD)); + gMeshRepo.mThread->mUnavailableQ.push_back(LLMeshRepoThread::LODRequest(mMeshParams, mLOD)); } } else @@ -3348,7 +3372,7 @@ void LLMeshLODHandler::processData(LLCore::BufferArray * /* body */, S32 /* body << " Data size: " << data_size << LL_ENDL; LLMutexLock lock(gMeshRepo.mThread->mMutex); - gMeshRepo.mThread->mUnavailableQ.push(LLMeshRepoThread::LODRequest(mMeshParams, mLOD)); + gMeshRepo.mThread->mUnavailableQ.push_back(LLMeshRepoThread::LODRequest(mMeshParams, mLOD)); } } @@ -3366,9 +3390,8 @@ void LLMeshSkinInfoHandler::processFailure(LLCore::HttpStatus status) << ", Reason: " << status.toString() << " (" << status.toTerseString() << "). Not retrying." << LL_ENDL; - - // *TODO: Mark mesh unavailable on error. For now, simply leave - // request unfulfilled rather than retry forever. + LLMutexLock lock(gMeshRepo.mThread->mMutex); + gMeshRepo.mThread->mSkinUnavailableQ.emplace_back(mMeshID); } void LLMeshSkinInfoHandler::processData(LLCore::BufferArray * /* body */, S32 /* body_offset */, @@ -3399,7 +3422,8 @@ void LLMeshSkinInfoHandler::processData(LLCore::BufferArray * /* body */, S32 /* LL_WARNS(LOG_MESH) << "Error during mesh skin info processing. ID: " << mMeshID << ", Unknown reason. Not retrying." << LL_ENDL; - // *TODO: Mark mesh unavailable on error + LLMutexLock lock(gMeshRepo.mThread->mMutex); + gMeshRepo.mThread->mSkinUnavailableQ.emplace_back(mMeshID); } } @@ -3508,7 +3532,7 @@ LLMeshRepository::LLMeshRepository() mMeshThreadCount(0), mThread(NULL) { - + mSkinInfoCullTimer.resetWithExpiry(10.f); } void LLMeshRepository::init() @@ -3609,6 +3633,22 @@ S32 LLMeshRepository::update() return size ; } +void LLMeshRepository::unregisterMesh(LLVOVolume* vobj) +{ + for (auto& lod : mLoadingMeshes) + { + for (auto& param : lod) + { + vector_replace_with_last(param.second, vobj); + } + } + + for (auto& skin_pair : mLoadingSkins) + { + vector_replace_with_last(skin_pair.second, vobj); + } +} + S32 LLMeshRepository::loadMesh(LLVOVolume* vobj, const LLVolumeParams& mesh_params, S32 detail, S32 last_lod) { LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK; //LL_LL_RECORD_BLOCK_TIME(FTM_MESH_FETCH); @@ -3624,15 +3664,19 @@ S32 LLMeshRepository::loadMesh(LLVOVolume* vobj, const LLVolumeParams& mesh_para { LLMutexLock lock(mMeshMutex); //add volume to list of loading meshes - mesh_load_map::iterator iter = mLoadingMeshes[detail].find(mesh_params); + const auto& mesh_id = mesh_params.getSculptID(); + mesh_load_map::iterator iter = mLoadingMeshes[detail].find(mesh_id); if (iter != mLoadingMeshes[detail].end()) { //request pending for this mesh, append volume id to list - iter->second.insert(vobj->getID()); + auto it = std::find(iter->second.begin(), iter->second.end(), vobj); + if (it == iter->second.end()) { + iter->second.push_back(vobj); + } } else { //first request for this mesh - mLoadingMeshes[detail][mesh_params].insert(vobj->getID()); + mLoadingMeshes[detail][mesh_id].push_back(vobj); mPendingRequests.push_back(LLMeshRepoThread::LODRequest(mesh_params, detail)); LLMeshRepository::sLODPending++; } @@ -3789,6 +3833,28 @@ void LLMeshRepository::notifyLoadedMeshes() //call completed callbacks on finished decompositions mDecompThread->notifyCompleted(); + if (mSkinInfoCullTimer.checkExpirationAndReset(10.f)) + { + //// Clean up dead skin info + //U64Bytes skinbytes(0); + for (auto iter = mSkinMap.begin(), ender = mSkinMap.end(); iter != ender;) + { + auto copy_iter = iter++; + + //skinbytes += U64Bytes(sizeof(LLMeshSkinInfo)); + //skinbytes += U64Bytes(copy_iter->second->mJointNames.size() * sizeof(std::string)); + //skinbytes += U64Bytes(copy_iter->second->mJointNums.size() * sizeof(S32)); + //skinbytes += U64Bytes(copy_iter->second->mJointNames.size() * sizeof(LLMatrix4a)); + //skinbytes += U64Bytes(copy_iter->second->mJointNames.size() * sizeof(LLMatrix4)); + + if (copy_iter->second->getNumRefs() == 1) + { + mSkinMap.erase(copy_iter); + } + } + //LL_INFOS() << "Skin info cache elements:" << mSkinMap.size() << " Memory: " << U64Kilobytes(skinbytes) << LL_ENDL; + } + // For major operations, attempt to get the required locks // without blocking and punt if they're not available. The // longest run of holdoffs is kept in sMaxLockHoldoffs just @@ -3859,10 +3925,9 @@ void LLMeshRepository::notifyLoadedMeshes() for (mesh_load_map::iterator iter = mLoadingMeshes[i].begin(); iter != mLoadingMeshes[i].end(); ++iter) { F32 max_score = 0.f; - for (std::set<LLUUID>::iterator obj_iter = iter->second.begin(); obj_iter != iter->second.end(); ++obj_iter) + for (auto obj_iter = iter->second.begin(); obj_iter != iter->second.end(); ++obj_iter) { - LLViewerObject* object = gObjectList.findObject(*obj_iter); - + LLVOVolume* object = *obj_iter; if (object) { LLDrawable* drawable = object->mDrawable; @@ -3874,7 +3939,7 @@ void LLMeshRepository::notifyLoadedMeshes() } } - score_map[iter->first.getSculptID()] = max_score; + score_map[iter->first] = max_score; } } @@ -3926,24 +3991,39 @@ void LLMeshRepository::notifyLoadedMeshes() mThread->mSignal->signal(); } -void LLMeshRepository::notifySkinInfoReceived(LLMeshSkinInfo& info) +void LLMeshRepository::notifySkinInfoReceived(LLMeshSkinInfo* info) { - mSkinMap[info.mMeshID] = info; + mSkinMap[info->mMeshID] = info; // Cache into LLPointer // Alternative: We can get skin size from header - sCacheBytesSkins += info.sizeBytes(); + sCacheBytesSkins += info->sizeBytes(); - skin_load_map::iterator iter = mLoadingSkins.find(info.mMeshID); + skin_load_map::iterator iter = mLoadingSkins.find(info->mMeshID); if (iter != mLoadingSkins.end()) { - for (std::set<LLUUID>::iterator obj_id = iter->second.begin(); obj_id != iter->second.end(); ++obj_id) + for (LLVOVolume* vobj : iter->second) { - LLVOVolume* vobj = (LLVOVolume*) gObjectList.findObject(*obj_id); if (vobj) { - vobj->notifyMeshLoaded(); + vobj->notifySkinInfoLoaded(info); } } - mLoadingSkins.erase(info.mMeshID); + mLoadingSkins.erase(iter); + } +} + +void LLMeshRepository::notifySkinInfoUnavailable(const LLUUID& mesh_id) +{ + skin_load_map::iterator iter = mLoadingSkins.find(mesh_id); + if (iter != mLoadingSkins.end()) + { + for (LLVOVolume* vobj : iter->second) + { + if (vobj) + { + vobj->notifySkinInfoUnavailable(); + } + } + mLoadingSkins.erase(iter); } } @@ -3972,14 +4052,15 @@ void LLMeshRepository::notifyMeshLoaded(const LLVolumeParams& mesh_params, LLVol S32 detail = LLVolumeLODGroup::getVolumeDetailFromScale(volume->getDetail()); //get list of objects waiting to be notified this mesh is loaded - mesh_load_map::iterator obj_iter = mLoadingMeshes[detail].find(mesh_params); + const auto& mesh_id = mesh_params.getSculptID(); + mesh_load_map::iterator obj_iter = mLoadingMeshes[detail].find(mesh_id); if (volume && obj_iter != mLoadingMeshes[detail].end()) { //make sure target volume is still valid if (volume->getNumVolumeFaces() <= 0) { - LL_WARNS(LOG_MESH) << "Mesh loading returned empty volume. ID: " << mesh_params.getSculptID() + LL_WARNS(LOG_MESH) << "Mesh loading returned empty volume. ID: " << mesh_id << LL_ENDL; } @@ -3993,37 +4074,35 @@ void LLMeshRepository::notifyMeshLoaded(const LLVolumeParams& mesh_params, LLVol } else { - LL_WARNS(LOG_MESH) << "Couldn't find system volume for mesh " << mesh_params.getSculptID() + LL_WARNS(LOG_MESH) << "Couldn't find system volume for mesh " << mesh_id << LL_ENDL; } } //notify waiting LLVOVolume instances that their requested mesh is available - for (std::set<LLUUID>::iterator vobj_iter = obj_iter->second.begin(); vobj_iter != obj_iter->second.end(); ++vobj_iter) + for (LLVOVolume* vobj : obj_iter->second) { - LLVOVolume* vobj = (LLVOVolume*) gObjectList.findObject(*vobj_iter); if (vobj) { vobj->notifyMeshLoaded(); } } - mLoadingMeshes[detail].erase(mesh_params); + mLoadingMeshes[detail].erase(obj_iter); } } void LLMeshRepository::notifyMeshUnavailable(const LLVolumeParams& mesh_params, S32 lod) { //called from main thread //get list of objects waiting to be notified this mesh is loaded - mesh_load_map::iterator obj_iter = mLoadingMeshes[lod].find(mesh_params); - - F32 detail = LLVolumeLODGroup::getVolumeScaleFromDetail(lod); - + const auto& mesh_id = mesh_params.getSculptID(); + mesh_load_map::iterator obj_iter = mLoadingMeshes[lod].find(mesh_id); if (obj_iter != mLoadingMeshes[lod].end()) { - for (std::set<LLUUID>::iterator vobj_iter = obj_iter->second.begin(); vobj_iter != obj_iter->second.end(); ++vobj_iter) + F32 detail = LLVolumeLODGroup::getVolumeScaleFromDetail(lod); + + for (LLVOVolume* vobj : obj_iter->second) { - LLVOVolume* vobj = (LLVOVolume*) gObjectList.findObject(*vobj_iter); if (vobj) { LLVolume* obj_volume = vobj->getVolume(); @@ -4037,7 +4116,7 @@ void LLMeshRepository::notifyMeshUnavailable(const LLVolumeParams& mesh_params, } } - mLoadingMeshes[lod].erase(mesh_params); + mLoadingMeshes[lod].erase(obj_iter); } } @@ -4046,7 +4125,7 @@ S32 LLMeshRepository::getActualMeshLOD(const LLVolumeParams& mesh_params, S32 lo return mThread->getActualMeshLOD(mesh_params, lod); } -const LLMeshSkinInfo* LLMeshRepository::getSkinInfo(const LLUUID& mesh_id, const LLVOVolume* requesting_obj) +const LLMeshSkinInfo* LLMeshRepository::getSkinInfo(const LLUUID& mesh_id, LLVOVolume* requesting_obj) { LL_PROFILE_ZONE_SCOPED_CATEGORY_AVATAR; if (mesh_id.notNull()) @@ -4054,7 +4133,7 @@ const LLMeshSkinInfo* LLMeshRepository::getSkinInfo(const LLUUID& mesh_id, const skin_map::iterator iter = mSkinMap.find(mesh_id); if (iter != mSkinMap.end()) { - return &(iter->second); + return iter->second; } //no skin info known about given mesh, try to fetch it @@ -4063,14 +4142,22 @@ const LLMeshSkinInfo* LLMeshRepository::getSkinInfo(const LLUUID& mesh_id, const LLMutexLock lock(mMeshMutex); //add volume to list of loading meshes skin_load_map::iterator iter = mLoadingSkins.find(mesh_id); - if (iter == mLoadingSkins.end()) - { //no request pending for this skin info + if (iter != mLoadingSkins.end()) + { //request pending for this mesh, append volume id to list + auto it = std::find(iter->second.begin(), iter->second.end(), requesting_obj); + if (it == iter->second.end()) { + iter->second.push_back(requesting_obj); + } + } + else + { + //first request for this mesh + mLoadingSkins[mesh_id].push_back(requesting_obj); mPendingSkinRequests.push(mesh_id); } - mLoadingSkins[mesh_id].insert(requesting_obj->getID()); } } - return NULL; + return nullptr; } void LLMeshRepository::fetchPhysicsShape(const LLUUID& mesh_id) @@ -4173,16 +4260,13 @@ bool LLMeshRepository::hasPhysicsShape(const LLUUID& mesh_id) bool LLMeshRepoThread::hasPhysicsShapeInHeader(const LLUUID& mesh_id) { LLMutexLock lock(mHeaderMutex); - if (mMeshHeaderSize[mesh_id] > 0) + mesh_header_map::iterator iter = mMeshHeader.find(mesh_id); + if (iter != mMeshHeader.end() && iter->second.first > 0) { - mesh_header_map::iterator iter = mMeshHeader.find(mesh_id); - if (iter != mMeshHeader.end()) + LLSD &mesh = iter->second.second; + if (mesh.has("physics_mesh") && mesh["physics_mesh"].has("size") && (mesh["physics_mesh"]["size"].asInteger() > 0)) { - LLSD &mesh = iter->second; - if (mesh.has("physics_mesh") && mesh["physics_mesh"].has("size") && (mesh["physics_mesh"]["size"].asInteger() > 0)) - { - return true; - } + return true; } } @@ -4207,9 +4291,9 @@ S32 LLMeshRepository::getMeshSize(const LLUUID& mesh_id, S32 lod) { LLMutexLock lock(mThread->mHeaderMutex); LLMeshRepoThread::mesh_header_map::iterator iter = mThread->mMeshHeader.find(mesh_id); - if (iter != mThread->mMeshHeader.end() && mThread->mMeshHeaderSize[mesh_id] > 0) + if (iter != mThread->mMeshHeader.end() && iter->second.first > 0) { - LLSD& header = iter->second; + const LLSD& header = iter->second.second; if (header.has("404")) { @@ -4313,9 +4397,9 @@ F32 LLMeshRepository::getStreamingCostLegacy(LLUUID mesh_id, F32 radius, S32* by { LLMutexLock lock(mThread->mHeaderMutex); LLMeshRepoThread::mesh_header_map::iterator iter = mThread->mMeshHeader.find(mesh_id); - if (iter != mThread->mMeshHeader.end() && mThread->mMeshHeaderSize[mesh_id] > 0) + if (iter != mThread->mMeshHeader.end() && iter->second.first > 0) { - result = getStreamingCostLegacy(iter->second, radius, bytes, bytes_visible, lod, unscaled_value); + result = getStreamingCostLegacy(iter->second.second, radius, bytes, bytes_visible, lod, unscaled_value); } } if (result > 0.f) @@ -4628,9 +4712,9 @@ bool LLMeshRepository::getCostData(LLUUID mesh_id, LLMeshCostData& data) { LLMutexLock lock(mThread->mHeaderMutex); LLMeshRepoThread::mesh_header_map::iterator iter = mThread->mMeshHeader.find(mesh_id); - if (iter != mThread->mMeshHeader.end() && mThread->mMeshHeaderSize[mesh_id] > 0) + if (iter != mThread->mMeshHeader.end() && iter->second.first > 0) { - LLSD& header = iter->second; + LLSD& header = iter->second.second; bool header_invalid = (header.has("404") || !header.has("lowest_lod") diff --git a/indra/newview/llmeshrepository.h b/indra/newview/llmeshrepository.h index f61da3e571..e3688ff243 100644 --- a/indra/newview/llmeshrepository.h +++ b/indra/newview/llmeshrepository.h @@ -210,10 +210,8 @@ public: LLCondition* mSignal; //map of known mesh headers - typedef std::map<LLUUID, LLSD> mesh_header_map; + typedef boost::unordered_map<LLUUID, std::pair<U32, LLSD>> mesh_header_map; // pair is header_size and data mesh_header_map mMeshHeader; - - std::map<LLUUID, U32> mMeshHeaderSize; class HeaderRequest : public RequestStats { @@ -283,10 +281,13 @@ public: }; //set of requested skin info - std::set<UUIDBasedRequest> mSkinRequests; + std::deque<UUIDBasedRequest> mSkinRequests; // list of completed skin info requests - std::list<LLMeshSkinInfo> mSkinInfoQ; + std::deque<LLMeshSkinInfo*> mSkinInfoQ; + + // list of skin info requests that have failed or are unavailaibe + std::deque<UUIDBasedRequest> mSkinUnavailableQ; //set of requested decompositions std::set<UUIDBasedRequest> mDecompositionRequests; @@ -304,13 +305,13 @@ public: std::queue<LODRequest> mLODReqQ; //queue of unavailable LODs (either asset doesn't exist or asset doesn't have desired LOD) - std::queue<LODRequest> mUnavailableQ; + std::deque<LODRequest> mUnavailableQ; //queue of successfully loaded meshes - std::queue<LoadedMesh> mLoadedQ; + std::deque<LoadedMesh> mLoadedQ; //map of pending header requests and currently desired LODs - typedef std::map<LLVolumeParams, std::vector<S32> > pending_lod_map; + typedef boost::unordered_map<LLUUID, std::vector<S32> > pending_lod_map; pending_lod_map mPendingLOD; // llcorehttp library interface objects. @@ -354,7 +355,7 @@ public: //send request for skin info, returns true if header info exists // (should hold onto mesh_id and try again later if header info does not exist) - bool fetchMeshSkinInfo(const LLUUID& mesh_id); + bool fetchMeshSkinInfo(const LLUUID& mesh_id, bool can_retry = true); //send request for decomposition, returns true if header info exists // (should hold onto mesh_id and try again later if header info does not exist) @@ -577,18 +578,20 @@ public: void shutdown(); S32 update(); + void unregisterMesh(LLVOVolume* volume); //mesh management functions S32 loadMesh(LLVOVolume* volume, const LLVolumeParams& mesh_params, S32 detail = 0, S32 last_lod = -1); void notifyLoadedMeshes(); void notifyMeshLoaded(const LLVolumeParams& mesh_params, LLVolume* volume); void notifyMeshUnavailable(const LLVolumeParams& mesh_params, S32 lod); - void notifySkinInfoReceived(LLMeshSkinInfo& info); + void notifySkinInfoReceived(LLMeshSkinInfo* info); + void notifySkinInfoUnavailable(const LLUUID& info); void notifyDecompositionReceived(LLModel::Decomposition* info); S32 getActualMeshLOD(const LLVolumeParams& mesh_params, S32 lod); static S32 getActualMeshLOD(LLSD& header, S32 lod); - const LLMeshSkinInfo* getSkinInfo(const LLUUID& mesh_id, const LLVOVolume* requesting_obj = nullptr); + const LLMeshSkinInfo* getSkinInfo(const LLUUID& mesh_id, LLVOVolume* requesting_obj = nullptr); LLModel::Decomposition* getDecomposition(const LLUUID& mesh_id); void fetchPhysicsShape(const LLUUID& mesh_id); bool hasPhysicsShape(const LLUUID& mesh_id); @@ -613,10 +616,10 @@ public: static void metricsProgress(unsigned int count); static void metricsUpdate(); - typedef std::map<LLVolumeParams, std::set<LLUUID> > mesh_load_map; + typedef boost::unordered_map<LLUUID, std::vector<LLVOVolume*> > mesh_load_map; mesh_load_map mLoadingMeshes[4]; - typedef std::unordered_map<LLUUID, LLMeshSkinInfo> skin_map; + typedef std::unordered_map<LLUUID, LLPointer<LLMeshSkinInfo>> skin_map; skin_map mSkinMap; typedef std::map<LLUUID, LLModel::Decomposition*> decomposition_map; @@ -627,7 +630,7 @@ public: std::vector<LLMeshRepoThread::LODRequest> mPendingRequests; //list of mesh ids awaiting skin info - typedef std::map<LLUUID, std::set<LLUUID> > skin_load_map; + typedef boost::unordered_map<LLUUID, std::vector<LLVOVolume*> > skin_load_map; skin_load_map mLoadingSkins; //list of mesh ids that need to send skin info fetch requests @@ -652,6 +655,8 @@ public: std::vector<LLMeshUploadThread*> mUploadWaitList; LLPhysicsDecomp* mDecompThread; + + LLFrameTimer mSkinInfoCullTimer; class inventory_data { diff --git a/indra/newview/llmodelpreview.cpp b/indra/newview/llmodelpreview.cpp index 642df7f931..e1a5b22490 100644 --- a/indra/newview/llmodelpreview.cpp +++ b/indra/newview/llmodelpreview.cpp @@ -1926,32 +1926,16 @@ void LLModelPreview::genMeshOptimizerLODs(S32 which_lod, S32 meshopt_mode, U32 d if (sloppy_ratio < 0) { // Sloppy method didn't work, try with smaller decimation values - S32 size_vertices = 0; - - for (U32 face_idx = 0; face_idx < base->getNumVolumeFaces(); ++face_idx) - { - const LLVolumeFace &face = base->getVolumeFace(face_idx); - size_vertices += face.mNumVertices; - } - - // Complex models aren't supposed to get here, they are supposed - // to work on a first try of sloppy due to having more viggle room. - // If they didn't, something is likely wrong, no point locking the - // thread in a long calculation that will fail. - const U32 too_many_vertices = 27000; - if (size_vertices > too_many_vertices) - { - LL_WARNS() << "Sloppy optimization method failed for a complex model " << target_model->getName() << LL_ENDL; - } - else { // Find a decimator that does work F32 sloppy_decimation_step = sqrt((F32)decimation); // example: 27->15->9->5->3 F32 sloppy_decimator = indices_decimator / sloppy_decimation_step; + U64Microseconds end_time = LLTimer::getTotalTime() + U64Seconds(5); while (sloppy_ratio < 0 && sloppy_decimator > precise_ratio - && sloppy_decimator > 1)// precise_ratio isn't supposed to be below 1, but check just in case + && sloppy_decimator > 1 // precise_ratio isn't supposed to be below 1, but check just in case + && end_time > LLTimer::getTotalTime()) { sloppy_ratio = genMeshOptimizerPerModel(base, target_model, sloppy_decimator, lod_error_threshold, MESH_OPTIMIZER_NO_TOPOLOGY); sloppy_decimator = sloppy_decimator / sloppy_decimation_step; diff --git a/indra/newview/llmutelist.cpp b/indra/newview/llmutelist.cpp index bf00d77dea..a7a7ed1b70 100644 --- a/indra/newview/llmutelist.cpp +++ b/indra/newview/llmutelist.cpp @@ -192,7 +192,7 @@ void LLMuteList::cleanupSingleton() LLAvatarNameCache::getInstance()->setAccountNameChangedCallback(NULL); } -BOOL LLMuteList::isLinden(const std::string& name) const +bool LLMuteList::isLinden(const std::string& name) { std::string username = boost::replace_all_copy(name, ".", " "); typedef boost::tokenizer<boost::char_separator<char> > tokenizer; @@ -200,9 +200,9 @@ BOOL LLMuteList::isLinden(const std::string& name) const tokenizer tokens(username, sep); tokenizer::iterator token_iter = tokens.begin(); - if (token_iter == tokens.end()) return FALSE; + if (token_iter == tokens.end()) return false; token_iter++; - if (token_iter == tokens.end()) return FALSE; + if (token_iter == tokens.end()) return false; std::string last_name = *token_iter; LLStringUtil::toLower(last_name); diff --git a/indra/newview/llmutelist.h b/indra/newview/llmutelist.h index 0d426fbd48..2c45014321 100644 --- a/indra/newview/llmutelist.h +++ b/indra/newview/llmutelist.h @@ -104,7 +104,7 @@ public: // Alternate (convenience) form for places we don't need to pass the name, but do need flags BOOL isMuted(const LLUUID& id, U32 flags) const { return isMuted(id, LLStringUtil::null, flags); }; - BOOL isLinden(const std::string& name) const; + static bool isLinden(const std::string& name); BOOL isLoaded() const { return mIsLoaded; } diff --git a/indra/newview/llnetmap.cpp b/indra/newview/llnetmap.cpp index b34be80b07..0ba3c3d691 100755..100644 --- a/indra/newview/llnetmap.cpp +++ b/indra/newview/llnetmap.cpp @@ -102,8 +102,7 @@ LLNetMap::LLNetMap (const Params & p) mObjectImagep(), mClosestAgentToCursor(), mClosestAgentAtLastRightClick(), - mToolTipMsg(), - mPopupMenu(NULL) + mToolTipMsg() { mScale = gSavedSettings.getF32("MiniMapScale"); if (gAgent.isFirstLogin()) @@ -119,6 +118,12 @@ LLNetMap::LLNetMap (const Params & p) LLNetMap::~LLNetMap() { + auto menu = static_cast<LLMenuGL*>(mPopupMenuHandle.get()); + if (menu) + { + menu->die(); + mPopupMenuHandle.markDead(); + } } BOOL LLNetMap::postBuild() @@ -134,11 +139,10 @@ BOOL LLNetMap::postBuild() commitRegistrar.add("Minimap.MapOrientation.Set", boost::bind(&LLNetMap::setMapOrientation, this, _2)); commitRegistrar.add("Minimap.AboutLand", boost::bind(&LLNetMap::popupShowAboutLand, this, _2)); - mPopupMenu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>("menu_mini_map.xml", gMenuHolder, - LLViewerMenuHolderGL::child_registry_t::instance()); - mPopupMenu->setItemEnabled("Re-center map", false); - - return true; + LLMenuGL* menu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>("menu_mini_map.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); + mPopupMenuHandle = menu->getHandle(); + menu->setItemEnabled("Re-center map", false); + return TRUE; } void LLNetMap::setScale( F32 scale ) @@ -206,8 +210,12 @@ void LLNetMap::draw() mCentering = false; } - bool can_recenter_map = !(centered || mCentering || auto_centering); - mPopupMenu->setItemEnabled("Re-center map", can_recenter_map); + auto menu = static_cast<LLMenuGL*>(mPopupMenuHandle.get()); + if (menu) + { + bool can_recenter_map = !(centered || mCentering || auto_centering); + menu->setItemEnabled("Re-center map", can_recenter_map); + } updateAboutLandPopupButton(); // Prepare a scissor region @@ -595,14 +603,15 @@ void LLNetMap::drawTracking(const LLVector3d& pos_global, const LLColor4& color, bool LLNetMap::isMouseOnPopupMenu() { - if (!mPopupMenu->isOpen()) + auto menu = static_cast<LLMenuGL*>(mPopupMenuHandle.get()); + if (!menu || !menu->isOpen()) { return false; } S32 popup_x; S32 popup_y; - LLUI::getInstance()->getMousePositionLocal(mPopupMenu, &popup_x, &popup_y); + LLUI::getInstance()->getMousePositionLocal(menu, &popup_x, &popup_y); // *NOTE: Tolerance is larger than it needs to be because the context menu is offset from the mouse when the menu is opened from certain // directions. This may be a quirk of LLMenuGL::showPopup. -Cosmic,2022-03-22 constexpr S32 tolerance = 10; @@ -613,7 +622,7 @@ bool LLNetMap::isMouseOnPopupMenu() { for (S32 sign_y = -1; sign_y <= 1; sign_y += 2) { - if (mPopupMenu->pointInView(popup_x + (sign_x * tolerance), popup_y + (sign_y * tolerance))) + if (menu->pointInView(popup_x + (sign_x * tolerance), popup_y + (sign_y * tolerance))) { return true; } @@ -624,7 +633,8 @@ bool LLNetMap::isMouseOnPopupMenu() void LLNetMap::updateAboutLandPopupButton() { - if (!mPopupMenu->isOpen()) + auto menu = static_cast<LLMenuGL*>(mPopupMenuHandle.get()); + if (!menu || !menu->isOpen()) { return; } @@ -632,7 +642,7 @@ void LLNetMap::updateAboutLandPopupButton() LLViewerRegion *region = LLWorld::getInstance()->getRegionFromPosGlobal(mPopupWorldPos); if (!region) { - mPopupMenu->setItemEnabled("About Land", false); + menu->setItemEnabled("About Land", false); } else { @@ -647,7 +657,7 @@ void LLNetMap::updateAboutLandPopupButton() { valid_parcel = hover_parcel->getOwnerID().notNull(); } - mPopupMenu->setItemEnabled("About Land", valid_parcel); + menu->setItemEnabled("About Land", valid_parcel); } } } @@ -1043,13 +1053,14 @@ BOOL LLNetMap::handleMouseUp(S32 x, S32 y, MASK mask) BOOL LLNetMap::handleRightMouseDown(S32 x, S32 y, MASK mask) { - if (mPopupMenu) + auto menu = static_cast<LLMenuGL*>(mPopupMenuHandle.get()); + if (menu) { - mPopupWorldPos = viewPosToGlobal(x, y); - mPopupMenu->buildDrawLabels(); - mPopupMenu->updateParent(LLMenuGL::sMenuContainer); - mPopupMenu->setItemEnabled("Stop tracking", LLTracker::isTracking(0)); - LLMenuGL::showPopup(this, mPopupMenu, x, y); + mPopupWorldPos = viewPosToGlobal(x, y); + menu->buildDrawLabels(); + menu->updateParent(LLMenuGL::sMenuContainer); + menu->setItemEnabled("Stop Tracking", LLTracker::isTracking(0)); + LLMenuGL::showPopup(this, menu, x, y); } return TRUE; } @@ -1182,9 +1193,10 @@ void LLNetMap::setZoom(const LLSD &userdata) void LLNetMap::handleStopTracking (const LLSD& userdata) { - if (mPopupMenu) + auto menu = static_cast<LLMenuGL*>(mPopupMenuHandle.get()); + if (menu) { - mPopupMenu->setItemEnabled ("Stop tracking", false); + menu->setItemEnabled ("Stop Tracking", false); LLTracker::stopTracking (LLTracker::isTracking(NULL)); } } diff --git a/indra/newview/llnetmap.h b/indra/newview/llnetmap.h index fe1aca65a9..75c1abc4ed 100644 --- a/indra/newview/llnetmap.h +++ b/indra/newview/llnetmap.h @@ -162,7 +162,7 @@ private: void setMapOrientation(const LLSD& userdata); void popupShowAboutLand(const LLSD& userdata); - LLMenuGL* mPopupMenu; + LLHandle<LLView> mPopupMenuHandle; uuid_vec_t gmSelected; }; diff --git a/indra/newview/llnotificationhandlerutil.cpp b/indra/newview/llnotificationhandlerutil.cpp index 39a0b9b50e..85adfaab55 100644 --- a/indra/newview/llnotificationhandlerutil.cpp +++ b/indra/newview/llnotificationhandlerutil.cpp @@ -275,7 +275,7 @@ void LLHandlerUtil::addNotifPanelToIM(const LLNotificationPtr& notification) LLSD offer; offer["notification_id"] = notification->getID(); offer["from"] = SYSTEM_FROM; - offer["time"] = LLLogChat::timestamp(false); + offer["time"] = LLLogChat::timestamp2LogString(0, false); // Use current time offer["index"] = (LLSD::Integer)session->mMsgs.size(); session->mMsgs.push_front(offer); diff --git a/indra/newview/llnotificationlistitem.cpp b/indra/newview/llnotificationlistitem.cpp index 6a79a0c68c..f86edfd0cf 100644 --- a/indra/newview/llnotificationlistitem.cpp +++ b/indra/newview/llnotificationlistitem.cpp @@ -521,8 +521,6 @@ void LLGroupNoticeNotificationListItem::close() void LLGroupNoticeNotificationListItem::onClickAttachment() { if (mInventoryOffer != NULL) { - mInventoryOffer->forceResponse(IOR_ACCEPT); - static const LLUIColor textColor = LLUIColorTable::instance().getColor( "GroupNotifyDimmedTextColor"); mAttachmentTextBox->setColor(textColor); @@ -532,7 +530,7 @@ void LLGroupNoticeNotificationListItem::onClickAttachment() if (!isAttachmentOpenable(mInventoryOffer->mType)) { LLNotifications::instance().add("AttachmentSaved", LLSD(), LLSD()); } - + mInventoryOffer->forceResponse(IOR_ACCEPT); mInventoryOffer = NULL; } } diff --git a/indra/newview/lloutfitgallery.cpp b/indra/newview/lloutfitgallery.cpp index 1facbbf37c..602b7412a4 100644 --- a/indra/newview/lloutfitgallery.cpp +++ b/indra/newview/lloutfitgallery.cpp @@ -1226,7 +1226,7 @@ void LLOutfitGallery::uploadOutfitImage(const std::vector<std::string>& filename checkRemovePhoto(outfit_id); std::string upload_pending_name = outfit_id.asString(); std::string upload_pending_desc = ""; - LLUUID photo_id = upload_new_resource(filename, // file + upload_new_resource(filename, // file upload_pending_name, upload_pending_desc, 0, LLFolderType::FT_NONE, LLInventoryType::IT_NONE, diff --git a/indra/newview/lloutfitslist.cpp b/indra/newview/lloutfitslist.cpp index 7270580032..4171fd8822 100644 --- a/indra/newview/lloutfitslist.cpp +++ b/indra/newview/lloutfitslist.cpp @@ -823,8 +823,7 @@ void LLOutfitListBase::onOpen(const LLSD& info) mCategoriesObserver->addCategory(outfits, boost::bind(&LLOutfitListBase::refreshList, this, outfits)); - const LLUUID cof = gInventory.findCategoryUUIDForType(LLFolderType::FT_CURRENT_OUTFIT); - + //const LLUUID cof = gInventory.findCategoryUUIDForType(LLFolderType::FT_CURRENT_OUTFIT); // Start observing changes in Current Outfit category. //mCategoriesObserver->addCategory(cof, boost::bind(&LLOutfitsList::onCOFChanged, this)); diff --git a/indra/newview/llpaneleditwearable.cpp b/indra/newview/llpaneleditwearable.cpp index ea10aa75ae..0103bf628a 100644 --- a/indra/newview/llpaneleditwearable.cpp +++ b/indra/newview/llpaneleditwearable.cpp @@ -1663,7 +1663,7 @@ void LLPanelEditWearable::initPreviousAlphaTextureEntry(LLAvatarAppearanceDefine class LLMetricSystemHandler : public LLCommandHandler { public: - LLMetricSystemHandler() : LLCommandHandler("metricsystem", UNTRUSTED_THROTTLE) { } + LLMetricSystemHandler() : LLCommandHandler("metricsystem", UNTRUSTED_CLICK_ONLY) { } bool handle(const LLSD& params, const LLSD& query_map, LLMediaCtrl* web) { diff --git a/indra/newview/llpanelexperiencelog.cpp b/indra/newview/llpanelexperiencelog.cpp index 44b4728df7..e5c637938f 100644 --- a/indra/newview/llpanelexperiencelog.cpp +++ b/indra/newview/llpanelexperiencelog.cpp @@ -112,7 +112,7 @@ void LLPanelExperienceLog::refresh() int items = 0; bool moreItems = false; LLSD events_to_save = events; - if (!events.emptyMap()) + if (events.isMap() && events.size() != 0) { LLSD::map_const_iterator day = events.endMap(); do diff --git a/indra/newview/llpanellandmedia.cpp b/indra/newview/llpanellandmedia.cpp index 26cd3ff1c1..e379d67e37 100644 --- a/indra/newview/llpanellandmedia.cpp +++ b/indra/newview/llpanellandmedia.cpp @@ -179,7 +179,6 @@ void LLPanelLandMedia::refresh() // enable/disable for text label for completeness mMediaSizeCtrlLabel->setEnabled( can_change_media && allow_resize ); - LLUUID tmp = parcel->getMediaID(); mMediaTextureCtrl->setImageAssetID ( parcel->getMediaID() ); mMediaTextureCtrl->setEnabled( can_change_media ); diff --git a/indra/newview/llpanellogin.cpp b/indra/newview/llpanellogin.cpp index 9df3a8e31a..b14fdbf38e 100644 --- a/indra/newview/llpanellogin.cpp +++ b/indra/newview/llpanellogin.cpp @@ -1103,6 +1103,18 @@ void LLPanelLogin::onRememberPasswordCheck(void*) if (sInstance) { gSavedSettings.setBOOL("UpdateRememberPasswordSetting", TRUE); + + LLPointer<LLCredential> cred; + bool remember_user, remember_password; + getFields(cred, remember_user, remember_password); + + std::string grid(LLGridManager::getInstance()->getGridId()); + std::string user_id(cred->userID()); + if (!remember_password) + { + gSecAPIHandler->removeFromProtectedMap("mfa_hash", grid, user_id); + gSecAPIHandler->syncProtectedMap(); + } } } diff --git a/indra/newview/llpanelmaininventory.cpp b/indra/newview/llpanelmaininventory.cpp index 89256b40c4..744d49ff57 100644 --- a/indra/newview/llpanelmaininventory.cpp +++ b/indra/newview/llpanelmaininventory.cpp @@ -307,6 +307,13 @@ LLPanelMainInventory::~LLPanelMainInventory( void ) gInventory.removeObserver(this); delete mSavedFolderState; + + auto menu = mMenuAddHandle.get(); + if(menu) + { + menu->die(); + mMenuAddHandle.markDead(); + } } LLInventoryPanel* LLPanelMainInventory::getAllItemsPanel() @@ -403,6 +410,18 @@ void LLPanelMainInventory::resetFilters() setFilterTextFromFilter(); } +void LLPanelMainInventory::resetAllItemsFilters() +{ + LLFloaterInventoryFinder *finder = getFinder(); + getAllItemsPanel()->getFilter().resetDefault(); + if (finder) + { + finder->updateElementsFromFilter(); + } + + setFilterTextFromFilter(); +} + void LLPanelMainInventory::setSortBy(const LLSD& userdata) { U32 sort_order_mask = getActivePanel()->getSortOrder(); @@ -1177,13 +1196,12 @@ void LLPanelMainInventory::initListCommandsHandlers() mEnableCallbackRegistrar.add("Inventory.GearDefault.Check", boost::bind(&LLPanelMainInventory::isActionChecked, this, _2)); mEnableCallbackRegistrar.add("Inventory.GearDefault.Enable", boost::bind(&LLPanelMainInventory::isActionEnabled, this, _2)); mMenuGearDefault = LLUICtrlFactory::getInstance()->createFromFile<LLToggleableMenu>("menu_inventory_gear_default.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); - mGearMenuButton->setMenu(mMenuGearDefault); + mGearMenuButton->setMenu(mMenuGearDefault, LLMenuButton::MP_TOP_LEFT, true); LLMenuGL* menu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>("menu_inventory_add.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); mMenuAddHandle = menu->getHandle(); mMenuVisibility = LLUICtrlFactory::getInstance()->createFromFile<LLToggleableMenu>("menu_inventory_search_visibility.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); - mVisibilityMenuButton->setMenu(mMenuVisibility); - mVisibilityMenuButton->setMenuPosition(LLMenuButton::MP_BOTTOM_LEFT); + mVisibilityMenuButton->setMenu(mMenuVisibility, LLMenuButton::MP_BOTTOM_LEFT, true); // Update the trash button when selected item(s) get worn or taken off. LLOutfitObserver::instance().addCOFChangedCallback(boost::bind(&LLPanelMainInventory::updateListCommands, this)); diff --git a/indra/newview/llpanelmaininventory.h b/indra/newview/llpanelmaininventory.h index 257bce930c..7aae5a0b3c 100644 --- a/indra/newview/llpanelmaininventory.h +++ b/indra/newview/llpanelmaininventory.h @@ -96,6 +96,7 @@ public: void toggleFindOptions(); void resetFilters(); + void resetAllItemsFilters(); protected: // diff --git a/indra/newview/llpanelmediasettingsgeneral.cpp b/indra/newview/llpanelmediasettingsgeneral.cpp index 416857bd30..8380394f2c 100644 --- a/indra/newview/llpanelmediasettingsgeneral.cpp +++ b/indra/newview/llpanelmediasettingsgeneral.cpp @@ -39,6 +39,7 @@ #include "llagent.h" #include "llviewerwindow.h" #include "llviewermedia.h" +#include "llvovolume.h" #include "llsdutil.h" #include "llselectmgr.h" #include "llbutton.h" @@ -452,10 +453,17 @@ bool LLPanelMediaSettingsGeneral::navigateHomeSelectedFace(bool only_if_current_ { viewer_media_t media_impl = LLViewerMedia::getInstance()->getMediaImplFromTextureID(object->getTE(face)->getMediaData()->getMediaID()); - if(media_impl) - { + if (media_impl) + { media_impl->setPriority(LLPluginClassMedia::PRIORITY_NORMAL); media_impl->navigateHome(); + + if (!only_if_current_is_empty) + { + LLSD media_data; + media_data[LLMediaEntry::CURRENT_URL_KEY] = std::string(); + object->getTE(face)->mergeIntoMediaData(media_data); + } return true; } } @@ -471,6 +479,23 @@ bool LLPanelMediaSettingsGeneral::navigateHomeSelectedFace(bool only_if_current_ LLObjectSelectionHandle selected_objects =LLSelectMgr::getInstance()->getSelection(); selected_objects->getSelectedTEValue( &functor_navigate_media, all_face_media_navigated ); + if (all_face_media_navigated) + { + struct functor_sync_to_server : public LLSelectedObjectFunctor + { + virtual bool apply(LLViewerObject* object) + { + LLVOVolume *volume = dynamic_cast<LLVOVolume*>(object); + if (volume) + { + volume->sendMediaDataUpdate(); + } + return true; + } + } sendfunc; + selected_objects->applyToObjects(&sendfunc); + } + // Note: we don't update the 'current URL' field until the media data itself changes return all_face_media_navigated; diff --git a/indra/newview/llpanelobject.cpp b/indra/newview/llpanelobject.cpp index bc7933d84b..2da431955f 100644 --- a/indra/newview/llpanelobject.cpp +++ b/indra/newview/llpanelobject.cpp @@ -2131,7 +2131,7 @@ bool LLPanelObject::menuEnableItem(const LLSD& userdata) } else if (command == "params_paste") { - return mClipboardParams.isMap() && !mClipboardParams.emptyMap(); + return mClipboardParams.isMap() && (mClipboardParams.size() != 0); } // copy options else if (command == "psr_copy") diff --git a/indra/newview/llpanelobjectinventory.cpp b/indra/newview/llpanelobjectinventory.cpp index fff25c6c61..bd40c9dd2b 100644 --- a/indra/newview/llpanelobjectinventory.cpp +++ b/indra/newview/llpanelobjectinventory.cpp @@ -1275,7 +1275,8 @@ LLPanelObjectInventory::LLPanelObjectInventory(const LLPanelObjectInventory::Par mHaveInventory(FALSE), mIsInventoryEmpty(TRUE), mInventoryNeedsUpdate(FALSE), - mInventoryViewModel(p.name) + mInventoryViewModel(p.name), + mShowRootFolder(p.show_root_folder) { // Setup context menu callbacks mCommitCallbackRegistrar.add("Inventory.DoToSelected", boost::bind(&LLPanelObjectInventory::doToSelected, this, _2)); @@ -1360,6 +1361,7 @@ void LLPanelObjectInventory::reset() mFolders = LLUICtrlFactory::create<LLFolderView>(p); mFolders->setCallbackRegistrar(&mCommitCallbackRegistrar); + mFolders->setEnableRegistrar(&mEnableCallbackRegistrar); if (hasFocus()) { @@ -1526,15 +1528,23 @@ void LLPanelObjectInventory::createFolderViews(LLInventoryObject* inventory_root p.font_highlight_color = item_color; LLFolderViewFolder* new_folder = LLUICtrlFactory::create<LLFolderViewFolder>(p); - new_folder->addToFolder(mFolders); - new_folder->toggleOpen(); + + if (mShowRootFolder) + { + new_folder->addToFolder(mFolders); + new_folder->toggleOpen(); + } if (!contents.empty()) { - createViewsForCategory(&contents, inventory_root, new_folder); + createViewsForCategory(&contents, inventory_root, mShowRootFolder ? new_folder : mFolders); } - // Refresh for label to add item count - new_folder->refresh(); + + if (mShowRootFolder) + { + // Refresh for label to add item count + new_folder->refresh(); + } } } diff --git a/indra/newview/llpanelobjectinventory.h b/indra/newview/llpanelobjectinventory.h index 7b9ecfb8f3..0e450d8ce9 100644 --- a/indra/newview/llpanelobjectinventory.h +++ b/indra/newview/llpanelobjectinventory.h @@ -48,8 +48,14 @@ class LLViewerObject; class LLPanelObjectInventory : public LLPanel, public LLVOInventoryListener { public: - // dummy param block for template registration purposes - struct Params : public LLPanel::Params {}; + struct Params : public LLInitParam::Block<Params, LLPanel::Params> + { + Optional<bool> show_root_folder; + + Params() + : show_root_folder("show_root_folder", true) + {} + }; LLPanelObjectInventory(const Params&); virtual ~LLPanelObjectInventory(); @@ -110,6 +116,7 @@ private: BOOL mIsInventoryEmpty; // 'Empty' label BOOL mInventoryNeedsUpdate; // for idle, set on changed callback LLFolderViewModelInventory mInventoryViewModel; + bool mShowRootFolder; }; #endif // LL_LLPANELOBJECTINVENTORY_H diff --git a/indra/newview/llpanelplaces.cpp b/indra/newview/llpanelplaces.cpp index 74ec576554..0f00231643 100644 --- a/indra/newview/llpanelplaces.cpp +++ b/indra/newview/llpanelplaces.cpp @@ -800,7 +800,6 @@ void LLPanelPlaces::onSaveButtonClicked() LLStringUtil::trim(current_title_value); LLStringUtil::trim(current_notes_value); - LLUUID item_id = mItem->getUUID(); LLUUID folder_id = mLandmarkInfo->getLandmarkFolder(); bool change_parent = folder_id != mItem->getParentUUID(); diff --git a/indra/newview/llpanelprofile.cpp b/indra/newview/llpanelprofile.cpp index f4eaa78f11..708ff26ced 100644 --- a/indra/newview/llpanelprofile.cpp +++ b/indra/newview/llpanelprofile.cpp @@ -484,6 +484,30 @@ public: // requires trusted browser to trigger LLAgentHandler() : LLCommandHandler("agent", UNTRUSTED_THROTTLE) { } + virtual bool canHandleUntrusted( + const LLSD& params, + const LLSD& query_map, + LLMediaCtrl* web, + const std::string& nav_type) + { + if (params.size() < 2) + { + return true; // don't block, will fail later + } + + if (nav_type == NAV_TYPE_CLICKED) + { + return true; + } + + const std::string verb = params[1].asString(); + if (verb == "about" || verb == "inspect" || verb == "reportAbuse") + { + return true; + } + return false; + } + bool handle(const LLSD& params, const LLSD& query_map, LLMediaCtrl* web) { @@ -1031,7 +1055,6 @@ void LLPanelProfileSecondLife::resetData() void LLPanelProfileSecondLife::processProfileProperties(const LLAvatarData* avatar_data) { - LLUUID avatar_id = getAvatarId(); const LLRelationship* relationship = LLAvatarTracker::instance().getBuddyInfo(getAvatarId()); if ((relationship != NULL || gAgent.isGodlike()) && !getSelfProfile()) { @@ -1280,6 +1303,8 @@ void LLPanelProfileSecondLife::fillRightsData() void LLPanelProfileSecondLife::fillAgeData(const LLDate &born_on) { + // Date from server comes already converted to stl timezone, + // so display it as an UTC + 0 std::string name_and_date = getString("date_format"); LLSD args_name; args_name["datetime"] = (S32)born_on.secondsSinceEpoch(); diff --git a/indra/newview/llpanelprofileclassifieds.cpp b/indra/newview/llpanelprofileclassifieds.cpp index a3913ddc49..1ff12b4f37 100644 --- a/indra/newview/llpanelprofileclassifieds.cpp +++ b/indra/newview/llpanelprofileclassifieds.cpp @@ -81,6 +81,30 @@ public: std::set<LLUUID> mClassifiedIds; std::string mRequestVerb; + + virtual bool canHandleUntrusted( + const LLSD& params, + const LLSD& query_map, + LLMediaCtrl* web, + const std::string& nav_type) + { + if (params.size() < 1) + { + return true; // don't block, will fail later + } + + if (nav_type == NAV_TYPE_CLICKED) + { + return true; + } + + const std::string verb = params[0].asString(); + if (verb == "create") + { + return false; + } + return true; + } bool handle(const LLSD& params, const LLSD& query_map, LLMediaCtrl* web) { diff --git a/indra/newview/llpanelprofilepicks.cpp b/indra/newview/llpanelprofilepicks.cpp index 774119f169..45d0252e4f 100644 --- a/indra/newview/llpanelprofilepicks.cpp +++ b/indra/newview/llpanelprofilepicks.cpp @@ -63,6 +63,30 @@ public: // requires trusted browser to trigger LLPickHandler() : LLCommandHandler("pick", UNTRUSTED_THROTTLE) { } + virtual bool canHandleUntrusted( + const LLSD& params, + const LLSD& query_map, + LLMediaCtrl* web, + const std::string& nav_type) + { + if (params.size() < 1) + { + return true; // don't block, will fail later + } + + if (nav_type == NAV_TYPE_CLICKED) + { + return true; + } + + const std::string verb = params[0].asString(); + if (verb == "create") + { + return false; + } + return true; + } + bool handle(const LLSD& params, const LLSD& query_map, LLMediaCtrl* web) { diff --git a/indra/newview/llpreviewnotecard.cpp b/indra/newview/llpreviewnotecard.cpp index ac6167ec01..095d5a0a1e 100644 --- a/indra/newview/llpreviewnotecard.cpp +++ b/indra/newview/llpreviewnotecard.cpp @@ -257,7 +257,7 @@ void LLPreviewNotecard::loadAsset() else { LLHost source_sim = LLHost(); - LLSD* user_data = new LLSD(); + LLSD* user_data = nullptr; if (mObjectUUID.notNull()) { LLViewerObject *objectp = gObjectList.findObject(mObjectUUID); @@ -276,6 +276,7 @@ void LLPreviewNotecard::loadAsset() mAssetStatus = PREVIEW_ASSET_LOADED; return; } + user_data = new LLSD(); user_data->with("taskid", mObjectUUID).with("itemid", mItemUUID); } else diff --git a/indra/newview/llscenemonitor.cpp b/indra/newview/llscenemonitor.cpp index 2e44dc1459..7089df677e 100644 --- a/indra/newview/llscenemonitor.cpp +++ b/indra/newview/llscenemonitor.cpp @@ -515,7 +515,7 @@ void LLSceneMonitor::fetchQueryResult() } //dump results to a file _scene_xmonitor_results.csv -void LLSceneMonitor::dumpToFile(std::string file_name) +void LLSceneMonitor::dumpToFile(const std::string &file_name) { if (!hasResults()) return; diff --git a/indra/newview/llscenemonitor.h b/indra/newview/llscenemonitor.h index 7cd531bd34..f2e1ef69b9 100644 --- a/indra/newview/llscenemonitor.h +++ b/indra/newview/llscenemonitor.h @@ -61,7 +61,7 @@ public: bool needsUpdate() const; const LLTrace::ExtendablePeriodicRecording* getRecording() const {return &mSceneLoadRecording;} - void dumpToFile(std::string file_name); + void dumpToFile(const std::string &file_name); bool hasResults() const { return mSceneLoadRecording.getResults().getDuration() != S32Seconds(0);} void reset(); diff --git a/indra/newview/llsceneview.cpp b/indra/newview/llsceneview.cpp index e250f9bc7a..5e339a52bf 100644 --- a/indra/newview/llsceneview.cpp +++ b/indra/newview/llsceneview.cpp @@ -207,7 +207,7 @@ void LLSceneView::draw() for (U32 i = 0; i < count; ++i) { F32 rad = size[idx][i]; - total += rad; + total += rad; F32 y = (rad-size_domain[0])/size_range*size_rect.getHeight()+size_rect.mBottom; F32 x = (F32) i / count * size_rect.getWidth() + size_rect.mLeft; diff --git a/indra/newview/llscriptfloater.cpp b/indra/newview/llscriptfloater.cpp index da912ef3d4..6a27ff3047 100644 --- a/indra/newview/llscriptfloater.cpp +++ b/indra/newview/llscriptfloater.cpp @@ -460,10 +460,11 @@ void LLScriptFloaterManager::onAddNotification(const LLUUID& notification_id) if(it != mNotifications.end()) { + LLUUID old_id = it->first; // copy LLUUID to prevent use after free when it is erased below LLChicletPanel * chiclet_panelp = LLChicletBar::getInstance()->getChicletPanel(); if (NULL != chiclet_panelp) { - LLIMChiclet * chicletp = chiclet_panelp->findChiclet<LLIMChiclet>(it->first); + LLIMChiclet * chicletp = chiclet_panelp->findChiclet<LLIMChiclet>(old_id); if (NULL != chicletp) { // Pass the new_message icon state further. @@ -472,14 +473,14 @@ void LLScriptFloaterManager::onAddNotification(const LLUUID& notification_id) } } - LLScriptFloater* floater = LLFloaterReg::findTypedInstance<LLScriptFloater>("script_floater", it->first); + LLScriptFloater* floater = LLFloaterReg::findTypedInstance<LLScriptFloater>("script_floater", old_id); if (floater) { // Generate chiclet with a "new message" indicator if a docked window was opened but not in focus. See EXT-3142. set_new_message |= !floater->hasFocus(); } - removeNotification(it->first); + removeNotification(old_id); } } diff --git a/indra/newview/llsechandler_basic.cpp b/indra/newview/llsechandler_basic.cpp index d0da3387ec..8e8f2f4fe0 100644 --- a/indra/newview/llsechandler_basic.cpp +++ b/indra/newview/llsechandler_basic.cpp @@ -355,7 +355,7 @@ LLSD cert_name_from_X509_NAME(X509_NAME* name) char buffer[32]; X509_NAME_ENTRY *entry = X509_NAME_get_entry(name, entry_index); - std::string name_value = std::string((const char*)ASN1_STRING_data(X509_NAME_ENTRY_get_data(entry)), + std::string name_value = std::string((const char*)ASN1_STRING_get0_data(X509_NAME_ENTRY_get_data(entry)), ASN1_STRING_length(X509_NAME_ENTRY_get_data(entry))); ASN1_OBJECT* name_obj = X509_NAME_ENTRY_get_object(entry); diff --git a/indra/newview/llsettingsvo.cpp b/indra/newview/llsettingsvo.cpp index 7c762170a7..707b602fc6 100644 --- a/indra/newview/llsettingsvo.cpp +++ b/indra/newview/llsettingsvo.cpp @@ -694,8 +694,8 @@ void LLSettingsVOSky::applySpecial(void *ptarget, bool force) LLSettingsSky::ptr_t psky = LLEnvironment::instance().getCurrentSky(); - LLVector4 sunDiffuse = LLVector4(psky->getSunlightColor().mV); - LLVector4 moonDiffuse = LLVector4(psky->getMoonlightColor().mV); + LLVector4 sunDiffuse = LLVector4(LLVector3(psky->getSunlightColor().mV)); + LLVector4 moonDiffuse = LLVector4(LLVector3(psky->getMoonlightColor().mV)); shader->uniform4fv(LLShaderMgr::SUNLIGHT_COLOR, sunDiffuse); shader->uniform4fv(LLShaderMgr::MOONLIGHT_COLOR, moonDiffuse); diff --git a/indra/newview/llskinningutil.cpp b/indra/newview/llskinningutil.cpp index cf3519c1c7..8bdccfd9f6 100644 --- a/indra/newview/llskinningutil.cpp +++ b/indra/newview/llskinningutil.cpp @@ -264,6 +264,9 @@ void LLSkinningUtil::getPerVertexSkinMatrix( // SL-366 - with weight validation/cleanup code, it should no longer be // possible to hit the bad scale case. llassert(valid_weights); + // When building for Release, the above llassert() goes away. Ward off + // variable-set-but-unused error. + (void)valid_weights; } void LLSkinningUtil::initJointNums(LLMeshSkinInfo* skin, LLVOAvatar *avatar) diff --git a/indra/newview/llspeakers.cpp b/indra/newview/llspeakers.cpp index ea671a130e..60bada8f58 100644 --- a/indra/newview/llspeakers.cpp +++ b/indra/newview/llspeakers.cpp @@ -982,7 +982,6 @@ void LLActiveSpeakerMgr::updateSpeakerList() // clean up text only speakers for (speaker_map_t::iterator speaker_it = mSpeakers.begin(); speaker_it != mSpeakers.end(); ++speaker_it) { - LLUUID speaker_id = speaker_it->first; LLSpeaker* speakerp = speaker_it->second; if (speakerp->mStatus == LLSpeaker::STATUS_TEXT_ONLY) { diff --git a/indra/newview/llspeakingindicatormanager.cpp b/indra/newview/llspeakingindicatormanager.cpp index 5ca1d4b4a5..0111d8869c 100644 --- a/indra/newview/llspeakingindicatormanager.cpp +++ b/indra/newview/llspeakingindicatormanager.cpp @@ -51,6 +51,10 @@ class SpeakingIndicatorManager : public LLSingleton<SpeakingIndicatorManager>, L LLSINGLETON(SpeakingIndicatorManager); ~SpeakingIndicatorManager(); LOG_CLASS(SpeakingIndicatorManager); + +protected: + void cleanupSingleton(); + public: /** @@ -183,12 +187,16 @@ SpeakingIndicatorManager::SpeakingIndicatorManager() SpeakingIndicatorManager::~SpeakingIndicatorManager() { - // Don't use LLVoiceClient::getInstance() here without check - // singleton MAY have already been destroyed. - if(LLVoiceClient::instanceExists()) - { - LLVoiceClient::getInstance()->removeObserver(this); - } +} + +void SpeakingIndicatorManager::cleanupSingleton() +{ + // Don't use LLVoiceClient::getInstance() here without a check, + // singleton MAY have already been destroyed. + if (LLVoiceClient::instanceExists()) + { + LLVoiceClient::getInstance()->removeObserver(this); + } } void SpeakingIndicatorManager::sOnCurrentChannelChanged(const LLUUID& /*session_id*/) diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp index 1dd5c5cbe5..6883ead5ee 100644 --- a/indra/newview/llstartup.cpp +++ b/indra/newview/llstartup.cpp @@ -272,12 +272,10 @@ void show_first_run_dialog(); bool first_run_dialog_callback(const LLSD& notification, const LLSD& response); void set_startup_status(const F32 frac, const std::string& string, const std::string& msg); bool login_alert_status(const LLSD& notification, const LLSD& response); -void login_packet_failed(void**, S32 result); void use_circuit_callback(void**, S32 result); void register_viewer_callbacks(LLMessageSystem* msg); void asset_callback_nothing(const LLUUID&, LLAssetType::EType, void*, S32); bool callback_choose_gender(const LLSD& notification, const LLSD& response); -void init_start_screen(S32 location_id); void release_start_screen(); void reset_login(); LLSD transform_cert_args(LLPointer<LLCertificate> cert); diff --git a/indra/newview/lltoast.h b/indra/newview/lltoast.h index 69074b1670..ab559f1e6f 100644 --- a/indra/newview/lltoast.h +++ b/indra/newview/lltoast.h @@ -35,6 +35,7 @@ #include "llviewercontrol.h" #include "lltexteditor.h" +#include <memory> #define MOUSE_LEAVE false #define MOUSE_ENTER true @@ -222,7 +223,7 @@ private: LLPanel* mWrapperPanel; // timer counts a lifetime of a toast - std::auto_ptr<LLToastLifeTimer> mTimer; + std::unique_ptr<LLToastLifeTimer> mTimer; F32 mToastLifetime; // in seconds F32 mToastFadingTime; // in seconds diff --git a/indra/newview/lltoastnotifypanel.cpp b/indra/newview/lltoastnotifypanel.cpp index 024f25bc98..bf3f4c1e88 100644 --- a/indra/newview/lltoastnotifypanel.cpp +++ b/indra/newview/lltoastnotifypanel.cpp @@ -89,6 +89,7 @@ LLButton* LLToastNotifyPanel::createButton(const LLSD& form_element, BOOL is_opt const LLFontGL* font = make_small_btn ? sFontSmall: sFont; // for block and ignore buttons in script dialog p.name = form_element["name"].asString(); p.label = form_element["text"].asString(); + p.tool_tip = form_element["text"].asString(); p.font = font; p.rect.height = BTN_HEIGHT; p.click_callback.function(boost::bind(&LLToastNotifyPanel::onClickButton, userdata)); diff --git a/indra/newview/lltoolbarview.cpp b/indra/newview/lltoolbarview.cpp index 752fc6f3f3..01d799dcd5 100644 --- a/indra/newview/lltoolbarview.cpp +++ b/indra/newview/lltoolbarview.cpp @@ -44,7 +44,6 @@ #include "llagent.h" // HACK for destinations guide on startup #include "llfloaterreg.h" // HACK for destinations guide on startup #include "llviewercontrol.h" // HACK for destinations guide on startup -#include "llinventorymodel.h" // HACK to disable starter avatars button for NUX #include <boost/foreach.hpp> @@ -320,22 +319,6 @@ bool LLToolBarView::loadToolbars(bool force_default) } } } - - // SL-18581: Don't show the starter avatar toolbar button for NUX users - LLViewerInventoryCategory* my_outfits_cat = gInventory.getCategory(gInventory.findCategoryUUIDForType(LLFolderType::FT_MY_OUTFITS)); - if (gAgent.isFirstLogin() - && my_outfits_cat != NULL - && my_outfits_cat->getDescendentCount() > 0) - { - for (S32 i = LLToolBarEnums::TOOLBAR_FIRST; i <= LLToolBarEnums::TOOLBAR_LAST; i++) - { - if (mToolbars[i]) - { - mToolbars[i]->removeCommand(LLCommandId("avatar")); - } - } - } - mToolbarsLoaded = true; return true; } diff --git a/indra/newview/lltoolfocus.cpp b/indra/newview/lltoolfocus.cpp index 07f46c5fbe..4e94895a3e 100644 --- a/indra/newview/lltoolfocus.cpp +++ b/indra/newview/lltoolfocus.cpp @@ -75,6 +75,7 @@ LLToolCamera::LLToolCamera() mOutsideSlopX(FALSE), mOutsideSlopY(FALSE), mValidClickPoint(FALSE), + mClickPickPending(false), mValidSelection(FALSE), mMouseSteering(FALSE), mMouseUpX(0), @@ -127,6 +128,11 @@ BOOL LLToolCamera::handleMouseDown(S32 x, S32 y, MASK mask) mValidClickPoint = FALSE; + // Sometimes Windows issues down and up events near simultaneously + // without giving async pick a chance to trigged + // Ex: mouse from numlock emulation + mClickPickPending = true; + // If mouse capture gets ripped away, claim we moused up // at the point we moused down. JC mMouseUpX = x; @@ -142,13 +148,15 @@ BOOL LLToolCamera::handleMouseDown(S32 x, S32 y, MASK mask) void LLToolCamera::pickCallback(const LLPickInfo& pick_info) { - if (!LLToolCamera::getInstance()->hasMouseCapture()) + LLToolCamera* camera = LLToolCamera::getInstance(); + if (!camera->mClickPickPending) { return; } + camera->mClickPickPending = false; - LLToolCamera::getInstance()->mMouseDownX = pick_info.mMousePt.mX; - LLToolCamera::getInstance()->mMouseDownY = pick_info.mMousePt.mY; + camera->mMouseDownX = pick_info.mMousePt.mX; + camera->mMouseDownY = pick_info.mMousePt.mY; gViewerWindow->moveCursorToCenter(); @@ -158,7 +166,7 @@ void LLToolCamera::pickCallback(const LLPickInfo& pick_info) // Check for hit the sky, or some other invalid point if (!hit_obj && pick_info.mPosGlobal.isExactlyZero()) { - LLToolCamera::getInstance()->mValidClickPoint = FALSE; + camera->mValidClickPoint = FALSE; return; } @@ -168,7 +176,7 @@ void LLToolCamera::pickCallback(const LLPickInfo& pick_info) LLObjectSelectionHandle selection = LLSelectMgr::getInstance()->getSelection(); if (!selection->getObjectCount() || selection->getSelectType() != SELECT_TYPE_HUD) { - LLToolCamera::getInstance()->mValidClickPoint = FALSE; + camera->mValidClickPoint = FALSE; return; } } @@ -192,7 +200,7 @@ void LLToolCamera::pickCallback(const LLPickInfo& pick_info) if( !good_customize_avatar_hit ) { - LLToolCamera::getInstance()->mValidClickPoint = FALSE; + camera->mValidClickPoint = FALSE; return; } @@ -237,7 +245,7 @@ void LLToolCamera::pickCallback(const LLPickInfo& pick_info) } - LLToolCamera::getInstance()->mValidClickPoint = TRUE; + camera->mValidClickPoint = TRUE; if( CAMERA_MODE_CUSTOMIZE_AVATAR == gAgentCamera.getCameraMode() ) { @@ -284,32 +292,36 @@ BOOL LLToolCamera::handleMouseUp(S32 x, S32 y, MASK mask) if (hasMouseCapture()) { - if (mValidClickPoint) - { - if( CAMERA_MODE_CUSTOMIZE_AVATAR == gAgentCamera.getCameraMode() ) - { - LLCoordGL mouse_pos; - LLVector3 focus_pos = gAgent.getPosAgentFromGlobal(gAgentCamera.getFocusGlobal()); - BOOL success = LLViewerCamera::getInstance()->projectPosAgentToScreen(focus_pos, mouse_pos); - if (success) - { - LLUI::getInstance()->setMousePositionScreen(mouse_pos.mX, mouse_pos.mY); - } - } - else if (mMouseSteering) - { - LLUI::getInstance()->setMousePositionScreen(mMouseDownX, mMouseDownY); - } - else - { - gViewerWindow->moveCursorToCenter(); - } - } - else - { - // not a valid zoomable object - LLUI::getInstance()->setMousePositionScreen(mMouseDownX, mMouseDownY); - } + // Do not move camera if we haven't gotten a pick + if (!mClickPickPending) + { + if (mValidClickPoint) + { + if (CAMERA_MODE_CUSTOMIZE_AVATAR == gAgentCamera.getCameraMode()) + { + LLCoordGL mouse_pos; + LLVector3 focus_pos = gAgent.getPosAgentFromGlobal(gAgentCamera.getFocusGlobal()); + BOOL success = LLViewerCamera::getInstance()->projectPosAgentToScreen(focus_pos, mouse_pos); + if (success) + { + LLUI::getInstance()->setMousePositionScreen(mouse_pos.mX, mouse_pos.mY); + } + } + else if (mMouseSteering) + { + LLUI::getInstance()->setMousePositionScreen(mMouseDownX, mMouseDownY); + } + else + { + gViewerWindow->moveCursorToCenter(); + } + } + else + { + // not a valid zoomable object + LLUI::getInstance()->setMousePositionScreen(mMouseDownX, mMouseDownY); + } + } // calls releaseMouse() internally setMouseCapture(FALSE); diff --git a/indra/newview/lltoolfocus.h b/indra/newview/lltoolfocus.h index cfc235b6c2..ef71f9230a 100644 --- a/indra/newview/lltoolfocus.h +++ b/indra/newview/lltoolfocus.h @@ -49,6 +49,7 @@ public: virtual LLTool* getOverrideTool(MASK mask) { return NULL; } + void setClickPickPending() { mClickPickPending = true; } static void pickCallback(const LLPickInfo& pick_info); BOOL mouseSteerMode() { return mMouseSteering; } @@ -65,6 +66,7 @@ protected: BOOL mOutsideSlopX; BOOL mOutsideSlopY; BOOL mValidClickPoint; + bool mClickPickPending; BOOL mValidSelection; BOOL mMouseSteering; S32 mMouseUpX; // needed for releaseMouse() diff --git a/indra/newview/lltoolpie.cpp b/indra/newview/lltoolpie.cpp index 5fb83bf08e..58011bbde2 100644 --- a/indra/newview/lltoolpie.cpp +++ b/indra/newview/lltoolpie.cpp @@ -443,6 +443,7 @@ BOOL LLToolPie::handleLeftClickPick() LLToolMgr::getInstance()->setTransientTool(LLToolCamera::getInstance()); gViewerWindow->hideCursor(); LLToolCamera::getInstance()->setMouseCapture(TRUE); + LLToolCamera::getInstance()->setClickPickPending(); LLToolCamera::getInstance()->pickCallback(mPick); gAgentCamera.setFocusOnAvatar(TRUE, TRUE); diff --git a/indra/newview/lltranslate.cpp b/indra/newview/lltranslate.cpp index a2c696c762..34d3ed8bb1 100644 --- a/indra/newview/lltranslate.cpp +++ b/indra/newview/lltranslate.cpp @@ -36,7 +36,7 @@ #include "llversioninfo.h" #include "llviewercontrol.h" #include "llcoros.h" -#include "reader.h" +#include "json/reader.h" #include "llcorehttputil.h" #include "llurlregistry.h" @@ -546,6 +546,18 @@ void LLBingTranslationHandler::verifyKey(const std::string &key, LLTranslate::Ke } //========================================================================= +LLTranslate::LLTranslate(): + mCharsSeen(0), + mCharsSent(0), + mFailureCount(0), + mSuccessCount(0) +{ +} + +LLTranslate::~LLTranslate() +{ +} + /*static*/ void LLTranslate::translateMessage(const std::string &from_lang, const std::string &to_lang, const std::string &mesg, TranslationSuccess_fn success, TranslationFailure_fn failure) @@ -634,6 +646,43 @@ bool LLTranslate::isTranslationConfigured() return getPreferredHandler().isConfigured(); } +void LLTranslate::logCharsSeen(size_t count) +{ + mCharsSeen += count; +} + +void LLTranslate::logCharsSent(size_t count) +{ + mCharsSent += count; +} + +void LLTranslate::logSuccess(S32 count) +{ + mSuccessCount += count; +} + +void LLTranslate::logFailure(S32 count) +{ + mFailureCount += count; +} + +LLSD LLTranslate::asLLSD() const +{ + LLSD res; + bool on = gSavedSettings.getBOOL("TranslateChat"); + res["on"] = on; + res["chars_seen"] = (S32) mCharsSeen; + if (on) + { + res["chars_sent"] = (S32) mCharsSent; + res["success_count"] = mSuccessCount; + res["failure_count"] = mFailureCount; + res["language"] = getTranslateLanguage(); + res["service"] = gSavedSettings.getString("TranslationService"); + } + return res; +} + // static LLTranslationAPIHandler& LLTranslate::getPreferredHandler() { diff --git a/indra/newview/lltranslate.h b/indra/newview/lltranslate.h index e0722fbd83..58707e2d36 100644 --- a/indra/newview/lltranslate.h +++ b/indra/newview/lltranslate.h @@ -30,6 +30,8 @@ #include "llbufferstream.h" #include <boost/function.hpp> +#include "llsingleton.h" + namespace Json { class Value; @@ -48,8 +50,10 @@ class LLTranslationAPIHandler; * * API keys for translation are taken from saved settings. */ -class LLTranslate +class LLTranslate: public LLSingleton<LLTranslate> { + LLSINGLETON(LLTranslate); + ~LLTranslate(); LOG_CLASS(LLTranslate); public : @@ -94,9 +98,19 @@ public : static std::string addNoTranslateTags(std::string mesg); static std::string removeNoTranslateTags(std::string mesg); + void logCharsSeen(size_t count); + void logCharsSent(size_t count); + void logSuccess(S32 count); + void logFailure(S32 count); + LLSD asLLSD() const; private: static LLTranslationAPIHandler& getPreferredHandler(); static LLTranslationAPIHandler& getHandler(EService service); + + size_t mCharsSeen; + size_t mCharsSent; + S32 mFailureCount; + S32 mSuccessCount; }; #endif diff --git a/indra/newview/llurldispatcher.cpp b/indra/newview/llurldispatcher.cpp index a1670351f4..7c92e7ef98 100644 --- a/indra/newview/llurldispatcher.cpp +++ b/indra/newview/llurldispatcher.cpp @@ -263,7 +263,7 @@ public: // inside the app, otherwise a malicious web page could // cause a constant teleport loop. JC LLTeleportHandler() : - LLCommandHandler("teleport", UNTRUSTED_THROTTLE), + LLCommandHandler("teleport", UNTRUSTED_CLICK_ONLY), LLEventAPI("LLTeleportHandler", "Low-level teleport API") { LLEventAPI::add("teleport", diff --git a/indra/newview/llviewerassetupload.cpp b/indra/newview/llviewerassetupload.cpp index 232b52a3f9..13491114b9 100644 --- a/indra/newview/llviewerassetupload.cpp +++ b/indra/newview/llviewerassetupload.cpp @@ -704,7 +704,7 @@ LLUUID LLBufferedAssetUploadInfo::finishUpload(LLSD &result) LLScriptAssetUpload::LLScriptAssetUpload(LLUUID itemId, std::string buffer, invnUploadFinish_f finish): LLBufferedAssetUploadInfo(itemId, LLAssetType::AT_LSL_TEXT, buffer, finish), mExerienceId(), - mTargetType(LSL2), + mTargetType(MONO), mIsRunning(false) { } @@ -725,7 +725,7 @@ LLSD LLScriptAssetUpload::generatePostBody() if (getTaskId().isNull()) { body["item_id"] = getItemId(); - body["target"] = "lsl2"; + body["target"] = "mono"; } else { diff --git a/indra/newview/llviewerfloaterreg.cpp b/indra/newview/llviewerfloaterreg.cpp index 59654350e4..c0398372b4 100644 --- a/indra/newview/llviewerfloaterreg.cpp +++ b/indra/newview/llviewerfloaterreg.cpp @@ -174,11 +174,103 @@ const std::string FLOATER_PROFILE("profile"); class LLFloaterOpenHandler : public LLCommandHandler { public: - // requires trusted browser to trigger + // requires trusted browser to trigger or an explicit click LLFloaterOpenHandler() : LLCommandHandler("openfloater", UNTRUSTED_THROTTLE) { } - bool handle(const LLSD& params, const LLSD& query_map, - LLMediaCtrl* web) + bool canHandleUntrusted( + const LLSD& params, + const LLSD& query_map, + LLMediaCtrl* web, + const std::string& nav_type) override + { + if (params.size() != 1) + { + return true; // will fail silently + } + + std::string fl_name = params[0].asString(); + + if (nav_type == NAV_TYPE_CLICKED) + { + const std::list<std::string> blacklist_clicked = { + "camera_presets", + "delete_pref_preset", + "forget_username", + "god_tools", + "group_picker", + "hud", + "incoming_call", + "linkreplace", + "message_critical", // Modal!!! Login specific. + "message_tos", // Modal!!! Login specific. + "save_pref_preset", + "save_camera_preset", + "region_restarting", + "outfit_snapshot", + "upload_anim_bvh", + "upload_anim_anim", + "upload_image", + "upload_model", + "upload_script", + "upload_sound" + }; + return std::find(blacklist_clicked.begin(), blacklist_clicked.end(), fl_name) == blacklist_clicked.end(); + } + else + { + const std::list<std::string> blacklist_untrusted = { + "360capture", + "block_timers", + "add_payment_method", + "appearance", + "associate_listing", + "avatar_picker", + "camera", + "camera_presets", + "classified", + "add_landmark", + "delete_pref_preset", + "env_fixed_environmentent_water", + "env_fixed_environmentent_sky", + "env_edit_extdaycycle", + "font_test", + "forget_username", + "god_tools", + "group_picker", + "hud", + "incoming_call", + "linkreplace", + "mem_leaking", + "marketplace_validation", + "message_critical", // Modal!!! Login specific. If this is in use elsewhere, better to create a non modal variant + "message_tos", // Modal!!! Login specific. + "mute_object_by_name", + "publish_classified", + "save_pref_preset", + "save_camera_preset", + "region_restarting", + "script_debug", + "script_debug_output", + "sell_land", + "outfit_snapshot", + "upload_anim_bvh", + "upload_anim_anim", + "upload_image", + "upload_model", + "upload_script", + "upload_sound" + }; + return std::find(blacklist_untrusted.begin(), blacklist_untrusted.end(), fl_name) == blacklist_untrusted.end(); + } + + + return true; + } + + bool handle( + const LLSD& params, + const LLSD& query_map, + LLMediaCtrl* web) override { if (params.size() != 1) { diff --git a/indra/newview/llviewerinput.cpp b/indra/newview/llviewerinput.cpp index 43b9cd90bd..6bab2c2100 100644 --- a/indra/newview/llviewerinput.cpp +++ b/indra/newview/llviewerinput.cpp @@ -1614,12 +1614,22 @@ BOOL LLViewerInput::handleMouse(LLWindow *window_impl, LLCoordGL pos, MASK mask, clicktype = CLICK_DOUBLELEFT; } + // If the first LMB click is handled by the menu, skip the following double click + static bool skip_double_click = false; + if (clicktype == CLICK_LEFT && down ) + { + skip_double_click = handled; + } if (double_click_sp && down) { // Consume click. // Due to handling, double click that is not handled will be immediately followed by LMB click } + else if (clicktype == CLICK_DOUBLELEFT && skip_double_click) + { + handled = true; + } // If UI handled 'down', it should handle 'up' as well // If we handle 'down' not by UI, then we should handle 'up'/'level' regardless of UI else if (handled) diff --git a/indra/newview/llviewerinventory.cpp b/indra/newview/llviewerinventory.cpp index 55ac817479..50252556de 100644 --- a/indra/newview/llviewerinventory.cpp +++ b/indra/newview/llviewerinventory.cpp @@ -232,7 +232,7 @@ class LLInventoryHandler : public LLCommandHandler { public: // requires trusted browser to trigger - LLInventoryHandler() : LLCommandHandler("inventory", UNTRUSTED_THROTTLE) { } + LLInventoryHandler() : LLCommandHandler("inventory", UNTRUSTED_CLICK_ONLY) { } bool handle(const LLSD& params, const LLSD& query_map, LLMediaCtrl* web) diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index c796ed30f7..a0223a5dbb 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -2803,14 +2803,15 @@ void handle_object_show_original() } -static void init_default_item_label(const std::string& item_name) +static void init_default_item_label(LLUICtrl* ctrl) { + const std::string& item_name = ctrl->getName(); boost::unordered_map<std::string, LLStringExplicit>::iterator it = sDefaultItemLabels.find(item_name); if (it == sDefaultItemLabels.end()) { // *NOTE: This will not work for items of type LLMenuItemCheckGL because they return boolean value // (doesn't seem to matter much ATM). - LLStringExplicit default_label = gMenuHolder->childGetValue(item_name).asString(); + LLStringExplicit default_label = ctrl->getValue().asString(); if (!default_label.empty()) { sDefaultItemLabels.insert(std::pair<std::string, LLStringExplicit>(item_name, default_label)); @@ -2841,18 +2842,17 @@ bool enable_object_touch(LLUICtrl* ctrl) new_value = obj->flagHandleTouch() || (parent && parent->flagHandleTouch()); } - std::string item_name = ctrl->getName(); - init_default_item_label(item_name); + init_default_item_label(ctrl); // Update label based on the node touch name if available. LLSelectNode* node = LLSelectMgr::getInstance()->getSelection()->getFirstRootNode(); if (node && node->mValid && !node->mTouchName.empty()) { - gMenuHolder->childSetValue(item_name, node->mTouchName); + ctrl->setValue(node->mTouchName); } else { - gMenuHolder->childSetValue(item_name, get_default_item_label(item_name)); + ctrl->setValue(get_default_item_label(ctrl->getName())); } return new_value; @@ -5632,6 +5632,7 @@ class LLToolsSelectNextPartFace : public view_listener_t } } LLSelectMgr::getInstance()->selectObjectOnly(to_select, new_te); + LLSelectMgr::getInstance()->addAsIndividual(to_select, new_te, false); } else { @@ -6595,20 +6596,18 @@ bool enable_object_sit(LLUICtrl* ctrl) bool sitting_on_sel = sitting_on_selection(); if (!sitting_on_sel) { - std::string item_name = ctrl->getName(); - // init default labels - init_default_item_label(item_name); + init_default_item_label(ctrl); // Update label LLSelectNode* node = LLSelectMgr::getInstance()->getSelection()->getFirstRootNode(); if (node && node->mValid && !node->mSitName.empty()) { - gMenuHolder->childSetValue(item_name, node->mSitName); + ctrl->setValue(node->mSitName); } else { - gMenuHolder->childSetValue(item_name, get_default_item_label(item_name)); + ctrl->setValue(get_default_item_label(ctrl->getName())); } } return !sitting_on_sel && is_object_sittable(); @@ -7654,7 +7653,6 @@ void handle_selected_texture_info(void*) map_t::iterator it; for (it = faces_per_texture.begin(); it != faces_per_texture.end(); ++it) { - LLUUID image_id = it->first; U8 te = it->second[0]; LLViewerTexture* img = node->getObject()->getTEImage(te); S32 height = img->getHeight(); diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp index d97ed61e11..c1a9b6be80 100644 --- a/indra/newview/llviewermessage.cpp +++ b/indra/newview/llviewermessage.cpp @@ -1907,7 +1907,7 @@ bool LLOfferInfo::inventory_offer_callback(const LLSD& notification, const LLSD& log_message = LLTrans::getString("InvOfferDecline", log_message_args); } chat.mText = log_message; - if( LLMuteList::getInstance()->isMuted(mFromID ) && ! LLMuteList::getInstance()->isLinden(mFromName) ) // muting for SL-42269 + if( LLMuteList::getInstance()->isMuted(mFromID ) && ! LLMuteList::isLinden(mFromName) ) // muting for SL-42269 { chat.mMuted = TRUE; accept_to_trash = false; // will send decline message @@ -2426,6 +2426,7 @@ void translateSuccess(LLChat chat, LLSD toastArgs, std::string originalMsg, std: chat.mText += " (" + LLTranslate::removeNoTranslateTags(translation) + ")"; } + LLTranslate::instance().logSuccess(1); LLNotificationsUI::LLNotificationManager::instance().onChat(chat, toastArgs); } @@ -2435,6 +2436,7 @@ void translateFailure(LLChat chat, LLSD toastArgs, int status, const std::string LLStringUtil::replaceString(msg, "\n", " "); // we want one-line error messages chat.mText += " (" + msg + ")"; + LLTranslate::instance().logFailure(1); LLNotificationsUI::LLNotificationManager::instance().onChat(chat, toastArgs); } @@ -2512,7 +2514,7 @@ void process_chat_from_simulator(LLMessageSystem *msg, void **user_data) LLMute::flagTextChat) || LLMuteList::getInstance()->isMuted(owner_id, LLMute::flagTextChat); is_linden = chat.mSourceType != CHAT_SOURCE_OBJECT && - LLMuteList::getInstance()->isLinden(from_name); + LLMuteList::isLinden(from_name); if (is_muted && (chat.mSourceType == CHAT_SOURCE_OBJECT)) { @@ -2669,6 +2671,7 @@ void process_chat_from_simulator(LLMessageSystem *msg, void **user_data) LLSD args; chat.mOwnerID = owner_id; + LLTranslate::instance().logCharsSeen(mesg.size()); if (gSavedSettings.getBOOL("TranslateChat") && chat.mSourceType != CHAT_SOURCE_SYSTEM) { if (chat.mChatStyle == CHAT_STYLE_IRC) @@ -2678,6 +2681,7 @@ void process_chat_from_simulator(LLMessageSystem *msg, void **user_data) const std::string from_lang = ""; // leave empty to trigger autodetect const std::string to_lang = LLTranslate::getTranslateLanguage(); + LLTranslate::instance().logCharsSent(mesg.size()); LLTranslate::translateMessage(from_lang, to_lang, mesg, boost::bind(&translateSuccess, chat, args, mesg, from_lang, _1, _2), boost::bind(&translateFailure, chat, args, _1, _2)); @@ -5819,8 +5823,12 @@ void process_script_question(LLMessageSystem *msg, void **user_data) { count++; known_questions |= script_perm.permbit; - // check whether permission question should cause special caution dialog - caution |= (script_perm.caution); + + if (!LLMuteList::isLinden(owner_name)) + { + // check whether permission question should cause special caution dialog + caution |= (script_perm.caution); + } if (("ScriptTakeMoney" == script_perm.question) && has_not_only_debit) continue; @@ -6346,7 +6354,7 @@ bool teleport_request_callback(const LLSD& notification, const LLSD& response) LLAvatarName av_name; LLAvatarNameCache::get(from_id, &av_name); - if(LLMuteList::getInstance()->isMuted(from_id) && !LLMuteList::getInstance()->isLinden(av_name.getUserName())) + if(LLMuteList::getInstance()->isMuted(from_id) && !LLMuteList::isLinden(av_name.getUserName())) { return false; } diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp index 7ac1df8e31..f47f0b4572 100644 --- a/indra/newview/llviewerobject.cpp +++ b/indra/newview/llviewerobject.cpp @@ -3234,36 +3234,39 @@ void LLViewerObject::processTaskInv(LLMessageSystem* msg, void** user_data) return; } - LLFilenameAndTask* ft = new LLFilenameAndTask; - ft->mTaskID = task_id; // we can receive multiple task updates simultaneously, make sure we will not rewrite newer with older update - msg->getS16Fast(_PREHASH_InventoryData, _PREHASH_Serial, ft->mSerial); + S16 serial = 0; + msg->getS16Fast(_PREHASH_InventoryData, _PREHASH_Serial, serial); - if (ft->mSerial == object->mInventorySerialNum - && ft->mSerial < object->mExpectedInventorySerialNum) + if (serial == object->mInventorySerialNum + && serial < object->mExpectedInventorySerialNum) { // Loop Protection. // We received same serial twice. // Viewer did some changes to inventory that couldn't be saved server side // or something went wrong to cause serial to be out of sync. // Drop xfer and restart after some time, assign server's value as expected - LL_WARNS() << "Task inventory serial might be out of sync, server serial: " << ft->mSerial << " client expected serial: " << object->mExpectedInventorySerialNum << LL_ENDL; - object->mExpectedInventorySerialNum = ft->mSerial; + LL_WARNS() << "Task inventory serial might be out of sync, server serial: " << serial << " client expected serial: " << object->mExpectedInventorySerialNum << LL_ENDL; + object->mExpectedInventorySerialNum = serial; object->fetchInventoryDelayed(INVENTORY_UPDATE_WAIT_TIME_DESYNC); } - else if (ft->mSerial < object->mExpectedInventorySerialNum) + else if (serial < object->mExpectedInventorySerialNum) { // Out of date message, record to current serial for loop protection, but do not load it // Drop xfer and restart after some time - if (ft->mSerial < object->mInventorySerialNum) + if (serial < object->mInventorySerialNum) { LL_WARNS() << "Task serial decreased. Potentially out of order packet or desync." << LL_ENDL; } - object->mInventorySerialNum = ft->mSerial; + object->mInventorySerialNum = serial; object->fetchInventoryDelayed(INVENTORY_UPDATE_WAIT_TIME_OUTDATED); } - else if (ft->mSerial >= object->mExpectedInventorySerialNum) + else if (serial >= object->mExpectedInventorySerialNum) { + LLFilenameAndTask* ft = new LLFilenameAndTask; + ft->mTaskID = task_id; + ft->mSerial = serial; + // We received version we expected or newer. Load it. object->mInventorySerialNum = ft->mSerial; object->mExpectedInventorySerialNum = ft->mSerial; @@ -3298,7 +3301,7 @@ void LLViewerObject::processTaskInv(LLMessageSystem* msg, void** user_data) object->mRegionp->getHost(), TRUE, &LLViewerObject::processTaskInvFile, - (void**)ft, + (void**)ft, // This takes ownership of ft LLXferManager::HIGH_PRIORITY); if (object->mInvRequestState == INVENTORY_XFER) { diff --git a/indra/newview/llviewerobjectlist.cpp b/indra/newview/llviewerobjectlist.cpp index e930b58111..efc4ded79e 100644 --- a/indra/newview/llviewerobjectlist.cpp +++ b/indra/newview/llviewerobjectlist.cpp @@ -815,7 +815,10 @@ void LLViewerObjectList::updateApparentAngles(LLAgent &agent) { virtual bool apply(LLViewerObject* objectp) { - objectp->boostTexturePriority(); + if (objectp) + { + objectp->boostTexturePriority(); + } return true; } } func; diff --git a/indra/newview/llviewerpartsource.cpp b/indra/newview/llviewerpartsource.cpp index f042040e98..1751ee1ebb 100644 --- a/indra/newview/llviewerpartsource.cpp +++ b/indra/newview/llviewerpartsource.cpp @@ -793,7 +793,7 @@ void LLViewerPartSourceBeam::update(const F32 dt) } LLViewerPart* part = new LLViewerPart(); - part->init(this, mImagep, NULL); + part->init(this, mImagep, updatePart); part->mFlags = LLPartData::LL_PART_INTERP_COLOR_MASK | LLPartData::LL_PART_INTERP_SCALE_MASK | diff --git a/indra/newview/llviewerprecompiledheaders.cpp b/indra/newview/llviewerprecompiledheaders.cpp deleted file mode 100644 index 307e903726..0000000000 --- a/indra/newview/llviewerprecompiledheaders.cpp +++ /dev/null @@ -1,34 +0,0 @@ -/** - * @file llviewerprecompiledheaders.cpp - * @brief precompiled headers for newview project - * - * $LicenseInfo:firstyear=2005&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2010, Linden Research, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; - * version 2.1 of the License only. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA - * $/LicenseInfo$ - */ - -// source file that includes just the standard includes -// newview.pch will be the pre-compiled header -// llviewerprecompiledheaders.obj will contain the pre-compiled type information - -#include "llviewerprecompiledheaders.h" - -// TODO: reference any additional headers you need in llviewerprecompiledheaders.h -// and not in this file diff --git a/indra/newview/llviewerstats.cpp b/indra/newview/llviewerstats.cpp index a4fbbb3e78..0f2b0714fd 100644 --- a/indra/newview/llviewerstats.cpp +++ b/indra/newview/llviewerstats.cpp @@ -64,6 +64,7 @@ #include "llvoicevivox.h" #include "llinventorymodel.h" #include "lluiusage.h" +#include "lltranslate.h" namespace LLStatViewer { @@ -500,6 +501,7 @@ void send_viewer_stats(bool include_preferences) agent["meters_traveled"] = gAgent.getDistanceTraveled(); agent["regions_visited"] = gAgent.getRegionsVisited(); agent["mem_use"] = LLMemory::getCurrentRSS() / 1024.0; + agent["translation"] = LLTranslate::instance().asLLSD(); LLSD &system = body["system"]; @@ -509,6 +511,7 @@ void send_viewer_stats(bool include_preferences) system["cpu_sse"] = gSysCPU.getSSEVersions(); system["address_size"] = ADDRESS_SIZE; system["os_bitness"] = LLOSInfo::instance().getOSBitness(); + system["hardware_concurrency"] = (LLSD::Integer) std::thread::hardware_concurrency(); unsigned char MACAddress[MAC_ADDRESS_BYTES]; LLUUID::getNodeID(MACAddress); std::string macAddressString = llformat("%02x-%02x-%02x-%02x-%02x-%02x", @@ -530,6 +533,7 @@ void send_viewer_stats(bool include_preferences) gGLManager.asLLSD(system["gl"]); + S32 shader_level = 0; if (LLPipeline::sRenderDeferred) { diff --git a/indra/newview/llviewertexteditor.cpp b/indra/newview/llviewertexteditor.cpp index e2de7ac825..7abb42dd8a 100644 --- a/indra/newview/llviewertexteditor.cpp +++ b/indra/newview/llviewertexteditor.cpp @@ -1252,7 +1252,6 @@ bool LLViewerTextEditor::onCopyToInvDialog(const LLSD& notification, const LLSD& S32 option = LLNotificationsUtil::getSelectedOption(notification, response); if( 0 == option ) { - LLUUID item_id = notification["payload"]["item_id"].asUUID(); llwchar wc = llwchar(notification["payload"]["item_wc"].asInteger()); LLInventoryItem* itemp = LLEmbeddedItems::getEmbeddedItemPtr(wc); if (itemp) diff --git a/indra/newview/llviewertexturelist.cpp b/indra/newview/llviewertexturelist.cpp index 93ae1670c8..6306e15f5c 100644 --- a/indra/newview/llviewertexturelist.cpp +++ b/indra/newview/llviewertexturelist.cpp @@ -1180,6 +1180,7 @@ F32 LLViewerTextureList::updateImagesFetchTextures(F32 max_time) { LLViewerFetchedTexture* imagep = *iter3++; imagep->updateFetch(); + if (min_count <= min_update_count) { mLastFetchKey = LLTextureKey(imagep->getID(), (ETexListType)imagep->getTextureListType()); diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index 3b391e311a..ddc11ac0bd 100644 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -1309,7 +1309,6 @@ LLWindowCallbacks::DragNDropResult LLViewerWindow::handleDragNDrop( LLWindow *wi TRUE /* pick_transparent */, FALSE /* pick_rigged */); - LLUUID object_id = pick_info.getObjectID(); S32 object_face = pick_info.mObjectFace; std::string url = data; @@ -3435,6 +3434,59 @@ void LLViewerWindow::updateUI() root_view = mRootView; } + static LLCachedControl<bool> dump_menu_holder(gSavedSettings, "DumpMenuHolderSize", false); + if (dump_menu_holder) + { + static bool init = false; + static LLFrameTimer child_count_timer; + static std::vector <std::string> child_vec; + if (!init) + { + child_count_timer.resetWithExpiry(5.f); + init = true; + } + if (child_count_timer.hasExpired()) + { + LL_INFOS() << "gMenuHolder child count: " << gMenuHolder->getChildCount() << LL_ENDL; + std::vector<std::string> local_child_vec; + LLView::child_list_t child_list = *gMenuHolder->getChildList(); + for (auto child : child_list) + { + local_child_vec.emplace_back(child->getName()); + } + if (!local_child_vec.empty() && local_child_vec != child_vec) + { + std::vector<std::string> out_vec; + std::sort(local_child_vec.begin(), local_child_vec.end()); + std::sort(child_vec.begin(), child_vec.end()); + std::set_difference(child_vec.begin(), child_vec.end(), local_child_vec.begin(), local_child_vec.end(), std::inserter(out_vec, out_vec.begin())); + if (!out_vec.empty()) + { + LL_INFOS() << "gMenuHolder removal diff size: '"<<out_vec.size() <<"' begin_child_diff"; + for (auto str : out_vec) + { + LL_CONT << " : " << str; + } + LL_CONT << " : end_child_diff" << LL_ENDL; + } + + out_vec.clear(); + std::set_difference(local_child_vec.begin(), local_child_vec.end(), child_vec.begin(), child_vec.end(), std::inserter(out_vec, out_vec.begin())); + if (!out_vec.empty()) + { + LL_INFOS() << "gMenuHolder addition diff size: '" << out_vec.size() << "' begin_child_diff"; + for (auto str : out_vec) + { + LL_CONT << " : " << str; + } + LL_CONT << " : end_child_diff" << LL_ENDL; + } + child_vec.swap(local_child_vec); + } + child_count_timer.resetWithExpiry(5.f); + } + } + // only update mouse hover set when UI is visible (since we shouldn't send hover events to invisible UI if (gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI)) { diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index 176528cb56..17299b6c61 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -3528,14 +3528,15 @@ void LLVOAvatar::idleUpdateNameTagText(bool new_name) void LLVOAvatar::addNameTagLine(const std::string& line, const LLColor4& color, S32 style, const LLFontGL* font, const bool use_ellipses) { + // extra width (NAMETAG_MAX_WIDTH) is for names only, not for chat llassert(mNameText); if (mVisibleChat) { - mNameText->addLabel(line); + mNameText->addLabel(line, LLHUDNameTag::NAMETAG_MAX_WIDTH); } else { - mNameText->addLine(line, color, (LLFontGL::StyleFlags)style, font, use_ellipses); + mNameText->addLine(line, color, (LLFontGL::StyleFlags)style, font, use_ellipses, LLHUDNameTag::NAMETAG_MAX_WIDTH); } mNameIsSet |= !line.empty(); } diff --git a/indra/newview/llvoiceclient.cpp b/indra/newview/llvoiceclient.cpp index 2ef2d66f18..6bb987ede4 100644 --- a/indra/newview/llvoiceclient.cpp +++ b/indra/newview/llvoiceclient.cpp @@ -797,7 +797,10 @@ void LLVoiceClient::addObserver(LLVoiceClientStatusObserver* observer) void LLVoiceClient::removeObserver(LLVoiceClientStatusObserver* observer) { - if (mVoiceModule && mVoiceModule->singletoneInstanceExists()) mVoiceModule->removeObserver(observer); + if (mVoiceModule) + { + mVoiceModule->removeObserver(observer); + } } void LLVoiceClient::addObserver(LLFriendObserver* observer) @@ -807,7 +810,10 @@ void LLVoiceClient::addObserver(LLFriendObserver* observer) void LLVoiceClient::removeObserver(LLFriendObserver* observer) { - if (mVoiceModule && mVoiceModule->singletoneInstanceExists()) mVoiceModule->removeObserver(observer); + if (mVoiceModule) + { + mVoiceModule->removeObserver(observer); + } } void LLVoiceClient::addObserver(LLVoiceClientParticipantObserver* observer) @@ -817,7 +823,10 @@ void LLVoiceClient::addObserver(LLVoiceClientParticipantObserver* observer) void LLVoiceClient::removeObserver(LLVoiceClientParticipantObserver* observer) { - if (mVoiceModule && mVoiceModule->singletoneInstanceExists()) mVoiceModule->removeObserver(observer); + if (mVoiceModule) + { + mVoiceModule->removeObserver(observer); + } } std::string LLVoiceClient::sipURIFromID(const LLUUID &id) diff --git a/indra/newview/llvoiceclient.h b/indra/newview/llvoiceclient.h index 246883b611..aa67502908 100644 --- a/indra/newview/llvoiceclient.h +++ b/indra/newview/llvoiceclient.h @@ -122,8 +122,6 @@ public: virtual const LLVoiceVersionInfo& getVersion()=0; - virtual bool singletoneInstanceExists()=0; - ///////////////////// /// @name Tuning //@{ diff --git a/indra/newview/llvoicevivox.cpp b/indra/newview/llvoicevivox.cpp index ab90f2e482..c73f96da2d 100644 --- a/indra/newview/llvoicevivox.cpp +++ b/indra/newview/llvoicevivox.cpp @@ -4525,7 +4525,7 @@ void LLVivoxVoiceClient::messageEvent( { bool is_do_not_disturb = gAgent.isDoNotDisturb(); bool is_muted = LLMuteList::getInstance()->isMuted(session->mCallerID, session->mName, LLMute::flagTextChat); - bool is_linden = LLMuteList::getInstance()->isLinden(session->mName); + bool is_linden = LLMuteList::isLinden(session->mName); LLChat chat; chat.mMuted = is_muted && !is_linden; @@ -5215,11 +5215,6 @@ void LLVivoxVoiceClient::declineInvite(std::string &sessionHandle) } } -bool LLVivoxVoiceClient::singletoneInstanceExists() -{ - return LLVivoxVoiceClient::instanceExists(); -} - void LLVivoxVoiceClient::leaveNonSpatialChannel() { LL_DEBUGS("Voice") << "Request to leave spacial channel." << LL_ENDL; diff --git a/indra/newview/llvoicevivox.h b/indra/newview/llvoicevivox.h index ebc3a62c35..0a785401c1 100644 --- a/indra/newview/llvoicevivox.h +++ b/indra/newview/llvoicevivox.h @@ -73,8 +73,6 @@ public: // Returns true if vivox has successfully logged in and is not in error state virtual bool isVoiceWorking() const; - - virtual bool singletoneInstanceExists(); ///////////////////// /// @name Tuning diff --git a/indra/newview/llvopartgroup.cpp b/indra/newview/llvopartgroup.cpp index f3affbeb33..51cf5f20c6 100644 --- a/indra/newview/llvopartgroup.cpp +++ b/indra/newview/llvopartgroup.cpp @@ -909,7 +909,6 @@ void LLParticlePartition::getGeometry(LLSpatialGroup* group) llassert(facep->getGeomCount() == 4); llassert(facep->getIndicesCount() == 6); - S32 idx = draw_vec.size()-1; BOOL fullbright = facep->isState(LLFace::FULLBRIGHT); diff --git a/indra/newview/llvosky.cpp b/indra/newview/llvosky.cpp index 1aa00bc894..909588367b 100644 --- a/indra/newview/llvosky.cpp +++ b/indra/newview/llvosky.cpp @@ -100,8 +100,8 @@ LLSkyTex::LLSkyTex() : void LLSkyTex::init(bool isShiny) { mIsShiny = isShiny; - mSkyData = new LLColor4[SKYTEX_RESOLUTION * SKYTEX_RESOLUTION]; - mSkyDirs = new LLVector3[SKYTEX_RESOLUTION * SKYTEX_RESOLUTION]; + mSkyData = new LLColor4[(U32)(SKYTEX_RESOLUTION * SKYTEX_RESOLUTION)]; + mSkyDirs = new LLVector3[(U32)(SKYTEX_RESOLUTION * SKYTEX_RESOLUTION)]; for (S32 i = 0; i < 2; ++i) { diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index a4e0d367c8..2e7ccc8334 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -228,6 +228,9 @@ LLVOVolume::LLVOVolume(const LLUUID &id, const LLPCode pcode, LLViewerRegion *re mColorChanged = FALSE; mSpotLightPriority = 0.f; + mSkinInfoFailed = false; + mSkinInfo = NULL; + mMediaImplList.resize(getNumTEs()); mLastFetchedMediaVersion = -1; mServerDrawableUpdateCount = 0; @@ -244,6 +247,8 @@ LLVOVolume::~LLVOVolume() delete mVolumeImpl; mVolumeImpl = NULL; + gMeshRepo.unregisterMesh(this); + if(!mMediaImplList.empty()) { for(U32 i = 0 ; i < mMediaImplList.size() ; i++) @@ -851,10 +856,7 @@ void LLVOVolume::updateTextureVirtualSize(bool forced) if (isSculpted()) { - LLSculptParams *sculpt_params = (LLSculptParams *)getParameterEntry(LLNetworkData::PARAMS_SCULPT); - LLUUID id = sculpt_params->getSculptTexture(); - - updateSculptTexture(); + updateSculptTexture(); @@ -1095,10 +1097,15 @@ BOOL LLVOVolume::setVolume(const LLVolumeParams ¶ms_in, const S32 detail, bo // if it's a mesh if ((volume_params.getSculptType() & LL_SCULPT_TYPE_MASK) == LL_SCULPT_TYPE_MESH) { + if (mSkinInfo && mSkinInfo->mMeshID != volume_params.getSculptID()) + { + mSkinInfo = NULL; + mSkinInfoFailed = false; + } + if (!getVolume()->isMeshAssetLoaded()) { //load request not yet issued, request pipeline load this mesh - LLUUID asset_id = volume_params.getSculptID(); S32 available_lod = gMeshRepo.loadMesh(this, volume_params, lod, last_lod); if (available_lod != lod) { @@ -1106,6 +1113,14 @@ BOOL LLVOVolume::setVolume(const LLVolumeParams ¶ms_in, const S32 detail, bo } } + if (!mSkinInfo && !mSkinInfoFailed) + { + const LLMeshSkinInfo* skin_info = gMeshRepo.getSkinInfo(volume_params.getSculptID(), this); + if (skin_info) + { + notifySkinInfoLoaded(skin_info); + } + } } else // otherwise is sculptie { @@ -1158,6 +1173,9 @@ void LLVOVolume::updateSculptTexture() { mSculptTexture = LLViewerTextureManager::getFetchedTexture(id, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE); } + + mSkinInfoFailed = false; + mSkinInfo = NULL; } else { @@ -1212,6 +1230,20 @@ void LLVOVolume::notifyMeshLoaded() updateVisualComplexity(); } +void LLVOVolume::notifySkinInfoLoaded(const LLMeshSkinInfo* skin) +{ + mSkinInfoFailed = false; + mSkinInfo = skin; + + notifyMeshLoaded(); +} + +void LLVOVolume::notifySkinInfoUnavailable() +{ + mSkinInfoFailed = true; + mSkinInfo = nullptr; +} + // sculpt replaces generate() for sculpted surfaces void LLVOVolume::sculpt() { @@ -3645,7 +3677,7 @@ const LLMeshSkinInfo* LLVOVolume::getSkinInfo() const { if (getVolume()) { - return gMeshRepo.getSkinInfo(getMeshID(), this); + return mSkinInfo; } else { diff --git a/indra/newview/llvovolume.h b/indra/newview/llvovolume.h index 01ad40274b..59599ddc0c 100644 --- a/indra/newview/llvovolume.h +++ b/indra/newview/llvovolume.h @@ -353,6 +353,8 @@ public: void updateVisualComplexity(); void notifyMeshLoaded(); + void notifySkinInfoLoaded(const LLMeshSkinInfo* skin); + void notifySkinInfoUnavailable(); // Returns 'true' iff the media data for this object is in flight bool isMediaDataBeingFetched() const; @@ -437,6 +439,8 @@ private: LLPointer<LLRiggedVolume> mRiggedVolume; + bool mSkinInfoFailed; + LLConstPointer<LLMeshSkinInfo> mSkinInfo; // statics public: static F32 sLODSlopDistanceFactor;// Changing this to zero, effectively disables the LOD transition slop diff --git a/indra/newview/llwatchdog.cpp b/indra/newview/llwatchdog.cpp index 0aa0280b25..ceff5cc8ee 100644 --- a/indra/newview/llwatchdog.cpp +++ b/indra/newview/llwatchdog.cpp @@ -222,18 +222,17 @@ void LLWatchdog::run() if(current_run_delta > (WATCHDOG_SLEEP_TIME_USEC * TIME_ELAPSED_MULTIPLIER)) { LL_INFOS() << "Watchdog thread delayed: resetting entries." << LL_ENDL; - std::for_each(mSuspects.begin(), - mSuspects.end(), - std::mem_fun(&LLWatchdogEntry::reset) - ); + for (const auto& suspect : mSuspects) + { + suspect->reset(); + } } else { SuspectsRegistry::iterator result = std::find_if(mSuspects.begin(), - mSuspects.end(), - std::not1(std::mem_fun(&LLWatchdogEntry::isAlive)) - ); + mSuspects.end(), + [](const LLWatchdogEntry* suspect){ return ! suspect->isAlive(); }); if(result != mSuspects.end()) { // error!!! diff --git a/indra/newview/llwearableitemslist.cpp b/indra/newview/llwearableitemslist.cpp index bf4db81475..89b74ae962 100644 --- a/indra/newview/llwearableitemslist.cpp +++ b/indra/newview/llwearableitemslist.cpp @@ -92,17 +92,77 @@ LLPanelWearableListItem::LLPanelWearableListItem(LLViewerInventoryItem* item, co ////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////// +static LLWidgetNameRegistry::StaticRegistrar sRegisterPanelWearableOutfitItem(&typeid(LLPanelWearableOutfitItem::Params), "wearable_outfit_list_item"); + +LLPanelWearableOutfitItem::Params::Params() +: add_btn("add_btn"), + remove_btn("remove_btn") +{ +} + +BOOL LLPanelWearableOutfitItem::postBuild() +{ + LLPanelWearableListItem::postBuild(); + + LLViewerInventoryItem* inv_item = getItem(); + mShowWidgets &= (inv_item->getType() != LLAssetType::AT_BODYPART); + if(mShowWidgets) + { + addWidgetToRightSide("add_wearable"); + addWidgetToRightSide("remove_wearable"); + + childSetAction("add_wearable", boost::bind(&LLPanelWearableOutfitItem::onAddWearable, this)); + childSetAction("remove_wearable", boost::bind(&LLPanelWearableOutfitItem::onRemoveWearable, this)); + + setWidgetsVisible(false); + reshapeWidgets(); + } + return TRUE; +} + +BOOL LLPanelWearableOutfitItem::handleDoubleClick(S32 x, S32 y, MASK mask) +{ + if(!mShowWidgets) + { + return LLPanelWearableListItem::handleDoubleClick(x, y, mask); + } + + if(LLAppearanceMgr::instance().isLinkedInCOF(mInventoryItemUUID)) + { + onRemoveWearable(); + } + else + { + onAddWearable(); + } + return TRUE; +} + +void LLPanelWearableOutfitItem::onAddWearable() +{ + setWidgetsVisible(false); + reshapeWidgets(); + LLAppearanceMgr::instance().wearItemOnAvatar(mInventoryItemUUID, true, false); +} + +void LLPanelWearableOutfitItem::onRemoveWearable() +{ + setWidgetsVisible(false); + reshapeWidgets(); + LLAppearanceMgr::instance().removeItemFromAvatar(mInventoryItemUUID); +} // static LLPanelWearableOutfitItem* LLPanelWearableOutfitItem::create(LLViewerInventoryItem* item, - bool worn_indication_enabled) + bool worn_indication_enabled, + bool show_widgets) { LLPanelWearableOutfitItem* list_item = NULL; if (item) { - const LLPanelInventoryListItemBase::Params& params = LLUICtrlFactory::getDefaultParams<LLPanelInventoryListItemBase>(); + const LLPanelWearableOutfitItem::Params& params = LLUICtrlFactory::getDefaultParams<LLPanelWearableOutfitItem>(); - list_item = new LLPanelWearableOutfitItem(item, worn_indication_enabled, params); + list_item = new LLPanelWearableOutfitItem(item, worn_indication_enabled, params, show_widgets); list_item->initFromParams(params); list_item->postBuild(); } @@ -110,11 +170,23 @@ LLPanelWearableOutfitItem* LLPanelWearableOutfitItem::create(LLViewerInventoryIt } LLPanelWearableOutfitItem::LLPanelWearableOutfitItem(LLViewerInventoryItem* item, - bool worn_indication_enabled, - const LLPanelWearableOutfitItem::Params& params) -: LLPanelInventoryListItemBase(item, params) + bool worn_indication_enabled, + const LLPanelWearableOutfitItem::Params& params, + bool show_widgets) +: LLPanelWearableListItem(item, params) , mWornIndicationEnabled(worn_indication_enabled) +, mShowWidgets(show_widgets) { + if(mShowWidgets) + { + LLButton::Params button_params = params.add_btn; + applyXUILayout(button_params, this); + addChild(LLUICtrlFactory::create<LLButton>(button_params)); + + button_params = params.remove_btn; + applyXUILayout(button_params, this); + addChild(LLUICtrlFactory::create<LLButton>(button_params)); + } } // virtual @@ -127,11 +199,22 @@ void LLPanelWearableOutfitItem::updateItem(const std::string& name, // We don't use get_is_item_worn() here because this update is triggered by // an inventory observer upon link in COF beind added or removed so actual // worn status of a linked item may still remain unchanged. - if (mWornIndicationEnabled && LLAppearanceMgr::instance().isLinkedInCOF(mInventoryItemUUID)) + bool is_worn = LLAppearanceMgr::instance().isLinkedInCOF(mInventoryItemUUID); + if (mWornIndicationEnabled && is_worn) { search_label += LLTrans::getString("worn"); item_state = IS_WORN; } + if(mShowWidgets) + { + setShowWidget("add_wearable", !is_worn); + setShowWidget("remove_wearable", is_worn); + if(mHovered) + { + setWidgetsVisible(true); + reshapeWidgets(); + } + } LLPanelInventoryListItemBase::updateItem(search_label, item_state); } @@ -634,6 +717,7 @@ static const LLDefaultChildRegistry::Register<LLWearableItemsList> r("wearable_i LLWearableItemsList::Params::Params() : standalone("standalone", true) , worn_indication_enabled("worn_indication_enabled", true) +, show_item_widgets("show_item_widgets", false) {} LLWearableItemsList::LLWearableItemsList(const LLWearableItemsList::Params& p) @@ -649,6 +733,7 @@ LLWearableItemsList::LLWearableItemsList(const LLWearableItemsList::Params& p) } mWornIndicationEnabled = p.worn_indication_enabled; setNoItemsCommentText(LLTrans::getString("LoadingData")); + mShowItemWidgets = p.show_item_widgets; } // virtual @@ -665,7 +750,7 @@ LLPanel* LLWearableItemsList::createNewItem(LLViewerInventoryItem* item) return NULL; } - return LLPanelWearableOutfitItem::create(item, mWornIndicationEnabled); + return LLPanelWearableOutfitItem::create(item, mWornIndicationEnabled, mShowItemWidgets); } void LLWearableItemsList::updateList(const LLUUID& category_id) diff --git a/indra/newview/llwearableitemslist.h b/indra/newview/llwearableitemslist.h index ba8488b237..f7774a7086 100644 --- a/indra/newview/llwearableitemslist.h +++ b/indra/newview/llwearableitemslist.h @@ -72,12 +72,23 @@ protected: * Extends LLPanelInventoryListItemBase with handling * double click to wear the item. */ -class LLPanelWearableOutfitItem : public LLPanelInventoryListItemBase +class LLPanelWearableOutfitItem : public LLPanelWearableListItem { LOG_CLASS(LLPanelWearableOutfitItem); public: + struct Params : public LLInitParam::Block<Params, LLPanelWearableListItem::Params> + { + Optional<LLButton::Params> add_btn, remove_btn; + + Params(); + }; + + BOOL postBuild(); + BOOL handleDoubleClick(S32 x, S32 y, MASK mask); + static LLPanelWearableOutfitItem* create(LLViewerInventoryItem* item, - bool worn_indication_enabled); + bool worn_indication_enabled, + bool show_widgets); /** * Updates item name and (worn) suffix. @@ -85,12 +96,16 @@ public: /*virtual*/ void updateItem(const std::string& name, EItemState item_state = IS_DEFAULT); + void onAddWearable(); + void onRemoveWearable(); + protected: LLPanelWearableOutfitItem(LLViewerInventoryItem* item, - bool worn_indication_enabled, const Params& params); + bool worn_indication_enabled, const Params& params, bool show_widgets = false); private: bool mWornIndicationEnabled; + bool mShowWidgets; }; class LLPanelDeletableWearableListItem : public LLPanelWearableListItem @@ -442,6 +457,7 @@ public: { Optional<bool> standalone; Optional<bool> worn_indication_enabled; + Optional<bool> show_item_widgets; Params(); }; @@ -482,6 +498,7 @@ protected: bool mIsStandalone; bool mWornIndicationEnabled; + bool mShowItemWidgets; ESortOrder mSortOrder; diff --git a/indra/newview/llwebprofile.cpp b/indra/newview/llwebprofile.cpp index 3cc82621c4..f2d7e4585a 100644 --- a/indra/newview/llwebprofile.cpp +++ b/indra/newview/llwebprofile.cpp @@ -42,7 +42,7 @@ #include "llcorehttputil.h" // third-party -#include "reader.h" // JSON +#include "json/reader.h" // JSON /* * Workflow: diff --git a/indra/newview/llworld.cpp b/indra/newview/llworld.cpp index 55bcbf8aa5..3201440b95 100644 --- a/indra/newview/llworld.cpp +++ b/indra/newview/llworld.cpp @@ -293,13 +293,13 @@ void LLWorld::removeRegion(const LLHost &host) mRegionRemovedSignal(regionp); - delete regionp; - updateWaterObjects(); //double check all objects of this region are removed. gObjectList.clearAllMapObjectsInRegion(regionp) ; //llassert_always(!gObjectList.hasMapObjectInRegion(regionp)) ; + + delete regionp; // Delete last to prevent use after free } @@ -764,13 +764,10 @@ void LLWorld::updateParticles() void LLWorld::renderPropertyLines() { - S32 region_count = 0; - for (region_list_t::iterator iter = mVisibleRegionList.begin(); iter != mVisibleRegionList.end(); ++iter) { LLViewerRegion* regionp = *iter; - region_count++; regionp->renderPropertyLines(); } } diff --git a/indra/newview/llxmlrpclistener.cpp b/indra/newview/llxmlrpclistener.cpp index 4401f61059..b816f9a3b5 100644 --- a/indra/newview/llxmlrpclistener.cpp +++ b/indra/newview/llxmlrpclistener.cpp @@ -38,7 +38,13 @@ // external library headers #include <boost/scoped_ptr.hpp> #include <boost/range.hpp> // boost::begin(), boost::end() + +#ifdef LL_USESYSTEMLIBS +#include <xmlrpc.h> +#else #include <xmlrpc-epi/xmlrpc.h> +#endif + #include "curl/curl.h" // other Linden headers @@ -343,7 +349,9 @@ public: switch (curlcode) { +#if CURLE_SSL_PEER_CERTIFICATE != CURLE_SSL_CACERT case CURLE_SSL_PEER_CERTIFICATE: +#endif case CURLE_SSL_CACERT: data["certificate"] = mTransaction->getErrorCertData(); break; diff --git a/indra/newview/llxmlrpctransaction.cpp b/indra/newview/llxmlrpctransaction.cpp index 5c56a1d34f..8d178dbbdc 100644 --- a/indra/newview/llxmlrpctransaction.cpp +++ b/indra/newview/llxmlrpctransaction.cpp @@ -44,7 +44,12 @@ #include "llviewercontrol.h" // Have to include these last to avoid queue redefinition! + +#ifdef LL_USESYSTEMLIBS +#include <xmlrpc.h> +#else #include <xmlrpc-epi/xmlrpc.h> +#endif #include "llappviewer.h" #include "lltrans.h" @@ -508,10 +513,11 @@ void LLXMLRPCTransaction::Impl::setHttpStatus(const LLCore::HttpStatus &status) message = LLTrans::getString("couldnt_resolve_host", args); break; +#if CURLE_SSL_PEER_CERTIFICATE != CURLE_SSL_CACERT case CURLE_SSL_PEER_CERTIFICATE: message = LLTrans::getString("ssl_peer_certificate"); break; - +#endif case CURLE_SSL_CACERT: case CURLE_SSL_CONNECT_ERROR: message = LLTrans::getString("ssl_connect_error"); diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index 13d6966723..d00ac5db76 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -1775,20 +1775,17 @@ void LLPipeline::unlinkDrawable(LLDrawable *drawable) void LLPipeline::removeMutedAVsLights(LLVOAvatar* muted_avatar) { LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE; - light_set_t::iterator iter = gPipeline.mNearbyLights.begin(); - - while (iter != gPipeline.mNearbyLights.end()) - { - if (iter->drawable->getVObj()->isAttachment() && iter->drawable->getVObj()->getAvatar() == muted_avatar) - { - gPipeline.mLights.erase(iter->drawable); - iter = gPipeline.mNearbyLights.erase(iter); - } - else - { - iter++; - } - } + for (light_set_t::iterator iter = gPipeline.mNearbyLights.begin(); + iter != gPipeline.mNearbyLights.end(); iter++) + { + const LLViewerObject *vobj = iter->drawable->getVObj(); + if (vobj && vobj->getAvatar() + && vobj->isAttachment() && vobj->getAvatar() == muted_avatar) + { + gPipeline.mLights.erase(iter->drawable); + gPipeline.mNearbyLights.erase(iter); + } + } } U32 LLPipeline::addObject(LLViewerObject *vobj) diff --git a/indra/newview/skins/default/textures/icons/add_icon.png b/indra/newview/skins/default/textures/icons/add_icon.png Binary files differnew file mode 100644 index 0000000000..cb68ee8e16 --- /dev/null +++ b/indra/newview/skins/default/textures/icons/add_icon.png diff --git a/indra/newview/skins/default/textures/icons/remove_icon.png b/indra/newview/skins/default/textures/icons/remove_icon.png Binary files differnew file mode 100644 index 0000000000..6e62ee33f4 --- /dev/null +++ b/indra/newview/skins/default/textures/icons/remove_icon.png diff --git a/indra/newview/skins/default/textures/textures.xml b/indra/newview/skins/default/textures/textures.xml index 4429a1677e..1f2c0867c4 100644 --- a/indra/newview/skins/default/textures/textures.xml +++ b/indra/newview/skins/default/textures/textures.xml @@ -743,6 +743,9 @@ with the same filename but different name <texture name="Wearables_Divider" file_name="windows/Wearables_Divider.png" preload="false" /> + <texture name="Add_Icon" file_name="icons/add_icon.png" preload="false" /> + <texture name="Remove_Icon" file_name="icons/remove_icon.png" preload="false" /> + <texture name="Web_Profile_Off" file_name="icons/Web_Profile_Off.png" preload="false" /> <texture name="WellButton_Lit" file_name="bottomtray/WellButton_Lit.png" preload="true" scale.left="4" scale.top="19" scale.right="28" scale.bottom="4" /> diff --git a/indra/newview/skins/default/xui/de/floater_tools.xml b/indra/newview/skins/default/xui/de/floater_tools.xml index a4dfde66bc..f6208e11a5 100644 --- a/indra/newview/skins/default/xui/de/floater_tools.xml +++ b/indra/newview/skins/default/xui/de/floater_tools.xml @@ -40,7 +40,7 @@ Klicken und ziehen, um Land auszuwählen </floater.string> <floater.string name="status_selectcount"> - [OBJ_COUNT] Objekte ausgewählt, Auswirkung auf Land [LAND_IMPACT] + [OBJ_COUNT] Objekte ausgewählt, Auswirkung auf Land [LAND_IMPACT] [secondlife:///app/openfloater/object_weights ?] </floater.string> <floater.string name="status_remaining_capacity"> Verbleibende Kapazität [LAND_CAPACITY]. diff --git a/indra/newview/skins/default/xui/en/floater_display_name.xml b/indra/newview/skins/default/xui/en/floater_display_name.xml index 3c8f415860..f3431da858 100644 --- a/indra/newview/skins/default/xui/en/floater_display_name.xml +++ b/indra/newview/skins/default/xui/en/floater_display_name.xml @@ -56,7 +56,7 @@ max_length_chars="31" height="20" top_pad="5" - left="50" /> + left_delta="0" /> <text top_pad="15" left="25" @@ -72,23 +72,33 @@ max_length_chars="31" height="20" top_pad="5" - left="50" /> + left_delta="0" /> + <button + label="Reset" + layout="topleft" + font="SansSerif" + width="120" + height="23" + top_pad="40" + left_delta="0" + name="reset_btn" + tool_tip="Use Username as a Display Name" /> <button height="23" label="Save" layout="topleft" font="SansSerif" - left="35" + left_pad="35" name="save_btn" tool_tip="Save your new Display Name" - top_pad="40" + top_delta="0" width="120" /> <button height="23" label="Cancel" font="SansSerif" layout="topleft" - left_pad="125" + left_pad="5" name="cancel_btn" width="120" /> </floater> diff --git a/indra/newview/skins/default/xui/en/floater_inventory_item_properties.xml b/indra/newview/skins/default/xui/en/floater_inventory_item_properties.xml index 45e16c59ae..850e1be372 100644 --- a/indra/newview/skins/default/xui/en/floater_inventory_item_properties.xml +++ b/indra/newview/skins/default/xui/en/floater_inventory_item_properties.xml @@ -323,7 +323,6 @@ follows="left|top" decimal_digits="0" increment="1" - control_name="Edit Cost" name="Edit Cost" label="Price:" label_width="100" diff --git a/indra/newview/skins/default/xui/en/floater_object_weights.xml b/indra/newview/skins/default/xui/en/floater_object_weights.xml index eb283a1043..889efa061c 100644 --- a/indra/newview/skins/default/xui/en/floater_object_weights.xml +++ b/indra/newview/skins/default/xui/en/floater_object_weights.xml @@ -2,7 +2,7 @@ <floater can_close="true" can_tear_off="false" - height="315" + height="289" help_topic="object_weights" layout="topleft" name="object_weights" @@ -320,23 +320,4 @@ top_delta="0" value="Total capacity" width="130" /> - <view_border - bevel_style="none" - follows="top|left" - height="0" - layout="topleft" - left="10" - name="land_impacts_text_border" - top_pad="5" - width="180"/> - - <text - follows="left|top" - height="16" - layout="topleft" - left="10" - name="help_SLURL" - top_pad="10" - value="[secondlife:///app/help/object_weights What is all this?...]" - width="180" /> </floater> diff --git a/indra/newview/skins/default/xui/en/floater_openobject.xml b/indra/newview/skins/default/xui/en/floater_openobject.xml index 912db80bcc..ec03d7d32c 100644 --- a/indra/newview/skins/default/xui/en/floater_openobject.xml +++ b/indra/newview/skins/default/xui/en/floater_openobject.xml @@ -3,7 +3,7 @@ legacy_header_height="18" can_resize="true" default_tab_group="1" - height="370" + height="350" layout="topleft" min_height="190" min_width="285" @@ -31,62 +31,18 @@ background_visible="false" draw_border="false" follows="all" - height="240" + height="265" layout="topleft" + show_root_folder="false" left="10" name="object_contents" top_pad="0" width="284" /> - <view_border - bevel_style="none" - follows="bottom|left" - height="50" - highlight_light_color="0.6 0.6 0.6" - layout="topleft" - left="10" - name="border" - top_pad="5" - width="270"/> - <text - follows="bottom|left" - height="15" - layout="topleft" - left="15" - name="border_note" - text_color="White" - top_delta="5"> - Copy to inventory and wear - </text> - <button - follows="bottom|left" - height="23" - label="Add to outfit" - label_selected="Add to outfit" - layout="topleft" - left="15" - name="copy_and_wear_button" - top_pad="3" - width="135"> - <button.commit_callback - function="OpenObject.MoveAndWear" /> - </button> - <button - follows="bottom|left" - height="23" - label="Replace outfit" - label_selected="Replace outfit" - layout="topleft" - left_pad="5" - name="copy_and_replace_button" - width="120"> - <button.commit_callback - function="OpenObject.ReplaceOutfit" /> - </button> <button follows="bottom|left" height="23" label="Only copy to inventory" - label_selected="Only copy to inventory" + label_selected="Copy to inventory" layout="topleft" left="15" name="copy_to_inventory_button" diff --git a/indra/newview/skins/default/xui/en/floater_pathfinding_linksets.xml b/indra/newview/skins/default/xui/en/floater_pathfinding_linksets.xml index 41384a77b8..59117c0178 100644 --- a/indra/newview/skins/default/xui/en/floater_pathfinding_linksets.xml +++ b/indra/newview/skins/default/xui/en/floater_pathfinding_linksets.xml @@ -82,17 +82,20 @@ width="62"> Name </text> - <line_editor - border_style="line" - border_thickness="1" - follows="left|top" - height="20" - layout="topleft" - left_pad="0" - top_pad="-18" - max_length_chars="255" - name="filter_by_name" - width="161" /> + + <search_editor + follows="left|top" + search_button_visible="false" + height="20" + text_readonly_color="DkGray" + label="Objects by Name" + layout="topleft" + left_pad="0" + top_pad="-18" + name="filter_by_name" + select_on_focus="true" + width="161"> + </search_editor> <text name="linksets_desc_label" height="13" @@ -108,17 +111,19 @@ width="88"> Description </text> - <line_editor - border_style="line" - border_thickness="1" - follows="left|top" - height="20" - layout="topleft" - left_pad="0" - top_pad="-17" - max_length_chars="255" - name="filter_by_description" - width="162" /> + <search_editor + follows="left|top" + search_button_visible="false" + height="20" + text_readonly_color="DkGray" + label="Objects by Description" + layout="topleft" + left_pad="0" + top_pad="-17" + name="filter_by_description" + select_on_focus="true" + width="162"> + </search_editor> <combo_box height="20" layout="topleft" diff --git a/indra/newview/skins/default/xui/en/floater_settings_debug.xml b/indra/newview/skins/default/xui/en/floater_settings_debug.xml index 3ed2bd7206..e4fda5cd10 100644 --- a/indra/newview/skins/default/xui/en/floater_settings_debug.xml +++ b/indra/newview/skins/default/xui/en/floater_settings_debug.xml @@ -2,41 +2,79 @@ <floater legacy_header_height="18" can_minimize="false" - height="215" + height="360" + min_height="367" layout="topleft" name="settings_debug" help_topic="settings_debug" title="DEBUG SETTINGS" - width="350"> - <combo_box - allow_text_entry="true" - follows="top|left" - height="22" - layout="topleft" - left="15" - max_chars="255" - name="settings_combo" - top="30" - width="320"> - <combo_box.commit_callback - function="SettingSelect" /> - </combo_box> - <text_editor - enabled="false" - height="60" - layout="topleft" - left_delta="0" - name="comment_text" - top_pad="10" - width="320" - word_wrap="true" /> + reuse_instance="true" + can_resize="true" + min_width="550" + width="570"> + <filter_editor + follows="left|top|right" + height="23" + layout="topleft" + left="10" + right="-10" + label="Enter search text" + max_length_chars="300" + name="filter_input" + text_pad_left="10" + top="30" /> + <scroll_list + column_padding="0" + draw_heading="true" + draw_stripes="false" + heading_height="23" + height="266" + layout="topleft" + search_column="1" + left="10" + follows="left|top|bottom" + name="setting_list" + top_pad="2" + width="300"> + <scroll_list.columns + name="changed_setting" + relative_width="0.05" /> + <scroll_list.columns + label="Setting" + name="setting" /> + </scroll_list> + <text + type="string" + length="1" + follows="left|top" + height="16" + layout="topleft" + name="setting_name_txt" + font="SansSerifSmallBold" + top_delta="8" + left_pad="10" + visible="false" + use_ellipses="true" + text_color="White" + width="240"> + Debug setting name + </text> + <text_editor + enabled="false" + height="75" + layout="topleft" + visible="false" + name="comment_text" + follows="left|top" + width="240" + top_delta="20" + word_wrap="true" /> <radio_group follows="top|left" height="30" layout="topleft" - left_delta="0" name="boolean_combo" - top_pad="10" + top_pad="15" visible="false" tab_stop="true" width="100"> @@ -55,21 +93,25 @@ </radio_group> <line_editor height="20" + follows="top|left" layout="topleft" left_delta="0" name="val_text" top_delta="0" visible="false" - width="300" > + width="220" > <line_editor.commit_callback function="CommitSettings" /> </line_editor> <color_swatch - bottom="185" + top_delta="0" + left_delta="0" + follows="top|left" can_apply_immediately="true" height="55" name="val_color_swatch" label="Color" + visible="false" layout="topleft" width="37" > <color_swatch.commit_callback @@ -79,10 +121,11 @@ height="20" label="x" layout="topleft" + follows="top|left" left_delta="0" max_val="1e+007" name="val_spinner_1" - top_delta="10" + top_delta="5" visible="false" width="120" > <spinner.commit_callback @@ -92,10 +135,11 @@ height="20" label="x" layout="topleft" - left_pad="15" + follows="top|left" + left_delta="0" max_val="1e+007" name="val_spinner_2" - top_delta="0" + top_pad="10" visible="false" width="120"> <spinner.commit_callback @@ -105,10 +149,11 @@ height="20" label="x" layout="topleft" - left="15" + follows="top|left" + left_delta="0" max_val="1e+007" name="val_spinner_3" - top="160" + top_pad="10" visible="false" width="120"> <spinner.commit_callback @@ -118,10 +163,11 @@ height="20" label="x" layout="topleft" - left_pad="15" + follows="top|left" + left_delta="0" max_val="1e+007" name="val_spinner_4" - top_delta="0" + top_pad="10" visible="false" width="120" > <spinner.commit_callback @@ -130,12 +176,26 @@ <button height="22" label="Reset to default" + follows="left|top" layout="topleft" - left="15" + left_delta="0" name="default_btn" - top="186" + visible="false" + top_pad="10" width="150" > <button.commit_callback function="ClickDefault" /> </button> + <check_box + control_name="DebugSettingsHideDefault" + height="16" + initial_value="true" + label="Show changed settings only" + layout="topleft" + top_pad="10" + left="10" + follows="left|bottom" + name="hide_default" + width="330"> + </check_box> </floater> diff --git a/indra/newview/skins/default/xui/en/floater_tools.xml b/indra/newview/skins/default/xui/en/floater_tools.xml index ade79b8884..d9b0ac0060 100644 --- a/indra/newview/skins/default/xui/en/floater_tools.xml +++ b/indra/newview/skins/default/xui/en/floater_tools.xml @@ -1140,7 +1140,6 @@ even though the user gets a free copy. decimal_digits="0" increment="1" left_pad="0" - control_name="Edit Cost" name="Edit Cost" label="L$" label_width="15" diff --git a/indra/newview/skins/default/xui/en/menu_participant_view.xml b/indra/newview/skins/default/xui/en/menu_participant_view.xml index 7ea87ee05c..b9750284cd 100644 --- a/indra/newview/skins/default/xui/en/menu_participant_view.xml +++ b/indra/newview/skins/default/xui/en/menu_participant_view.xml @@ -90,7 +90,7 @@ parameter="conversation_log" /> </menu_item_check> <menu_item_separator layout="topleft" /> - <menu_item_check name="Translate_chat" label="Translate Nearby chat"> + <menu_item_check name="Translate_chat" label="Translate chat"> <menu_item_check.on_click function="IMFloaterContainer.Action" parameter="Translating.Toggle" /> diff --git a/indra/newview/skins/default/xui/en/outfit_accordion_tab.xml b/indra/newview/skins/default/xui/en/outfit_accordion_tab.xml index 2a24c74feb..d74dca8b95 100644 --- a/indra/newview/skins/default/xui/en/outfit_accordion_tab.xml +++ b/indra/newview/skins/default/xui/en/outfit_accordion_tab.xml @@ -18,6 +18,7 @@ follows="all" keep_one_selected="true" multi_select="true" + show_item_widgets="true" name="wearable_items_list" translate="false" standalone="false" diff --git a/indra/newview/skins/default/xui/en/panel_media_settings_general.xml b/indra/newview/skins/default/xui/en/panel_media_settings_general.xml index 2316beeb36..4c566dc60a 100644 --- a/indra/newview/skins/default/xui/en/panel_media_settings_general.xml +++ b/indra/newview/skins/default/xui/en/panel_media_settings_general.xml @@ -92,10 +92,7 @@ label="Reset" left_delta="233" name="current_url_reset_btn" - width="110" > - <button.commit_callback - function="Media.ResetCurrentUrl"/> - </button> + width="110"/> <check_box bottom_delta="-25" enabled="true" diff --git a/indra/newview/skins/default/xui/en/panel_outfits_wearing.xml b/indra/newview/skins/default/xui/en/panel_outfits_wearing.xml index 42a7974316..b2dc975c6e 100644 --- a/indra/newview/skins/default/xui/en/panel_outfits_wearing.xml +++ b/indra/newview/skins/default/xui/en/panel_outfits_wearing.xml @@ -36,6 +36,7 @@ left="3" multi_select="true" name="cof_items_list" + show_item_widgets="true" standalone="false" top="0" width="309" diff --git a/indra/newview/skins/default/xui/en/panel_preferences_privacy.xml b/indra/newview/skins/default/xui/en/panel_preferences_privacy.xml index 2ec5cef640..ef08fdf7c4 100644 --- a/indra/newview/skins/default/xui/en/panel_preferences_privacy.xml +++ b/indra/newview/skins/default/xui/en/panel_preferences_privacy.xml @@ -19,7 +19,7 @@ follows="left|top" height="23" label="Clear History" - tool_tip="Clear login image, last location, teleport history, web and texture cache" + tool_tip="Clear search and teleport history, web and texture cache" layout="topleft" left="30" name="clear_cache" diff --git a/indra/newview/skins/default/xui/en/panel_profile_secondlife.xml b/indra/newview/skins/default/xui/en/panel_profile_secondlife.xml index 551b477876..777b37d666 100644 --- a/indra/newview/skins/default/xui/en/panel_profile_secondlife.xml +++ b/indra/newview/skins/default/xui/en/panel_profile_secondlife.xml @@ -9,9 +9,13 @@ follows="all" layout="topleft" > + <!-- + Date from server comes already converted to stl timezone, + so display it as an UTC+0 + --> <string name="date_format" - value="SL birthdate: [mth,datetime,slt] [day,datetime,slt], [year,datetime,slt]" /> + value="SL birthdate: [mth,datetime,utc] [day,datetime,utc], [year,datetime,utc]" /> <string name="age_format" value="[AGE]" /> diff --git a/indra/newview/skins/default/xui/en/panel_region_estate.xml b/indra/newview/skins/default/xui/en/panel_region_estate.xml index 9b9c870c49..33e99a46ae 100644 --- a/indra/newview/skins/default/xui/en/panel_region_estate.xml +++ b/indra/newview/skins/default/xui/en/panel_region_estate.xml @@ -82,7 +82,7 @@ <view_border bevel_style="none" follows="top|left" - height="185" + height="205" layout="topleft" left="10" top_pad="5" @@ -126,6 +126,16 @@ top_pad="2" width="278" /> <check_box + follows="top|left" + height="18" + label="Must not be a scripted agent" + layout="topleft" + left_delta="0" + name="limit_bots" + tool_tip="Residents must not be a scripted agents (bots) to access this estate. See the [SUPPORT_SITE] for more information." + top_pad="2" + width="278" /> + <check_box height="18" label="Parcel owners can be more restrictive" layout="topleft" diff --git a/indra/newview/skins/default/xui/en/sidepanel_item_info.xml b/indra/newview/skins/default/xui/en/sidepanel_item_info.xml index 9a68479d05..35d14251c7 100644 --- a/indra/newview/skins/default/xui/en/sidepanel_item_info.xml +++ b/indra/newview/skins/default/xui/en/sidepanel_item_info.xml @@ -450,7 +450,6 @@ follows="left|top" decimal_digits="0" increment="1" - control_name="Edit Cost" name="Edit Cost" label="Price: L$" label_width="75" @@ -461,8 +460,72 @@ max_val="999999999" top_pad="10" tool_tip="Object cost." /> - </panel> - + <text + type="string" + length="1" + follows="left|top" + height="10" + layout="topleft" + left="10" + name="BaseMaskDebug" + text_color="White" + top_pad="30" + width="130"> + B: + </text> + <text + type="string" + length="1" + follows="left|top" + height="10" + layout="topleft" + left_delta="60" + name="OwnerMaskDebug" + text_color="White" + top_delta="0" + width="270"> + O: + </text> + <text + type="string" + length="1" + follows="left|top" + height="10" + layout="topleft" + left_delta="60" + name="GroupMaskDebug" + text_color="White" + top_delta="0" + width="210"> + G: + </text> + <text + type="string" + length="1" + follows="left|top" + height="10" + layout="topleft" + left_delta="60" + name="EveryoneMaskDebug" + text_color="White" + top_delta="0" + width="150"> + E: + </text> + <text + type="string" + length="1" + follows="left|top" + height="10" + layout="topleft" + left_delta="60" + name="NextMaskDebug" + text_color="White" + top_delta="0" + width="90"> + N: + </text> + </panel> </scroll_container> <panel height="30" diff --git a/indra/newview/skins/default/xui/en/sidepanel_task_info.xml b/indra/newview/skins/default/xui/en/sidepanel_task_info.xml index 1c9d750aa6..0b32215964 100644 --- a/indra/newview/skins/default/xui/en/sidepanel_task_info.xml +++ b/indra/newview/skins/default/xui/en/sidepanel_task_info.xml @@ -454,7 +454,6 @@ increment="1" top_pad="10" left="120" - control_name="Edit Cost" name="Edit Cost" label="Price: L$" label_width="73" diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml index efc70440d2..fb39646ddd 100644 --- a/indra/newview/skins/default/xui/en/strings.xml +++ b/indra/newview/skins/default/xui/en/strings.xml @@ -126,8 +126,8 @@ http://secondlife.com/download For more information, see our FAQ below: http://secondlife.com/viewer-access-faq</string> - <string name="LoginFailed">Login failure. -If you feel this is an error, please contact support@secondlife.com.</string> + <string name="LoginFailed">"Login process did not complete due to system issues. Try again in a few minutes. +If you feel this is an error, contact Support at https://support.secondlife.com"</string> <string name="LoginIntermediateOptionalUpdateAvailable">Optional viewer update available: [VERSION]</string> <string name="LoginFailedRequiredUpdate">Required viewer update: [VERSION]</string> <string name="LoginFailedAlreadyLoggedIn">This agent is already logged in. @@ -3983,7 +3983,7 @@ Please check http://status.secondlifegrid.net to see if there is a known problem <string name="Premium_PlusMembership">Premium Plus</string> <string name="InternalMembership">Internal</string> <!-- No need to translate --> - <string name="MembershipUpgradeText">Upgrade to Premium</string> + <string name="MembershipUpgradeText">Change membership plan...</string> <string name="MembershipPremiumText">My Premium membership</string> <!-- Question strings for delete items notifications --> diff --git a/indra/newview/skins/default/xui/en/widgets/filter_editor.xml b/indra/newview/skins/default/xui/en/widgets/filter_editor.xml index 1c4822b8d5..9c80deeafc 100644 --- a/indra/newview/skins/default/xui/en/widgets/filter_editor.xml +++ b/indra/newview/skins/default/xui/en/widgets/filter_editor.xml @@ -6,7 +6,7 @@ text_pad_left="7" select_on_focus="true" text_tentative_color="TextFgTentativeColor" - highlight_text_field="false" + highlight_text_field="true" background_image="TextField_Search_Off" background_image_disabled="TextField_Search_Disabled" background_image_focused="TextField_Search_Active" diff --git a/indra/newview/skins/default/xui/en/widgets/search_editor.xml b/indra/newview/skins/default/xui/en/widgets/search_editor.xml index dc5a07bf4f..18d99f1ed1 100644 --- a/indra/newview/skins/default/xui/en/widgets/search_editor.xml +++ b/indra/newview/skins/default/xui/en/widgets/search_editor.xml @@ -7,7 +7,7 @@ text_pad_right="6" select_on_focus="true" text_tentative_color="TextFgTentativeColor" - highlight_text_field="false" + highlight_text_field="true" background_image="TextField_Search_Off" background_image_disabled="TextField_Search_Disabled" background_image_focused="TextField_Search_Active" diff --git a/indra/newview/skins/default/xui/en/widgets/wearable_outfit_list_item.xml b/indra/newview/skins/default/xui/en/widgets/wearable_outfit_list_item.xml new file mode 100644 index 0000000000..cd84b91b1f --- /dev/null +++ b/indra/newview/skins/default/xui/en/widgets/wearable_outfit_list_item.xml @@ -0,0 +1,64 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<inventory_list_item + follows="top|right|left" + height="20" + name="inventory_item" + tab_stop="false" + hover_image="ListItem_Over" + selected_image="ListItem_Select" + separator_image="Wearables_Divider" + width="380"> + <!-- DEFAULT style for inventory list item --> + <default_style + font="SansSerifSmall" + font.style="NORMAL" /> + + <!-- style for inventory list item WORN on avatar --> + <worn_style + font="SansSerifSmall" + font.style="BOLD" + color="EmphasisColor" /> + <item_icon + height="16" + follows="top|left" + image_name="Inv_Object" + layout="topleft" + left="0" + name="item_icon" + top="0" + width="16" /> + <item_name + follows="left|right" + height="20" + layout="topleft" + left="21" + parse_urls="false" + use_ellipses="true" + name="item_name" + text_color="white" + top="4" + value="..." + width="359" /> + <add_btn + name="add_wearable" + layout="topleft" + follows="top|right" + image_unselected="Add_Icon" + image_selected="Add_Icon" + top="1" + left="0" + height="16" + width="16" + tab_stop="false" /> + <remove_btn + name="remove_wearable" + layout="topleft" + follows="top|right" + image_unselected="Remove_Icon" + image_selected="Remove_Icon" + top="1" + left="26" + height="16" + width="16" + tab_stop="false" /> +</inventory_list_item> diff --git a/indra/newview/skins/default/xui/es/floater_tools.xml b/indra/newview/skins/default/xui/es/floater_tools.xml index 6fce98472d..ffa85a2f04 100644 --- a/indra/newview/skins/default/xui/es/floater_tools.xml +++ b/indra/newview/skins/default/xui/es/floater_tools.xml @@ -25,7 +25,7 @@ Pulsa y arrastra para seleccionar el terreno. </floater.string> <floater.string name="status_selectcount"> - [OBJ_COUNT] objetos seleccionados, impacto en el terreno [LAND_IMPACT] + [OBJ_COUNT] objetos seleccionados, impacto en el terreno [LAND_IMPACT] [secondlife:///app/openfloater/object_weights ?] </floater.string> <floater.string name="status_remaining_capacity"> Capacidad restante [LAND_CAPACITY]. diff --git a/indra/newview/skins/default/xui/fr/floater_tools.xml b/indra/newview/skins/default/xui/fr/floater_tools.xml index 9597d38dca..c161f3f530 100644 --- a/indra/newview/skins/default/xui/fr/floater_tools.xml +++ b/indra/newview/skins/default/xui/fr/floater_tools.xml @@ -40,7 +40,7 @@ Cliquez et faites glisser pour sélectionner le terrain. </floater.string> <floater.string name="status_selectcount"> - [OBJ_COUNT] objets sélectionnés, impact sur le terrain [LAND_IMPACT] + [OBJ_COUNT] objets sélectionnés, impact sur le terrain [LAND_IMPACT] [secondlife:///app/openfloater/object_weights ?] </floater.string> <floater.string name="status_remaining_capacity"> Capacité restante [LAND_CAPACITY]. diff --git a/indra/newview/skins/default/xui/it/floater_tools.xml b/indra/newview/skins/default/xui/it/floater_tools.xml index a21ae9a485..f98a2da277 100644 --- a/indra/newview/skins/default/xui/it/floater_tools.xml +++ b/indra/newview/skins/default/xui/it/floater_tools.xml @@ -40,7 +40,7 @@ Clicca e trascina per selezionare il terreno </floater.string> <floater.string name="status_selectcount"> - [OBJ_COUNT] oggetti selezionati, impatto terreno [LAND_IMPACT] + [OBJ_COUNT] oggetti selezionati, impatto terreno [LAND_IMPACT] [secondlife:///app/openfloater/object_weights ?] </floater.string> <floater.string name="status_remaining_capacity"> Capacità restante [LAND_CAPACITY]. diff --git a/indra/newview/skins/default/xui/ja/floater_tools.xml b/indra/newview/skins/default/xui/ja/floater_tools.xml index aec0dbdb55..13f766698e 100644 --- a/indra/newview/skins/default/xui/ja/floater_tools.xml +++ b/indra/newview/skins/default/xui/ja/floater_tools.xml @@ -40,7 +40,7 @@ 土地をクリックし、ドラッグして選択 </floater.string> <floater.string name="status_selectcount"> - 選択されているオブジェクトは [OBJ_COUNT] 個、土地の負荷は [LAND_IMPACT] + 選択されているオブジェクトは [OBJ_COUNT] 個、土地の負荷は [LAND_IMPACT] [secondlife:///app/openfloater/object_weights 詳細] </floater.string> <floater.string name="status_remaining_capacity"> 残りの許容数 [LAND_CAPACITY]。 diff --git a/indra/newview/skins/default/xui/pl/floater_tools.xml b/indra/newview/skins/default/xui/pl/floater_tools.xml index 5e2ed4a351..8932a86fd1 100644 --- a/indra/newview/skins/default/xui/pl/floater_tools.xml +++ b/indra/newview/skins/default/xui/pl/floater_tools.xml @@ -40,7 +40,7 @@ Kliknij i przeciągnij, aby zaznaczyć teren </floater.string> <floater.string name="status_selectcount"> - [OBJ_COUNT] zaznaczonych obiektów, wpływ na strefę: [LAND_IMPACT] + [OBJ_COUNT] zaznaczonych obiektów, wpływ na strefę: [LAND_IMPACT] [secondlife:///app/openfloater/object_weights ?] </floater.string> <floater.string name="status_remaining_capacity"> Pojemność pozostała: [LAND_CAPACITY]. diff --git a/indra/newview/skins/default/xui/pt/floater_tools.xml b/indra/newview/skins/default/xui/pt/floater_tools.xml index 0882f485a6..c0eab171c8 100644 --- a/indra/newview/skins/default/xui/pt/floater_tools.xml +++ b/indra/newview/skins/default/xui/pt/floater_tools.xml @@ -40,7 +40,7 @@ Clicar e arrastar para selecionar a terra </floater.string> <floater.string name="status_selectcount"> - [OBJ_COUNT] objetos selecionados, impacto no terreno [LAND_IMPACT] + [OBJ_COUNT] objetos selecionados, impacto no terreno [LAND_IMPACT] [secondlife:///app/openfloater/object_weights ?] </floater.string> <floater.string name="status_remaining_capacity"> Capacidade restante [LAND_CAPACITY]. diff --git a/indra/newview/skins/default/xui/ru/floater_tools.xml b/indra/newview/skins/default/xui/ru/floater_tools.xml index 82ee3c49ae..44f54aabb6 100644 --- a/indra/newview/skins/default/xui/ru/floater_tools.xml +++ b/indra/newview/skins/default/xui/ru/floater_tools.xml @@ -40,7 +40,7 @@ Щелкните и перетащите для выделения земли </floater.string> <floater.string name="status_selectcount"> - Выбрано объектов: [OBJ_COUNT], влияние на землю [LAND_IMPACT] + Выбрано объектов: [OBJ_COUNT], влияние на землю [LAND_IMPACT] [secondlife:///app/openfloater/object_weights ?] </floater.string> <floater.string name="status_remaining_capacity"> Остаток емкости [LAND_CAPACITY]. diff --git a/indra/newview/skins/default/xui/tr/floater_tools.xml b/indra/newview/skins/default/xui/tr/floater_tools.xml index d6b9a4a533..d48a617e38 100644 --- a/indra/newview/skins/default/xui/tr/floater_tools.xml +++ b/indra/newview/skins/default/xui/tr/floater_tools.xml @@ -40,7 +40,7 @@ Araziyi seçmek için tıklayın ve sürükleyin </floater.string> <floater.string name="status_selectcount"> - [OBJ_COUNT] nesne seçili, [LAND_IMPACT] arazi etkisi + [OBJ_COUNT] nesne seçili, [LAND_IMPACT] arazi etkisi [secondlife:///app/openfloater/object_weights Ek bilgi] </floater.string> <floater.string name="status_remaining_capacity"> Kalan kapasite [LAND_CAPACITY]. diff --git a/indra/newview/skins/default/xui/zh/floater_tools.xml b/indra/newview/skins/default/xui/zh/floater_tools.xml index 539c7454f1..f83b058ce1 100644 --- a/indra/newview/skins/default/xui/zh/floater_tools.xml +++ b/indra/newview/skins/default/xui/zh/floater_tools.xml @@ -40,7 +40,7 @@ 按住並拖曳,可以選取土地 </floater.string> <floater.string name="status_selectcount"> - 選取了 [OBJ_COUNT] 個物件,土地衝擊量 [LAND_IMPACT] + 選取了 [OBJ_COUNT] 個物件,土地衝擊量 [LAND_IMPACT] [secondlife:///app/openfloater/object_weights 詳情] </floater.string> <floater.string name="status_remaining_capacity"> 剩餘容納量 [LAND_CAPACITY]。 diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py index 59eb18b734..89481add29 100755 --- a/indra/newview/viewer_manifest.py +++ b/indra/newview/viewer_manifest.py @@ -75,7 +75,7 @@ class ViewerManifest(LLManifest): # include the entire shaders directory recursively self.path("shaders") # include the extracted list of contributors - contributions_path = "../../doc/contributions.txt" + contributions_path = os.path.join(self.args['source'], "..", "..", "doc", "contributions.txt") contributor_names = self.extract_names(contributions_path) self.put_in_file(contributor_names.encode(), "contributors.txt", src=contributions_path) @@ -435,7 +435,7 @@ class WindowsManifest(ViewerManifest): self.cmakedirs(os.path.dirname(dst)) self.created_paths.append(dst) if not os.path.isdir(src): - if(self.args['configuration'].lower() == 'debug'): + if(self.args['buildtype'].lower() == 'debug'): test_assembly_binding(src, "Microsoft.VC80.DebugCRT", "8.0.50727.4053") else: test_assembly_binding(src, "Microsoft.VC80.CRT", "8.0.50727.4053") @@ -458,7 +458,7 @@ class WindowsManifest(ViewerManifest): self.created_paths.append(dst) if not os.path.isdir(src): try: - if(self.args['configuration'].lower() == 'debug'): + if(self.args['buildtype'].lower() == 'debug'): test_assembly_binding(src, "Microsoft.VC80.DebugCRT", "") else: test_assembly_binding(src, "Microsoft.VC80.CRT", "") @@ -504,10 +504,10 @@ class WindowsManifest(ViewerManifest): # Get shared libs from the shared libs staging directory with self.prefix(src=os.path.join(self.args['build'], os.pardir, - 'sharedlibs', self.args['configuration'])): + 'sharedlibs', self.args['buildtype'])): # Get fmodstudio dll if needed if self.args['fmodstudio'] == 'ON': - if(self.args['configuration'].lower() == 'debug'): + if(self.args['buildtype'].lower() == 'debug'): self.path("fmodL.dll") else: self.path("fmod.dll") @@ -518,7 +518,7 @@ class WindowsManifest(ViewerManifest): self.path("alut.dll") # For textures - self.path("openjpeg.dll") + self.path("openjp2.dll") # Uriparser self.path("uriparser.dll") @@ -603,7 +603,7 @@ class WindowsManifest(ViewerManifest): # MSVC DLLs needed for CEF and have to be in same directory as plugin with self.prefix(src=os.path.join(self.args['build'], os.pardir, - 'sharedlibs', 'Release')): + 'sharedlibs', self.args['buildtype'])): self.path("msvcp140.dll") self.path("vcruntime140.dll") self.path_optional("vcruntime140_1.dll") @@ -909,7 +909,7 @@ class DarwinManifest(ViewerManifest): # Let exception, if any, propagate -- if this doesn't # work, we need the build to noisily fail! oldpath = subprocess.check_output( - ['objdump', '-macho', '-dylib-id', '-non-verbose', + ['objdump', '--macho', '--dylib-id', '--non-verbose', os.path.join(relpkgdir, "BugsplatMac.framework", "BugsplatMac")] ).splitlines()[-1] # take the last line of output self.run_command( @@ -1040,7 +1040,7 @@ class DarwinManifest(ViewerManifest): # Fmod studio dylibs (vary based on configuration) if self.args['fmodstudio'] == 'ON': - if self.args['configuration'].lower() == 'debug': + if self.args['buildtype'].lower() == 'debug': for libfile in ( "libfmodL.dylib", ): @@ -1501,7 +1501,7 @@ class Linux_i686_Manifest(LinuxManifest): self.path("libdirectfb-1.*.so.*") self.path("libfusion-1.*.so.*") self.path("libdirect-1.*.so.*") - self.path("libopenjpeg.so*") + self.path("libopenjp2.so*") self.path("libdirectfb-1.4.so.5") self.path("libfusion-1.4.so.5") self.path("libdirect-1.4.so.5*") diff --git a/indra/test/CMakeLists.txt b/indra/test/CMakeLists.txt index 084aa8d9f7..b7a39a7450 100644 --- a/indra/test/CMakeLists.txt +++ b/indra/test/CMakeLists.txt @@ -5,35 +5,12 @@ project (lltest) include(00-Common) include(LLCommon) include(LLCoreHttp) -include(LLInventory) -include(LLMath) -include(LLMessage) -include(LLFileSystem) -include(LLXML) include(Linking) include(Tut) include(LLAddBuildTest) include(bugsplat) include(GoogleMock) -include_directories( - ${LLCOMMON_INCLUDE_DIRS} - ${LLCOREHTTP_INCLUDE_DIRS} - ${LLDATABASE_INCLUDE_DIRS} - ${LLMATH_INCLUDE_DIRS} - ${LLMESSAGE_INCLUDE_DIRS} - ${LLINVENTORY_INCLUDE_DIRS} - ${LLFILESYSTEM_INCLUDE_DIRS} - ${LLXML_INCLUDE_DIRS} - ${LSCRIPT_INCLUDE_DIRS} - ${GOOGLEMOCK_INCLUDE_DIRS} - ${TUT_INCLUDE_DIR} - ) -include_directories(SYSTEM - ${LLCOMMON_SYSTEM_INCLUDE_DIRS} - ${LLXML_SYSTEM_INCLUDE_DIRS} - ) - set(test_SOURCE_FILES io.cpp llapp_tut.cpp @@ -76,39 +53,20 @@ if (NOT WINDOWS) ) endif (NOT WINDOWS) -set_source_files_properties(${test_HEADER_FILES} - PROPERTIES HEADER_FILE_ONLY TRUE) - list(APPEND test_SOURCE_FILES ${test_HEADER_FILES}) add_executable(lltest ${test_SOURCE_FILES}) -if (USE_BUGSPLAT) - set_target_properties(lltest PROPERTIES COMPILE_DEFINITIONS "${BUGSPLAT_DEFINE}") -endif (USE_BUGSPLAT) - target_link_libraries(lltest - ${LEGACY_STDIO_LIBS} - ${LLDATABASE_LIBRARIES} - ${LLINVENTORY_LIBRARIES} - ${LLMESSAGE_LIBRARIES} - ${LLMATH_LIBRARIES} - ${LLFILESYSTEM_LIBRARIES} - ${LLXML_LIBRARIES} - ${LSCRIPT_LIBRARIES} - ${LLCOMMON_LIBRARIES} - ${LLCOREHTTP_LIBRARIES} - ${EXPAT_LIBRARIES} - ${GOOGLEMOCK_LIBRARIES} - ${PTHREAD_LIBRARY} - ${WINDOWS_LIBRARIES} - ${BOOST_PROGRAM_OPTIONS_LIBRARY} - ${BOOST_REGEX_LIBRARY} - ${BOOST_FIBER_LIBRARY} - ${BOOST_CONTEXT_LIBRARY} - ${BOOST_SYSTEM_LIBRARY} - ${DL_LIBRARY} - ) + llinventory + llmessage + llmath + llfilesystem + llxml + llcommon + llcorehttp + ll::googlemock + ) if (WINDOWS) set_target_properties(lltest @@ -120,10 +78,10 @@ endif (WINDOWS) set(TEST_EXE $<TARGET_FILE:lltest>) -SET_TEST_PATH(DYLD_LIBRARY_PATH) +SET_TEST_PATH(LD_LIBRARY_PATH) LL_TEST_COMMAND(command - "${DYLD_LIBRARY_PATH}" + "${LD_LIBRARY_PATH}" "${TEST_EXE}" "--output=${CMAKE_CURRENT_BINARY_DIR}/cpp_test_results.txt" "--touch=${CMAKE_CURRENT_BINARY_DIR}/cpp_tests_ok.txt") @@ -144,4 +102,13 @@ set(test_results ${CMAKE_CURRENT_BINARY_DIR}/cpp_tests_ok.txt) # developers choose to disable LL_TESTS. if (LL_TESTS) add_custom_target(tests_ok ALL DEPENDS ${test_results}) + if(DARWIN) + # Support our "@executable_path/../Resources" load path for our test + # executable. This SHOULD properly be "$<TARGET_FILE_DIR:lltest>/Resources", + # but the CMake $<TARGET_FILE_DIR> generator expression isn't evaluated by + # CREATE_LINK, so fudge it. + add_custom_command( TARGET lltest POST_BUILD + COMMAND cmake -E create_symlink ${SHARED_LIB_STAGING_DIR} ${CMAKE_BINARY_DIR}/test/Resources + ) + endif() endif (LL_TESTS) diff --git a/indra/test/lldoubledispatch_tut.cpp b/indra/test/lldoubledispatch_tut.cpp index ad8f6454d4..dbf55e666f 100644 --- a/indra/test/lldoubledispatch_tut.cpp +++ b/indra/test/lldoubledispatch_tut.cpp @@ -35,8 +35,9 @@ #include "lldoubledispatch.h" // STL headers // std headers -#include <string> #include <iostream> +#include <memory> +#include <string> #include <typeinfo> // external library headers // other Linden headers @@ -135,10 +136,10 @@ namespace tut // Instantiate a few GameObjects. Make sure we refer to them // polymorphically, and don't let them leak. - std::auto_ptr<GameObject> home; - std::auto_ptr<GameObject> obstacle; - std::auto_ptr<GameObject> tug; - std::auto_ptr<GameObject> patrol; + std::unique_ptr<GameObject> home; + std::unique_ptr<GameObject> obstacle; + std::unique_ptr<GameObject> tug; + std::unique_ptr<GameObject> patrol; // prototype objects Asteroid dummyAsteroid; diff --git a/indra/viewer_components/login/CMakeLists.txt b/indra/viewer_components/login/CMakeLists.txt index 23518b791c..8381803b03 100644 --- a/indra/viewer_components/login/CMakeLists.txt +++ b/indra/viewer_components/login/CMakeLists.txt @@ -7,21 +7,7 @@ if(LL_TESTS) include(LLAddBuildTest) endif(LL_TESTS) include(LLCommon) -include(LLMath) -include(LLXML) -include(Boost) include(LLCoreHttp) -include(LLMessage) - -include_directories( - ${LLCOMMON_INCLUDE_DIRS} - ${LLMATH_INCLUDE_DIRS} - ${LLXML_INCLUDE_DIRS} - ) -include_directories(SYSTEM - ${LLCOMMON_SYSTEM_INCLUDE_DIRS} - ${LLXML_SYSTEM_INCLUDE_DIRS} - ) set(login_SOURCE_FILES lllogin.cpp @@ -31,9 +17,6 @@ set(login_HEADER_FILES lllogin.h ) -set_source_files_properties(${login_HEADER_FILES} - PROPERTIES HEADER_FILE_ONLY TRUE) - list(APPEND login_SOURCE_FILES ${login_HEADER_FILES} @@ -42,17 +25,14 @@ list(APPEND add_library(lllogin ${login_SOURCE_FILES} ) +target_include_directories( lllogin INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}) target_link_libraries(lllogin - ${LLMESSAGE_LIBRARIES} - ${LLCOREHTTP_LIBRARIES} - ${LLCOMMON_LIBRARIES} - ${LLMATH_LIBRARIES} - ${LLXML_LIBRARIES} - ${BOOST_THREAD_LIBRARY} - ${BOOST_FIBER_LIBRARY} - ${BOOST_CONTEXT_LIBRARY} - ${BOOST_SYSTEM_LIBRARY} + llmessage + llcorehttp + llcommon + llmath + llxml ) if(LL_TESTS) @@ -62,7 +42,7 @@ if(LL_TESTS) set_source_files_properties( lllogin.cpp PROPERTIES - LL_TEST_ADDITIONAL_LIBRARIES "${LLMESSAGE_LIBRARIES};${LLCOREHTTP_LIBRARIES};${LLCOMMON_LIBRARIES};${BOOST_FIBER_LIBRARY};${BOOST_CONTEXT_LIBRARY};${BOOST_THREAD_LIBRARY};${BOOST_SYSTEM_LIBRARY}" + LL_TEST_ADDITIONAL_LIBRARIES llmessage llcorehttp llcommon ) LL_ADD_PROJECT_UNIT_TESTS(lllogin "${lllogin_TEST_SOURCE_FILES}") diff --git a/scripts/packages-formatter.py b/scripts/packages-formatter.py index ff7c892577..4449111e46 100755 --- a/scripts/packages-formatter.py +++ b/scripts/packages-formatter.py @@ -34,6 +34,7 @@ import argparse parser = argparse.ArgumentParser(description='Format dependency version and copyright information for the viewer About box content') parser.add_argument('channel', help='viewer channel name') parser.add_argument('version', help='viewer version number') +parser.add_argument('install_dir', help="install dir of packages") args = parser.parse_args() _autobuild=os.getenv('AUTOBUILD', 'autobuild') @@ -74,8 +75,8 @@ def add_info(key, pkg, lines): else: dups[key].add(pkg) -versions=autobuild('install', '--versions') -copyrights=autobuild('install', '--copyrights') +versions=autobuild('install', '--versions', '--install-dir', args.install_dir) +copyrights=autobuild('install', '--copyrights', '--install-dir', args.install_dir) viewer_copyright = copyrights.readline() # first line is the copyright for the viewer itself # Two different autobuild outputs, but we treat them essentially the same way: |